Author: Nikolas Klauser Date: 2025-02-26T16:01:14+01:00 New Revision: 8dd8e5f7d692cc43f4322f04034f5c472381aa43
URL: https://github.com/llvm/llvm-project/commit/8dd8e5f7d692cc43f4322f04034f5c472381aa43 DIFF: https://github.com/llvm/llvm-project/commit/8dd8e5f7d692cc43f4322f04034f5c472381aa43.diff LOG: [Clang] Add BuiltinTemplates.td to generate code for builtin templates (#123736) This makes it significantly easier to add new builtin templates, since you only have to modify two places instead of a dozen or so. The `BuiltinTemplates.td` could also be extended to generate documentation from it in the future. Added: clang/include/clang/Basic/BuiltinTemplates.td clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp Modified: clang/include/clang/AST/ASTContext.h clang/include/clang/AST/DeclID.h clang/include/clang/Basic/Builtins.h clang/include/clang/Basic/CMakeLists.txt clang/lib/AST/ASTContext.cpp clang/lib/AST/ASTImporter.cpp clang/lib/AST/DeclTemplate.cpp clang/lib/Lex/PPMacroExpansion.cpp clang/lib/Sema/SemaLookup.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/utils/TableGen/CMakeLists.txt clang/utils/TableGen/TableGen.cpp clang/utils/TableGen/TableGenBackends.h Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index d275873651786..4c6966c922cc7 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -410,14 +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; - - /// The identifier '__builtin_common_type'. - mutable IdentifierInfo *BuiltinCommonTypeName = nullptr; +#define BuiltinTemplate(BTName) mutable IdentifierInfo *Name##BTName = nullptr; +#include "clang/Basic/BuiltinTemplates.inc" QualType ObjCConstantStringType; mutable RecordDecl *CFConstantStringTagDecl = nullptr; @@ -629,9 +623,10 @@ 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(BTName) \ + mutable BuiltinTemplateDecl *Decl##BTName = nullptr; +#include "clang/Basic/BuiltinTemplates.inc" /// The associated SourceManager object. SourceManager &SourceMgr; @@ -1157,9 +1152,9 @@ class ASTContext : public RefCountedBase<ASTContext> { } ExternCContextDecl *getExternCContextDecl() const; - BuiltinTemplateDecl *getMakeIntegerSeqDecl() const; - BuiltinTemplateDecl *getTypePackElementDecl() const; - BuiltinTemplateDecl *getBuiltinCommonTypeDecl() const; + +#define BuiltinTemplate(BTName) BuiltinTemplateDecl *get##BTName##Decl() const; +#include "clang/Basic/BuiltinTemplates.inc" // Builtin Types. CanQualType VoidTy; @@ -2107,23 +2102,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; - } - - IdentifierInfo *getBuiltinCommonTypeName() const { - if (!BuiltinCommonTypeName) - BuiltinCommonTypeName = &Idents.get("__builtin_common_type"); - return BuiltinCommonTypeName; +#define BuiltinTemplate(BTName) \ + IdentifierInfo *get##BTName##Name() const { \ + if (!Name##BTName) \ + Name##BTName = &Idents.get(#BTName); \ + return Name##BTName; \ } +#include "clang/Basic/BuiltinTemplates.inc" /// Retrieve the Objective-C "instancetype" type, if already known; /// otherwise, returns a NULL type; diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h index 49964b43c7d1d..384f7b031e007 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(BTName) PREDEF_DECL##BTName##_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..d46ce063d2f7e --- /dev/null +++ b/clang/include/clang/Basic/BuiltinTemplates.td @@ -0,0 +1,52 @@ +//===--- 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 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; +} + +// 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">, + Class<"HasNoTypeMember">, + Class<"Ts", /*is_variadic=*/1>]>; diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h index d1c1ab44417fa..12c250afb4c61 100644 --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -459,14 +459,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(BTName) BTK##BTName, +#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 93dbc9c8ca62f..a671d5c764c22 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -96,6 +96,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 4a791316a6269..fce1c34897da7 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1198,28 +1198,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 43da76e14d0a3..82180486f3c7c 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -5465,15 +5465,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(BTName) \ + case BuiltinTemplateKind::BTK##BTName: \ + ToD = Importer.getToContext().get##BTName##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 63caf04f7ef38..b8fe19c69dc29 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -1581,140 +1581,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 944966a791add..8e35d56d3f1a6 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1831,10 +1831,9 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { return true; } 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) + // Report builtin templates as being builtins. +#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 0f5b7426e743e..aecf8ed1b4e4d 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 4a40df6399f64..294e8e063e0a3 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -8114,12 +8114,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; @@ -8132,17 +8126,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(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" 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 79b777cddd0b0..a01e72f193cf1 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -5539,15 +5539,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(BTName) \ + RegisterPredefDecl(Context.Decl##BTName, PREDEF_DECL##BTName##_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..34bc782e007d5 --- /dev/null +++ b/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp @@ -0,0 +1,162 @@ +//=- 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" + +#include <sstream> + +using namespace llvm; + +static std::string TemplateNameList; +static 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, + ArrayRef<const Record *> TemplateArgs) { + llvm::SmallVector<std::string, 4> Params; + llvm::StringMap<std::string> TemplateNameToParmName; + + std::ostringstream Code; + Code << std::boolalpha; + + size_t Position = 0; + for (const Record *Arg : TemplateArgs) { + std::string ParmName = "Parm" + std::to_string(PS.UniqueCounter++); + if (Arg->isSubClassOf("Template")) { + ++PS.CurrentDepth; + auto [TemplateCode, TPLName] = + ParseTemplateParameterList(PS, Arg->getValueAsListOfDefs("Args")); + --PS.CurrentDepth; + 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"); + } + + 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; + } + 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)); + } + + auto TPLName = "TPL" + std::to_string(PS.UniqueCounter++); + Code << " auto *" << TPLName + << " = TemplateParameterList::Create(C, SourceLocation(), " + "SourceLocation(), {"; + + if (Params.empty()) { + PrintFatalError( + "Expected at least one argument in template parameter list"); + } + + bool First = true; + for (auto e : Params) { + if (First) { + First = false; + Code << e; + } else { + Code << ", " << e; + } + } + Code << "}, SourceLocation(), nullptr);\n"; + + return {std::move(Code).str(), std::move(TPLName)}; +} + +static void +EmitCreateBuiltinTemplateParameterList(std::vector<const Record *> TemplateArgs, + StringRef Name) { + using namespace std::string_literals; + CreateBuiltinTemplateParameterList += + "case BTK"s + std::string{Name} + ": {\n"s; + + ParserState PS; + auto [Code, TPLName] = ParseTemplateParameterList(PS, TemplateArgs); + CreateBuiltinTemplateParameterList += Code + "\n return " + TPLName + ";\n"; + + CreateBuiltinTemplateParameterList += " }\n"; +} + +void EmitBuiltinTemplate(raw_ostream &OS, const Record *BuiltinTemplate) { + auto Name = BuiltinTemplate->getName(); + + std::vector<const Record *> TemplateHead = + BuiltinTemplate->getValueAsListOfDefs("TemplateHead"); + + EmitCreateBuiltinTemplateParameterList(TemplateHead, 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 569d7a6a3ac8b..7ffe6d2a913a9 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, @@ -173,6 +174,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", @@ -393,6 +396,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 03ed3dad93631..ae8ea3ad34aa5 100644 --- a/clang/utils/TableGen/TableGenBackends.h +++ b/clang/utils/TableGen/TableGenBackends.h @@ -88,6 +88,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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits