/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* A CRTP writer for Clang Type nodes                                         *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

template <class PropertyWriter>
class AbstractTypeWriter {
public:
  PropertyWriter &W;

  AbstractTypeWriter(PropertyWriter &W) : W(W) {}

  void write(const Type *node) {
    switch (node->getTypeClass()) {
    case Type::Adjusted:
      return writeAdjustedType(static_cast<const AdjustedType *>(node));
    case Type::Decayed:
      return writeDecayedType(static_cast<const DecayedType *>(node));
    case Type::ConstantArray:
      return writeConstantArrayType(static_cast<const ConstantArrayType *>(node));
    case Type::DependentSizedArray:
      return writeDependentSizedArrayType(static_cast<const DependentSizedArrayType *>(node));
    case Type::IncompleteArray:
      return writeIncompleteArrayType(static_cast<const IncompleteArrayType *>(node));
    case Type::VariableArray:
      return writeVariableArrayType(static_cast<const VariableArrayType *>(node));
    case Type::Atomic:
      return writeAtomicType(static_cast<const AtomicType *>(node));
    case Type::Attributed:
      return writeAttributedType(static_cast<const AttributedType *>(node));
    case Type::BlockPointer:
      return writeBlockPointerType(static_cast<const BlockPointerType *>(node));
    case Type::Builtin:
      return writeBuiltinType(static_cast<const BuiltinType *>(node));
    case Type::Complex:
      return writeComplexType(static_cast<const ComplexType *>(node));
    case Type::Decltype:
      return writeDecltypeType(static_cast<const DecltypeType *>(node));
    case Type::Auto:
      return writeAutoType(static_cast<const AutoType *>(node));
    case Type::DeducedTemplateSpecialization:
      return writeDeducedTemplateSpecializationType(static_cast<const DeducedTemplateSpecializationType *>(node));
    case Type::DependentAddressSpace:
      return writeDependentAddressSpaceType(static_cast<const DependentAddressSpaceType *>(node));
    case Type::DependentExtInt:
      return writeDependentExtIntType(static_cast<const DependentExtIntType *>(node));
    case Type::DependentName:
      return writeDependentNameType(static_cast<const DependentNameType *>(node));
    case Type::DependentSizedExtVector:
      return writeDependentSizedExtVectorType(static_cast<const DependentSizedExtVectorType *>(node));
    case Type::DependentTemplateSpecialization:
      return writeDependentTemplateSpecializationType(static_cast<const DependentTemplateSpecializationType *>(node));
    case Type::DependentVector:
      return writeDependentVectorType(static_cast<const DependentVectorType *>(node));
    case Type::Elaborated:
      return writeElaboratedType(static_cast<const ElaboratedType *>(node));
    case Type::ExtInt:
      return writeExtIntType(static_cast<const ExtIntType *>(node));
    case Type::FunctionNoProto:
      return writeFunctionNoProtoType(static_cast<const FunctionNoProtoType *>(node));
    case Type::FunctionProto:
      return writeFunctionProtoType(static_cast<const FunctionProtoType *>(node));
    case Type::InjectedClassName:
      return writeInjectedClassNameType(static_cast<const InjectedClassNameType *>(node));
    case Type::MacroQualified:
      return writeMacroQualifiedType(static_cast<const MacroQualifiedType *>(node));
    case Type::ConstantMatrix:
      return writeConstantMatrixType(static_cast<const ConstantMatrixType *>(node));
    case Type::DependentSizedMatrix:
      return writeDependentSizedMatrixType(static_cast<const DependentSizedMatrixType *>(node));
    case Type::MemberPointer:
      return writeMemberPointerType(static_cast<const MemberPointerType *>(node));
    case Type::ObjCObjectPointer:
      return writeObjCObjectPointerType(static_cast<const ObjCObjectPointerType *>(node));
    case Type::ObjCObject:
      return writeObjCObjectType(static_cast<const ObjCObjectType *>(node));
    case Type::ObjCInterface:
      return writeObjCInterfaceType(static_cast<const ObjCInterfaceType *>(node));
    case Type::ObjCTypeParam:
      return writeObjCTypeParamType(static_cast<const ObjCTypeParamType *>(node));
    case Type::PackExpansion:
      return writePackExpansionType(static_cast<const PackExpansionType *>(node));
    case Type::Paren:
      return writeParenType(static_cast<const ParenType *>(node));
    case Type::Pipe:
      return writePipeType(static_cast<const PipeType *>(node));
    case Type::Pointer:
      return writePointerType(static_cast<const PointerType *>(node));
    case Type::LValueReference:
      return writeLValueReferenceType(static_cast<const LValueReferenceType *>(node));
    case Type::RValueReference:
      return writeRValueReferenceType(static_cast<const RValueReferenceType *>(node));
    case Type::SubstTemplateTypeParmPack:
      return writeSubstTemplateTypeParmPackType(static_cast<const SubstTemplateTypeParmPackType *>(node));
    case Type::SubstTemplateTypeParm:
      return writeSubstTemplateTypeParmType(static_cast<const SubstTemplateTypeParmType *>(node));
    case Type::Enum:
      return writeEnumType(static_cast<const EnumType *>(node));
    case Type::Record:
      return writeRecordType(static_cast<const RecordType *>(node));
    case Type::TemplateSpecialization:
      return writeTemplateSpecializationType(static_cast<const TemplateSpecializationType *>(node));
    case Type::TemplateTypeParm:
      return writeTemplateTypeParmType(static_cast<const TemplateTypeParmType *>(node));
    case Type::TypeOfExpr:
      return writeTypeOfExprType(static_cast<const TypeOfExprType *>(node));
    case Type::TypeOf:
      return writeTypeOfType(static_cast<const TypeOfType *>(node));
    case Type::Typedef:
      return writeTypedefType(static_cast<const TypedefType *>(node));
    case Type::UnaryTransform:
      return writeUnaryTransformType(static_cast<const UnaryTransformType *>(node));
    case Type::UnresolvedUsing:
      return writeUnresolvedUsingType(static_cast<const UnresolvedUsingType *>(node));
    case Type::Vector:
      return writeVectorType(static_cast<const VectorType *>(node));
    case Type::ExtVector:
      return writeExtVectorType(static_cast<const ExtVectorType *>(node));
    }
    llvm_unreachable("bad kind");
  }

  void writeAdjustedType(const AdjustedType *node) {
    QualType originalType = ( node->getOriginalType() );
    W.find("originalType").writeQualType(originalType);
    QualType adjustedType = ( node->getAdjustedType() );
    W.find("adjustedType").writeQualType(adjustedType);
  }

  void writeDecayedType(const DecayedType *node) {
    QualType originalType = ( node->getOriginalType() );
    W.find("originalType").writeQualType(originalType);
  }

  void writeConstantArrayType(const ConstantArrayType *node) {
    llvm::APInt sizeValue = ( node->getSize() );
    W.find("sizeValue").writeAPInt(sizeValue);
    const Expr* size = ( node->getSizeExpr() );
    W.find("size").writeExprRef(size);
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
    ArrayType::ArraySizeModifier sizeModifier = ( node->getSizeModifier() );
    W.find("sizeModifier").writeArraySizeModifier(sizeModifier);
    Qualifiers indexQualifiers = ( Qualifiers::fromCVRMask(node->getIndexTypeCVRQualifiers()) );
    W.find("indexQualifiers").writeQualifiers(indexQualifiers);
  }

  void writeDependentSizedArrayType(const DependentSizedArrayType *node) {
    const Expr* size = ( node->getSizeExpr() );
    W.find("size").writeExprRef(size);
    SourceLocation leftBracketLoc = ( node->getLBracketLoc() );
    W.find("leftBracketLoc").writeSourceLocation(leftBracketLoc);
    SourceLocation rightBracketLoc = ( node->getRBracketLoc() );
    W.find("rightBracketLoc").writeSourceLocation(rightBracketLoc);
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
    ArrayType::ArraySizeModifier sizeModifier = ( node->getSizeModifier() );
    W.find("sizeModifier").writeArraySizeModifier(sizeModifier);
    Qualifiers indexQualifiers = ( Qualifiers::fromCVRMask(node->getIndexTypeCVRQualifiers()) );
    W.find("indexQualifiers").writeQualifiers(indexQualifiers);
  }

  void writeIncompleteArrayType(const IncompleteArrayType *node) {
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
    ArrayType::ArraySizeModifier sizeModifier = ( node->getSizeModifier() );
    W.find("sizeModifier").writeArraySizeModifier(sizeModifier);
    Qualifiers indexQualifiers = ( Qualifiers::fromCVRMask(node->getIndexTypeCVRQualifiers()) );
    W.find("indexQualifiers").writeQualifiers(indexQualifiers);
  }

  void writeVariableArrayType(const VariableArrayType *node) {
    SourceLocation leftBracketLoc = ( node->getLBracketLoc() );
    W.find("leftBracketLoc").writeSourceLocation(leftBracketLoc);
    SourceLocation rightBracketLoc = ( node->getRBracketLoc() );
    W.find("rightBracketLoc").writeSourceLocation(rightBracketLoc);
    const Expr* size = ( node->getSizeExpr() );
    W.find("size").writeExprRef(size);
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
    ArrayType::ArraySizeModifier sizeModifier = ( node->getSizeModifier() );
    W.find("sizeModifier").writeArraySizeModifier(sizeModifier);
    Qualifiers indexQualifiers = ( Qualifiers::fromCVRMask(node->getIndexTypeCVRQualifiers()) );
    W.find("indexQualifiers").writeQualifiers(indexQualifiers);
  }

  void writeAtomicType(const AtomicType *node) {
    QualType valueType = ( node->getValueType() );
    W.find("valueType").writeQualType(valueType);
  }

  void writeAttributedType(const AttributedType *node) {
    QualType modifiedType = ( node->getModifiedType() );
    W.find("modifiedType").writeQualType(modifiedType);
    QualType equivalentType = ( node->getEquivalentType() );
    W.find("equivalentType").writeQualType(equivalentType);
    attr::Kind attribute = ( node->getAttrKind() );
    W.find("attribute").writeAttrKind(attribute);
  }

  void writeBlockPointerType(const BlockPointerType *node) {
    QualType pointeeType = ( node->getPointeeType() );
    W.find("pointeeType").writeQualType(pointeeType);
  }

  void writeBuiltinType(const BuiltinType *node) {
    BuiltinType::Kind kind = ( node->getKind() );
    W.find("kind").writeBuiltinTypeKind(kind);
  }

  void writeComplexType(const ComplexType *node) {
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
  }

  void writeDecltypeType(const DecltypeType *node) {
    QualType underlyingType = ( node->getUnderlyingType() );
    W.find("underlyingType").writeQualType(underlyingType);
    const Expr* expression = ( node->getUnderlyingExpr() );
    W.find("expression").writeExprRef(expression);
  }

  void writeAutoType(const AutoType *node) {
    llvm::Optional<QualType> deducedType = ( makeOptionalFromNullable(node->getDeducedType()) );
    W.find("deducedType").writeOptional(deducedType);
    AutoTypeKeyword keyword = ( node->getKeyword() );
    W.find("keyword").writeAutoTypeKeyword(keyword);
    llvm::Optional<const ConceptDecl*> typeConstraintConcept = ( makeOptionalFromPointer(
        const_cast<const ConceptDecl*>(node->getTypeConstraintConcept())) );
    W.find("typeConstraintConcept").writeOptional(typeConstraintConcept);
    llvm::ArrayRef<TemplateArgument> typeConstraintArguments = ( node->getTypeConstraintArguments() );
    W.find("typeConstraintArguments").writeArray(typeConstraintArguments);
    uint32_t dependence = ( !node->getDeducedType().isNull() ? 0 :
                  node->containsUnexpandedParameterPack() ? 2 :
                  node->isDependentType() ? 1 : 0 );
    W.find("dependence").writeUInt32(dependence);
  }

  void writeDeducedTemplateSpecializationType(const DeducedTemplateSpecializationType *node) {
    llvm::Optional<TemplateName> templateName = ( makeOptionalFromNullable(node->getTemplateName()) );
    W.find("templateName").writeOptional(templateName);
    QualType deducedType = ( node->getDeducedType() );
    W.find("deducedType").writeQualType(deducedType);
    bool dependent = ( !node->getDeducedType().isNull()
                    ? false : node->isDependentType() );
    W.find("dependent").writeBool(dependent);
  }

