Skip to content

Commit 8dd8e5f

Browse files
authored
[Clang] Add BuiltinTemplates.td to generate code for builtin templates (#123736)
This makes it significantly easier to add new builtin templates, since you only have to modify two places instead of a dozen or so. The `BuiltinTemplates.td` could also be extended to generate documentation from it in the future.
1 parent defe43b commit 8dd8e5f

16 files changed

+278
-244
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -410,14 +410,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
410410
/// The identifier 'NSCopying'.
411411
IdentifierInfo *NSCopyingName = nullptr;
412412

413-
/// The identifier '__make_integer_seq'.
414-
mutable IdentifierInfo *MakeIntegerSeqName = nullptr;
415-
416-
/// The identifier '__type_pack_element'.
417-
mutable IdentifierInfo *TypePackElementName = nullptr;
418-
419-
/// The identifier '__builtin_common_type'.
420-
mutable IdentifierInfo *BuiltinCommonTypeName = nullptr;
413+
#define BuiltinTemplate(BTName) mutable IdentifierInfo *Name##BTName = nullptr;
414+
#include "clang/Basic/BuiltinTemplates.inc"
421415

422416
QualType ObjCConstantStringType;
423417
mutable RecordDecl *CFConstantStringTagDecl = nullptr;
@@ -629,9 +623,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
629623

630624
TranslationUnitDecl *TUDecl = nullptr;
631625
mutable ExternCContextDecl *ExternCContext = nullptr;
632-
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr;
633-
mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr;
634-
mutable BuiltinTemplateDecl *BuiltinCommonTypeDecl = nullptr;
626+
627+
#define BuiltinTemplate(BTName) \
628+
mutable BuiltinTemplateDecl *Decl##BTName = nullptr;
629+
#include "clang/Basic/BuiltinTemplates.inc"
635630

636631
/// The associated SourceManager object.
637632
SourceManager &SourceMgr;
@@ -1157,9 +1152,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
11571152
}
11581153

11591154
ExternCContextDecl *getExternCContextDecl() const;
1160-
BuiltinTemplateDecl *getMakeIntegerSeqDecl() const;
1161-
BuiltinTemplateDecl *getTypePackElementDecl() const;
1162-
BuiltinTemplateDecl *getBuiltinCommonTypeDecl() const;
1155+
1156+
#define BuiltinTemplate(BTName) BuiltinTemplateDecl *get##BTName##Decl() const;
1157+
#include "clang/Basic/BuiltinTemplates.inc"
11631158

11641159
// Builtin Types.
11651160
CanQualType VoidTy;
@@ -2107,23 +2102,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
21072102
return BoolName;
21082103
}
21092104

