diff options
author | dim <dim@FreeBSD.org> | 2011-02-20 13:06:31 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-20 13:06:31 +0000 |
commit | 39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df (patch) | |
tree | a9243275843fbeaa590afc07ee888e006b8d54ea /include/clang/Serialization/ASTWriter.h | |
parent | 69b4eca4a4255ba43baa5c1d9bbdec3ec17f479e (diff) | |
download | FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.zip FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.tar.gz |
Vendor import of clang trunk r126079:
http://llvm.org/svn/llvm-project/cfe/trunk@126079
Diffstat (limited to 'include/clang/Serialization/ASTWriter.h')
-rw-r--r-- | include/clang/Serialization/ASTWriter.h | 230 |
1 files changed, 163 insertions, 67 deletions
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 426fc47..beb4936 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -17,11 +17,13 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/TemplateBase.h" +#include "clang/AST/ASTMutationListener.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTDeserializationListener.h" #include "clang/Sema/SemaConsumer.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Bitcode/BitstreamWriter.h" #include <map> #include <queue> @@ -36,13 +38,19 @@ namespace llvm { namespace clang { class ASTContext; +class ASTSerializationListener; class NestedNameSpecifier; class CXXBaseSpecifier; -class CXXBaseOrMemberInitializer; -class LabelStmt; +class CXXCtorInitializer; +class FPOptions; +class HeaderSearch; class MacroDefinition; class MemorizeStatCalls; +class OpaqueValueExpr; +class OpenCLOptions; class ASTReader; +class PreprocessedEntity; +class PreprocessingRecord; class Preprocessor; class Sema; class SourceManager; @@ -55,9 +63,11 @@ class TargetInfo; /// representation of a given abstract syntax tree and its supporting /// data structures. This bitstream can be de-serialized via an /// instance of the ASTReader class. -class ASTWriter : public ASTDeserializationListener { +class ASTWriter : public ASTDeserializationListener, + public ASTMutationListener { public: typedef llvm::SmallVector<uint64_t, 64> RecordData; + typedef llvm::SmallVectorImpl<uint64_t> RecordDataImpl; friend class ASTDeclWriter; private: @@ -67,6 +77,10 @@ private: /// \brief The reader of existing AST files, if we're chaining. ASTReader *Chain; + /// \brief A listener object that receives notifications when certain + /// entities are serialized. + ASTSerializationListener *SerializationListener; + /// \brief Stores a declaration or a type to be written to the AST file. class DeclOrType { public: @@ -163,7 +177,7 @@ private: /// \brief Offset of each selector within the method pool/selector /// table, indexed by the Selector ID (-1). std::vector<uint32_t> SelectorOffsets; - + /// \brief Offsets of each of the macro identifiers into the /// bitstream. /// @@ -172,15 +186,30 @@ private: /// defined. llvm::DenseMap<const IdentifierInfo *, uint64_t> MacroOffsets; + /// \brief The set of identifiers that had macro definitions at some point. + std::vector<const IdentifierInfo *> DeserializedMacroNames; + + /// \brief The first ID number we can use for our own macro definitions. + serialization::MacroID FirstMacroID; + + /// \brief The decl ID that will be assigned to the next new macro definition. + serialization::MacroID NextMacroID; + /// \brief Mapping from macro definitions (as they occur in the preprocessing - /// record) to the index into the macro definitions table. - llvm::DenseMap<const MacroDefinition *, serialization::IdentID> + /// record) to the macro IDs. + llvm::DenseMap<const MacroDefinition *, serialization::MacroID> MacroDefinitions; /// \brief Mapping from the macro definition indices in \c MacroDefinitions /// to the corresponding offsets within the preprocessor block. std::vector<uint32_t> MacroDefinitionOffsets; + typedef llvm::SmallVector<uint64_t, 2> UpdateRecord; + typedef llvm::DenseMap<const Decl *, UpdateRecord> DeclUpdateMap; + /// \brief Mapping from declarations that came from a chained PCH to the + /// record containing modifications to them. + DeclUpdateMap DeclUpdates; + typedef llvm::DenseMap<Decl *, Decl *> FirstLatestDeclMap; /// \brief Map of first declarations from a chained PCH that point to the /// most recent declarations in another PCH. @@ -200,13 +229,17 @@ private: /// record. llvm::SmallVector<uint64_t, 16> ExternalDefinitions; - /// \brief Namespaces that have received extensions since their serialized + /// \brief DeclContexts that have received extensions since their serialized /// form. /// - /// Basically, when we're chaining and encountering a namespace, we check if + /// For namespaces, when we're chaining and encountering a namespace, we check if /// its primary namespace comes from the chain. If it does, we add the primary /// to this set, so that we can write out lexical content updates for it. - llvm::SmallPtrSet<const NamespaceDecl *, 16> UpdatedNamespaces; + llvm::SmallPtrSet<const DeclContext *, 16> UpdatedDeclContexts; + + typedef llvm::SmallPtrSet<const Decl *, 16> DeclsToRewriteTy; + /// \brief Decls that will be replaced in the current dependent AST file. + DeclsToRewriteTy DeclsToRewrite; /// \brief Decls that have been replaced in the current dependent AST file. /// @@ -217,16 +250,6 @@ private: llvm::SmallVector<std::pair<serialization::DeclID, uint64_t>, 16> ReplacedDecls; - typedef llvm::SmallVector<serialization::DeclID, 4> - AdditionalTemplateSpecializationsList; - typedef llvm::DenseMap<serialization::DeclID, - AdditionalTemplateSpecializationsList> - AdditionalTemplateSpecializationsMap; - - /// \brief Additional specializations (including partial) of templates that - /// were introduced after the template was serialized. - AdditionalTemplateSpecializationsMap AdditionalTemplateSpecializations; - /// \brief Statements that we've encountered while serializing a /// declaration or type. llvm::SmallVector<Stmt *, 16> StmtsToEmit; @@ -238,8 +261,8 @@ private: /// \brief Mapping from SwitchCase statements to IDs. std::map<SwitchCase *, unsigned> SwitchCaseIDs; - /// \brief Mapping from LabelStmt statements to IDs. - std::map<LabelStmt *, unsigned> LabelIDs; + /// \brief Mapping from OpaqueValueExpr expressions to IDs. + llvm::DenseMap<OpaqueValueExpr *, unsigned> OpaqueValues; /// \brief The number of statements written to the AST file. unsigned NumStatements; @@ -255,17 +278,50 @@ private: /// file. unsigned NumVisibleDeclContexts; + /// \brief The offset of each CXXBaseSpecifier set within the AST. + llvm::SmallVector<uint32_t, 4> 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. + llvm::SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite; + /// \brief Write the given subexpression to the bitstream. void WriteSubStmt(Stmt *S); void WriteBlockInfoBlock(); - void WriteMetadata(ASTContext &Context, const char *isysroot); + void WriteMetadata(ASTContext &Context, const char *isysroot, + const std::string &OutputFile); void WriteLanguageOptions(const LangOptions &LangOpts); void WriteStatCache(MemorizeStatCalls &StatCalls); void WriteSourceManagerBlock(SourceManager &SourceMgr, const Preprocessor &PP, const char* isysroot); void WritePreprocessor(const Preprocessor &PP); + void WriteHeaderSearch(HeaderSearch &HS, const char* isysroot); + void WritePreprocessorDetail(PreprocessingRecord &PPRec); + void WritePragmaDiagnosticMappings(const Diagnostic &Diag); void WriteType(QualType T); uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC); @@ -273,10 +329,12 @@ private: void WriteSelectors(Sema &SemaRef); void WriteReferencedSelectorsPool(Sema &SemaRef); void WriteIdentifierTable(Preprocessor &PP); - void WriteAttributeRecord(const AttrVec &Attrs); - void WriteDeclUpdateBlock(); + void WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record); + void WriteDeclUpdatesBlocks(); + void WriteDeclReplacementsBlock(); void WriteDeclContextVisibleUpdate(const DeclContext *DC); - void WriteAdditionalTemplateSpecializations(); + void WriteFPPragmaOptions(const FPOptions &Opts); + void WriteOpenCLExtensions(Sema &SemaRef); unsigned ParmVarDeclAbbrev; unsigned DeclContextLexicalAbbrev; @@ -286,7 +344,7 @@ private: void WriteDecl(ASTContext &Context, Decl *D); void WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, - const char* isysroot); + const char* isysroot, const std::string &OutputFile); void WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, const char* isysroot); @@ -295,6 +353,12 @@ public: /// the given bitstream. ASTWriter(llvm::BitstreamWriter &Stream); + /// \brief Set the listener that will receive notification of serialization + /// events. + void SetSerializationListener(ASTSerializationListener *Listener) { + SerializationListener = Listener; + } + /// \brief Write a precompiled header for the given semantic analysis. /// /// \param SemaRef a reference to the semantic analysis object that processed @@ -309,32 +373,38 @@ public: /// \param PPRec Record of the preprocessing actions that occurred while /// preprocessing this file, e.g., macro instantiations void WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, + const std::string &OutputFile, const char* isysroot); /// \brief Emit a source location. - void AddSourceLocation(SourceLocation Loc, RecordData &Record); + void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record); /// \brief Emit a source range. - void AddSourceRange(SourceRange Range, RecordData &Record); + void AddSourceRange(SourceRange Range, RecordDataImpl &Record); /// \brief Emit an integral value. - void AddAPInt(const llvm::APInt &Value, RecordData &Record); + void AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record); /// \brief Emit a signed integral value. - void AddAPSInt(const llvm::APSInt &Value, RecordData &Record); + void AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record); /// \brief Emit a floating-point value. - void AddAPFloat(const llvm::APFloat &Value, RecordData &Record); + void AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record); /// \brief Emit a reference to an identifier. - void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record); + void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record); /// \brief Emit a Selector (which is a smart pointer reference). - void AddSelectorRef(Selector, RecordData &Record); + void AddSelectorRef(Selector, RecordDataImpl &Record); /// \brief Emit a CXXTemporary. - void AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record); + 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); @@ -353,10 +423,10 @@ public: /// \brief Retrieve the ID number corresponding to the given macro /// definition. - serialization::IdentID getMacroDefinitionID(MacroDefinition *MD); + serialization::MacroID getMacroDefinitionID(MacroDefinition *MD); /// \brief Emit a reference to a type. - void AddTypeRef(QualType T, RecordData &Record); + void AddTypeRef(QualType T, RecordDataImpl &Record); /// \brief Force a type to be emitted and get its ID. serialization::TypeID GetOrCreateTypeID(QualType T); @@ -371,20 +441,21 @@ public: serialization::TypeIdx getTypeIdx(QualType T) const; /// \brief Emits a reference to a declarator info. - void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record); + void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record); /// \brief Emits a template argument location info. void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, const TemplateArgumentLocInfo &Arg, - RecordData &Record); + RecordDataImpl &Record); /// \brief Emits a template argument location. void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, - RecordData &Record); + RecordDataImpl &Record); /// \brief Emit a reference to a declaration. - void AddDeclRef(const Decl *D, RecordData &Record); + void AddDeclRef(const Decl *D, RecordDataImpl &Record); + /// \brief Force a declaration to be emitted and get its ID. serialization::DeclID GetDeclRef(const Decl *D); @@ -393,49 +464,57 @@ public: serialization::DeclID getDeclID(const Decl *D); /// \brief Emit a declaration name. - void AddDeclarationName(DeclarationName Name, RecordData &Record); + void AddDeclarationName(DeclarationName Name, RecordDataImpl &Record); + void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, + DeclarationName Name, RecordDataImpl &Record); + void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo, + RecordDataImpl &Record); + + void AddQualifierInfo(const QualifierInfo &Info, RecordDataImpl &Record); /// \brief Emit a nested name specifier. - void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordData &Record); + void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordDataImpl &Record); /// \brief Emit a template name. - void AddTemplateName(TemplateName Name, RecordData &Record); + void AddTemplateName(TemplateName Name, RecordDataImpl &Record); /// \brief Emit a template argument. - void AddTemplateArgument(const TemplateArgument &Arg, RecordData &Record); + void AddTemplateArgument(const TemplateArgument &Arg, RecordDataImpl &Record); /// \brief Emit a template parameter list. void AddTemplateParameterList(const TemplateParameterList *TemplateParams, - RecordData &Record); + RecordDataImpl &Record); /// \brief Emit a template argument list. void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, - RecordData &Record); + RecordDataImpl &Record); /// \brief Emit a UnresolvedSet structure. - void AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordData &Record); + void AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordDataImpl &Record); /// \brief Emit a C++ base specifier. - void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, RecordData &Record); + void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, RecordDataImpl &Record); + + /// \brief Emit a CXXCtorInitializer array. + void AddCXXCtorInitializers( + const CXXCtorInitializer * const *CtorInitializers, + unsigned NumCtorInitializers, + RecordDataImpl &Record); - /// \brief Emit a CXXBaseOrMemberInitializer array. - void AddCXXBaseOrMemberInitializers( - const CXXBaseOrMemberInitializer * const *BaseOrMembers, - unsigned NumBaseOrMembers, RecordData &Record); + void AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record); /// \brief Add a string to the given record. - void AddString(llvm::StringRef Str, RecordData &Record); + void AddString(llvm::StringRef Str, RecordDataImpl &Record); - /// \brief Mark a namespace as needing an update. - void AddUpdatedNamespace(const NamespaceDecl *NS) { - UpdatedNamespaces.insert(NS); + /// \brief Mark a declaration context as needing an update. + void AddUpdatedDeclContext(const DeclContext *DC) { + UpdatedDeclContexts.insert(DC); } - /// \brief Record a template specialization or partial specialization of - /// a template from a previous PCH file. - void AddAdditionalTemplateSpecialization(serialization::DeclID Templ, - serialization::DeclID Spec) { - AdditionalTemplateSpecializations[Templ].push_back(Spec); + void RewriteDecl(const Decl *D) { + DeclsToRewrite.insert(D); + // Reset the flag, so that we don't add this decl multiple times. + const_cast<Decl *>(D)->setChangedSinceDeserialization(false); } /// \brief Note that the identifier II occurs at the given offset @@ -462,32 +541,46 @@ public: /// 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 Record an ID for the given switch-case statement. unsigned RecordSwitchCaseID(SwitchCase *S); /// \brief Retrieve the ID for the given switch-case statement. unsigned getSwitchCaseID(SwitchCase *S); - /// \brief Retrieve the ID for the given label statement, which may - /// or may not have been emitted yet. - unsigned GetLabelID(LabelStmt *S); + void ClearSwitchCaseIDs(); + + /// \brief Retrieve the ID for the given opaque value expression. + unsigned getOpaqueValueID(OpaqueValueExpr *e); unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; } bool hasChain() const { return Chain; } // ASTDeserializationListener implementation - void SetReader(ASTReader *Reader); + void ReaderInitialized(ASTReader *Reader); void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II); void TypeRead(serialization::TypeIdx Idx, QualType T); void DeclRead(serialization::DeclID ID, const Decl *D); - void SelectorRead(serialization::SelectorID iD, Selector Sel); + void SelectorRead(serialization::SelectorID ID, Selector Sel); + void MacroDefinitionRead(serialization::MacroID ID, MacroDefinition *MD); + + // ASTMutationListener implementation. + virtual void CompletedTagDefinition(const TagDecl *D); + virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D); + virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D); + virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, + const ClassTemplateSpecializationDecl *D); }; /// \brief AST and semantic-analysis consumer that generates a /// precompiled header from the parsed source code. class PCHGenerator : public SemaConsumer { const Preprocessor &PP; + std::string OutputFile; const char *isysroot; llvm::raw_ostream *Out; Sema *SemaPtr; @@ -495,16 +588,19 @@ class PCHGenerator : public SemaConsumer { std::vector<unsigned char> Buffer; llvm::BitstreamWriter Stream; ASTWriter Writer; + bool Chaining; protected: ASTWriter &getWriter() { return Writer; } const ASTWriter &getWriter() const { return Writer; } public: - PCHGenerator(const Preprocessor &PP, bool Chaining, + PCHGenerator(const Preprocessor &PP, const std::string &OutputFile, bool Chaining, const char *isysroot, llvm::raw_ostream *Out); virtual void InitializeSema(Sema &S) { SemaPtr = &S; } virtual void HandleTranslationUnit(ASTContext &Ctx); + virtual ASTMutationListener *GetASTMutationListener(); + virtual ASTSerializationListener *GetASTSerializationListener(); virtual ASTDeserializationListener *GetASTDeserializationListener(); }; |