  void writeDependentAddressSpaceType(const DependentAddressSpaceType *node) {
    QualType pointeeType = ( node->getPointeeType() );
    W.find("pointeeType").writeQualType(pointeeType);
    const Expr* addressSpace = ( node->getAddrSpaceExpr() );
    W.find("addressSpace").writeExprRef(addressSpace);
    SourceLocation attributeLoc = ( node->getAttributeLoc() );
    W.find("attributeLoc").writeSourceLocation(attributeLoc);
  }

  void writeDependentExtIntType(const DependentExtIntType *node) {
    bool isUnsigned = ( node->isUnsigned() );
    W.find("isUnsigned").writeBool(isUnsigned);
    const Expr* numBitsExpr = ( node->getNumBitsExpr() );
    W.find("numBitsExpr").writeExprRef(numBitsExpr);
  }

  void writeDependentNameType(const DependentNameType *node) {
    ElaboratedTypeKeyword keyword = ( node->getKeyword() );
    W.find("keyword").writeElaboratedTypeKeyword(keyword);
    NestedNameSpecifier * qualifier = ( node->getQualifier() );
    W.find("qualifier").writeNestedNameSpecifier(qualifier);
    const IdentifierInfo* name = ( node->getIdentifier() );
    W.find("name").writeIdentifier(name);
    llvm::Optional<QualType> underlyingType = (
      node->isCanonicalUnqualified()
        ? llvm::None
        : llvm::Optional<QualType>(node->getCanonicalTypeInternal())
    );
    W.find("underlyingType").writeOptional(underlyingType);
  }

  void writeDependentSizedExtVectorType(const DependentSizedExtVectorType *node) {
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
    const Expr* size = ( node->getSizeExpr() );
    W.find("size").writeExprRef(size);
    SourceLocation attributeLoc = ( node->getAttributeLoc() );
    W.find("attributeLoc").writeSourceLocation(attributeLoc);
  }

  void writeDependentTemplateSpecializationType(const DependentTemplateSpecializationType *node) {
    ElaboratedTypeKeyword keyword = ( node->getKeyword() );
    W.find("keyword").writeElaboratedTypeKeyword(keyword);
    NestedNameSpecifier * qualifier = ( node->getQualifier() );
    W.find("qualifier").writeNestedNameSpecifier(qualifier);
    const IdentifierInfo* name = ( node->getIdentifier() );
    W.find("name").writeIdentifier(name);
    llvm::ArrayRef<TemplateArgument> templateArguments = ( node->template_arguments() );
    W.find("templateArguments").writeArray(templateArguments);
  }

  void writeDependentVectorType(const DependentVectorType *node) {
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
    const Expr* size = ( node->getSizeExpr() );
    W.find("size").writeExprRef(size);
    SourceLocation attributeLoc = ( node->getAttributeLoc() );
    W.find("attributeLoc").writeSourceLocation(attributeLoc);
    VectorType::VectorKind vectorKind = ( node->getVectorKind() );
    W.find("vectorKind").writeVectorKind(vectorKind);
  }

  void writeElaboratedType(const ElaboratedType *node) {
    ElaboratedTypeKeyword keyword = ( node->getKeyword() );
    W.find("keyword").writeElaboratedTypeKeyword(keyword);
    NestedNameSpecifier * qualifier = ( node->getQualifier() );
    W.find("qualifier").writeNestedNameSpecifier(qualifier);
    QualType namedType = ( node->getNamedType() );
    W.find("namedType").writeQualType(namedType);
    llvm::Optional<const TagDecl*> ownedTag = ( makeOptionalFromPointer(
                    const_cast<const TagDecl *>(node->getOwnedTagDecl())) );
    W.find("ownedTag").writeOptional(ownedTag);
  }

  void writeExtIntType(const ExtIntType *node) {
    bool isUnsigned = ( node->isUnsigned() );
    W.find("isUnsigned").writeBool(isUnsigned);
    uint32_t numBits = ( node->getNumBits() );
    W.find("numBits").writeUInt32(numBits);
  }

