//==--- 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 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()));
  }]>;
}
