diff options
Diffstat (limited to 'include/clang/Serialization')
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 135 | ||||
-rw-r--r-- | include/clang/Serialization/ASTDeserializationListener.h | 21 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 484 | ||||
-rw-r--r-- | include/clang/Serialization/ASTSerializationListener.h | 44 | ||||
-rw-r--r-- | include/clang/Serialization/ASTWriter.h | 230 |
5 files changed, 664 insertions, 250 deletions
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 0fa446d..68fd91d 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -19,7 +19,7 @@ #include "clang/AST/Type.h" #include "llvm/Bitcode/BitCodes.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include "llvm/ADT/DenseMap.h" namespace clang { @@ -54,6 +54,9 @@ namespace clang { /// reserved for the translation unit declaration. typedef uint32_t DeclID; + /// \brief a Decl::Kind/DeclID pair. + typedef std::pair<uint32_t, DeclID> KindDeclIDPair; + /// \brief An ID number that refers to a type in an AST file. /// /// The ID of a type is partitioned into two parts: the lower @@ -112,12 +115,19 @@ namespace clang { typedef llvm::DenseMap<QualType, TypeIdx, UnsafeQualTypeDenseMapInfo> TypeIdxMap; - /// \brief An ID number that refers to an identifier in an AST - /// file. + /// \brief An ID number that refers to an identifier in an AST file. typedef uint32_t IdentID; + /// \brief An ID number that refers to a macro in an AST file. + typedef uint32_t MacroID; + + /// \brief An ID number that refers to an ObjC selctor in an AST file. typedef uint32_t SelectorID; + /// \brief An ID number that refers to a set of CXXBaseSpecifiers in an + /// AST file. + typedef uint32_t CXXBaseSpecifiersID; + /// \brief Describes the various kinds of blocks that occur within /// an AST file. enum BlockIDs { @@ -135,7 +145,13 @@ namespace clang { /// \brief The block containing the definitions of all of the /// types and decls used within the AST file. - DECLTYPES_BLOCK_ID + DECLTYPES_BLOCK_ID, + + /// \brief The block containing DECL_UPDATES records. + DECL_UPDATES_BLOCK_ID, + + /// \brief The block containing the detailed preprocessing record. + PREPROCESSOR_DETAIL_BLOCK_ID }; /// \brief Record types that occur within the AST block itself. @@ -318,9 +334,35 @@ namespace clang { /// In practice, this should only be used for the TU and namespaces. UPDATE_VISIBLE = 34, - /// \brief Record code for template specializations introduced after - /// serializations of the original template decl. - ADDITIONAL_TEMPLATE_SPECIALIZATIONS = 35 + /// \brief Record for offsets of DECL_UPDATES records for declarations + /// that were modified after being deserialized and need updates. + DECL_UPDATE_OFFSETS = 35, + + /// \brief Record of updates for a declaration that was modified after + /// being deserialized. + DECL_UPDATES = 36, + + /// \brief Record code for the table of offsets to CXXBaseSpecifier + /// sets. + CXX_BASE_SPECIFIER_OFFSETS = 37, + + /// \brief Record code for #pragma diagnostic mappings. + DIAG_PRAGMA_MAPPINGS = 38, + + /// \brief Record code for special CUDA declarations. + CUDA_SPECIAL_DECL_REFS = 39, + + /// \brief Record code for header search information. + HEADER_SEARCH_TABLE = 40, + + /// \brief The directory that the PCH was originally created in. + ORIGINAL_PCH_DIR = 41, + + /// \brief Record code for floating point #pragma options. + FP_PRAGMA_OPTIONS = 42, + + /// \brief Record code for enabled OpenCL extensions. + OPENCL_EXTENSIONS = 43 }; /// \brief Record types used within a source manager block. @@ -359,16 +401,23 @@ namespace clang { /// \brief Describes one token. /// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags] - PP_TOKEN = 3, + PP_TOKEN = 3 + }; + /// \brief Record types used within a preprocessor detail block. + enum PreprocessorDetailRecordTypes { /// \brief Describes a macro instantiation within the preprocessing /// record. - PP_MACRO_INSTANTIATION = 4, + PPD_MACRO_INSTANTIATION = 0, /// \brief Describes a macro definition within the preprocessing record. - PP_MACRO_DEFINITION = 5 + PPD_MACRO_DEFINITION = 1, + + /// \brief Describes an inclusion directive within the preprocessing + /// record. + PPD_INCLUSION_DIRECTIVE = 2 }; - + /// \defgroup ASTAST AST file AST constants /// /// The constants in this group describe various components of the @@ -521,7 +570,17 @@ namespace clang { /// \brief A DependentTemplateSpecializationType record. TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32, /// \brief A DependentSizedArrayType record. - TYPE_DEPENDENT_SIZED_ARRAY = 33 + TYPE_DEPENDENT_SIZED_ARRAY = 33, + /// \brief A ParenType record. + TYPE_PAREN = 34, + /// \brief A PackExpansionType record. + TYPE_PACK_EXPANSION = 35, + /// \brief An AttributedType record. + TYPE_ATTRIBUTED = 36, + /// \brief A SubstTemplateTypeParmPackType record. + TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37, + /// \brief A AutoType record. + TYPE_AUTO = 38 }; /// \brief The type IDs for special types constructed by semantic @@ -573,10 +632,8 @@ namespace clang { /// constant describes a record for a specific declaration class /// in the AST. enum DeclCode { - /// \brief Attributes attached to a declaration. - DECL_ATTR = 50, /// \brief A TranslationUnitDecl record. - DECL_TRANSLATION_UNIT, + DECL_TRANSLATION_UNIT = 50, /// \brief A TypedefDecl record. DECL_TYPEDEF, /// \brief An EnumDecl record. @@ -642,7 +699,9 @@ namespace clang { /// IDs. This data is used when performing qualified name lookup /// into a DeclContext via DeclContext::lookup. DECL_CONTEXT_VISIBLE, - /// \brief A NamespaceDecl rcord. + /// \brief A LabelDecl record. + DECL_LABEL, + /// \brief A NamespaceDecl record. DECL_NAMESPACE, /// \brief A NamespaceAliasDecl record. DECL_NAMESPACE_ALIAS, @@ -690,7 +749,14 @@ namespace clang { /// \brief A TemplateTemplateParmDecl record. DECL_TEMPLATE_TEMPLATE_PARM, /// \brief A StaticAssertDecl record. - DECL_STATIC_ASSERT + DECL_STATIC_ASSERT, + /// \brief A record containing CXXBaseSpecifiers. + DECL_CXX_BASE_SPECIFIERS, + /// \brief A IndirectFieldDecl record. + DECL_INDIRECTFIELD, + /// \brief A NonTypeTemplateParmDecl record that stores an expanded + /// non-type template parameter pack. + DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK }; /// \brief Record codes for each kind of statement or expression. @@ -796,8 +862,6 @@ namespace clang { EXPR_ADDR_LABEL, /// \brief A StmtExpr record. EXPR_STMT, - /// \brief A TypesCompatibleExpr record. - EXPR_TYPES_COMPATIBLE, /// \brief A ChooseExpr record. EXPR_CHOOSE, /// \brief A GNUNullExpr record. @@ -823,12 +887,10 @@ namespace clang { EXPR_OBJC_IVAR_REF_EXPR, /// \brief An ObjCPropertyRefExpr record. EXPR_OBJC_PROPERTY_REF_EXPR, - /// \brief An ObjCImplicitSetterGetterRefExpr record. + /// \brief UNUSED EXPR_OBJC_KVC_REF_EXPR, /// \brief An ObjCMessageExpr record. EXPR_OBJC_MESSAGE_EXPR, - /// \brief An ObjCSuperExpr record. - EXPR_OBJC_SUPER_EXPR, /// \brief An ObjCIsa Expr record. EXPR_OBJC_ISA, @@ -875,6 +937,8 @@ namespace clang { EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr). EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type). + EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr). + EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type). EXPR_CXX_THIS, // CXXThisExpr EXPR_CXX_THROW, // CXXThrowExpr EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr @@ -885,15 +949,28 @@ namespace clang { EXPR_CXX_DELETE, // CXXDeleteExpr EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr - EXPR_CXX_EXPR_WITH_TEMPORARIES, // CXXExprWithTemporaries + EXPR_EXPR_WITH_CLEANUPS, // ExprWithCleanups - EXPR_CXX_DEPENDENT_SCOPE_MEMBER, // CXXDependentScopeMemberExpr - EXPR_CXX_DEPENDENT_SCOPE_DECL_REF, // DependentScopeDeclRefExpr - EXPR_CXX_UNRESOLVED_CONSTRUCT, // CXXUnresolvedConstructExpr - EXPR_CXX_UNRESOLVED_MEMBER, // UnresolvedMemberExpr - EXPR_CXX_UNRESOLVED_LOOKUP, // UnresolvedLookupExpr + EXPR_CXX_DEPENDENT_SCOPE_MEMBER, // CXXDependentScopeMemberExpr + EXPR_CXX_DEPENDENT_SCOPE_DECL_REF, // DependentScopeDeclRefExpr + EXPR_CXX_UNRESOLVED_CONSTRUCT, // CXXUnresolvedConstructExpr + EXPR_CXX_UNRESOLVED_MEMBER, // UnresolvedMemberExpr + EXPR_CXX_UNRESOLVED_LOOKUP, // UnresolvedLookupExpr + + EXPR_CXX_UNARY_TYPE_TRAIT, // UnaryTypeTraitExpr + EXPR_CXX_NOEXCEPT, // CXXNoexceptExpr + + EXPR_OPAQUE_VALUE, // OpaqueValueExpr + EXPR_BINARY_CONDITIONAL_OPERATOR, // BinaryConditionalOperator + EXPR_BINARY_TYPE_TRAIT, // BinaryTypeTraitExpr + + EXPR_PACK_EXPANSION, // PackExpansionExpr + EXPR_SIZEOF_PACK, // SizeOfPackExpr + EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr + + // CUDA - EXPR_CXX_UNARY_TYPE_TRAIT // UnaryTypeTraitExpr + EXPR_CUDA_KERNEL_CALL // CUDAKernelCallExpr }; /// \brief The kinds of designators that can occur in a diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h index f8114de..f8cdebe 100644 --- a/include/clang/Serialization/ASTDeserializationListener.h +++ b/include/clang/Serialization/ASTDeserializationListener.h @@ -22,26 +22,31 @@ namespace clang { class Decl; class ASTReader; class QualType; - +class MacroDefinition; + class ASTDeserializationListener { protected: - virtual ~ASTDeserializationListener() {} + virtual ~ASTDeserializationListener(); public: - /// \brief Tell the listener about the reader. - virtual void SetReader(ASTReader *Reader) = 0; + + /// \brief The ASTReader was initialized. + virtual void ReaderInitialized(ASTReader *Reader) { } /// \brief An identifier was deserialized from the AST file. virtual void IdentifierRead(serialization::IdentID ID, - IdentifierInfo *II) = 0; + IdentifierInfo *II) { } /// \brief A type was deserialized from the AST file. The ID here has the /// qualifier bits already removed, and T is guaranteed to be locally /// unqualified. - virtual void TypeRead(serialization::TypeIdx Idx, QualType T) = 0; + virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { } /// \brief A decl was deserialized from the AST file. - virtual void DeclRead(serialization::DeclID ID, const Decl *D) = 0; + virtual void DeclRead(serialization::DeclID ID, const Decl *D) { } /// \brief A selector was read from the AST file. - virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) = 0; + virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) { } + /// \brief A macro definition was read from the AST file. + virtual void MacroDefinitionRead(serialization::MacroID, + MacroDefinition *MD) { } }; } diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index d31be88..9799b8d 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -20,6 +20,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/TemplateBase.h" #include "clang/Lex/ExternalPreprocessorSource.h" +#include "clang/Lex/HeaderSearch.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" @@ -31,7 +32,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Bitcode/BitstreamReader.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include <deque> #include <map> #include <string> @@ -47,22 +48,26 @@ namespace clang { class AddrLabelExpr; class ASTConsumer; class ASTContext; +class ASTIdentifierIterator; class Attr; class Decl; class DeclContext; class NestedNameSpecifier; class CXXBaseSpecifier; -class CXXBaseOrMemberInitializer; +class CXXCtorInitializer; class GotoStmt; -class LabelStmt; class MacroDefinition; class NamedDecl; -class ASTDeserializationListener; +class OpaqueValueExpr; class Preprocessor; class Sema; class SwitchCase; +class ASTDeserializationListener; class ASTReader; class ASTDeclReader; +class ASTStmtReader; +class ASTIdentifierLookupTrait; +class TypeLocReader; struct HeaderFileInfo; struct PCHPredefinesBlock { @@ -161,14 +166,27 @@ private: class ASTReader : public ExternalPreprocessorSource, public ExternalPreprocessingRecordSource, + public ExternalHeaderFileInfoSource, public ExternalSemaSource, public IdentifierInfoLookup, public ExternalIdentifierLookup, - public ExternalSLocEntrySource { + public ExternalSLocEntrySource +{ public: enum ASTReadResult { Success, Failure, IgnorePCH }; + /// \brief Types of AST files. + enum ASTFileType { + Module, ///< File is a module proper. + PCH, ///< File is a PCH file treated as such. + Preamble, ///< File is a PCH file treated as the preamble. + MainFile ///< File is a PCH file treated as the actual main file. + }; friend class PCHValidator; friend class ASTDeclReader; + friend class ASTStmtReader; + friend class ASTIdentifierIterator; + friend class ASTIdentifierLookupTrait; + friend class TypeLocReader; private: /// \brief The receiver of some callbacks invoked by ASTReader. llvm::OwningPtr<ASTReaderListener> Listener; @@ -193,31 +211,15 @@ private: /// \brief The AST consumer. ASTConsumer *Consumer; - /// \brief Information that is needed for every file in the chain. + /// \brief Information that is needed for every module. struct PerFileData { - PerFileData(); + PerFileData(ASTFileType Ty); ~PerFileData(); - /// \brief The AST stat cache installed for this file, if any. - /// - /// The dynamic type of this stat cache is always ASTStatCache - void *StatCache; - - /// \brief The bitstream reader from which we'll read the AST file. - llvm::BitstreamReader StreamFile; - llvm::BitstreamCursor Stream; - - /// \brief The size of this file, in bits. - uint64_t SizeInBits; + // === General information === - /// \brief The cursor to the start of the preprocessor block, which stores - /// all of the macro definitions. - llvm::BitstreamCursor MacroCursor; - - /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It - /// has read all the abbreviations at the start of the block and is ready to - /// jump around with these in context. - llvm::BitstreamCursor DeclsCursor; + /// \brief The type of this AST file. + ASTFileType Type; /// \brief The file name of the AST file. std::string FileName; @@ -226,6 +228,17 @@ private: /// this AST file. llvm::OwningPtr<llvm::MemoryBuffer> Buffer; + /// \brief The size of this file, in bits. + uint64_t SizeInBits; + + /// \brief The bitstream reader from which we'll read the AST file. + llvm::BitstreamReader StreamFile; + + /// \brief The main bitstream cursor for the main block. + llvm::BitstreamCursor Stream; + + // === Source Locations === + /// \brief Cursor used to read source location entries. llvm::BitstreamCursor SLocEntryCursor; @@ -236,19 +249,10 @@ private: /// AST file. const uint32_t *SLocOffsets; - /// \brief The number of types in this AST file. - unsigned LocalNumTypes; - - /// \brief Offset of each type within the bitstream, indexed by the - /// type ID, or the representation of a Type*. - const uint32_t *TypeOffsets; - - /// \brief The number of declarations in this AST file. - unsigned LocalNumDecls; + /// \brief The entire size of this module's source location offset range. + unsigned LocalSLocSize; - /// \brief Offset of each declaration within the bitstream, indexed - /// by the declaration ID (-1). - const uint32_t *DeclOffsets; + // === Identifiers === /// \brief The number of identifiers in this AST file. unsigned LocalNumIdentifiers; @@ -260,26 +264,72 @@ private: /// stored. const uint32_t *IdentifierOffsets; - /// \brief Actual data for the on-disk hash table. + /// \brief Actual data for the on-disk hash table of identifiers. /// - // This pointer points into a memory buffer, where the on-disk hash - // table for identifiers actually lives. + /// This pointer points into a memory buffer, where the on-disk hash + /// table for identifiers actually lives. const char *IdentifierTableData; /// \brief A pointer to an on-disk hash table of opaque type /// IdentifierHashTable. void *IdentifierLookupTable; + // === Macros === + + /// \brief The cursor to the start of the preprocessor block, which stores + /// all of the macro definitions. + llvm::BitstreamCursor MacroCursor; + + /// \brief The offset of the start of the set of defined macros. + uint64_t MacroStartOffset; + + // === Detailed PreprocessingRecord === + + /// \brief The cursor to the start of the (optional) detailed preprocessing + /// record block. + llvm::BitstreamCursor PreprocessorDetailCursor; + + /// \brief The offset of the start of the preprocessor detail cursor. + uint64_t PreprocessorDetailStartOffset; + /// \brief The number of macro definitions in this file. unsigned LocalNumMacroDefinitions; - + /// \brief Offsets of all of the macro definitions in the preprocessing /// record in the AST file. const uint32_t *MacroDefinitionOffsets; - - /// \brief The number of preallocated preprocessing entities in the - /// preprocessing record. - unsigned NumPreallocatedPreprocessingEntities; + + // === Header search information === + + /// \brief The number of local HeaderFileInfo structures. + unsigned LocalNumHeaderFileInfos; + + /// \brief Actual data for the on-disk hash table of header file + /// information. + /// + /// This pointer points into a memory buffer, where the on-disk hash + /// table for header file information actually lives. + const char *HeaderFileInfoTableData; + + /// \brief The on-disk hash table that contains information about each of + /// the header files. + void *HeaderFileInfoTable; + + // === Selectors === + + /// \brief The number of selectors new to this file. + /// + /// This is the number of entries in SelectorOffsets. + unsigned LocalNumSelectors; + + /// \brief Offsets into the selector lookup table's data array + /// where each selector resides. + const uint32_t *SelectorOffsets; + + /// \brief A pointer to the character data that comprises the selector table + /// + /// The SelectorOffsets table refers into this memory. + const unsigned char *SelectorLookupTableData; /// \brief A pointer to an on-disk hash table of opaque type /// ASTSelectorLookupTable. @@ -288,26 +338,81 @@ private: /// instance and factory methods. void *SelectorLookupTable; - /// \brief A pointer to the character data that comprises the selector table + /// \brief Method selectors used in a @selector expression. Used for + /// implementation of -Wselector. + llvm::SmallVector<uint64_t, 64> ReferencedSelectorsData; + + // === Declarations === + + /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It + /// has read all the abbreviations at the start of the block and is ready to + /// jump around with these in context. + llvm::BitstreamCursor DeclsCursor; + + /// \brief The number of declarations in this AST file. + unsigned LocalNumDecls; + + /// \brief Offset of each declaration within the bitstream, indexed + /// by the declaration ID (-1). + const uint32_t *DeclOffsets; + + /// \brief A snapshot of the pending instantiations in the chain. /// - /// The SelectorOffsets table refers into this memory. - const unsigned char *SelectorLookupTableData; + /// This record tracks the instantiations that Sema has to perform at the + /// end of the TU. It consists of a pair of values for every pending + /// instantiation where the first value is the ID of the decl and the second + /// is the instantiation location. + llvm::SmallVector<uint64_t, 64> PendingInstantiations; + + /// \brief The number of C++ base specifier sets in this AST file. + unsigned LocalNumCXXBaseSpecifiers; + + /// \brief Offset of each C++ base specifier set within the bitstream, + /// indexed by the C++ base specifier set ID (-1). + const uint32_t *CXXBaseSpecifiersOffsets; + + // === Types === - /// \brief Offsets into the method pool lookup table's data array - /// where each selector resides. - const uint32_t *SelectorOffsets; + /// \brief The number of types in this AST file. + unsigned LocalNumTypes; - /// \brief The number of selectors new to this file. + /// \brief Offset of each type within the bitstream, indexed by the + /// type ID, or the representation of a Type*. + const uint32_t *TypeOffsets; + + // === Miscellaneous === + + /// \brief The AST stat cache installed for this file, if any. /// - /// This is the number of entries in SelectorOffsets. - unsigned LocalNumSelectors; + /// The dynamic type of this stat cache is always ASTStatCache + void *StatCache; + + /// \brief The number of preallocated preprocessing entities in the + /// preprocessing record. + unsigned NumPreallocatedPreprocessingEntities; + + /// \brief The next module in source order. + PerFileData *NextInSource; + + /// \brief All the modules that loaded this one. Can contain NULL for + /// directly loaded modules. + llvm::SmallVector<PerFileData *, 1> Loaders; }; + /// \brief All loaded modules, indexed by name. + llvm::StringMap<PerFileData*> Modules; + + /// \brief The first module in source order. + PerFileData *FirstInSource; + /// \brief The chain of AST files. The first entry is the one named by the /// user, the last one is the one that doesn't depend on anything further. /// That is, the entry I was created with -include-pch I+1. llvm::SmallVector<PerFileData*, 2> Chain; + /// \brief SLocEntries that we're going to preload. + llvm::SmallVector<uint64_t, 64> PreloadSLocEntries; + /// \brief Types that have already been loaded from the chain. /// /// When the pointer at index I is non-NULL, the type with @@ -331,6 +436,14 @@ private: /// = I + 1 has already been loaded. std::vector<Decl *> DeclsLoaded; + typedef std::pair<PerFileData *, uint64_t> FileOffset; + typedef llvm::SmallVector<FileOffset, 2> FileOffsetsTy; + typedef llvm::DenseMap<serialization::DeclID, FileOffsetsTy> + DeclUpdateOffsetsMap; + /// \brief Declarations that have modifications residing in a later file + /// in the chain. + DeclUpdateOffsetsMap DeclUpdateOffsets; + typedef llvm::DenseMap<serialization::DeclID, std::pair<PerFileData *, uint64_t> > DeclReplacementMap; @@ -340,7 +453,7 @@ private: /// \brief Information about the contents of a DeclContext. struct DeclContextInfo { void *NameLookupTableData; // a ASTDeclContextNameLookupTable. - const serialization::DeclID *LexicalDecls; + const serialization::KindDeclIDPair *LexicalDecls; unsigned NumLexicalDecls; }; // In a full chain, there could be multiple updates to every decl context, @@ -366,22 +479,20 @@ private: /// haven't been loaded yet. DeclContextVisibleUpdatesPending PendingVisibleUpdates; + typedef llvm::SmallVector<CXXRecordDecl *, 4> ForwardRefs; + typedef llvm::DenseMap<const CXXRecordDecl *, ForwardRefs> + PendingForwardRefsMap; + /// \brief Forward references that have a definition but the definition decl + /// is still initializing. When the definition gets read it will update + /// the DefinitionData pointer of all pending references. + PendingForwardRefsMap PendingForwardRefs; + typedef llvm::DenseMap<serialization::DeclID, serialization::DeclID> FirstLatestDeclIDMap; /// \brief Map of first declarations from a chained PCH that point to the /// most recent declarations in another AST file. FirstLatestDeclIDMap FirstLatestDeclIDs; - typedef llvm::SmallVector<serialization::DeclID, 4> - AdditionalTemplateSpecializations; - typedef llvm::DenseMap<serialization::DeclID, - AdditionalTemplateSpecializations> - AdditionalTemplateSpecializationsMap; - - /// \brief Additional specializations (including partial) of templates that - /// were introduced after the template was serialized. - AdditionalTemplateSpecializationsMap AdditionalTemplateSpecializationsPending; - /// \brief Read the records that describe the contents of declcontexts. bool ReadDeclContextStorage(llvm::BitstreamCursor &Cursor, const std::pair<uint64_t, uint64_t> &Offsets, @@ -405,6 +516,11 @@ private: /// \brief The macro definitions we have already loaded. llvm::SmallVector<MacroDefinition *, 16> MacroDefinitionsLoaded; + /// \brief Mapping from identifiers that represent macros whose definitions + /// have not yet been deserialized to the global offset where the macro + /// record resides. + llvm::DenseMap<IdentifierInfo *, uint64_t> UnreadMacroRecordOffsets; + /// \name CodeGen-relevant special data /// \brief Fields containing data that is relevant to CodeGen. //@{ @@ -437,10 +553,6 @@ private: /// \brief Fields containing data that is used for generating diagnostics //@{ - /// \brief Method selectors used in a @selector expression. Used for - /// implementation of -Wselector. - llvm::SmallVector<uint64_t, 64> ReferencedSelectorsData; - /// \brief A snapshot of Sema's unused file-scoped variable tracking, for /// generating warnings. llvm::SmallVector<uint64_t, 16> UnusedFileScopedDecls; @@ -466,14 +578,6 @@ private: /// local external declarations. llvm::SmallVector<uint64_t, 16> LocallyScopedExternalDecls; - /// \brief A snapshot of the pwnsinf instantiations in the chain. - /// - /// This record tracks the instantiations that Sema has to perform at the end - /// of the TU. It consists of a pair of values for every pending instantiation - /// where the first value is the ID of the decl and the second is the - /// instantiation location. - llvm::SmallVector<uint64_t, 64> PendingInstantiations; - /// \brief The IDs of all dynamic class declarations in the chain. /// /// Sema tracks these because it checks for the key functions being defined @@ -490,8 +594,23 @@ private: /// The AST context tracks a few important types, such as va_list, directly. llvm::SmallVector<uint64_t, 16> SpecialTypes; + /// \brief The IDs of CUDA-specific declarations ASTContext stores directly. + /// + /// The AST context tracks a few important decls, currently cudaConfigureCall, + /// directly. + llvm::SmallVector<uint64_t, 2> CUDASpecialDeclRefs; + + /// \brief The floating point pragma option settings. + llvm::SmallVector<uint64_t, 1> FPPragmaOptions; + + /// \brief The OpenCL extension settings. + llvm::SmallVector<uint64_t, 1> OpenCLExtensions; + //@} + /// \brief Diagnostic IDs and their mappings that the user changed. + llvm::SmallVector<uint64_t, 8> PragmaDiagMappings; + /// \brief The original file name that was used to build the primary AST file, /// which may have been modified for relocatable-pch support. std::string OriginalFileName; @@ -500,6 +619,13 @@ private: /// AST file. std::string ActualOriginalFileName; + /// \brief The directory that the PCH was originally created in. Used to + /// allow resolving headers even after headers+PCH was moved to a new path. + std::string OriginalDir; + + /// \brief The directory that the PCH we are reading is stored in. + std::string CurrentDir; + /// \brief Whether this precompiled header is a relocatable PCH file. bool RelocatablePCH; @@ -511,27 +637,17 @@ private: /// headers when they are loaded. bool DisableValidation; + /// \brief Whether to disable the use of stat caches in AST files. + bool DisableStatCache; + /// \brief Mapping from switch-case IDs in the chain to switch-case statements /// /// Statements usually don't have IDs, but switch cases need them, so that the /// switch statement can refer to them. std::map<unsigned, SwitchCase *> SwitchCaseStmts; - /// \brief Mapping from label statement IDs in the chain to label statements. - /// - /// Statements usually don't have IDs, but labeled statements need them, so - /// that goto statements and address-of-label expressions can refer to them. - std::map<unsigned, LabelStmt *> LabelStmts; - - /// \brief Mapping from label IDs to the set of "goto" statements - /// that point to that label before the label itself has been - /// de-serialized. - std::multimap<unsigned, GotoStmt *> UnresolvedGotoStmts; - - /// \brief Mapping from label IDs to the set of address label - /// expressions that point to that label before the label itself has - /// been de-serialized. - std::multimap<unsigned, AddrLabelExpr *> UnresolvedAddrLabelExprs; + /// \brief Mapping from opaque value IDs to OpaqueValueExprs. + std::map<unsigned, OpaqueValueExpr*> OpaqueValueExprs; /// \brief The number of stat() calls that hit/missed the stat /// cache. @@ -544,6 +660,9 @@ private: /// \brief The number of source location entries in the chain. unsigned TotalNumSLocEntries; + /// \brief The next offset for a SLocEntry after everything in this reader. + unsigned NextSLocOffset; + /// \brief The number of statements (and expressions) de-serialized /// from the chain. unsigned NumStatementsRead; @@ -602,6 +721,13 @@ private: /// Objective-C protocols. std::deque<Decl *> InterestingDecls; + /// \brief We delay loading of the previous declaration chain to avoid + /// deeply nested calls when there are many redeclarations. + std::deque<std::pair<Decl *, serialization::DeclID> > PendingPreviousDecls; + + /// \brief Ready to load the previous declaration of the given Decl. + void loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID); + /// \brief When reading a Stmt tree, Stmt operands are placed in this stack. llvm::SmallVector<Stmt *, 16> StmtStack; @@ -645,20 +771,26 @@ private: std::string SuggestedPredefines; /// \brief Reads a statement from the specified cursor. - Stmt *ReadStmtFromStream(llvm::BitstreamCursor &Cursor); + Stmt *ReadStmtFromStream(PerFileData &F); void MaybeAddSystemRootToFilename(std::string &Filename); - ASTReadResult ReadASTCore(llvm::StringRef FileName); + ASTReadResult ReadASTCore(llvm::StringRef FileName, ASTFileType Type); ASTReadResult ReadASTBlock(PerFileData &F); bool CheckPredefinesBuffers(); - bool ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record); + bool ParseLineTable(PerFileData &F, llvm::SmallVectorImpl<uint64_t> &Record); ASTReadResult ReadSourceManagerBlock(PerFileData &F); ASTReadResult ReadSLocEntryRecord(unsigned ID); - llvm::BitstreamCursor &SLocCursorForID(unsigned ID); + PerFileData *SLocCursorForID(unsigned ID); + SourceLocation getImportLocation(PerFileData *F); bool ParseLanguageOptions(const llvm::SmallVectorImpl<uint64_t> &Record); - typedef std::pair<llvm::BitstreamCursor *, uint64_t> RecordLocation; + struct RecordLocation { + RecordLocation(PerFileData *M, uint64_t O) + : F(M), Offset(O) {} + PerFileData *F; + uint64_t Offset; + }; QualType ReadTypeRecord(unsigned Index); RecordLocation TypeCursorForIndex(unsigned Index); @@ -695,8 +827,14 @@ public: /// \param DisableValidation If true, the AST reader will suppress most /// of its regular consistency checking, allowing the use of precompiled /// headers that cannot be determined to be compatible. + /// + /// \param DisableStatCache If true, the AST reader will ignore the + /// stat cache in the AST files. This performance pessimization can + /// help when an AST file is being used in cases where the + /// underlying files in the file system may have changed, but + /// parsing should still continue. ASTReader(Preprocessor &PP, ASTContext *Context, const char *isysroot = 0, - bool DisableValidation = false); + bool DisableValidation = false, bool DisableStatCache = false); /// \brief Load the AST file without using any pre-initialized Preprocessor. /// @@ -717,14 +855,20 @@ public: /// \param DisableValidation If true, the AST reader will suppress most /// of its regular consistency checking, allowing the use of precompiled /// headers that cannot be determined to be compatible. - ASTReader(SourceManager &SourceMgr, FileManager &FileMgr, + /// + /// \param DisableStatCache If true, the AST reader will ignore the + /// stat cache in the AST files. This performance pessimization can + /// help when an AST file is being used in cases where the + /// underlying files in the file system may have changed, but + /// parsing should still continue. + ASTReader(SourceManager &SourceMgr, FileManager &FileMgr, Diagnostic &Diags, const char *isysroot = 0, - bool DisableValidation = false); + bool DisableValidation = false, bool DisableStatCache = false); ~ASTReader(); /// \brief Load the precompiled header designated by the given file /// name. - ASTReadResult ReadAST(const std::string &FileName); + ASTReadResult ReadAST(const std::string &FileName, ASTFileType Type); /// \brief Set the AST callbacks listener. void setListener(ASTReaderListener *listener) { @@ -749,6 +893,7 @@ public: /// \brief Retrieve the name of the original source file name directly from /// the AST file, without actually loading the AST file. static std::string getOriginalSourceFile(const std::string &ASTFileName, + FileManager &FileMgr, Diagnostic &Diags); /// \brief Returns the suggested contents of the predefines buffer, @@ -756,14 +901,27 @@ public: /// build prior to including the precompiled header. const std::string &getSuggestedPredefines() { return SuggestedPredefines; } - /// \brief Read preprocessed entities into the + /// \brief Read preprocessed entities into the preprocessing record. virtual void ReadPreprocessedEntities(); + /// \brief Read the preprocessed entity at the given offset. + virtual PreprocessedEntity *ReadPreprocessedEntityAtOffset(uint64_t Offset); + + /// \brief Read the header file information for the given file entry. + virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE); + + void ReadPragmaDiagnosticMappings(Diagnostic &Diag); + /// \brief Returns the number of source locations found in the chain. unsigned getTotalNumSLocs() const { return TotalNumSLocEntries; } + /// \brief Returns the next SLocEntry offset after the chain. + unsigned getNextSLocOffset() const { + return NextSLocOffset; + } + /// \brief Returns the number of identifiers found in the chain. unsigned getTotalNumIdentifiers() const { return static_cast<unsigned>(IdentifiersLoaded.size()); @@ -784,20 +942,27 @@ public: return static_cast<unsigned>(SelectorsLoaded.size()); } + /// \brief Returns the number of macro definitions found in the chain. + unsigned getTotalNumMacroDefinitions() const { + return static_cast<unsigned>(MacroDefinitionsLoaded.size()); + } + + /// \brief Returns the number of C++ base specifiers found in the chain. + unsigned getTotalNumCXXBaseSpecifiers() const; + /// \brief Reads a TemplateArgumentLocInfo appropriate for the /// given TemplateArgument kind. TemplateArgumentLocInfo - GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, - llvm::BitstreamCursor &DeclsCursor, + GetTemplateArgumentLocInfo(PerFileData &F, TemplateArgument::ArgKind Kind, const RecordData &Record, unsigned &Idx); /// \brief Reads a TemplateArgumentLoc. TemplateArgumentLoc - ReadTemplateArgumentLoc(llvm::BitstreamCursor &DeclsCursor, + ReadTemplateArgumentLoc(PerFileData &F, const RecordData &Record, unsigned &Idx); /// \brief Reads a declarator info from the given record. - TypeSourceInfo *GetTypeSourceInfo(llvm::BitstreamCursor &DeclsCursor, + TypeSourceInfo *GetTypeSourceInfo(PerFileData &F, const RecordData &Record, unsigned &Idx); /// \brief Resolve and return the translation unit declaration. @@ -822,6 +987,12 @@ public: Decl *GetDecl(serialization::DeclID ID); virtual Decl *GetExternalDecl(uint32_t ID); + /// \brief Resolve a CXXBaseSpecifiers ID into an offset into the chain + /// of loaded AST files. + uint64_t GetCXXBaseSpecifiersOffset(serialization::CXXBaseSpecifiersID ID); + + virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); + /// \brief Resolve the offset of a statement into a statement. /// /// This operation will read a new statement from the external @@ -857,6 +1028,7 @@ public: /// \returns true if there was an error while reading the /// declarations for this declaration context. virtual bool FindExternalLexicalDecls(const DeclContext *DC, + bool (*isKindWeWant)(Decl::Kind), llvm::SmallVectorImpl<Decl*> &Decls); /// \brief Notify ASTReader that we started deserialization of @@ -897,6 +1069,10 @@ public: return get(Name.begin(), Name.end()); } + /// \brief Retrieve an iterator into the set of all identifiers + /// in all loaded AST files. + virtual IdentifierIterator *getIdentifiers() const; + /// \brief Load the contents of the global method pool for a given /// selector. /// @@ -943,47 +1119,65 @@ public: /// \brief Read a declaration name. DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx); + void ReadDeclarationNameLoc(PerFileData &F, + DeclarationNameLoc &DNLoc, DeclarationName Name, + const RecordData &Record, unsigned &Idx); + void ReadDeclarationNameInfo(PerFileData &F, DeclarationNameInfo &NameInfo, + const RecordData &Record, unsigned &Idx); + + void ReadQualifierInfo(PerFileData &F, QualifierInfo &Info, + const RecordData &Record, unsigned &Idx); NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx); /// \brief Read a template name. - TemplateName ReadTemplateName(const RecordData &Record, unsigned &Idx); + TemplateName ReadTemplateName(PerFileData &F, const RecordData &Record, + unsigned &Idx); /// \brief Read a template argument. - TemplateArgument ReadTemplateArgument(llvm::BitstreamCursor &DeclsCursor, + TemplateArgument ReadTemplateArgument(PerFileData &F, const RecordData &Record,unsigned &Idx); /// \brief Read a template parameter list. - TemplateParameterList *ReadTemplateParameterList(const RecordData &Record, + TemplateParameterList *ReadTemplateParameterList(PerFileData &F, + const RecordData &Record, unsigned &Idx); /// \brief Read a template argument array. void ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs, - llvm::BitstreamCursor &DeclsCursor, - const RecordData &Record, unsigned &Idx); + PerFileData &F, const RecordData &Record, + unsigned &Idx); /// \brief Read a UnresolvedSet structure. void ReadUnresolvedSet(UnresolvedSetImpl &Set, const RecordData &Record, unsigned &Idx); /// \brief Read a C++ base specifier. - CXXBaseSpecifier ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor, + CXXBaseSpecifier ReadCXXBaseSpecifier(PerFileData &F, const RecordData &Record,unsigned &Idx); - /// \brief Read a CXXBaseOrMemberInitializer array. - std::pair<CXXBaseOrMemberInitializer **, unsigned> - ReadCXXBaseOrMemberInitializers(llvm::BitstreamCursor &DeclsCursor, - const RecordData &Record, unsigned &Idx); + /// \brief Read a CXXCtorInitializer array. + std::pair<CXXCtorInitializer **, unsigned> + ReadCXXCtorInitializers(PerFileData &F, const RecordData &Record, + unsigned &Idx); + + /// \brief Read a source location from raw form. + SourceLocation ReadSourceLocation(PerFileData &Module, unsigned Raw) { + (void)Module; // No remapping yet + return SourceLocation::getFromRawEncoding(Raw); + } /// \brief Read a source location. - SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) { - return SourceLocation::getFromRawEncoding(Record[Idx++]); + SourceLocation ReadSourceLocation(PerFileData &Module, + const RecordData &Record, unsigned& Idx) { + return ReadSourceLocation(Module, Record[Idx++]); } /// \brief Read a source range. - SourceRange ReadSourceRange(const RecordData &Record, unsigned& Idx); + SourceRange ReadSourceRange(PerFileData &F, + const RecordData &Record, unsigned& Idx); /// \brief Read an integral value llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx); @@ -1000,13 +1194,14 @@ public: CXXTemporary *ReadCXXTemporary(const RecordData &Record, unsigned &Idx); /// \brief Reads attributes from the current stream position. - void ReadAttributes(llvm::BitstreamCursor &DeclsCursor, AttrVec &Attrs); + void ReadAttributes(PerFileData &F, AttrVec &Attrs, + const RecordData &Record, unsigned &Idx); /// \brief Reads a statement. - Stmt *ReadStmt(llvm::BitstreamCursor &Cursor); + Stmt *ReadStmt(PerFileData &F); /// \brief Reads an expression. - Expr *ReadExpr(llvm::BitstreamCursor &Cursor); + Expr *ReadExpr(PerFileData &F); /// \brief Reads a sub-statement operand during statement reading. Stmt *ReadSubStmt() { @@ -1022,13 +1217,30 @@ public: Expr *ReadSubExpr(); /// \brief Reads the macro record located at the given offset. - void ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset); + PreprocessedEntity *ReadMacroRecord(PerFileData &F, uint64_t Offset); + /// \brief Reads the preprocessed entity located at the current stream + /// position. + PreprocessedEntity *LoadPreprocessedEntity(PerFileData &F); + + /// \brief Note that the identifier is a macro whose record will be loaded + /// from the given AST file at the given (file-local) offset. + void SetIdentifierIsMacro(IdentifierInfo *II, PerFileData &F, + uint64_t Offset); + /// \brief Read the set of macros defined by this external macro source. virtual void ReadDefinedMacros(); + /// \brief Read the macro definition for this identifier. + virtual void LoadMacroDefinition(IdentifierInfo *II); + + /// \brief Read the macro definition corresponding to this iterator + /// into the unread macro record offsets table. + void LoadMacroDefinition( + llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos); + /// \brief Retrieve the macro definition with the given ID. - MacroDefinition *getMacroDefinition(serialization::IdentID ID); + MacroDefinition *getMacroDefinition(serialization::MacroID ID); /// \brief Retrieve the AST context that this AST reader supplements. ASTContext *getContext() { return Context; } @@ -1053,27 +1265,7 @@ public: /// \brief Retrieve the switch-case statement with the given ID. SwitchCase *getSwitchCaseWithID(unsigned ID); - /// \brief Record that the given label statement has been - /// deserialized and has the given ID. - void RecordLabelStmt(LabelStmt *S, unsigned ID); - - /// \brief Set the label of the given statement to the label - /// identified by ID. - /// - /// Depending on the order in which the label and other statements - /// referencing that label occur, this operation may complete - /// immediately (updating the statement) or it may queue the - /// statement to be back-patched later. - void SetLabelOf(GotoStmt *S, unsigned ID); - - /// \brief Set the label of the given expression to the label - /// identified by ID. - /// - /// Depending on the order in which the label and other statements - /// referencing that label occur, this operation may complete - /// immediately (updating the statement) or it may queue the - /// statement to be back-patched later. - void SetLabelOf(AddrLabelExpr *S, unsigned ID); + void ClearSwitchCaseIDs(); }; /// \brief Helper class that saves the current stream position and diff --git a/include/clang/Serialization/ASTSerializationListener.h b/include/clang/Serialization/ASTSerializationListener.h new file mode 100644 index 0000000..0c62e0b --- /dev/null +++ b/include/clang/Serialization/ASTSerializationListener.h @@ -0,0 +1,44 @@ +//===- ASTSerializationListener.h - Decl/Type PCH Write Events -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ASTSerializationListener class, which is notified +// by the ASTWriter when an entity is serialized. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_FRONTEND_AST_SERIALIZATION_LISTENER_H +#define LLVM_CLANG_FRONTEND_AST_SERIALIZATION_LISTENER_H + +#include "llvm/Support/DataTypes.h" + +namespace clang { + +class PreprocessedEntity; + +/// \brief Listener object that receives callbacks when certain kinds of +/// entities are serialized. +class ASTSerializationListener { +public: + virtual ~ASTSerializationListener(); + + /// \brief Callback invoked whenever a preprocessed entity is serialized. + /// + /// This callback will only occur when the translation unit was created with + /// a detailed preprocessing record. + /// + /// \param Entity The entity that has been serialized. + /// + /// \param Offset The offset (in bits) of this entity in the resulting + /// AST file. + virtual void SerializedPreprocessedEntity(PreprocessedEntity *Entity, + uint64_t Offset) = 0; +}; + +} + +#endif 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(); }; |