  void writeFunctionNoProtoType(const FunctionNoProtoType *node) {
    QualType returnType = ( node->getReturnType() );
    W.find("returnType").writeQualType(returnType);
    bool noReturn = ( node->getExtInfo().getNoReturn() );
    W.find("noReturn").writeBool(noReturn);
    bool hasRegParm = ( node->getExtInfo().getHasRegParm() );
    W.find("hasRegParm").writeBool(hasRegParm);
    uint32_t regParm = ( node->getExtInfo().getRegParm() );
    W.find("regParm").writeUInt32(regParm);
    CallingConv callingConvention = ( node->getExtInfo().getCC() );
    W.find("callingConvention").writeCallingConv(callingConvention);
    bool producesResult = ( node->getExtInfo().getProducesResult() );
    W.find("producesResult").writeBool(producesResult);
    bool noCallerSavedRegs = ( node->getExtInfo().getNoCallerSavedRegs() );
    W.find("noCallerSavedRegs").writeBool(noCallerSavedRegs);
    bool noCfCheck = ( node->getExtInfo().getNoCfCheck() );
    W.find("noCfCheck").writeBool(noCfCheck);
    bool cmseNSCall = ( node->getExtInfo().getCmseNSCall() );
    W.find("cmseNSCall").writeBool(cmseNSCall);
  }

  void writeFunctionProtoType(const FunctionProtoType *node) {
    bool variadic = ( node->isVariadic() );
    W.find("variadic").writeBool(variadic);
    bool trailingReturn = ( node->hasTrailingReturn() );
    W.find("trailingReturn").writeBool(trailingReturn);
    Qualifiers methodQualifiers = ( node->getMethodQuals() );
    W.find("methodQualifiers").writeQualifiers(methodQualifiers);
    RefQualifierKind refQualifier = ( node->getRefQualifier() );
    W.find("refQualifier").writeRefQualifierKind(refQualifier);
    FunctionProtoType::ExceptionSpecInfo exceptionSpecifier = ( node->getExceptionSpecInfo() );
    W.find("exceptionSpecifier").writeExceptionSpecInfo(exceptionSpecifier);
    llvm::ArrayRef<QualType> parameters = ( node->getParamTypes() );
    W.find("parameters").writeArray(parameters);
    llvm::ArrayRef<FunctionProtoType::ExtParameterInfo> extParameterInfo = ( node->hasExtParameterInfos()
                    ? node->getExtParameterInfos()
                    : llvm::ArrayRef<FunctionProtoType::ExtParameterInfo>() );
    W.find("extParameterInfo").writeArray(extParameterInfo);
    QualType returnType = ( node->getReturnType() );
    W.find("returnType").writeQualType(returnType);
    bool noReturn = ( node->getExtInfo().getNoReturn() );
    W.find("noReturn").writeBool(noReturn);
    bool hasRegParm = ( node->getExtInfo().getHasRegParm() );
    W.find("hasRegParm").writeBool(hasRegParm);
    uint32_t regParm = ( node->getExtInfo().getRegParm() );
    W.find("regParm").writeUInt32(regParm);
    CallingConv callingConvention = ( node->getExtInfo().getCC() );
    W.find("callingConvention").writeCallingConv(callingConvention);
    bool producesResult = ( node->getExtInfo().getProducesResult() );
    W.find("producesResult").writeBool(producesResult);
    bool noCallerSavedRegs = ( node->getExtInfo().getNoCallerSavedRegs() );
    W.find("noCallerSavedRegs").writeBool(noCallerSavedRegs);
    bool noCfCheck = ( node->getExtInfo().getNoCfCheck() );
    W.find("noCfCheck").writeBool(noCfCheck);
    bool cmseNSCall = ( node->getExtInfo().getCmseNSCall() );
    W.find("cmseNSCall").writeBool(cmseNSCall);
  }

  void writeInjectedClassNameType(const InjectedClassNameType *node) {
    const Decl* declaration = ( node->getDecl()->getCanonicalDecl() );
    W.find("declaration").writeDeclRef(declaration);
    QualType injectedSpecializationType = ( node->getInjectedSpecializationType() );
    W.find("injectedSpecializationType").writeQualType(injectedSpecializationType);
  }

  void writeMacroQualifiedType(const MacroQualifiedType *node) {
    QualType underlyingType = ( node->getUnderlyingType() );
    W.find("underlyingType").writeQualType(underlyingType);
    const IdentifierInfo* macroIdentifier = ( node->getMacroIdentifier() );
    W.find("macroIdentifier").writeIdentifier(macroIdentifier);
  }

  void writeConstantMatrixType(const ConstantMatrixType *node) {
    uint32_t numRows = ( node->getNumRows() );
    W.find("numRows").writeUInt32(numRows);
    uint32_t numColumns = ( node->getNumColumns() );
    W.find("numColumns").writeUInt32(numColumns);
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
  }

