Skip to content

Commit e0db731

Browse files
committed
[Clang] Add __builtin_common_reference
1 parent f334db9 commit e0db731

26 files changed

+738
-117
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,23 @@ Builtin type aliases
15461546

15471547
Clang provides a few builtin aliases to improve the throughput of certain metaprogramming facilities.
15481548

1549+
__builtin_common_reference
1550+
--------------------------
1551+
1552+
.. code-block:: c++
1553+
1554+
template <template <class, class, template <class> class, template <class> class> class BasicCommonReferenceT,
1555+
template <class... Args> CommonTypeT,
1556+
template <class> HasTypeMember,
1557+
class HasNoTypeMember,
1558+
class... Ts>
1559+
using __builtin_common_reference = ...;
1560+
1561+
This alias is used for implementing ``std::common_refernce``. If ``std::common_reference`` should contain a ``type``
1562+
member, it is an alias to ``HasTypeMember<TheCommonReference>``. Otherwse it is an alias to ``HasNoTypeMember``. The
1563+
``CommonTypeT`` is usually ``std::common_type_t``. ``BasicCommonReferenceT`` is usually an alias template to
1564+
``basic_common_reference<T, U, TX, UX>::type``.
1565+
15491566
__builtin_common_type
15501567
---------------------
15511568

clang/include/clang/AST/ASTContext.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
419419
/// The identifier '__builtin_common_type'.
420420
mutable IdentifierInfo *BuiltinCommonTypeName = nullptr;
421421

422+
/// The identifier '__builtin_common_reference'.
423+
mutable IdentifierInfo *BuiltinCommonReferenceName = nullptr;
424+
422425
QualType ObjCConstantStringType;
423426
mutable RecordDecl *CFConstantStringTagDecl = nullptr;
424427
mutable TypedefDecl *CFConstantStringTypeDecl = nullptr;
@@ -627,6 +630,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
627630
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr;
628631
mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr;
629632
mutable BuiltinTemplateDecl *BuiltinCommonTypeDecl = nullptr;
633+
mutable BuiltinTemplateDecl *BuiltinCommonReferenceDecl = nullptr;
634+
mutable CVRefQualifyingTemplateDecl *CVRefQualifyingDecls[12] = {};
630635

631636
/// The associated SourceManager object.
632637
SourceManager &SourceMgr;
@@ -1155,6 +1160,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
11551160
BuiltinTemplateDecl *getMakeIntegerSeqDecl() const;
11561161
BuiltinTemplateDecl *getTypePackElementDecl() const;
11571162
BuiltinTemplateDecl *getBuiltinCommonTypeDecl() const;
1163+
BuiltinTemplateDecl *getBuiltinCommonReferenceDecl() const;
1164+
CVRefQualifyingTemplateDecl *getCVRefQualifyingAliasDecl(QualType From) const;
11581165

11591166
// Builtin Types.
11601167
CanQualType VoidTy;
@@ -2072,6 +2079,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
20722079
return BuiltinCommonTypeName;
20732080
}
20742081

2082+
IdentifierInfo *getBuiltinCommonReferenceName() const {
2083+
if (!BuiltinCommonReferenceName)
2084+
BuiltinCommonReferenceName = &Idents.get("__builtin_common_reference");
2085+
return BuiltinCommonReferenceName;
2086+
}
2087+
20752088
/// Retrieve the Objective-C "instancetype" type, if already known;
20762089
/// otherwise, returns a NULL type;
20772090
QualType getObjCInstanceType() {

clang/include/clang/AST/ASTNodeTraverser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,10 @@ class ASTNodeTraverser
684684
dumpTemplateParameters(D->getTemplateParameters());
685685
}
686686

687+
void VisitCVRefQualifyingTemplateDecl(const CVRefQualifyingTemplateDecl *D) {
688+
dumpTemplateParameters(D->getTemplateParameters());
689+
}
690+
687691
void
688692
VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) {
689693
dumpTemplateArgumentList(D->getTemplateArgs());

clang/include/clang/AST/DeclID.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ enum PredefinedDeclIDs {
8686
/// The internal '__builtin_common_type' template.
8787
PREDEF_DECL_COMMON_TYPE_ID,
8888

89+
/// The internal '__builtin_common_reference' template.
90+
PREDEF_DECL_COMMON_REFERENCE_ID,
91+
8992
/// The number of declaration IDs that are predefined.
9093
NUM_PREDEF_DECL_IDS
9194
};

clang/include/clang/AST/DeclTemplate.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,6 +1777,43 @@ class BuiltinTemplateDecl : public TemplateDecl {
17771777
BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; }
17781778
};
17791779

1780+
class CVRefQualifyingTemplateDecl : public TemplateDecl {
1781+
public:
1782+
// LValueRef and RValueRef are mutually exclusive
1783+
enum CVRefQuals {
1784+
None = 0x0,
1785+
Const = 0x1,
1786+
Volatile = 0x2,
1787+
LValueRef = 0x4,
1788+
RValueRef = 0x8,
1789+
LLVM_BITMASK_LARGEST_ENUMERATOR,
1790+
};
1791+
1792+
private:
1793+
CVRefQuals Quals;
1794+
1795+
CVRefQualifyingTemplateDecl(const ASTContext &C, DeclContext *DC,
1796+
CVRefQuals Quals);
1797+
1798+
void anchor() override;
1799+
1800+
public:
1801+
// Implement isa/cast/dyncast support
1802+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1803+
static bool classofKind(Kind K) { return K == CVRefQualifyingTemplate; }
1804+
1805+
static CVRefQualifyingTemplateDecl *Create(const ASTContext &C,
1806+
DeclContext *DC, CVRefQuals Ref) {
1807+
return new (C, DC) CVRefQualifyingTemplateDecl(C, DC, Ref);
1808+
}
1809+
1810+
SourceRange getSourceRange() const override LLVM_READONLY {
1811+
return {};
1812+
}
1813+
1814+
CVRefQuals getQuals() { return Quals; }
1815+
};
1816+
17801817
/// Provides information about an explicit instantiation of a variable or class
17811818
/// template.
17821819
struct ExplicitInstantiationInfo {

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,6 +1960,10 @@ DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
19601960
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
19611961
})
19621962

