Re-commit r265518 ("[modules] Continue factoring encoding of AST records out of

ASTWriter."), reverted in r265526, with a fix for an iterator invalidation bug
(thanks, MSan!).

llvm-svn: 265564
This commit is contained in:
Richard Smith 2016-04-06 17:06:00 +00:00
parent 4812c91f56
commit 290d801916
6 changed files with 999 additions and 1106 deletions

View File

@ -1714,6 +1714,7 @@ public:
friend class ASTDeclReader; friend class ASTDeclReader;
friend class ASTDeclWriter; friend class ASTDeclWriter;
friend class ASTRecordWriter;
friend class ASTReader; friend class ASTReader;
friend class ASTWriter; friend class ASTWriter;
}; };

View File

@ -90,6 +90,7 @@ public:
friend class ASTDeclWriter; friend class ASTDeclWriter;
friend class ASTStmtWriter; friend class ASTStmtWriter;
friend class ASTTypeWriter;
friend class ASTRecordWriter; friend class ASTRecordWriter;
private: private:
/// \brief Map that provides the ID numbers of each type within the /// \brief Map that provides the ID numbers of each type within the
@ -391,14 +392,6 @@ private:
/// redeclaration chains. /// redeclaration chains.
llvm::DenseMap<const Decl *, const Decl *> FirstLocalDeclCache; llvm::DenseMap<const Decl *, const Decl *> FirstLocalDeclCache;
/// \brief Statements that we've encountered while serializing a
/// declaration or type.
SmallVector<Stmt *, 16> StmtsToEmit;
/// \brief Statements collection to use for ASTWriter::AddStmt().
/// It will point to StmtsToEmit unless it is overriden.
SmallVector<Stmt *, 16> *CollectedStmts;
/// \brief Mapping from SwitchCase statements to IDs. /// \brief Mapping from SwitchCase statements to IDs.
llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs; llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs;
@ -555,7 +548,6 @@ private:
void WriteDeclAbbrevs(); void WriteDeclAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D); void WriteDecl(ASTContext &Context, Decl *D);
void AddFunctionDefinition(const FunctionDecl *FD, RecordDataImpl &Record);
uint64_t WriteASTCore(Sema &SemaRef, uint64_t WriteASTCore(Sema &SemaRef,
StringRef isysroot, const std::string &OutputFile, StringRef isysroot, const std::string &OutputFile,
@ -649,26 +641,6 @@ public:
/// \brief Determine the type ID of an already-emitted type. /// \brief Determine the type ID of an already-emitted type.
serialization::TypeID getTypeID(QualType T) const; serialization::TypeID getTypeID(QualType T) const;
/// \brief Emits a reference to a declarator info.
void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record);
/// \brief Emits a type with source-location information.
void AddTypeLoc(TypeLoc TL, RecordDataImpl &Record);
/// \brief Emits a template argument location info.
void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const TemplateArgumentLocInfo &Arg,
RecordDataImpl &Record);
/// \brief Emits a template argument location.
void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
RecordDataImpl &Record);
/// \brief Emits an AST template argument list info.
void AddASTTemplateArgumentListInfo(
const ASTTemplateArgumentListInfo *ASTTemplArgList,
RecordDataImpl &Record);
/// \brief Find the first local declaration of a given local redeclarable /// \brief Find the first local declaration of a given local redeclarable
/// decl. /// decl.
const Decl *getFirstLocalDecl(const Decl *D); const Decl *getFirstLocalDecl(const Decl *D);
@ -684,59 +656,26 @@ public:
/// declaration. /// declaration.
serialization::DeclID getDeclID(const Decl *D); serialization::DeclID getDeclID(const Decl *D);
void AddAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
/// \brief Emit a declaration name. /// \brief Emit a declaration name.
void AddDeclarationName(DeclarationName Name, RecordDataImpl &Record); void AddDeclarationName(DeclarationName Name, RecordDataImpl &Record);
void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
DeclarationName Name, RecordDataImpl &Record);
void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
RecordDataImpl &Record);
unsigned getAnonymousDeclarationNumber(const NamedDecl *D);
void AddQualifierInfo(const QualifierInfo &Info, RecordDataImpl &Record); unsigned getAnonymousDeclarationNumber(const NamedDecl *D);
/// \brief Emit a nested name specifier. /// \brief Emit a nested name specifier.
void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordDataImpl &Record); void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordDataImpl &Record);
/// \brief Emit a nested name specifier with source-location information.
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
RecordDataImpl &Record);
/// \brief Emit a template name.
void AddTemplateName(TemplateName Name, RecordDataImpl &Record);
/// \brief Emit a template argument.
void AddTemplateArgument(const TemplateArgument &Arg, RecordDataImpl &Record);
/// \brief Emit a template parameter list. /// \brief Emit a template parameter list.
void AddTemplateParameterList(const TemplateParameterList *TemplateParams, void AddTemplateParameterList(const TemplateParameterList *TemplateParams,
RecordDataImpl &Record); RecordDataImpl &Record);
/// \brief Emit a template argument list.
void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
RecordDataImpl &Record);
/// \brief Emit a UnresolvedSet structure. /// \brief Emit a UnresolvedSet structure.
void AddUnresolvedSet(const ASTUnresolvedSet &Set, RecordDataImpl &Record); void AddUnresolvedSet(const ASTUnresolvedSet &Set, RecordDataImpl &Record);
/// \brief Emit a C++ base specifier.
void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
RecordDataImpl &Record);
/// \brief Emit the ID for a CXXCtorInitializer array and register the array /// \brief Emit the ID for a CXXCtorInitializer array and register the array
/// for later serialization. /// for later serialization.
void AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> Inits, void AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> Inits,
RecordDataImpl &Record); RecordDataImpl &Record);
/// \brief Emit a CXXCtorInitializer array.
void AddCXXCtorInitializers(
const CXXCtorInitializer * const *CtorInitializers,
unsigned NumCtorInitializers,
RecordDataImpl &Record);
void AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record);
/// \brief Add a string to the given record. /// \brief Add a string to the given record.
void AddString(StringRef Str, RecordDataImpl &Record); void AddString(StringRef Str, RecordDataImpl &Record);
@ -771,22 +710,6 @@ public:
/// within the method pool/selector table. /// within the method pool/selector table.
void SetSelectorOffset(Selector Sel, uint32_t Offset); void SetSelectorOffset(Selector Sel, uint32_t Offset);
/// \brief Add the given statement or expression to the queue of
/// statements to emit.
///
/// This routine should be used when emitting types and declarations
/// that have expressions as part of their formulation. Once the
/// type or declaration has been written, call FlushStmts() to write
/// the corresponding statements just after the type or
/// declaration.
void AddStmt(Stmt *S) {
CollectedStmts->push_back(S);
}
/// \brief Flush all of the statements and expressions that have
/// been added to the queue via AddStmt().
void FlushStmts();
/// \brief Flush all of the C++ base specifier sets that have been added /// \brief Flush all of the C++ base specifier sets that have been added
/// via \c AddCXXBaseSpecifiersRef(). /// via \c AddCXXBaseSpecifiersRef().
void FlushCXXBaseSpecifiers(); void FlushCXXBaseSpecifiers();
@ -798,7 +721,6 @@ public:
/// \brief Flush all pending records that are tacked onto the end of /// \brief Flush all pending records that are tacked onto the end of
/// decl and decl update records. /// decl and decl update records.
void FlushPendingAfterDecl() { void FlushPendingAfterDecl() {
FlushStmts();
FlushCXXBaseSpecifiers(); FlushCXXBaseSpecifiers();
FlushCXXCtorInitializers(); FlushCXXCtorInitializers();
} }
@ -872,6 +794,15 @@ class ASTRecordWriter {
ASTWriter *Writer; ASTWriter *Writer;
ASTWriter::RecordDataImpl *Record; ASTWriter::RecordDataImpl *Record;
/// \brief Statements that we've encountered while serializing a
/// declaration or type.
SmallVector<Stmt *, 16> StmtsToEmit;
/// \brief Flush all of the statements and expressions that have
/// been added to the queue via AddStmt().
void FlushStmts();
void FlushSubStmts();
public: public:
/// Construct a ASTRecordWriter that uses the default encoding scheme. /// Construct a ASTRecordWriter that uses the default encoding scheme.
ASTRecordWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) ASTRecordWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
@ -897,15 +828,37 @@ public:
uint64_t &operator[](size_t N) { return (*Record)[N]; } uint64_t &operator[](size_t N) { return (*Record)[N]; }
/// @} /// @}
/// \brief Emit the record to the stream, followed by its substatements, and
/// \brief Emit the record to the stream, and return its offset. /// return its offset.
// FIXME: Allow record producers to suggest Abbrevs. // FIXME: Allow record producers to suggest Abbrevs.
uint64_t Emit(unsigned Code, unsigned Abbrev = 0) { uint64_t Emit(unsigned Code, unsigned Abbrev = 0) {
uint64_t Offset = Writer->Stream.GetCurrentBitNo(); uint64_t Offset = Writer->Stream.GetCurrentBitNo();
Writer->Stream.EmitRecord(Code, *Record); Writer->Stream.EmitRecord(Code, *Record, Abbrev);
FlushStmts();
return Offset; return Offset;
} }
/// \brief Emit the record to the stream, preceded by its substatements.
uint64_t EmitStmt(unsigned Code, unsigned Abbrev = 0) {
FlushSubStmts();
Writer->Stream.EmitRecord(Code, *Record, Abbrev);
return Writer->Stream.GetCurrentBitNo();
}
/// \brief Add the given statement or expression to the queue of
/// statements to emit.
///
/// This routine should be used when emitting types and declarations
/// that have expressions as part of their formulation. Once the
/// type or declaration has been written, Emit() will write
/// the corresponding statements just after the record.
void AddStmt(Stmt *S) {
StmtsToEmit.push_back(S);
}
/// \brief Add a definition for the given function to the queue of statements
/// to emit.
void AddFunctionDefinition(const FunctionDecl *FD);
/// \brief Emit a source location. /// \brief Emit a source location.
void AddSourceLocation(SourceLocation Loc) { void AddSourceLocation(SourceLocation Loc) {
@ -959,26 +912,21 @@ public:
} }
/// \brief Emits a reference to a declarator info. /// \brief Emits a reference to a declarator info.
void AddTypeSourceInfo(TypeSourceInfo *TInfo) { void AddTypeSourceInfo(TypeSourceInfo *TInfo);
return Writer->AddTypeSourceInfo(TInfo, *Record);
} /// \brief Emits a type with source-location information.
void AddTypeLoc(TypeLoc TL);
/// \brief Emits a template argument location info. /// \brief Emits a template argument location info.
void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const TemplateArgumentLocInfo &Arg) { const TemplateArgumentLocInfo &Arg);
return Writer->AddTemplateArgumentLocInfo(Kind, Arg, *Record);
}
/// \brief Emits a template argument location. /// \brief Emits a template argument location.
void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg) { void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg);
return Writer->AddTemplateArgumentLoc(Arg, *Record);
}
/// \brief Emits an AST template argument list info. /// \brief Emits an AST template argument list info.
void AddASTTemplateArgumentListInfo( void AddASTTemplateArgumentListInfo(
const ASTTemplateArgumentListInfo *ASTTemplArgList) { const ASTTemplateArgumentListInfo *ASTTemplArgList);
return Writer->AddASTTemplateArgumentListInfo(ASTTemplArgList, *Record);
}
/// \brief Emit a reference to a declaration. /// \brief Emit a reference to a declaration.
void AddDeclRef(const Decl *D) { void AddDeclRef(const Decl *D) {
@ -990,17 +938,10 @@ public:
} }
void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
DeclarationName Name) { DeclarationName Name);
return Writer->AddDeclarationNameLoc(DNLoc, Name, *Record); void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
}
void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo) { void AddQualifierInfo(const QualifierInfo &Info);
return Writer->AddDeclarationNameInfo(NameInfo, *Record);
}
void AddQualifierInfo(const QualifierInfo &Info) {
return Writer->AddQualifierInfo(Info, *Record);
}
/// \brief Emit a nested name specifier. /// \brief Emit a nested name specifier.
void AddNestedNameSpecifier(NestedNameSpecifier *NNS) { void AddNestedNameSpecifier(NestedNameSpecifier *NNS) {
@ -1008,19 +949,13 @@ public:
} }
/// \brief Emit a nested name specifier with source-location information. /// \brief Emit a nested name specifier with source-location information.
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
return Writer->AddNestedNameSpecifierLoc(NNS, *Record);
}
/// \brief Emit a template name. /// \brief Emit a template name.
void AddTemplateName(TemplateName Name) { void AddTemplateName(TemplateName Name);
return Writer->AddTemplateName(Name, *Record);
}
/// \brief Emit a template argument. /// \brief Emit a template argument.
void AddTemplateArgument(const TemplateArgument &Arg) { void AddTemplateArgument(const TemplateArgument &Arg);
return Writer->AddTemplateArgument(Arg, *Record);
}
/// \brief Emit a template parameter list. /// \brief Emit a template parameter list.
void AddTemplateParameterList(const TemplateParameterList *TemplateParams) { void AddTemplateParameterList(const TemplateParameterList *TemplateParams) {
@ -1028,9 +963,7 @@ public:
} }
/// \brief Emit a template argument list. /// \brief Emit a template argument list.
void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs) { void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs);
return Writer->AddTemplateArgumentList(TemplateArgs, *Record);
}
/// \brief Emit a UnresolvedSet structure. /// \brief Emit a UnresolvedSet structure.
void AddUnresolvedSet(const ASTUnresolvedSet &Set) { void AddUnresolvedSet(const ASTUnresolvedSet &Set) {
@ -1038,9 +971,7 @@ public:
} }
/// \brief Emit a C++ base specifier. /// \brief Emit a C++ base specifier.
void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base) { void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base);
return Writer->AddCXXBaseSpecifier(Base, *Record);
}
/// \brief Emit the ID for a CXXCtorInitializer array and register the array /// \brief Emit the ID for a CXXCtorInitializer array and register the array
/// for later serialization. /// for later serialization.
@ -1050,14 +981,9 @@ public:
/// \brief Emit a CXXCtorInitializer array. /// \brief Emit a CXXCtorInitializer array.
void AddCXXCtorInitializers(const CXXCtorInitializer *const *CtorInitializers, void AddCXXCtorInitializers(const CXXCtorInitializer *const *CtorInitializers,
unsigned NumCtorInitializers) { unsigned NumCtorInitializers);
return Writer->AddCXXCtorInitializers(CtorInitializers, NumCtorInitializers,
*Record);
}
void AddCXXDefinitionData(const CXXRecordDecl *D) { void AddCXXDefinitionData(const CXXRecordDecl *D);
return Writer->AddCXXDefinitionData(D, *Record);
}
/// \brief Emit a string. /// \brief Emit a string.
void AddString(StringRef Str) { void AddString(StringRef Str) {
@ -1075,9 +1001,7 @@ public:
} }
/// \brief Emit a list of attributes. /// \brief Emit a list of attributes.
void AddAttributes(ArrayRef<const Attr*> Attrs) { void AddAttributes(ArrayRef<const Attr*> Attrs);
return Writer->AddAttributes(Attrs, *Record);
}
}; };
/// \brief AST and semantic-analysis consumer that generates a /// \brief AST and semantic-analysis consumer that generates a

