[llvm-exegesis] Remove unused Counter::read method (#76651)
[llvm-project.git] / clang / utils / TableGen / ASTTableGen.h
blob41f78a6a3bbcdddaebe5aa45bba7b206282766ab
1 //=== ASTTableGen.h - Common definitions for AST node tablegen --*- 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 //===----------------------------------------------------------------------===//
9 #ifndef CLANG_AST_TABLEGEN_H
10 #define CLANG_AST_TABLEGEN_H
12 #include "llvm/TableGen/Record.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include <optional>
16 // These are spellings in the tblgen files.
18 #define HasPropertiesClassName "HasProperties"
20 // ASTNodes and their common fields. `Base` is actually defined
21 // in subclasses, but it's still common across the hierarchies.
22 #define ASTNodeClassName "ASTNode"
23 #define BaseFieldName "Base"
24 #define AbstractFieldName "Abstract"
26 // Comment node hierarchy.
27 #define CommentNodeClassName "CommentNode"
29 // Decl node hierarchy.
30 #define DeclNodeClassName "DeclNode"
31 #define DeclContextNodeClassName "DeclContext"
33 // Stmt node hierarchy.
34 #define StmtNodeClassName "StmtNode"
36 // Type node hierarchy.
37 #define TypeNodeClassName "TypeNode"
38 #define AlwaysDependentClassName "AlwaysDependent"
39 #define NeverCanonicalClassName "NeverCanonical"
40 #define NeverCanonicalUnlessDependentClassName "NeverCanonicalUnlessDependent"
41 #define LeafTypeClassName "LeafType"
43 // Cases of various non-ASTNode structured types like DeclarationName.
44 #define TypeKindClassName "PropertyTypeKind"
45 #define KindTypeFieldName "KindType"
46 #define KindPropertyNameFieldName "KindPropertyName"
47 #define TypeCaseClassName "PropertyTypeCase"
49 // Properties of AST nodes.
50 #define PropertyClassName "Property"
51 #define ClassFieldName "Class"
52 #define NameFieldName "Name"
53 #define TypeFieldName "Type"
54 #define ReadFieldName "Read"
56 // Types of properties.
57 #define PropertyTypeClassName "PropertyType"
58 #define CXXTypeNameFieldName "CXXName"
59 #define PassByReferenceFieldName "PassByReference"
60 #define ConstWhenWritingFieldName "ConstWhenWriting"
61 #define ConditionalCodeFieldName "Conditional"
62 #define PackOptionalCodeFieldName "PackOptional"
63 #define UnpackOptionalCodeFieldName "UnpackOptional"
64 #define BufferElementTypesFieldName "BufferElementTypes"
65 #define ArrayTypeClassName "Array"
66 #define ArrayElementTypeFieldName "Element"
67 #define OptionalTypeClassName "Optional"
68 #define OptionalElementTypeFieldName "Element"
69 #define SubclassPropertyTypeClassName "SubclassPropertyType"
70 #define SubclassBaseTypeFieldName "Base"
71 #define SubclassClassNameFieldName "SubclassName"
72 #define EnumPropertyTypeClassName "EnumPropertyType"
74 // Write helper rules.
75 #define ReadHelperRuleClassName "ReadHelper"
76 #define HelperCodeFieldName "Code"
78 // Creation rules.
79 #define CreationRuleClassName "Creator"
80 #define CreateFieldName "Create"
82 // Override rules.
83 #define OverrideRuleClassName "Override"
84 #define IgnoredPropertiesFieldName "IgnoredProperties"
86 namespace clang {
87 namespace tblgen {
89 class WrappedRecord {
90 llvm::Record *Record;
92 protected:
93 WrappedRecord(llvm::Record *record = nullptr) : Record(record) {}
95 llvm::Record *get() const {
96 assert(Record && "accessing null record");
97 return Record;
100 public:
101 llvm::Record *getRecord() const { return Record; }
103 explicit operator bool() const { return Record != nullptr; }
105 llvm::ArrayRef<llvm::SMLoc> getLoc() const {
106 return get()->getLoc();
109 /// Does the node inherit from the given TableGen class?
110 bool isSubClassOf(llvm::StringRef className) const {
111 return get()->isSubClassOf(className);
114 template <class NodeClass>
115 NodeClass getAs() const {
116 return (isSubClassOf(NodeClass::getTableGenNodeClassName())
117 ? NodeClass(get()) : NodeClass());
120 friend bool operator<(WrappedRecord lhs, WrappedRecord rhs) {
121 assert(lhs && rhs && "sorting null nodes");
122 return lhs.get()->getName() < rhs.get()->getName();
124 friend bool operator>(WrappedRecord lhs, WrappedRecord rhs) {
125 return rhs < lhs;
127 friend bool operator<=(WrappedRecord lhs, WrappedRecord rhs) {
128 return !(rhs < lhs);
130 friend bool operator>=(WrappedRecord lhs, WrappedRecord rhs) {
131 return !(lhs < rhs);
133 friend bool operator==(WrappedRecord lhs, WrappedRecord rhs) {
134 // This should handle null nodes.
135 return lhs.getRecord() == rhs.getRecord();
137 friend bool operator!=(WrappedRecord lhs, WrappedRecord rhs) {
138 return !(lhs == rhs);
142 /// Anything in the AST that has properties.
143 class HasProperties : public WrappedRecord {
144 public:
145 static constexpr llvm::StringRef ClassName = HasPropertiesClassName;
147 HasProperties(llvm::Record *record = nullptr) : WrappedRecord(record) {}
149 llvm::StringRef getName() const;
151 static llvm::StringRef getTableGenNodeClassName() {
152 return HasPropertiesClassName;
156 /// An (optional) reference to a TableGen node representing a class
157 /// in one of Clang's AST hierarchies.
158 class ASTNode : public HasProperties {
159 public:
160 ASTNode(llvm::Record *record = nullptr) : HasProperties(record) {}
162 llvm::StringRef getName() const {
163 return get()->getName();
166 /// Return the node for the base, if there is one.
167 ASTNode getBase() const {
168 return get()->getValueAsOptionalDef(BaseFieldName);
171 /// Is the corresponding class abstract?
172 bool isAbstract() const {
173 return get()->getValueAsBit(AbstractFieldName);
176 static llvm::StringRef getTableGenNodeClassName() {
177 return ASTNodeClassName;
181 class DeclNode : public ASTNode {
182 public:
183 DeclNode(llvm::Record *record = nullptr) : ASTNode(record) {}
185 llvm::StringRef getId() const;
186 std::string getClassName() const;
187 DeclNode getBase() const { return DeclNode(ASTNode::getBase().getRecord()); }
189 static llvm::StringRef getASTHierarchyName() {
190 return "Decl";
192 static llvm::StringRef getASTIdTypeName() {
193 return "Decl::Kind";
195 static llvm::StringRef getASTIdAccessorName() {
196 return "getKind";
198 static llvm::StringRef getTableGenNodeClassName() {
199 return DeclNodeClassName;
203 class TypeNode : public ASTNode {
204 public:
205 TypeNode(llvm::Record *record = nullptr) : ASTNode(record) {}
207 llvm::StringRef getId() const;
208 llvm::StringRef getClassName() const;
209 TypeNode getBase() const { return TypeNode(ASTNode::getBase().getRecord()); }
211 static llvm::StringRef getASTHierarchyName() {
212 return "Type";
214 static llvm::StringRef getASTIdTypeName() {
215 return "Type::TypeClass";
217 static llvm::StringRef getASTIdAccessorName() {
218 return "getTypeClass";
220 static llvm::StringRef getTableGenNodeClassName() {
221 return TypeNodeClassName;
225 class StmtNode : public ASTNode {
226 public:
227 StmtNode(llvm::Record *record = nullptr) : ASTNode(record) {}
229 std::string getId() const;
230 llvm::StringRef getClassName() const;
231 StmtNode getBase() const { return StmtNode(ASTNode::getBase().getRecord()); }
233 static llvm::StringRef getASTHierarchyName() {
234 return "Stmt";
236 static llvm::StringRef getASTIdTypeName() {
237 return "Stmt::StmtClass";
239 static llvm::StringRef getASTIdAccessorName() {
240 return "getStmtClass";
242 static llvm::StringRef getTableGenNodeClassName() {
243 return StmtNodeClassName;
247 /// The type of a property.
248 class PropertyType : public WrappedRecord {
249 public:
250 PropertyType(llvm::Record *record = nullptr) : WrappedRecord(record) {}
252 /// Is this a generic specialization (i.e. `Array<T>` or `Optional<T>`)?
253 bool isGenericSpecialization() const {
254 return get()->isAnonymous();
257 /// The abstract type name of the property. Doesn't work for generic
258 /// specializations.
259 llvm::StringRef getAbstractTypeName() const {
260 return get()->getName();
263 /// The C++ type name of the property. Doesn't work for generic
264 /// specializations.
265 llvm::StringRef getCXXTypeName() const {
266 return get()->getValueAsString(CXXTypeNameFieldName);
268 void emitCXXValueTypeName(bool forRead, llvm::raw_ostream &out) const;
270 /// Whether the C++ type should be passed around by reference.
271 bool shouldPassByReference() const {
272 return get()->getValueAsBit(PassByReferenceFieldName);
275 /// Whether the C++ type should have 'const' prepended when working with
276 /// a value of the type being written.
277 bool isConstWhenWriting() const {
278 return get()->getValueAsBit(ConstWhenWritingFieldName);
281 /// If this is `Array<T>`, return `T`; otherwise return null.
282 PropertyType getArrayElementType() const {
283 if (isSubClassOf(ArrayTypeClassName))
284 return get()->getValueAsDef(ArrayElementTypeFieldName);
285 return nullptr;
288 /// If this is `Optional<T>`, return `T`; otherwise return null.
289 PropertyType getOptionalElementType() const {
290 if (isSubClassOf(OptionalTypeClassName))
291 return get()->getValueAsDef(OptionalElementTypeFieldName);
292 return nullptr;
295 /// If this is a subclass type, return its superclass type.
296 PropertyType getSuperclassType() const {
297 if (isSubClassOf(SubclassPropertyTypeClassName))
298 return get()->getValueAsDef(SubclassBaseTypeFieldName);
299 return nullptr;
302 // Given that this is a subclass type, return the C++ name of its
303 // subclass type. This is just the bare class name, suitable for
304 // use in `cast<>`.
305 llvm::StringRef getSubclassClassName() const {
306 return get()->getValueAsString(SubclassClassNameFieldName);
309 /// Does this represent an enum type?
310 bool isEnum() const {
311 return isSubClassOf(EnumPropertyTypeClassName);
314 llvm::StringRef getPackOptionalCode() const {
315 return get()->getValueAsString(PackOptionalCodeFieldName);
318 llvm::StringRef getUnpackOptionalCode() const {
319 return get()->getValueAsString(UnpackOptionalCodeFieldName);
322 std::vector<llvm::Record*> getBufferElementTypes() const {
323 return get()->getValueAsListOfDefs(BufferElementTypesFieldName);
326 static llvm::StringRef getTableGenNodeClassName() {
327 return PropertyTypeClassName;
331 /// A rule for returning the kind of a type.
332 class TypeKindRule : public WrappedRecord {
333 public:
334 TypeKindRule(llvm::Record *record = nullptr) : WrappedRecord(record) {}
336 /// Return the type to which this applies.
337 PropertyType getParentType() const {
338 return get()->getValueAsDef(TypeFieldName);
341 /// Return the type of the kind.
342 PropertyType getKindType() const {
343 return get()->getValueAsDef(KindTypeFieldName);
346 /// Return the name to use for the kind property.
347 llvm::StringRef getKindPropertyName() const {
348 return get()->getValueAsString(KindPropertyNameFieldName);
351 /// Return the code for reading the kind value.
352 llvm::StringRef getReadCode() const {
353 return get()->getValueAsString(ReadFieldName);
356 static llvm::StringRef getTableGenNodeClassName() {
357 return TypeKindClassName;
361 /// An implementation case of a property type.
362 class TypeCase : public HasProperties {
363 public:
364 TypeCase(llvm::Record *record = nullptr) : HasProperties(record) {}
366 /// Return the name of this case.
367 llvm::StringRef getCaseName() const {
368 return get()->getValueAsString(NameFieldName);
371 /// Return the type of which this is a case.
372 PropertyType getParentType() const {
373 return get()->getValueAsDef(TypeFieldName);
376 static llvm::StringRef getTableGenNodeClassName() {
377 return TypeCaseClassName;
381 /// A property of an AST node.
382 class Property : public WrappedRecord {
383 public:
384 Property(llvm::Record *record = nullptr) : WrappedRecord(record) {}
386 /// Return the name of this property.
387 llvm::StringRef getName() const {
388 return get()->getValueAsString(NameFieldName);
391 /// Return the type of this property.
392 PropertyType getType() const {
393 return get()->getValueAsDef(TypeFieldName);
396 /// Return the class of which this is a property.
397 HasProperties getClass() const {
398 return get()->getValueAsDef(ClassFieldName);
401 /// Return the code for reading this property.
402 llvm::StringRef getReadCode() const {
403 return get()->getValueAsString(ReadFieldName);
406 /// Return the code for determining whether to add this property.
407 llvm::StringRef getCondition() const {
408 return get()->getValueAsString(ConditionalCodeFieldName);
411 static llvm::StringRef getTableGenNodeClassName() {
412 return PropertyClassName;
416 /// A rule for running some helper code for reading properties from
417 /// a value (which is actually done when writing the value out).
418 class ReadHelperRule : public WrappedRecord {
419 public:
420 ReadHelperRule(llvm::Record *record = nullptr) : WrappedRecord(record) {}
422 /// Return the class for which this is a creation rule.
423 /// Should never be abstract.
424 HasProperties getClass() const {
425 return get()->getValueAsDef(ClassFieldName);
428 llvm::StringRef getHelperCode() const {
429 return get()->getValueAsString(HelperCodeFieldName);
432 static llvm::StringRef getTableGenNodeClassName() {
433 return ReadHelperRuleClassName;
437 /// A rule for how to create an AST node from its properties.
438 class CreationRule : public WrappedRecord {
439 public:
440 CreationRule(llvm::Record *record = nullptr) : WrappedRecord(record) {}
442 /// Return the class for which this is a creation rule.
443 /// Should never be abstract.
444 HasProperties getClass() const {
445 return get()->getValueAsDef(ClassFieldName);
448 llvm::StringRef getCreationCode() const {
449 return get()->getValueAsString(CreateFieldName);
452 static llvm::StringRef getTableGenNodeClassName() {
453 return CreationRuleClassName;
457 /// A rule which overrides the standard rules for serializing an AST node.
458 class OverrideRule : public WrappedRecord {
459 public:
460 OverrideRule(llvm::Record *record = nullptr) : WrappedRecord(record) {}
462 /// Return the class for which this is an override rule.
463 /// Should never be abstract.
464 HasProperties getClass() const {
465 return get()->getValueAsDef(ClassFieldName);
468 /// Return a set of properties that are unnecessary when serializing
469 /// this AST node. Generally this is used for inherited properties
470 /// that are derived for this subclass.
471 std::vector<llvm::StringRef> getIgnoredProperties() const {
472 return get()->getValueAsListOfStrings(IgnoredPropertiesFieldName);
475 static llvm::StringRef getTableGenNodeClassName() {
476 return OverrideRuleClassName;
480 /// A visitor for an AST node hierarchy. Note that `base` can be null for
481 /// the root class.
482 template <class NodeClass>
483 using ASTNodeHierarchyVisitor =
484 llvm::function_ref<void(NodeClass node, NodeClass base)>;
486 void visitASTNodeHierarchyImpl(llvm::RecordKeeper &records,
487 llvm::StringRef nodeClassName,
488 ASTNodeHierarchyVisitor<ASTNode> visit);
490 template <class NodeClass>
491 void visitASTNodeHierarchy(llvm::RecordKeeper &records,
492 ASTNodeHierarchyVisitor<NodeClass> visit) {
493 visitASTNodeHierarchyImpl(records, NodeClass::getTableGenNodeClassName(),
494 [visit](ASTNode node, ASTNode base) {
495 visit(NodeClass(node.getRecord()),
496 NodeClass(base.getRecord()));
500 } // end namespace clang::tblgen
501 } // end namespace clang
503 #endif