summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTWriter.cpp
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/Serialization/ASTWriter.cpp
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/Serialization/ASTWriter.cpp')
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp684
1 files changed, 37 insertions, 647 deletions
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