================ @@ -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) { + std::vector<std::string> Params; + std::unordered_map<std::string, 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, ---------------- philnik777 wrote:
```c++ /*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ |* *| |* Tables and code for Clang's builtin templates *| |* *| |* Automatically generated file, do not edit! *| |* *| \*===----------------------------------------------------------------------===*/ #if defined(CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST) case BTK__builtin_common_type: { auto *Parm1 = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(), 1, 0, /*Id=*/nullptr, /*Typename=*/false, true); auto *TPL2 = TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), {Parm1}, SourceLocation(), nullptr); auto *Parm0 = TemplateTemplateParmDecl::Create(C, DC, SourceLocation(), 0, 0, /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL2); auto *Parm4 = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(), 1, 0, /*Id=*/nullptr, /*Typename=*/false, false); auto *TPL5 = TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), {Parm4}, SourceLocation(), nullptr); auto *Parm3 = TemplateTemplateParmDecl::Create(C, DC, SourceLocation(), 0, 1, /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL5); auto *Parm6 = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(), 0, 2, /*Id=*/nullptr, /*Typename=*/false, false); auto *Parm7 = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(), 0, 3, /*Id=*/nullptr, /*Typename=*/false, true); auto *TPL8 = TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), {Parm0, Parm3, Parm6, Parm7}, SourceLocation(), nullptr); return TPL8; } case BTK__make_integer_seq: { auto *Parm1 = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(), 1, 0, /*Id=*/nullptr, /*Typename=*/false, false); auto *TSI3 = C.getTrivialTypeSourceInfo(QualType(Parm1->getTypeForDecl(), 0)); auto *Parm2 = NonTypeTemplateParmDecl::Create(C, DC, SourceLocation(), SourceLocation(), 1, 1, /*Id=*/nullptr, TSI3->getType(), true, TSI3); auto *TPL4 = TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), {Parm1, Parm2}, SourceLocation(), nullptr); auto *Parm0 = TemplateTemplateParmDecl::Create(C, DC, SourceLocation(), 0, 0, /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL4); auto *Parm5 = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(), 0, 1, /*Id=*/nullptr, /*Typename=*/false, false); auto *TSI7 = C.getTrivialTypeSourceInfo(QualType(Parm5->getTypeForDecl(), 0)); auto *Parm6 = NonTypeTemplateParmDecl::Create(C, DC, SourceLocation(), SourceLocation(), 0, 2, /*Id=*/nullptr, TSI7->getType(), false, TSI7); auto *TPL8 = TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), {Parm0, Parm5, Parm6}, SourceLocation(), nullptr); return TPL8; } case BTK__type_pack_element: { TypeSourceInfo *SizeTInfo = C.getTrivialTypeSourceInfo(C.getSizeType()); auto *Parm0 = NonTypeTemplateParmDecl::Create(C, DC, SourceLocation(), SourceLocation(), 0, 0, /*Id=*/nullptr, SizeTInfo->getType(), /*ParameterPack=*/false, SizeTInfo); auto *Parm1 = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), SourceLocation(), 0, 1, /*Id=*/nullptr, /*Typename=*/false, true); auto *TPL2 = TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), {Parm0, Parm1}, SourceLocation(), nullptr); return TPL2; } #undef CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST #else BuiltinTemplate(__builtin_common_type) BuiltinTemplate(__make_integer_seq) BuiltinTemplate(__type_pack_element) #undef BuiltinTemplate #endif ``` https://github.com/llvm/llvm-project/pull/123736 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits