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