PropertiesBase.td 28 KB

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