ClangTypeNodesEmitter.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. //=== ClangTypeNodesEmitter.cpp - Generate type node tables -----*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This tblgen backend emits the node table (the .def file) for Clang
  10. // type nodes.
  11. //
  12. // This file defines the AST type info database. Each type node is
  13. // enumerated by providing its name (e.g., "Builtin" or "Enum") and
  14. // base class (e.g., "Type" or "TagType"). Depending on where in the
  15. // abstract syntax tree the type will show up, the enumeration uses
  16. // one of five different macros:
  17. //
  18. // TYPE(Class, Base) - A type that can show up anywhere in the AST,
  19. // and might be dependent, canonical, or non-canonical. All clients
  20. // will need to understand these types.
  21. //
  22. // ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in
  23. // the type hierarchy but has no concrete instances.
  24. //
  25. // NON_CANONICAL_TYPE(Class, Base) - A type that can show up
  26. // anywhere in the AST but will never be a part of a canonical
  27. // type. Clients that only need to deal with canonical types
  28. // (ignoring, e.g., typedefs and other type aliases used for
  29. // pretty-printing) can ignore these types.
  30. //
  31. // DEPENDENT_TYPE(Class, Base) - A type that will only show up
  32. // within a C++ template that has not been instantiated, e.g., a
  33. // type that is always dependent. Clients that do not need to deal
  34. // with uninstantiated C++ templates can ignore these types.
  35. //
  36. // NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that
  37. // is non-canonical unless it is dependent. Defaults to TYPE because
  38. // it is neither reliably dependent nor reliably non-canonical.
  39. //
  40. // There is a sixth macro, independent of the others. Most clients
  41. // will not need to use it.
  42. //
  43. // LEAF_TYPE(Class) - A type that never has inner types. Clients
  44. // which can operate on such types more efficiently may wish to do so.
  45. //
  46. //===----------------------------------------------------------------------===//
  47. #include "llvm/ADT/StringRef.h"
  48. #include "llvm/TableGen/Error.h"
  49. #include "llvm/TableGen/Record.h"
  50. #include "llvm/TableGen/TableGenBackend.h"
  51. #include <set>
  52. #include <string>
  53. #include <vector>
  54. #include "TableGenBackends.h"
  55. using namespace llvm;
  56. // These are spellings in the generated output.
  57. #define TypeMacroName "TYPE"
  58. #define AbstractTypeMacroName "ABSTRACT_TYPE"
  59. #define DependentTypeMacroName "DEPENDENT_TYPE"
  60. #define NonCanonicalTypeMacroName "NON_CANONICAL_TYPE"
  61. #define NonCanonicalUnlessDependentTypeMacroName "NON_CANONICAL_UNLESS_DEPENDENT_TYPE"
  62. #define TypeMacroArgs "(Class, Base)"
  63. #define LastTypeMacroName "LAST_TYPE"
  64. #define LeafTypeMacroName "LEAF_TYPE"
  65. // These are spellings in the tblgen file.
  66. // (Type is also used for the spelling of the AST class.)
  67. #define TypeClassName "Type"
  68. #define DerivedTypeClassName "DerivedType"
  69. #define AlwaysDependentClassName "AlwaysDependent"
  70. #define NeverCanonicalClassName "NeverCanonical"
  71. #define NeverCanonicalUnlessDependentClassName "NeverCanonicalUnlessDependent"
  72. #define LeafTypeClassName "LeafType"
  73. #define AbstractFieldName "Abstract"
  74. #define BaseFieldName "Base"
  75. static StringRef getIdForType(Record *type) {
  76. // The record name is expected to be the full C++ class name,
  77. // including "Type". Check for that and strip it off.
  78. auto fullName = type->getName();
  79. if (!fullName.endswith("Type"))
  80. PrintFatalError(type->getLoc(), "name of Type node doesn't end in Type");
  81. return fullName.drop_back(4);
  82. }
  83. namespace {
  84. class TypeNodeEmitter {
  85. RecordKeeper &Records;
  86. raw_ostream &Out;
  87. const std::vector<Record*> Types;
  88. std::vector<StringRef> MacrosToUndef;
  89. public:
  90. TypeNodeEmitter(RecordKeeper &records, raw_ostream &out)
  91. : Records(records), Out(out),
  92. Types(Records.getAllDerivedDefinitions("Type")) {
  93. }
  94. void emit();
  95. private:
  96. void emitFallbackDefine(StringRef macroName, StringRef fallbackMacroName,
  97. StringRef args);
  98. void emitNodeInvocations();
  99. void emitLastNodeInvocation();
  100. void emitLeafNodeInvocations();
  101. void addMacroToUndef(StringRef macroName);
  102. void emitUndefs();
  103. };
  104. }
  105. void TypeNodeEmitter::emit() {
  106. if (Types.empty())
  107. PrintFatalError("no Type records in input!");
  108. emitSourceFileHeader("An x-macro database of Clang type nodes", Out);
  109. // Preamble
  110. addMacroToUndef(TypeMacroName);
  111. addMacroToUndef(AbstractTypeMacroName);
  112. emitFallbackDefine(AbstractTypeMacroName, TypeMacroName, TypeMacroArgs);
  113. emitFallbackDefine(NonCanonicalTypeMacroName, TypeMacroName, TypeMacroArgs);
  114. emitFallbackDefine(DependentTypeMacroName, TypeMacroName, TypeMacroArgs);
  115. emitFallbackDefine(NonCanonicalUnlessDependentTypeMacroName, TypeMacroName,
  116. TypeMacroArgs);
  117. // Invocations.
  118. emitNodeInvocations();
  119. emitLastNodeInvocation();
  120. emitLeafNodeInvocations();
  121. // Postmatter
  122. emitUndefs();
  123. }
  124. void TypeNodeEmitter::emitFallbackDefine(StringRef macroName,
  125. StringRef fallbackMacroName,
  126. StringRef args) {
  127. Out << "#ifndef " << macroName << "\n";
  128. Out << "# define " << macroName << args
  129. << " " << fallbackMacroName << args << "\n";
  130. Out << "#endif\n";
  131. addMacroToUndef(macroName);
  132. }
  133. void TypeNodeEmitter::emitNodeInvocations() {
  134. for (auto type : Types) {
  135. // The name with the Type suffix.
  136. StringRef id = getIdForType(type);
  137. // Figure out which macro to use.
  138. StringRef macroName;
  139. auto setMacroName = [&](StringRef newName) {
  140. if (!macroName.empty())
  141. PrintFatalError(type->getLoc(),
  142. Twine("conflict when computing macro name for "
  143. "Type node: trying to use both \"")
  144. + macroName + "\" and \"" + newName + "\"");
  145. macroName = newName;
  146. };
  147. if (type->isSubClassOf(AlwaysDependentClassName))
  148. setMacroName(DependentTypeMacroName);
  149. if (type->isSubClassOf(NeverCanonicalClassName))
  150. setMacroName(NonCanonicalTypeMacroName);
  151. if (type->isSubClassOf(NeverCanonicalUnlessDependentClassName))
  152. setMacroName(NonCanonicalUnlessDependentTypeMacroName);
  153. if (type->getValueAsBit(AbstractFieldName))
  154. setMacroName(AbstractTypeMacroName);
  155. if (macroName.empty())
  156. macroName = TypeMacroName;
  157. // Compute the base class.
  158. StringRef baseName = TypeClassName;
  159. if (type->isSubClassOf(DerivedTypeClassName))
  160. baseName = type->getValueAsDef(BaseFieldName)->getName();
  161. // Generate the invocation line.
  162. Out << macroName << "(" << id << ", " << baseName << ")\n";
  163. }
  164. }
  165. void TypeNodeEmitter::emitLastNodeInvocation() {
  166. // We check that this is non-empty earlier.
  167. Out << "#ifdef " LastTypeMacroName "\n"
  168. LastTypeMacroName "(" << getIdForType(Types.back()) << ")\n"
  169. "#undef " LastTypeMacroName "\n"
  170. "#endif\n";
  171. }
  172. void TypeNodeEmitter::emitLeafNodeInvocations() {
  173. Out << "#ifdef " LeafTypeMacroName "\n";
  174. for (auto type : Types) {
  175. if (!type->isSubClassOf(LeafTypeClassName)) continue;
  176. Out << LeafTypeMacroName "(" << getIdForType(type) << ")\n";
  177. }
  178. Out << "#undef " LeafTypeMacroName "\n"
  179. "#endif\n";
  180. }
  181. void TypeNodeEmitter::addMacroToUndef(StringRef macroName) {
  182. MacrosToUndef.push_back(macroName);
  183. }
  184. void TypeNodeEmitter::emitUndefs() {
  185. for (auto &macroName : MacrosToUndef) {
  186. Out << "#undef " << macroName << "\n";
  187. }
  188. }
  189. void clang::EmitClangTypeNodes(RecordKeeper &records, raw_ostream &out) {
  190. TypeNodeEmitter(records, out).emit();
  191. }