diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 779 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 684 |
2 files changed, 57 insertions, 1406 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 3fdf451d3d0..c85cfcd3a33 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -13,6 +13,7 @@ #include "clang/Serialization/ASTReader.h" #include "ASTCommon.h" #include "ASTReaderInternals.h" +#include "clang/AST/AbstractTypeReader.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTMutationListener.h" @@ -6316,16 +6317,13 @@ ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) { return RecordLocation(M, M->TypeOffsets[Index - M->BaseTypeIndex]); } -static FunctionType::ExtInfo readFunctionExtInfo(ASTRecordReader &Record) { - bool noreturn = Record.readBool(); - bool hasregparm = Record.readBool(); - unsigned regparm = Record.readInt(); - auto cc = static_cast<CallingConv>(Record.readInt()); - bool producesResult = Record.readBool(); - bool nocallersavedregs = Record.readBool(); - bool nocfcheck = Record.readBool(); - return FunctionType::ExtInfo(noreturn, hasregparm, regparm, cc, - producesResult, nocallersavedregs, nocfcheck); +static llvm::Optional<Type::TypeClass> getTypeClassForCode(TypeCode code) { + switch (code) { +#define TYPE_BIT_CODE(CLASS_ID, CODE_ID, CODE_VALUE) \ + case TYPE_##CODE_ID: return Type::CLASS_ID; +#include "clang/Serialization/TypeBitCodes.def" + default: return llvm::None; + } } /// Read and return the type with the given index.. @@ -6365,534 +6363,20 @@ QualType ASTReader::readTypeRecord(unsigned Index) { Error(Code.takeError()); return QualType(); } - switch ((TypeCode) Code.get()) { - case TYPE_EXT_QUAL: { - if (Record.size() != 2) { - Error("Incorrect encoding of extended qualifier type"); - return QualType(); - } - QualType Base = Record.readType(); - Qualifiers Quals = Record.readQualifiers(); - return Context.getQualifiedType(Base, Quals); - } - - case TYPE_COMPLEX: { - if (Record.size() != 1) { - Error("Incorrect encoding of complex type"); - return QualType(); - } - QualType ElemType = Record.readType(); - return Context.getComplexType(ElemType); - } - - case TYPE_POINTER: { - if (Record.size() != 1) { - Error("Incorrect encoding of pointer type"); - return QualType(); - } - QualType PointeeType = Record.readType(); - return Context.getPointerType(PointeeType); - } - - case TYPE_DECAYED: { - if (Record.size() != 1) { - Error("Incorrect encoding of decayed type"); - return QualType(); - } - QualType OriginalType = Record.readType(); - QualType DT = Context.getAdjustedParameterType(OriginalType); - if (!isa<DecayedType>(DT)) - Error("Decayed type does not decay"); - return DT; - } - - case TYPE_ADJUSTED: { - if (Record.size() != 2) { - Error("Incorrect encoding of adjusted type"); - return QualType(); - } - QualType OriginalTy = Record.readType(); - QualType AdjustedTy = Record.readType(); - return Context.getAdjustedType(OriginalTy, AdjustedTy); - } - - case TYPE_BLOCK_POINTER: { - if (Record.size() != 1) { - Error("Incorrect encoding of block pointer type"); - return QualType(); - } - QualType PointeeType = Record.readType(); - return Context.getBlockPointerType(PointeeType); - } - - case TYPE_LVALUE_REFERENCE: { - if (Record.size() != 2) { - Error("Incorrect encoding of lvalue reference type"); - return QualType(); - } - QualType PointeeType = Record.readType(); - return Context.getLValueReferenceType(PointeeType, Record.readBool()); - } - - case TYPE_RVALUE_REFERENCE: { - if (Record.size() != 1) { - Error("Incorrect encoding of rvalue reference type"); - return QualType(); - } - QualType PointeeType = Record.readType(); - return Context.getRValueReferenceType(PointeeType); - } - - case TYPE_MEMBER_POINTER: { - if (Record.size() != 2) { - Error("Incorrect encoding of member pointer type"); - return QualType(); - } - QualType PointeeType = Record.readType(); - QualType ClassType = Record.readType(); - if (PointeeType.isNull() || ClassType.isNull()) - return QualType(); - - return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr()); - } - - case TYPE_CONSTANT_ARRAY: { - QualType ElementType = Record.readType(); - ArrayType::ArraySizeModifier ASM = - (ArrayType::ArraySizeModifier) Record.readInt(); - unsigned IndexTypeQuals = Record.readInt(); - llvm::APInt Size = Record.readAPInt(); - Expr *SizeExpr = Record.readExpr(); - return Context.getConstantArrayType(ElementType, Size, SizeExpr, - ASM, IndexTypeQuals); - } - - case TYPE_INCOMPLETE_ARRAY: { - QualType ElementType = Record.readType(); - ArrayType::ArraySizeModifier ASM = - (ArrayType::ArraySizeModifier) Record.readInt(); - unsigned IndexTypeQuals = Record.readInt(); - return Context.getIncompleteArrayType(ElementType, ASM, IndexTypeQuals); - } - - case TYPE_VARIABLE_ARRAY: { - QualType ElementType = Record.readType(); - ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record.readInt(); - unsigned IndexTypeQuals = Record.readInt(); - SourceLocation LBLoc = Record.readSourceLocation(); - SourceLocation RBLoc = Record.readSourceLocation(); - return Context.getVariableArrayType(ElementType, ReadExpr(*Loc.F), - ASM, IndexTypeQuals, - SourceRange(LBLoc, RBLoc)); - } - - case TYPE_VECTOR: { - if (Record.size() != 3) { - Error("incorrect encoding of vector type in AST file"); - return QualType(); - } - - QualType ElementType = Record.readType(); - unsigned NumElements = Record.readInt(); - unsigned VecKind = Record.readInt(); - return Context.getVectorType(ElementType, NumElements, - (VectorType::VectorKind)VecKind); - } - - case TYPE_EXT_VECTOR: { - if (Record.size() != 3) { - Error("incorrect encoding of extended vector type in AST file"); - return QualType(); - } - - QualType ElementType = Record.readType(); - unsigned NumElements = Record.readInt(); - return Context.getExtVectorType(ElementType, NumElements); - } - - case TYPE_FUNCTION_NO_PROTO: { - if (Record.size() != 8) { - Error("incorrect encoding of no-proto function type"); - return QualType(); - } - QualType ResultType = Record.readType(); - FunctionType::ExtInfo Info = readFunctionExtInfo(Record); - return Context.getFunctionNoProtoType(ResultType, Info); - } - - case TYPE_FUNCTION_PROTO: { - QualType ResultType = Record.readType(); - - FunctionProtoType::ExtProtoInfo EPI; - EPI.ExtInfo = readFunctionExtInfo(Record); - EPI.Variadic = Record.readBool(); - EPI.HasTrailingReturn = Record.readBool(); - EPI.TypeQuals = Record.readQualifiers(); - EPI.RefQualifier = static_cast<RefQualifierKind>(Record.readInt()); - SmallVector<QualType, 8> ExceptionStorage; - EPI.ExceptionSpec = Record.readExceptionSpecInfo(ExceptionStorage); - - unsigned NumParams = Record.readInt(); - SmallVector<QualType, 16> ParamTypes; - for (unsigned I = 0; I != NumParams; ++I) - ParamTypes.push_back(Record.readType()); - - SmallVector<FunctionProtoType::ExtParameterInfo, 4> ExtParameterInfos; - if (Record.getIdx() != Record.size()) { - for (unsigned I = 0; I != NumParams; ++I) - ExtParameterInfos.push_back( - FunctionProtoType::ExtParameterInfo - ::getFromOpaqueValue(Record.readInt())); - EPI.ExtParameterInfos = ExtParameterInfos.data(); - } - - assert(Record.getIdx() == Record.size()); - - return Context.getFunctionType(ResultType, ParamTypes, EPI); - } - - case TYPE_UNRESOLVED_USING: { - return Context.getTypeDeclType( - Record.readDeclAs<UnresolvedUsingTypenameDecl>()); - } - - case TYPE_TYPEDEF: { - if (Record.size() != 2) { - Error("incorrect encoding of typedef type"); - return QualType(); - } - TypedefNameDecl *Decl = Record.readDeclAs<TypedefNameDecl>(); - QualType Canonical = Record.readType(); - if (!Canonical.isNull()) - Canonical = Context.getCanonicalType(Canonical); - return Context.getTypedefType(Decl, Canonical); - } - - case TYPE_TYPEOF_EXPR: - return Context.getTypeOfExprType(ReadExpr(*Loc.F)); - - case TYPE_TYPEOF: { - if (Record.size() != 1) { - Error("incorrect encoding of typeof(type) in AST file"); - return QualType(); - } - QualType UnderlyingType = Record.readType(); - return Context.getTypeOfType(UnderlyingType); - } - - case TYPE_DECLTYPE: { - QualType UnderlyingType = Record.readType(); - return Context.getDecltypeType(Record.readExpr(), UnderlyingType); - } - - case TYPE_UNARY_TRANSFORM: { - QualType BaseType = Record.readType(); - QualType UnderlyingType = Record.readType(); - UnaryTransformType::UTTKind UKind = - (UnaryTransformType::UTTKind)Record.readInt(); - return Context.getUnaryTransformType(BaseType, UnderlyingType, UKind); - } - - case TYPE_AUTO: { - QualType Deduced = Record.readType(); - AutoTypeKeyword Keyword = (AutoTypeKeyword) Record.readInt(); - bool IsDependent = false, IsPack = false; - if (Deduced.isNull()) { - auto Dependence = Record.readInt(); - IsDependent = Dependence > 0; - IsPack = Dependence > 1; - } - return Context.getAutoType(Deduced, Keyword, IsDependent, IsPack); - } - - case TYPE_DEDUCED_TEMPLATE_SPECIALIZATION: { - TemplateName Name = Record.readTemplateName(); - QualType Deduced = Record.readType(); - bool IsDependent = Deduced.isNull() ? Record.readBool() : false; - return Context.getDeducedTemplateSpecializationType(Name, Deduced, - IsDependent); - } - - case TYPE_RECORD: { - if (Record.size() != 2) { - Error("incorrect encoding of record type"); - return QualType(); - } - bool IsDependent = Record.readBool(); - RecordDecl *RD = Record.readDeclAs<RecordDecl>(); - RD = cast<RecordDecl>(RD->getCanonicalDecl()); - QualType T = Context.getRecordType(RD); - const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent); - return T; - } - - case TYPE_ENUM: { - if (Record.size() != 2) { - Error("incorrect encoding of enum type"); - return QualType(); - } - bool IsDependent = Record.readBool(); - QualType T = Context.getEnumType(Record.readDeclAs<EnumDecl>()); - const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent); - return T; - } - - case TYPE_ATTRIBUTED: { - if (Record.size() != 3) { - Error("incorrect encoding of attributed type"); - return QualType(); - } - QualType modifiedType = Record.readType(); - QualType equivalentType = Record.readType(); - AttributedType::Kind kind = static_cast<AttributedType::Kind>(Record.readInt()); - return Context.getAttributedType(kind, modifiedType, equivalentType); - } - - case TYPE_PAREN: { - if (Record.size() != 1) { - Error("incorrect encoding of paren type"); - return QualType(); - } - QualType InnerType = Record.readType(); - return Context.getParenType(InnerType); - } - - case TYPE_MACRO_QUALIFIED: { - if (Record.size() != 2) { - Error("incorrect encoding of macro defined type"); - return QualType(); - } - QualType UnderlyingTy = Record.readType(); - IdentifierInfo *MacroII = Record.readIdentifier(); - return Context.getMacroQualifiedType(UnderlyingTy, MacroII); - } - - case TYPE_PACK_EXPANSION: { - if (Record.size() != 2) { - Error("incorrect encoding of pack expansion type"); - return QualType(); - } - QualType Pattern = Record.readType(); - if (Pattern.isNull()) - return QualType(); - Optional<unsigned> NumExpansions; - unsigned RawNumExpansions = Record.readInt(); - if (RawNumExpansions) - NumExpansions = RawNumExpansions - 1; - return Context.getPackExpansionType(Pattern, NumExpansions); - } - - case TYPE_ELABORATED: { - ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record.readInt(); - NestedNameSpecifier *NNS = Record.readNestedNameSpecifier(); - QualType NamedType = Record.readType(); - TagDecl *OwnedTagDecl = Record.readDeclAs<TagDecl>(); - return Context.getElaboratedType(Keyword, NNS, NamedType, OwnedTagDecl); - } - - case TYPE_OBJC_INTERFACE: { - ObjCInterfaceDecl *ItfD = Record.readDeclAs<ObjCInterfaceDecl>(); - return Context.getObjCInterfaceType(ItfD->getCanonicalDecl()); - } - - case TYPE_OBJC_TYPE_PARAM: { - ObjCTypeParamDecl *Decl = Record.readDeclAs<ObjCTypeParamDecl>(); - unsigned NumProtos = Record.readInt(); - SmallVector<ObjCProtocolDecl*, 4> Protos; - for (unsigned I = 0; I != NumProtos; ++I) - Protos.push_back(Record.readDeclAs<ObjCProtocolDecl>()); - return Context.getObjCTypeParamType(Decl, Protos); - } - - case TYPE_OBJC_OBJECT: { - QualType Base = Record.readType(); - unsigned NumTypeArgs = Record.readInt(); - SmallVector<QualType, 4> TypeArgs; - for (unsigned I = 0; I != NumTypeArgs; ++I) - TypeArgs.push_back(Record.readType()); - unsigned NumProtos = Record.readInt(); - SmallVector<ObjCProtocolDecl*, 4> Protos; - for (unsigned I = 0; I != NumProtos; ++I) - Protos.push_back(Record.readDeclAs<ObjCProtocolDecl>()); - bool IsKindOf = Record.readBool(); - return Context.getObjCObjectType(Base, TypeArgs, Protos, IsKindOf); - } - - case TYPE_OBJC_OBJECT_POINTER: { - QualType Pointee = Record.readType(); - return Context.getObjCObjectPointerType(Pointee); - } - - case TYPE_SUBST_TEMPLATE_TYPE_PARM: { - QualType Parm = Record.readType(); - QualType Replacement = Record.readType(); - return Context.getSubstTemplateTypeParmType( - cast<TemplateTypeParmType>(Parm), - Context.getCanonicalType(Replacement)); - } - - case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: { - QualType Parm = Record.readType(); - TemplateArgument ArgPack = Record.readTemplateArgument(); - return Context.getSubstTemplateTypeParmPackType( - cast<TemplateTypeParmType>(Parm), - ArgPack); - } - - case TYPE_INJECTED_CLASS_NAME: { - CXXRecordDecl *D = Record.readDeclAs<CXXRecordDecl>(); - QualType TST = Record.readType(); // probably derivable - // FIXME: ASTContext::getInjectedClassNameType is not currently suitable - // for AST reading, too much interdependencies. - const Type *T = nullptr; - for (auto *DI = D; DI; DI = DI->getPreviousDecl()) { - if (const Type *Existing = DI->getTypeForDecl()) { - T = Existing; - break; - } - } - if (!T) { - T = new (Context, TypeAlignment) InjectedClassNameType(D, TST); - for (auto *DI = D; DI; DI = DI->getPreviousDecl()) - DI->setTypeForDecl(T); - } - return QualType(T, 0); - } - - case TYPE_TEMPLATE_TYPE_PARM: { - unsigned Depth = Record.readInt(); - unsigned Index = Record.readInt(); - bool Pack = Record.readBool(); - auto D = Record.readDeclAs<TemplateTypeParmDecl>(); - return Context.getTemplateTypeParmType(Depth, Index, Pack, D); - } - - case TYPE_DEPENDENT_NAME: { - ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record.readInt(); - NestedNameSpecifier *NNS = Record.readNestedNameSpecifier(); - const IdentifierInfo *Name = Record.readIdentifier(); - QualType Canon = Record.readType(); - if (!Canon.isNull()) - Canon = Context.getCanonicalType(Canon); - return Context.getDependentNameType(Keyword, NNS, Name, Canon); - } - - case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: { - ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record.readInt(); - NestedNameSpecifier *NNS = Record.readNestedNameSpecifier(); - const IdentifierInfo *Name = Record.readIdentifier(); - unsigned NumArgs = Record.readInt(); - SmallVector<TemplateArgument, 8> Args; - Args.reserve(NumArgs); - while (NumArgs--) - Args.push_back(Record.readTemplateArgument()); - return Context.getDependentTemplateSpecializationType(Keyword, NNS, Name, - Args); - } - - case TYPE_DEPENDENT_SIZED_ARRAY: { - // ArrayType - QualType ElementType = Record.readType(); - ArrayType::ArraySizeModifier ASM - = (ArrayType::ArraySizeModifier)Record.readInt(); - unsigned IndexTypeQuals = Record.readInt(); - - // DependentSizedArrayType - Expr *NumElts = Record.readExpr(); - SourceRange Brackets = Record.readSourceRange(); - - return Context.getDependentSizedArrayType(ElementType, NumElts, ASM, - IndexTypeQuals, Brackets); - } - - case TYPE_TEMPLATE_SPECIALIZATION: { - bool IsDependent = Record.readBool(); - TemplateName Name = Record.readTemplateName(); - SmallVector<TemplateArgument, 8> Args; - Record.readTemplateArgumentList(Args); - QualType Underlying = Record.readType(); - QualType T; - if (Underlying.isNull()) - T = Context.getCanonicalTemplateSpecializationType(Name, Args); - else - T = Context.getTemplateSpecializationType(Name, Args, Underlying); - const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent); - return T; - } - - case TYPE_ATOMIC: { - if (Record.size() != 1) { - Error("Incorrect encoding of atomic type"); - return QualType(); - } - QualType ValueType = Record.readType(); - return Context.getAtomicType(ValueType); - } - - case TYPE_PIPE: { - if (Record.size() != 2) { - Error("Incorrect encoding of pipe type"); - return QualType(); - } - - // Reading the pipe element type. - QualType ElementType = Record.readType(); - unsigned ReadOnly = Record.readInt(); - return Context.getPipeType(ElementType, ReadOnly); - } - - case TYPE_DEPENDENT_SIZED_VECTOR: { - QualType ElementType = Record.readType(); - Expr *SizeExpr = Record.readExpr(); - SourceLocation AttrLoc = Record.readSourceLocation(); - unsigned VecKind = Record.readInt(); - - return Context.getDependentVectorType(ElementType, SizeExpr, AttrLoc, - (VectorType::VectorKind)VecKind); - } - - case TYPE_DEPENDENT_SIZED_EXT_VECTOR: { - // DependentSizedExtVectorType - QualType ElementType = Record.readType(); - Expr *SizeExpr = Record.readExpr(); - SourceLocation AttrLoc = Record.readSourceLocation(); - - return Context.getDependentSizedExtVectorType(ElementType, SizeExpr, - AttrLoc); + if (Code.get() == TYPE_EXT_QUAL) { + QualType baseType = Record.readQualType(); + Qualifiers quals = Record.readQualifiers(); + return Context.getQualifiedType(baseType, quals); } - case TYPE_DEPENDENT_ADDRESS_SPACE: { - // DependentAddressSpaceType - QualType PointeeType = Record.readType(); - Expr *AddrSpaceExpr = Record.readExpr(); - SourceLocation AttrLoc = Record.readSourceLocation(); - - return Context.getDependentAddressSpaceType(PointeeType, AddrSpaceExpr, - AttrLoc); - } + auto maybeClass = getTypeClassForCode((TypeCode) Code.get()); + if (!maybeClass) { + Error("Unexpected code for type"); + return QualType(); } - llvm_unreachable("Invalid TypeCode!"); -} -FunctionProtoType::ExceptionSpecInfo -ASTRecordReader::readExceptionSpecInfo(SmallVectorImpl<QualType> &Exceptions) { - FunctionProtoType::ExceptionSpecInfo ESI; - ExceptionSpecificationType EST = - static_cast<ExceptionSpecificationType>(readInt()); - ESI.Type = EST; - if (EST == EST_Dynamic) { - for (unsigned I = 0, N = readInt(); I != N; ++I) - Exceptions.push_back(readType()); - ESI.Exceptions = Exceptions; - } else if (isComputedNoexcept(EST)) { - ESI.NoexceptExpr = readExpr(); - } else if (EST == EST_Uninstantiated) { - ESI.SourceDecl = readDeclAs<FunctionDecl>(); - ESI.SourceTemplate = readDeclAs<FunctionDecl>(); - } else if (EST == EST_Unevaluated) { - ESI.SourceDecl = readDeclAs<FunctionDecl>(); - } - return ESI; + serialization::AbstractTypeReader<ASTRecordReader> TypeReader(Record); + return TypeReader.read(*maybeClass); } namespace clang { @@ -9075,49 +8559,6 @@ ASTReader::getGlobalSelectorID(ModuleFile &M, unsigned LocalID) const { return LocalID + I->second; } -DeclarationName ASTRecordReader::readDeclarationName() { - ASTContext &Context = getContext(); - DeclarationName::NameKind Kind = (DeclarationName::NameKind)readInt(); - switch (Kind) { - case DeclarationName::Identifier: - return DeclarationName(readIdentifier()); - - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - return DeclarationName(readSelector()); - - case DeclarationName::CXXConstructorName: - return Context.DeclarationNames.getCXXConstructorName( - Context.getCanonicalType(readType())); - - case DeclarationName::CXXDestructorName: - return Context.DeclarationNames.getCXXDestructorName( - Context.getCanonicalType(readType())); - - case DeclarationName::CXXDeductionGuideName: - return Context.DeclarationNames.getCXXDeductionGuideName( - readDeclAs<TemplateDecl>()); - - case DeclarationName::CXXConversionFunctionName: - return Context.DeclarationNames.getCXXConversionFunctionName( - Context.getCanonicalType(readType())); - - case DeclarationName::CXXOperatorName: - return Context.DeclarationNames.getCXXOperatorName( - (OverloadedOperatorKind)readInt()); - - case DeclarationName::CXXLiteralOperatorName: - return Context.DeclarationNames.getCXXLiteralOperatorName( - readIdentifier()); - - case DeclarationName::CXXUsingDirective: - return DeclarationName::getUsingDirectiveName(); - } - - llvm_unreachable("Invalid NameKind!"); -} - DeclarationNameLoc ASTRecordReader::readDeclarationNameLoc(DeclarationName Name) { DeclarationNameLoc DNLoc; @@ -9171,118 +8612,6 @@ void ASTRecordReader::readQualifierInfo(QualifierInfo &Info) { } } -TemplateName -ASTRecordReader::readTemplateName() { - ASTContext &Context = getContext(); - TemplateName::NameKind Kind = (TemplateName::NameKind)readInt(); - switch (Kind) { - case TemplateName::Template: - return TemplateName(readDeclAs<TemplateDecl>()); - - case TemplateName::OverloadedTemplate: { - unsigned size = readInt(); - UnresolvedSet<8> Decls; - while (size--) - Decls.addDecl(readDeclAs<NamedDecl>()); - - return Context.getOverloadedTemplateName(Decls.begin(), Decls.end()); - } - - case TemplateName::AssumedTemplate: { - DeclarationName Name = readDeclarationName(); - return Context.getAssumedTemplateName(Name); - } - - case TemplateName::QualifiedTemplate: { - NestedNameSpecifier *NNS = readNestedNameSpecifier(); - bool hasTemplKeyword = readBool(); - TemplateDecl *Template = readDeclAs<TemplateDecl>(); - return Context.getQualifiedTemplateName(NNS, hasTemplKeyword, Template); - } - - case TemplateName::DependentTemplate: { - NestedNameSpecifier *NNS = readNestedNameSpecifier(); - if (readBool()) // isIdentifier - return Context.getDependentTemplateName(NNS, readIdentifier()); - return Context.getDependentTemplateName(NNS, - (OverloadedOperatorKind)readInt()); - } - - case TemplateName::SubstTemplateTemplateParm: { - auto *param = readDeclAs<TemplateTemplateParmDecl>(); - if (!param) return TemplateName(); - TemplateName replacement = readTemplateName(); - return Context.getSubstTemplateTemplateParm(param, replacement); - } - - case TemplateName::SubstTemplateTemplateParmPack: { - TemplateTemplateParmDecl *Param - = readDeclAs<TemplateTemplateParmDecl>(); - if (!Param) - return TemplateName(); - - TemplateArgument ArgPack = readTemplateArgument(); - if (ArgPack.getKind() != TemplateArgument::Pack) - return TemplateName(); - - return Context.getSubstTemplateTemplateParmPack(Param, ArgPack); - } - } - - llvm_unreachable("Unhandled template name kind!"); -} - -TemplateArgument ASTRecordReader::readTemplateArgument(bool Canonicalize) { - ASTContext &Context = getContext(); - if (Canonicalize) { - // The caller wants a canonical template argument. Sometimes the AST only - // wants template arguments in canonical form (particularly as the template - // argument lists of template specializations) so ensure we preserve that - // canonical form across serialization. - TemplateArgument Arg = readTemplateArgument(false); - return Context.getCanonicalTemplateArgument(Arg); - } - - TemplateArgument::ArgKind Kind = (TemplateArgument::ArgKind) readInt(); - switch (Kind) { - case TemplateArgument::Null: - return TemplateArgument(); - case TemplateArgument::Type: - return TemplateArgument(readType()); - case TemplateArgument::Declaration: { - ValueDecl *D = readDeclAs<ValueDecl>(); - return TemplateArgument(D, readType()); - } - case TemplateArgument::NullPtr: - return TemplateArgument(readType(), /*isNullPtr*/true); - case TemplateArgument::Integral: { - llvm::APSInt Value = readAPSInt(); - QualType T = readType(); - return TemplateArgument(Context, Value, T); - } - case TemplateArgument::Template: - return TemplateArgument(readTemplateName()); - case TemplateArgument::TemplateExpansion: { - TemplateName Name = readTemplateName(); - Optional<unsigned> NumTemplateExpansions; - if (unsigned NumExpansions = readInt()) - NumTemplateExpansions = NumExpansions - 1; - return TemplateArgument(Name, NumTemplateExpansions); - } - case TemplateArgument::Expression: - return TemplateArgument(readExpr()); - case TemplateArgument::Pack: { - unsigned NumArgs = readInt(); - TemplateArgument *Args = new (Context) TemplateArgument[NumArgs]; - for (unsigned I = 0; I != NumArgs; ++I) - Args[I] = readTemplateArgument(); - return TemplateArgument(llvm::makeArrayRef(Args, NumArgs)); - } - } - - llvm_unreachable("Unhandled template argument kind!"); -} - TemplateParameterList * ASTRecordReader::readTemplateParameterList() { SourceLocation TemplateLoc = readSourceLocation(); @@ -9403,67 +8732,13 @@ ASTRecordReader::readCXXCtorInitializers() { return CtorInitializers; } -NestedNameSpecifier * -ASTRecordReader::readNestedNameSpecifier() { - ASTContext &Context = getContext(); - unsigned N = readInt(); - NestedNameSpecifier *NNS = nullptr, *Prev = nullptr; - for (unsigned I = 0; I != N; ++I) { - NestedNameSpecifier::SpecifierKind Kind - = (NestedNameSpecifier::SpecifierKind)readInt(); - switch (Kind) { - case NestedNameSpecifier::Identifier: { - IdentifierInfo *II = readIdentifier(); - NNS = NestedNameSpecifier::Create(Context, Prev, II); - break; - } - - case NestedNameSpecifier::Namespace: { - NamespaceDecl *NS = readDeclAs<NamespaceDecl>(); - NNS = NestedNameSpecifier::Create(Context, Prev, NS); - break; - } - - case NestedNameSpecifier::NamespaceAlias: { - NamespaceAliasDecl *Alias = readDeclAs<NamespaceAliasDecl>(); - NNS = NestedNameSpecifier::Create(Context, Prev, Alias); - break; - } - - case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: { - const Type *T = readType().getTypePtrOrNull(); - if (!T) - return nullptr; - - bool Template = readBool(); - NNS = NestedNameSpecifier::Create(Context, Prev, Template, T); - break; - } - - case NestedNameSpecifier::Global: - NNS = NestedNameSpecifier::GlobalSpecifier(Context); - // No associated value, and there can't be a prefix. - break; - - case NestedNameSpecifier::Super: { - CXXRecordDecl *RD = readDeclAs<CXXRecordDecl>(); - NNS = NestedNameSpecifier::SuperSpecifier(Context, RD); - break; - } - } - Prev = NNS; - } - return NNS; -} - NestedNameSpecifierLoc ASTRecordReader::readNestedNameSpecifierLoc() { ASTContext &Context = getContext(); unsigned N = readInt(); NestedNameSpecifierLocBuilder Builder; for (unsigned I = 0; I != N; ++I) { - auto Kind = (NestedNameSpecifier::SpecifierKind) readInt(); + auto Kind = readNestedNameSpecifierKind(); switch (Kind) { case NestedNameSpecifier::Identifier: { IdentifierInfo *II = readIdentifier(); @@ -9548,7 +8823,7 @@ readAPFloatSemantics(ASTRecordReader &reader) { APValue ASTRecordReader::readAPValue() { unsigned Kind = readInt(); - switch (Kind) { + switch ((APValue::ValueKind) Kind) { case APValue::None: return APValue(); case APValue::Indeterminate: @@ -9586,20 +8861,6 @@ APValue ASTRecordReader::readAPValue() { llvm_unreachable("Invalid APValue::ValueKind"); } -/// Read an integral value -llvm::APInt ASTRecordReader::readAPInt() { - unsigned BitWidth = readInt(); - unsigned NumWords = llvm::APInt::getNumWords(BitWidth); - llvm::APInt Result(BitWidth, NumWords, readIntArray(NumWords).data()); - return Result; -} - -/// Read a signed integral value -llvm::APSInt ASTRecordReader::readAPSInt() { - bool isUnsigned = readBool(); - return llvm::APSInt(readAPInt(), isUnsigned); -} - /// Read a floating-point value llvm::APFloat ASTRecordReader::readAPFloat(const llvm::fltSemantics &Sem) { return llvm::APFloat(Sem, readAPInt()); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e3458c48b14..8c39309d263 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -14,6 +14,7 @@ #include "ASTCommon.h" #include "ASTReaderInternals.h" #include "MultiOnDiskHashTable.h" +#include "clang/AST/AbstractTypeWriter.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTUnresolvedSet.h" #include "clang/AST/Attr.h" @@ -132,457 +133,43 @@ static StringRef bytes(const SmallVectorImpl<T> &v) { // Type serialization //===----------------------------------------------------------------------===// -namespace clang { - - class ASTTypeWriter { - ASTWriter &Writer; - ASTRecordWriter Record; - - /// Type code that corresponds to the record generated. - TypeCode Code = static_cast<TypeCode>(0); - - /// Abbreviation to use for the record, if any. - unsigned AbbrevToUse = 0; - - public: - ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) - : Writer(Writer), Record(Writer, Record) {} - - uint64_t Emit() { - return Record.Emit(Code, AbbrevToUse); - } - - void Visit(QualType T) { - if (T.hasLocalNonFastQualifiers()) { - Qualifiers Qs = T.getLocalQualifiers(); - Record.AddTypeRef(T.getLocalUnqualifiedType()); - Record.push_back(Qs.getAsOpaqueValue()); - Code = TYPE_EXT_QUAL; - AbbrevToUse = Writer.TypeExtQualAbbrev; - } else { - switch (T->getTypeClass()) { - // For all of the concrete, non-dependent types, call the - // appropriate visitor function. -#define TYPE(Class, Base) \ - case Type::Class: Visit##Class##Type(cast<Class##Type>(T)); break; -#define ABSTRACT_TYPE(Class, Base) -#include "clang/AST/TypeNodes.inc" - } - } - } - - void VisitArrayType(const ArrayType *T); - void VisitFunctionType(const FunctionType *T); - void VisitTagType(const TagType *T); - -#define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T); -#define ABSTRACT_TYPE(Class, Base) -#include "clang/AST/TypeNodes.inc" - }; - -} // namespace clang - -void ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) { - llvm_unreachable("Built-in types are never serialized"); -} - -void ASTTypeWriter::VisitComplexType(const ComplexType *T) { - Record.AddTypeRef(T->getElementType()); - Code = TYPE_COMPLEX; -} - -void ASTTypeWriter::VisitPointerType(const PointerType *T) { - Record.AddTypeRef(T->getPointeeType()); - Code = TYPE_POINTER; -} - -void ASTTypeWriter::VisitDecayedType(const DecayedType *T) { - Record.AddTypeRef(T->getOriginalType()); - Code = TYPE_DECAYED; -} - -void ASTTypeWriter::VisitAdjustedType(const AdjustedType *T) { - Record.AddTypeRef(T->getOriginalType()); - Record.AddTypeRef(T->getAdjustedType()); - Code = TYPE_ADJUSTED; -} - -void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) { - Record.AddTypeRef(T->getPointeeType()); - Code = TYPE_BLOCK_POINTER; -} - -void ASTTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) { - Record.AddTypeRef(T->getPointeeTypeAsWritten()); - Record.push_back(T->isSpelledAsLValue()); - Code = TYPE_LVALUE_REFERENCE; -} - -void ASTTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) { - Record.AddTypeRef(T->getPointeeTypeAsWritten()); - Code = TYPE_RVALUE_REFERENCE; -} - -void ASTTypeWriter::VisitMemberPointerType(const MemberPointerType *T) { - Record.AddTypeRef(T->getPointeeType()); - Record.AddTypeRef(QualType(T->getClass(), 0)); - Code = TYPE_MEMBER_POINTER; -} - -void ASTTypeWriter::VisitArrayType(const ArrayType *T) { - Record.AddTypeRef(T->getElementType()); - Record.push_back(T->getSizeModifier()); // FIXME: stable values - Record.push_back(T->getIndexTypeCVRQualifiers()); // FIXME: stable values -} - -void ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) { - VisitArrayType(T); - Record.AddAPInt(T->getSize()); - Record.AddStmt(const_cast<Expr*>(T->getSizeExpr())); - Code = TYPE_CONSTANT_ARRAY; -} - -void ASTTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) { - VisitArrayType(T); - Code = TYPE_INCOMPLETE_ARRAY; -} - -void ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) { - VisitArrayType(T); - Record.AddSourceLocation(T->getLBracketLoc()); - Record.AddSourceLocation(T->getRBracketLoc()); - Record.AddStmt(T->getSizeExpr()); - Code = TYPE_VARIABLE_ARRAY; -} - -void ASTTypeWriter::VisitVectorType(const VectorType *T) { - Record.AddTypeRef(T->getElementType()); - Record.push_back(T->getNumElements()); - Record.push_back(T->getVectorKind()); - Code = TYPE_VECTOR; -} - -void ASTTypeWriter::VisitExtVectorType(const ExtVectorType *T) { - VisitVectorType(T); - Code = TYPE_EXT_VECTOR; -} - -void ASTTypeWriter::VisitFunctionType(const FunctionType *T) { - Record.AddTypeRef(T->getReturnType()); - FunctionType::ExtInfo C = T->getExtInfo(); - Record.push_back(C.getNoReturn()); - Record.push_back(C.getHasRegParm()); - Record.push_back(C.getRegParm()); - // FIXME: need to stabilize encoding of calling convention... - Record.push_back(C.getCC()); - Record.push_back(C.getProducesResult()); - Record.push_back(C.getNoCallerSavedRegs()); - Record.push_back(C.getNoCfCheck()); - - if (C.getHasRegParm() || C.getRegParm() || C.getProducesResult()) - AbbrevToUse = 0; -} - -void ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) { - VisitFunctionType(T); - Code = TYPE_FUNCTION_NO_PROTO; -} - -static void addExceptionSpec(const FunctionProtoType *T, - ASTRecordWriter &Record) { - Record.push_back(T->getExceptionSpecType()); - if (T->getExceptionSpecType() == EST_Dynamic) { - Record.push_back(T->getNumExceptions()); - for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) - Record.AddTypeRef(T->getExceptionType(I)); - } else if (isComputedNoexcept(T->getExceptionSpecType())) { - Record.AddStmt(T->getNoexceptExpr()); - } else if (T->getExceptionSpecType() == EST_Uninstantiated) { - Record.AddDeclRef(T->getExceptionSpecDecl()); - Record.AddDeclRef(T->getExceptionSpecTemplate()); - } else if (T->getExceptionSpecType() == EST_Unevaluated) { - Record.AddDeclRef(T->getExceptionSpecDecl()); +static TypeCode getTypeCodeForTypeClass(Type::TypeClass id) { + switch (id) { +#define TYPE_BIT_CODE(CLASS_ID, CODE_ID, CODE_VALUE) \ + case Type::CLASS_ID: return TYPE_##CODE_ID; +#include "clang/Serialization/TypeBitCodes.def" + case Type::Builtin: + llvm_unreachable("shouldn't be serializing a builtin type this way"); } + llvm_unreachable("bad type kind"); } -void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { - VisitFunctionType(T); +namespace { - Record.push_back(T->isVariadic()); - Record.push_back(T->hasTrailingReturn()); - Record.push_back(T->getMethodQuals().getAsOpaqueValue()); - Record.push_back(static_cast<unsigned>(T->getRefQualifier())); - addExceptionSpec(T, Record); +class ASTTypeWriter { + ASTWriter &Writer; + ASTWriter::RecordData Record; + ASTRecordWriter BasicWriter; - Record.push_back(T->getNumParams()); - for (unsigned I = 0, N = T->getNumParams(); I != N; ++I) - Record.AddTypeRef(T->getParamType(I)); +public: + ASTTypeWriter(ASTWriter &Writer) + : Writer(Writer), BasicWriter(Writer, Record) {} + + uint64_t write(QualType T) { + if (T.hasLocalNonFastQualifiers()) { + Qualifiers Qs = T.getLocalQualifiers(); + BasicWriter.writeQualType(T.getLocalUnqualifiedType()); + BasicWriter.writeQualifiers(Qs); + return BasicWriter.Emit(TYPE_EXT_QUAL, Writer.getTypeExtQualAbbrev()); + } - if (T->hasExtParameterInfos()) { - for (unsigned I = 0, N = T->getNumParams(); I != N; ++I) - Record.push_back(T->getExtParameterInfo(I).getOpaqueValue()); + const Type *typePtr = T.getTypePtr(); + serialization::AbstractTypeWriter<ASTRecordWriter> atw(BasicWriter); + atw.write(typePtr); + return BasicWriter.Emit(getTypeCodeForTypeClass(typePtr->getTypeClass()), + /*abbrev*/ 0); } - - if (T->isVariadic() || T->hasTrailingReturn() || T->getMethodQuals() || - T->getRefQualifier() || T->getExceptionSpecType() != EST_None || - T->hasExtParameterInfos()) - AbbrevToUse = 0; - - Code = TYPE_FUNCTION_PROTO; -} - -void ASTTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { - Record.AddDeclRef(T->getDecl()); - Code = TYPE_UNRESOLVED_USING; -} - -void ASTTypeWriter::VisitTypedefType(const TypedefType *T) { - Record.AddDeclRef(T->getDecl()); - assert(!T->isCanonicalUnqualified() && "Invalid typedef ?"); - Record.AddTypeRef(T->getCanonicalTypeInternal()); - Code = TYPE_TYPEDEF; -} - -void ASTTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) { - Record.AddStmt(T->getUnderlyingExpr()); - Code = TYPE_TYPEOF_EXPR; -} - -void ASTTypeWriter::VisitTypeOfType(const TypeOfType *T) { - Record.AddTypeRef(T->getUnderlyingType()); - Code = TYPE_TYPEOF; -} - -void ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) { - Record.AddTypeRef(T->getUnderlyingType()); - Record.AddStmt(T->getUnderlyingExpr()); - Code = TYPE_DECLTYPE; -} - -void ASTTypeWriter::VisitUnaryTransformType(const UnaryTransformType *T) { - Record.AddTypeRef(T->getBaseType()); - Record.AddTypeRef(T->getUnderlyingType()); - Record.push_back(T->getUTTKind()); - Code = TYPE_UNARY_TRANSFORM; -} - -void ASTTypeWriter::VisitAutoType(const AutoType *T) { - Record.AddTypeRef(T->getDeducedType()); - Record.push_back((unsigned)T->getKeyword()); - if (T->getDeducedType().isNull()) - Record.push_back(T->containsUnexpandedParameterPack() ? 2 : - T->isDependentType() ? 1 : 0); - Code = TYPE_AUTO; -} - -void ASTTypeWriter::VisitDeducedTemplateSpecializationType( - const DeducedTemplateSpecializationType *T) { - Record.AddTemplateName(T->getTemplateName()); - Record.AddTypeRef(T->getDeducedType()); - if (T->getDeducedType().isNull()) - Record.push_back(T->isDependentType()); - Code = TYPE_DEDUCED_TEMPLATE_SPECIALIZATION; -} - -void ASTTypeWriter::VisitTagType(const TagType *T) { - Record.push_back(T->isDependentType()); - Record.AddDeclRef(T->getDecl()->getCanonicalDecl()); - assert(!T->isBeingDefined() && - "Cannot serialize in the middle of a type definition"); -} - -void ASTTypeWriter::VisitRecordType(const RecordType *T) { - VisitTagType(T); - Code = TYPE_RECORD; -} - -void ASTTypeWriter::VisitEnumType(const EnumType *T) { - VisitTagType(T); - Code = TYPE_ENUM; -} - -void ASTTypeWriter::VisitAttributedType(const AttributedType *T) { - Record.AddTypeRef(T->getModifiedType()); - Record.AddTypeRef(T->getEquivalentType()); - Record.push_back(T->getAttrKind()); - Code = TYPE_ATTRIBUTED; -} - -void -ASTTypeWriter::VisitSubstTemplateTypeParmType( - const SubstTemplateTypeParmType *T) { - Record.AddTypeRef(QualType(T->getReplacedParameter(), 0)); - Record.AddTypeRef(T->getReplacementType()); - Code = TYPE_SUBST_TEMPLATE_TYPE_PARM; -} - -void -ASTTypeWriter::VisitSubstTemplateTypeParmPackType( - const SubstTemplateTypeParmPackType *T) { - Record.AddTypeRef(QualType(T->getReplacedParameter(), 0)); - Record.AddTemplateArgument(T->getArgumentPack()); - Code = TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK; -} - -void -ASTTypeWriter::VisitTemplateSpecializationType( - const TemplateSpecializationType *T) { - Record.push_back(T->isDependentType()); - Record.AddTemplateName(T->getTemplateName()); - Record.push_back(T->getNumArgs()); - for (const auto &ArgI : *T) - Record.AddTemplateArgument(ArgI); - Record.AddTypeRef(T->isTypeAlias() ? T->getAliasedType() - : T->isCanonicalUnqualified() - ? QualType() - : T->getCanonicalTypeInternal()); - Code = TYPE_TEMPLATE_SPECIALIZATION; -} - -void -ASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) { - VisitArrayType(T); - Record.AddStmt(T->getSizeExpr()); - Record.AddSourceRange(T->getBracketsRange()); - Code = TYPE_DEPENDENT_SIZED_ARRAY; -} - -void -ASTTypeWriter::VisitDependentSizedExtVectorType( - const DependentSizedExtVectorType *T) { - Record.AddTypeRef(T->getElementType()); - Record.AddStmt(T->getSizeExpr()); - Record.AddSourceLocation(T->getAttributeLoc()); - Code = TYPE_DEPENDENT_SIZED_EXT_VECTOR; -} - -void ASTTypeWriter::VisitDependentVectorType(const DependentVectorType *T) { - Record.AddTypeRef(T->getElementType()); - Record.AddStmt(const_cast<Expr*>(T->getSizeExpr())); - Record.AddSourceLocation(T->getAttributeLoc()); - Record.push_back(T->getVectorKind()); - Code = TYPE_DEPENDENT_SIZED_VECTOR; -} - -void -ASTTypeWriter::VisitDependentAddressSpaceType( - const DependentAddressSpaceType *T) { - Record.AddTypeRef(T->getPointeeType()); - Record.AddStmt(T->getAddrSpaceExpr()); - Record.AddSourceLocation(T->getAttributeLoc()); - Code = TYPE_DEPENDENT_ADDRESS_SPACE; -} - -void -ASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { - Record.push_back(T->getDepth()); - Record.push_back(T->getIndex()); - Record.push_back(T->isParameterPack()); - Record.AddDeclRef(T->getDecl()); - Code = TYPE_TEMPLATE_TYPE_PARM; -} - -void -ASTTypeWriter::VisitDependentNameType(const DependentNameType *T) { - Record.push_back(T->getKeyword()); - Record.AddNestedNameSpecifier(T->getQualifier()); - Record.AddIdentifierRef(T->getIdentifier()); - Record.AddTypeRef( - T->isCanonicalUnqualified() ? QualType() : T->getCanonicalTypeInternal()); - Code = TYPE_DEPENDENT_NAME; -} - -void -ASTTypeWriter::VisitDependentTemplateSpecializationType( - const DependentTemplateSpecializationType *T) { - Record.push_back(T->getKeyword()); - Record.AddNestedNameSpecifier(T->getQualifier()); - Record.AddIdentifierRef(T->getIdentifier()); - Record.push_back(T->getNumArgs()); - for (const auto &I : *T) - Record.AddTemplateArgument(I); - Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION; -} - -void ASTTypeWriter::VisitPackExpansionType(const PackExpansionType *T) { - Record.AddTypeRef(T->getPattern()); - if (Optional<unsigned> NumExpansions = T->getNumExpansions()) - Record.push_back(*NumExpansions + 1); - else - Record.push_back(0); - Code = TYPE_PACK_EXPANSION; -} - -void ASTTypeWriter::VisitParenType(const ParenType *T) { - Record.AddTypeRef(T->getInnerType()); - Code = TYPE_PAREN; -} - -void ASTTypeWriter::VisitMacroQualifiedType(const MacroQualifiedType *T) { - Record.AddTypeRef(T->getUnderlyingType()); - Record.AddIdentifierRef(T->getMacroIdentifier()); - Code = TYPE_MACRO_QUALIFIED; -} - -void ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) { - Record.push_back(T->getKeyword()); - Record.AddNestedNameSpecifier(T->getQualifier()); - Record.AddTypeRef(T->getNamedType()); - Record.AddDeclRef(T->getOwnedTagDecl()); - Code = TYPE_ELABORATED; -} - -void ASTTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) { - Record.AddDeclRef(T->getDecl()->getCanonicalDecl()); - Record.AddTypeRef(T->getInjectedSpecializationType()); - Code = TYPE_INJECTED_CLASS_NAME; -} - -void ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) { - Record.AddDeclRef(T->getDecl()->getCanonicalDecl()); - Code = TYPE_OBJC_INTERFACE; -} - -void ASTTypeWriter::VisitObjCTypeParamType(const ObjCTypeParamType *T) { - Record.AddDeclRef(T->getDecl()); - Record.push_back(T->getNumProtocols()); - for (const auto *I : T->quals()) - Record.AddDeclRef(I); - Code = TYPE_OBJC_TYPE_PARAM; -} - -void ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) { - Record.AddTypeRef(T->getBaseType()); - Record.push_back(T->getTypeArgsAsWritten().size()); - for (auto TypeArg : T->getTypeArgsAsWritten()) - Record.AddTypeRef(TypeArg); - Record.push_back(T->getNumProtocols()); - for (const auto *I : T->quals()) - Record.AddDeclRef(I); - Record.push_back(T->isKindOfTypeAsWritten()); - Code = TYPE_OBJC_OBJECT; -} - -void -ASTTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { - Record.AddTypeRef(T->getPointeeType()); - Code = TYPE_OBJC_OBJECT_POINTER; -} - -void -ASTTypeWriter::VisitAtomicType(const AtomicType *T) { - Record.AddTypeRef(T->getValueType()); - Code = TYPE_ATOMIC; -} - -void -ASTTypeWriter::VisitPipeType(const PipeType *T) { - Record.AddTypeRef(T->getElementType()); - Record.push_back(T->isReadOnly()); - Code = TYPE_PIPE; -} - -namespace { +}; class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { ASTRecordWriter &Record; @@ -3198,12 +2785,8 @@ void ASTWriter::WriteType(QualType T) { assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST"); - RecordData Record; - // Emit the type's representation. - ASTTypeWriter W(*this, Record); - W.Visit(T); - uint64_t Offset = W.Emit(); + uint64_t Offset = ASTTypeWriter(*this).write(T); // Record the offset for this type. unsigned Index = Idx.getIndex() - FirstTypeID; @@ -5364,11 +4947,12 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { Record.AddStmt(cast<CXXDestructorDecl>(D)->getOperatorDeleteThisArg()); break; - case UPD_CXX_RESOLVED_EXCEPTION_SPEC: - addExceptionSpec( - cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>(), - Record); + case UPD_CXX_RESOLVED_EXCEPTION_SPEC: { + auto prototype = + cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>(); + Record.writeExceptionSpecInfo(prototype->getExceptionSpecInfo()); break; + } case UPD_CXX_DEDUCED_RETURN_TYPE: Record.push_back(GetOrCreateTypeID(Update.getType())); @@ -5434,17 +5018,6 @@ void ASTWriter::AddSourceRange(SourceRange Range, RecordDataImpl &Record) { AddSourceLocation(Range.getEnd(), Record); } -void ASTRecordWriter::AddAPInt(const llvm::APInt &Value) { - Record->push_back(Value.getBitWidth()); - const uint64_t *Words = Value.getRawData(); - Record->append(Words, Words + Value.getNumWords()); -} - -void ASTRecordWriter::AddAPSInt(const llvm::APSInt &Value) { - Record->push_back(Value.isUnsigned()); - AddAPInt(Value); -} - void ASTRecordWriter::AddAPFloat(const llvm::APFloat &Value) { AddAPInt(Value.bitcastToAPInt()); } @@ -5762,44 +5335,6 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { Decls.insert(I, LocDecl); } -void ASTRecordWriter::AddDeclarationName(DeclarationName Name) { - // FIXME: Emit a stable enum for NameKind. 0 = Identifier etc. - Record->push_back(Name.getNameKind()); - switch (Name.getNameKind()) { - case DeclarationName::Identifier: - AddIdentifierRef(Name.getAsIdentifierInfo()); - break; - - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - AddSelectorRef(Name.getObjCSelector()); - break; - - case DeclarationName::CXXConstructorName: - case DeclarationName::CXXDestructorName: - case DeclarationName::CXXConversionFunctionName: - AddTypeRef(Name.getCXXNameType()); - break; - - case DeclarationName::CXXDeductionGuideName: - AddDeclRef(Name.getCXXDeductionGuideTemplate()); - break; - - case DeclarationName::CXXOperatorName: - Record->push_back(Name.getCXXOverloadedOperator()); - break; - - case DeclarationName::CXXLiteralOperatorName: - AddIdentifierRef(Name.getCXXLiteralIdentifier()); - break; - - case DeclarationName::CXXUsingDirective: - // No extra data to emit - break; - } -} - unsigned ASTWriter::getAnonymousDeclarationNumber(const NamedDecl *D) { assert(needsAnonymousDeclarationNumber(D) && "expected an anonymous declaration"); @@ -5866,52 +5401,6 @@ void ASTRecordWriter::AddQualifierInfo(const QualifierInfo &Info) { AddTemplateParameterList(Info.TemplParamLists[i]); } -void ASTRecordWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS) { - // Nested name specifiers usually aren't too long. I think that 8 would - // typically accommodate the vast majority. - SmallVector<NestedNameSpecifier *, 8> NestedNames; - - // Push each of the NNS's onto a stack for serialization in reverse order. - while (NNS) { - NestedNames.push_back(NNS); - NNS = NNS->getPrefix(); - } - - Record->push_back(NestedNames.size()); - while(!NestedNames.empty()) { - NNS = NestedNames.pop_back_val(); - NestedNameSpecifier::SpecifierKind Kind = NNS->getKind(); - Record->push_back(Kind); - switch (Kind) { - case NestedNameSpecifier::Identifier: - AddIdentifierRef(NNS->getAsIdentifier()); - break; - - case NestedNameSpecifier::Namespace: - AddDeclRef(NNS->getAsNamespace()); - break; - - case NestedNameSpecifier::NamespaceAlias: - AddDeclRef(NNS->getAsNamespaceAlias()); - break; - - case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: - AddTypeRef(QualType(NNS->getAsType(), 0)); - Record->push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate); - break; - - case NestedNameSpecifier::Global: - // Don't need to write an associated value. - break; - - case NestedNameSpecifier::Super: - AddDeclRef(NNS->getAsRecordDecl()); - break; - } - } -} - void ASTRecordWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { // Nested name specifiers usually aren't too long. I think that 8 would // typically accommodate the vast majority. @@ -5966,105 +5455,6 @@ void ASTRecordWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { } } -void ASTRecordWriter::AddTemplateName(TemplateName Name) { - TemplateName::NameKind Kind = Name.getKind(); - Record->push_back(Kind); - switch (Kind) { - case TemplateName::Template: - AddDeclRef(Name.getAsTemplateDecl()); - break; - - case TemplateName::OverloadedTemplate: { - OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate(); - Record->push_back(OvT->size()); - for (const auto &I : *OvT) - AddDeclRef(I); - break; - } - - case TemplateName::AssumedTemplate: { - AssumedTemplateStorage *ADLT = Name.getAsAssumedTemplateName(); - AddDeclarationName(ADLT->getDeclName()); - break; - } - - case TemplateName::QualifiedTemplate: { - QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName(); - AddNestedNameSpecifier(QualT->getQualifier()); - Record->push_back(QualT->hasTemplateKeyword()); - AddDeclRef(QualT->getTemplateDecl()); - break; - } - - case TemplateName::DependentTemplate: { - DependentTemplateName *DepT = Name.getAsDependentTemplateName(); - AddNestedNameSpecifier(DepT->getQualifier()); - Record->push_back(DepT->isIdentifier()); - if (DepT->isIdentifier()) - AddIdentifierRef(DepT->getIdentifier()); - else - Record->push_back(DepT->getOperator()); - break; - } - - case TemplateName::SubstTemplateTemplateParm: { - SubstTemplateTemplateParmStorage *subst - = Name.getAsSubstTemplateTemplateParm(); - AddDeclRef(subst->getParameter()); - AddTemplateName(subst->getReplacement()); - break; - } - - case TemplateName::SubstTemplateTemplateParmPack: { - SubstTemplateTemplateParmPackStorage *SubstPack - = Name.getAsSubstTemplateTemplateParmPack(); - AddDeclRef(SubstPack->getParameterPack()); - AddTemplateArgument(SubstPack->getArgumentPack()); - break; - } - } -} - -void ASTRecordWriter::AddTemplateArgument(const TemplateArgument &Arg) { - Record->push_back(Arg.getKind()); - switch (Arg.getKind()) { - case TemplateArgument::Null: - break; - case TemplateArgument::Type: - AddTypeRef(Arg.getAsType()); - break; - case TemplateArgument::Declaration: - AddDeclRef(Arg.getAsDecl()); - AddTypeRef(Arg.getParamTypeForDecl()); - break; - case TemplateArgument::NullPtr: - AddTypeRef(Arg.getNullPtrType()); - break; - case TemplateArgument::Integral: - AddAPSInt(Arg.getAsIntegral()); - AddTypeRef(Arg.getIntegralType()); - break; - case TemplateArgument::Template: - AddTemplateName(Arg.getAsTemplateOrTemplatePattern()); - break; - case TemplateArgument::TemplateExpansion: - AddTemplateName(Arg.getAsTemplateOrTemplatePattern()); - if (Optional<unsigned> NumExpansions = Arg.getNumTemplateExpansions()) - Record->push_back(*NumExpansions + 1); - else - Record->push_back(0); - break; - case TemplateArgument::Expression: - AddStmt(Arg.getAsExpr()); - break; - case TemplateArgument::Pack: - Record->push_back(Arg.pack_size()); - for (const auto &P : Arg.pack_elements()) - AddTemplateArgument(P); - break; - } -} - void ASTRecordWriter::AddTemplateParameterList( const TemplateParameterList *TemplateParams) { assert(TemplateParams && "No TemplateParams!"); |