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 <nikolasklau...@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 <nikolasklau...@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 <nikolasklau...@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 <nikolasklau...@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 <nikolasklau...@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 <nikolasklau...@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 <nikolasklau...@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">, _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits