summaryrefslogtreecommitdiff
path: root/include/clang/Serialization/ASTWriter.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Serialization/ASTWriter.h')
-rw-r--r--include/clang/Serialization/ASTWriter.h448
1 files changed, 236 insertions, 212 deletions
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index ef8c65341388..bfdb9f2262b5 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -90,6 +90,8 @@ public:
friend class ASTDeclWriter;
friend class ASTStmtWriter;
+ friend class ASTTypeWriter;
+ friend class ASTRecordWriter;
private:
/// \brief Map that provides the ID numbers of each type within the
/// output stream, plus those deserialized from a chained PCH.
@@ -382,25 +384,6 @@ private:
/// should serialize.
llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories;
- struct ReplacedDeclInfo {
- serialization::DeclID ID;
- uint64_t Offset;
- unsigned Loc;
-
- ReplacedDeclInfo() : ID(0), Offset(0), Loc(0) {}
- ReplacedDeclInfo(serialization::DeclID ID, uint64_t Offset,
- SourceLocation Loc)
- : ID(ID), Offset(Offset), Loc(Loc.getRawEncoding()) {}
- };
-
- /// \brief Decls that have been replaced in the current dependent AST file.
- ///
- /// When a decl changes fundamentally after being deserialized (this shouldn't
- /// happen, but the ObjC AST nodes are designed this way), it will be
- /// serialized again. In this case, it is registered here, so that the reader
- /// knows to read the updated version.
- SmallVector<ReplacedDeclInfo, 16> ReplacedDecls;
-
/// \brief The set of declarations that may have redeclaration chains that
/// need to be serialized.
llvm::SmallVector<const Decl *, 16> Redeclarations;
@@ -409,14 +392,6 @@ private:
/// redeclaration chains.
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.
llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs;
@@ -434,62 +409,6 @@ private:
/// file.
unsigned NumVisibleDeclContexts;
- /// \brief The offset of each CXXBaseSpecifier set within the AST.
- SmallVector<uint32_t, 16> CXXBaseSpecifiersOffsets;
-
- /// \brief The first ID number we can use for our own base specifiers.
- serialization::CXXBaseSpecifiersID FirstCXXBaseSpecifiersID;
-
- /// \brief The base specifiers ID that will be assigned to the next new
- /// set of C++ base specifiers.
- serialization::CXXBaseSpecifiersID NextCXXBaseSpecifiersID;
-
- /// \brief A set of C++ base specifiers that is queued to be written into the
- /// AST file.
- struct QueuedCXXBaseSpecifiers {
- QueuedCXXBaseSpecifiers() : ID(), Bases(), BasesEnd() { }
-
- QueuedCXXBaseSpecifiers(serialization::CXXBaseSpecifiersID ID,
- CXXBaseSpecifier const *Bases,
- CXXBaseSpecifier const *BasesEnd)
- : ID(ID), Bases(Bases), BasesEnd(BasesEnd) { }
-
- serialization::CXXBaseSpecifiersID ID;
- CXXBaseSpecifier const * Bases;
- CXXBaseSpecifier const * BasesEnd;
- };
-
- /// \brief Queue of C++ base specifiers to be written to the AST file,
- /// in the order they should be written.
- SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite;
-
- /// \brief The offset of each CXXCtorInitializer list within the AST.
- SmallVector<uint32_t, 16> CXXCtorInitializersOffsets;
-
- /// \brief The first ID number we can use for our own ctor initializers.
- serialization::CXXCtorInitializersID FirstCXXCtorInitializersID;
-
- /// \brief The ctor initializers ID that will be assigned to the next new
- /// list of C++ ctor initializers.
- serialization::CXXCtorInitializersID NextCXXCtorInitializersID;
-
- /// \brief A set of C++ ctor initializers that is queued to be written
- /// into the AST file.
- struct QueuedCXXCtorInitializers {
- QueuedCXXCtorInitializers() : ID() {}
-
- QueuedCXXCtorInitializers(serialization::CXXCtorInitializersID ID,
- ArrayRef<CXXCtorInitializer*> Inits)
- : ID(ID), Inits(Inits) {}
-
- serialization::CXXCtorInitializersID ID;
- ArrayRef<CXXCtorInitializer*> Inits;
- };
-
- /// \brief Queue of C++ ctor initializers to be written to the AST file,
- /// in the order they should be written.
- SmallVector<QueuedCXXCtorInitializers, 2> CXXCtorInitializersToWrite;
-
/// \brief A mapping from each known submodule to its ID number, which will
/// be a positive integer.
llvm::DenseMap<Module *, unsigned> SubmoduleIDs;
@@ -502,9 +421,7 @@ private:
unsigned getSubmoduleID(Module *Mod);
/// \brief Write the given subexpression to the bitstream.
- void WriteSubStmt(Stmt *S,
- llvm::DenseMap<Stmt *, uint64_t> &SubStmtEntries,
- llvm::DenseSet<Stmt *> &ParentStmts);
+ void WriteSubStmt(Stmt *S);
void WriteBlockInfoBlock();
uint64_t WriteControlBlock(Preprocessor &PP, ASTContext &Context,
@@ -520,8 +437,6 @@ private:
void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
bool isModule);
- void WriteCXXBaseSpecifiersOffsets();
- void WriteCXXCtorInitializersOffsets();
unsigned TypeExtQualAbbrev;
unsigned TypeFunctionProtoAbbrev;
@@ -542,15 +457,15 @@ private:
void WriteReferencedSelectorsPool(Sema &SemaRef);
void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
bool IsModule);
- void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
- void WriteDeclReplacementsBlock();
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
void WriteFPPragmaOptions(const FPOptions &Opts);
void WriteOpenCLExtensions(Sema &SemaRef);
void WriteObjCCategories();
void WriteLateParsedTemplates(Sema &SemaRef);
void WriteOptimizePragmaOptions(Sema &SemaRef);
+ void WriteMSStructPragmaOptions(Sema &SemaRef);
+ void WriteMSPointersToMembersPragmaOptions(Sema &SemaRef);
void WriteModuleFileExtension(Sema &SemaRef,
ModuleFileExtensionWriter &Writer);
@@ -573,7 +488,6 @@ private:
void WriteDeclAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D);
- void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record);
uint64_t WriteASTCore(Sema &SemaRef,
StringRef isysroot, const std::string &OutputFile,
@@ -621,29 +535,9 @@ public:
/// \brief Emit a source range.
void AddSourceRange(SourceRange Range, RecordDataImpl &Record);
- /// \brief Emit an integral value.
- void AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record);
-
- /// \brief Emit a signed integral value.
- void AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record);
-
- /// \brief Emit a floating-point value.
- void AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record);
-
/// \brief Emit a reference to an identifier.
void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record);
- /// \brief Emit a Selector (which is a smart pointer reference).
- void AddSelectorRef(Selector, RecordDataImpl &Record);
-
- /// \brief Emit a CXXTemporary.
- void AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record);
-
- /// \brief Emit a set of C++ base specifiers to the record.
- void AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases,
- CXXBaseSpecifier const *BasesEnd,
- RecordDataImpl &Record);
-
/// \brief Get the unique number used to refer to the given selector.
serialization::SelectorID getSelectorRef(Selector Sel);
@@ -667,30 +561,21 @@ public:
/// \brief Determine the type ID of an already-emitted type.
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
/// decl.
const Decl *getFirstLocalDecl(const Decl *D);
+ /// \brief Is this a local declaration (that is, one that will be written to
+ /// our AST file)? This is the case for declarations that are neither imported
+ /// from another AST file nor predefined.
+ bool IsLocalDecl(const Decl *D) {
+ if (D->isFromASTFile())
+ return false;
+ auto I = DeclIDs.find(D);
+ return (I == DeclIDs.end() ||
+ I->second >= serialization::NUM_PREDEF_DECL_IDS);
+ };
+
/// \brief Emit a reference to a declaration.
void AddDeclRef(const Decl *D, RecordDataImpl &Record);
@@ -702,57 +587,8 @@ public:
/// declaration.
serialization::DeclID getDeclID(const Decl *D);
- /// \brief Emit a declaration name.
- 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);
-
- /// \brief Emit a nested name specifier.
- 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.
- void AddTemplateParameterList(const TemplateParameterList *TemplateParams,
- RecordDataImpl &Record);
-
- /// \brief Emit a template argument list.
- void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
- RecordDataImpl &Record);
-
- /// \brief Emit a UnresolvedSet structure.
- 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
- /// for later serialization.
- void AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> Inits,
- 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.
void AddString(StringRef Str, RecordDataImpl &Record);
@@ -787,38 +623,6 @@ public:
/// within the method pool/selector table.
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
- /// via \c AddCXXBaseSpecifiersRef().
- void FlushCXXBaseSpecifiers();
-
- /// \brief Flush all of the C++ constructor initializer lists that have been
- /// added via \c AddCXXCtorInitializersRef().
- void FlushCXXCtorInitializers();
-
- /// \brief Flush all pending records that are tacked onto the end of
- /// decl and decl update records.
- void FlushPendingAfterDecl() {
- FlushStmts();
- FlushCXXBaseSpecifiers();
- FlushCXXCtorInitializers();
- }
-
/// \brief Record an ID for the given switch-case statement.
unsigned RecordSwitchCaseID(SwitchCase *S);
@@ -851,6 +655,7 @@ public:
bool hasChain() const { return Chain; }
ASTReader *getChain() const { return Chain; }
+private:
// ASTDeserializationListener implementation
void ReaderInitialized(ASTReader *Reader) override;
void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override;
@@ -877,11 +682,230 @@ public:
const ObjCInterfaceDecl *IFD) override;
void DeclarationMarkedUsed(const Decl *D) override;
void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
+ void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
+ const Attr *Attr) override;
void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override;
void AddedAttributeToRecord(const Attr *Attr,
const RecordDecl *Record) override;
};
+/// \brief An object for streaming information to a record.
+class ASTRecordWriter {
+ ASTWriter *Writer;
+ ASTWriter::RecordDataImpl *Record;
+
+ /// \brief Statements that we've encountered while serializing a
+ /// declaration or type.
+ SmallVector<Stmt *, 16> StmtsToEmit;
+
+ /// \brief Indices of record elements that describe offsets within the
+ /// bitcode. These will be converted to offsets relative to the current
+ /// record when emitted.
+ SmallVector<unsigned, 8> OffsetIndices;
+
+ /// \brief Flush all of the statements and expressions that have
+ /// been added to the queue via AddStmt().
+ void FlushStmts();
+ void FlushSubStmts();
+
+ void PrepareToEmit(uint64_t MyOffset) {
+ // Convert offsets into relative form.
+ for (unsigned I : OffsetIndices) {
+ auto &StoredOffset = (*Record)[I];
+ assert(StoredOffset < MyOffset && "invalid offset");
+ if (StoredOffset)
+ StoredOffset = MyOffset - StoredOffset;
+ }
+ OffsetIndices.clear();
+ }
+
+public:
+ /// Construct a ASTRecordWriter that uses the default encoding scheme.
+ ASTRecordWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
+ : Writer(&Writer), Record(&Record) {}
+
+ /// Construct a ASTRecordWriter that uses the same encoding scheme as another
+ /// ASTRecordWriter.
+ ASTRecordWriter(ASTRecordWriter &Parent, ASTWriter::RecordDataImpl &Record)
+ : Writer(Parent.Writer), Record(&Record) {}
+
+ /// Copying an ASTRecordWriter is almost certainly a bug.
+ ASTRecordWriter(const ASTRecordWriter&) = delete;
+ void operator=(const ASTRecordWriter&) = delete;
+
+ /// \brief Extract the underlying record storage.
+ ASTWriter::RecordDataImpl &getRecordData() const { return *Record; }
+
+ /// \brief Minimal vector-like interface.
+ /// @{
+ void push_back(uint64_t N) { Record->push_back(N); }
+ template<typename InputIterator>
+ void append(InputIterator begin, InputIterator end) {
+ Record->append(begin, end);
+ }
+ bool empty() const { return Record->empty(); }
+ size_t size() const { return Record->size(); }
+ uint64_t &operator[](size_t N) { return (*Record)[N]; }
+ /// @}
+
+ /// \brief Emit the record to the stream, followed by its substatements, and
+ /// return its offset.
+ // FIXME: Allow record producers to suggest Abbrevs.
+ uint64_t Emit(unsigned Code, unsigned Abbrev = 0) {
+ uint64_t Offset = Writer->Stream.GetCurrentBitNo();
+ PrepareToEmit(Offset);
+ Writer->Stream.EmitRecord(Code, *Record, Abbrev);
+ FlushStmts();
+ return Offset;
+ }
+
+ /// \brief Emit the record to the stream, preceded by its substatements.
+ uint64_t EmitStmt(unsigned Code, unsigned Abbrev = 0) {
+ FlushSubStmts();
+ PrepareToEmit(Writer->Stream.GetCurrentBitNo());
+ Writer->Stream.EmitRecord(Code, *Record, Abbrev);
+ return Writer->Stream.GetCurrentBitNo();
+ }
+
+ /// \brief Add a bit offset into the record. This will be converted into an
+ /// offset relative to the current record when emitted.
+ void AddOffset(uint64_t BitOffset) {
+ OffsetIndices.push_back(Record->size());
+ Record->push_back(BitOffset);
+ }
+
+ /// \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.
+ void AddSourceLocation(SourceLocation Loc) {
+ return Writer->AddSourceLocation(Loc, *Record);
+ }
+
+ /// \brief Emit a source range.
+ void AddSourceRange(SourceRange Range) {
+ return Writer->AddSourceRange(Range, *Record);
+ }
+
+ /// \brief Emit an integral value.
+ void AddAPInt(const llvm::APInt &Value);
+
+ /// \brief Emit a signed integral value.
+ void AddAPSInt(const llvm::APSInt &Value);
+
+ /// \brief Emit a floating-point value.
+ void AddAPFloat(const llvm::APFloat &Value);
+
+ /// \brief Emit a reference to an identifier.
+ void AddIdentifierRef(const IdentifierInfo *II) {
+ return Writer->AddIdentifierRef(II, *Record);
+ }
+
+ /// \brief Emit a Selector (which is a smart pointer reference).
+ void AddSelectorRef(Selector S);
+
+ /// \brief Emit a CXXTemporary.
+ void AddCXXTemporary(const CXXTemporary *Temp);
+
+ /// \brief Emit a C++ base specifier.
+ void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base);
+
+ /// \brief Emit a set of C++ base specifiers.
+ void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases);
+
+ /// \brief Emit a reference to a type.
+ void AddTypeRef(QualType T) {
+ return Writer->AddTypeRef(T, *Record);
+ }
+
+ /// \brief Emits a reference to a declarator info.
+ void AddTypeSourceInfo(TypeSourceInfo *TInfo);
+
+ /// \brief Emits a type with source-location information.
+ void AddTypeLoc(TypeLoc TL);
+
+ /// \brief Emits a template argument location info.
+ void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+ const TemplateArgumentLocInfo &Arg);
+
+ /// \brief Emits a template argument location.
+ void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg);
+
+ /// \brief Emits an AST template argument list info.
+ void AddASTTemplateArgumentListInfo(
+ const ASTTemplateArgumentListInfo *ASTTemplArgList);
+
+ /// \brief Emit a reference to a declaration.
+ void AddDeclRef(const Decl *D) {
+ return Writer->AddDeclRef(D, *Record);
+ }
+
+ /// \brief Emit a declaration name.
+ void AddDeclarationName(DeclarationName Name);
+
+ void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
+ DeclarationName Name);
+ void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
+
+ void AddQualifierInfo(const QualifierInfo &Info);
+
+ /// \brief Emit a nested name specifier.
+ void AddNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+ /// \brief Emit a nested name specifier with source-location information.
+ void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
+
+ /// \brief Emit a template name.
+ void AddTemplateName(TemplateName Name);
+
+ /// \brief Emit a template argument.
+ void AddTemplateArgument(const TemplateArgument &Arg);
+
+ /// \brief Emit a template parameter list.
+ void AddTemplateParameterList(const TemplateParameterList *TemplateParams);
+
+ /// \brief Emit a template argument list.
+ void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs);
+
+ /// \brief Emit a UnresolvedSet structure.
+ void AddUnresolvedSet(const ASTUnresolvedSet &Set);
+
+ /// \brief Emit a CXXCtorInitializer array.
+ void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer*> CtorInits);
+
+ void AddCXXDefinitionData(const CXXRecordDecl *D);
+
+ /// \brief Emit a string.
+ void AddString(StringRef Str) {
+ return Writer->AddString(Str, *Record);
+ }
+
+ /// \brief Emit a path.
+ void AddPath(StringRef Path) {
+ return Writer->AddPath(Path, *Record);
+ }
+
+ /// \brief Emit a version tuple.
+ void AddVersionTuple(const VersionTuple &Version) {
+ return Writer->AddVersionTuple(Version, *Record);
+ }
+
+ /// \brief Emit a list of attributes.
+ void AddAttributes(ArrayRef<const Attr*> Attrs);
+};
+
/// \brief AST and semantic-analysis consumer that generates a
/// precompiled header from the parsed source code.
class PCHGenerator : public SemaConsumer {