2110-
IdentifierInfo *getMakeIntegerSeqName() const {
2111-
if (!MakeIntegerSeqName)
2112-
MakeIntegerSeqName = &Idents.get("__make_integer_seq");
2113-
return MakeIntegerSeqName;
2114-
}
2115-
2116-
IdentifierInfo *getTypePackElementName() const {
2117-
if (!TypePackElementName)
2118-
TypePackElementName = &Idents.get("__type_pack_element");
2119-
return TypePackElementName;
2120-
}
2121-
2122-
IdentifierInfo *getBuiltinCommonTypeName() const {
2123-
if (!BuiltinCommonTypeName)
2124-
BuiltinCommonTypeName = &Idents.get("__builtin_common_type");
2125-
return BuiltinCommonTypeName;
2105+
#define BuiltinTemplate(BTName) \
2106+
IdentifierInfo *get##BTName##Name() const { \
2107+
if (!Name##BTName) \
2108+
Name##BTName = &Idents.get(#BTName); \
2109+
return Name##BTName; \
21262110
}
2111+
#include "clang/Basic/BuiltinTemplates.inc"
21272112

21282113
/// Retrieve the Objective-C "instancetype" type, if already known;
21292114
/// otherwise, returns a NULL type;

clang/include/clang/AST/DeclID.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,14 @@ enum PredefinedDeclIDs {
7171
/// The extern "C" context.
7272
PREDEF_DECL_EXTERN_C_CONTEXT_ID,
7373

74-
/// The internal '__make_integer_seq' template.
75-
PREDEF_DECL_MAKE_INTEGER_SEQ_ID,
76-
7774
/// The internal '__NSConstantString' typedef.
7875
PREDEF_DECL_CF_CONSTANT_STRING_ID,
7976

8077
/// The internal '__NSConstantString' tag type.
8178
PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID,
8279

83-
/// The internal '__type_pack_element' template.
84-
PREDEF_DECL_TYPE_PACK_ELEMENT_ID,
85-
86-
/// The internal '__builtin_common_type' template.
87-
PREDEF_DECL_COMMON_TYPE_ID,
80+
#define BuiltinTemplate(BTName) PREDEF_DECL##BTName##_ID,
81+
#include "clang/Basic/BuiltinTemplates.inc"
8882

8983
/// The number of declaration IDs that are predefined.
9084
NUM_PREDEF_DECL_IDS
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===--- BuiltinTemplates.td - Clang builtin template aliases ---*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
class TemplateArg<string name> {
10+
string Name = name;
11+
}
12+
13+
class Template<list<TemplateArg> args, string name> : TemplateArg<name> {
14+
list<TemplateArg> Args = args;
15+
}
16+
17+
class Class<string name, bit is_variadic = 0> : TemplateArg<name> {
18+
bit IsVariadic = is_variadic;
19+
}
20+
21+
class NTTP<string type_name, string name, bit is_variadic = 0> : TemplateArg<name> {
22+
string TypeName = type_name;
23+
bit IsVariadic = is_variadic;
24+
}
25+
26+
class BuiltinNTTP<string type_name> : TemplateArg<""> {
27+
string TypeName = type_name;
28+
}
29+
30+
def SizeT : BuiltinNTTP<"size_t"> {}
31+
32+
class BuiltinTemplate<list<TemplateArg> template_head> {
33+
list<TemplateArg> TemplateHead = template_head;
34+
}
35+
36+
// template <template <class T, T... Ints> IntSeq, class T, T N>
37+
def __make_integer_seq : BuiltinTemplate<
38+
[Template<[Class<"T">, NTTP<"T", "Ints", /*is_variadic=*/1>], "IntSeq">, Class<"T">, NTTP<"T", "N">]>;
39+
40+
// template <size_t, class... T>
41+
def __type_pack_element : BuiltinTemplate<
42+
[SizeT, Class<"T", /*is_variadic=*/1>]>;
43+
44+
// template <template <class... Args> BaseTemplate,
45+
// template <class TypeMember> HasTypeMember,
46+
// class HasNoTypeMember
47+
// class... Ts>
48+
def __builtin_common_type : BuiltinTemplate<
49+
[Template<[Class<"Args", /*is_variadic=*/1>], "BaseTemplate">,
50+
Template<[Class<"TypeMember">], "HasTypeMember">,
51+
Class<"HasNoTypeMember">,
52+
Class<"Ts", /*is_variadic=*/1>]>;

clang/include/clang/Basic/Builtins.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -459,14 +459,8 @@ bool evaluateRequiredTargetFeatures(
459459

460460
/// Kinds of BuiltinTemplateDecl.
461461
enum BuiltinTemplateKind : int {
462-
/// This names the __make_integer_seq BuiltinTemplateDecl.
463-
BTK__make_integer_seq,
464-
465-
/// This names the __type_pack_element BuiltinTemplateDecl.
466-
BTK__type_pack_element,
467-
468-
/// This names the __builtin_common_type BuiltinTemplateDecl.
469-
BTK__builtin_common_type,
462+
#define BuiltinTemplate(BTName) BTK##BTName,
463+
#include "clang/Basic/BuiltinTemplates.inc"
470464
};
471465

472466
} // end namespace clang

clang/include/clang/Basic/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ clang_tablegen(BuiltinsX86_64.inc -gen-clang-builtins
9696
SOURCE BuiltinsX86_64.td
9797
TARGET ClangBuiltinsX86_64)
9898

99+
clang_tablegen(BuiltinTemplates.inc -gen-clang-builtin-templates
100+
SOURCE BuiltinTemplates.td
101+
TARGET ClangBuiltinTemplates)
102+
99103
# ARM NEON and MVE
100104
clang_tablegen(arm_neon.inc -gen-arm-neon-sema
101105
SOURCE arm_neon.td

clang/lib/AST/ASTContext.cpp

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,28 +1198,14 @@ ASTContext::buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
11981198
return BuiltinTemplate;
11991199
}
12001200

1201-
BuiltinTemplateDecl *
1202-
ASTContext::getMakeIntegerSeqDecl() const {
1203-
if (!MakeIntegerSeqDecl)
1204-
MakeIntegerSeqDecl = buildBuiltinTemplateDecl(BTK__make_integer_seq,
1205-
getMakeIntegerSeqName());
1206-
return MakeIntegerSeqDecl;
1207-
}
1208-
1209-
BuiltinTemplateDecl *
1210-
ASTContext::getTypePackElementDecl() const {
1211-
if (!TypePackElementDecl)
1212-
TypePackElementDecl = buildBuiltinTemplateDecl(BTK__type_pack_element,
1213-
getTypePackElementName());
1214-
return TypePackElementDecl;
1215-
}
1216-
1217-
BuiltinTemplateDecl *ASTContext::getBuiltinCommonTypeDecl() const {
1218-
if (!BuiltinCommonTypeDecl)
1219-
BuiltinCommonTypeDecl = buildBuiltinTemplateDecl(
1220-
BTK__builtin_common_type, getBuiltinCommonTypeName());
1221-
return BuiltinCommonTypeDecl;
1222-
}
1201+
#define BuiltinTemplate(BTName) \
1202+
BuiltinTemplateDecl *ASTContext::get##BTName##Decl() const { \
1203+
if (!Decl##BTName) \
1204+
Decl##BTName = \
1205+
buildBuiltinTemplateDecl(BTK##BTName, get##BTName##Name()); \
1206+
return Decl##BTName; \
1207+
}
1208+
#include "clang/Basic/BuiltinTemplates.inc"
12231209

12241210
RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,
12251211
RecordDecl::TagKind TK) const {

clang/lib/AST/ASTImporter.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5465,15 +5465,11 @@ ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
54655465
ExpectedDecl ASTNodeImporter::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
54665466
Decl* ToD = nullptr;
54675467
switch (D->getBuiltinTemplateKind()) {
5468-
case BuiltinTemplateKind::BTK__make_integer_seq:
5469-
ToD = Importer.getToContext().getMakeIntegerSeqDecl();
5470-
break;
5471-
case BuiltinTemplateKind::BTK__type_pack_element:
5472-
ToD = Importer.getToContext().getTypePackElementDecl();
5473-
break;
5474-
case BuiltinTemplateKind::BTK__builtin_common_type:
5475-
ToD = Importer.getToContext().getBuiltinCommonTypeDecl();
5468+
#define BuiltinTemplate(BTName) \
5469+
case BuiltinTemplateKind::BTK##BTName: \
5470+
ToD = Importer.getToContext().get##BTName##Decl(); \
54765471
break;
5472+
#include "clang/Basic/BuiltinTemplates.inc"
54775473
}
54785474
assert(ToD && "BuiltinTemplateDecl of unsupported kind!");
54795475
Importer.MapImported(D, ToD);

clang/lib/AST/DeclTemplate.cpp

Lines changed: 2 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,140 +1581,11 @@ SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
15811581
return Range;
15821582
}
15831583

1584-
static TemplateParameterList *
1585-
createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1586-
// typename T
1587-
auto *T = TemplateTypeParmDecl::Create(
1588-
C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1589-
/*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1590-
/*HasTypeConstraint=*/false);
1591-
T->setImplicit(true);
1592-
1593-
// T ...Ints
1594-
TypeSourceInfo *TI =
1595-
C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1596-
auto *N = NonTypeTemplateParmDecl::Create(
1597-
C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1598-
/*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1599-
N->setImplicit(true);
1600-
1601-
// <typename T, T ...Ints>
1602-
NamedDecl *P[2] = {T, N};
1603-
auto *TPL = TemplateParameterList::Create(
1604-
C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1605-
1606-
// template <typename T, ...Ints> class IntSeq
1607-
auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1608-
C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1609-
/*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL);
1610-
TemplateTemplateParm->setImplicit(true);
1611-
1612-
// typename T
1613-
auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1614-
C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1615-
/*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1616-
/*HasTypeConstraint=*/false);
1617-
TemplateTypeParm->setImplicit(true);
1618-
1619-
// T N
1620-
TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1621-
QualType(TemplateTypeParm->getTypeForDecl(), 0));
1622-
auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1623-
C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1624-
/*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1625-
NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1626-
NonTypeTemplateParm};
1627-
1628-
// template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1629-
return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1630-
Params, SourceLocation(), nullptr);
1631-
}
1632-
1633-
static TemplateParameterList *
1634-
createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1635-
// std::size_t Index
1636-
TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1637-
auto *Index = NonTypeTemplateParmDecl::Create(
1638-
C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1639-
/*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1640-
1641-
// typename ...T
1642-
auto *Ts = TemplateTypeParmDecl::Create(
1643-
C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1644-
/*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1645-
/*HasTypeConstraint=*/false);
1646-
Ts->setImplicit(true);
1647-
1648-
// template <std::size_t Index, typename ...T>
1649-
NamedDecl *Params[] = {Index, Ts};
1650-
return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1651-
llvm::ArrayRef(Params), SourceLocation(),
1652-
nullptr);
1653-
}
1654-
1655-
static TemplateParameterList *createBuiltinCommonTypeList(const ASTContext &C,
1656-
DeclContext *DC) {
1657-
// class... Args
1658-
auto *Args =
1659-
TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
1660-
/*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
1661-
/*Typename=*/false, /*ParameterPack=*/true);
1662-
1663-
// <class... Args>
1664-
auto *BaseTemplateList = TemplateParameterList::Create(
1665-
C, SourceLocation(), SourceLocation(), Args, SourceLocation(), nullptr);
1666-
1667-
// template <class... Args> class BaseTemplate
1668-
auto *BaseTemplate = TemplateTemplateParmDecl::Create(
1669-
C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1670-
/*ParameterPack=*/false, /*Id=*/nullptr,
1671-
/*Typename=*/false, BaseTemplateList);
1672-
1673-
// class TypeMember
1674-
auto *TypeMember =
1675-
TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
1676-
/*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
1677-
/*Typename=*/false, /*ParameterPack=*/false);
1678-
1679-
// <class TypeMember>
1680-
auto *HasTypeMemberList =
1681-
TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1682-
TypeMember, SourceLocation(), nullptr);
1683-
1684-
// template <class TypeMember> class HasTypeMember
1685-
auto *HasTypeMember = TemplateTemplateParmDecl::Create(
1686-
C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/1,
1687-
/*ParameterPack=*/false, /*Id=*/nullptr,
1688-
/*Typename=*/false, HasTypeMemberList);
1689-
1690-
// class HasNoTypeMember
1691-
auto *HasNoTypeMember = TemplateTypeParmDecl::Create(
1692-
C, DC, {}, {}, /*Depth=*/0, /*Position=*/2, /*Id=*/nullptr,
1693-
/*Typename=*/false, /*ParameterPack=*/false);
1694-
1695-
// class... Ts
1696-
auto *Ts = TemplateTypeParmDecl::Create(
1697-
C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/3,
1698-
/*Id=*/nullptr, /*Typename=*/false, /*ParameterPack=*/true);
1699-
1700-
// template <template <class... Args> class BaseTemplate,
1701-
// template <class TypeMember> class HasTypeMember, class HasNoTypeMember,
1702-
// class... Ts>
1703-
return TemplateParameterList::Create(
1704-
C, SourceLocation(), SourceLocation(),
1705-
{BaseTemplate, HasTypeMember, HasNoTypeMember, Ts}, SourceLocation(),
1706-
nullptr);
1707-
}
1708-
17091584
static TemplateParameterList *createBuiltinTemplateParameterList(
17101585
const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
17111586
switch (BTK) {
1712-
case BTK__make_integer_seq:
1713-
return createMakeIntegerSeqParameterList(C, DC);
1714-
case BTK__type_pack_element:
1715-
return createTypePackElementParameterList(C, DC);
1716-
case BTK__builtin_common_type:
1717-
return createBuiltinCommonTypeList(C, DC);
1587+
#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST
1588+
#include "clang/Basic/BuiltinTemplates.inc"
17181589
}
17191590

17201591
llvm_unreachable("unhandled BuiltinTemplateKind!");

clang/lib/Lex/PPMacroExpansion.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,10 +1831,9 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
18311831
return true;
18321832
} else {
18331833
return llvm::StringSwitch<bool>(II->getName())
1834-
// Report builtin templates as being builtins.
1835-
.Case("__make_integer_seq", getLangOpts().CPlusPlus)
1836-
.Case("__type_pack_element", getLangOpts().CPlusPlus)
1837-
.Case("__builtin_common_type", getLangOpts().CPlusPlus)
1834+
// Report builtin templates as being builtins.
1835+
#define BuiltinTemplate(BTName) .Case(#BTName, getLangOpts().CPlusPlus)
1836+
#include "clang/Basic/BuiltinTemplates.inc"
18381837
// Likewise for some builtin preprocessor macros.
18391838
// FIXME: This is inconsistent; we usually suggest detecting
18401839
// builtin macros via #ifdef. Don't add more cases here.

0 commit comments

Comments
 (0)