]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td
Merge ^/vendor/lvm-project/release-10.x up to its last change (upstream
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / include / clang / AST / PropertiesBase.td
1 //==--- PropertiesBase.td - Baseline definitions for AST properties -------===//
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 class HasProperties;
10
11 /// The type of the property.
12 class PropertyType<string typeName = ""> {
13   /// The C++ type name for the type.
14   string CXXName = !if(!ne(typeName, ""), typeName, NAME);
15
16   /// Whether the C++ type should generally be passed around by reference.
17   bit PassByReference = 0;
18
19   /// Whether `const` should be prepended to the type when writing.
20   bit ConstWhenWriting = 0;
21
22   /// Given a value of type Optional<CXXName> bound as 'value', yield a
23   /// CXXName that can be serialized into a DataStreamTypeWriter.
24   string PackOptional = "";
25
26   /// Given a value of type CXXName bound as 'value' that was deserialized
27   /// by a DataStreamTypeReader, yield an Optional<CXXName>.
28   string UnpackOptional = "";
29
30   /// A list of types for which buffeers must be passed to the read
31   /// operations.
32   list<PropertyType> BufferElementTypes = [];
33 }
34
35 /// Property types that correspond to specific C++ enums.
36 class EnumPropertyType<string typeName = ""> : PropertyType<typeName> {}
37
38 /// Property types that correspond to a specific C++ class.
39 /// Supports optional values by using the null representation.
40 class RefPropertyType<string className> : PropertyType<className # "*"> {
41   let PackOptional =
42     "value ? *value : nullptr";
43   let UnpackOptional =
44     "value ? llvm::Optional<" # CXXName # ">(value) : llvm::None";
45 }
46
47 /// Property types that correspond to a specific subclass of another type.
48 class SubclassPropertyType<string className, PropertyType base>
49     : RefPropertyType<className> {
50   PropertyType Base = base;
51   string SubclassName = className;
52   let ConstWhenWriting = base.ConstWhenWriting;
53 }
54
55 /// Property types that support optional values by using their
56 /// default value.
57 class DefaultValuePropertyType<string typeName = ""> : PropertyType<typeName> {
58   let PackOptional =
59     "value ? *value : " # CXXName # "()";
60   let UnpackOptional =
61     "value.isNull() ? llvm::None : llvm::Optional<" # CXXName # ">(value)";
62 }
63
64 /// Property types that correspond to integer types and support optional
65 /// values by shifting the value over by 1.
66 class CountPropertyType<string typeName = ""> : PropertyType<typeName> {
67   let PackOptional =
68     "value ? *value + 1 : 0";
69   let UnpackOptional =
70     "value ? llvm::Optional<" # CXXName # ">(value - 1) : llvm::None";
71 }
72
73 def APInt : PropertyType<"llvm::APInt"> { let PassByReference = 1; }
74 def APSInt : PropertyType<"llvm::APSInt"> { let PassByReference = 1; }
75 def ArraySizeModifier : EnumPropertyType<"ArrayType::ArraySizeModifier">;
76 def AttrKind : EnumPropertyType<"attr::Kind">;
77 def AutoTypeKeyword : EnumPropertyType;
78 def Bool : PropertyType<"bool">;
79 def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">;
80 def CallingConv : EnumPropertyType;
81 def DeclarationName : PropertyType;
82 def DeclarationNameKind : EnumPropertyType<"DeclarationName::NameKind">;
83 def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
84   def CXXRecordDeclRef :
85     SubclassPropertyType<"CXXRecordDecl", DeclRef>;
86   def FunctionDeclRef :
87     SubclassPropertyType<"FunctionDecl", DeclRef>;
88   def NamedDeclRef :
89     SubclassPropertyType<"NamedDecl", DeclRef>;
90   def NamespaceDeclRef :
91     SubclassPropertyType<"NamespaceDecl", DeclRef>;
92   def NamespaceAliasDeclRef :
93     SubclassPropertyType<"NamespaceAliasDecl", DeclRef>;
94   def ObjCProtocolDeclRef :
95     SubclassPropertyType<"ObjCProtocolDecl", DeclRef>;
96   def ObjCTypeParamDeclRef :
97     SubclassPropertyType<"ObjCTypeParamDecl", DeclRef>;
98   def TagDeclRef :
99     SubclassPropertyType<"TagDecl", DeclRef>;
100   def TemplateDeclRef :
101     SubclassPropertyType<"TemplateDecl", DeclRef>;
102   def ConceptDeclRef :
103     SubclassPropertyType<"ConceptDecl", DeclRef>;
104   def TemplateTypeParmDeclRef :
105     SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
106   def TemplateTemplateParmDeclRef :
107     SubclassPropertyType<"TemplateTemplateParmDecl", DeclRef>;
108   def ValueDeclRef :
109     SubclassPropertyType<"ValueDecl", DeclRef>;
110 def ElaboratedTypeKeyword : EnumPropertyType;
111 def ExtParameterInfo : PropertyType<"FunctionProtoType::ExtParameterInfo">;
112 def Identifier : RefPropertyType<"IdentifierInfo"> { let ConstWhenWriting = 1; }
113 def NestedNameSpecifier : PropertyType<"NestedNameSpecifier *">;
114 def NestedNameSpecifierKind :
115   EnumPropertyType<"NestedNameSpecifier::SpecifierKind">;
116 def OverloadedOperatorKind : EnumPropertyType;
117 def Qualifiers : PropertyType;
118 def QualType : DefaultValuePropertyType;
119 def RefQualifierKind : EnumPropertyType;
120 def Selector : PropertyType;
121 def SourceLocation : PropertyType;
122 def StmtRef : RefPropertyType<"Stmt"> { let ConstWhenWriting = 1; }
123   def ExprRef : SubclassPropertyType<"Expr", StmtRef>;
124 def TemplateArgument : PropertyType;
125 def TemplateArgumentKind : EnumPropertyType<"TemplateArgument::ArgKind">;
126 def TemplateName : DefaultValuePropertyType;
127 def TemplateNameKind : EnumPropertyType<"TemplateName::NameKind">;
128 def UInt32 : CountPropertyType<"uint32_t">;
129 def UInt64 : CountPropertyType<"uint64_t">;
130 def UnaryTypeTransformKind : EnumPropertyType<"UnaryTransformType::UTTKind">;
131 def VectorKind : EnumPropertyType<"VectorType::VectorKind">;
132
133 def ExceptionSpecInfo : PropertyType<"FunctionProtoType::ExceptionSpecInfo"> {
134   let BufferElementTypes = [ QualType ];
135 }
136
137 /// Arrays.  The corresponding C++ type is ArrayRef of the corresponding
138 /// C++ type of the element.
139 class Array<PropertyType element> : PropertyType {
140   PropertyType Element = element;
141   let BufferElementTypes = [ element ];
142 }
143
144 /// llvm::Optional<T>.  The corresponding C++ type is generally just the
145 /// corresponding C++ type of the element.
146 ///
147 /// Optional<Unsigned> may restrict the range of the operand for some
148 /// serialization clients.
149 class Optional<PropertyType element> : PropertyType {
150   PropertyType Element = element;
151   let PassByReference = element.PassByReference;
152 }
153
154 /// A property of an AST node.
155 class Property<string name, PropertyType type> {
156   HasProperties Class;
157   string Name = name;
158   PropertyType Type = type;
159
160   /// A function for reading the property, expressed in terms of a variable
161   /// "node".
162   code Read;
163
164   /// Code specifying when this property is available.  Can be defined
165   /// in terms of other properties, in which case this property must be
166   /// read/written after those properties.  Using this will make the
167   /// value Optional when deserializing.
168   ///
169   /// FIXME: the emitter doesn't yet force dependent properties to be
170   /// read/written later; this only works if the properties used in the
171   /// condition happen to be written first.
172   code Conditional = "";
173 }
174
175 /// A rule for declaring helper variables when read properties from a
176 /// value of this type.  Note that this means that this code is actually
177 /// run when *writing* values of this type; however, naming this
178 /// `ReadHelper` makes the connection to the `Read` operations on the
179 /// properties much clearer.
180 class ReadHelper<code _code> {
181   HasProperties Class;
182
183   /// Code which will be run when writing objects of this type before
184   /// writing any of the properties, specified in terms of a variable
185   /// `node`.
186   code Code = _code;
187 }
188
189 /// A rule for creating objects of this type.
190 class Creator<code create> {
191   HasProperties Class;
192
193   /// A function for creating values of this kind, expressed in terms of a
194   /// variable `ctx` of type `ASTContext &`.  Must also refer to all of the
195   /// properties by name.
196   code Create = create;
197 }
198
199 /// A rule which overrides some of the normal rules.
200 class Override {
201   HasProperties Class;
202
203   /// Properties from base classes that should be ignored.
204   list<string> IgnoredProperties = [];
205 }
206
207 /// A description of how to break a type into cases.  Providing this and
208 /// an exhaustive list of the cases will cause AbstractBasic{Reader,Writer}
209 /// to be generated with a default implementation of how to read the
210 /// type.
211 ///
212 /// Creator rules for the cases can additionally access a variable
213 /// `kind` of the KindType.
214 class PropertyTypeKind<PropertyType type,
215                        PropertyType kindType,
216                        string readCode> {
217   /// The type for which this describes cases.
218   PropertyType Type = type;
219
220   /// The type of this type's kind enum.
221   PropertyType KindType = kindType;
222
223   /// The property name to use for the kind.
224   string KindPropertyName = "kind";
225
226   /// An expression which reads the kind from a value, expressed in terms
227   /// of a variable `node`.
228   string Read = readCode;
229 }
230
231 /// One of the options for representing a particular type.
232 class PropertyTypeCase<PropertyType type, string name> : HasProperties {
233   /// The type of which this is a case.
234   PropertyType Type = type;
235
236   /// The name of the case (a value of the type's kind enum).
237   string Name = name;
238 }
239
240 // Type cases for DeclarationName.
241 def : PropertyTypeKind<DeclarationName, DeclarationNameKind,
242                        "node.getNameKind()">;
243 let Class = PropertyTypeCase<DeclarationName, "Identifier"> in {
244   def : Property<"identifier", Identifier> {
245     let Read = [{ node.getAsIdentifierInfo() }];
246   }
247   def : Creator<[{
248     return DeclarationName(identifier);
249   }]>;
250 }
251 foreach count = ["Zero", "One", "Multi"] in {
252   let Class = PropertyTypeCase<DeclarationName, "ObjC"#count#"ArgSelector"> in {
253     def : Property<"selector", Selector> {
254       let Read = [{ node.getObjCSelector() }];
255     }
256     def : Creator<[{
257       return DeclarationName(selector);
258     }]>;
259   }
260 }
261 foreach kind = ["Constructor", "Destructor", "ConversionFunction"] in {
262   let Class = PropertyTypeCase<DeclarationName, "CXX"#kind#"Name"> in {
263     def : Property<"type", QualType> {
264       let Read = [{ node.getCXXNameType() }];
265     }
266     def : Creator<[{
267       return ctx.DeclarationNames.getCXX}]#kind#[{Name(
268                ctx.getCanonicalType(type));
269     }]>;
270   }
271 }
272 let Class = PropertyTypeCase<DeclarationName, "CXXDeductionGuideName"> in {
273   def : Property<"declaration", TemplateDeclRef> {
274     let Read = [{ node.getCXXDeductionGuideTemplate() }];
275   }
276   def : Creator<[{
277     return ctx.DeclarationNames.getCXXDeductionGuideName(declaration);
278   }]>;
279 }
280 let Class = PropertyTypeCase<DeclarationName, "CXXOperatorName"> in {
281   def : Property<"operatorKind", OverloadedOperatorKind> {
282     let Read = [{ node.getCXXOverloadedOperator() }];
283   }
284   def : Creator<[{
285     return ctx.DeclarationNames.getCXXOperatorName(operatorKind);
286   }]>;
287 }
288 let Class = PropertyTypeCase<DeclarationName, "CXXLiteralOperatorName"> in {
289   def : Property<"identifier", Identifier> {
290     let Read = [{ node.getCXXLiteralIdentifier() }];
291   }
292   def : Creator<[{
293     return ctx.DeclarationNames.getCXXLiteralOperatorName(identifier);
294   }]>;
295 }
296 let Class = PropertyTypeCase<DeclarationName, "CXXUsingDirective"> in {
297   def : Creator<[{
298     return DeclarationName::getUsingDirectiveName();
299   }]>;
300 }
301
302 // Type cases for TemplateName.
303 def : PropertyTypeKind<TemplateName, TemplateNameKind, "node.getKind()">;
304 let Class = PropertyTypeCase<TemplateName, "Template"> in {
305   def : Property<"declaration", TemplateDeclRef> {
306     let Read = [{ node.getAsTemplateDecl() }];
307   }
308   def : Creator<[{
309     return TemplateName(declaration);
310   }]>;
311 }
312 let Class = PropertyTypeCase<TemplateName, "OverloadedTemplate"> in {
313   def : Property<"overloads", Array<NamedDeclRef>> {
314     let Read = [{ node.getAsOverloadedTemplate()->decls() }];
315   }
316   def : Creator<[{
317     // Copy into an UnresolvedSet to satisfy the interface.
318     UnresolvedSet<8> overloadSet;
319     for (auto overload : overloads) {
320       overloadSet.addDecl(overload);
321     }
322
323     return ctx.getOverloadedTemplateName(overloadSet.begin(),
324                                          overloadSet.end());
325   }]>;
326 }
327 let Class = PropertyTypeCase<TemplateName, "AssumedTemplate"> in {
328   def : Property<"name", DeclarationName> {
329     let Read = [{ node.getAsAssumedTemplateName()->getDeclName() }];
330   }
331   def : Creator<[{
332     return ctx.getAssumedTemplateName(name);
333   }]>;
334 }
335 let Class = PropertyTypeCase<TemplateName, "QualifiedTemplate"> in {
336   def : ReadHelper<[{
337     auto qtn = node.getAsQualifiedTemplateName();
338   }]>;
339   def : Property<"qualifier", NestedNameSpecifier> {
340     let Read = [{ qtn->getQualifier() }];
341   }
342   def : Property<"hasTemplateKeyword", Bool> {
343     let Read = [{ qtn->hasTemplateKeyword() }];
344   }
345   def : Property<"declaration", TemplateDeclRef> {
346     let Read = [{ qtn->getTemplateDecl() }];
347   }
348   def : Creator<[{
349     return ctx.getQualifiedTemplateName(qualifier, hasTemplateKeyword,
350                                         declaration);
351   }]>;
352 }
353 let Class = PropertyTypeCase<TemplateName, "DependentTemplate"> in {
354   def : ReadHelper<[{
355     auto dtn = node.getAsDependentTemplateName();
356   }]>;
357   def : Property<"qualifier", NestedNameSpecifier> {
358     let Read = [{ dtn->getQualifier() }];
359   }
360   def : Property<"identifier", Optional<Identifier>> {
361     let Read = [{ makeOptionalFromPointer(
362                     dtn->isIdentifier()
363                       ? dtn->getIdentifier()
364                       : nullptr) }];
365   }
366   def : Property<"operatorKind", OverloadedOperatorKind> {
367     let Conditional = [{ !identifier }];
368     let Read = [{ dtn->getOperator() }];
369   }
370   def : Creator<[{
371     if (identifier) {
372       return ctx.getDependentTemplateName(qualifier, *identifier);
373     } else {
374       return ctx.getDependentTemplateName(qualifier, *operatorKind);
375     }
376   }]>;
377 }
378 let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParm"> in {
379   def : ReadHelper<[{
380     auto parm = node.getAsSubstTemplateTemplateParm();
381   }]>;
382   def : Property<"parameter", TemplateTemplateParmDeclRef> {
383     let Read = [{ parm->getParameter() }];
384   }
385   def : Property<"replacement", TemplateName> {
386     let Read = [{ parm->getReplacement() }];
387   }
388   def : Creator<[{
389     return ctx.getSubstTemplateTemplateParm(parameter, replacement);
390   }]>;
391 }
392 let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in {
393   def : ReadHelper<[{
394     auto parm = node.getAsSubstTemplateTemplateParmPack();
395   }]>;
396   def : Property<"parameterPack", TemplateTemplateParmDeclRef> {
397     let Read = [{ parm->getParameterPack() }];
398   }
399   def : Property<"argumentPack", TemplateArgument> {
400     let Read = [{ parm->getArgumentPack() }];
401   }
402   def : Creator<[{
403     return ctx.getSubstTemplateTemplateParmPack(parameterPack, argumentPack);
404   }]>;
405 }
406
407 // Type cases for TemplateArgument.
408 def : PropertyTypeKind<TemplateArgument, TemplateArgumentKind,
409                        "node.getKind()">;
410 let Class = PropertyTypeCase<TemplateArgument, "Null"> in {
411   def : Creator<[{
412     return TemplateArgument();
413   }]>;
414 }
415 let Class = PropertyTypeCase<TemplateArgument, "Type"> in {
416   def : Property<"type", QualType> {
417     let Read = [{ node.getAsType() }];
418   }
419   def : Creator<[{
420     return TemplateArgument(type);
421   }]>;
422 }
423 let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in {
424   def : Property<"declaration", ValueDeclRef> {
425     let Read = [{ node.getAsDecl() }];
426   }
427   def : Property<"parameterType", QualType> {
428     let Read = [{ node.getParamTypeForDecl() }];
429   }
430   def : Creator<[{
431     return TemplateArgument(declaration, parameterType);
432   }]>;
433 }
434 let Class = PropertyTypeCase<TemplateArgument, "NullPtr"> in {
435   def : Property<"type", QualType> {
436     let Read = [{ node.getNullPtrType() }];
437   }
438   def : Creator<[{
439     return TemplateArgument(type, /*nullptr*/ true);
440   }]>;
441 }
442 let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
443   def : Property<"value", APSInt> {
444     let Read = [{ node.getAsIntegral() }];
445   }
446   def : Property<"type", QualType> {
447     let Read = [{ node.getIntegralType() }];
448   }
449   def : Creator<[{
450     return TemplateArgument(ctx, value, type);
451   }]>;
452 }
453 let Class = PropertyTypeCase<TemplateArgument, "Template"> in {
454   def : Property<"name", TemplateName> {
455     let Read = [{ node.getAsTemplateOrTemplatePattern() }];
456   }
457   def : Creator<[{
458     return TemplateArgument(name);
459   }]>;
460 }
461 let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in {
462   def : Property<"name", TemplateName> {
463     let Read = [{ node.getAsTemplateOrTemplatePattern() }];
464   }
465   def : Property<"numExpansions", Optional<UInt32>> {
466     let Read = [{
467       // Translate unsigned -> uint32_t just in case.
468       node.getNumTemplateExpansions().map(
469         [](unsigned i) { return uint32_t(i); })
470     }];
471   }
472   def : Creator<[{
473     auto numExpansionsUnsigned =
474       numExpansions.map([](uint32_t i) { return unsigned(i); });
475     return TemplateArgument(name, numExpansionsUnsigned);
476   }]>;
477 }
478 let Class = PropertyTypeCase<TemplateArgument, "Expression"> in {
479   def : Property<"expression", ExprRef> {
480     let Read = [{ node.getAsExpr() }];
481   }
482   def : Creator<[{
483     return TemplateArgument(expression);
484   }]>;
485 }
486 let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {
487   def : Property<"elements", Array<TemplateArgument>> {
488     let Read = [{ node.pack_elements() }];
489   }
490   def : Creator<[{
491     // Copy the pack into the ASTContext.
492     TemplateArgument *ctxElements = new (ctx) TemplateArgument[elements.size()];
493     for (size_t i = 0, e = elements.size(); i != e; ++i)
494       ctxElements[i] = elements[i];
495     return TemplateArgument(llvm::makeArrayRef(ctxElements, elements.size()));
496   }]>;
497 }