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 9class HasProperties; 10 11/// The type of the property. 12class 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. 36class 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. 40class RefPropertyType<string className> : PropertyType<className # "*"> { 41 let PackOptional = 42 "value ? *value : nullptr"; 43 let UnpackOptional = 44 "value ? std::optional<" # CXXName # ">(value) : std::nullopt"; 45} 46 47/// Property types that correspond to a specific subclass of another type. 48class 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. 57class DefaultValuePropertyType<string typeName = ""> : PropertyType<typeName> { 58 let PackOptional = 59 "value ? *value : " # CXXName # "()"; 60 let UnpackOptional = 61 "value.isNull() ? std::nullopt : std::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. 66class CountPropertyType<string typeName = ""> : PropertyType<typeName> { 67 let PackOptional = 68 "value ? *value + 1 : 0"; 69 let UnpackOptional = 70 "value ? std::optional<" # CXXName # ">(value - 1) : std::nullopt"; 71} 72 73def APInt : PropertyType<"llvm::APInt"> { let PassByReference = 1; } 74def APSInt : PropertyType<"llvm::APSInt"> { let PassByReference = 1; } 75def APValue : PropertyType { let PassByReference = 1; } 76def APValueKind : EnumPropertyType<"APValue::ValueKind">; 77def ArraySizeModifier : EnumPropertyType<"ArraySizeModifier">; 78def AttrKind : EnumPropertyType<"attr::Kind">; 79def AutoTypeKeyword : EnumPropertyType; 80def Bool : PropertyType<"bool">; 81def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">; 82def BTFTypeTagAttr : PropertyType<"const BTFTypeTagAttr *">; 83def CallingConv : EnumPropertyType; 84def DeclarationName : PropertyType; 85def DeclarationNameKind : EnumPropertyType<"DeclarationName::NameKind">; 86def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; } 87 def CXXRecordDeclRef : 88 SubclassPropertyType<"CXXRecordDecl", DeclRef>; 89 def FunctionDeclRef : 90 SubclassPropertyType<"FunctionDecl", DeclRef>; 91 def NamedDeclRef : 92 SubclassPropertyType<"NamedDecl", DeclRef>; 93 def NamespaceDeclRef : 94 SubclassPropertyType<"NamespaceDecl", DeclRef>; 95 def NamespaceAliasDeclRef : 96 SubclassPropertyType<"NamespaceAliasDecl", DeclRef>; 97 def ObjCProtocolDeclRef : 98 SubclassPropertyType<"ObjCProtocolDecl", DeclRef>; 99 def ObjCTypeParamDeclRef : 100 SubclassPropertyType<"ObjCTypeParamDecl", DeclRef>; 101 def TagDeclRef : 102 SubclassPropertyType<"TagDecl", DeclRef>; 103 def TemplateDeclRef : 104 SubclassPropertyType<"TemplateDecl", DeclRef>; 105 def ConceptDeclRef : 106 SubclassPropertyType<"ConceptDecl", DeclRef>; 107 def TemplateTypeParmDeclRef : 108 SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>; 109 def TemplateTemplateParmDeclRef : 110 SubclassPropertyType<"TemplateTemplateParmDecl", DeclRef>; 111 def UsingShadowDeclRef : 112 SubclassPropertyType<"UsingShadowDecl", DeclRef>; 113 def ValueDeclRef : 114 SubclassPropertyType<"ValueDecl", DeclRef>; 115def ElaboratedTypeKeyword : EnumPropertyType; 116def ExtParameterInfo : PropertyType<"FunctionProtoType::ExtParameterInfo">; 117def FixedPointSemantics : PropertyType<"llvm::FixedPointSemantics"> { 118 let PassByReference = 1; 119} 120def FunctionEffect : PropertyType<"FunctionEffect">; 121def EffectConditionExpr : PropertyType<"EffectConditionExpr">; 122def Identifier : RefPropertyType<"IdentifierInfo"> { let ConstWhenWriting = 1; } 123def LValuePathEntry : PropertyType<"APValue::LValuePathEntry">; 124def LValuePathSerializationHelper : 125 PropertyType<"APValue::LValuePathSerializationHelper"> { 126 let BufferElementTypes = [ LValuePathEntry ]; 127} 128def NestedNameSpecifier : PropertyType<"NestedNameSpecifier *">; 129def NestedNameSpecifierKind : 130 EnumPropertyType<"NestedNameSpecifier::SpecifierKind">; 131def OverloadedOperatorKind : EnumPropertyType; 132def Qualifiers : PropertyType; 133def QualType : DefaultValuePropertyType; 134def RefQualifierKind : EnumPropertyType; 135def Selector : PropertyType; 136def SourceLocation : PropertyType; 137def StmtRef : RefPropertyType<"Stmt"> { let ConstWhenWriting = 1; } 138 def ExprRef : SubclassPropertyType<"Expr", StmtRef>; 139def TemplateArgument : PropertyType; 140def TemplateArgumentKind : EnumPropertyType<"TemplateArgument::ArgKind">; 141def TemplateName : DefaultValuePropertyType; 142def TemplateNameKind : EnumPropertyType<"TemplateName::NameKind">; 143def TypeOfKind : EnumPropertyType<"TypeOfKind">; 144def UInt32 : CountPropertyType<"uint32_t">; 145def UInt64 : CountPropertyType<"uint64_t">; 146def UnaryTypeTransformKind : EnumPropertyType<"UnaryTransformType::UTTKind">; 147def VectorKind : EnumPropertyType<"VectorKind">; 148def TypeCoupledDeclRefInfo : PropertyType; 149 150def ExceptionSpecInfo : PropertyType<"FunctionProtoType::ExceptionSpecInfo"> { 151 let BufferElementTypes = [ QualType ]; 152} 153 154/// Arrays. The corresponding C++ type is ArrayRef of the corresponding 155/// C++ type of the element. 156class Array<PropertyType element> : PropertyType { 157 PropertyType Element = element; 158 let BufferElementTypes = [ element ]; 159} 160 161/// std::optional<T>. The corresponding C++ type is generally just the 162/// corresponding C++ type of the element. 163/// 164/// Optional<Unsigned> may restrict the range of the operand for some 165/// serialization clients. 166class Optional<PropertyType element> : PropertyType { 167 PropertyType Element = element; 168 let PassByReference = element.PassByReference; 169} 170 171/// A property of an AST node. 172class Property<string name, PropertyType type> { 173 HasProperties Class; 174 string Name = name; 175 PropertyType Type = type; 176 177 /// A function for reading the property, expressed in terms of a variable 178 /// "node". 179 code Read; 180 181 /// Code specifying when this property is available. Can be defined 182 /// in terms of other properties, in which case this property must be 183 /// read/written after those properties. Using this will make the 184 /// value Optional when deserializing. 185 /// 186 /// FIXME: the emitter doesn't yet force dependent properties to be 187 /// read/written later; this only works if the properties used in the 188 /// condition happen to be written first. 189 code Conditional = ""; 190} 191 192/// A rule for declaring helper variables when read properties from a 193/// value of this type. Note that this means that this code is actually 194/// run when *writing* values of this type; however, naming this 195/// `ReadHelper` makes the connection to the `Read` operations on the 196/// properties much clearer. 197class ReadHelper<code _code> { 198 HasProperties Class; 199 200 /// Code which will be run when writing objects of this type before 201 /// writing any of the properties, specified in terms of a variable 202 /// `node`. 203 code Code = _code; 204} 205 206/// A rule for creating objects of this type. 207class Creator<code create> { 208 HasProperties Class; 209 210 /// A function for creating values of this kind, expressed in terms of a 211 /// variable `ctx` of type `ASTContext &`. Must also refer to all of the 212 /// properties by name. 213 code Create = create; 214} 215 216/// A rule which overrides some of the normal rules. 217class Override { 218 HasProperties Class; 219 220 /// Properties from base classes that should be ignored. 221 list<string> IgnoredProperties = []; 222} 223 224/// A description of how to break a type into cases. Providing this and 225/// an exhaustive list of the cases will cause AbstractBasic{Reader,Writer} 226/// to be generated with a default implementation of how to read the 227/// type. 228/// 229/// Creator rules for the cases can additionally access a variable 230/// `kind` of the KindType. 231class PropertyTypeKind<PropertyType type, 232 PropertyType kindType, 233 string readCode> { 234 /// The type for which this describes cases. 235 PropertyType Type = type; 236 237 /// The type of this type's kind enum. 238 PropertyType KindType = kindType; 239 240 /// The property name to use for the kind. 241 string KindPropertyName = "kind"; 242 243 /// An expression which reads the kind from a value, expressed in terms 244 /// of a variable `node`. 245 string Read = readCode; 246} 247 248/// One of the options for representing a particular type. 249class PropertyTypeCase<PropertyType type, string name> : HasProperties { 250 /// The type of which this is a case. 251 PropertyType Type = type; 252 253 /// The name of the case (a value of the type's kind enum). 254 string Name = name; 255} 256 257// Type cases for APValue. 258def : PropertyTypeKind<APValue, APValueKind, 259 "node.getKind()">; 260let Class = PropertyTypeCase<APValue, "None"> in { 261 def : Creator<[{ return APValue(); }]>; 262} 263let Class = PropertyTypeCase<APValue, "Indeterminate"> in { 264 def : Creator<[{ return APValue::IndeterminateValue(); }]>; 265} 266let Class = PropertyTypeCase<APValue, "Int"> in { 267 def : Property<"value", APSInt> { 268 let Read = [{ node.getInt() }]; 269 } 270 def : Creator<[{ return APValue(value); }]>; 271} 272let Class = PropertyTypeCase<APValue, "Float"> in { 273 def : Property<"semantics", UInt32> { 274 let Read = [{ 275 static_cast<uint32_t>( 276 llvm::APFloatBase::SemanticsToEnum(node.getFloat().getSemantics())) 277 }]; 278 } 279 def : Property<"value", APInt> { 280 let Read = [{ node.getFloat().bitcastToAPInt() }]; 281 } 282 def : Creator<[{ 283 const llvm::fltSemantics &floatSema = llvm::APFloatBase::EnumToSemantics( 284 static_cast<llvm::APFloatBase::Semantics>(semantics)); 285 return APValue(llvm::APFloat(floatSema, value)); 286 }]>; 287} 288let Class = PropertyTypeCase<APValue, "FixedPoint"> in { 289 def : Property<"semantics", FixedPointSemantics> { 290 let Read = [{ node.getFixedPoint().getSemantics() }]; 291 } 292 def : Property<"value", APSInt> { 293 let Read = [{ node.getFixedPoint().getValue() }]; 294 } 295 def : Creator<[{ 296 return APValue(llvm::APFixedPoint(std::move(value), semantics)); 297 }]>; 298} 299let Class = PropertyTypeCase<APValue, "ComplexInt"> in { 300 def : Property<"real", APSInt> { 301 let Read = [{ node.getComplexIntReal() }]; 302 } 303 def : Property<"imag", APSInt> { 304 let Read = [{ node.getComplexIntImag() }]; 305 } 306 def : Creator<[{ return APValue(real, imag); }]>; 307} 308let Class = PropertyTypeCase<APValue, "ComplexFloat"> in { 309 def : ReadHelper<[{ 310 auto sema = llvm::APFloatBase::SemanticsToEnum( 311 node.getComplexFloatReal().getSemantics()); 312 assert(sema == llvm::APFloatBase::SemanticsToEnum( 313 node.getComplexFloatImag().getSemantics())); 314 }]>; 315 def : Property<"semantics", UInt32> { 316 let Read = [{ static_cast<uint32_t>(sema) }]; 317 } 318 def : Property<"real", APInt> { 319 let Read = [{ node.getComplexFloatReal().bitcastToAPInt() }]; 320 } 321 def : Property<"imag", APInt> { 322 let Read = [{ node.getComplexFloatImag().bitcastToAPInt() }]; 323 } 324 def : Creator<[{ 325 const llvm::fltSemantics &sema = llvm::APFloatBase::EnumToSemantics( 326 static_cast<llvm::APFloatBase::Semantics>(semantics)); 327 return APValue(llvm::APFloat(sema, real), 328 llvm::APFloat(sema, imag)); 329 }]>; 330} 331let Class = PropertyTypeCase<APValue, "Vector"> in { 332 def : ReadHelper<[{ 333 SmallVector<APValue, 4> buffer; 334 unsigned len = node.getVectorLength(); 335 for (unsigned i = 0; i < len; ++i) 336 buffer.push_back(node.getVectorElt(i)); 337 }]>; 338 def : Property<"elements", Array<APValue>> { 339 let Read = [{ buffer }]; 340 } 341 def : Creator<[{ 342 APValue result; 343 result.MakeVector(); 344 unsigned length = elements.size(); 345 (void)result.setVectorUninit(length); 346 for (unsigned i = 0; i < length; i++) 347 result.getVectorElt(i) = elements[i]; 348 return result; 349 }]>; 350} 351let Class = PropertyTypeCase<APValue, "Array"> in { 352 def : ReadHelper<[{ 353 SmallVector<APValue, 4> buffer{}; 354 unsigned initLength = node.getArrayInitializedElts(); 355 for (unsigned i = 0; i < initLength; ++i) 356 buffer.push_back(node.getArrayInitializedElt(i)); 357 if (node.hasArrayFiller()) 358 buffer.push_back(node.getArrayFiller()); 359 }]>; 360 def : Property<"totalLength", UInt32> { 361 let Read = [{ node.getArraySize() }]; 362 } 363 def : Property<"hasFiller", Bool> { 364 let Read = [{ node.hasArrayFiller() }]; 365 } 366 def : Property<"elements", Array<APValue>> { 367 let Read = [{ buffer }]; 368 } 369 def : Creator<[{ 370 APValue result; 371 unsigned initLength = elements.size() - (hasFiller ? 1 : 0); 372 result.MakeArray(initLength, totalLength); 373 for (unsigned i = 0; i < initLength; ++i) 374 result.getArrayInitializedElt(i) = elements[i]; 375 if (hasFiller) 376 result.getArrayFiller() = elements.back(); 377 return result; 378 }]>; 379} 380let Class = PropertyTypeCase<APValue, "Struct"> in { 381 def : ReadHelper<[{ 382 SmallVector<APValue, 4> structBases; 383 unsigned numBases = node.getStructNumBases(); 384 for (unsigned i = 0; i < numBases; ++i) 385 structBases.push_back(node.getStructBase(i)); 386 SmallVector<APValue, 4> structFields; 387 unsigned numFields = node.getStructNumFields(); 388 for (unsigned i = 0; i < numFields; ++i) 389 structFields.push_back(node.getStructField(i)); 390 }]>; 391 def : Property<"bases", Array<APValue>> { 392 let Read = [{ structBases }]; 393 } 394 def : Property<"fields", Array<APValue>> { 395 let Read = [{ structFields }]; 396 } 397 def : Creator<[{ 398 APValue result; 399 result.MakeStruct(bases.size(), fields.size()); 400 for (unsigned i = 0; i < bases.size(); ++i) 401 result.getStructBase(i) = bases[i]; 402 for (unsigned i = 0; i < fields.size(); ++i) 403 result.getStructField(i) = fields[i]; 404 return result; 405 }]>; 406} 407let Class = PropertyTypeCase<APValue, "Union"> in { 408 def : Property<"fieldDecl", DeclRef> { 409 let Read = [{ node.getUnionField() }]; 410 } 411 def : Property<"value", APValue> { 412 let Read = [{ node.getUnionValue() }]; 413 } 414 def : Creator<[{ 415 return APValue(cast<clang::FieldDecl>(fieldDecl), std::move(value)); 416 }]>; 417} 418let Class = PropertyTypeCase<APValue, "AddrLabelDiff"> in { 419 def : Property<"lhs", StmtRef> { 420 let Read = [{ const_cast<AddrLabelExpr *>(node.getAddrLabelDiffLHS()) }]; 421 } 422 def : Property<"rhs", StmtRef> { 423 let Read = [{ const_cast<AddrLabelExpr *>(node.getAddrLabelDiffRHS()) }]; 424 } 425 def : Creator<[{ 426 return APValue(cast<AddrLabelExpr>(lhs), cast<AddrLabelExpr>(rhs)); 427 }]>; 428} 429let Class = PropertyTypeCase<APValue, "MemberPointer"> in { 430 def : Property<"isDerived", Bool> { 431 let Read = [{ node.isMemberPointerToDerivedMember() }]; 432 } 433 def : Property<"member", ValueDeclRef> { 434 let Read = [{ node.getMemberPointerDecl() }]; 435 } 436 def : Property<"memberPath", Array<CXXRecordDeclRef>> { 437 let Read = [{ node.getMemberPointerPath() }]; 438 } 439 def : Creator<[{ 440 APValue result; 441 unsigned pathSize = memberPath.size(); 442 const CXXRecordDecl **pathArray = 443 result.setMemberPointerUninit(member, isDerived, pathSize).data(); 444 for (unsigned i = 0; i < pathSize; ++i) 445 pathArray[i] = memberPath[i]->getCanonicalDecl(); 446 return result; 447 }]>; 448} 449let Class = PropertyTypeCase<APValue, "LValue"> in { 450 def : ReadHelper<[{ 451 auto lvalueBase = node.getLValueBase(); 452 const Expr *expr = 453 lvalueBase ? lvalueBase.dyn_cast<const Expr *>() : nullptr; 454 bool lvalueBaseIsExpr = (bool) expr; 455 bool lvalueBaseIsTypeInfo = lvalueBase.is<TypeInfoLValue>(); 456 bool lvalueBaseIsDynamicAlloc = lvalueBase.is<DynamicAllocLValue>(); 457 QualType elemTy; 458 if (lvalueBase) { 459 if (lvalueBaseIsTypeInfo) { 460 elemTy = lvalueBase.getTypeInfoType(); 461 } else if (lvalueBaseIsDynamicAlloc) { 462 elemTy = lvalueBase.getDynamicAllocType(); 463 } else if (lvalueBaseIsExpr) { 464 elemTy = expr->getType(); 465 } else { 466 elemTy = lvalueBase.get<const ValueDecl *>()->getType(); 467 } 468 } 469 }]>; 470 def : Property<"hasLValuePath", Bool> { 471 let Read = [{ node.hasLValuePath() }]; 472 } 473 def : Property<"isLValueOnePastTheEnd", Bool> { 474 let Read = [{ node.isLValueOnePastTheEnd() }]; 475 } 476 def : Property<"isExpr", Bool> { 477 let Read = [{ lvalueBaseIsExpr }]; 478 } 479 def : Property<"isTypeInfo", Bool> { 480 let Read = [{ lvalueBaseIsTypeInfo }]; 481 } 482 def : Property<"isDynamicAlloc", Bool> { 483 let Read = [{ lvalueBaseIsDynamicAlloc }]; 484 } 485 def : Property<"hasBase", Bool> { 486 let Read = [{ static_cast<bool>(lvalueBase) }]; 487 } 488 def : Property<"isNullPtr", Bool> { 489 let Read = [{ node.isNullPointer() }]; 490 } 491 def : Property<"typeInfo", QualType> { 492 let Conditional = [{ hasBase && isTypeInfo }]; 493 let Read = [{ 494 QualType(node.getLValueBase().get<TypeInfoLValue>().getType(), 0) 495 }]; 496 } 497 def : Property<"dynamicAlloc", UInt32> { 498 let Conditional = [{ hasBase && isDynamicAlloc }]; 499 let Read = [{ node.getLValueBase().get<DynamicAllocLValue>().getIndex() }]; 500 } 501 def : Property<"type", QualType> { 502 let Conditional = [{ hasBase && (isTypeInfo || isDynamicAlloc) }]; 503 let Read = [{ 504 isTypeInfo 505 ? node.getLValueBase().getTypeInfoType() 506 : node.getLValueBase().getDynamicAllocType() 507 }]; 508 } 509 def : Property<"callIndex", UInt32> { 510 let Conditional = [{ hasBase && !isTypeInfo }]; 511 let Read = [{ node.getLValueBase().getCallIndex() }]; 512 } 513 def : Property<"version", UInt32> { 514 let Conditional = [{ hasBase && !isTypeInfo }]; 515 let Read = [{ node.getLValueBase().getVersion() }]; 516 } 517 def : Property<"stmt", StmtRef> { 518 let Conditional = [{ hasBase && !isTypeInfo && isExpr }]; 519 let Read = [{ const_cast<Expr *>(expr) }]; 520 } 521 def : Property<"decl", DeclRef> { 522 let Conditional = [{ hasBase && !isTypeInfo && !isDynamicAlloc && !isExpr }]; 523 let Read = [{ lvalueBase.get<const ValueDecl *>() }]; 524 } 525 def : Property<"offsetQuantity", UInt32> { 526 let Read = [{ node.getLValueOffset().getQuantity() }]; 527 } 528 def : Property<"lvaluePath", LValuePathSerializationHelper> { 529 let Conditional = [{ hasLValuePath }]; 530 let Read = [{ 531 APValue::LValuePathSerializationHelper(node.getLValuePath(), elemTy) 532 }]; 533 } 534 def : Creator<[{ 535 (void)ctx; 536 APValue::LValueBase base; 537 if (hasBase) { 538 if (isTypeInfo) { 539 base = APValue::LValueBase::getTypeInfo( 540 TypeInfoLValue(typeInfo->getTypePtr()), *type); 541 } else if (isDynamicAlloc) { 542 base = APValue::LValueBase::getDynamicAlloc( 543 DynamicAllocLValue(*dynamicAlloc), *type); 544 } else if (isExpr) { 545 base = APValue::LValueBase(cast<Expr>(*stmt), 546 *callIndex, *version); 547 } else { 548 base = APValue::LValueBase(cast<ValueDecl>(*decl), 549 *callIndex, *version); 550 } 551 } 552 CharUnits offset = CharUnits::fromQuantity(offsetQuantity); 553 APValue result; 554 result.MakeLValue(); 555 if (!hasLValuePath) { 556 result.setLValue(base, offset, APValue::NoLValuePath{}, isNullPtr); 557 return result; 558 } 559 auto pathLength = lvaluePath->Path.size(); 560 APValue::LValuePathEntry *path = result.setLValueUninit( 561 base, offset, pathLength, isLValueOnePastTheEnd, isNullPtr).data(); 562 llvm::copy(lvaluePath->Path, path); 563 return result; 564 }]>; 565} 566 567// Type cases for DeclarationName. 568def : PropertyTypeKind<DeclarationName, DeclarationNameKind, 569 "node.getNameKind()">; 570let Class = PropertyTypeCase<DeclarationName, "Identifier"> in { 571 def : Property<"identifier", Identifier> { 572 let Read = [{ node.getAsIdentifierInfo() }]; 573 } 574 def : Creator<[{ 575 return DeclarationName(identifier); 576 }]>; 577} 578foreach count = ["Zero", "One", "Multi"] in { 579 let Class = PropertyTypeCase<DeclarationName, "ObjC"#count#"ArgSelector"> in { 580 def : Property<"selector", Selector> { 581 let Read = [{ node.getObjCSelector() }]; 582 } 583 def : Creator<[{ 584 return DeclarationName(selector); 585 }]>; 586 } 587} 588foreach kind = ["Constructor", "Destructor", "ConversionFunction"] in { 589 let Class = PropertyTypeCase<DeclarationName, "CXX"#kind#"Name"> in { 590 def : Property<"type", QualType> { 591 let Read = [{ node.getCXXNameType() }]; 592 } 593 def : Creator<[{ 594 return ctx.DeclarationNames.getCXX}]#kind#[{Name( 595 ctx.getCanonicalType(type)); 596 }]>; 597 } 598} 599let Class = PropertyTypeCase<DeclarationName, "CXXDeductionGuideName"> in { 600 def : Property<"declaration", TemplateDeclRef> { 601 let Read = [{ node.getCXXDeductionGuideTemplate() }]; 602 } 603 def : Creator<[{ 604 return ctx.DeclarationNames.getCXXDeductionGuideName(declaration); 605 }]>; 606} 607let Class = PropertyTypeCase<DeclarationName, "CXXOperatorName"> in { 608 def : Property<"operatorKind", OverloadedOperatorKind> { 609 let Read = [{ node.getCXXOverloadedOperator() }]; 610 } 611 def : Creator<[{ 612 return ctx.DeclarationNames.getCXXOperatorName(operatorKind); 613 }]>; 614} 615let Class = PropertyTypeCase<DeclarationName, "CXXLiteralOperatorName"> in { 616 def : Property<"identifier", Identifier> { 617 let Read = [{ node.getCXXLiteralIdentifier() }]; 618 } 619 def : Creator<[{ 620 return ctx.DeclarationNames.getCXXLiteralOperatorName(identifier); 621 }]>; 622} 623let Class = PropertyTypeCase<DeclarationName, "CXXUsingDirective"> in { 624 def : Creator<[{ 625 return DeclarationName::getUsingDirectiveName(); 626 }]>; 627} 628 629// Type cases for TemplateName. 630def : PropertyTypeKind<TemplateName, TemplateNameKind, "node.getKind()">; 631let Class = PropertyTypeCase<TemplateName, "Template"> in { 632 def : Property<"declaration", TemplateDeclRef> { 633 let Read = [{ node.getAsTemplateDecl() }]; 634 } 635 def : Creator<[{ 636 return TemplateName(declaration); 637 }]>; 638} 639 640let Class = PropertyTypeCase<TemplateName, "UsingTemplate"> in { 641 def : Property<"foundDecl", UsingShadowDeclRef> { 642 let Read = [{ node.getAsUsingShadowDecl() }]; 643 } 644 def : Creator<[{ 645 return TemplateName(foundDecl); 646 }]>; 647} 648 649let Class = PropertyTypeCase<TemplateName, "OverloadedTemplate"> in { 650 def : Property<"overloads", Array<NamedDeclRef>> { 651 let Read = [{ node.getAsOverloadedTemplate()->decls() }]; 652 } 653 def : Creator<[{ 654 // Copy into an UnresolvedSet to satisfy the interface. 655 UnresolvedSet<8> overloadSet; 656 for (auto overload : overloads) { 657 overloadSet.addDecl(overload); 658 } 659 660 return ctx.getOverloadedTemplateName(overloadSet.begin(), 661 overloadSet.end()); 662 }]>; 663} 664let Class = PropertyTypeCase<TemplateName, "AssumedTemplate"> in { 665 def : Property<"name", DeclarationName> { 666 let Read = [{ node.getAsAssumedTemplateName()->getDeclName() }]; 667 } 668 def : Creator<[{ 669 return ctx.getAssumedTemplateName(name); 670 }]>; 671} 672let Class = PropertyTypeCase<TemplateName, "QualifiedTemplate"> in { 673 def : ReadHelper<[{ 674 auto qtn = node.getAsQualifiedTemplateName(); 675 }]>; 676 def : Property<"qualifier", NestedNameSpecifier> { 677 let Read = [{ qtn->getQualifier() }]; 678 } 679 def : Property<"hasTemplateKeyword", Bool> { 680 let Read = [{ qtn->hasTemplateKeyword() }]; 681 } 682 def : Property<"underlyingTemplateName", TemplateName> { 683 let Read = [{ qtn->getUnderlyingTemplate() }]; 684 } 685 def : Creator<[{ 686 return ctx.getQualifiedTemplateName(qualifier, hasTemplateKeyword, 687 underlyingTemplateName); 688 }]>; 689} 690let Class = PropertyTypeCase<TemplateName, "DependentTemplate"> in { 691 def : ReadHelper<[{ 692 auto dtn = node.getAsDependentTemplateName(); 693 }]>; 694 def : Property<"qualifier", NestedNameSpecifier> { 695 let Read = [{ dtn->getQualifier() }]; 696 } 697 def : Property<"identifier", Optional<Identifier>> { 698 let Read = [{ makeOptionalFromPointer( 699 dtn->isIdentifier() 700 ? dtn->getIdentifier() 701 : nullptr) }]; 702 } 703 def : Property<"operatorKind", OverloadedOperatorKind> { 704 let Conditional = [{ !identifier }]; 705 let Read = [{ dtn->getOperator() }]; 706 } 707 def : Creator<[{ 708 if (identifier) { 709 return ctx.getDependentTemplateName(qualifier, *identifier); 710 } else { 711 return ctx.getDependentTemplateName(qualifier, *operatorKind); 712 } 713 }]>; 714} 715let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParm"> in { 716 def : ReadHelper<[{ 717 auto parm = node.getAsSubstTemplateTemplateParm(); 718 }]>; 719 def : Property<"replacement", TemplateName> { 720 let Read = [{ parm->getReplacement() }]; 721 } 722 def : Property<"associatedDecl", DeclRef> { 723 let Read = [{ parm->getAssociatedDecl() }]; 724 } 725 def : Property<"index", UInt32> { 726 let Read = [{ parm->getIndex() }]; 727 } 728 def : Property<"packIndex", Optional<UInt32>> { 729 let Read = [{ parm->getPackIndex() }]; 730 } 731 def : Creator<[{ 732 return ctx.getSubstTemplateTemplateParm(replacement, associatedDecl, index, packIndex); 733 }]>; 734} 735let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in { 736 def : ReadHelper<[{ 737 auto parm = node.getAsSubstTemplateTemplateParmPack(); 738 }]>; 739 def : Property<"argumentPack", TemplateArgument> { 740 let Read = [{ parm->getArgumentPack() }]; 741 } 742 def : Property<"associatedDecl", DeclRef> { 743 let Read = [{ parm->getAssociatedDecl() }]; 744 } 745 def : Property<"index", UInt32> { 746 let Read = [{ parm->getIndex() }]; 747 } 748 def : Property<"final", Bool> { 749 let Read = [{ parm->getFinal() }]; 750 } 751 def : Creator<[{ 752 return ctx.getSubstTemplateTemplateParmPack(argumentPack, associatedDecl, index, final); 753 }]>; 754} 755 756// Type cases for TemplateArgument. 757def : PropertyTypeKind<TemplateArgument, TemplateArgumentKind, 758 "node.getKind()">; 759let Class = PropertyTypeCase<TemplateArgument, "Null"> in { 760 def : Creator<[{ 761 return TemplateArgument(); 762 }]>; 763} 764let Class = PropertyTypeCase<TemplateArgument, "Type"> in { 765 def : Property<"type", QualType> { 766 let Read = [{ node.getAsType() }]; 767 } 768 def : Property<"isDefaulted", Bool> { 769 let Read = [{ node.getIsDefaulted() }]; 770 } 771 def : Creator<[{ 772 return TemplateArgument(type, /* isNullPtr */ false, isDefaulted); 773 }]>; 774} 775let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in { 776 def : Property<"declaration", ValueDeclRef> { 777 let Read = [{ node.getAsDecl() }]; 778 } 779 def : Property<"parameterType", QualType> { 780 let Read = [{ node.getParamTypeForDecl() }]; 781 } 782 def : Property<"isDefaulted", Bool> { 783 let Read = [{ node.getIsDefaulted() }]; 784 } 785 def : Creator<[{ 786 return TemplateArgument(declaration, parameterType, isDefaulted); 787 }]>; 788} 789let Class = PropertyTypeCase<TemplateArgument, "NullPtr"> in { 790 def : Property<"type", QualType> { 791 let Read = [{ node.getNullPtrType() }]; 792 } 793 def : Property<"isDefaulted", Bool> { 794 let Read = [{ node.getIsDefaulted() }]; 795 } 796 def : Creator<[{ 797 return TemplateArgument(type, /*nullptr*/ true, isDefaulted); 798 }]>; 799} 800let Class = PropertyTypeCase<TemplateArgument, "Integral"> in { 801 def : Property<"value", APSInt> { 802 let Read = [{ node.getAsIntegral() }]; 803 } 804 def : Property<"type", QualType> { 805 let Read = [{ node.getIntegralType() }]; 806 } 807 def : Property<"isDefaulted", Bool> { 808 let Read = [{ node.getIsDefaulted() }]; 809 } 810 def : Creator<[{ 811 return TemplateArgument(ctx, value, type, isDefaulted); 812 }]>; 813} 814let Class = PropertyTypeCase<TemplateArgument, "StructuralValue"> in { 815 def : Property<"value", APValue> { 816 let Read = [{ node.getAsStructuralValue() }]; 817 } 818 def : Property<"type", QualType> { 819 let Read = [{ node.getStructuralValueType() }]; 820 } 821 def : Property<"isDefaulted", Bool> { 822 let Read = [{ node.getIsDefaulted() }]; 823 } 824 def : Creator<[{ 825 return TemplateArgument(ctx, type, value, isDefaulted); 826 }]>; 827} 828let Class = PropertyTypeCase<TemplateArgument, "Template"> in { 829 def : Property<"name", TemplateName> { 830 let Read = [{ node.getAsTemplateOrTemplatePattern() }]; 831 } 832 def : Property<"isDefaulted", Bool> { 833 let Read = [{ node.getIsDefaulted() }]; 834 } 835 def : Creator<[{ 836 return TemplateArgument(name, isDefaulted); 837 }]>; 838} 839let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in { 840 def : Property<"name", TemplateName> { 841 let Read = [{ node.getAsTemplateOrTemplatePattern() }]; 842 } 843 def : Property<"numExpansions", Optional<UInt32>> { 844 let Read = [{ 845 // Translate unsigned -> uint32_t just in case. 846 llvm::transformOptional(node.getNumTemplateExpansions(), 847 [](unsigned i) { return uint32_t(i); }) 848 }]; 849 } 850 def : Property<"isDefaulted", Bool> { 851 let Read = [{ node.getIsDefaulted() }]; 852 } 853 def : Creator<[{ 854 auto numExpansionsUnsigned = llvm::transformOptional( 855 numExpansions, [](uint32_t i) { return unsigned(i); }); 856 857 return TemplateArgument(name, numExpansionsUnsigned, isDefaulted); 858 }]>; 859} 860let Class = PropertyTypeCase<TemplateArgument, "Expression"> in { 861 def : Property<"expression", ExprRef> { 862 let Read = [{ node.getAsExpr() }]; 863 } 864 def : Property<"isDefaulted", Bool> { 865 let Read = [{ node.getIsDefaulted() }]; 866 } 867 def : Creator<[{ 868 return TemplateArgument(expression, isDefaulted); 869 }]>; 870} 871let Class = PropertyTypeCase<TemplateArgument, "Pack"> in { 872 def : Property<"elements", Array<TemplateArgument>> { 873 let Read = [{ node.pack_elements() }]; 874 } 875 def : Creator<[{ 876 // Copy the pack into the ASTContext. 877 TemplateArgument *ctxElements = new (ctx) TemplateArgument[elements.size()]; 878 for (size_t i = 0, e = elements.size(); i != e; ++i) 879 ctxElements[i] = elements[i]; 880 return TemplateArgument(llvm::ArrayRef(ctxElements, elements.size())); 881 }]>; 882} 883