PropertiesBase.td 27 KB

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