View File

@ -82,19 +82,42 @@ static StringRef bytes(const SmallVectorImpl<T> &v) {
// Type serialization // Type serialization
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
namespace { namespace clang {
class ASTTypeWriter { class ASTTypeWriter {
ASTWriter &Writer; ASTWriter &Writer;
ASTRecordWriter Record; ASTRecordWriter Record;
public:
/// \brief Type code that corresponds to the record generated. /// \brief Type code that corresponds to the record generated.
TypeCode Code; TypeCode Code;
/// \brief Abbreviation to use for the record, if any. /// \brief Abbreviation to use for the record, if any.
unsigned AbbrevToUse; unsigned AbbrevToUse;
public:
ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
: Writer(Writer), Record(Writer, Record), Code(TYPE_EXT_QUAL) { } : Writer(Writer), Record(Writer, Record), Code((TypeCode)0), AbbrevToUse(0) { }
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.def"
}
}
}
void VisitArrayType(const ArrayType *T); void VisitArrayType(const ArrayType *T);
void VisitFunctionType(const FunctionType *T); void VisitFunctionType(const FunctionType *T);
@ -104,7 +127,7 @@ namespace {
#define ABSTRACT_TYPE(Class, Base) #define ABSTRACT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def" #include "clang/AST/TypeNodes.def"
}; };
} // end anonymous namespace } // end namespace clang
void ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) { void ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) {
llvm_unreachable("Built-in types are never serialized"); llvm_unreachable("Built-in types are never serialized");
@ -174,7 +197,7 @@ void ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
VisitArrayType(T); VisitArrayType(T);
Record.AddSourceLocation(T->getLBracketLoc()); Record.AddSourceLocation(T->getLBracketLoc());
Record.AddSourceLocation(T->getRBracketLoc()); Record.AddSourceLocation(T->getRBracketLoc());
Writer.AddStmt(T->getSizeExpr()); Record.AddStmt(T->getSizeExpr());
Code = TYPE_VARIABLE_ARRAY; Code = TYPE_VARIABLE_ARRAY;
} }
@ -209,15 +232,15 @@ void ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
Code = TYPE_FUNCTION_NO_PROTO; Code = TYPE_FUNCTION_NO_PROTO;
} }
static void addExceptionSpec(ASTWriter &Writer, const FunctionProtoType *T, static void addExceptionSpec(const FunctionProtoType *T,
ASTRecordWriter Record) { ASTRecordWriter &Record) {
Record.push_back(T->getExceptionSpecType()); Record.push_back(T->getExceptionSpecType());
if (T->getExceptionSpecType() == EST_Dynamic) { if (T->getExceptionSpecType() == EST_Dynamic) {
Record.push_back(T->getNumExceptions()); Record.push_back(T->getNumExceptions());
for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I)
Record.AddTypeRef(T->getExceptionType(I)); Record.AddTypeRef(T->getExceptionType(I));
} else if (T->getExceptionSpecType() == EST_ComputedNoexcept) { } else if (T->getExceptionSpecType() == EST_ComputedNoexcept) {
Writer.AddStmt(T->getNoexceptExpr()); Record.AddStmt(T->getNoexceptExpr());
} else if (T->getExceptionSpecType() == EST_Uninstantiated) { } else if (T->getExceptionSpecType() == EST_Uninstantiated) {
Record.AddDeclRef(T->getExceptionSpecDecl()); Record.AddDeclRef(T->getExceptionSpecDecl());
Record.AddDeclRef(T->getExceptionSpecTemplate()); Record.AddDeclRef(T->getExceptionSpecTemplate());
@ -233,7 +256,7 @@ void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
Record.push_back(T->hasTrailingReturn()); Record.push_back(T->hasTrailingReturn());
Record.push_back(T->getTypeQuals()); Record.push_back(T->getTypeQuals());
Record.push_back(static_cast<unsigned>(T->getRefQualifier())); Record.push_back(static_cast<unsigned>(T->getRefQualifier()));
addExceptionSpec(Writer, T, Record); addExceptionSpec(T, Record);
Record.push_back(T->getNumParams()); Record.push_back(T->getNumParams());
for (unsigned I = 0, N = T->getNumParams(); I != N; ++I) for (unsigned I = 0, N = T->getNumParams(); I != N; ++I)
@ -265,7 +288,7 @@ void ASTTypeWriter::VisitTypedefType(const TypedefType *T) {
} }
void ASTTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) { void ASTTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) {
Writer.AddStmt(T->getUnderlyingExpr()); Record.AddStmt(T->getUnderlyingExpr());
Code = TYPE_TYPEOF_EXPR; Code = TYPE_TYPEOF_EXPR;
} }
@ -276,7 +299,7 @@ void ASTTypeWriter::VisitTypeOfType(const TypeOfType *T) {
void ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) { void ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) {
Record.AddTypeRef(T->getUnderlyingType()); Record.AddTypeRef(T->getUnderlyingType());
Writer.AddStmt(T->getUnderlyingExpr()); Record.AddStmt(T->getUnderlyingExpr());
Code = TYPE_DECLTYPE; Code = TYPE_DECLTYPE;
} }
@ -353,7 +376,7 @@ ASTTypeWriter::VisitTemplateSpecializationType(
void void
ASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) { ASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
VisitArrayType(T); VisitArrayType(T);
Writer.AddStmt(T->getSizeExpr()); Record.AddStmt(T->getSizeExpr());
Record.AddSourceRange(T->getBracketsRange()); Record.AddSourceRange(T->getBracketsRange());
Code = TYPE_DEPENDENT_SIZED_ARRAY; Code = TYPE_DEPENDENT_SIZED_ARRAY;
} }
@ -461,12 +484,11 @@ ASTTypeWriter::VisitPipeType(const PipeType *T) {
namespace { namespace {
class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
ASTWriter &Writer; ASTRecordWriter &Record;
ASTRecordWriter Record;
public: public:
TypeLocWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) TypeLocWriter(ASTRecordWriter &Record)
: Writer(Writer), Record(Writer, Record) { } : Record(Record) { }
#define ABSTRACT_TYPELOC(CLASS, PARENT) #define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \ #define TYPELOC(CLASS, PARENT) \
@ -521,7 +543,7 @@ void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) {
Record.AddSourceLocation(TL.getRBracketLoc()); Record.AddSourceLocation(TL.getRBracketLoc());
Record.push_back(TL.getSizeExpr() ? 1 : 0); Record.push_back(TL.getSizeExpr() ? 1 : 0);
if (TL.getSizeExpr()) if (TL.getSizeExpr())
Writer.AddStmt(TL.getSizeExpr()); Record.AddStmt(TL.getSizeExpr());
} }
void TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { void TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
VisitArrayTypeLoc(TL); VisitArrayTypeLoc(TL);
@ -605,7 +627,7 @@ void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
if (TL.hasAttrExprOperand()) { if (TL.hasAttrExprOperand()) {
Expr *operand = TL.getAttrExprOperand(); Expr *operand = TL.getAttrExprOperand();
Record.push_back(operand ? 1 : 0); Record.push_back(operand ? 1 : 0);
if (operand) Writer.AddStmt(operand); if (operand) Record.AddStmt(operand);
} else if (TL.hasAttrEnumOperand()) { } else if (TL.hasAttrEnumOperand()) {
Record.AddSourceLocation(TL.getAttrEnumOperandLoc()); Record.AddSourceLocation(TL.getAttrEnumOperandLoc());
} }
@ -2737,49 +2759,30 @@ void ASTWriter::WriteCXXBaseSpecifiersOffsets() {
/// \brief Write the representation of a type to the AST stream. /// \brief Write the representation of a type to the AST stream.
void ASTWriter::WriteType(QualType T) { void ASTWriter::WriteType(QualType T) {
TypeIdx &Idx = TypeIdxs[T]; TypeIdx &IdxRef = TypeIdxs[T];
if (Idx.getIndex() == 0) // we haven't seen this type before. if (IdxRef.getIndex() == 0) // we haven't seen this type before.
Idx = TypeIdx(NextTypeID++); IdxRef = TypeIdx(NextTypeID++);
TypeIdx Idx = IdxRef;
assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST"); assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST");
// Record the offset for this type.
unsigned Index = Idx.getIndex() - FirstTypeID;
if (TypeOffsets.size() == Index)
TypeOffsets.push_back(Stream.GetCurrentBitNo());
else if (TypeOffsets.size() < Index) {
TypeOffsets.resize(Index + 1);
TypeOffsets[Index] = Stream.GetCurrentBitNo();
}
RecordData Record; RecordData Record;
// Emit the type's representation. // Emit the type's representation.
ASTTypeWriter W(*this, Record); ASTTypeWriter W(*this, Record);
W.AbbrevToUse = 0; W.Visit(T);
uint64_t Offset = W.Emit();
if (T.hasLocalNonFastQualifiers()) { // Record the offset for this type.
Qualifiers Qs = T.getLocalQualifiers(); unsigned Index = Idx.getIndex() - FirstTypeID;
AddTypeRef(T.getLocalUnqualifiedType(), Record); if (TypeOffsets.size() == Index)
Record.push_back(Qs.getAsOpaqueValue()); TypeOffsets.push_back(Offset);
W.Code = TYPE_EXT_QUAL; else if (TypeOffsets.size() < Index) {
W.AbbrevToUse = TypeExtQualAbbrev; TypeOffsets.resize(Index + 1);
TypeOffsets[Index] = Offset;
} else { } else {
switch (T->getTypeClass()) { llvm_unreachable("Types emitted in wrong order");
// For all of the concrete, non-dependent types, call the
// appropriate visitor function.
#define TYPE(Class, Base) \
case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break;
#define ABSTRACT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
}
} }
// Emit the serialized record.
Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
// Flush any expressions that were written as part of this type.
FlushStmts();
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -3989,12 +3992,12 @@ void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// \brief Emit the list of attributes to the specified record. /// \brief Emit the list of attributes to the specified record.
void ASTWriter::AddAttributes(ArrayRef<const Attr *> Attrs, void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) {
RecordDataImpl &Record) { auto &Record = *this;
Record.push_back(Attrs.size()); Record.push_back(Attrs.size());
for (const auto *A : Attrs) { for (const auto *A : Attrs) {
Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs
AddSourceRange(A->getRange(), Record); Record.AddSourceRange(A->getRange());
#include "clang/Serialization/AttrPCHWrite.inc" #include "clang/Serialization/AttrPCHWrite.inc"
@ -4099,7 +4102,7 @@ ASTWriter::ASTWriter(
NextMacroID(FirstMacroID), FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS), NextMacroID(FirstMacroID), FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS),
NextSubmoduleID(FirstSubmoduleID), NextSubmoduleID(FirstSubmoduleID),
FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID), FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),
CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0), NumStatements(0), NumMacros(0),
NumLexicalDeclContexts(0), NumVisibleDeclContexts(0), NumLexicalDeclContexts(0), NumVisibleDeclContexts(0),
NextCXXBaseSpecifiersID(1), NextCXXCtorInitializersID(1), NextCXXBaseSpecifiersID(1), NextCXXCtorInitializersID(1),
TypeExtQualAbbrev(0), TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0), TypeExtQualAbbrev(0), TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0),
@ -4683,8 +4686,8 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
break; break;
case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT: case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT:
AddStmt(const_cast<Expr*>( Record.AddStmt(const_cast<Expr *>(
cast<ParmVarDecl>(Update.getDecl())->getDefaultArg())); cast<ParmVarDecl>(Update.getDecl())->getDefaultArg()));
break; break;
case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: { case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
@ -4738,7 +4741,6 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
case UPD_CXX_RESOLVED_EXCEPTION_SPEC: case UPD_CXX_RESOLVED_EXCEPTION_SPEC:
addExceptionSpec( addExceptionSpec(
*this,
cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>(), cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>(),
Record); Record);
break; break;
@ -4780,7 +4782,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
Record.push_back(UPD_CXX_ADDED_FUNCTION_DEFINITION); Record.push_back(UPD_CXX_ADDED_FUNCTION_DEFINITION);
Record.push_back(Def->isInlined()); Record.push_back(Def->isInlined());
Record.AddSourceLocation(Def->getInnerLocStart()); Record.AddSourceLocation(Def->getInnerLocStart());
AddFunctionDefinition(Def, Record.getRecordData()); Record.AddFunctionDefinition(Def);
} }
OffsetsRecord.push_back(GetDeclRef(D)); OffsetsRecord.push_back(GetDeclRef(D));
@ -4902,24 +4904,23 @@ void ASTWriter::AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases,
Record.push_back(NextCXXBaseSpecifiersID++); Record.push_back(NextCXXBaseSpecifiersID++);
} }
void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, void ASTRecordWriter::AddTemplateArgumentLocInfo(
const TemplateArgumentLocInfo &Arg, TemplateArgument::ArgKind Kind, const TemplateArgumentLocInfo &Arg) {
RecordDataImpl &Record) {
switch (Kind) { switch (Kind) {
case TemplateArgument::Expression: case TemplateArgument::Expression:
AddStmt(Arg.getAsExpr()); AddStmt(Arg.getAsExpr());
break; break;
case TemplateArgument::Type: case TemplateArgument::Type:
AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record); AddTypeSourceInfo(Arg.getAsTypeSourceInfo());
break; break;
case TemplateArgument::Template: case TemplateArgument::Template:
AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc(), Record); AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc());
AddSourceLocation(Arg.getTemplateNameLoc(), Record); AddSourceLocation(Arg.getTemplateNameLoc());
break; break;
case TemplateArgument::TemplateExpansion: case TemplateArgument::TemplateExpansion:
AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc(), Record); AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc());
AddSourceLocation(Arg.getTemplateNameLoc(), Record); AddSourceLocation(Arg.getTemplateNameLoc());
AddSourceLocation(Arg.getTemplateEllipsisLoc(), Record); AddSourceLocation(Arg.getTemplateEllipsisLoc());
break; break;
case TemplateArgument::Null: case TemplateArgument::Null:
case TemplateArgument::Integral: case TemplateArgument::Integral:
@ -4931,35 +4932,32 @@ void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
} }
} }
void ASTWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, void ASTRecordWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg) {
RecordDataImpl &Record) { AddTemplateArgument(Arg.getArgument());
AddTemplateArgument(Arg.getArgument(), Record);
if (Arg.getArgument().getKind() == TemplateArgument::Expression) { if (Arg.getArgument().getKind() == TemplateArgument::Expression) {
bool InfoHasSameExpr bool InfoHasSameExpr
= Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr(); = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr();
Record.push_back(InfoHasSameExpr); Record->push_back(InfoHasSameExpr);
if (InfoHasSameExpr) if (InfoHasSameExpr)
return; // Avoid storing the same expr twice. return; // Avoid storing the same expr twice.
} }
AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo(), AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo());
Record);
} }
void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, void ASTRecordWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo) {
RecordDataImpl &Record) {
if (!TInfo) { if (!TInfo) {
AddTypeRef(QualType(), Record); AddTypeRef(QualType());
return; return;
} }
AddTypeLoc(TInfo->getTypeLoc(), Record); AddTypeLoc(TInfo->getTypeLoc());
} }
void ASTWriter::AddTypeLoc(TypeLoc TL, RecordDataImpl &Record) { void ASTRecordWriter::AddTypeLoc(TypeLoc TL) {
AddTypeRef(TL.getType(), Record); AddTypeRef(TL.getType());
TypeLocWriter TLW(*this, Record); TypeLocWriter TLW(*this);
for (; !TL.isNull(); TL = TL.getNextTypeLoc()) for (; !TL.isNull(); TL = TL.getNextTypeLoc())
TLW.Visit(TL); TLW.Visit(TL);
} }
@ -5149,28 +5147,25 @@ unsigned ASTWriter::getAnonymousDeclarationNumber(const NamedDecl *D) {
return It->second; return It->second;
} }
void ASTWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, void ASTRecordWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
DeclarationName Name, RecordDataImpl &Record) { DeclarationName Name) {
switch (Name.getNameKind()) { switch (Name.getNameKind()) {
case DeclarationName::CXXConstructorName: case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName: case DeclarationName::CXXDestructorName:
case DeclarationName::CXXConversionFunctionName: case DeclarationName::CXXConversionFunctionName:
AddTypeSourceInfo(DNLoc.NamedType.TInfo, Record); AddTypeSourceInfo(DNLoc.NamedType.TInfo);
break; break;
case DeclarationName::CXXOperatorName: case DeclarationName::CXXOperatorName:
AddSourceLocation(SourceLocation::getFromRawEncoding(
DNLoc.CXXOperatorName.BeginOpNameLoc));
AddSourceLocation( AddSourceLocation(
SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.BeginOpNameLoc), SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.EndOpNameLoc));
Record);
AddSourceLocation(
SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.EndOpNameLoc),
Record);
break; break;
case DeclarationName::CXXLiteralOperatorName: case DeclarationName::CXXLiteralOperatorName:
AddSourceLocation( AddSourceLocation(SourceLocation::getFromRawEncoding(
SourceLocation::getFromRawEncoding(DNLoc.CXXLiteralOperatorName.OpNameLoc), DNLoc.CXXLiteralOperatorName.OpNameLoc));
Record);
break; break;
case DeclarationName::Identifier: case DeclarationName::Identifier:
@ -5182,19 +5177,18 @@ void ASTWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
} }
} }
void ASTWriter::AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo, void ASTRecordWriter::AddDeclarationNameInfo(
RecordDataImpl &Record) { const DeclarationNameInfo &NameInfo) {
AddDeclarationName(NameInfo.getName(), Record); AddDeclarationName(NameInfo.getName());
AddSourceLocation(NameInfo.getLoc(), Record); AddSourceLocation(NameInfo.getLoc());
AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName(), Record); AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName());
} }
void ASTWriter::AddQualifierInfo(const QualifierInfo &Info, void ASTRecordWriter::AddQualifierInfo(const QualifierInfo &Info) {
RecordDataImpl &Record) { AddNestedNameSpecifierLoc(Info.QualifierLoc);
AddNestedNameSpecifierLoc(Info.QualifierLoc, Record); Record->push_back(Info.NumTemplParamLists);
Record.push_back(Info.NumTemplParamLists);
for (unsigned i=0, e=Info.NumTemplParamLists; i != e; ++i) for (unsigned i=0, e=Info.NumTemplParamLists; i != e; ++i)
AddTemplateParameterList(Info.TemplParamLists[i], Record); AddTemplateParameterList(Info.TemplParamLists[i]);
} }
void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS, void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,
@ -5244,8 +5238,7 @@ void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,
} }
} }
void ASTWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, void ASTRecordWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
RecordDataImpl &Record) {
// Nested name specifiers usually aren't too long. I think that 8 would // Nested name specifiers usually aren't too long. I think that 8 would
// typically accommodate the vast majority. // typically accommodate the vast majority.
SmallVector<NestedNameSpecifierLoc , 8> NestedNames; SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
@ -5257,137 +5250,136 @@ void ASTWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
NNS = NNS.getPrefix(); NNS = NNS.getPrefix();
} }
Record.push_back(NestedNames.size()); Record->push_back(NestedNames.size());
while(!NestedNames.empty()) { while(!NestedNames.empty()) {
NNS = NestedNames.pop_back_val(); NNS = NestedNames.pop_back_val();
NestedNameSpecifier::SpecifierKind Kind NestedNameSpecifier::SpecifierKind Kind
= NNS.getNestedNameSpecifier()->getKind(); = NNS.getNestedNameSpecifier()->getKind();
Record.push_back(Kind); Record->push_back(Kind);
switch (Kind) { switch (Kind) {
case NestedNameSpecifier::Identifier: case NestedNameSpecifier::Identifier:
AddIdentifierRef(NNS.getNestedNameSpecifier()->getAsIdentifier(), Record); AddIdentifierRef(NNS.getNestedNameSpecifier()->getAsIdentifier());
AddSourceRange(NNS.getLocalSourceRange(), Record); AddSourceRange(NNS.getLocalSourceRange());
break; break;
case NestedNameSpecifier::Namespace: case NestedNameSpecifier::Namespace:
AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespace(), Record); AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespace());
AddSourceRange(NNS.getLocalSourceRange(), Record); AddSourceRange(NNS.getLocalSourceRange());
break; break;
case NestedNameSpecifier::NamespaceAlias: case NestedNameSpecifier::NamespaceAlias:
AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), Record); AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias());
AddSourceRange(NNS.getLocalSourceRange(), Record); AddSourceRange(NNS.getLocalSourceRange());
break; break;
case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: case NestedNameSpecifier::TypeSpecWithTemplate:
Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate); Record->push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
AddTypeLoc(NNS.getTypeLoc(), Record); AddTypeLoc(NNS.getTypeLoc());
AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record); AddSourceLocation(NNS.getLocalSourceRange().getEnd());
break; break;
case NestedNameSpecifier::Global: case NestedNameSpecifier::Global:
AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record); AddSourceLocation(NNS.getLocalSourceRange().getEnd());
break; break;
case NestedNameSpecifier::Super: case NestedNameSpecifier::Super:
AddDeclRef(NNS.getNestedNameSpecifier()->getAsRecordDecl(), Record); AddDeclRef(NNS.getNestedNameSpecifier()->getAsRecordDecl());
AddSourceRange(NNS.getLocalSourceRange(), Record); AddSourceRange(NNS.getLocalSourceRange());
break; break;
} }
} }
} }
void ASTWriter::AddTemplateName(TemplateName Name, RecordDataImpl &Record) { void ASTRecordWriter::AddTemplateName(TemplateName Name) {
TemplateName::NameKind Kind = Name.getKind(); TemplateName::NameKind Kind = Name.getKind();
Record.push_back(Kind); Record->push_back(Kind);
switch (Kind) { switch (Kind) {
case TemplateName::Template: case TemplateName::Template:
AddDeclRef(Name.getAsTemplateDecl(), Record); AddDeclRef(Name.getAsTemplateDecl());
break; break;
case TemplateName::OverloadedTemplate: { case TemplateName::OverloadedTemplate: {
OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate(); OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate();
Record.push_back(OvT->size()); Record->push_back(OvT->size());
for (const auto &I : *OvT) for (const auto &I : *OvT)
AddDeclRef(I, Record); AddDeclRef(I);
break; break;
} }
case TemplateName::QualifiedTemplate: { case TemplateName::QualifiedTemplate: {
QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName(); QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName();
AddNestedNameSpecifier(QualT->getQualifier(), Record); AddNestedNameSpecifier(QualT->getQualifier());
Record.push_back(QualT->hasTemplateKeyword()); Record->push_back(QualT->hasTemplateKeyword());
AddDeclRef(QualT->getTemplateDecl(), Record); AddDeclRef(QualT->getTemplateDecl());
break; break;
} }
case TemplateName::DependentTemplate: { case TemplateName::DependentTemplate: {
DependentTemplateName *DepT = Name.getAsDependentTemplateName(); DependentTemplateName *DepT = Name.getAsDependentTemplateName();
AddNestedNameSpecifier(DepT->getQualifier(), Record); AddNestedNameSpecifier(DepT->getQualifier());
Record.push_back(DepT->isIdentifier()); Record->push_back(DepT->isIdentifier());
if (DepT->isIdentifier()) if (DepT->isIdentifier())
AddIdentifierRef(DepT->getIdentifier(), Record); AddIdentifierRef(DepT->getIdentifier());
else else
Record.push_back(DepT->getOperator()); Record->push_back(DepT->getOperator());
break; break;
} }
case TemplateName::SubstTemplateTemplateParm: { case TemplateName::SubstTemplateTemplateParm: {
SubstTemplateTemplateParmStorage *subst SubstTemplateTemplateParmStorage *subst
= Name.getAsSubstTemplateTemplateParm(); = Name.getAsSubstTemplateTemplateParm();
AddDeclRef(subst->getParameter(), Record); AddDeclRef(subst->getParameter());
AddTemplateName(subst->getReplacement(), Record); AddTemplateName(subst->getReplacement());
break; break;
} }
case TemplateName::SubstTemplateTemplateParmPack: { case TemplateName::SubstTemplateTemplateParmPack: {
SubstTemplateTemplateParmPackStorage *SubstPack SubstTemplateTemplateParmPackStorage *SubstPack
= Name.getAsSubstTemplateTemplateParmPack(); = Name.getAsSubstTemplateTemplateParmPack();
AddDeclRef(SubstPack->getParameterPack(), Record); AddDeclRef(SubstPack->getParameterPack());
AddTemplateArgument(SubstPack->getArgumentPack(), Record); AddTemplateArgument(SubstPack->getArgumentPack());
break; break;
} }
} }
} }
void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, void ASTRecordWriter::AddTemplateArgument(const TemplateArgument &Arg) {
RecordDataImpl &Record) { Record->push_back(Arg.getKind());
Record.push_back(Arg.getKind());
switch (Arg.getKind()) { switch (Arg.getKind()) {
case TemplateArgument::Null: case TemplateArgument::Null:
break; break;
case TemplateArgument::Type: case TemplateArgument::Type:
AddTypeRef(Arg.getAsType(), Record); AddTypeRef(Arg.getAsType());
break; break;
case TemplateArgument::Declaration: case TemplateArgument::Declaration:
AddDeclRef(Arg.getAsDecl(), Record); AddDeclRef(Arg.getAsDecl());
AddTypeRef(Arg.getParamTypeForDecl(), Record); AddTypeRef(Arg.getParamTypeForDecl());
break; break;
case TemplateArgument::NullPtr: case TemplateArgument::NullPtr:
AddTypeRef(Arg.getNullPtrType(), Record); AddTypeRef(Arg.getNullPtrType());
break; break;
case TemplateArgument::Integral: case TemplateArgument::Integral:
AddAPSInt(Arg.getAsIntegral(), Record); AddAPSInt(Arg.getAsIntegral());
AddTypeRef(Arg.getIntegralType(), Record); AddTypeRef(Arg.getIntegralType());
break; break;
case TemplateArgument::Template: case TemplateArgument::Template:
AddTemplateName(Arg.getAsTemplateOrTemplatePattern(), Record); AddTemplateName(Arg.getAsTemplateOrTemplatePattern());
break; break;
case TemplateArgument::TemplateExpansion: case TemplateArgument::TemplateExpansion:
AddTemplateName(Arg.getAsTemplateOrTemplatePattern(), Record); AddTemplateName(Arg.getAsTemplateOrTemplatePattern());
if (Optional<unsigned> NumExpansions = Arg.getNumTemplateExpansions()) if (Optional<unsigned> NumExpansions = Arg.getNumTemplateExpansions())
Record.push_back(*NumExpansions + 1); Record->push_back(*NumExpansions + 1);
else else
Record.push_back(0); Record->push_back(0);
break; break;
case TemplateArgument::Expression: case TemplateArgument::Expression:
AddStmt(Arg.getAsExpr()); AddStmt(Arg.getAsExpr());
break; break;
case TemplateArgument::Pack: case TemplateArgument::Pack:
Record.push_back(Arg.pack_size()); Record->push_back(Arg.pack_size());
for (const auto &P : Arg.pack_elements()) for (const auto &P : Arg.pack_elements())
AddTemplateArgument(P, Record); AddTemplateArgument(P);
break; break;
} }
} }
@ -5405,25 +5397,23 @@ ASTWriter::AddTemplateParameterList(const TemplateParameterList *TemplateParams,
} }
/// \brief Emit a template argument list. /// \brief Emit a template argument list.
void void ASTRecordWriter::AddTemplateArgumentList(
ASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, const TemplateArgumentList *TemplateArgs) {
RecordDataImpl &Record) {
assert(TemplateArgs && "No TemplateArgs!"); assert(TemplateArgs && "No TemplateArgs!");
Record.push_back(TemplateArgs->size()); Record->push_back(TemplateArgs->size());
for (int i=0, e = TemplateArgs->size(); i != e; ++i) for (int i=0, e = TemplateArgs->size(); i != e; ++i)
AddTemplateArgument(TemplateArgs->get(i), Record); AddTemplateArgument(TemplateArgs->get(i));
} }
void void ASTRecordWriter::AddASTTemplateArgumentListInfo(
ASTWriter::AddASTTemplateArgumentListInfo const ASTTemplateArgumentListInfo *ASTTemplArgList) {
(const ASTTemplateArgumentListInfo *ASTTemplArgList, RecordDataImpl &Record) {
assert(ASTTemplArgList && "No ASTTemplArgList!"); assert(ASTTemplArgList && "No ASTTemplArgList!");
AddSourceLocation(ASTTemplArgList->LAngleLoc, Record); AddSourceLocation(ASTTemplArgList->LAngleLoc);
AddSourceLocation(ASTTemplArgList->RAngleLoc, Record); AddSourceLocation(ASTTemplArgList->RAngleLoc);
Record.push_back(ASTTemplArgList->NumTemplateArgs); Record->push_back(ASTTemplArgList->NumTemplateArgs);
const TemplateArgumentLoc *TemplArgs = ASTTemplArgList->getTemplateArgs(); const TemplateArgumentLoc *TemplArgs = ASTTemplArgList->getTemplateArgs();
for (int i=0, e = ASTTemplArgList->NumTemplateArgs; i != e; ++i) for (int i=0, e = ASTTemplArgList->NumTemplateArgs; i != e; ++i)
AddTemplateArgumentLoc(TemplArgs[i], Record); AddTemplateArgumentLoc(TemplArgs[i]);
} }
void void
@ -5436,17 +5426,16 @@ ASTWriter::AddUnresolvedSet(const ASTUnresolvedSet &Set, RecordDataImpl &Record)
} }
} }
void ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, // FIXME: Move this out of the main ASTRecordWriter interface.
RecordDataImpl &Record) { void ASTRecordWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
Record.push_back(Base.isVirtual()); Record->push_back(Base.isVirtual());
Record.push_back(Base.isBaseOfClass()); Record->push_back(Base.isBaseOfClass());
Record.push_back(Base.getAccessSpecifierAsWritten()); Record->push_back(Base.getAccessSpecifierAsWritten());
Record.push_back(Base.getInheritConstructors()); Record->push_back(Base.getInheritConstructors());
AddTypeSourceInfo(Base.getTypeSourceInfo(), Record); AddTypeSourceInfo(Base.getTypeSourceInfo());
AddSourceRange(Base.getSourceRange(), Record); AddSourceRange(Base.getSourceRange());
AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc() AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc()
: SourceLocation(), : SourceLocation());
Record);
} }
void ASTWriter::FlushCXXBaseSpecifiers() { void ASTWriter::FlushCXXBaseSpecifiers() {
@ -5454,26 +5443,30 @@ void ASTWriter::FlushCXXBaseSpecifiers() {
unsigned N = CXXBaseSpecifiersToWrite.size(); unsigned N = CXXBaseSpecifiersToWrite.size();
for (unsigned I = 0; I != N; ++I) { for (unsigned I = 0; I != N; ++I) {
Record.clear(); Record.clear();
// Record the offset of this base-specifier set.
unsigned Index = CXXBaseSpecifiersToWrite[I].ID - 1;
if (Index == CXXBaseSpecifiersOffsets.size())
CXXBaseSpecifiersOffsets.push_back(Stream.GetCurrentBitNo());
else {
if (Index > CXXBaseSpecifiersOffsets.size())
CXXBaseSpecifiersOffsets.resize(Index + 1);
CXXBaseSpecifiersOffsets[Index] = Stream.GetCurrentBitNo();
}
const CXXBaseSpecifier *B = CXXBaseSpecifiersToWrite[I].Bases, const CXXBaseSpecifier *B = CXXBaseSpecifiersToWrite[I].Bases,
*BEnd = CXXBaseSpecifiersToWrite[I].BasesEnd; *BEnd = CXXBaseSpecifiersToWrite[I].BasesEnd;
Record.push_back(BEnd - B);
// Write the base specifier set.
ASTRecordWriter Writer(*this, Record);
Writer.push_back(BEnd - B);
for (; B != BEnd; ++B) for (; B != BEnd; ++B)
AddCXXBaseSpecifier(*B, Record); Writer.AddCXXBaseSpecifier(*B);
Stream.EmitRecord(serialization::DECL_CXX_BASE_SPECIFIERS, Record); uint64_t Offset = Writer.Emit(serialization::DECL_CXX_BASE_SPECIFIERS);
// Flush any expressions that were written as part of the base specifiers. // Record the offset of this base-specifier set.
FlushStmts(); //
// FIXME: We don't need an indirect lookup table for these; instead, write
// the base specifier record prior to the decl record and store its offset
// from the decl record rather than its ID.
unsigned Index = CXXBaseSpecifiersToWrite[I].ID - 1;
if (Index == CXXBaseSpecifiersOffsets.size())
CXXBaseSpecifiersOffsets.push_back(Offset);
else {
if (Index > CXXBaseSpecifiersOffsets.size())
CXXBaseSpecifiersOffsets.resize(Index + 1);
CXXBaseSpecifiersOffsets[Index] = Offset;
}
} }
assert(N == CXXBaseSpecifiersToWrite.size() && assert(N == CXXBaseSpecifiersToWrite.size() &&
@ -5481,40 +5474,40 @@ void ASTWriter::FlushCXXBaseSpecifiers() {
CXXBaseSpecifiersToWrite.clear(); CXXBaseSpecifiersToWrite.clear();
} }
void ASTWriter::AddCXXCtorInitializers( // FIXME: Move this out of the main ASTRecordWriter interface.
const CXXCtorInitializer * const *CtorInitializers, void ASTRecordWriter::AddCXXCtorInitializers(
unsigned NumCtorInitializers, const CXXCtorInitializer *const *CtorInitializers,
RecordDataImpl &Record) { unsigned NumCtorInitializers) {
Record.push_back(NumCtorInitializers); Record->push_back(NumCtorInitializers);
for (unsigned i=0; i != NumCtorInitializers; ++i) { for (unsigned i=0; i != NumCtorInitializers; ++i) {
const CXXCtorInitializer *Init = CtorInitializers[i]; const CXXCtorInitializer *Init = CtorInitializers[i];
if (Init->isBaseInitializer()) { if (Init->isBaseInitializer()) {
Record.push_back(CTOR_INITIALIZER_BASE); Record->push_back(CTOR_INITIALIZER_BASE);
AddTypeSourceInfo(Init->getTypeSourceInfo(), Record); AddTypeSourceInfo(Init->getTypeSourceInfo());
Record.push_back(Init->isBaseVirtual()); Record->push_back(Init->isBaseVirtual());
} else if (Init->isDelegatingInitializer()) { } else if (Init->isDelegatingInitializer()) {
Record.push_back(CTOR_INITIALIZER_DELEGATING); Record->push_back(CTOR_INITIALIZER_DELEGATING);
AddTypeSourceInfo(Init->getTypeSourceInfo(), Record); AddTypeSourceInfo(Init->getTypeSourceInfo());
} else if (Init->isMemberInitializer()){ } else if (Init->isMemberInitializer()){
Record.push_back(CTOR_INITIALIZER_MEMBER); Record->push_back(CTOR_INITIALIZER_MEMBER);
AddDeclRef(Init->getMember(), Record); AddDeclRef(Init->getMember());
} else { } else {
Record.push_back(CTOR_INITIALIZER_INDIRECT_MEMBER); Record->push_back(CTOR_INITIALIZER_INDIRECT_MEMBER);
AddDeclRef(Init->getIndirectMember(), Record); AddDeclRef(Init->getIndirectMember());
} }
AddSourceLocation(Init->getMemberLocation(), Record); AddSourceLocation(Init->getMemberLocation());
AddStmt(Init->getInit()); AddStmt(Init->getInit());
AddSourceLocation(Init->getLParenLoc(), Record); AddSourceLocation(Init->getLParenLoc());
AddSourceLocation(Init->getRParenLoc(), Record); AddSourceLocation(Init->getRParenLoc());
Record.push_back(Init->isWritten()); Record->push_back(Init->isWritten());
if (Init->isWritten()) { if (Init->isWritten()) {
Record.push_back(Init->getSourceOrder()); Record->push_back(Init->getSourceOrder());
} else { } else {
Record.push_back(Init->getNumArrayIndices()); Record->push_back(Init->getNumArrayIndices());
for (unsigned i=0, e=Init->getNumArrayIndices(); i != e; ++i) for (unsigned i=0, e=Init->getNumArrayIndices(); i != e; ++i)
AddDeclRef(Init->getArrayIndex(i), Record); AddDeclRef(Init->getArrayIndex(i));
} }
} }
} }
@ -5527,21 +5520,19 @@ void ASTWriter::FlushCXXCtorInitializers() {
for (auto &Init : CXXCtorInitializersToWrite) { for (auto &Init : CXXCtorInitializersToWrite) {
Record.clear(); Record.clear();
ASTRecordWriter Writer(*this, Record);
Writer.AddCXXCtorInitializers(Init.Inits.data(), Init.Inits.size());
uint64_t Offset = Writer.Emit(serialization::DECL_CXX_CTOR_INITIALIZERS);
// Record the offset of this mem-initializer list. // Record the offset of this mem-initializer list.
unsigned Index = Init.ID - 1; unsigned Index = Init.ID - 1;
if (Index == CXXCtorInitializersOffsets.size()) if (Index == CXXCtorInitializersOffsets.size())
CXXCtorInitializersOffsets.push_back(Stream.GetCurrentBitNo()); CXXCtorInitializersOffsets.push_back(Offset);
else { else {
if (Index > CXXCtorInitializersOffsets.size()) if (Index > CXXCtorInitializersOffsets.size())
CXXCtorInitializersOffsets.resize(Index + 1); CXXCtorInitializersOffsets.resize(Index + 1);
CXXCtorInitializersOffsets[Index] = Stream.GetCurrentBitNo(); CXXCtorInitializersOffsets[Index] = Offset;
} }
AddCXXCtorInitializers(Init.Inits.data(), Init.Inits.size(), Record);
Stream.EmitRecord(serialization::DECL_CXX_CTOR_INITIALIZERS, Record);
// Flush any expressions that were written as part of the initializers.
FlushStmts();
} }
assert(N == CXXCtorInitializersToWrite.size() && assert(N == CXXCtorInitializersToWrite.size() &&
@ -5549,82 +5540,81 @@ void ASTWriter::FlushCXXCtorInitializers() {
CXXCtorInitializersToWrite.clear(); CXXCtorInitializersToWrite.clear();
} }
void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) { void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
auto &Data = D->data(); auto &Data = D->data();
Record.push_back(Data.IsLambda); Record->push_back(Data.IsLambda);
Record.push_back(Data.UserDeclaredConstructor); Record->push_back(Data.UserDeclaredConstructor);
Record.push_back(Data.UserDeclaredSpecialMembers); Record->push_back(Data.UserDeclaredSpecialMembers);
Record.push_back(Data.Aggregate); Record->push_back(Data.Aggregate);
Record.push_back(Data.PlainOldData); Record->push_back(Data.PlainOldData);
Record.push_back(Data.Empty); Record->push_back(Data.Empty);
Record.push_back(Data.Polymorphic); Record->push_back(Data.Polymorphic);
Record.push_back(Data.Abstract); Record->push_back(Data.Abstract);
Record.push_back(Data.IsStandardLayout); Record->push_back(Data.IsStandardLayout);
Record.push_back(Data.HasNoNonEmptyBases); Record->push_back(Data.HasNoNonEmptyBases);
Record.push_back(Data.HasPrivateFields); Record->push_back(Data.HasPrivateFields);
Record.push_back(Data.HasProtectedFields); Record->push_back(Data.HasProtectedFields);
Record.push_back(Data.HasPublicFields); Record->push_back(Data.HasPublicFields);
Record.push_back(Data.HasMutableFields); Record->push_back(Data.HasMutableFields);
Record.push_back(Data.HasVariantMembers); Record->push_back(Data.HasVariantMembers);
Record.push_back(Data.HasOnlyCMembers); Record->push_back(Data.HasOnlyCMembers);
Record.push_back(Data.HasInClassInitializer); Record->push_back(Data.HasInClassInitializer);
Record.push_back(Data.HasUninitializedReferenceMember); Record->push_back(Data.HasUninitializedReferenceMember);
Record.push_back(Data.HasUninitializedFields); Record->push_back(Data.HasUninitializedFields);
Record.push_back(Data.NeedOverloadResolutionForMoveConstructor); Record->push_back(Data.NeedOverloadResolutionForMoveConstructor);
Record.push_back(Data.NeedOverloadResolutionForMoveAssignment); Record->push_back(Data.NeedOverloadResolutionForMoveAssignment);
Record.push_back(Data.NeedOverloadResolutionForDestructor); Record->push_back(Data.NeedOverloadResolutionForDestructor);
Record.push_back(Data.DefaultedMoveConstructorIsDeleted); Record->push_back(Data.DefaultedMoveConstructorIsDeleted);
Record.push_back(Data.DefaultedMoveAssignmentIsDeleted); Record->push_back(Data.DefaultedMoveAssignmentIsDeleted);
Record.push_back(Data.DefaultedDestructorIsDeleted); Record->push_back(Data.DefaultedDestructorIsDeleted);
Record.push_back(Data.HasTrivialSpecialMembers); Record->push_back(Data.HasTrivialSpecialMembers);
Record.push_back(Data.DeclaredNonTrivialSpecialMembers); Record->push_back(Data.DeclaredNonTrivialSpecialMembers);
Record.push_back(Data.HasIrrelevantDestructor); Record->push_back(Data.HasIrrelevantDestructor);
Record.push_back(Data.HasConstexprNonCopyMoveConstructor); Record->push_back(Data.HasConstexprNonCopyMoveConstructor);
Record.push_back(Data.HasDefaultedDefaultConstructor); Record->push_back(Data.HasDefaultedDefaultConstructor);
Record.push_back(Data.DefaultedDefaultConstructorIsConstexpr); Record->push_back(Data.DefaultedDefaultConstructorIsConstexpr);
Record.push_back(Data.HasConstexprDefaultConstructor); Record->push_back(Data.HasConstexprDefaultConstructor);
Record.push_back(Data.HasNonLiteralTypeFieldsOrBases); Record->push_back(Data.HasNonLiteralTypeFieldsOrBases);
Record.push_back(Data.ComputedVisibleConversions); Record->push_back(Data.ComputedVisibleConversions);
Record.push_back(Data.UserProvidedDefaultConstructor); Record->push_back(Data.UserProvidedDefaultConstructor);
Record.push_back(Data.DeclaredSpecialMembers); Record->push_back(Data.DeclaredSpecialMembers);
Record.push_back(Data.ImplicitCopyConstructorHasConstParam); Record->push_back(Data.ImplicitCopyConstructorHasConstParam);
Record.push_back(Data.ImplicitCopyAssignmentHasConstParam); Record->push_back(Data.ImplicitCopyAssignmentHasConstParam);
Record.push_back(Data.HasDeclaredCopyConstructorWithConstParam); Record->push_back(Data.HasDeclaredCopyConstructorWithConstParam);
Record.push_back(Data.HasDeclaredCopyAssignmentWithConstParam); Record->push_back(Data.HasDeclaredCopyAssignmentWithConstParam);
// IsLambda bit is already saved. // IsLambda bit is already saved.
Record.push_back(Data.NumBases); Record->push_back(Data.NumBases);
if (Data.NumBases > 0) if (Data.NumBases > 0)
AddCXXBaseSpecifiersRef(Data.getBases(), Data.getBases() + Data.NumBases, AddCXXBaseSpecifiersRef(Data.getBases(), Data.getBases() + Data.NumBases);
Record);
// FIXME: Make VBases lazily computed when needed to avoid storing them. // FIXME: Make VBases lazily computed when needed to avoid storing them.
Record.push_back(Data.NumVBases); Record->push_back(Data.NumVBases);
if (Data.NumVBases > 0) if (Data.NumVBases > 0)
AddCXXBaseSpecifiersRef(Data.getVBases(), Data.getVBases() + Data.NumVBases, AddCXXBaseSpecifiersRef(Data.getVBases(),
Record); Data.getVBases() + Data.NumVBases);
AddUnresolvedSet(Data.Conversions.get(*Context), Record); AddUnresolvedSet(Data.Conversions.get(*Writer->Context));
AddUnresolvedSet(Data.VisibleConversions.get(*Context), Record); AddUnresolvedSet(Data.VisibleConversions.get(*Writer->Context));
// Data.Definition is the owning decl, no need to write it. // Data.Definition is the owning decl, no need to write it.
AddDeclRef(D->getFirstFriend(), Record); AddDeclRef(D->getFirstFriend());
// Add lambda-specific data. // Add lambda-specific data.
if (Data.IsLambda) { if (Data.IsLambda) {
auto &Lambda = D->getLambdaData(); auto &Lambda = D->getLambdaData();
Record.push_back(Lambda.Dependent); Record->push_back(Lambda.Dependent);
Record.push_back(Lambda.IsGenericLambda); Record->push_back(Lambda.IsGenericLambda);
Record.push_back(Lambda.CaptureDefault); Record->push_back(Lambda.CaptureDefault);
Record.push_back(Lambda.NumCaptures); Record->push_back(Lambda.NumCaptures);
Record.push_back(Lambda.NumExplicitCaptures); Record->push_back(Lambda.NumExplicitCaptures);
Record.push_back(Lambda.ManglingNumber); Record->push_back(Lambda.ManglingNumber);
AddDeclRef(Lambda.ContextDecl, Record); AddDeclRef(Lambda.ContextDecl);
AddTypeSourceInfo(Lambda.MethodTyInfo, Record); AddTypeSourceInfo(Lambda.MethodTyInfo);
for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) { for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
const LambdaCapture &Capture = Lambda.Captures[I]; const LambdaCapture &Capture = Lambda.Captures[I];
AddSourceLocation(Capture.getLocation(), Record); AddSourceLocation(Capture.getLocation());
Record.push_back(Capture.isImplicit()); Record->push_back(Capture.isImplicit());
Record.push_back(Capture.getCaptureKind()); Record->push_back(Capture.getCaptureKind());
switch (Capture.getCaptureKind()) { switch (Capture.getCaptureKind()) {
case LCK_StarThis: case LCK_StarThis:
case LCK_This: case LCK_This:
@ -5634,10 +5624,9 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec
case LCK_ByRef: case LCK_ByRef:
VarDecl *Var = VarDecl *Var =
Capture.capturesVariable() ? Capture.getCapturedVar() : nullptr; Capture.capturesVariable() ? Capture.getCapturedVar() : nullptr;
AddDeclRef(Var, Record); AddDeclRef(Var);
AddSourceLocation(Capture.isPackExpansion() ? Capture.getEllipsisLoc() AddSourceLocation(Capture.isPackExpansion() ? Capture.getEllipsisLoc()
: SourceLocation(), : SourceLocation());
Record);
break; break;
} }
} }

View File

@ -171,17 +171,6 @@ namespace clang {
Record.AddSourceLocation(typeParams->getRAngleLoc()); Record.AddSourceLocation(typeParams->getRAngleLoc());
} }
void AddFunctionDefinition(const FunctionDecl *FD) {
assert(FD->doesThisDeclarationHaveABody());
if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
Record.push_back(CD->NumCtorInitializers);
if (CD->NumCtorInitializers)
Record.AddCXXCtorInitializersRef(
llvm::makeArrayRef(CD->init_begin(), CD->init_end()));
}
Writer.AddStmt(FD->getBody());
}
/// Add to the record the first declaration from each module file that /// Add to the record the first declaration from each module file that
/// provides a declaration of D. The intent is to provide a sufficient /// provides a declaration of D. The intent is to provide a sufficient
/// set such that reloading this set will load all current redeclarations. /// set such that reloading this set will load all current redeclarations.
@ -293,7 +282,7 @@ void ASTDeclWriter::Visit(Decl *D) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Record.push_back(FD->doesThisDeclarationHaveABody()); Record.push_back(FD->doesThisDeclarationHaveABody());
if (FD->doesThisDeclarationHaveABody()) if (FD->doesThisDeclarationHaveABody())
AddFunctionDefinition(FD); Record.AddFunctionDefinition(FD);
} }
} }
@ -508,7 +497,7 @@ void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
VisitValueDecl(D); VisitValueDecl(D);
Record.push_back(D->getInitExpr()? 1 : 0); Record.push_back(D->getInitExpr()? 1 : 0);
if (D->getInitExpr()) if (D->getInitExpr())
Writer.AddStmt(D->getInitExpr()); Record.AddStmt(D->getInitExpr());
Record.AddAPSInt(D->getInitVal()); Record.AddAPSInt(D->getInitVal());
Code = serialization::DECL_ENUM_CONSTANT; Code = serialization::DECL_ENUM_CONSTANT;
@ -629,7 +618,7 @@ void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
D->getSelfDecl() != nullptr || D->getCmdDecl() != nullptr; D->getSelfDecl() != nullptr || D->getCmdDecl() != nullptr;
Record.push_back(HasBodyStuff); Record.push_back(HasBodyStuff);
if (HasBodyStuff) { if (HasBodyStuff) {
Writer.AddStmt(D->getBody()); Record.AddStmt(D->getBody());
Record.AddDeclRef(D->getSelfDecl()); Record.AddDeclRef(D->getSelfDecl());
Record.AddDeclRef(D->getCmdDecl()); Record.AddDeclRef(D->getCmdDecl());
} }
@ -846,8 +835,8 @@ void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
Record.AddDeclRef(D->getPropertyDecl()); Record.AddDeclRef(D->getPropertyDecl());
Record.AddDeclRef(D->getPropertyIvarDecl()); Record.AddDeclRef(D->getPropertyIvarDecl());
Record.AddSourceLocation(D->getPropertyIvarDeclLoc()); Record.AddSourceLocation(D->getPropertyIvarDeclLoc());
Writer.AddStmt(D->getGetterCXXConstructor()); Record.AddStmt(D->getGetterCXXConstructor());
Writer.AddStmt(D->getSetterCXXAssignment()); Record.AddStmt(D->getSetterCXXAssignment());
Code = serialization::DECL_OBJC_PROPERTY_IMPL; Code = serialization::DECL_OBJC_PROPERTY_IMPL;
} }
@ -863,7 +852,7 @@ void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
QualType(static_cast<Type *>(D->InitStorage.getPointer()), 0)); QualType(static_cast<Type *>(D->InitStorage.getPointer()), 0));
} else { } else {
Record.push_back(D->InitStorage.getInt() + 1); Record.push_back(D->InitStorage.getInt() + 1);
Writer.AddStmt(static_cast<Expr *>(D->InitStorage.getPointer())); Record.AddStmt(static_cast<Expr *>(D->InitStorage.getPointer()));
} }
if (!D->getDeclName()) if (!D->getDeclName())
Record.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D)); Record.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D));
@ -922,7 +911,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
if (D->getInit()) { if (D->getInit()) {
Record.push_back(!D->isInitKnownICE() ? 1 : (D->isInitICE() ? 3 : 2)); Record.push_back(!D->isInitKnownICE() ? 1 : (D->isInitICE() ? 3 : 2));
Writer.AddStmt(D->getInit()); Record.AddStmt(D->getInit());
} else { } else {
Record.push_back(0); Record.push_back(0);
} }
@ -984,7 +973,7 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
Record.push_back(D->hasInheritedDefaultArg()); Record.push_back(D->hasInheritedDefaultArg());
Record.push_back(D->hasUninstantiatedDefaultArg()); Record.push_back(D->hasUninstantiatedDefaultArg());
if (D->hasUninstantiatedDefaultArg()) if (D->hasUninstantiatedDefaultArg())
Writer.AddStmt(D->getUninstantiatedDefaultArg()); Record.AddStmt(D->getUninstantiatedDefaultArg());
Code = serialization::DECL_PARM_VAR; Code = serialization::DECL_PARM_VAR;
assert(!D->isARCPseudoStrong()); // can be true of ImplicitParamDecl assert(!D->isARCPseudoStrong()); // can be true of ImplicitParamDecl
@ -1023,7 +1012,7 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
VisitDecl(D); VisitDecl(D);
Writer.AddStmt(D->getAsmString()); Record.AddStmt(D->getAsmString());
Record.AddSourceLocation(D->getRParenLoc()); Record.AddSourceLocation(D->getRParenLoc());
Code = serialization::DECL_FILE_SCOPE_ASM; Code = serialization::DECL_FILE_SCOPE_ASM;
} }
@ -1035,7 +1024,7 @@ void ASTDeclWriter::VisitEmptyDecl(EmptyDecl *D) {
void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) { void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
VisitDecl(D); VisitDecl(D);
Writer.AddStmt(D->getBody()); Record.AddStmt(D->getBody());
Record.AddTypeSourceInfo(D->getSignatureAsWritten()); Record.AddTypeSourceInfo(D->getSignatureAsWritten());
Record.push_back(D->param_size()); Record.push_back(D->param_size());
for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end(); for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
@ -1055,7 +1044,7 @@ void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
if (capture.hasCopyExpr()) flags |= 4; if (capture.hasCopyExpr()) flags |= 4;
Record.push_back(flags); Record.push_back(flags);
if (capture.hasCopyExpr()) Writer.AddStmt(capture.getCopyExpr()); if (capture.hasCopyExpr()) Record.AddStmt(capture.getCopyExpr());
} }
Code = serialization::DECL_BLOCK; Code = serialization::DECL_BLOCK;
@ -1505,7 +1494,7 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
!D->defaultArgumentWasInherited(); !D->defaultArgumentWasInherited();
Record.push_back(OwnsDefaultArg); Record.push_back(OwnsDefaultArg);
if (OwnsDefaultArg) if (OwnsDefaultArg)
Writer.AddStmt(D->getDefaultArgument()); Record.AddStmt(D->getDefaultArgument());
Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM; Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
} }
} }
@ -1546,9 +1535,9 @@ void ASTDeclWriter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) { void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
VisitDecl(D); VisitDecl(D);
Writer.AddStmt(D->getAssertExpr()); Record.AddStmt(D->getAssertExpr());
Record.push_back(D->isFailed()); Record.push_back(D->isFailed());
Writer.AddStmt(D->getMessage()); Record.AddStmt(D->getMessage());
Record.AddSourceLocation(D->getRParenLoc()); Record.AddSourceLocation(D->getRParenLoc());
Code = serialization::DECL_STATIC_ASSERT; Code = serialization::DECL_STATIC_ASSERT;
} }
@ -1661,15 +1650,15 @@ void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
Record.push_back(D->varlist_size()); Record.push_back(D->varlist_size());
VisitDecl(D); VisitDecl(D);
for (auto *I : D->varlists()) for (auto *I : D->varlists())
Writer.AddStmt(I); Record.AddStmt(I);
Code = serialization::DECL_OMP_THREADPRIVATE; Code = serialization::DECL_OMP_THREADPRIVATE;
} }
void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) { void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
VisitValueDecl(D); VisitValueDecl(D);
Record.AddSourceLocation(D->getLocStart()); Record.AddSourceLocation(D->getLocStart());
Writer.AddStmt(D->getCombiner()); Record.AddStmt(D->getCombiner());
Writer.AddStmt(D->getInitializer()); Record.AddStmt(D->getInitializer());
Record.AddDeclRef(D->getPrevDeclInScope()); Record.AddDeclRef(D->getPrevDeclInScope());
Code = serialization::DECL_OMP_DECLARE_REDUCTION; Code = serialization::DECL_OMP_DECLARE_REDUCTION;
} }
@ -2149,9 +2138,6 @@ static bool isRequiredDecl(const Decl *D, ASTContext &Context,
} }
void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
// Switch case IDs are per Decl.
ClearSwitchCaseIDs();
// Determine the ID for this declaration. // Determine the ID for this declaration.
serialization::DeclID ID; serialization::DeclID ID;
assert(!D->isFromASTFile() && "should not be emitting imported decl"); assert(!D->isFromASTFile() && "should not be emitting imported decl");
@ -2210,10 +2196,16 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
EagerlyDeserializedDecls.push_back(ID); EagerlyDeserializedDecls.push_back(ID);
} }
void ASTWriter::AddFunctionDefinition(const FunctionDecl *FD, void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
RecordDataImpl &Record) { // Switch case IDs are per function body.
ClearSwitchCaseIDs(); Writer->ClearSwitchCaseIDs();
ASTDeclWriter W(*this, FD->getASTContext(), Record); assert(FD->doesThisDeclarationHaveABody());
W.AddFunctionDefinition(FD); if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
Record->push_back(CD->getNumCtorInitializers());
if (CD->getNumCtorInitializers())
AddCXXCtorInitializersRef(
llvm::makeArrayRef(CD->init_begin(), CD->init_end()));
}
AddStmt(FD->getBody());
} }

File diff suppressed because it is too large Load Diff

View File

@ -87,16 +87,13 @@ static std::string ReadPCHRecord(StringRef type) {
// Assumes that the way to get the value is SA->getname() // Assumes that the way to get the value is SA->getname()
static std::string WritePCHRecord(StringRef type, StringRef name) { static std::string WritePCHRecord(StringRef type, StringRef name) {
return StringSwitch<std::string>(type) return "Record." + StringSwitch<std::string>(type)
.EndsWith("Decl *", "AddDeclRef(" + std::string(name) + .EndsWith("Decl *", "AddDeclRef(" + std::string(name) + ");\n")
", Record);\n") .Case("TypeSourceInfo *", "AddTypeSourceInfo(" + std::string(name) + ");\n")
.Case("TypeSourceInfo *",
"AddTypeSourceInfo(" + std::string(name) + ", Record);\n")
.Case("Expr *", "AddStmt(" + std::string(name) + ");\n") .Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
.Case("IdentifierInfo *", .Case("IdentifierInfo *", "AddIdentifierRef(" + std::string(name) + ");\n")
"AddIdentifierRef(" + std::string(name) + ", Record);\n") .Case("StringRef", "AddString(" + std::string(name) + ");\n")
.Case("StringRef", "AddString(" + std::string(name) + ", Record);\n") .Default("push_back(" + std::string(name) + ");\n");
.Default("Record.push_back(" + std::string(name) + ");\n");
} }
// Normalize attribute name by removing leading and trailing // Normalize attribute name by removing leading and trailing
@ -371,7 +368,7 @@ namespace {
OS << getLowerName(); OS << getLowerName();
} }
void writePCHWrite(raw_ostream &OS) const override { void writePCHWrite(raw_ostream &OS) const override {
OS << " AddString(SA->get" << getUpperName() << "(), Record);\n"; OS << " Record.AddString(SA->get" << getUpperName() << "());\n";
} }
void writeValue(raw_ostream &OS) const override { void writeValue(raw_ostream &OS) const override {
OS << "\\\"\" << get" << getUpperName() << "() << \"\\\""; OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
@ -487,10 +484,10 @@ namespace {
void writePCHWrite(raw_ostream &OS) const override { void writePCHWrite(raw_ostream &OS) const override {
OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n"; OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n";
OS << " if (SA->is" << getUpperName() << "Expr())\n"; OS << " if (SA->is" << getUpperName() << "Expr())\n";
OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n"; OS << " Record.AddStmt(SA->get" << getUpperName() << "Expr());\n";
OS << " else\n"; OS << " else\n";
OS << " AddTypeSourceInfo(SA->get" << getUpperName() OS << " Record.AddTypeSourceInfo(SA->get" << getUpperName()
<< "Type(), Record);\n"; << "Type());\n";
} }
void writeValue(raw_ostream &OS) const override { void writeValue(raw_ostream &OS) const override {
OS << "\";\n"; OS << "\";\n";
@ -887,7 +884,7 @@ namespace {
OS << getLowerName(); OS << getLowerName();
} }
void writePCHWrite(raw_ostream &OS) const override { void writePCHWrite(raw_ostream &OS) const override {
OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n"; OS << " Record.AddVersionTuple(SA->get" << getUpperName() << "());\n";
} }
void writeValue(raw_ostream &OS) const override { void writeValue(raw_ostream &OS) const override {
OS << getLowerName() << "=\" << get" << getUpperName() << "() << \""; OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";