  void writeDependentSizedMatrixType(const DependentSizedMatrixType *node) {
    const Expr* rows = ( node->getRowExpr() );
    W.find("rows").writeExprRef(rows);
    const Expr* columns = ( node->getColumnExpr() );
    W.find("columns").writeExprRef(columns);
    SourceLocation attributeLoc = ( node->getAttributeLoc() );
    W.find("attributeLoc").writeSourceLocation(attributeLoc);
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
  }

  void writeMemberPointerType(const MemberPointerType *node) {
    QualType pointeeType = ( node->getPointeeType() );
    W.find("pointeeType").writeQualType(pointeeType);
    QualType baseType = ( QualType(node->getClass(), 0) );
    W.find("baseType").writeQualType(baseType);
  }

  void writeObjCObjectPointerType(const ObjCObjectPointerType *node) {
    QualType pointeeType = ( node->getPointeeType() );
    W.find("pointeeType").writeQualType(pointeeType);
  }

  void writeObjCObjectType(const ObjCObjectType *node) {
    QualType baseType = ( node->getBaseType() );
    W.find("baseType").writeQualType(baseType);
    llvm::ArrayRef<QualType> typeArgsAsWritten = ( node->getTypeArgsAsWritten() );
    W.find("typeArgsAsWritten").writeArray(typeArgsAsWritten);
    llvm::ArrayRef<const ObjCProtocolDecl*> qualifiers = ( node->getProtocols() );
    W.find("qualifiers").writeArray(qualifiers);
    bool isKindOfTypeAsWritten = ( node->isKindOfTypeAsWritten() );
    W.find("isKindOfTypeAsWritten").writeBool(isKindOfTypeAsWritten);
  }

  void writeObjCInterfaceType(const ObjCInterfaceType *node) {
    const Decl* declaration = ( node->getDecl()->getCanonicalDecl() );
    W.find("declaration").writeDeclRef(declaration);
  }

  void writeObjCTypeParamType(const ObjCTypeParamType *node) {
    const ObjCTypeParamDecl* declaration = ( node->getDecl() );
    W.find("declaration").writeObjCTypeParamDeclRef(declaration);
    llvm::ArrayRef<const ObjCProtocolDecl*> qualifiers = ( node->getProtocols() );
    W.find("qualifiers").writeArray(qualifiers);
  }

  void writePackExpansionType(const PackExpansionType *node) {
    QualType pattern = ( node->getPattern() );
    W.find("pattern").writeQualType(pattern);
    llvm::Optional<uint32_t> numExpansions = ( node->getNumExpansions() );
    W.find("numExpansions").writeOptional(numExpansions);
  }

  void writeParenType(const ParenType *node) {
    QualType innerType = ( node->getInnerType() );
    W.find("innerType").writeQualType(innerType);
  }

  void writePipeType(const PipeType *node) {
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
    bool isReadOnly = ( node->isReadOnly() );
    W.find("isReadOnly").writeBool(isReadOnly);
  }

  void writePointerType(const PointerType *node) {
    QualType pointeeType = ( node->getPointeeType() );
    W.find("pointeeType").writeQualType(pointeeType);
  }

  void writeLValueReferenceType(const LValueReferenceType *node) {
    bool isSpelledAsLValue = ( node->isSpelledAsLValue() );
    W.find("isSpelledAsLValue").writeBool(isSpelledAsLValue);
    QualType pointeeTypeAsWritten = ( node->getPointeeTypeAsWritten() );
    W.find("pointeeTypeAsWritten").writeQualType(pointeeTypeAsWritten);
  }

  void writeRValueReferenceType(const RValueReferenceType *node) {
    QualType pointeeTypeAsWritten = ( node->getPointeeTypeAsWritten() );
    W.find("pointeeTypeAsWritten").writeQualType(pointeeTypeAsWritten);
  }

