1480093f4SDimitry Andric//==--- PropertiesBase.td - Baseline definitions for AST properties -------===// 2480093f4SDimitry Andric// 3480093f4SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric// 7480093f4SDimitry Andric//===----------------------------------------------------------------------===// 8480093f4SDimitry Andric 9480093f4SDimitry Andricclass HasProperties; 10480093f4SDimitry Andric 11480093f4SDimitry Andric/// The type of the property. 12480093f4SDimitry Andricclass PropertyType<string typeName = ""> { 13480093f4SDimitry Andric /// The C++ type name for the type. 14480093f4SDimitry Andric string CXXName = !if(!ne(typeName, ""), typeName, NAME); 15480093f4SDimitry Andric 16480093f4SDimitry Andric /// Whether the C++ type should generally be passed around by reference. 17480093f4SDimitry Andric bit PassByReference = 0; 18480093f4SDimitry Andric 19480093f4SDimitry Andric /// Whether `const` should be prepended to the type when writing. 20480093f4SDimitry Andric bit ConstWhenWriting = 0; 21480093f4SDimitry Andric 22480093f4SDimitry Andric /// Given a value of type Optional<CXXName> bound as 'value', yield a 23480093f4SDimitry Andric /// CXXName that can be serialized into a DataStreamTypeWriter. 24480093f4SDimitry Andric string PackOptional = ""; 25480093f4SDimitry Andric 26480093f4SDimitry Andric /// Given a value of type CXXName bound as 'value' that was deserialized 27480093f4SDimitry Andric /// by a DataStreamTypeReader, yield an Optional<CXXName>. 28480093f4SDimitry Andric string UnpackOptional = ""; 29480093f4SDimitry Andric 30480093f4SDimitry Andric /// A list of types for which buffeers must be passed to the read 31480093f4SDimitry Andric /// operations. 32480093f4SDimitry Andric list<PropertyType> BufferElementTypes = []; 33480093f4SDimitry Andric} 34480093f4SDimitry Andric 35480093f4SDimitry Andric/// Property types that correspond to specific C++ enums. 36480093f4SDimitry Andricclass EnumPropertyType<string typeName = ""> : PropertyType<typeName> {} 37480093f4SDimitry Andric 38480093f4SDimitry Andric/// Property types that correspond to a specific C++ class. 39480093f4SDimitry Andric/// Supports optional values by using the null representation. 40480093f4SDimitry Andricclass RefPropertyType<string className> : PropertyType<className # "*"> { 41480093f4SDimitry Andric let PackOptional = 42480093f4SDimitry Andric "value ? *value : nullptr"; 43480093f4SDimitry Andric let UnpackOptional = 44bdd1243dSDimitry Andric "value ? std::optional<" # CXXName # ">(value) : std::nullopt"; 45480093f4SDimitry Andric} 46480093f4SDimitry Andric 47480093f4SDimitry Andric/// Property types that correspond to a specific subclass of another type. 48480093f4SDimitry Andricclass SubclassPropertyType<string className, PropertyType base> 49480093f4SDimitry Andric : RefPropertyType<className> { 50480093f4SDimitry Andric PropertyType Base = base; 51480093f4SDimitry Andric string SubclassName = className; 52480093f4SDimitry Andric let ConstWhenWriting = base.ConstWhenWriting; 53480093f4SDimitry Andric} 54480093f4SDimitry Andric 55480093f4SDimitry Andric/// Property types that support optional values by using their 56480093f4SDimitry Andric/// default value. 57480093f4SDimitry Andricclass DefaultValuePropertyType<string typeName = ""> : PropertyType<typeName> { 58480093f4SDimitry Andric let PackOptional = 59480093f4SDimitry Andric "value ? *value : " # CXXName # "()"; 60480093f4SDimitry Andric let UnpackOptional = 61bdd1243dSDimitry Andric "value.isNull() ? std::nullopt : std::optional<" # CXXName # ">(value)"; 62480093f4SDimitry Andric} 63480093f4SDimitry Andric 64480093f4SDimitry Andric/// Property types that correspond to integer types and support optional 65480093f4SDimitry Andric/// values by shifting the value over by 1. 66480093f4SDimitry Andricclass CountPropertyType<string typeName = ""> : PropertyType<typeName> { 67480093f4SDimitry Andric let PackOptional = 68480093f4SDimitry Andric "value ? *value + 1 : 0"; 69480093f4SDimitry Andric let UnpackOptional = 70bdd1243dSDimitry Andric "value ? std::optional<" # CXXName # ">(value - 1) : std::nullopt"; 71480093f4SDimitry Andric} 72480093f4SDimitry Andric 73480093f4SDimitry Andricdef APInt : PropertyType<"llvm::APInt"> { let PassByReference = 1; } 74480093f4SDimitry Andricdef APSInt : PropertyType<"llvm::APSInt"> { let PassByReference = 1; } 75e8d8bef9SDimitry Andricdef APValue : PropertyType { let PassByReference = 1; } 76e8d8bef9SDimitry Andricdef APValueKind : EnumPropertyType<"APValue::ValueKind">; 775f757f3fSDimitry Andricdef ArraySizeModifier : EnumPropertyType<"ArraySizeModifier">; 78480093f4SDimitry Andricdef AttrKind : EnumPropertyType<"attr::Kind">; 79480093f4SDimitry Andricdef AutoTypeKeyword : EnumPropertyType; 80480093f4SDimitry Andricdef Bool : PropertyType<"bool">; 81480093f4SDimitry Andricdef BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">; 8281ad6265SDimitry Andricdef BTFTypeTagAttr : PropertyType<"const BTFTypeTagAttr *">; 83480093f4SDimitry Andricdef CallingConv : EnumPropertyType; 84480093f4SDimitry Andricdef DeclarationName : PropertyType; 85480093f4SDimitry Andricdef DeclarationNameKind : EnumPropertyType<"DeclarationName::NameKind">; 86480093f4SDimitry Andricdef DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; } 87480093f4SDimitry Andric def CXXRecordDeclRef : 88480093f4SDimitry Andric SubclassPropertyType<"CXXRecordDecl", DeclRef>; 89480093f4SDimitry Andric def FunctionDeclRef : 90480093f4SDimitry Andric SubclassPropertyType<"FunctionDecl", DeclRef>; 91480093f4SDimitry Andric def NamedDeclRef : 92480093f4SDimitry Andric SubclassPropertyType<"NamedDecl", DeclRef>; 93480093f4SDimitry Andric def NamespaceDeclRef : 94480093f4SDimitry Andric SubclassPropertyType<"NamespaceDecl", DeclRef>; 95480093f4SDimitry Andric def NamespaceAliasDeclRef : 96480093f4SDimitry Andric SubclassPropertyType<"NamespaceAliasDecl", DeclRef>; 97480093f4SDimitry Andric def ObjCProtocolDeclRef : 98480093f4SDimitry Andric SubclassPropertyType<"ObjCProtocolDecl", DeclRef>; 99480093f4SDimitry Andric def ObjCTypeParamDeclRef : 100480093f4SDimitry Andric SubclassPropertyType<"ObjCTypeParamDecl", DeclRef>; 101480093f4SDimitry Andric def TagDeclRef : 102480093f4SDimitry Andric SubclassPropertyType<"TagDecl", DeclRef>; 103480093f4SDimitry Andric def TemplateDeclRef : 104480093f4SDimitry Andric SubclassPropertyType<"TemplateDecl", DeclRef>; 10555e4f9d5SDimitry Andric def ConceptDeclRef : 10655e4f9d5SDimitry Andric SubclassPropertyType<"ConceptDecl", DeclRef>; 107480093f4SDimitry Andric def TemplateTypeParmDeclRef : 108480093f4SDimitry Andric SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>; 109480093f4SDimitry Andric def TemplateTemplateParmDeclRef : 110480093f4SDimitry Andric SubclassPropertyType<"TemplateTemplateParmDecl", DeclRef>; 1110eae32dcSDimitry Andric def UsingShadowDeclRef : 1120eae32dcSDimitry Andric SubclassPropertyType<"UsingShadowDecl", DeclRef>; 113480093f4SDimitry Andric def ValueDeclRef : 114480093f4SDimitry Andric SubclassPropertyType<"ValueDecl", DeclRef>; 115480093f4SDimitry Andricdef ElaboratedTypeKeyword : EnumPropertyType; 116480093f4SDimitry Andricdef ExtParameterInfo : PropertyType<"FunctionProtoType::ExtParameterInfo">; 117e8d8bef9SDimitry Andricdef FixedPointSemantics : PropertyType<"llvm::FixedPointSemantics"> { 118e8d8bef9SDimitry Andric let PassByReference = 1; 119e8d8bef9SDimitry Andric} 120480093f4SDimitry Andricdef Identifier : RefPropertyType<"IdentifierInfo"> { let ConstWhenWriting = 1; } 121e8d8bef9SDimitry Andricdef LValuePathEntry : PropertyType<"APValue::LValuePathEntry">; 122e8d8bef9SDimitry Andricdef LValuePathSerializationHelper : 123e8d8bef9SDimitry Andric PropertyType<"APValue::LValuePathSerializationHelper"> { 124e8d8bef9SDimitry Andric let BufferElementTypes = [ LValuePathEntry ]; 125e8d8bef9SDimitry Andric} 126480093f4SDimitry Andricdef NestedNameSpecifier : PropertyType<"NestedNameSpecifier *">; 127480093f4SDimitry Andricdef NestedNameSpecifierKind : 128480093f4SDimitry Andric EnumPropertyType<"NestedNameSpecifier::SpecifierKind">; 129480093f4SDimitry Andricdef OverloadedOperatorKind : EnumPropertyType; 130480093f4SDimitry Andricdef Qualifiers : PropertyType; 131480093f4SDimitry Andricdef QualType : DefaultValuePropertyType; 132480093f4SDimitry Andricdef RefQualifierKind : EnumPropertyType; 133480093f4SDimitry Andricdef Selector : PropertyType; 134480093f4SDimitry Andricdef SourceLocation : PropertyType; 135480093f4SDimitry Andricdef StmtRef : RefPropertyType<"Stmt"> { let ConstWhenWriting = 1; } 136480093f4SDimitry Andric def ExprRef : SubclassPropertyType<"Expr", StmtRef>; 137480093f4SDimitry Andricdef TemplateArgument : PropertyType; 138480093f4SDimitry Andricdef TemplateArgumentKind : EnumPropertyType<"TemplateArgument::ArgKind">; 139480093f4SDimitry Andricdef TemplateName : DefaultValuePropertyType; 140480093f4SDimitry Andricdef TemplateNameKind : EnumPropertyType<"TemplateName::NameKind">; 141bdd1243dSDimitry Andricdef TypeOfKind : EnumPropertyType<"TypeOfKind">; 142480093f4SDimitry Andricdef UInt32 : CountPropertyType<"uint32_t">; 143480093f4SDimitry Andricdef UInt64 : CountPropertyType<"uint64_t">; 144480093f4SDimitry Andricdef UnaryTypeTransformKind : EnumPropertyType<"UnaryTransformType::UTTKind">; 1455f757f3fSDimitry Andricdef VectorKind : EnumPropertyType<"VectorKind">; 146480093f4SDimitry Andric 147480093f4SDimitry Andricdef ExceptionSpecInfo : PropertyType<"FunctionProtoType::ExceptionSpecInfo"> { 148480093f4SDimitry Andric let BufferElementTypes = [ QualType ]; 149480093f4SDimitry Andric} 150480093f4SDimitry Andric 151480093f4SDimitry Andric/// Arrays. The corresponding C++ type is ArrayRef of the corresponding 152480093f4SDimitry Andric/// C++ type of the element. 153480093f4SDimitry Andricclass Array<PropertyType element> : PropertyType { 154480093f4SDimitry Andric PropertyType Element = element; 155480093f4SDimitry Andric let BufferElementTypes = [ element ]; 156480093f4SDimitry Andric} 157480093f4SDimitry Andric 158bdd1243dSDimitry Andric/// std::optional<T>. The corresponding C++ type is generally just the 159480093f4SDimitry Andric/// corresponding C++ type of the element. 160480093f4SDimitry Andric/// 161480093f4SDimitry Andric/// Optional<Unsigned> may restrict the range of the operand for some 162480093f4SDimitry Andric/// serialization clients. 163480093f4SDimitry Andricclass Optional<PropertyType element> : PropertyType { 164480093f4SDimitry Andric PropertyType Element = element; 165480093f4SDimitry Andric let PassByReference = element.PassByReference; 166480093f4SDimitry Andric} 167480093f4SDimitry Andric 168480093f4SDimitry Andric/// A property of an AST node. 169480093f4SDimitry Andricclass Property<string name, PropertyType type> { 170480093f4SDimitry Andric HasProperties Class; 171480093f4SDimitry Andric string Name = name; 172480093f4SDimitry Andric PropertyType Type = type; 173480093f4SDimitry Andric 174480093f4SDimitry Andric /// A function for reading the property, expressed in terms of a variable 175480093f4SDimitry Andric /// "node". 176480093f4SDimitry Andric code Read; 177480093f4SDimitry Andric 178480093f4SDimitry Andric /// Code specifying when this property is available. Can be defined 179480093f4SDimitry Andric /// in terms of other properties, in which case this property must be 180480093f4SDimitry Andric /// read/written after those properties. Using this will make the 181480093f4SDimitry Andric /// value Optional when deserializing. 182480093f4SDimitry Andric /// 183480093f4SDimitry Andric /// FIXME: the emitter doesn't yet force dependent properties to be 184480093f4SDimitry Andric /// read/written later; this only works if the properties used in the 185480093f4SDimitry Andric /// condition happen to be written first. 186480093f4SDimitry Andric code Conditional = ""; 187480093f4SDimitry Andric} 188480093f4SDimitry Andric 189480093f4SDimitry Andric/// A rule for declaring helper variables when read properties from a 190480093f4SDimitry Andric/// value of this type. Note that this means that this code is actually 191480093f4SDimitry Andric/// run when *writing* values of this type; however, naming this 192480093f4SDimitry Andric/// `ReadHelper` makes the connection to the `Read` operations on the 193480093f4SDimitry Andric/// properties much clearer. 194480093f4SDimitry Andricclass ReadHelper<code _code> { 195480093f4SDimitry Andric HasProperties Class; 196480093f4SDimitry Andric 197480093f4SDimitry Andric /// Code which will be run when writing objects of this type before 198480093f4SDimitry Andric /// writing any of the properties, specified in terms of a variable 199480093f4SDimitry Andric /// `node`. 200480093f4SDimitry Andric code Code = _code; 201480093f4SDimitry Andric} 202480093f4SDimitry Andric 203480093f4SDimitry Andric/// A rule for creating objects of this type. 204480093f4SDimitry Andricclass Creator<code create> { 205480093f4SDimitry Andric HasProperties Class; 206480093f4SDimitry Andric 207480093f4SDimitry Andric /// A function for creating values of this kind, expressed in terms of a 208480093f4SDimitry Andric /// variable `ctx` of type `ASTContext &`. Must also refer to all of the 209480093f4SDimitry Andric /// properties by name. 210480093f4SDimitry Andric code Create = create; 211480093f4SDimitry Andric} 212480093f4SDimitry Andric 213480093f4SDimitry Andric/// A rule which overrides some of the normal rules. 214480093f4SDimitry Andricclass Override { 215480093f4SDimitry Andric HasProperties Class; 216480093f4SDimitry Andric 217480093f4SDimitry Andric /// Properties from base classes that should be ignored. 218480093f4SDimitry Andric list<string> IgnoredProperties = []; 219480093f4SDimitry Andric} 220480093f4SDimitry Andric 221480093f4SDimitry Andric/// A description of how to break a type into cases. Providing this and 222480093f4SDimitry Andric/// an exhaustive list of the cases will cause AbstractBasic{Reader,Writer} 223480093f4SDimitry Andric/// to be generated with a default implementation of how to read the 224480093f4SDimitry Andric/// type. 225480093f4SDimitry Andric/// 226480093f4SDimitry Andric/// Creator rules for the cases can additionally access a variable 227480093f4SDimitry Andric/// `kind` of the KindType. 228480093f4SDimitry Andricclass PropertyTypeKind<PropertyType type, 229480093f4SDimitry Andric PropertyType kindType, 230480093f4SDimitry Andric string readCode> { 231480093f4SDimitry Andric /// The type for which this describes cases. 232480093f4SDimitry Andric PropertyType Type = type; 233480093f4SDimitry Andric 234480093f4SDimitry Andric /// The type of this type's kind enum. 235480093f4SDimitry Andric PropertyType KindType = kindType; 236480093f4SDimitry Andric 237480093f4SDimitry Andric /// The property name to use for the kind. 238480093f4SDimitry Andric string KindPropertyName = "kind"; 239480093f4SDimitry Andric 240480093f4SDimitry Andric /// An expression which reads the kind from a value, expressed in terms 241480093f4SDimitry Andric /// of a variable `node`. 242480093f4SDimitry Andric string Read = readCode; 243480093f4SDimitry Andric} 244480093f4SDimitry Andric 245480093f4SDimitry Andric/// One of the options for representing a particular type. 246480093f4SDimitry Andricclass PropertyTypeCase<PropertyType type, string name> : HasProperties { 247480093f4SDimitry Andric /// The type of which this is a case. 248480093f4SDimitry Andric PropertyType Type = type; 249480093f4SDimitry Andric 250480093f4SDimitry Andric /// The name of the case (a value of the type's kind enum). 251480093f4SDimitry Andric string Name = name; 252480093f4SDimitry Andric} 253480093f4SDimitry Andric 254e8d8bef9SDimitry Andric// Type cases for APValue. 255e8d8bef9SDimitry Andricdef : PropertyTypeKind<APValue, APValueKind, 256e8d8bef9SDimitry Andric "node.getKind()">; 257e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "None"> in { 258e8d8bef9SDimitry Andric def : Creator<[{ return APValue(); }]>; 259e8d8bef9SDimitry Andric} 260e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "Indeterminate"> in { 261e8d8bef9SDimitry Andric def : Creator<[{ return APValue::IndeterminateValue(); }]>; 262e8d8bef9SDimitry Andric} 263e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "Int"> in { 264e8d8bef9SDimitry Andric def : Property<"value", APSInt> { 265e8d8bef9SDimitry Andric let Read = [{ node.getInt() }]; 266e8d8bef9SDimitry Andric } 267e8d8bef9SDimitry Andric def : Creator<[{ return APValue(value); }]>; 268e8d8bef9SDimitry Andric} 269e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "Float"> in { 270e8d8bef9SDimitry Andric def : Property<"semantics", UInt32> { 271e8d8bef9SDimitry Andric let Read = [{ 272e8d8bef9SDimitry Andric static_cast<uint32_t>( 273e8d8bef9SDimitry Andric llvm::APFloatBase::SemanticsToEnum(node.getFloat().getSemantics())) 274e8d8bef9SDimitry Andric }]; 275e8d8bef9SDimitry Andric } 276e8d8bef9SDimitry Andric def : Property<"value", APInt> { 277e8d8bef9SDimitry Andric let Read = [{ node.getFloat().bitcastToAPInt() }]; 278e8d8bef9SDimitry Andric } 279e8d8bef9SDimitry Andric def : Creator<[{ 280e8d8bef9SDimitry Andric const llvm::fltSemantics &floatSema = llvm::APFloatBase::EnumToSemantics( 281e8d8bef9SDimitry Andric static_cast<llvm::APFloatBase::Semantics>(semantics)); 282e8d8bef9SDimitry Andric return APValue(llvm::APFloat(floatSema, value)); 283e8d8bef9SDimitry Andric }]>; 284e8d8bef9SDimitry Andric} 285e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "FixedPoint"> in { 286e8d8bef9SDimitry Andric def : Property<"semantics", FixedPointSemantics> { 287e8d8bef9SDimitry Andric let Read = [{ node.getFixedPoint().getSemantics() }]; 288e8d8bef9SDimitry Andric } 289e8d8bef9SDimitry Andric def : Property<"value", APSInt> { 290e8d8bef9SDimitry Andric let Read = [{ node.getFixedPoint().getValue() }]; 291e8d8bef9SDimitry Andric } 292e8d8bef9SDimitry Andric def : Creator<[{ 293e8d8bef9SDimitry Andric return APValue(llvm::APFixedPoint(std::move(value), semantics)); 294e8d8bef9SDimitry Andric }]>; 295e8d8bef9SDimitry Andric} 296e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "ComplexInt"> in { 297e8d8bef9SDimitry Andric def : Property<"real", APSInt> { 298e8d8bef9SDimitry Andric let Read = [{ node.getComplexIntReal() }]; 299e8d8bef9SDimitry Andric } 300e8d8bef9SDimitry Andric def : Property<"imag", APSInt> { 301e8d8bef9SDimitry Andric let Read = [{ node.getComplexIntImag() }]; 302e8d8bef9SDimitry Andric } 303e8d8bef9SDimitry Andric def : Creator<[{ return APValue(real, imag); }]>; 304e8d8bef9SDimitry Andric} 305e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "ComplexFloat"> in { 306e8d8bef9SDimitry Andric def : ReadHelper<[{ 307e8d8bef9SDimitry Andric auto sema = llvm::APFloatBase::SemanticsToEnum( 308e8d8bef9SDimitry Andric node.getComplexFloatReal().getSemantics()); 309e8d8bef9SDimitry Andric assert(sema == llvm::APFloatBase::SemanticsToEnum( 310e8d8bef9SDimitry Andric node.getComplexFloatImag().getSemantics())); 311e8d8bef9SDimitry Andric }]>; 312e8d8bef9SDimitry Andric def : Property<"semantics", UInt32> { 313e8d8bef9SDimitry Andric let Read = [{ static_cast<uint32_t>(sema) }]; 314e8d8bef9SDimitry Andric } 315e8d8bef9SDimitry Andric def : Property<"real", APInt> { 316e8d8bef9SDimitry Andric let Read = [{ node.getComplexFloatReal().bitcastToAPInt() }]; 317e8d8bef9SDimitry Andric } 318e8d8bef9SDimitry Andric def : Property<"imag", APInt> { 319e8d8bef9SDimitry Andric let Read = [{ node.getComplexFloatImag().bitcastToAPInt() }]; 320e8d8bef9SDimitry Andric } 321e8d8bef9SDimitry Andric def : Creator<[{ 322e8d8bef9SDimitry Andric const llvm::fltSemantics &sema = llvm::APFloatBase::EnumToSemantics( 323e8d8bef9SDimitry Andric static_cast<llvm::APFloatBase::Semantics>(semantics)); 324e8d8bef9SDimitry Andric return APValue(llvm::APFloat(sema, real), 325e8d8bef9SDimitry Andric llvm::APFloat(sema, imag)); 326e8d8bef9SDimitry Andric }]>; 327e8d8bef9SDimitry Andric} 328e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "Vector"> in { 329e8d8bef9SDimitry Andric def : ReadHelper<[{ 330e8d8bef9SDimitry Andric SmallVector<APValue, 4> buffer; 331e8d8bef9SDimitry Andric unsigned len = node.getVectorLength(); 332e8d8bef9SDimitry Andric for (unsigned i = 0; i < len; ++i) 333e8d8bef9SDimitry Andric buffer.push_back(node.getVectorElt(i)); 334e8d8bef9SDimitry Andric }]>; 335e8d8bef9SDimitry Andric def : Property<"elements", Array<APValue>> { 336e8d8bef9SDimitry Andric let Read = [{ buffer }]; 337e8d8bef9SDimitry Andric } 338e8d8bef9SDimitry Andric def : Creator<[{ 339e8d8bef9SDimitry Andric APValue result; 340e8d8bef9SDimitry Andric result.MakeVector(); 341e8d8bef9SDimitry Andric unsigned length = elements.size(); 342e8d8bef9SDimitry Andric (void)result.setVectorUninit(length); 343e8d8bef9SDimitry Andric for (unsigned i = 0; i < length; i++) 344e8d8bef9SDimitry Andric result.getVectorElt(i) = elements[i]; 345e8d8bef9SDimitry Andric return result; 346e8d8bef9SDimitry Andric }]>; 347e8d8bef9SDimitry Andric} 348e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "Array"> in { 349e8d8bef9SDimitry Andric def : ReadHelper<[{ 350e8d8bef9SDimitry Andric SmallVector<APValue, 4> buffer{}; 351e8d8bef9SDimitry Andric unsigned initLength = node.getArrayInitializedElts(); 352e8d8bef9SDimitry Andric for (unsigned i = 0; i < initLength; ++i) 353e8d8bef9SDimitry Andric buffer.push_back(node.getArrayInitializedElt(i)); 354e8d8bef9SDimitry Andric if (node.hasArrayFiller()) 355e8d8bef9SDimitry Andric buffer.push_back(node.getArrayFiller()); 356e8d8bef9SDimitry Andric }]>; 357e8d8bef9SDimitry Andric def : Property<"totalLength", UInt32> { 358e8d8bef9SDimitry Andric let Read = [{ node.getArraySize() }]; 359e8d8bef9SDimitry Andric } 360e8d8bef9SDimitry Andric def : Property<"hasFiller", Bool> { 361e8d8bef9SDimitry Andric let Read = [{ node.hasArrayFiller() }]; 362e8d8bef9SDimitry Andric } 363e8d8bef9SDimitry Andric def : Property<"elements", Array<APValue>> { 364e8d8bef9SDimitry Andric let Read = [{ buffer }]; 365e8d8bef9SDimitry Andric } 366e8d8bef9SDimitry Andric def : Creator<[{ 367e8d8bef9SDimitry Andric APValue result; 368e8d8bef9SDimitry Andric unsigned initLength = elements.size() - (hasFiller ? 1 : 0); 369e8d8bef9SDimitry Andric result.MakeArray(initLength, totalLength); 370e8d8bef9SDimitry Andric for (unsigned i = 0; i < initLength; ++i) 371e8d8bef9SDimitry Andric result.getArrayInitializedElt(i) = elements[i]; 372e8d8bef9SDimitry Andric if (hasFiller) 373e8d8bef9SDimitry Andric result.getArrayFiller() = elements.back(); 374e8d8bef9SDimitry Andric return result; 375e8d8bef9SDimitry Andric }]>; 376e8d8bef9SDimitry Andric} 377e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "Struct"> in { 378e8d8bef9SDimitry Andric def : ReadHelper<[{ 379e8d8bef9SDimitry Andric SmallVector<APValue, 4> structBases; 380e8d8bef9SDimitry Andric unsigned numBases = node.getStructNumBases(); 381e8d8bef9SDimitry Andric for (unsigned i = 0; i < numBases; ++i) 382e8d8bef9SDimitry Andric structBases.push_back(node.getStructBase(i)); 383e8d8bef9SDimitry Andric SmallVector<APValue, 4> structFields; 384e8d8bef9SDimitry Andric unsigned numFields = node.getStructNumFields(); 385e8d8bef9SDimitry Andric for (unsigned i = 0; i < numFields; ++i) 386e8d8bef9SDimitry Andric structFields.push_back(node.getStructField(i)); 387e8d8bef9SDimitry Andric }]>; 388e8d8bef9SDimitry Andric def : Property<"bases", Array<APValue>> { 389e8d8bef9SDimitry Andric let Read = [{ structBases }]; 390e8d8bef9SDimitry Andric } 391e8d8bef9SDimitry Andric def : Property<"fields", Array<APValue>> { 392e8d8bef9SDimitry Andric let Read = [{ structFields }]; 393e8d8bef9SDimitry Andric } 394e8d8bef9SDimitry Andric def : Creator<[{ 395e8d8bef9SDimitry Andric APValue result; 396e8d8bef9SDimitry Andric result.MakeStruct(bases.size(), fields.size()); 397e8d8bef9SDimitry Andric for (unsigned i = 0; i < bases.size(); ++i) 398e8d8bef9SDimitry Andric result.getStructBase(i) = bases[i]; 399e8d8bef9SDimitry Andric for (unsigned i = 0; i < fields.size(); ++i) 400e8d8bef9SDimitry Andric result.getStructField(i) = fields[i]; 401e8d8bef9SDimitry Andric return result; 402e8d8bef9SDimitry Andric }]>; 403e8d8bef9SDimitry Andric} 404e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "Union"> in { 405e8d8bef9SDimitry Andric def : Property<"fieldDecl", DeclRef> { 406e8d8bef9SDimitry Andric let Read = [{ node.getUnionField() }]; 407e8d8bef9SDimitry Andric } 408e8d8bef9SDimitry Andric def : Property<"value", APValue> { 409e8d8bef9SDimitry Andric let Read = [{ node.getUnionValue() }]; 410e8d8bef9SDimitry Andric } 411e8d8bef9SDimitry Andric def : Creator<[{ 412e8d8bef9SDimitry Andric return APValue(cast<clang::FieldDecl>(fieldDecl), std::move(value)); 413e8d8bef9SDimitry Andric }]>; 414e8d8bef9SDimitry Andric} 415e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "AddrLabelDiff"> in { 416e8d8bef9SDimitry Andric def : Property<"lhs", StmtRef> { 417e8d8bef9SDimitry Andric let Read = [{ const_cast<AddrLabelExpr *>(node.getAddrLabelDiffLHS()) }]; 418e8d8bef9SDimitry Andric } 419e8d8bef9SDimitry Andric def : Property<"rhs", StmtRef> { 420e8d8bef9SDimitry Andric let Read = [{ const_cast<AddrLabelExpr *>(node.getAddrLabelDiffRHS()) }]; 421e8d8bef9SDimitry Andric } 422e8d8bef9SDimitry Andric def : Creator<[{ 423e8d8bef9SDimitry Andric return APValue(cast<AddrLabelExpr>(lhs), cast<AddrLabelExpr>(rhs)); 424e8d8bef9SDimitry Andric }]>; 425e8d8bef9SDimitry Andric} 426e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "MemberPointer"> in { 427e8d8bef9SDimitry Andric def : Property<"isDerived", Bool> { 428e8d8bef9SDimitry Andric let Read = [{ node.isMemberPointerToDerivedMember() }]; 429e8d8bef9SDimitry Andric } 430e8d8bef9SDimitry Andric def : Property<"member", ValueDeclRef> { 431e8d8bef9SDimitry Andric let Read = [{ node.getMemberPointerDecl() }]; 432e8d8bef9SDimitry Andric } 433e8d8bef9SDimitry Andric def : Property<"memberPath", Array<CXXRecordDeclRef>> { 434e8d8bef9SDimitry Andric let Read = [{ node.getMemberPointerPath() }]; 435e8d8bef9SDimitry Andric } 436e8d8bef9SDimitry Andric def : Creator<[{ 437e8d8bef9SDimitry Andric APValue result; 438e8d8bef9SDimitry Andric unsigned pathSize = memberPath.size(); 439e8d8bef9SDimitry Andric const CXXRecordDecl **pathArray = 440e8d8bef9SDimitry Andric result.setMemberPointerUninit(member, isDerived, pathSize).data(); 441e8d8bef9SDimitry Andric for (unsigned i = 0; i < pathSize; ++i) 442e8d8bef9SDimitry Andric pathArray[i] = memberPath[i]->getCanonicalDecl(); 443e8d8bef9SDimitry Andric return result; 444e8d8bef9SDimitry Andric }]>; 445e8d8bef9SDimitry Andric} 446e8d8bef9SDimitry Andriclet Class = PropertyTypeCase<APValue, "LValue"> in { 447e8d8bef9SDimitry Andric def : ReadHelper<[{ 448e8d8bef9SDimitry Andric auto lvalueBase = node.getLValueBase(); 449e8d8bef9SDimitry Andric const Expr *expr = 450e8d8bef9SDimitry Andric lvalueBase ? lvalueBase.dyn_cast<const Expr *>() : nullptr; 451e8d8bef9SDimitry Andric bool lvalueBaseIsExpr = (bool) expr; 452e8d8bef9SDimitry Andric bool lvalueBaseIsTypeInfo = lvalueBase.is<TypeInfoLValue>(); 45306c3fb27SDimitry Andric bool lvalueBaseIsDynamicAlloc = lvalueBase.is<DynamicAllocLValue>(); 454e8d8bef9SDimitry Andric QualType elemTy; 455e8d8bef9SDimitry Andric if (lvalueBase) { 456e8d8bef9SDimitry Andric if (lvalueBaseIsTypeInfo) { 457e8d8bef9SDimitry Andric elemTy = lvalueBase.getTypeInfoType(); 45806c3fb27SDimitry Andric } else if (lvalueBaseIsDynamicAlloc) { 45906c3fb27SDimitry Andric elemTy = lvalueBase.getDynamicAllocType(); 460e8d8bef9SDimitry Andric } else if (lvalueBaseIsExpr) { 461e8d8bef9SDimitry Andric elemTy = expr->getType(); 462e8d8bef9SDimitry Andric } else { 463e8d8bef9SDimitry Andric elemTy = lvalueBase.get<const ValueDecl *>()->getType(); 464e8d8bef9SDimitry Andric } 465e8d8bef9SDimitry Andric } 466e8d8bef9SDimitry Andric }]>; 467e8d8bef9SDimitry Andric def : Property<"hasLValuePath", Bool> { 468e8d8bef9SDimitry Andric let Read = [{ node.hasLValuePath() }]; 469e8d8bef9SDimitry Andric } 470e8d8bef9SDimitry Andric def : Property<"isLValueOnePastTheEnd", Bool> { 471e8d8bef9SDimitry Andric let Read = [{ node.isLValueOnePastTheEnd() }]; 472e8d8bef9SDimitry Andric } 473e8d8bef9SDimitry Andric def : Property<"isExpr", Bool> { 474e8d8bef9SDimitry Andric let Read = [{ lvalueBaseIsExpr }]; 475e8d8bef9SDimitry Andric } 476e8d8bef9SDimitry Andric def : Property<"isTypeInfo", Bool> { 477e8d8bef9SDimitry Andric let Read = [{ lvalueBaseIsTypeInfo }]; 478e8d8bef9SDimitry Andric } 47906c3fb27SDimitry Andric def : Property<"isDynamicAlloc", Bool> { 48006c3fb27SDimitry Andric let Read = [{ lvalueBaseIsDynamicAlloc }]; 48106c3fb27SDimitry Andric } 482e8d8bef9SDimitry Andric def : Property<"hasBase", Bool> { 483e8d8bef9SDimitry Andric let Read = [{ static_cast<bool>(lvalueBase) }]; 484e8d8bef9SDimitry Andric } 485e8d8bef9SDimitry Andric def : Property<"isNullPtr", Bool> { 486e8d8bef9SDimitry Andric let Read = [{ node.isNullPointer() }]; 487e8d8bef9SDimitry Andric } 488e8d8bef9SDimitry Andric def : Property<"typeInfo", QualType> { 489e8d8bef9SDimitry Andric let Conditional = [{ hasBase && isTypeInfo }]; 490e8d8bef9SDimitry Andric let Read = [{ 491e8d8bef9SDimitry Andric QualType(node.getLValueBase().get<TypeInfoLValue>().getType(), 0) 492e8d8bef9SDimitry Andric }]; 493e8d8bef9SDimitry Andric } 49406c3fb27SDimitry Andric def : Property<"dynamicAlloc", UInt32> { 49506c3fb27SDimitry Andric let Conditional = [{ hasBase && isDynamicAlloc }]; 49606c3fb27SDimitry Andric let Read = [{ node.getLValueBase().get<DynamicAllocLValue>().getIndex() }]; 49706c3fb27SDimitry Andric } 498e8d8bef9SDimitry Andric def : Property<"type", QualType> { 49906c3fb27SDimitry Andric let Conditional = [{ hasBase && (isTypeInfo || isDynamicAlloc) }]; 50006c3fb27SDimitry Andric let Read = [{ 50106c3fb27SDimitry Andric isTypeInfo 50206c3fb27SDimitry Andric ? node.getLValueBase().getTypeInfoType() 50306c3fb27SDimitry Andric : node.getLValueBase().getDynamicAllocType() 50406c3fb27SDimitry Andric }]; 505e8d8bef9SDimitry Andric } 506e8d8bef9SDimitry Andric def : Property<"callIndex", UInt32> { 507e8d8bef9SDimitry Andric let Conditional = [{ hasBase && !isTypeInfo }]; 508e8d8bef9SDimitry Andric let Read = [{ node.getLValueBase().getCallIndex() }]; 509e8d8bef9SDimitry Andric } 510e8d8bef9SDimitry Andric def : Property<"version", UInt32> { 511e8d8bef9SDimitry Andric let Conditional = [{ hasBase && !isTypeInfo }]; 512e8d8bef9SDimitry Andric let Read = [{ node.getLValueBase().getVersion() }]; 513e8d8bef9SDimitry Andric } 514e8d8bef9SDimitry Andric def : Property<"stmt", StmtRef> { 515e8d8bef9SDimitry Andric let Conditional = [{ hasBase && !isTypeInfo && isExpr }]; 516e8d8bef9SDimitry Andric let Read = [{ const_cast<Expr *>(expr) }]; 517e8d8bef9SDimitry Andric } 518e8d8bef9SDimitry Andric def : Property<"decl", DeclRef> { 51906c3fb27SDimitry Andric let Conditional = [{ hasBase && !isTypeInfo && !isDynamicAlloc && !isExpr }]; 520e8d8bef9SDimitry Andric let Read = [{ lvalueBase.get<const ValueDecl *>() }]; 521e8d8bef9SDimitry Andric } 522e8d8bef9SDimitry Andric def : Property<"offsetQuantity", UInt32> { 523e8d8bef9SDimitry Andric let Read = [{ node.getLValueOffset().getQuantity() }]; 524e8d8bef9SDimitry Andric } 525e8d8bef9SDimitry Andric def : Property<"lvaluePath", LValuePathSerializationHelper> { 526e8d8bef9SDimitry Andric let Conditional = [{ hasLValuePath }]; 527e8d8bef9SDimitry Andric let Read = [{ 528e8d8bef9SDimitry Andric APValue::LValuePathSerializationHelper(node.getLValuePath(), elemTy) 529e8d8bef9SDimitry Andric }]; 530e8d8bef9SDimitry Andric } 531e8d8bef9SDimitry Andric def : Creator<[{ 532e8d8bef9SDimitry Andric (void)ctx; 533e8d8bef9SDimitry Andric APValue::LValueBase base; 534e8d8bef9SDimitry Andric if (hasBase) { 535e8d8bef9SDimitry Andric if (isTypeInfo) { 536e8d8bef9SDimitry Andric base = APValue::LValueBase::getTypeInfo( 537bdd1243dSDimitry Andric TypeInfoLValue(typeInfo->getTypePtr()), *type); 53806c3fb27SDimitry Andric } else if (isDynamicAlloc) { 53906c3fb27SDimitry Andric base = APValue::LValueBase::getDynamicAlloc( 54006c3fb27SDimitry Andric DynamicAllocLValue(*dynamicAlloc), *type); 541e8d8bef9SDimitry Andric } else if (isExpr) { 542bdd1243dSDimitry Andric base = APValue::LValueBase(cast<Expr>(*stmt), 543bdd1243dSDimitry Andric *callIndex, *version); 544e8d8bef9SDimitry Andric } else { 545bdd1243dSDimitry Andric base = APValue::LValueBase(cast<ValueDecl>(*decl), 546bdd1243dSDimitry Andric *callIndex, *version); 547e8d8bef9SDimitry Andric } 548e8d8bef9SDimitry Andric } 549e8d8bef9SDimitry Andric CharUnits offset = CharUnits::fromQuantity(offsetQuantity); 550e8d8bef9SDimitry Andric APValue result; 551e8d8bef9SDimitry Andric result.MakeLValue(); 552e8d8bef9SDimitry Andric if (!hasLValuePath) { 553e8d8bef9SDimitry Andric result.setLValue(base, offset, APValue::NoLValuePath{}, isNullPtr); 554e8d8bef9SDimitry Andric return result; 555e8d8bef9SDimitry Andric } 556e8d8bef9SDimitry Andric auto pathLength = lvaluePath->Path.size(); 557e8d8bef9SDimitry Andric APValue::LValuePathEntry *path = result.setLValueUninit( 558e8d8bef9SDimitry Andric base, offset, pathLength, isLValueOnePastTheEnd, isNullPtr).data(); 559e8d8bef9SDimitry Andric llvm::copy(lvaluePath->Path, path); 560e8d8bef9SDimitry Andric return result; 561e8d8bef9SDimitry Andric }]>; 562e8d8bef9SDimitry Andric} 563e8d8bef9SDimitry Andric 564480093f4SDimitry Andric// Type cases for DeclarationName. 565480093f4SDimitry Andricdef : PropertyTypeKind<DeclarationName, DeclarationNameKind, 566480093f4SDimitry Andric "node.getNameKind()">; 567480093f4SDimitry Andriclet Class = PropertyTypeCase<DeclarationName, "Identifier"> in { 568480093f4SDimitry Andric def : Property<"identifier", Identifier> { 569480093f4SDimitry Andric let Read = [{ node.getAsIdentifierInfo() }]; 570480093f4SDimitry Andric } 571480093f4SDimitry Andric def : Creator<[{ 572480093f4SDimitry Andric return DeclarationName(identifier); 573480093f4SDimitry Andric }]>; 574480093f4SDimitry Andric} 575480093f4SDimitry Andricforeach count = ["Zero", "One", "Multi"] in { 576480093f4SDimitry Andric let Class = PropertyTypeCase<DeclarationName, "ObjC"#count#"ArgSelector"> in { 577480093f4SDimitry Andric def : Property<"selector", Selector> { 578480093f4SDimitry Andric let Read = [{ node.getObjCSelector() }]; 579480093f4SDimitry Andric } 580480093f4SDimitry Andric def : Creator<[{ 581480093f4SDimitry Andric return DeclarationName(selector); 582480093f4SDimitry Andric }]>; 583480093f4SDimitry Andric } 584480093f4SDimitry Andric} 585480093f4SDimitry Andricforeach kind = ["Constructor", "Destructor", "ConversionFunction"] in { 586480093f4SDimitry Andric let Class = PropertyTypeCase<DeclarationName, "CXX"#kind#"Name"> in { 587480093f4SDimitry Andric def : Property<"type", QualType> { 588480093f4SDimitry Andric let Read = [{ node.getCXXNameType() }]; 589480093f4SDimitry Andric } 590480093f4SDimitry Andric def : Creator<[{ 591480093f4SDimitry Andric return ctx.DeclarationNames.getCXX}]#kind#[{Name( 592480093f4SDimitry Andric ctx.getCanonicalType(type)); 593480093f4SDimitry Andric }]>; 594480093f4SDimitry Andric } 595480093f4SDimitry Andric} 596480093f4SDimitry Andriclet Class = PropertyTypeCase<DeclarationName, "CXXDeductionGuideName"> in { 597480093f4SDimitry Andric def : Property<"declaration", TemplateDeclRef> { 598480093f4SDimitry Andric let Read = [{ node.getCXXDeductionGuideTemplate() }]; 599480093f4SDimitry Andric } 600480093f4SDimitry Andric def : Creator<[{ 601480093f4SDimitry Andric return ctx.DeclarationNames.getCXXDeductionGuideName(declaration); 602480093f4SDimitry Andric }]>; 603480093f4SDimitry Andric} 604480093f4SDimitry Andriclet Class = PropertyTypeCase<DeclarationName, "CXXOperatorName"> in { 605480093f4SDimitry Andric def : Property<"operatorKind", OverloadedOperatorKind> { 606480093f4SDimitry Andric let Read = [{ node.getCXXOverloadedOperator() }]; 607480093f4SDimitry Andric } 608480093f4SDimitry Andric def : Creator<[{ 609480093f4SDimitry Andric return ctx.DeclarationNames.getCXXOperatorName(operatorKind); 610480093f4SDimitry Andric }]>; 611480093f4SDimitry Andric} 612480093f4SDimitry Andriclet Class = PropertyTypeCase<DeclarationName, "CXXLiteralOperatorName"> in { 613480093f4SDimitry Andric def : Property<"identifier", Identifier> { 614480093f4SDimitry Andric let Read = [{ node.getCXXLiteralIdentifier() }]; 615480093f4SDimitry Andric } 616480093f4SDimitry Andric def : Creator<[{ 617480093f4SDimitry Andric return ctx.DeclarationNames.getCXXLiteralOperatorName(identifier); 618480093f4SDimitry Andric }]>; 619480093f4SDimitry Andric} 620480093f4SDimitry Andriclet Class = PropertyTypeCase<DeclarationName, "CXXUsingDirective"> in { 621480093f4SDimitry Andric def : Creator<[{ 622480093f4SDimitry Andric return DeclarationName::getUsingDirectiveName(); 623480093f4SDimitry Andric }]>; 624480093f4SDimitry Andric} 625480093f4SDimitry Andric 626480093f4SDimitry Andric// Type cases for TemplateName. 627480093f4SDimitry Andricdef : PropertyTypeKind<TemplateName, TemplateNameKind, "node.getKind()">; 628480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateName, "Template"> in { 629480093f4SDimitry Andric def : Property<"declaration", TemplateDeclRef> { 630480093f4SDimitry Andric let Read = [{ node.getAsTemplateDecl() }]; 631480093f4SDimitry Andric } 632480093f4SDimitry Andric def : Creator<[{ 633480093f4SDimitry Andric return TemplateName(declaration); 634480093f4SDimitry Andric }]>; 635480093f4SDimitry Andric} 63681ad6265SDimitry Andric 63781ad6265SDimitry Andriclet Class = PropertyTypeCase<TemplateName, "UsingTemplate"> in { 63881ad6265SDimitry Andric def : Property<"foundDecl", UsingShadowDeclRef> { 63981ad6265SDimitry Andric let Read = [{ node.getAsUsingShadowDecl() }]; 64081ad6265SDimitry Andric } 64181ad6265SDimitry Andric def : Creator<[{ 64281ad6265SDimitry Andric return TemplateName(foundDecl); 64381ad6265SDimitry Andric }]>; 64481ad6265SDimitry Andric} 64581ad6265SDimitry Andric 646480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateName, "OverloadedTemplate"> in { 647480093f4SDimitry Andric def : Property<"overloads", Array<NamedDeclRef>> { 648480093f4SDimitry Andric let Read = [{ node.getAsOverloadedTemplate()->decls() }]; 649480093f4SDimitry Andric } 650480093f4SDimitry Andric def : Creator<[{ 651480093f4SDimitry Andric // Copy into an UnresolvedSet to satisfy the interface. 652480093f4SDimitry Andric UnresolvedSet<8> overloadSet; 653480093f4SDimitry Andric for (auto overload : overloads) { 654480093f4SDimitry Andric overloadSet.addDecl(overload); 655480093f4SDimitry Andric } 656480093f4SDimitry Andric 657480093f4SDimitry Andric return ctx.getOverloadedTemplateName(overloadSet.begin(), 658480093f4SDimitry Andric overloadSet.end()); 659480093f4SDimitry Andric }]>; 660480093f4SDimitry Andric} 661480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateName, "AssumedTemplate"> in { 662480093f4SDimitry Andric def : Property<"name", DeclarationName> { 663480093f4SDimitry Andric let Read = [{ node.getAsAssumedTemplateName()->getDeclName() }]; 664480093f4SDimitry Andric } 665480093f4SDimitry Andric def : Creator<[{ 666480093f4SDimitry Andric return ctx.getAssumedTemplateName(name); 667480093f4SDimitry Andric }]>; 668480093f4SDimitry Andric} 669480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateName, "QualifiedTemplate"> in { 670480093f4SDimitry Andric def : ReadHelper<[{ 671480093f4SDimitry Andric auto qtn = node.getAsQualifiedTemplateName(); 672480093f4SDimitry Andric }]>; 673480093f4SDimitry Andric def : Property<"qualifier", NestedNameSpecifier> { 674480093f4SDimitry Andric let Read = [{ qtn->getQualifier() }]; 675480093f4SDimitry Andric } 676480093f4SDimitry Andric def : Property<"hasTemplateKeyword", Bool> { 677480093f4SDimitry Andric let Read = [{ qtn->hasTemplateKeyword() }]; 678480093f4SDimitry Andric } 67981ad6265SDimitry Andric def : Property<"underlyingTemplateName", TemplateName> { 68081ad6265SDimitry Andric let Read = [{ qtn->getUnderlyingTemplate() }]; 681480093f4SDimitry Andric } 682480093f4SDimitry Andric def : Creator<[{ 683480093f4SDimitry Andric return ctx.getQualifiedTemplateName(qualifier, hasTemplateKeyword, 68481ad6265SDimitry Andric underlyingTemplateName); 685480093f4SDimitry Andric }]>; 686480093f4SDimitry Andric} 687480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateName, "DependentTemplate"> in { 688480093f4SDimitry Andric def : ReadHelper<[{ 689480093f4SDimitry Andric auto dtn = node.getAsDependentTemplateName(); 690480093f4SDimitry Andric }]>; 691480093f4SDimitry Andric def : Property<"qualifier", NestedNameSpecifier> { 692480093f4SDimitry Andric let Read = [{ dtn->getQualifier() }]; 693480093f4SDimitry Andric } 694480093f4SDimitry Andric def : Property<"identifier", Optional<Identifier>> { 695480093f4SDimitry Andric let Read = [{ makeOptionalFromPointer( 696480093f4SDimitry Andric dtn->isIdentifier() 697480093f4SDimitry Andric ? dtn->getIdentifier() 698480093f4SDimitry Andric : nullptr) }]; 699480093f4SDimitry Andric } 700480093f4SDimitry Andric def : Property<"operatorKind", OverloadedOperatorKind> { 701480093f4SDimitry Andric let Conditional = [{ !identifier }]; 702480093f4SDimitry Andric let Read = [{ dtn->getOperator() }]; 703480093f4SDimitry Andric } 704480093f4SDimitry Andric def : Creator<[{ 705480093f4SDimitry Andric if (identifier) { 706480093f4SDimitry Andric return ctx.getDependentTemplateName(qualifier, *identifier); 707480093f4SDimitry Andric } else { 708480093f4SDimitry Andric return ctx.getDependentTemplateName(qualifier, *operatorKind); 709480093f4SDimitry Andric } 710480093f4SDimitry Andric }]>; 711480093f4SDimitry Andric} 712480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParm"> in { 713480093f4SDimitry Andric def : ReadHelper<[{ 714480093f4SDimitry Andric auto parm = node.getAsSubstTemplateTemplateParm(); 715480093f4SDimitry Andric }]>; 716480093f4SDimitry Andric def : Property<"replacement", TemplateName> { 717480093f4SDimitry Andric let Read = [{ parm->getReplacement() }]; 718480093f4SDimitry Andric } 719bdd1243dSDimitry Andric def : Property<"associatedDecl", DeclRef> { 720bdd1243dSDimitry Andric let Read = [{ parm->getAssociatedDecl() }]; 721bdd1243dSDimitry Andric } 722bdd1243dSDimitry Andric def : Property<"index", UInt32> { 723bdd1243dSDimitry Andric let Read = [{ parm->getIndex() }]; 724bdd1243dSDimitry Andric } 725bdd1243dSDimitry Andric def : Property<"packIndex", Optional<UInt32>> { 726bdd1243dSDimitry Andric let Read = [{ parm->getPackIndex() }]; 727bdd1243dSDimitry Andric } 728480093f4SDimitry Andric def : Creator<[{ 729bdd1243dSDimitry Andric return ctx.getSubstTemplateTemplateParm(replacement, associatedDecl, index, packIndex); 730480093f4SDimitry Andric }]>; 731480093f4SDimitry Andric} 732480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in { 733480093f4SDimitry Andric def : ReadHelper<[{ 734480093f4SDimitry Andric auto parm = node.getAsSubstTemplateTemplateParmPack(); 735480093f4SDimitry Andric }]>; 736480093f4SDimitry Andric def : Property<"argumentPack", TemplateArgument> { 737480093f4SDimitry Andric let Read = [{ parm->getArgumentPack() }]; 738480093f4SDimitry Andric } 739bdd1243dSDimitry Andric def : Property<"associatedDecl", DeclRef> { 740bdd1243dSDimitry Andric let Read = [{ parm->getAssociatedDecl() }]; 741bdd1243dSDimitry Andric } 742bdd1243dSDimitry Andric def : Property<"index", UInt32> { 743bdd1243dSDimitry Andric let Read = [{ parm->getIndex() }]; 744bdd1243dSDimitry Andric } 745bdd1243dSDimitry Andric def : Property<"final", Bool> { 746bdd1243dSDimitry Andric let Read = [{ parm->getFinal() }]; 747bdd1243dSDimitry Andric } 748480093f4SDimitry Andric def : Creator<[{ 749bdd1243dSDimitry Andric return ctx.getSubstTemplateTemplateParmPack(argumentPack, associatedDecl, index, final); 750480093f4SDimitry Andric }]>; 751480093f4SDimitry Andric} 752480093f4SDimitry Andric 753480093f4SDimitry Andric// Type cases for TemplateArgument. 754480093f4SDimitry Andricdef : PropertyTypeKind<TemplateArgument, TemplateArgumentKind, 755480093f4SDimitry Andric "node.getKind()">; 756480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateArgument, "Null"> in { 757480093f4SDimitry Andric def : Creator<[{ 758480093f4SDimitry Andric return TemplateArgument(); 759480093f4SDimitry Andric }]>; 760480093f4SDimitry Andric} 761480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateArgument, "Type"> in { 762480093f4SDimitry Andric def : Property<"type", QualType> { 763480093f4SDimitry Andric let Read = [{ node.getAsType() }]; 764480093f4SDimitry Andric } 76506c3fb27SDimitry Andric def : Property<"isDefaulted", Bool> { 76606c3fb27SDimitry Andric let Read = [{ node.getIsDefaulted() }]; 76706c3fb27SDimitry Andric } 768480093f4SDimitry Andric def : Creator<[{ 76906c3fb27SDimitry Andric return TemplateArgument(type, /* isNullPtr */ false, isDefaulted); 770480093f4SDimitry Andric }]>; 771480093f4SDimitry Andric} 772480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateArgument, "Declaration"> in { 773480093f4SDimitry Andric def : Property<"declaration", ValueDeclRef> { 774480093f4SDimitry Andric let Read = [{ node.getAsDecl() }]; 775480093f4SDimitry Andric } 776480093f4SDimitry Andric def : Property<"parameterType", QualType> { 777480093f4SDimitry Andric let Read = [{ node.getParamTypeForDecl() }]; 778480093f4SDimitry Andric } 77906c3fb27SDimitry Andric def : Property<"isDefaulted", Bool> { 78006c3fb27SDimitry Andric let Read = [{ node.getIsDefaulted() }]; 78106c3fb27SDimitry Andric } 782480093f4SDimitry Andric def : Creator<[{ 78306c3fb27SDimitry Andric return TemplateArgument(declaration, parameterType, isDefaulted); 784480093f4SDimitry Andric }]>; 785480093f4SDimitry Andric} 786480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateArgument, "NullPtr"> in { 787480093f4SDimitry Andric def : Property<"type", QualType> { 788480093f4SDimitry Andric let Read = [{ node.getNullPtrType() }]; 789480093f4SDimitry Andric } 79006c3fb27SDimitry Andric def : Property<"isDefaulted", Bool> { 79106c3fb27SDimitry Andric let Read = [{ node.getIsDefaulted() }]; 79206c3fb27SDimitry Andric } 793480093f4SDimitry Andric def : Creator<[{ 79406c3fb27SDimitry Andric return TemplateArgument(type, /*nullptr*/ true, isDefaulted); 795480093f4SDimitry Andric }]>; 796480093f4SDimitry Andric} 797480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateArgument, "Integral"> in { 798480093f4SDimitry Andric def : Property<"value", APSInt> { 799480093f4SDimitry Andric let Read = [{ node.getAsIntegral() }]; 800480093f4SDimitry Andric } 801480093f4SDimitry Andric def : Property<"type", QualType> { 802480093f4SDimitry Andric let Read = [{ node.getIntegralType() }]; 803480093f4SDimitry Andric } 80406c3fb27SDimitry Andric def : Property<"isDefaulted", Bool> { 80506c3fb27SDimitry Andric let Read = [{ node.getIsDefaulted() }]; 80606c3fb27SDimitry Andric } 807480093f4SDimitry Andric def : Creator<[{ 80806c3fb27SDimitry Andric return TemplateArgument(ctx, value, type, isDefaulted); 809480093f4SDimitry Andric }]>; 810480093f4SDimitry Andric} 811*7a6dacacSDimitry Andriclet Class = PropertyTypeCase<TemplateArgument, "StructuralValue"> in { 812*7a6dacacSDimitry Andric def : Property<"value", APValue> { 813*7a6dacacSDimitry Andric let Read = [{ node.getAsStructuralValue() }]; 814*7a6dacacSDimitry Andric } 815*7a6dacacSDimitry Andric def : Property<"type", QualType> { 816*7a6dacacSDimitry Andric let Read = [{ node.getStructuralValueType() }]; 817*7a6dacacSDimitry Andric } 818*7a6dacacSDimitry Andric def : Property<"isDefaulted", Bool> { 819*7a6dacacSDimitry Andric let Read = [{ node.getIsDefaulted() }]; 820*7a6dacacSDimitry Andric } 821*7a6dacacSDimitry Andric def : Creator<[{ 822*7a6dacacSDimitry Andric return TemplateArgument(ctx, type, value, isDefaulted); 823*7a6dacacSDimitry Andric }]>; 824*7a6dacacSDimitry Andric} 825480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateArgument, "Template"> in { 826480093f4SDimitry Andric def : Property<"name", TemplateName> { 827480093f4SDimitry Andric let Read = [{ node.getAsTemplateOrTemplatePattern() }]; 828480093f4SDimitry Andric } 82906c3fb27SDimitry Andric def : Property<"isDefaulted", Bool> { 83006c3fb27SDimitry Andric let Read = [{ node.getIsDefaulted() }]; 83106c3fb27SDimitry Andric } 832480093f4SDimitry Andric def : Creator<[{ 83306c3fb27SDimitry Andric return TemplateArgument(name, isDefaulted); 834480093f4SDimitry Andric }]>; 835480093f4SDimitry Andric} 836480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in { 837480093f4SDimitry Andric def : Property<"name", TemplateName> { 838480093f4SDimitry Andric let Read = [{ node.getAsTemplateOrTemplatePattern() }]; 839480093f4SDimitry Andric } 840480093f4SDimitry Andric def : Property<"numExpansions", Optional<UInt32>> { 841480093f4SDimitry Andric let Read = [{ 842480093f4SDimitry Andric // Translate unsigned -> uint32_t just in case. 843bdd1243dSDimitry Andric llvm::transformOptional(node.getNumTemplateExpansions(), 844480093f4SDimitry Andric [](unsigned i) { return uint32_t(i); }) 845480093f4SDimitry Andric }]; 846480093f4SDimitry Andric } 84706c3fb27SDimitry Andric def : Property<"isDefaulted", Bool> { 84806c3fb27SDimitry Andric let Read = [{ node.getIsDefaulted() }]; 84906c3fb27SDimitry Andric } 850480093f4SDimitry Andric def : Creator<[{ 851bdd1243dSDimitry Andric auto numExpansionsUnsigned = llvm::transformOptional( 852bdd1243dSDimitry Andric numExpansions, [](uint32_t i) { return unsigned(i); }); 853bdd1243dSDimitry Andric 85406c3fb27SDimitry Andric return TemplateArgument(name, numExpansionsUnsigned, isDefaulted); 855480093f4SDimitry Andric }]>; 856480093f4SDimitry Andric} 857480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateArgument, "Expression"> in { 858480093f4SDimitry Andric def : Property<"expression", ExprRef> { 859480093f4SDimitry Andric let Read = [{ node.getAsExpr() }]; 860480093f4SDimitry Andric } 86106c3fb27SDimitry Andric def : Property<"isDefaulted", Bool> { 86206c3fb27SDimitry Andric let Read = [{ node.getIsDefaulted() }]; 86306c3fb27SDimitry Andric } 864480093f4SDimitry Andric def : Creator<[{ 86506c3fb27SDimitry Andric return TemplateArgument(expression, isDefaulted); 866480093f4SDimitry Andric }]>; 867480093f4SDimitry Andric} 868480093f4SDimitry Andriclet Class = PropertyTypeCase<TemplateArgument, "Pack"> in { 869480093f4SDimitry Andric def : Property<"elements", Array<TemplateArgument>> { 870480093f4SDimitry Andric let Read = [{ node.pack_elements() }]; 871480093f4SDimitry Andric } 872480093f4SDimitry Andric def : Creator<[{ 873480093f4SDimitry Andric // Copy the pack into the ASTContext. 874480093f4SDimitry Andric TemplateArgument *ctxElements = new (ctx) TemplateArgument[elements.size()]; 875480093f4SDimitry Andric for (size_t i = 0, e = elements.size(); i != e; ++i) 876480093f4SDimitry Andric ctxElements[i] = elements[i]; 877bdd1243dSDimitry Andric return TemplateArgument(llvm::ArrayRef(ctxElements, elements.size())); 878480093f4SDimitry Andric }]>; 879480093f4SDimitry Andric} 880