123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807 |
- //==--- PropertiesBase.td - Baseline definitions for AST properties -------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- class HasProperties;
- /// The type of the property.
- class PropertyType<string typeName = ""> {
- /// The C++ type name for the type.
- string CXXName = !if(!ne(typeName, ""), typeName, NAME);
- /// Whether the C++ type should generally be passed around by reference.
- bit PassByReference = 0;
- /// Whether `const` should be prepended to the type when writing.
- bit ConstWhenWriting = 0;
- /// Given a value of type Optional<CXXName> bound as 'value', yield a
- /// CXXName that can be serialized into a DataStreamTypeWriter.
- string PackOptional = "";
- /// Given a value of type CXXName bound as 'value' that was deserialized
- /// by a DataStreamTypeReader, yield an Optional<CXXName>.
- string UnpackOptional = "";
- /// A list of types for which buffeers must be passed to the read
- /// operations.
- list<PropertyType> BufferElementTypes = [];
- }
- /// Property types that correspond to specific C++ enums.
- class EnumPropertyType<string typeName = ""> : PropertyType<typeName> {}
- /// Property types that correspond to a specific C++ class.
- /// Supports optional values by using the null representation.
- class RefPropertyType<string className> : PropertyType<className # "*"> {
- let PackOptional =
- "value ? *value : nullptr";
- let UnpackOptional =
- "value ? llvm::Optional<" # CXXName # ">(value) : llvm::None";
- }
- /// Property types that correspond to a specific subclass of another type.
- class SubclassPropertyType<string className, PropertyType base>
- : RefPropertyType<className> {
- PropertyType Base = base;
- string SubclassName = className;
- let ConstWhenWriting = base.ConstWhenWriting;
- }
- /// Property types that support optional values by using their
- /// default value.
- class DefaultValuePropertyType<string typeName = ""> : PropertyType<typeName> {
- let PackOptional =
- "value ? *value : " # CXXName # "()";
- let UnpackOptional =
- "value.isNull() ? llvm::None : llvm::Optional<" # CXXName # ">(value)";
- }
- /// Property types that correspond to integer types and support optional
- /// values by shifting the value over by 1.
- class CountPropertyType<string typeName = ""> : PropertyType<typeName> {
- let PackOptional =
- "value ? *value + 1 : 0";
- let UnpackOptional =
- "value ? llvm::Optional<" # CXXName # ">(value - 1) : llvm::None";
- }
- def APInt : PropertyType<"llvm::APInt"> { let PassByReference = 1; }
- def APSInt : PropertyType<"llvm::APSInt"> { let PassByReference = 1; }
- def APValue : PropertyType { let PassByReference = 1; }
- def APValueKind : EnumPropertyType<"APValue::ValueKind">;
- def ArraySizeModifier : EnumPropertyType<"ArrayType::ArraySizeModifier">;
- def AttrKind : EnumPropertyType<"attr::Kind">;
- def AutoTypeKeyword : EnumPropertyType;
- def Bool : PropertyType<"bool">;
- def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">;
- def CallingConv : EnumPropertyType;
- def DeclarationName : PropertyType;
- def DeclarationNameKind : EnumPropertyType<"DeclarationName::NameKind">;
- def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
- def CXXRecordDeclRef :
- SubclassPropertyType<"CXXRecordDecl", DeclRef>;
- def FunctionDeclRef :
- SubclassPropertyType<"FunctionDecl", DeclRef>;
- def NamedDeclRef :
- SubclassPropertyType<"NamedDecl", DeclRef>;
- def NamespaceDeclRef :
- SubclassPropertyType<"NamespaceDecl", DeclRef>;
- def NamespaceAliasDeclRef :
- SubclassPropertyType<"NamespaceAliasDecl", DeclRef>;
- def ObjCProtocolDeclRef :
- SubclassPropertyType<"ObjCProtocolDecl", DeclRef>;
- def ObjCTypeParamDeclRef :
- SubclassPropertyType<"ObjCTypeParamDecl", DeclRef>;
- def TagDeclRef :
- SubclassPropertyType<"TagDecl", DeclRef>;
- def TemplateDeclRef :
- SubclassPropertyType<"TemplateDecl", DeclRef>;
- def ConceptDeclRef :
- SubclassPropertyType<"ConceptDecl", DeclRef>;
- def TemplateTypeParmDeclRef :
- SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
- def TemplateTemplateParmDeclRef :
- SubclassPropertyType<"TemplateTemplateParmDecl", DeclRef>;
- def UsingShadowDeclRef :
- SubclassPropertyType<"UsingShadowDecl", DeclRef>;
- def ValueDeclRef :
- SubclassPropertyType<"ValueDecl", DeclRef>;
- def ElaboratedTypeKeyword : EnumPropertyType;
- def ExtParameterInfo : PropertyType<"FunctionProtoType::ExtParameterInfo">;
- def FixedPointSemantics : PropertyType<"llvm::FixedPointSemantics"> {
- let PassByReference = 1;
- }
- def Identifier : RefPropertyType<"IdentifierInfo"> { let ConstWhenWriting = 1; }
- def LValuePathEntry : PropertyType<"APValue::LValuePathEntry">;
- def LValuePathSerializationHelper :
- PropertyType<"APValue::LValuePathSerializationHelper"> {
- let BufferElementTypes = [ LValuePathEntry ];
- }
- def NestedNameSpecifier : PropertyType<"NestedNameSpecifier *">;
- def NestedNameSpecifierKind :
- EnumPropertyType<"NestedNameSpecifier::SpecifierKind">;
- def OverloadedOperatorKind : EnumPropertyType;
- def Qualifiers : PropertyType;
- def QualType : DefaultValuePropertyType;
- def RefQualifierKind : EnumPropertyType;
- def Selector : PropertyType;
- def SourceLocation : PropertyType;
- def StmtRef : RefPropertyType<"Stmt"> { let ConstWhenWriting = 1; }
- def ExprRef : SubclassPropertyType<"Expr", StmtRef>;
- def TemplateArgument : PropertyType;
- def TemplateArgumentKind : EnumPropertyType<"TemplateArgument::ArgKind">;
- def TemplateName : DefaultValuePropertyType;
- def TemplateNameKind : EnumPropertyType<"TemplateName::NameKind">;
- def UInt32 : CountPropertyType<"uint32_t">;
- def UInt64 : CountPropertyType<"uint64_t">;
- def UnaryTypeTransformKind : EnumPropertyType<"UnaryTransformType::UTTKind">;
- def VectorKind : EnumPropertyType<"VectorType::VectorKind">;
- def ExceptionSpecInfo : PropertyType<"FunctionProtoType::ExceptionSpecInfo"> {
- let BufferElementTypes = [ QualType ];
- }
- /// Arrays. The corresponding C++ type is ArrayRef of the corresponding
- /// C++ type of the element.
- class Array<PropertyType element> : PropertyType {
- PropertyType Element = element;
- let BufferElementTypes = [ element ];
- }
- /// llvm::Optional<T>. The corresponding C++ type is generally just the
- /// corresponding C++ type of the element.
- ///
- /// Optional<Unsigned> may restrict the range of the operand for some
- /// serialization clients.
- class Optional<PropertyType element> : PropertyType {
- PropertyType Element = element;
- let PassByReference = element.PassByReference;
- }
- /// A property of an AST node.
- class Property<string name, PropertyType type> {
- HasProperties Class;
- string Name = name;
- PropertyType Type = type;
- /// A function for reading the property, expressed in terms of a variable
- /// "node".
- code Read;
- /// Code specifying when this property is available. Can be defined
- /// in terms of other properties, in which case this property must be
- /// read/written after those properties. Using this will make the
- /// value Optional when deserializing.
- ///
- /// FIXME: the emitter doesn't yet force dependent properties to be
- /// read/written later; this only works if the properties used in the
- /// condition happen to be written first.
- code Conditional = "";
- }
- /// A rule for declaring helper variables when read properties from a
- /// value of this type. Note that this means that this code is actually
- /// run when *writing* values of this type; however, naming this
- /// `ReadHelper` makes the connection to the `Read` operations on the
- /// properties much clearer.
- class ReadHelper<code _code> {
- HasProperties Class;
- /// Code which will be run when writing objects of this type before
- /// writing any of the properties, specified in terms of a variable
- /// `node`.
- code Code = _code;
- }
- /// A rule for creating objects of this type.
- class Creator<code create> {
- HasProperties Class;
- /// A function for creating values of this kind, expressed in terms of a
- /// variable `ctx` of type `ASTContext &`. Must also refer to all of the
- /// properties by name.
- code Create = create;
- }
- /// A rule which overrides some of the normal rules.
- class Override {
- HasProperties Class;
- /// Properties from base classes that should be ignored.
- list<string> IgnoredProperties = [];
- }
- /// A description of how to break a type into cases. Providing this and
- /// an exhaustive list of the cases will cause AbstractBasic{Reader,Writer}
- /// to be generated with a default implementation of how to read the
- /// type.
- ///
- /// Creator rules for the cases can additionally access a variable
- /// `kind` of the KindType.
- class PropertyTypeKind<PropertyType type,
- PropertyType kindType,
- string readCode> {
- /// The type for which this describes cases.
- PropertyType Type = type;
- /// The type of this type's kind enum.
- PropertyType KindType = kindType;
- /// The property name to use for the kind.
- string KindPropertyName = "kind";
- /// An expression which reads the kind from a value, expressed in terms
- /// of a variable `node`.
- string Read = readCode;
- }
- /// One of the options for representing a particular type.
- class PropertyTypeCase<PropertyType type, string name> : HasProperties {
- /// The type of which this is a case.
- PropertyType Type = type;
- /// The name of the case (a value of the type's kind enum).
- string Name = name;
- }
- // Type cases for APValue.
- def : PropertyTypeKind<APValue, APValueKind,
- "node.getKind()">;
- let Class = PropertyTypeCase<APValue, "None"> in {
- def : Creator<[{ return APValue(); }]>;
- }
- let Class = PropertyTypeCase<APValue, "Indeterminate"> in {
- def : Creator<[{ return APValue::IndeterminateValue(); }]>;
- }
- let Class = PropertyTypeCase<APValue, "Int"> in {
- def : Property<"value", APSInt> {
- let Read = [{ node.getInt() }];
- }
- def : Creator<[{ return APValue(value); }]>;
- }
- let Class = PropertyTypeCase<APValue, "Float"> in {
- def : Property<"semantics", UInt32> {
- let Read = [{
- static_cast<uint32_t>(
- llvm::APFloatBase::SemanticsToEnum(node.getFloat().getSemantics()))
- }];
- }
- def : Property<"value", APInt> {
- let Read = [{ node.getFloat().bitcastToAPInt() }];
- }
- def : Creator<[{
- const llvm::fltSemantics &floatSema = llvm::APFloatBase::EnumToSemantics(
- static_cast<llvm::APFloatBase::Semantics>(semantics));
- return APValue(llvm::APFloat(floatSema, value));
- }]>;
- }
- let Class = PropertyTypeCase<APValue, "FixedPoint"> in {
- def : Property<"semantics", FixedPointSemantics> {
- let Read = [{ node.getFixedPoint().getSemantics() }];
- }
- def : Property<"value", APSInt> {
- let Read = [{ node.getFixedPoint().getValue() }];
- }
- def : Creator<[{
- return APValue(llvm::APFixedPoint(std::move(value), semantics));
- }]>;
- }
- let Class = PropertyTypeCase<APValue, "ComplexInt"> in {
- def : Property<"real", APSInt> {
- let Read = [{ node.getComplexIntReal() }];
- }
- def : Property<"imag", APSInt> {
- let Read = [{ node.getComplexIntImag() }];
- }
- def : Creator<[{ return APValue(real, imag); }]>;
- }
- let Class = PropertyTypeCase<APValue, "ComplexFloat"> in {
- def : ReadHelper<[{
- auto sema = llvm::APFloatBase::SemanticsToEnum(
- node.getComplexFloatReal().getSemantics());
- assert(sema == llvm::APFloatBase::SemanticsToEnum(
- node.getComplexFloatImag().getSemantics()));
- }]>;
- def : Property<"semantics", UInt32> {
- let Read = [{ static_cast<uint32_t>(sema) }];
- }
- def : Property<"real", APInt> {
- let Read = [{ node.getComplexFloatReal().bitcastToAPInt() }];
- }
- def : Property<"imag", APInt> {
- let Read = [{ node.getComplexFloatImag().bitcastToAPInt() }];
- }
- def : Creator<[{
- const llvm::fltSemantics &sema = llvm::APFloatBase::EnumToSemantics(
- static_cast<llvm::APFloatBase::Semantics>(semantics));
- return APValue(llvm::APFloat(sema, real),
- llvm::APFloat(sema, imag));
- }]>;
- }
- let Class = PropertyTypeCase<APValue, "Vector"> in {
- def : ReadHelper<[{
- SmallVector<APValue, 4> buffer;
- unsigned len = node.getVectorLength();
- for (unsigned i = 0; i < len; ++i)
- buffer.push_back(node.getVectorElt(i));
- }]>;
- def : Property<"elements", Array<APValue>> {
- let Read = [{ buffer }];
- }
- def : Creator<[{
- APValue result;
- result.MakeVector();
- unsigned length = elements.size();
- (void)result.setVectorUninit(length);
- for (unsigned i = 0; i < length; i++)
- result.getVectorElt(i) = elements[i];
- return result;
- }]>;
- }
- let Class = PropertyTypeCase<APValue, "Array"> in {
- def : ReadHelper<[{
- SmallVector<APValue, 4> buffer{};
- unsigned initLength = node.getArrayInitializedElts();
- for (unsigned i = 0; i < initLength; ++i)
- buffer.push_back(node.getArrayInitializedElt(i));
- if (node.hasArrayFiller())
- buffer.push_back(node.getArrayFiller());
- }]>;
- def : Property<"totalLength", UInt32> {
- let Read = [{ node.getArraySize() }];
- }
- def : Property<"hasFiller", Bool> {
- let Read = [{ node.hasArrayFiller() }];
- }
- def : Property<"elements", Array<APValue>> {
- let Read = [{ buffer }];
- }
- def : Creator<[{
- APValue result;
- unsigned initLength = elements.size() - (hasFiller ? 1 : 0);
- result.MakeArray(initLength, totalLength);
- for (unsigned i = 0; i < initLength; ++i)
- result.getArrayInitializedElt(i) = elements[i];
- if (hasFiller)
- result.getArrayFiller() = elements.back();
- return result;
- }]>;
- }
- let Class = PropertyTypeCase<APValue, "Struct"> in {
- def : ReadHelper<[{
- SmallVector<APValue, 4> structBases;
- unsigned numBases = node.getStructNumBases();
- for (unsigned i = 0; i < numBases; ++i)
- structBases.push_back(node.getStructBase(i));
- SmallVector<APValue, 4> structFields;
- unsigned numFields = node.getStructNumFields();
- for (unsigned i = 0; i < numFields; ++i)
- structFields.push_back(node.getStructField(i));
- }]>;
- def : Property<"bases", Array<APValue>> {
- let Read = [{ structBases }];
- }
- def : Property<"fields", Array<APValue>> {
- let Read = [{ structFields }];
- }
- def : Creator<[{
- APValue result;
- result.MakeStruct(bases.size(), fields.size());
- for (unsigned i = 0; i < bases.size(); ++i)
- result.getStructBase(i) = bases[i];
- for (unsigned i = 0; i < fields.size(); ++i)
- result.getStructField(i) = fields[i];
- return result;
- }]>;
- }
- let Class = PropertyTypeCase<APValue, "Union"> in {
- def : Property<"fieldDecl", DeclRef> {
- let Read = [{ node.getUnionField() }];
- }
- def : Property<"value", APValue> {
- let Read = [{ node.getUnionValue() }];
- }
- def : Creator<[{
- return APValue(cast<clang::FieldDecl>(fieldDecl), std::move(value));
- }]>;
- }
- let Class = PropertyTypeCase<APValue, "AddrLabelDiff"> in {
- def : Property<"lhs", StmtRef> {
- let Read = [{ const_cast<AddrLabelExpr *>(node.getAddrLabelDiffLHS()) }];
- }
- def : Property<"rhs", StmtRef> {
- let Read = [{ const_cast<AddrLabelExpr *>(node.getAddrLabelDiffRHS()) }];
- }
- def : Creator<[{
- return APValue(cast<AddrLabelExpr>(lhs), cast<AddrLabelExpr>(rhs));
- }]>;
- }
- let Class = PropertyTypeCase<APValue, "MemberPointer"> in {
- def : Property<"isDerived", Bool> {
- let Read = [{ node.isMemberPointerToDerivedMember() }];
- }
- def : Property<"member", ValueDeclRef> {
- let Read = [{ node.getMemberPointerDecl() }];
- }
- def : Property<"memberPath", Array<CXXRecordDeclRef>> {
- let Read = [{ node.getMemberPointerPath() }];
- }
- def : Creator<[{
- APValue result;
- unsigned pathSize = memberPath.size();
- const CXXRecordDecl **pathArray =
- result.setMemberPointerUninit(member, isDerived, pathSize).data();
- for (unsigned i = 0; i < pathSize; ++i)
- pathArray[i] = memberPath[i]->getCanonicalDecl();
- return result;
- }]>;
- }
- let Class = PropertyTypeCase<APValue, "LValue"> in {
- def : ReadHelper<[{
- auto lvalueBase = node.getLValueBase();
- const Expr *expr =
- lvalueBase ? lvalueBase.dyn_cast<const Expr *>() : nullptr;
- bool lvalueBaseIsExpr = (bool) expr;
- bool lvalueBaseIsTypeInfo = lvalueBase.is<TypeInfoLValue>();
- QualType elemTy;
- if (lvalueBase) {
- if (lvalueBaseIsTypeInfo) {
- elemTy = lvalueBase.getTypeInfoType();
- } else if (lvalueBaseIsExpr) {
- elemTy = expr->getType();
- } else {
- elemTy = lvalueBase.get<const ValueDecl *>()->getType();
- }
- }
- }]>;
- def : Property<"hasLValuePath", Bool> {
- let Read = [{ node.hasLValuePath() }];
- }
- def : Property<"isLValueOnePastTheEnd", Bool> {
- let Read = [{ node.isLValueOnePastTheEnd() }];
- }
- def : Property<"isExpr", Bool> {
- let Read = [{ lvalueBaseIsExpr }];
- }
- def : Property<"isTypeInfo", Bool> {
- let Read = [{ lvalueBaseIsTypeInfo }];
- }
- def : Property<"hasBase", Bool> {
- let Read = [{ static_cast<bool>(lvalueBase) }];
- }
- def : Property<"isNullPtr", Bool> {
- let Read = [{ node.isNullPointer() }];
- }
- def : Property<"typeInfo", QualType> {
- let Conditional = [{ hasBase && isTypeInfo }];
- let Read = [{
- QualType(node.getLValueBase().get<TypeInfoLValue>().getType(), 0)
- }];
- }
- def : Property<"type", QualType> {
- let Conditional = [{ hasBase && isTypeInfo }];
- let Read = [{ node.getLValueBase().getTypeInfoType() }];
- }
- def : Property<"callIndex", UInt32> {
- let Conditional = [{ hasBase && !isTypeInfo }];
- let Read = [{ node.getLValueBase().getCallIndex() }];
- }
- def : Property<"version", UInt32> {
- let Conditional = [{ hasBase && !isTypeInfo }];
- let Read = [{ node.getLValueBase().getVersion() }];
- }
- def : Property<"stmt", StmtRef> {
- let Conditional = [{ hasBase && !isTypeInfo && isExpr }];
- let Read = [{ const_cast<Expr *>(expr) }];
- }
- def : Property<"decl", DeclRef> {
- let Conditional = [{ hasBase && !isTypeInfo && !isExpr }];
- let Read = [{ lvalueBase.get<const ValueDecl *>() }];
- }
- def : Property<"offsetQuantity", UInt32> {
- let Read = [{ node.getLValueOffset().getQuantity() }];
- }
- def : Property<"lvaluePath", LValuePathSerializationHelper> {
- let Conditional = [{ hasLValuePath }];
- let Read = [{
- APValue::LValuePathSerializationHelper(node.getLValuePath(), elemTy)
- }];
- }
- def : Creator<[{
- (void)ctx;
- APValue::LValueBase base;
- QualType elemTy;
- if (hasBase) {
- if (isTypeInfo) {
- base = APValue::LValueBase::getTypeInfo(
- TypeInfoLValue(typeInfo.getValue().getTypePtr()), type.getValue());
- elemTy = base.getTypeInfoType();
- } else if (isExpr) {
- base = APValue::LValueBase(cast<Expr>(stmt.getValue()),
- callIndex.getValue(), version.getValue());
- elemTy = base.get<const Expr *>()->getType();
- } else {
- base = APValue::LValueBase(cast<ValueDecl>(decl.getValue()),
- callIndex.getValue(), version.getValue());
- elemTy = base.get<const ValueDecl *>()->getType();
- }
- }
- CharUnits offset = CharUnits::fromQuantity(offsetQuantity);
- APValue result;
- result.MakeLValue();
- if (!hasLValuePath) {
- result.setLValue(base, offset, APValue::NoLValuePath{}, isNullPtr);
- return result;
- }
- auto pathLength = lvaluePath->Path.size();
- APValue::LValuePathEntry *path = result.setLValueUninit(
- base, offset, pathLength, isLValueOnePastTheEnd, isNullPtr).data();
- assert(lvaluePath->getType() == elemTy && "Unexpected type reference!");
- llvm::copy(lvaluePath->Path, path);
- return result;
- }]>;
- }
- // Type cases for DeclarationName.
- def : PropertyTypeKind<DeclarationName, DeclarationNameKind,
- "node.getNameKind()">;
- let Class = PropertyTypeCase<DeclarationName, "Identifier"> in {
- def : Property<"identifier", Identifier> {
- let Read = [{ node.getAsIdentifierInfo() }];
- }
- def : Creator<[{
- return DeclarationName(identifier);
- }]>;
- }
- foreach count = ["Zero", "One", "Multi"] in {
- let Class = PropertyTypeCase<DeclarationName, "ObjC"#count#"ArgSelector"> in {
- def : Property<"selector", Selector> {
- let Read = [{ node.getObjCSelector() }];
- }
- def : Creator<[{
- return DeclarationName(selector);
- }]>;
- }
- }
- foreach kind = ["Constructor", "Destructor", "ConversionFunction"] in {
- let Class = PropertyTypeCase<DeclarationName, "CXX"#kind#"Name"> in {
- def : Property<"type", QualType> {
- let Read = [{ node.getCXXNameType() }];
- }
- def : Creator<[{
- return ctx.DeclarationNames.getCXX}]#kind#[{Name(
- ctx.getCanonicalType(type));
- }]>;
- }
- }
- let Class = PropertyTypeCase<DeclarationName, "CXXDeductionGuideName"> in {
- def : Property<"declaration", TemplateDeclRef> {
- let Read = [{ node.getCXXDeductionGuideTemplate() }];
- }
- def : Creator<[{
- return ctx.DeclarationNames.getCXXDeductionGuideName(declaration);
- }]>;
- }
- let Class = PropertyTypeCase<DeclarationName, "CXXOperatorName"> in {
- def : Property<"operatorKind", OverloadedOperatorKind> {
- let Read = [{ node.getCXXOverloadedOperator() }];
- }
- def : Creator<[{
- return ctx.DeclarationNames.getCXXOperatorName(operatorKind);
- }]>;
- }
- let Class = PropertyTypeCase<DeclarationName, "CXXLiteralOperatorName"> in {
- def : Property<"identifier", Identifier> {
- let Read = [{ node.getCXXLiteralIdentifier() }];
- }
- def : Creator<[{
- return ctx.DeclarationNames.getCXXLiteralOperatorName(identifier);
- }]>;
- }
- let Class = PropertyTypeCase<DeclarationName, "CXXUsingDirective"> in {
- def : Creator<[{
- return DeclarationName::getUsingDirectiveName();
- }]>;
- }
- // Type cases for TemplateName.
- def : PropertyTypeKind<TemplateName, TemplateNameKind, "node.getKind()">;
- let Class = PropertyTypeCase<TemplateName, "Template"> in {
- def : Property<"declaration", TemplateDeclRef> {
- let Read = [{ node.getAsTemplateDecl() }];
- }
- def : Creator<[{
- return TemplateName(declaration);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateName, "OverloadedTemplate"> in {
- def : Property<"overloads", Array<NamedDeclRef>> {
- let Read = [{ node.getAsOverloadedTemplate()->decls() }];
- }
- def : Creator<[{
- // Copy into an UnresolvedSet to satisfy the interface.
- UnresolvedSet<8> overloadSet;
- for (auto overload : overloads) {
- overloadSet.addDecl(overload);
- }
- return ctx.getOverloadedTemplateName(overloadSet.begin(),
- overloadSet.end());
- }]>;
- }
- let Class = PropertyTypeCase<TemplateName, "AssumedTemplate"> in {
- def : Property<"name", DeclarationName> {
- let Read = [{ node.getAsAssumedTemplateName()->getDeclName() }];
- }
- def : Creator<[{
- return ctx.getAssumedTemplateName(name);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateName, "QualifiedTemplate"> in {
- def : ReadHelper<[{
- auto qtn = node.getAsQualifiedTemplateName();
- }]>;
- def : Property<"qualifier", NestedNameSpecifier> {
- let Read = [{ qtn->getQualifier() }];
- }
- def : Property<"hasTemplateKeyword", Bool> {
- let Read = [{ qtn->hasTemplateKeyword() }];
- }
- def : Property<"declaration", TemplateDeclRef> {
- let Read = [{ qtn->getTemplateDecl() }];
- }
- def : Creator<[{
- return ctx.getQualifiedTemplateName(qualifier, hasTemplateKeyword,
- declaration);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateName, "DependentTemplate"> in {
- def : ReadHelper<[{
- auto dtn = node.getAsDependentTemplateName();
- }]>;
- def : Property<"qualifier", NestedNameSpecifier> {
- let Read = [{ dtn->getQualifier() }];
- }
- def : Property<"identifier", Optional<Identifier>> {
- let Read = [{ makeOptionalFromPointer(
- dtn->isIdentifier()
- ? dtn->getIdentifier()
- : nullptr) }];
- }
- def : Property<"operatorKind", OverloadedOperatorKind> {
- let Conditional = [{ !identifier }];
- let Read = [{ dtn->getOperator() }];
- }
- def : Creator<[{
- if (identifier) {
- return ctx.getDependentTemplateName(qualifier, *identifier);
- } else {
- return ctx.getDependentTemplateName(qualifier, *operatorKind);
- }
- }]>;
- }
- let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParm"> in {
- def : ReadHelper<[{
- auto parm = node.getAsSubstTemplateTemplateParm();
- }]>;
- def : Property<"parameter", TemplateTemplateParmDeclRef> {
- let Read = [{ parm->getParameter() }];
- }
- def : Property<"replacement", TemplateName> {
- let Read = [{ parm->getReplacement() }];
- }
- def : Creator<[{
- return ctx.getSubstTemplateTemplateParm(parameter, replacement);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in {
- def : ReadHelper<[{
- auto parm = node.getAsSubstTemplateTemplateParmPack();
- }]>;
- def : Property<"parameterPack", TemplateTemplateParmDeclRef> {
- let Read = [{ parm->getParameterPack() }];
- }
- def : Property<"argumentPack", TemplateArgument> {
- let Read = [{ parm->getArgumentPack() }];
- }
- def : Creator<[{
- return ctx.getSubstTemplateTemplateParmPack(parameterPack, argumentPack);
- }]>;
- }
- // Type cases for TemplateArgument.
- def : PropertyTypeKind<TemplateArgument, TemplateArgumentKind,
- "node.getKind()">;
- let Class = PropertyTypeCase<TemplateArgument, "Null"> in {
- def : Creator<[{
- return TemplateArgument();
- }]>;
- }
- let Class = PropertyTypeCase<TemplateArgument, "Type"> in {
- def : Property<"type", QualType> {
- let Read = [{ node.getAsType() }];
- }
- def : Creator<[{
- return TemplateArgument(type);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in {
- def : Property<"declaration", ValueDeclRef> {
- let Read = [{ node.getAsDecl() }];
- }
- def : Property<"parameterType", QualType> {
- let Read = [{ node.getParamTypeForDecl() }];
- }
- def : Creator<[{
- return TemplateArgument(declaration, parameterType);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateArgument, "NullPtr"> in {
- def : Property<"type", QualType> {
- let Read = [{ node.getNullPtrType() }];
- }
- def : Creator<[{
- return TemplateArgument(type, /*nullptr*/ true);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
- def : Property<"value", APSInt> {
- let Read = [{ node.getAsIntegral() }];
- }
- def : Property<"type", QualType> {
- let Read = [{ node.getIntegralType() }];
- }
- def : Creator<[{
- return TemplateArgument(ctx, value, type);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateArgument, "Template"> in {
- def : Property<"name", TemplateName> {
- let Read = [{ node.getAsTemplateOrTemplatePattern() }];
- }
- def : Creator<[{
- return TemplateArgument(name);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in {
- def : Property<"name", TemplateName> {
- let Read = [{ node.getAsTemplateOrTemplatePattern() }];
- }
- def : Property<"numExpansions", Optional<UInt32>> {
- let Read = [{
- // Translate unsigned -> uint32_t just in case.
- node.getNumTemplateExpansions().map(
- [](unsigned i) { return uint32_t(i); })
- }];
- }
- def : Creator<[{
- auto numExpansionsUnsigned =
- numExpansions.map([](uint32_t i) { return unsigned(i); });
- return TemplateArgument(name, numExpansionsUnsigned);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateArgument, "Expression"> in {
- def : Property<"expression", ExprRef> {
- let Read = [{ node.getAsExpr() }];
- }
- def : Creator<[{
- return TemplateArgument(expression);
- }]>;
- }
- let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {
- def : Property<"elements", Array<TemplateArgument>> {
- let Read = [{ node.pack_elements() }];
- }
- def : Creator<[{
- // Copy the pack into the ASTContext.
- TemplateArgument *ctxElements = new (ctx) TemplateArgument[elements.size()];
- for (size_t i = 0, e = elements.size(); i != e; ++i)
- ctxElements[i] = elements[i];
- return TemplateArgument(llvm::makeArrayRef(ctxElements, elements.size()));
- }]>;
- }
|