  void writeSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *node) {
    QualType replacedParameter = ( QualType(node->getReplacedParameter(), 0) );
    W.find("replacedParameter").writeQualType(replacedParameter);
    TemplateArgument replacementPack = ( node->getArgumentPack() );
    W.find("replacementPack").writeTemplateArgument(replacementPack);
  }

  void writeSubstTemplateTypeParmType(const SubstTemplateTypeParmType *node) {
    QualType replacedParameter = ( QualType(node->getReplacedParameter(), 0) );
    W.find("replacedParameter").writeQualType(replacedParameter);
    QualType replacementType = ( node->getReplacementType() );
    W.find("replacementType").writeQualType(replacementType);
  }

  void writeEnumType(const EnumType *node) {
    bool dependent = ( node->isDependentType() );
    W.find("dependent").writeBool(dependent);
    const Decl* declaration = ( node->getDecl()->getCanonicalDecl() );
    W.find("declaration").writeDeclRef(declaration);
  }

  void writeRecordType(const RecordType *node) {
    bool dependent = ( node->isDependentType() );
    W.find("dependent").writeBool(dependent);
    const Decl* declaration = ( node->getDecl()->getCanonicalDecl() );
    W.find("declaration").writeDeclRef(declaration);
  }

  void writeTemplateSpecializationType(const TemplateSpecializationType *node) {
    bool dependent = ( node->isDependentType() );
    W.find("dependent").writeBool(dependent);
    TemplateName templateName = ( node->getTemplateName() );
    W.find("templateName").writeTemplateName(templateName);
    llvm::ArrayRef<TemplateArgument> templateArguments = ( node->template_arguments() );
    W.find("templateArguments").writeArray(templateArguments);
    llvm::Optional<QualType> underlyingType = (
      node->isTypeAlias()
        ? llvm::Optional<QualType>(node->getAliasedType())
        : node->isCanonicalUnqualified()
            ? llvm::None
            : llvm::Optional<QualType>(node->getCanonicalTypeInternal())
    );
    W.find("underlyingType").writeOptional(underlyingType);
  }

  void writeTemplateTypeParmType(const TemplateTypeParmType *node) {
    uint32_t depth = ( node->getDepth() );
    W.find("depth").writeUInt32(depth);
    uint32_t index = ( node->getIndex() );
    W.find("index").writeUInt32(index);
    bool isParameterPack = ( node->isParameterPack() );
    W.find("isParameterPack").writeBool(isParameterPack);
    llvm::Optional<const TemplateTypeParmDecl*> declaration = ( makeOptionalFromPointer(
                    const_cast<const TemplateTypeParmDecl*>(node->getDecl())) );
    W.find("declaration").writeOptional(declaration);
  }

  void writeTypeOfExprType(const TypeOfExprType *node) {
    const Expr* expression = ( node->getUnderlyingExpr() );
    W.find("expression").writeExprRef(expression);
  }

  void writeTypeOfType(const TypeOfType *node) {
    QualType underlyingType = ( node->getUnderlyingType() );
    W.find("underlyingType").writeQualType(underlyingType);
  }

  void writeTypedefType(const TypedefType *node) {
    const Decl* declaration = ( node->getDecl() );
    W.find("declaration").writeDeclRef(declaration);
    llvm::Optional<QualType> canonicalType = ( makeOptionalFromNullable(node->getCanonicalTypeInternal()) );
    W.find("canonicalType").writeOptional(canonicalType);
  }

  void writeUnaryTransformType(const UnaryTransformType *node) {
    QualType baseType = ( node->getBaseType() );
    W.find("baseType").writeQualType(baseType);
    QualType underlyingType = ( node->getUnderlyingType() );
    W.find("underlyingType").writeQualType(underlyingType);
    UnaryTransformType::UTTKind transform = ( node->getUTTKind() );
    W.find("transform").writeUnaryTypeTransformKind(transform);
  }

  void writeUnresolvedUsingType(const UnresolvedUsingType *node) {
    const Decl* declaration = ( node->getDecl() );
    W.find("declaration").writeDeclRef(declaration);
  }

  void writeVectorType(const VectorType *node) {
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
    uint32_t numElements = ( node->getNumElements() );
    W.find("numElements").writeUInt32(numElements);
    VectorType::VectorKind vectorKind = ( node->getVectorKind() );
    W.find("vectorKind").writeVectorKind(vectorKind);
  }

  void writeExtVectorType(const ExtVectorType *node) {
    QualType elementType = ( node->getElementType() );
    W.find("elementType").writeQualType(elementType);
    uint32_t numElements = ( node->getNumElements() );
    W.find("numElements").writeUInt32(numElements);
  }

};

