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;

clang/lib/AST/ASTImporter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5469,6 +5469,9 @@ ExpectedDecl ASTNodeImporter::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
54695469
case BuiltinTemplateKind::BTK__builtin_common_type:
54705470
ToD = Importer.getToContext().getBuiltinCommonTypeDecl();
54715471
break;
5472+
case BuiltinTemplateKind::BTK__builtin_common_reference:
5473+
ToD = Importer.getToContext().getBuiltinCommonReferenceDecl();
5474+
break;
54725475
}
54735476
assert(ToD && "BuiltinTemplateDecl of unsupported kind!");
54745477
Importer.MapImported(D, ToD);

clang/lib/AST/DeclBase.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
967967

968968
case UsingDirective:
969969
case BuiltinTemplate:
970+
case CVRefQualifyingTemplate:
970971
case ClassTemplateSpecialization:
971972
case ClassTemplatePartialSpecialization:
972973
case VarTemplateSpecialization:

clang/lib/AST/DeclTemplate.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ bool TemplateDecl::isTypeAlias() const {
306306
switch (getKind()) {
307307
case TemplateDecl::TypeAliasTemplate:
308308
case TemplateDecl::BuiltinTemplate:
309+
case TemplateDecl::CVRefQualifyingTemplate:
309310
return true;
310311
default:
311312
return false;
@@ -1696,6 +1697,83 @@ static TemplateParameterList *createBuiltinCommonTypeList(const ASTContext &C,
16961697
nullptr);
16971698
}
16981699

1700+
static TemplateTypeParmDecl *BICreateTemplateParm(const ASTContext &C,
1701+
DeclContext *DC,
1702+
unsigned Depth,
1703+
unsigned Position,
1704+
bool ParameterPack = false) {
1705+
return TemplateTypeParmDecl::Create(
1706+
C, DC, SourceLocation(), SourceLocation(), Depth, Position,
1707+
/*Id=*/nullptr, /*Typename=*/false, ParameterPack);
1708+
}
1709+
1710+
static TemplateTemplateParmDecl *
1711+
BICreateTemplateTemplateParm(const ASTContext &C, DeclContext *DC,
1712+
ArrayRef<NamedDecl *> Parms, unsigned Depth,
1713+
unsigned Position, bool ParameterPack = false) {
1714+
auto *List = TemplateParameterList::Create(
1715+
C, SourceLocation(), SourceLocation(), Parms, SourceLocation(), nullptr);
1716+
return TemplateTemplateParmDecl::Create(C, DC, SourceLocation(), Depth,
1717+
Position, ParameterPack,
1718+
/*Id=*/nullptr, false, List);
1719+
}
1720+
1721+
static TemplateTemplateParmDecl *
1722+
createBuiltinCommonReferenceBasicCommonReferenceT(const ASTContext &C,
1723+
DeclContext *DC) {
1724+
auto *T = BICreateTemplateParm(C, DC, /*Depth=*/1, /*Position=*/0);
1725+
auto *U = BICreateTemplateParm(C, DC, /*Depth=*/1, /*Position=*/1);
1726+
auto *TXArg = BICreateTemplateParm(C, DC, /*Depth=*/2, /*Position=*/0);
1727+
auto *TX =
1728+
BICreateTemplateTemplateParm(C, DC, {TXArg}, /*Depth=*/1, /*Position=*/2);
1729+
auto *UXArg = BICreateTemplateParm(C, DC, /*Depth=*/2, /*Position=*/0);
1730+
auto *UX =
1731+
BICreateTemplateTemplateParm(C, DC, {UXArg}, /*Depth=*/1, /*Position=*/2);
1732+
return BICreateTemplateTemplateParm(C, DC, {T, U, TX, UX}, /*Depth=*/0,
1733+
/*Position=*/0);
1734+
}
1735+
1736+
static TemplateParameterList *createBuiltinCommonReferenceList(const ASTContext &C,
1737+
DeclContext *DC) {
1738+
// template <class, class, template <class> class, template <class> class>
1739+
// class
1740+
auto *BasicCommonReference =
1741+
createBuiltinCommonReferenceBasicCommonReferenceT(C, DC);
1742+
// class... Args
1743+
auto *Args = BICreateTemplateParm(C, DC, /*Depth=*/1, /*Position=*/0,
1744+
/*ParameterPack=*/true);
1745+
1746+
// template <class... Args>
1747+
auto *BaseTemplate =
1748+
BICreateTemplateTemplateParm(C, DC, Args, /*Depth=*/0, /*Position=*/1);
1749+
1750+
// class TypeMember
1751+
auto *TypeMember = BICreateTemplateParm(C, DC, /*Depth=*/1, /*Position=*/0);
1752+
1753+
// template <class TypeMember>
1754+
auto *HasTypeMember = BICreateTemplateTemplateParm(
1755+
C, DC, TypeMember, /*Depth=*/0, /*Position=*/2);
1756+
1757+
// class HasNoTypeMember
1758+
auto *HasNoTypeMember =
1759+
BICreateTemplateParm(C, DC, /*Depth=*/0, /*Position=*/3);
1760+
1761+
// class... Ts
1762+
auto *Ts = BICreateTemplateParm(C, DC, /*Depth=*/0, /*Position=*/4,
1763+
/*ParameterPack=*/true);
1764+
1765+
// template <template <class, class, template <class> class, template <class>
1766+
// class BasicCommonReference,
1767+
// template <class... Args> class CommonType,
1768+
// template <class TypeMember> class HasTypeMember,
1769+
// class HasNoTypeMember,
1770+
// class... Ts>
1771+
return TemplateParameterList::Create(
1772+
C, SourceLocation(), SourceLocation(),
1773+
{BasicCommonReference, BaseTemplate, HasTypeMember, HasNoTypeMember, Ts},
1774+
SourceLocation(), nullptr);
1775+
}
1776+
16991777
static TemplateParameterList *createBuiltinTemplateParameterList(
17001778
const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
17011779
switch (BTK) {
@@ -1705,6 +1783,8 @@ static TemplateParameterList *createBuiltinTemplateParameterList(
17051783
return createTypePackElementParameterList(C, DC);
17061784
case BTK__builtin_common_type:
17071785
return createBuiltinCommonTypeList(C, DC);
1786+
case BTK__builtin_common_reference:
1787+
return createBuiltinCommonReferenceList(C, DC);
17081788
}
17091789

17101790
llvm_unreachable("unhandled BuiltinTemplateKind!");
@@ -1719,6 +1799,26 @@ BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
17191799
createBuiltinTemplateParameterList(C, DC, BTK)),
17201800
BTK(BTK) {}
17211801

1802+
void CVRefQualifyingTemplateDecl::anchor() {}
1803+
1804+
static TemplateParameterList *
1805+
createCVRefQualifyingTemplateParameterList(const ASTContext &C,
1806+
DeclContext *DC) {
1807+
auto *T = TemplateTypeParmDecl::Create(
1808+
C, DC, SourceLocation(), SourceLocation(),
1809+
/*Depth=*/0, /*Position=*/0, /*Id=*/nullptr, false, false);
1810+
return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1811+
{T}, SourceLocation(), nullptr);
1812+
}
1813+
1814+
CVRefQualifyingTemplateDecl::CVRefQualifyingTemplateDecl(const ASTContext &C,
1815+
DeclContext *DC,
1816+
CVRefQuals Quals)
1817+
: TemplateDecl(CVRefQualifyingTemplate, DC, SourceLocation(),
1818+
DeclarationName(),
1819+
createCVRefQualifyingTemplateParameterList(C, DC)),
1820+
Quals(Quals) {}
1821+
17221822
TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
17231823
QualType T,
17241824
const APValue &V) {
@@ -1784,6 +1884,8 @@ TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {
17841884
return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
17851885
case Decl::Kind::BuiltinTemplate:
17861886
return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1887+
case Decl::Kind::CVRefQualifyingTemplate:
1888+
return cast<CVRefQualifyingTemplateDecl>(D)->getTemplateParameters();
17871889
case Decl::Kind::CXXDeductionGuide:
17881890
case Decl::Kind::CXXConversion:
17891891
case Decl::Kind::CXXConstructor:

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static_assert(clang::Sema::MaximumAlignment <= llvm::Value::MaximumAlignment,
5050
void CodeGenFunction::EmitDecl(const Decl &D) {
5151
switch (D.getKind()) {
5252
case Decl::BuiltinTemplate:
53+
case Decl::CVRefQualifyingTemplate:
5354
case Decl::TranslationUnit:
5455
case Decl::ExternCContext:
5556
case Decl::Namespace:

0 commit comments

Comments
 (0)