-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Clang] Add BuiltinTemplates.td to generate code for builtin templates #123736
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-modules Author: Nikolas Klauser (philnik777) ChangesThis makes it significantly easier to add new builtin templates, since you only have to modify two places instead of a dozen or so. The Patch is 30.36 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/123736.diff 16 Files Affected:
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 0e07c5d6ce8fba..eed257e4d92fff 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -410,11 +410,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// The identifier 'NSCopying'.
IdentifierInfo *NSCopyingName = nullptr;
- /// The identifier '__make_integer_seq'.
- mutable IdentifierInfo *MakeIntegerSeqName = nullptr;
- /// The identifier '__type_pack_element'.
- mutable IdentifierInfo *TypePackElementName = nullptr;
+#define BuiltinTemplate(BTName) mutable IdentifierInfo *Name##BTName = nullptr;
+#include "clang/Basic/BuiltinTemplates.inc"
/// The identifier '__builtin_common_type'.
mutable IdentifierInfo *BuiltinCommonTypeName = nullptr;
@@ -624,9 +622,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
TranslationUnitDecl *TUDecl = nullptr;
mutable ExternCContextDecl *ExternCContext = nullptr;
- mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr;
- mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr;
- mutable BuiltinTemplateDecl *BuiltinCommonTypeDecl = nullptr;
+
+#define BuiltinTemplate(Name) mutable BuiltinTemplateDecl *Decl##Name = nullptr;
+#include "clang/Basic/BuiltinTemplates.inc"
/// The associated SourceManager object.
SourceManager &SourceMgr;
@@ -1152,9 +1150,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
}
ExternCContextDecl *getExternCContextDecl() const;
- BuiltinTemplateDecl *getMakeIntegerSeqDecl() const;
- BuiltinTemplateDecl *getTypePackElementDecl() const;
- BuiltinTemplateDecl *getBuiltinCommonTypeDecl() const;
+
+#define BuiltinTemplate(Name) BuiltinTemplateDecl *get##Name##Decl() const;
+#include "clang/Basic/BuiltinTemplates.inc"
// Builtin Types.
CanQualType VoidTy;
@@ -2054,17 +2052,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
return BoolName;
}
- IdentifierInfo *getMakeIntegerSeqName() const {
- if (!MakeIntegerSeqName)
- MakeIntegerSeqName = &Idents.get("__make_integer_seq");
- return MakeIntegerSeqName;
- }
-
- IdentifierInfo *getTypePackElementName() const {
- if (!TypePackElementName)
- TypePackElementName = &Idents.get("__type_pack_element");
- return TypePackElementName;
+#define BuiltinTemplate(BTName) \
+ IdentifierInfo *get##BTName##Name() const { \
+ if (!Name##BTName) \
+ Name##BTName = &Idents.get(#BTName); \
+ return Name##BTName; \
}
+#include "clang/Basic/BuiltinTemplates.inc"
IdentifierInfo *getBuiltinCommonTypeName() const {
if (!BuiltinCommonTypeName)
diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h
index 49964b43c7d1d8..71e28ec1f9c65f 100644
--- a/clang/include/clang/AST/DeclID.h
+++ b/clang/include/clang/AST/DeclID.h
@@ -71,20 +71,14 @@ enum PredefinedDeclIDs {
/// The extern "C" context.
PREDEF_DECL_EXTERN_C_CONTEXT_ID,
- /// The internal '__make_integer_seq' template.
- PREDEF_DECL_MAKE_INTEGER_SEQ_ID,
-
/// The internal '__NSConstantString' typedef.
PREDEF_DECL_CF_CONSTANT_STRING_ID,
/// The internal '__NSConstantString' tag type.
PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID,
- /// The internal '__type_pack_element' template.
- PREDEF_DECL_TYPE_PACK_ELEMENT_ID,
-
- /// The internal '__builtin_common_type' template.
- PREDEF_DECL_COMMON_TYPE_ID,
+#define BuiltinTemplate(Name) PREDEF_DECL##Name##_ID,
+#include "clang/Basic/BuiltinTemplates.inc"
/// The number of declaration IDs that are predefined.
NUM_PREDEF_DECL_IDS
diff --git a/clang/include/clang/Basic/BuiltinTemplates.td b/clang/include/clang/Basic/BuiltinTemplates.td
new file mode 100644
index 00000000000000..3d51088e0bccaf
--- /dev/null
+++ b/clang/include/clang/Basic/BuiltinTemplates.td
@@ -0,0 +1,23 @@
+//===--- BuiltinTemplates.td - Clang builtin template aliases ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+class BuiltinTemplate<string prototype> {
+ string Prototype = prototype;
+}
+
+def __make_integer_seq : BuiltinTemplate<
+ "template <template <class T, T... Ints> class IntSeq, class T, T N>">;
+
+def __type_pack_element : BuiltinTemplate<
+ "template <size_t, class... T>">;
+
+def __builtin_common_type : BuiltinTemplate<
+ "template <template <class... Args> class BaseTemplate,"
+ " template <class TypeMember> class HasTypeMember,"
+ " class HasNoTypeMember,"
+ " class... Ts>">;
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index 63559d977ce6b6..eef96f35095a88 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -306,14 +306,8 @@ bool evaluateRequiredTargetFeatures(
/// Kinds of BuiltinTemplateDecl.
enum BuiltinTemplateKind : int {
- /// This names the __make_integer_seq BuiltinTemplateDecl.
- BTK__make_integer_seq,
-
- /// This names the __type_pack_element BuiltinTemplateDecl.
- BTK__type_pack_element,
-
- /// This names the __builtin_common_type BuiltinTemplateDecl.
- BTK__builtin_common_type,
+#define BuiltinTemplate(Name) BTK##Name,
+#include "clang/Basic/BuiltinTemplates.inc"
};
} // end namespace clang
diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt
index 56c27bacdb20b8..3fe6d8985b32d8 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -77,6 +77,10 @@ clang_tablegen(BuiltinsX86_64.inc -gen-clang-builtins
SOURCE BuiltinsX86_64.td
TARGET ClangBuiltinsX86_64)
+clang_tablegen(BuiltinTemplates.inc -gen-clang-builtin-templates
+ SOURCE BuiltinTemplates.td
+ TARGET ClangBuiltinTemplates)
+
# ARM NEON and MVE
clang_tablegen(arm_neon.inc -gen-arm-neon-sema
SOURCE arm_neon.td
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index be1dd29d462788..288135e47fc39c 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1195,28 +1195,14 @@ ASTContext::buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
return BuiltinTemplate;
}
-BuiltinTemplateDecl *
-ASTContext::getMakeIntegerSeqDecl() const {
- if (!MakeIntegerSeqDecl)
- MakeIntegerSeqDecl = buildBuiltinTemplateDecl(BTK__make_integer_seq,
- getMakeIntegerSeqName());
- return MakeIntegerSeqDecl;
-}
-
-BuiltinTemplateDecl *
-ASTContext::getTypePackElementDecl() const {
- if (!TypePackElementDecl)
- TypePackElementDecl = buildBuiltinTemplateDecl(BTK__type_pack_element,
- getTypePackElementName());
- return TypePackElementDecl;
-}
-
-BuiltinTemplateDecl *ASTContext::getBuiltinCommonTypeDecl() const {
- if (!BuiltinCommonTypeDecl)
- BuiltinCommonTypeDecl = buildBuiltinTemplateDecl(
- BTK__builtin_common_type, getBuiltinCommonTypeName());
- return BuiltinCommonTypeDecl;
-}
+#define BuiltinTemplate(BTName) \
+ BuiltinTemplateDecl *ASTContext::get##BTName##Decl() const { \
+ if (!Decl##BTName) \
+ Decl##BTName = \
+ buildBuiltinTemplateDecl(BTK##BTName, get##BTName##Name()); \
+ return Decl##BTName; \
+ }
+#include "clang/Basic/BuiltinTemplates.inc"
RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,
RecordDecl::TagKind TK) const {
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 0669aa1b809c34..f63e017c33a002 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -5461,15 +5461,11 @@ ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
ExpectedDecl ASTNodeImporter::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
Decl* ToD = nullptr;
switch (D->getBuiltinTemplateKind()) {
- case BuiltinTemplateKind::BTK__make_integer_seq:
- ToD = Importer.getToContext().getMakeIntegerSeqDecl();
- break;
- case BuiltinTemplateKind::BTK__type_pack_element:
- ToD = Importer.getToContext().getTypePackElementDecl();
- break;
- case BuiltinTemplateKind::BTK__builtin_common_type:
- ToD = Importer.getToContext().getBuiltinCommonTypeDecl();
+#define BuiltinTemplate(Name) \
+ case BuiltinTemplateKind::BTK##Name: \
+ ToD = Importer.getToContext().get##Name##Decl(); \
break;
+#include "clang/Basic/BuiltinTemplates.inc"
}
assert(ToD && "BuiltinTemplateDecl of unsupported kind!");
Importer.MapImported(D, ToD);
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 40ee3753c24227..de060dc612c317 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -1571,140 +1571,11 @@ SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
return Range;
}
-static TemplateParameterList *
-createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
- // typename T
- auto *T = TemplateTypeParmDecl::Create(
- C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
- /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
- /*HasTypeConstraint=*/false);
- T->setImplicit(true);
-
- // T ...Ints
- TypeSourceInfo *TI =
- C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
- auto *N = NonTypeTemplateParmDecl::Create(
- C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
- /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
- N->setImplicit(true);
-
- // <typename T, T ...Ints>
- NamedDecl *P[2] = {T, N};
- auto *TPL = TemplateParameterList::Create(
- C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
-
- // template <typename T, ...Ints> class IntSeq
- auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
- C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
- /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL);
- TemplateTemplateParm->setImplicit(true);
-
- // typename T
- auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
- C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
- /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
- /*HasTypeConstraint=*/false);
- TemplateTypeParm->setImplicit(true);
-
- // T N
- TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
- QualType(TemplateTypeParm->getTypeForDecl(), 0));
- auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
- C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
- /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
- NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
- NonTypeTemplateParm};
-
- // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
- return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
- Params, SourceLocation(), nullptr);
-}
-
-static TemplateParameterList *
-createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
- // std::size_t Index
- TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
- auto *Index = NonTypeTemplateParmDecl::Create(
- C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
- /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
-
- // typename ...T
- auto *Ts = TemplateTypeParmDecl::Create(
- C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
- /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
- /*HasTypeConstraint=*/false);
- Ts->setImplicit(true);
-
- // template <std::size_t Index, typename ...T>
- NamedDecl *Params[] = {Index, Ts};
- return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
- llvm::ArrayRef(Params), SourceLocation(),
- nullptr);
-}
-
-static TemplateParameterList *createBuiltinCommonTypeList(const ASTContext &C,
- DeclContext *DC) {
- // class... Args
- auto *Args =
- TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
- /*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
- /*Typename=*/false, /*ParameterPack=*/true);
-
- // <class... Args>
- auto *BaseTemplateList = TemplateParameterList::Create(
- C, SourceLocation(), SourceLocation(), Args, SourceLocation(), nullptr);
-
- // template <class... Args> class BaseTemplate
- auto *BaseTemplate = TemplateTemplateParmDecl::Create(
- C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
- /*ParameterPack=*/false, /*Id=*/nullptr,
- /*Typename=*/false, BaseTemplateList);
-
- // class TypeMember
- auto *TypeMember =
- TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
- /*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
- /*Typename=*/false, /*ParameterPack=*/false);
-
- // <class TypeMember>
- auto *HasTypeMemberList =
- TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
- TypeMember, SourceLocation(), nullptr);
-
- // template <class TypeMember> class HasTypeMember
- auto *HasTypeMember = TemplateTemplateParmDecl::Create(
- C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/1,
- /*ParameterPack=*/false, /*Id=*/nullptr,
- /*Typename=*/false, HasTypeMemberList);
-
- // class HasNoTypeMember
- auto *HasNoTypeMember = TemplateTypeParmDecl::Create(
- C, DC, {}, {}, /*Depth=*/0, /*Position=*/2, /*Id=*/nullptr,
- /*Typename=*/false, /*ParameterPack=*/false);
-
- // class... Ts
- auto *Ts = TemplateTypeParmDecl::Create(
- C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/3,
- /*Id=*/nullptr, /*Typename=*/false, /*ParameterPack=*/true);
-
- // template <template <class... Args> class BaseTemplate,
- // template <class TypeMember> class HasTypeMember, class HasNoTypeMember,
- // class... Ts>
- return TemplateParameterList::Create(
- C, SourceLocation(), SourceLocation(),
- {BaseTemplate, HasTypeMember, HasNoTypeMember, Ts}, SourceLocation(),
- nullptr);
-}
-
static TemplateParameterList *createBuiltinTemplateParameterList(
const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
switch (BTK) {
- case BTK__make_integer_seq:
- return createMakeIntegerSeqParameterList(C, DC);
- case BTK__type_pack_element:
- return createTypePackElementParameterList(C, DC);
- case BTK__builtin_common_type:
- return createBuiltinCommonTypeList(C, DC);
+#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST
+#include "clang/Basic/BuiltinTemplates.inc"
}
llvm_unreachable("unhandled BuiltinTemplateKind!");
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 347c13da0ad215..fdbf53b9a623a6 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1831,9 +1831,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
} else {
return llvm::StringSwitch<bool>(II->getName())
// Report builtin templates as being builtins.
- .Case("__make_integer_seq", getLangOpts().CPlusPlus)
- .Case("__type_pack_element", getLangOpts().CPlusPlus)
- .Case("__builtin_common_type", getLangOpts().CPlusPlus)
+#define BuiltinTemplate(BTName) .Case(#BTName, getLangOpts().CPlusPlus)
+#include "clang/Basic/BuiltinTemplates.inc"
// Likewise for some builtin preprocessor macros.
// FIXME: This is inconsistent; we usually suggest detecting
// builtin macros via #ifdef. Don't add more cases here.
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index e1171d4284c763..abfb0569b5c4ff 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -924,18 +924,12 @@ bool Sema::LookupBuiltin(LookupResult &R) {
IdentifierInfo *II = R.getLookupName().getAsIdentifierInfo();
if (II) {
if (getLangOpts().CPlusPlus && NameKind == Sema::LookupOrdinaryName) {
- if (II == getASTContext().getMakeIntegerSeqName()) {
- R.addDecl(getASTContext().getMakeIntegerSeqDecl());
- return true;
- }
- if (II == getASTContext().getTypePackElementName()) {
- R.addDecl(getASTContext().getTypePackElementDecl());
- return true;
- }
- if (II == getASTContext().getBuiltinCommonTypeName()) {
- R.addDecl(getASTContext().getBuiltinCommonTypeDecl());
- return true;
- }
+#define BuiltinTemplate(BIName) \
+ if (II == getASTContext().get##BIName##Name()) { \
+ R.addDecl(getASTContext().get##BIName##Decl()); \
+ return true; \
+ }
+#include "clang/Basic/BuiltinTemplates.inc"
}
// Check if this is an OpenCL Builtin, and if so, insert its overloads.
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 7361cace49dd7b..f19f71d1482970 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -8005,12 +8005,6 @@ Decl *ASTReader::getPredefinedDecl(PredefinedDeclIDs ID) {
NewLoaded = Context.getExternCContextDecl();
break;
- case PREDEF_DECL_MAKE_INTEGER_SEQ_ID:
- if (Context.MakeIntegerSeqDecl)
- return Context.MakeIntegerSeqDecl;
- NewLoaded = Context.getMakeIntegerSeqDecl();
- break;
-
case PREDEF_DECL_CF_CONSTANT_STRING_ID:
if (Context.CFConstantStringTypeDecl)
return Context.CFConstantStringTypeDecl;
@@ -8023,17 +8017,13 @@ Decl *ASTReader::getPredefinedDecl(PredefinedDeclIDs ID) {
NewLoaded = Context.getCFConstantStringTagDecl();
break;
- case PREDEF_DECL_TYPE_PACK_ELEMENT_ID:
- if (Context.TypePackElementDecl)
- return Context.TypePackElementDecl;
- NewLoaded = Context.getTypePackElementDecl();
- break;
-
- case PREDEF_DECL_COMMON_TYPE_ID:
- if (Context.BuiltinCommonTypeDecl)
- return Context.BuiltinCommonTypeDecl;
- NewLoaded = Context.getBuiltinCommonTypeDecl();
+#define BuiltinTemplate(Name) \
+ case PREDEF_DECL##Name##_ID: \
+ if (Context.Decl##Name) \
+ return Context.Decl##Name; \
+ NewLoaded = Context.get##Name##Decl(); \
break;
+#include "clang/Basic/BuiltinTemplates.inc"
case NUM_PREDEF_DECL_IDS:
llvm_unreachable("Invalid decl ID");
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 0ae2157eed4ecc..c21586f79fef01 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5292,15 +5292,13 @@ void ASTWriter::PrepareWritingSpecialDecls(Sema &SemaRef) {
RegisterPredefDecl(Context.MSGuidTagDecl,
PREDEF_DECL_BUILTIN_MS_GUID_ID);
RegisterPredefDecl(Context.ExternCContext, PREDEF_DECL_EXTERN_C_CONTEXT_ID);
- RegisterPredefDecl(Context.MakeIntegerSeqDecl,
- PREDEF_DECL_MAKE_INTEGER_SEQ_ID);
RegisterPredefDecl(Context.CFCon...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff c25bd6e35134f591ee7dfeb4494df02987106f7e 417b15f8e28625e696c4254d20626034e79736b8 --extensions h,cpp -- clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp clang/include/clang/AST/ASTContext.h clang/include/clang/AST/DeclID.h clang/include/clang/Basic/Builtins.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ASTImporter.cpp clang/lib/AST/DeclTemplate.cpp clang/lib/Lex/PPMacroExpansion.cpp clang/lib/Sema/SemaLookup.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/utils/TableGen/TableGen.cpp clang/utils/TableGen/TableGenBackends.h View the diff from clang-format here.diff --git a/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
index 2c3b3cc9a6..f5ec77e3a2 100644
--- a/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
+++ b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
@@ -150,8 +150,7 @@ void EmitCreateBuiltinTemplateParameterList(StringRef TemplateHead,
CreateBuiltinTemplateParameterList +=
"case BTK"s + std::string{Name} + ": {\n"s;
if (!TemplateHead.consume_front("template"))
- PrintFatalError(
- "Expected template head to start with 'template' keyword");
+ PrintFatalError("Expected template head to start with 'template' keyword");
ParserState PS;
auto [Code, TPLName] = ParseTemplateParameterList(PS, TemplateHead);
|
ae765ca
to
586dd4e
Compare
} | ||
|
||
def __make_integer_seq : BuiltinTemplate< | ||
"template <template <class T, T... Ints> class IntSeq, class T, T N>">; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its unfortunate that we have this much "just arbitrary text" here. I don't have a better idea, and no real wish to try to make it 'better', but this makes me grumpy and I wanted to let you know.
ALSO, and something that IS actionable: Can we document the importance of the defined 'name'? Since it is the actual name of the builtin that we're exposing to the user? Typically these (names in .td files) are internal names that are generally arbitrary, so it would be nice to document that:
"An entry here will introduce a template builtin with the name X, and whatever-else-we-are-doing-here."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it would be better to give the templates an internal name to be more consistent?
|
||
std::pair<std::string, std::string> | ||
ParseTemplateParameterList(ParserState &PS, StringRef &TemplateParmList) { | ||
auto Alphabetic = [](char c) { return std::isalpha(c); }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof, a re-implemented template head parser is REALLY scary here to me. I think I now AM more than just grumpy here, and wish we could do a better 'list' of template args/interface for them instead of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m not familiar w/ every last thing that would go into that, but can we maybe literally just use the actual parser for this?
As in, this might be a stupid idea, but would it be feasible to just throw this as source text at the start of the translation unit and then parse it, maybe w/ something like a [[clang::__builtin_template__]]
attribute?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@erichkeane Do you have any better idea how to represent this? I could represent as something like
def __make_integer_seq : BuiltinTemplate<Template<[Class<"T">, NTTP<"T", "Ints", /*variadic*/true>], "IntSeq">, Class<"T">, NTTP<"T", "N">>;
But that's really hard to read IMO.
@Sirraide With an attribute we'd still have to verify that the parsed template actually represents the template, since users would be able to declare templates with an attribute, so we'd be back at square one AFAICT. It would also mean introducing code into every single translation unit, which would probably increase the startup time of clang.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that's really hard to read IMO.
Yeah that’s really verbose... which is why my line of thought was that we literally have an entire C++ compiler, so it’d be nice if we could just write actual C++.
since users would be able to declare templates with an attribute
Sure, but if someone thinks that using an attribute called __builtin_template__
in their own code is a good idea then that’s on them candidly (we could just straight-up error if it’s defined in an actual file supplied by the user). Also, my idea was to maybe only expose the spelling w/ the double underscore to make it clearer that it’s for use by the implementation only, but that may not be necessary if we make it an error.
I’m not sure this approach would really be simpler or anything like that, but it might be worth it (if it’s feasible at all, that is), provided that the number of builtin templates continues to grow in the future. I feel like some sort of ‘preamble’ that gets prepended to every TU might be a useful thing to have in general.
It would also mean introducing code into every single translation unit, which would probably increase the startup time of clang.
I mean, these are all fairly small template declarations and user code routinely has tons of much larger templates, so I don’t think this will be too noticeable. ;Þ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(For the record though, if my suggested approach sounds like ‘too much compiler magic’, then the tablegen approach is fine too imo; either way is better than manually building AST nodes for template parameters ;Þ)
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.