summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2019-12-13 21:54:44 -0500
committerJohn McCall <rjmccall@apple.com>2019-12-14 00:17:01 -0500
commitd505e57cc273750541ec8bbce2065b8b87c99ad6 (patch)
tree5a96e0ced43a51381773c434c065bb2c9cd3f3a2 /clang/lib
parent6404bd236240639d4986d1ee634ded4bc81d8bd8 (diff)
downloadbcm5719-llvm-d505e57cc273750541ec8bbce2065b8b87c99ad6.tar.gz
bcm5719-llvm-d505e57cc273750541ec8bbce2065b8b87c99ad6.zip
Abstract serialization: TableGen the (de)serialization code for Types.
The basic technical design here is that we have three levels of readers and writers: - At the lowest level, there's a `Basic{Reader,Writer}` that knows how to emit the basic structures of the AST. CRTP allows this to be metaprogrammed so that the client only needs to support a handful of primitive types (e.g. `uint64_t` and `IdentifierInfo*`) and more complicated "inline" structures such as `DeclarationName` can just be emitted in terms of those primitives. In Clang's binary-serialization code, these are `ASTRecord{Reader,Writer}`. For now, a large number of basic structures are still emitted explicitly by code on those classes rather than by either TableGen or CRTP metaprogramming, but I expect to move more of these over. - In the middle, there's a `Property{Reader,Writer}` which is responsible for processing the properties of a larger object. The object-level reader/writer asks the property-level reader/writer to project out a particular property, yielding a basic reader/writer which will be used to read/write the property's value, like so: ``` propertyWriter.find("count").writeUInt32(node->getCount()); ``` Clang's binary-serialization code ignores this level (it uses the basic reader/writer as the property reader/writer and has the projection methods just return `*this`) and simply relies on the roperties being read/written in a stable order. - At the highest level, there's an object reader/writer (e.g. `Type{Reader,Writer}` which emits a logical object with properties. Think of this as writing something like a JSON dictionary literal. I haven't introduced support for bitcode abbreviations yet --- it turns out that there aren't any operative abbreviations for types besides the QualType one --- but I do have some ideas of how they should work. At any rate, they'll be necessary in order to handle statements. I'm sorry for not disentangling the patches that added basic and type reader/writers; I made some effort to, but I ran out of energy after disentangling a number of other patches from the work. Negligible impact on module size, time to build a set of about 20 fairly large modules, or time to read a few declarations out of them.
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp779
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp684
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!");
OpenPOWER on IntegriCloud