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