[clang] [Clang] Add BuiltinTemplates.td to generate code for builtin templates (PR #123736)
Nikolas Klauser via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 20 00:12:37 PST 2025
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/123736
>From 586dd4edfc79c88cc1583b64d186c1481fbd6ce1 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 4 Sep 2024 13:31:39 +0200
Subject: [PATCH 1/7] [Clang] Add BuiltinTemplates.td to generate code for
builtin templates
---
clang/include/clang/AST/ASTContext.h | 35 ++--
clang/include/clang/AST/DeclID.h | 10 +-
clang/include/clang/Basic/BuiltinTemplates.td | 23 +++
clang/include/clang/Basic/Builtins.h | 10 +-
clang/include/clang/Basic/CMakeLists.txt | 4 +
clang/lib/AST/ASTContext.cpp | 30 +--
clang/lib/AST/ASTImporter.cpp | 12 +-
clang/lib/AST/DeclTemplate.cpp | 133 +------------
clang/lib/Lex/PPMacroExpansion.cpp | 5 +-
clang/lib/Sema/SemaLookup.cpp | 18 +-
clang/lib/Serialization/ASTReader.cpp | 22 +--
clang/lib/Serialization/ASTWriter.cpp | 8 +-
clang/utils/TableGen/CMakeLists.txt | 1 +
.../TableGen/ClangBuiltinTemplatesEmitter.cpp | 184 ++++++++++++++++++
clang/utils/TableGen/TableGen.cpp | 6 +
clang/utils/TableGen/TableGenBackends.h | 2 +
16 files changed, 269 insertions(+), 234 deletions(-)
create mode 100644 clang/include/clang/Basic/BuiltinTemplates.td
create mode 100644 clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 0e07c5d6ce8fb..98db5522d564e 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -410,11 +410,8 @@ 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 +621,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 +1149,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 +2051,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 49964b43c7d1d..71e28ec1f9c65 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 0000000000000..3d51088e0bcca
--- /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 63559d977ce6b..eef96f35095a8 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 56c27bacdb20b..3fe6d8985b32d 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 be1dd29d46278..288135e47fc39 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 0669aa1b809c3..f63e017c33a00 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 40ee3753c2422..de060dc612c31 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 347c13da0ad21..fdbf53b9a623a 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 e1171d4284c76..abfb0569b5c4f 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 7361cace49dd7..f19f71d148297 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 0ae2157eed4ec..c21586f79fef0 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.CFConstantStringTypeDecl,
PREDEF_DECL_CF_CONSTANT_STRING_ID);
RegisterPredefDecl(Context.CFConstantStringTagDecl,
PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID);
- RegisterPredefDecl(Context.TypePackElementDecl,
- PREDEF_DECL_TYPE_PACK_ELEMENT_ID);
- RegisterPredefDecl(Context.BuiltinCommonTypeDecl, PREDEF_DECL_COMMON_TYPE_ID);
+#define BuiltinTemplate(Name) \
+ RegisterPredefDecl(Context.Decl##Name, PREDEF_DECL##Name##_ID);
+#include "clang/Basic/BuiltinTemplates.inc"
const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
diff --git a/clang/utils/TableGen/CMakeLists.txt b/clang/utils/TableGen/CMakeLists.txt
index 5b072a1ac1969..ce759ec8548d9 100644
--- a/clang/utils/TableGen/CMakeLists.txt
+++ b/clang/utils/TableGen/CMakeLists.txt
@@ -8,6 +8,7 @@ add_tablegen(clang-tblgen CLANG
ClangASTPropertiesEmitter.cpp
ClangAttrEmitter.cpp
ClangBuiltinsEmitter.cpp
+ ClangBuiltinTemplatesEmitter.cpp
ClangCommentCommandInfoEmitter.cpp
ClangCommentHTMLNamedCharacterReferenceEmitter.cpp
ClangCommentHTMLTagsEmitter.cpp
diff --git a/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
new file mode 100644
index 0000000000000..8e6d1dbaddea9
--- /dev/null
+++ b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
@@ -0,0 +1,184 @@
+//=- ClangBuiltinsEmitter.cpp - Generate Clang builtin templates-*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits Clang's builtin templates.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TableGenBackends.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/TableGenBackend.h"
+
+using namespace llvm;
+
+std::string TemplateNameList;
+std::string CreateBuiltinTemplateParameterList;
+
+namespace {
+struct ParserState {
+ size_t UniqueCounter = 0;
+ size_t CurrentDepth = 0;
+ bool EmittedSizeTInfo = false;
+};
+
+std::pair<std::string, std::string>
+ParseTemplateParameterList(ParserState &PS, StringRef &TemplateParmList) {
+ auto Alphabetic = [](char c) { return std::isalpha(c); };
+ auto BoolToStr = [](bool b) { return b ? "true" : "false"; };
+
+ std::string Generator;
+ std::vector<std::string> Params;
+ std::unordered_map<std::string, std::string> TemplateNameToParmName;
+ TemplateParmList = TemplateParmList.ltrim();
+ if (!TemplateParmList.consume_front("<"))
+ PrintFatalError("Expected '<' to start the parameter list");
+
+ size_t Position = 0;
+ while (true) {
+ std::string ParmName = "Parm" + std::to_string(PS.UniqueCounter++);
+ if (TemplateParmList.consume_front("size_t")) {
+ if (!PS.EmittedSizeTInfo) {
+ PS.EmittedSizeTInfo = true;
+ Generator += R"C++(
+ TypeSourceInfo *SizeTInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
+)C++";
+ }
+
+ Generator += " auto *" + ParmName + R"C++(
+ = NonTypeTemplateParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
+ )C++" + std::to_string(PS.CurrentDepth) +
+ ", " + std::to_string(Position++) + R"C++(, /*Id=*/nullptr,
+ SizeTInfo->getType(), /*ParameterPack=*/false, SizeTInfo);
+)C++";
+ } else if (TemplateParmList.consume_front("class")) {
+ bool ParameterPack = TemplateParmList.consume_front("...");
+
+ Generator += " auto *" + ParmName + R"C++(
+ = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
+ )C++" + std::to_string(PS.CurrentDepth) +
+ ", " + std::to_string(Position++) +
+ R"C++(, /*Id=*/nullptr, /*Typename=*/false, )C++" +
+ BoolToStr(ParameterPack) + ");\n";
+ } else if (TemplateParmList.consume_front("template")) {
+ ++PS.CurrentDepth;
+ auto [Code, TPLName] = ParseTemplateParameterList(PS, TemplateParmList);
+ --PS.CurrentDepth;
+ TemplateParmList = TemplateParmList.ltrim();
+ if (!TemplateParmList.consume_front("class")) {
+ PrintFatalError("Expected 'class' after template template list");
+ }
+ Generator += Code;
+ Generator +=
+ " auto *" + ParmName + R"C++(
+ = TemplateTemplateParmDecl::Create(C, DC, SourceLocation(), )C++" +
+ std::to_string(PS.CurrentDepth) + ", " + std::to_string(Position++) +
+ ", /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, " +
+ TPLName + ");\n";
+ } else {
+ auto Name = TemplateParmList.take_while(Alphabetic).str();
+ if (TemplateNameToParmName.find(Name) != TemplateNameToParmName.end()) {
+ TemplateParmList = TemplateParmList.drop_front(Name.size());
+ bool ParameterPack = TemplateParmList.consume_front("...");
+
+ auto TSIName = "TSI" + std::to_string(PS.UniqueCounter++);
+ Generator += " auto *" + TSIName + R"C++(
+ = C.getTrivialTypeSourceInfo(QualType()C++" +
+ TemplateNameToParmName[Name] +
+ R"C++(->getTypeForDecl(), 0));
+ auto *)C++" + ParmName +
+ R"C++( = NonTypeTemplateParmDecl::Create(
+ C, DC, SourceLocation(), SourceLocation(), )C++" +
+ std::to_string(PS.CurrentDepth) + ", " +
+ std::to_string(Position++) + ", /*Id=*/nullptr, " +
+ TSIName + "->getType(), " + BoolToStr(ParameterPack) +
+ ", " + TSIName + ");\n";
+ } else {
+ PrintFatalError("Unknown argument");
+ }
+ }
+ TemplateParmList = TemplateParmList.ltrim();
+ auto ID = TemplateParmList.take_while(Alphabetic);
+ if (!ID.empty()) {
+ TemplateNameToParmName[ID.str()] = ParmName;
+ TemplateParmList = TemplateParmList.drop_front(ID.size());
+ }
+
+ Params.emplace_back(std::move(ParmName));
+
+ if (!TemplateParmList.consume_front(","))
+ break;
+ TemplateParmList = TemplateParmList.ltrim();
+ }
+
+ if (!TemplateParmList.consume_front(">")) {
+ PrintWarning("Expected '>' to close template parameter list");
+ PrintWarning(TemplateParmList);
+ }
+
+ auto TPLName = "TPL" + std::to_string(PS.UniqueCounter++);
+ Generator += " auto *" + TPLName + R"C++( = TemplateParameterList::Create(
+ C, SourceLocation(), SourceLocation(), {)C++";
+
+ if (Params.empty())
+ PrintFatalError(
+ "Expected at least one argument in template parameter list");
+
+ bool First = true;
+ for (auto e : Params) {
+ if (First) {
+ First = false;
+ Generator += e;
+ } else {
+ Generator += ", " + e;
+ }
+ }
+ Generator += "}, SourceLocation(), nullptr);\n";
+
+ return {std::move(Generator), std::move(TPLName)};
+}
+
+void EmitCreateBuiltinTemplateParameterList(StringRef Prototype,
+ StringRef Name) {
+ using namespace std::string_literals;
+ CreateBuiltinTemplateParameterList +=
+ "case BTK"s + std::string{Name} + ": {\n"s;
+ if (!Prototype.consume_front("template"))
+ PrintFatalError(
+ "Expected template prototype to start with 'template' keyword");
+
+ ParserState PS;
+ auto [Code, TPLName] = ParseTemplateParameterList(PS, Prototype);
+ CreateBuiltinTemplateParameterList += Code + "\n return " + TPLName + ";\n";
+
+ CreateBuiltinTemplateParameterList += " }\n";
+}
+
+void EmitBuiltinTemplate(raw_ostream &OS, const Record *BuiltinTemplate) {
+ auto Prototype = BuiltinTemplate->getValueAsString("Prototype");
+ auto Name = BuiltinTemplate->getName();
+
+ EmitCreateBuiltinTemplateParameterList(Prototype, Name);
+
+ TemplateNameList += "BuiltinTemplate(";
+ TemplateNameList += Name;
+ TemplateNameList += ")\n";
+}
+} // namespace
+
+void clang::EmitClangBuiltinTemplates(const llvm::RecordKeeper &Records,
+ llvm::raw_ostream &OS) {
+ emitSourceFileHeader("Tables and code for Clang's builtin templates", OS);
+ for (const auto *Builtin :
+ Records.getAllDerivedDefinitions("BuiltinTemplate"))
+ EmitBuiltinTemplate(OS, Builtin);
+
+ OS << "#if defined(CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST)\n"
+ << CreateBuiltinTemplateParameterList
+ << "#undef CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST\n#else\n"
+ << TemplateNameList << "#undef BuiltinTemplate\n#endif\n";
+}
diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp
index 8b8eadbe7f7e5..e526ff9640c51 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -47,6 +47,7 @@ enum ActionType {
GenClangBasicReader,
GenClangBasicWriter,
GenClangBuiltins,
+ GenClangBuiltinTemplates,
GenClangDiagsDefs,
GenClangDiagsEnums,
GenClangDiagGroups,
@@ -172,6 +173,8 @@ cl::opt<ActionType> Action(
"Generate clang attribute traverser"),
clEnumValN(GenClangBuiltins, "gen-clang-builtins",
"Generate clang builtins list"),
+ clEnumValN(GenClangBuiltinTemplates, "gen-clang-builtin-templates",
+ "Generate clang builtins list"),
clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs",
"Generate Clang diagnostics definitions"),
clEnumValN(GenClangDiagsEnums, "gen-clang-diags-enums",
@@ -387,6 +390,9 @@ bool ClangTableGenMain(raw_ostream &OS, const RecordKeeper &Records) {
case GenClangBuiltins:
EmitClangBuiltins(Records, OS);
break;
+ case GenClangBuiltinTemplates:
+ EmitClangBuiltinTemplates(Records, OS);
+ break;
case GenClangDiagsDefs:
EmitClangDiagsDefs(Records, OS, ClangComponent);
break;
diff --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h
index 0448c94de08e3..cc58489180ba5 100644
--- a/clang/utils/TableGen/TableGenBackends.h
+++ b/clang/utils/TableGen/TableGenBackends.h
@@ -86,6 +86,8 @@ void EmitClangAttrDocTable(const llvm::RecordKeeper &Records,
void EmitClangBuiltins(const llvm::RecordKeeper &Records,
llvm::raw_ostream &OS);
+void EmitClangBuiltinTemplates(const llvm::RecordKeeper &Records,
+ llvm::raw_ostream &OS);
void EmitClangDiagsDefs(const llvm::RecordKeeper &Records,
llvm::raw_ostream &OS, const std::string &Component);
>From dc4232eab5fb22d8e7e25f4beb1895d067b05cb5 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 25 Jan 2025 11:02:04 +0100
Subject: [PATCH 2/7] Use BTName everywhere
---
clang/include/clang/AST/ASTContext.h | 8 +++-----
clang/include/clang/AST/DeclID.h | 2 +-
clang/include/clang/Basic/Builtins.h | 2 +-
clang/lib/AST/ASTImporter.cpp | 6 +++---
clang/lib/Serialization/ASTReader.cpp | 10 +++++-----
clang/lib/Serialization/ASTWriter.cpp | 4 ++--
6 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 98db5522d564e..f8cef3b86046d 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -413,9 +413,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
#define BuiltinTemplate(BTName) mutable IdentifierInfo *Name##BTName = nullptr;
#include "clang/Basic/BuiltinTemplates.inc"
- /// The identifier '__builtin_common_type'.
- mutable IdentifierInfo *BuiltinCommonTypeName = nullptr;
-
QualType ObjCConstantStringType;
mutable RecordDecl *CFConstantStringTagDecl = nullptr;
mutable TypedefDecl *CFConstantStringTypeDecl = nullptr;
@@ -622,7 +619,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
TranslationUnitDecl *TUDecl = nullptr;
mutable ExternCContextDecl *ExternCContext = nullptr;
-#define BuiltinTemplate(Name) mutable BuiltinTemplateDecl *Decl##Name = nullptr;
+#define BuiltinTemplate(BTName) \
+ mutable BuiltinTemplateDecl *Decl##BTName = nullptr;
#include "clang/Basic/BuiltinTemplates.inc"
/// The associated SourceManager object.
@@ -1150,7 +1148,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
ExternCContextDecl *getExternCContextDecl() const;
-#define BuiltinTemplate(Name) BuiltinTemplateDecl *get##Name##Decl() const;
+#define BuiltinTemplate(BTName) BuiltinTemplateDecl *get##BTName##Decl() const;
#include "clang/Basic/BuiltinTemplates.inc"
// Builtin Types.
diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h
index 71e28ec1f9c65..384f7b031e007 100644
--- a/clang/include/clang/AST/DeclID.h
+++ b/clang/include/clang/AST/DeclID.h
@@ -77,7 +77,7 @@ enum PredefinedDeclIDs {
/// The internal '__NSConstantString' tag type.
PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID,
-#define BuiltinTemplate(Name) PREDEF_DECL##Name##_ID,
+#define BuiltinTemplate(BTName) PREDEF_DECL##BTName##_ID,
#include "clang/Basic/BuiltinTemplates.inc"
/// The number of declaration IDs that are predefined.
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index eef96f35095a8..fd9b3c942b36f 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -306,7 +306,7 @@ bool evaluateRequiredTargetFeatures(
/// Kinds of BuiltinTemplateDecl.
enum BuiltinTemplateKind : int {
-#define BuiltinTemplate(Name) BTK##Name,
+#define BuiltinTemplate(BTName) BTK##BTName,
#include "clang/Basic/BuiltinTemplates.inc"
};
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index f63e017c33a00..64fe18cf3434c 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -5461,9 +5461,9 @@ ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
ExpectedDecl ASTNodeImporter::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
Decl* ToD = nullptr;
switch (D->getBuiltinTemplateKind()) {
-#define BuiltinTemplate(Name) \
- case BuiltinTemplateKind::BTK##Name: \
- ToD = Importer.getToContext().get##Name##Decl(); \
+#define BuiltinTemplate(BTName) \
+ case BuiltinTemplateKind::BTK##BTName: \
+ ToD = Importer.getToContext().get##BTName##Decl(); \
break;
#include "clang/Basic/BuiltinTemplates.inc"
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index f19f71d148297..3d251b242961f 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -8017,11 +8017,11 @@ Decl *ASTReader::getPredefinedDecl(PredefinedDeclIDs ID) {
NewLoaded = Context.getCFConstantStringTagDecl();
break;
-#define BuiltinTemplate(Name) \
- case PREDEF_DECL##Name##_ID: \
- if (Context.Decl##Name) \
- return Context.Decl##Name; \
- NewLoaded = Context.get##Name##Decl(); \
+#define BuiltinTemplate(BTName) \
+ case PREDEF_DECL##BTName##_ID: \
+ if (Context.Decl##BTName) \
+ return Context.Decl##BTName; \
+ NewLoaded = Context.get##BTName##Decl(); \
break;
#include "clang/Basic/BuiltinTemplates.inc"
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index c21586f79fef0..e0333663bf8bd 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5296,8 +5296,8 @@ void ASTWriter::PrepareWritingSpecialDecls(Sema &SemaRef) {
PREDEF_DECL_CF_CONSTANT_STRING_ID);
RegisterPredefDecl(Context.CFConstantStringTagDecl,
PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID);
-#define BuiltinTemplate(Name) \
- RegisterPredefDecl(Context.Decl##Name, PREDEF_DECL##Name##_ID);
+#define BuiltinTemplate(BTName) \
+ RegisterPredefDecl(Context.Decl##BTName, PREDEF_DECL##BTName##_ID);
#include "clang/Basic/BuiltinTemplates.inc"
const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
>From 86111211f879b816929b1988def4c858c4ab011d Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 25 Jan 2025 12:03:54 +0100
Subject: [PATCH 3/7] Use stringstream
---
clang/include/clang/AST/ASTContext.h | 6 --
.../TableGen/ClangBuiltinTemplatesEmitter.cpp | 74 ++++++++++---------
2 files changed, 38 insertions(+), 42 deletions(-)
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index f8cef3b86046d..d03dc9e28eae7 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -2057,12 +2057,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
}
#include "clang/Basic/BuiltinTemplates.inc"
- IdentifierInfo *getBuiltinCommonTypeName() const {
- if (!BuiltinCommonTypeName)
- BuiltinCommonTypeName = &Idents.get("__builtin_common_type");
- return BuiltinCommonTypeName;
- }
-
/// Retrieve the Objective-C "instancetype" type, if already known;
/// otherwise, returns a NULL type;
QualType getObjCInstanceType() {
diff --git a/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
index 8e6d1dbaddea9..aa13473a69acc 100644
--- a/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
+++ b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
@@ -14,10 +14,12 @@
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/TableGenBackend.h"
+#include <sstream>
+
using namespace llvm;
-std::string TemplateNameList;
-std::string CreateBuiltinTemplateParameterList;
+static std::string TemplateNameList;
+static std::string CreateBuiltinTemplateParameterList;
namespace {
struct ParserState {
@@ -29,9 +31,9 @@ struct ParserState {
std::pair<std::string, std::string>
ParseTemplateParameterList(ParserState &PS, StringRef &TemplateParmList) {
auto Alphabetic = [](char c) { return std::isalpha(c); };
- auto BoolToStr = [](bool b) { return b ? "true" : "false"; };
- std::string Generator;
+ std::ostringstream Generator;
+ Generator << std::boolalpha;
std::vector<std::string> Params;
std::unordered_map<std::string, std::string> TemplateNameToParmName;
TemplateParmList = TemplateParmList.ltrim();
@@ -44,26 +46,26 @@ ParseTemplateParameterList(ParserState &PS, StringRef &TemplateParmList) {
if (TemplateParmList.consume_front("size_t")) {
if (!PS.EmittedSizeTInfo) {
PS.EmittedSizeTInfo = true;
- Generator += R"C++(
+ Generator << R"C++(
TypeSourceInfo *SizeTInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
)C++";
}
- Generator += " auto *" + ParmName + R"C++(
+ Generator << " auto *" << ParmName << R"C++(
= NonTypeTemplateParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
- )C++" + std::to_string(PS.CurrentDepth) +
- ", " + std::to_string(Position++) + R"C++(, /*Id=*/nullptr,
+ )C++" << PS.CurrentDepth
+ << ", " << Position++ << R"C++(, /*Id=*/nullptr,
SizeTInfo->getType(), /*ParameterPack=*/false, SizeTInfo);
)C++";
} else if (TemplateParmList.consume_front("class")) {
bool ParameterPack = TemplateParmList.consume_front("...");
- Generator += " auto *" + ParmName + R"C++(
+ Generator << " auto *" << ParmName << R"C++(
= TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
- )C++" + std::to_string(PS.CurrentDepth) +
- ", " + std::to_string(Position++) +
- R"C++(, /*Id=*/nullptr, /*Typename=*/false, )C++" +
- BoolToStr(ParameterPack) + ");\n";
+ )C++" << PS.CurrentDepth
+ << ", " << Position++
+ << R"C++(, /*Id=*/nullptr, /*Typename=*/false, )C++"
+ << ParameterPack << ");\n";
} else if (TemplateParmList.consume_front("template")) {
++PS.CurrentDepth;
auto [Code, TPLName] = ParseTemplateParameterList(PS, TemplateParmList);
@@ -72,13 +74,13 @@ ParseTemplateParameterList(ParserState &PS, StringRef &TemplateParmList) {
if (!TemplateParmList.consume_front("class")) {
PrintFatalError("Expected 'class' after template template list");
}
- Generator += Code;
- Generator +=
- " auto *" + ParmName + R"C++(
- = TemplateTemplateParmDecl::Create(C, DC, SourceLocation(), )C++" +
- std::to_string(PS.CurrentDepth) + ", " + std::to_string(Position++) +
- ", /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, " +
- TPLName + ");\n";
+ Generator << Code;
+ Generator
+ << " auto *" << ParmName << R"C++(
+ = TemplateTemplateParmDecl::Create(C, DC, SourceLocation(), )C++"
+ << PS.CurrentDepth << ", " << Position++
+ << ", /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, "
+ << TPLName << ");\n";
} else {
auto Name = TemplateParmList.take_while(Alphabetic).str();
if (TemplateNameToParmName.find(Name) != TemplateNameToParmName.end()) {
@@ -86,17 +88,17 @@ ParseTemplateParameterList(ParserState &PS, StringRef &TemplateParmList) {
bool ParameterPack = TemplateParmList.consume_front("...");
auto TSIName = "TSI" + std::to_string(PS.UniqueCounter++);
- Generator += " auto *" + TSIName + R"C++(
- = C.getTrivialTypeSourceInfo(QualType()C++" +
- TemplateNameToParmName[Name] +
- R"C++(->getTypeForDecl(), 0));
- auto *)C++" + ParmName +
- R"C++( = NonTypeTemplateParmDecl::Create(
- C, DC, SourceLocation(), SourceLocation(), )C++" +
- std::to_string(PS.CurrentDepth) + ", " +
- std::to_string(Position++) + ", /*Id=*/nullptr, " +
- TSIName + "->getType(), " + BoolToStr(ParameterPack) +
- ", " + TSIName + ");\n";
+ Generator << " auto *" << TSIName << R"C++(
+ = C.getTrivialTypeSourceInfo(QualType()C++"
+ << TemplateNameToParmName[Name] <<
+ R"C++(->getTypeForDecl(), 0));
+ auto *)C++" << ParmName
+ <<
+ R"C++( = NonTypeTemplateParmDecl::Create(
+ C, DC, SourceLocation(), SourceLocation(), )C++"
+ << PS.CurrentDepth << ", " << Position++
+ << ", /*Id=*/nullptr, " << TSIName << "->getType(), "
+ << ParameterPack << ", " << TSIName << ");\n";
} else {
PrintFatalError("Unknown argument");
}
@@ -121,7 +123,7 @@ ParseTemplateParameterList(ParserState &PS, StringRef &TemplateParmList) {
}
auto TPLName = "TPL" + std::to_string(PS.UniqueCounter++);
- Generator += " auto *" + TPLName + R"C++( = TemplateParameterList::Create(
+ Generator << " auto *" << TPLName << R"C++( = TemplateParameterList::Create(
C, SourceLocation(), SourceLocation(), {)C++";
if (Params.empty())
@@ -132,14 +134,14 @@ ParseTemplateParameterList(ParserState &PS, StringRef &TemplateParmList) {
for (auto e : Params) {
if (First) {
First = false;
- Generator += e;
+ Generator << e;
} else {
- Generator += ", " + e;
+ Generator << ", " << e;
}
}
- Generator += "}, SourceLocation(), nullptr);\n";
+ Generator << "}, SourceLocation(), nullptr);\n";
- return {std::move(Generator), std::move(TPLName)};
+ return {std::move(Generator).str(), std::move(TPLName)};
}
void EmitCreateBuiltinTemplateParameterList(StringRef Prototype,
>From 417b15f8e28625e696c4254d20626034e79736b8 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 25 Jan 2025 12:06:21 +0100
Subject: [PATCH 4/7] Rename protoype to temaplate_head
---
clang/include/clang/Basic/BuiltinTemplates.td | 4 ++--
.../utils/TableGen/ClangBuiltinTemplatesEmitter.cpp | 12 ++++++------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/clang/include/clang/Basic/BuiltinTemplates.td b/clang/include/clang/Basic/BuiltinTemplates.td
index 3d51088e0bcca..60e6bf25a04b8 100644
--- a/clang/include/clang/Basic/BuiltinTemplates.td
+++ b/clang/include/clang/Basic/BuiltinTemplates.td
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-class BuiltinTemplate<string prototype> {
- string Prototype = prototype;
+class BuiltinTemplate<string template_head> {
+ string TemplateHead = template_head;
}
def __make_integer_seq : BuiltinTemplate<
diff --git a/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
index aa13473a69acc..2c3b3cc9a6059 100644
--- a/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
+++ b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
@@ -144,27 +144,27 @@ ParseTemplateParameterList(ParserState &PS, StringRef &TemplateParmList) {
return {std::move(Generator).str(), std::move(TPLName)};
}
-void EmitCreateBuiltinTemplateParameterList(StringRef Prototype,
+void EmitCreateBuiltinTemplateParameterList(StringRef TemplateHead,
StringRef Name) {
using namespace std::string_literals;
CreateBuiltinTemplateParameterList +=
"case BTK"s + std::string{Name} + ": {\n"s;
- if (!Prototype.consume_front("template"))
+ if (!TemplateHead.consume_front("template"))
PrintFatalError(
- "Expected template prototype to start with 'template' keyword");
+ "Expected template head to start with 'template' keyword");
ParserState PS;
- auto [Code, TPLName] = ParseTemplateParameterList(PS, Prototype);
+ auto [Code, TPLName] = ParseTemplateParameterList(PS, TemplateHead);
CreateBuiltinTemplateParameterList += Code + "\n return " + TPLName + ";\n";
CreateBuiltinTemplateParameterList += " }\n";
}
void EmitBuiltinTemplate(raw_ostream &OS, const Record *BuiltinTemplate) {
- auto Prototype = BuiltinTemplate->getValueAsString("Prototype");
+ auto TemplateHead = BuiltinTemplate->getValueAsString("TemplateHead");
auto Name = BuiltinTemplate->getName();
- EmitCreateBuiltinTemplateParameterList(Prototype, Name);
+ EmitCreateBuiltinTemplateParameterList(TemplateHead, Name);
TemplateNameList += "BuiltinTemplate(";
TemplateNameList += Name;
>From c517ac94601ec33dd35d4996714e9286a6b52072 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 7 Feb 2025 23:26:10 +0100
Subject: [PATCH 5/7] Address comments
---
clang/include/clang/Basic/BuiltinTemplates.td | 42 +++++
.../TableGen/ClangBuiltinTemplatesEmitter.cpp | 162 ++++++++----------
2 files changed, 111 insertions(+), 93 deletions(-)
diff --git a/clang/include/clang/Basic/BuiltinTemplates.td b/clang/include/clang/Basic/BuiltinTemplates.td
index 60e6bf25a04b8..2007e814b9aad 100644
--- a/clang/include/clang/Basic/BuiltinTemplates.td
+++ b/clang/include/clang/Basic/BuiltinTemplates.td
@@ -6,6 +6,47 @@
//
//===----------------------------------------------------------------------===//
+class TemplateArg<string name> {
+ string Name = name;
+}
+
+class Template<list<TemplateArg> args, string name> : TemplateArg<name> {
+ list<TemplateArg> Args = args;
+}
+
+class Class<string name, bit is_variadic = 0> : TemplateArg<name> {
+ bit IsVariadic = is_variadic;
+}
+
+class NTTP<string type_name, string name, bit is_variadic = 0> : TemplateArg<name> {
+ string TypeName = type_name;
+ bit IsVariadic = is_variadic;
+}
+
+class BuiltinNTTP<string type_name> : TemplateArg<""> {
+ string TypeName = type_name;
+}
+
+def SizeT : BuiltinNTTP<"size_t"> {}
+
+class BuiltinTemplate<list<TemplateArg> template_head> {
+ list<TemplateArg> TemplateHead = template_head;
+}
+
+def __make_integer_seq : BuiltinTemplate<
+ [Template<[Class<"T">, NTTP<"T", "Ints", /*is_variadic=*/1>], "IntSeq">, Class<"T">, NTTP<"T", "N">]>;
+
+def __type_pack_element : BuiltinTemplate<
+ [SizeT, Class<"T", /*is_variadic=*/1>]>;
+
+def __builtin_common_type : BuiltinTemplate<
+ [Template<[Class<"Args", /*is_variadic=*/1>], "BaseTemplate">,
+ Template<[Class<"TypeMember">], "HasTypeMember">,
+ Class<"HasNoTypeMember">,
+ Class<"Ts", /*is_variadic=*/1>]>;
+
+/*
+
class BuiltinTemplate<string template_head> {
string TemplateHead = template_head;
}
@@ -21,3 +62,4 @@ def __builtin_common_type : BuiltinTemplate<
" template <class TypeMember> class HasTypeMember,"
" class HasNoTypeMember,"
" class... Ts>">;
+*/
diff --git a/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
index 2c3b3cc9a6059..a9a6b7e8793fb 100644
--- a/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
+++ b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
@@ -29,141 +29,117 @@ struct ParserState {
};
std::pair<std::string, std::string>
-ParseTemplateParameterList(ParserState &PS, StringRef &TemplateParmList) {
- auto Alphabetic = [](char c) { return std::isalpha(c); };
-
- std::ostringstream Generator;
- Generator << std::boolalpha;
+ParseTemplateParameterList(ParserState &PS,
+ ArrayRef<const Record *> TemplateArgs) {
std::vector<std::string> Params;
std::unordered_map<std::string, std::string> TemplateNameToParmName;
- TemplateParmList = TemplateParmList.ltrim();
- if (!TemplateParmList.consume_front("<"))
- PrintFatalError("Expected '<' to start the parameter list");
+
+ std::ostringstream Code;
+ Code << std::boolalpha;
size_t Position = 0;
- while (true) {
+ for (const Record *Arg : TemplateArgs) {
std::string ParmName = "Parm" + std::to_string(PS.UniqueCounter++);
- if (TemplateParmList.consume_front("size_t")) {
- if (!PS.EmittedSizeTInfo) {
- PS.EmittedSizeTInfo = true;
- Generator << R"C++(
- TypeSourceInfo *SizeTInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
-)C++";
- }
-
- Generator << " auto *" << ParmName << R"C++(
- = NonTypeTemplateParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
- )C++" << PS.CurrentDepth
- << ", " << Position++ << R"C++(, /*Id=*/nullptr,
- SizeTInfo->getType(), /*ParameterPack=*/false, SizeTInfo);
-)C++";
- } else if (TemplateParmList.consume_front("class")) {
- bool ParameterPack = TemplateParmList.consume_front("...");
-
- Generator << " auto *" << ParmName << R"C++(
- = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(),
- )C++" << PS.CurrentDepth
- << ", " << Position++
- << R"C++(, /*Id=*/nullptr, /*Typename=*/false, )C++"
- << ParameterPack << ");\n";
- } else if (TemplateParmList.consume_front("template")) {
+ if (Arg->isSubClassOf("Template")) {
++PS.CurrentDepth;
- auto [Code, TPLName] = ParseTemplateParameterList(PS, TemplateParmList);
+ auto [TemplateCode, TPLName] =
+ ParseTemplateParameterList(PS, Arg->getValueAsListOfDefs("Args"));
--PS.CurrentDepth;
- TemplateParmList = TemplateParmList.ltrim();
- if (!TemplateParmList.consume_front("class")) {
- PrintFatalError("Expected 'class' after template template list");
+ Code << TemplateCode << " auto *" << ParmName
+ << " = TemplateTemplateParmDecl::Create(C, DC, SourceLocation(), "
+ << PS.CurrentDepth << ", " << Position++
+ << ", /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, "
+ << TPLName << ");\n";
+ } else if (Arg->isSubClassOf("Class")) {
+ Code << " auto *" << ParmName
+ << " = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), "
+ "SourceLocation(), "
+ << PS.CurrentDepth << ", " << Position++
+ << ", /*Id=*/nullptr, /*Typename=*/false, "
+ << Arg->getValueAsBit("IsVariadic") << ");\n";
+ } else if (Arg->isSubClassOf("NTTP")) {
+ auto Type = Arg->getValueAsString("TypeName");
+
+ if (TemplateNameToParmName.find(Type.str()) ==
+ TemplateNameToParmName.end()) {
+ PrintFatalError("Unkown Type Name");
}
- Generator << Code;
- Generator
- << " auto *" << ParmName << R"C++(
- = TemplateTemplateParmDecl::Create(C, DC, SourceLocation(), )C++"
- << PS.CurrentDepth << ", " << Position++
- << ", /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, "
- << TPLName << ");\n";
- } else {
- auto Name = TemplateParmList.take_while(Alphabetic).str();
- if (TemplateNameToParmName.find(Name) != TemplateNameToParmName.end()) {
- TemplateParmList = TemplateParmList.drop_front(Name.size());
- bool ParameterPack = TemplateParmList.consume_front("...");
-
- auto TSIName = "TSI" + std::to_string(PS.UniqueCounter++);
- Generator << " auto *" << TSIName << R"C++(
- = C.getTrivialTypeSourceInfo(QualType()C++"
- << TemplateNameToParmName[Name] <<
- R"C++(->getTypeForDecl(), 0));
- auto *)C++" << ParmName
- <<
- R"C++( = NonTypeTemplateParmDecl::Create(
- C, DC, SourceLocation(), SourceLocation(), )C++"
- << PS.CurrentDepth << ", " << Position++
- << ", /*Id=*/nullptr, " << TSIName << "->getType(), "
- << ParameterPack << ", " << TSIName << ");\n";
- } else {
- PrintFatalError("Unknown argument");
+
+ auto TSIName = "TSI" + std::to_string(PS.UniqueCounter++);
+ Code << " auto *" << TSIName << " = C.getTrivialTypeSourceInfo(QualType("
+ << TemplateNameToParmName[Type.str()] << "->getTypeForDecl(), 0));\n"
+ << " auto *" << ParmName
+ << " = NonTypeTemplateParmDecl::Create(C, DC, SourceLocation(), "
+ "SourceLocation(), "
+ << PS.CurrentDepth << ", " << Position++ << ", /*Id=*/nullptr, "
+ << TSIName << "->getType(), " << Arg->getValueAsBit("IsVariadic")
+ << ", " << TSIName << ");\n";
+ } else if (Arg->isSubClassOf("BuiltinNTTP")) {
+ if (Arg->getValueAsString("TypeName") != "size_t")
+ PrintFatalError("Unkown Type Name");
+ if (!PS.EmittedSizeTInfo) {
+ Code << "TypeSourceInfo *SizeTInfo = "
+ "C.getTrivialTypeSourceInfo(C.getSizeType());\n";
+ PS.EmittedSizeTInfo = true;
}
- }
- TemplateParmList = TemplateParmList.ltrim();
- auto ID = TemplateParmList.take_while(Alphabetic);
- if (!ID.empty()) {
- TemplateNameToParmName[ID.str()] = ParmName;
- TemplateParmList = TemplateParmList.drop_front(ID.size());
+ Code << " auto *" << ParmName
+ << " = NonTypeTemplateParmDecl::Create(C, DC, SourceLocation(), "
+ "SourceLocation(), "
+ << PS.CurrentDepth << ", " << Position++
+ << ", /*Id=*/nullptr, SizeTInfo->getType(), "
+ "/*ParameterPack=*/false, SizeTInfo);\n";
+ } else {
+ PrintFatalError("Unknown Argument Type");
}
+ TemplateNameToParmName[Arg->getValueAsString("Name").str()] = ParmName;
Params.emplace_back(std::move(ParmName));
-
- if (!TemplateParmList.consume_front(","))
- break;
- TemplateParmList = TemplateParmList.ltrim();
- }
-
- if (!TemplateParmList.consume_front(">")) {
- PrintWarning("Expected '>' to close template parameter list");
- PrintWarning(TemplateParmList);
}
auto TPLName = "TPL" + std::to_string(PS.UniqueCounter++);
- Generator << " auto *" << TPLName << R"C++( = TemplateParameterList::Create(
- C, SourceLocation(), SourceLocation(), {)C++";
+ Code << " auto *" << TPLName
+ << " = TemplateParameterList::Create(C, SourceLocation(), "
+ "SourceLocation(), {";
- if (Params.empty())
+ if (Params.empty()) {
PrintFatalError(
"Expected at least one argument in template parameter list");
+ }
bool First = true;
for (auto e : Params) {
if (First) {
First = false;
- Generator << e;
+ Code << e;
} else {
- Generator << ", " << e;
+ Code << ", " << e;
}
}
- Generator << "}, SourceLocation(), nullptr);\n";
+ Code << "}, SourceLocation(), nullptr);\n";
- return {std::move(Generator).str(), std::move(TPLName)};
+ return {std::move(Code).str(), std::move(TPLName)};
}
-void EmitCreateBuiltinTemplateParameterList(StringRef TemplateHead,
- StringRef Name) {
+static void
+EmitCreateBuiltinTemplateParameterList(std::vector<const Record *> TemplateArgs,
+ StringRef Name) {
using namespace std::string_literals;
CreateBuiltinTemplateParameterList +=
"case BTK"s + std::string{Name} + ": {\n"s;
- if (!TemplateHead.consume_front("template"))
- PrintFatalError(
- "Expected template head to start with 'template' keyword");
ParserState PS;
- auto [Code, TPLName] = ParseTemplateParameterList(PS, TemplateHead);
+ auto [Code, TPLName] = ParseTemplateParameterList(PS, TemplateArgs);
CreateBuiltinTemplateParameterList += Code + "\n return " + TPLName + ";\n";
CreateBuiltinTemplateParameterList += " }\n";
}
void EmitBuiltinTemplate(raw_ostream &OS, const Record *BuiltinTemplate) {
- auto TemplateHead = BuiltinTemplate->getValueAsString("TemplateHead");
auto Name = BuiltinTemplate->getName();
+ std::vector<const Record *> TemplateHead =
+ BuiltinTemplate->getValueAsListOfDefs("TemplateHead");
+
EmitCreateBuiltinTemplateParameterList(TemplateHead, Name);
TemplateNameList += "BuiltinTemplate(";
>From 9a582a15e584a1cb20781b15dc7a1d5b3a2ead6a Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 7 Feb 2025 23:26:38 +0100
Subject: [PATCH 6/7] Remove old code
---
clang/include/clang/Basic/BuiltinTemplates.td | 19 -------------------
1 file changed, 19 deletions(-)
diff --git a/clang/include/clang/Basic/BuiltinTemplates.td b/clang/include/clang/Basic/BuiltinTemplates.td
index 2007e814b9aad..e04b9728e3b01 100644
--- a/clang/include/clang/Basic/BuiltinTemplates.td
+++ b/clang/include/clang/Basic/BuiltinTemplates.td
@@ -44,22 +44,3 @@ def __builtin_common_type : BuiltinTemplate<
Template<[Class<"TypeMember">], "HasTypeMember">,
Class<"HasNoTypeMember">,
Class<"Ts", /*is_variadic=*/1>]>;
-
-/*
-
-class BuiltinTemplate<string template_head> {
- string TemplateHead = template_head;
-}
-
-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>">;
-*/
>From eb7a8707faf942292a7a82feb3ae74ba6b93feb4 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 20 Feb 2025 09:12:23 +0100
Subject: [PATCH 7/7] Address comments
---
clang/include/clang/Basic/BuiltinTemplates.td | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/clang/include/clang/Basic/BuiltinTemplates.td b/clang/include/clang/Basic/BuiltinTemplates.td
index e04b9728e3b01..d46ce063d2f7e 100644
--- a/clang/include/clang/Basic/BuiltinTemplates.td
+++ b/clang/include/clang/Basic/BuiltinTemplates.td
@@ -33,12 +33,18 @@ class BuiltinTemplate<list<TemplateArg> template_head> {
list<TemplateArg> TemplateHead = template_head;
}
+// template <template <class T, T... Ints> IntSeq, class T, T N>
def __make_integer_seq : BuiltinTemplate<
[Template<[Class<"T">, NTTP<"T", "Ints", /*is_variadic=*/1>], "IntSeq">, Class<"T">, NTTP<"T", "N">]>;
+// template <size_t, class... T>
def __type_pack_element : BuiltinTemplate<
[SizeT, Class<"T", /*is_variadic=*/1>]>;
+// template <template <class... Args> BaseTemplate,
+// template <class TypeMember> HasTypeMember,
+// class HasNoTypeMember
+// class... Ts>
def __builtin_common_type : BuiltinTemplate<
[Template<[Class<"Args", /*is_variadic=*/1>], "BaseTemplate">,
Template<[Class<"TypeMember">], "HasTypeMember">,
More information about the cfe-commits
mailing list