1963+
DEF_TRAVERSE_DECL(CVRefQualifyingTemplateDecl, {
1964+
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
1965+
})
1966+
19631967
template <typename Derived>
19641968
bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
19651969
const TemplateTypeParmDecl *D) {

clang/include/clang/Basic/Builtins.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ enum BuiltinTemplateKind : int {
311311

312312
/// This names the __builtin_common_type BuiltinTemplateDecl.
313313
BTK__builtin_common_type,
314+
315+
/// This names the __builtin_common_reference BuiltinTemplateDecl.
316+
BTK__builtin_common_reference,
314317
};
315318

316319
} // end namespace clang

clang/include/clang/Basic/DeclNodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def Named : DeclNode<Decl, "named declarations", 1>;
7171
def TypeAliasTemplate : DeclNode<RedeclarableTemplate>;
7272
def TemplateTemplateParm : DeclNode<Template>;
7373
def BuiltinTemplate : DeclNode<Template>;
74+
def CVRefQualifyingTemplate : DeclNode<Template>;
7475
def Concept : DeclNode<Template>;
7576
def BaseUsing : DeclNode<Named, "", 1>;
7677
def Using : DeclNode<BaseUsing>;

clang/include/clang/Sema/Sema.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14897,15 +14897,34 @@ class Sema final : public SemaBase {
1489714897
QualType BuiltinDecay(QualType BaseType, SourceLocation Loc);
1489814898
QualType BuiltinAddReference(QualType BaseType, UTTKind UKind,
1489914899
SourceLocation Loc);
14900+
14901+
QualType BuiltinAddRValueReference(QualType BaseType, SourceLocation Loc) {
14902+
return BuiltinAddReference(BaseType, UnaryTransformType::AddRvalueReference,
14903+
Loc);
14904+
}
14905+
14906+
QualType BuiltinAddLValueReference(QualType BaseType, SourceLocation Loc) {
14907+
return BuiltinAddReference(BaseType, UnaryTransformType::AddLvalueReference,
14908+
Loc);
14909+
}
14910+
1490014911
QualType BuiltinRemoveExtent(QualType BaseType, UTTKind UKind,
1490114912
SourceLocation Loc);
1490214913
QualType BuiltinRemoveReference(QualType BaseType, UTTKind UKind,
1490314914
SourceLocation Loc);
14915+
14916+
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc) {
14917+
return BuiltinRemoveReference(BaseType, UTTKind::RemoveCVRef, Loc);
14918+
}
14919+
1490414920
QualType BuiltinChangeCVRQualifiers(QualType BaseType, UTTKind UKind,
1490514921
SourceLocation Loc);
1490614922
QualType BuiltinChangeSignedness(QualType BaseType, UTTKind UKind,
1490714923
SourceLocation Loc);
1490814924

14925+
bool BuiltinIsConvertible(QualType From, QualType To, SourceLocation Loc,
14926+
bool CheckNothrow = false);
14927+
1490914928
/// Ensure that the type T is a literal type.
1491014929
///
1491114930
/// This routine checks whether the type @p T is a literal type. If @p T is an

clang/lib/AST/ASTContext.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,37 @@ BuiltinTemplateDecl *ASTContext::getBuiltinCommonTypeDecl() const {
12181218
return BuiltinCommonTypeDecl;
12191219
}
12201220

1221+
BuiltinTemplateDecl *ASTContext::getBuiltinCommonReferenceDecl() const {
1222+
if (!BuiltinCommonReferenceDecl)
1223+
BuiltinCommonReferenceDecl = buildBuiltinTemplateDecl(
1224+
BTK__builtin_common_reference, getBuiltinCommonReferenceName());
1225+
return BuiltinCommonReferenceDecl;
1226+
}
1227+
1228+
CVRefQualifyingTemplateDecl *
1229+
ASTContext::getCVRefQualifyingAliasDecl(QualType From) const {
1230+
using CVRefQuals = CVRefQualifyingTemplateDecl::CVRefQuals;
1231+
1232+
CVRefQuals Q = CVRefQuals::None;
1233+
if (From->isReferenceType()) {
1234+
Q |= From->isLValueReferenceType() ? CVRefQuals::LValueRef
1235+
: CVRefQuals::RValueRef;
1236+
From = From.getNonReferenceType();
1237+
}
1238+
1239+
if (From.isConstQualified())
1240+
Q |= CVRefQuals::Const;
1241+
if (From.isVolatileQualified())
1242+
Q |= CVRefQuals::Volatile;
1243+
auto *Decl = CVRefQualifyingDecls[Q];
1244+
if (!Decl)
1245+
Decl =
1246+
CVRefQualifyingTemplateDecl::Create(*this, getTranslationUnitDecl(), Q);
1247+
Decl->setImplicit();
1248+
getTranslationUnitDecl()->addDecl(Decl);
1249+
return Decl;
1250+
}
1251+
12211252
RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,
12221253
RecordDecl::TagKind TK) const {
12231254
SourceLocation Loc;

0 commit comments

Comments
 (0)