diff options
author | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
commit | 056abd2059c65a3e908193aeae16fad98017437c (patch) | |
tree | 2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /include/clang/Serialization | |
parent | cc73504950eb7b5dff2dded9bedd67bc36d64641 (diff) | |
download | FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.zip FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.tar.gz |
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):
http://llvm.org/svn/llvm-project/cfe/branches/release_32@168974
Diffstat (limited to 'include/clang/Serialization')
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 234 | ||||
-rw-r--r-- | include/clang/Serialization/ASTDeserializationListener.h | 6 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 476 | ||||
-rw-r--r-- | include/clang/Serialization/ASTWriter.h | 72 | ||||
-rw-r--r-- | include/clang/Serialization/ContinuousRangeMap.h | 4 | ||||
-rw-r--r-- | include/clang/Serialization/Module.h | 66 | ||||
-rw-r--r-- | include/clang/Serialization/ModuleManager.h | 9 |
7 files changed, 597 insertions, 270 deletions
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index dbe6e5a..8c58fb2 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -126,7 +126,13 @@ namespace clang { /// \brief The number of predefined identifier IDs. const unsigned int NUM_PREDEF_IDENT_IDS = 1; + + /// \brief An ID number that refers to a macro in an AST file. + typedef uint32_t MacroID; + /// \brief The number of predefined macro IDs. + const unsigned int NUM_PREDEF_MACRO_IDS = 1; + /// \brief An ID number that refers to an ObjC selector in an AST file. typedef uint32_t SelectorID; @@ -210,7 +216,71 @@ namespace clang { SUBMODULE_BLOCK_ID, /// \brief The block containing comments. - COMMENTS_BLOCK_ID + COMMENTS_BLOCK_ID, + + /// \brief The control block, which contains all of the + /// information that needs to be validated prior to committing + /// to loading the AST file. + CONTROL_BLOCK_ID, + + /// \brief The block of input files, which were used as inputs + /// to create this AST file. + /// + /// This block is part of the control block. + INPUT_FILES_BLOCK_ID + }; + + /// \brief Record types that occur within the control block. + enum ControlRecordTypes { + /// \brief AST file metadata, including the AST file version number + /// and information about the compiler used to build this AST file. + METADATA = 1, + + /// \brief Record code for the list of other AST files imported by + /// this AST file. + IMPORTS = 2, + + /// \brief Record code for the language options table. + /// + /// The record with this code contains the contents of the + /// LangOptions structure. We serialize the entire contents of + /// the structure, and let the reader decide which options are + /// actually important to check. + LANGUAGE_OPTIONS = 3, + + /// \brief Record code for the target options table. + TARGET_OPTIONS = 4, + + /// \brief Record code for the original file that was used to + /// generate the AST file, including both its file ID and its + /// name. + ORIGINAL_FILE = 5, + + /// \brief The directory that the PCH was originally created in. + ORIGINAL_PCH_DIR = 6, + + /// \brief Offsets into the input-files block where input files + /// reside. + INPUT_FILE_OFFSETS = 7, + + /// \brief Record code for the diagnostic options table. + DIAGNOSTIC_OPTIONS = 8, + + /// \brief Record code for the filesystem options table. + FILE_SYSTEM_OPTIONS = 9, + + /// \brief Record code for the headers search options table. + HEADER_SEARCH_OPTIONS = 10, + + /// \brief Record code for the preprocessor options table. + PREPROCESSOR_OPTIONS = 11 + }; + + /// \brief Record types that occur within the input-files block + /// inside the control block. + enum InputFileRecordTypes { + /// \brief An input file. + INPUT_FILE = 1 }; /// \brief Record types that occur within the AST block itself. @@ -241,25 +311,13 @@ namespace clang { /// reserved for the translation unit declaration. DECL_OFFSET = 2, - /// \brief Record code for the language options table. - /// - /// The record with this code contains the contents of the - /// LangOptions structure. We serialize the entire contents of - /// the structure, and let the reader decide which options are - /// actually important to check. - LANGUAGE_OPTIONS = 3, - - /// \brief AST file metadata, including the AST file version number - /// and the target triple used to build the AST file. - METADATA = 4, - /// \brief Record code for the table of offsets of each /// identifier ID. /// /// The offset table contains offsets into the blob stored in /// the IDENTIFIER_TABLE record. Each offset points to the /// NULL-terminated string that corresponds to that identifier. - IDENTIFIER_OFFSET = 5, + IDENTIFIER_OFFSET = 3, /// \brief Record code for the identifier table. /// @@ -273,7 +331,7 @@ namespace clang { /// between offsets (for unresolved identifier IDs) and /// IdentifierInfo pointers (for already-resolved identifier /// IDs). - IDENTIFIER_TABLE = 6, + IDENTIFIER_TABLE = 4, /// \brief Record code for the array of external definitions. /// @@ -283,7 +341,7 @@ namespace clang { /// reported to the AST consumer after the AST file has been /// read, since their presence can affect the semantics of the /// program (e.g., for code generation). - EXTERNAL_DEFINITIONS = 7, + EXTERNAL_DEFINITIONS = 5, /// \brief Record code for the set of non-builtin, special /// types. @@ -292,33 +350,33 @@ namespace clang { /// that are constructed during semantic analysis (e.g., /// __builtin_va_list). The SPECIAL_TYPE_* constants provide /// offsets into this record. - SPECIAL_TYPES = 8, + SPECIAL_TYPES = 6, /// \brief Record code for the extra statistics we gather while /// generating an AST file. - STATISTICS = 9, + STATISTICS = 7, /// \brief Record code for the array of tentative definitions. - TENTATIVE_DEFINITIONS = 10, + TENTATIVE_DEFINITIONS = 8, /// \brief Record code for the array of locally-scoped external /// declarations. - LOCALLY_SCOPED_EXTERNAL_DECLS = 11, + LOCALLY_SCOPED_EXTERNAL_DECLS = 9, /// \brief Record code for the table of offsets into the /// Objective-C method pool. - SELECTOR_OFFSETS = 12, + SELECTOR_OFFSETS = 10, /// \brief Record code for the Objective-C method pool, - METHOD_POOL = 13, + METHOD_POOL = 11, /// \brief The value of the next __COUNTER__ to dispense. /// [PP_COUNTER_VALUE, Val] - PP_COUNTER_VALUE = 14, + PP_COUNTER_VALUE = 12, /// \brief Record code for the table of offsets into the block /// of source-location information. - SOURCE_LOCATION_OFFSETS = 15, + SOURCE_LOCATION_OFFSETS = 13, /// \brief Record code for the set of source location entries /// that need to be preloaded by the AST reader. @@ -326,153 +384,138 @@ namespace clang { /// This set contains the source location entry for the /// predefines buffer and for any file entries that need to be /// preloaded. - SOURCE_LOCATION_PRELOADS = 16, - - /// \brief Record code for the stat() cache. - STAT_CACHE = 17, + SOURCE_LOCATION_PRELOADS = 14, /// \brief Record code for the set of ext_vector type names. - EXT_VECTOR_DECLS = 18, - - /// \brief Record code for the original file that was used to - /// generate the AST file. - ORIGINAL_FILE_NAME = 19, - - /// \brief Record code for the file ID of the original file used to - /// generate the AST file. - ORIGINAL_FILE_ID = 20, - - /// \brief Record code for the version control branch and revision - /// information of the compiler used to build this AST file. - VERSION_CONTROL_BRANCH_REVISION = 21, + EXT_VECTOR_DECLS = 16, /// \brief Record code for the array of unused file scoped decls. - UNUSED_FILESCOPED_DECLS = 22, + UNUSED_FILESCOPED_DECLS = 17, /// \brief Record code for the table of offsets to entries in the /// preprocessing record. - PPD_ENTITIES_OFFSETS = 23, + PPD_ENTITIES_OFFSETS = 18, /// \brief Record code for the array of VTable uses. - VTABLE_USES = 24, + VTABLE_USES = 19, /// \brief Record code for the array of dynamic classes. - DYNAMIC_CLASSES = 25, - - /// \brief Record code for the list of other AST files imported by - /// this AST file. - IMPORTS = 26, + DYNAMIC_CLASSES = 20, /// \brief Record code for referenced selector pool. - REFERENCED_SELECTOR_POOL = 27, + REFERENCED_SELECTOR_POOL = 21, /// \brief Record code for an update to the TU's lexically contained /// declarations. - TU_UPDATE_LEXICAL = 28, + TU_UPDATE_LEXICAL = 22, /// \brief Record code for the array describing the locations (in the /// LOCAL_REDECLARATIONS record) of the redeclaration chains, indexed by /// the first known ID. - LOCAL_REDECLARATIONS_MAP = 29, + LOCAL_REDECLARATIONS_MAP = 23, /// \brief Record code for declarations that Sema keeps references of. - SEMA_DECL_REFS = 30, + SEMA_DECL_REFS = 24, /// \brief Record code for weak undeclared identifiers. - WEAK_UNDECLARED_IDENTIFIERS = 31, + WEAK_UNDECLARED_IDENTIFIERS = 25, /// \brief Record code for pending implicit instantiations. - PENDING_IMPLICIT_INSTANTIATIONS = 32, + PENDING_IMPLICIT_INSTANTIATIONS = 26, /// \brief Record code for a decl replacement block. /// /// If a declaration is modified after having been deserialized, and then /// written to a dependent AST file, its ID and offset must be added to /// the replacement block. - DECL_REPLACEMENTS = 33, + DECL_REPLACEMENTS = 27, /// \brief Record code for an update to a decl context's lookup table. /// /// In practice, this should only be used for the TU and namespaces. - UPDATE_VISIBLE = 34, + UPDATE_VISIBLE = 28, /// \brief Record for offsets of DECL_UPDATES records for declarations /// that were modified after being deserialized and need updates. - DECL_UPDATE_OFFSETS = 35, + DECL_UPDATE_OFFSETS = 29, /// \brief Record of updates for a declaration that was modified after /// being deserialized. - DECL_UPDATES = 36, + DECL_UPDATES = 30, /// \brief Record code for the table of offsets to CXXBaseSpecifier /// sets. - CXX_BASE_SPECIFIER_OFFSETS = 37, + CXX_BASE_SPECIFIER_OFFSETS = 31, /// \brief Record code for \#pragma diagnostic mappings. - DIAG_PRAGMA_MAPPINGS = 38, + DIAG_PRAGMA_MAPPINGS = 32, /// \brief Record code for special CUDA declarations. - CUDA_SPECIAL_DECL_REFS = 39, + CUDA_SPECIAL_DECL_REFS = 33, /// \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, + HEADER_SEARCH_TABLE = 34, /// \brief Record code for floating point \#pragma options. - FP_PRAGMA_OPTIONS = 42, + FP_PRAGMA_OPTIONS = 35, /// \brief Record code for enabled OpenCL extensions. - OPENCL_EXTENSIONS = 43, + OPENCL_EXTENSIONS = 36, /// \brief The list of delegating constructor declarations. - DELEGATING_CTORS = 44, + DELEGATING_CTORS = 37, - /// \brief Record code for the table of offsets into the block - /// of file source-location information. - FILE_SOURCE_LOCATION_OFFSETS = 45, - /// \brief Record code for the set of known namespaces, which are used /// for typo correction. - KNOWN_NAMESPACES = 46, + KNOWN_NAMESPACES = 38, /// \brief Record code for the remapping information used to relate /// loaded modules to the various offsets and IDs(e.g., source location /// offests, declaration and type IDs) that are used in that module to /// refer to other modules. - MODULE_OFFSET_MAP = 47, + MODULE_OFFSET_MAP = 39, /// \brief Record code for the source manager line table information, /// which stores information about \#line directives. - SOURCE_MANAGER_LINE_TABLE = 48, + SOURCE_MANAGER_LINE_TABLE = 40, /// \brief Record code for map of Objective-C class definition IDs to the /// ObjC categories in a module that are attached to that class. - OBJC_CATEGORIES_MAP = 49, + OBJC_CATEGORIES_MAP = 41, /// \brief Record code for a file sorted array of DeclIDs in a module. - FILE_SORTED_DECLS = 50, + FILE_SORTED_DECLS = 42, /// \brief Record code for an array of all of the (sub)modules that were /// imported by the AST file. - IMPORTED_MODULES = 51, + IMPORTED_MODULES = 43, /// \brief Record code for the set of merged declarations in an AST file. - MERGED_DECLARATIONS = 52, + MERGED_DECLARATIONS = 44, /// \brief Record code for the array of redeclaration chains. /// /// This array can only be interpreted properly using the local /// redeclarations map. - LOCAL_REDECLARATIONS = 53, + LOCAL_REDECLARATIONS = 45, /// \brief Record code for the array of Objective-C categories (including /// extensions). /// /// This array can only be interpreted properly using the Objective-C /// categories map. - OBJC_CATEGORIES = 54 + OBJC_CATEGORIES = 46, + + /// \brief Record code for the table of offsets of each macro ID. + /// + /// The offset table contains offsets into the blob stored in + /// the preprocessor block. Each offset points to the corresponding + /// macro definition. + MACRO_OFFSET = 47, + + /// \brief Record of updates for a macro that was modified after + /// being deserialized. + MACRO_UPDATES = 48 }; /// \brief Record types used within a source manager block. @@ -537,16 +580,21 @@ namespace clang { SUBMODULE_UMBRELLA_HEADER = 2, /// \brief Specifies a header that falls into this (sub)module. SUBMODULE_HEADER = 3, + /// \brief Specifies a top-level header that falls into this (sub)module. + SUBMODULE_TOPHEADER = 4, /// \brief Specifies an umbrella directory. - SUBMODULE_UMBRELLA_DIR = 4, + SUBMODULE_UMBRELLA_DIR = 5, /// \brief Specifies the submodules that are imported by this /// submodule. - SUBMODULE_IMPORTS = 5, + SUBMODULE_IMPORTS = 6, /// \brief Specifies the submodules that are re-exported from this /// submodule. - SUBMODULE_EXPORTS = 6, + SUBMODULE_EXPORTS = 7, /// \brief Specifies a required feature. - SUBMODULE_REQUIRES = 7 + SUBMODULE_REQUIRES = 8, + /// \brief Specifies a header that has been explicitly excluded + /// from this submodule. + SUBMODULE_EXCLUDED_HEADER = 9 }; /// \brief Record types used within a comments block. @@ -642,7 +690,9 @@ namespace clang { /// \brief The pseudo-object placeholder type. PREDEF_TYPE_PSEUDO_OBJECT = 35, /// \brief The __va_list_tag placeholder type. - PREDEF_TYPE_VA_LIST_TAG = 36 + PREDEF_TYPE_VA_LIST_TAG = 36, + /// \brief The placeholder type for builtin functions. + PREDEF_TYPE_BUILTIN_FN = 37 }; /// \brief The number of predefined type IDs that are reserved for @@ -943,6 +993,9 @@ namespace clang { /// \brief A NonTypeTemplateParmDecl record that stores an expanded /// non-type template parameter pack. DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK, + /// \brief A TemplateTemplateParmDecl record that stores an expanded + /// template template parameter pack. + DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK, /// \brief A ClassScopeFunctionSpecializationDecl record a class scope /// function specialization. (Microsoft extension). DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION, @@ -999,8 +1052,10 @@ namespace clang { STMT_RETURN, /// \brief A DeclStmt record. STMT_DECL, - /// \brief An AsmStmt record. - STMT_ASM, + /// \brief A GCC-style AsmStmt record. + STMT_GCCASM, + /// \brief A MS-style AsmStmt record. + STMT_MSASM, /// \brief A PredefinedExpr record. EXPR_PREDEFINED, /// \brief A DeclRefExpr record. @@ -1186,6 +1241,7 @@ namespace clang { EXPR_SIZEOF_PACK, // SizeOfPackExpr EXPR_SUBST_NON_TYPE_TEMPLATE_PARM, // SubstNonTypeTemplateParmExpr EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr + EXPR_FUNCTION_PARM_PACK, // FunctionParmPackExpr EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr // CUDA diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h index ab0d313..0218129 100644 --- a/include/clang/Serialization/ASTDeserializationListener.h +++ b/include/clang/Serialization/ASTDeserializationListener.h @@ -23,6 +23,7 @@ class Decl; class ASTReader; class QualType; class MacroDefinition; +class MacroInfo; class Module; class ASTDeserializationListener { @@ -37,6 +38,8 @@ public: /// \brief An identifier was deserialized from the AST file. virtual void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) { } + /// \brief A macro was read from the AST file. + virtual void MacroRead(serialization::MacroID ID, MacroInfo *MI) { } /// \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. @@ -48,9 +51,6 @@ public: /// \brief A macro definition was read from the AST file. virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinition *MD) { } - /// \brief A macro definition that had previously been deserialized - /// (and removed via IdentifierRead) has now been made visible. - virtual void MacroVisible(IdentifierInfo *II) { } /// \brief A module definition was read from the AST file. virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) { } }; diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index f0b7275..e23ea5c 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -24,6 +24,7 @@ #include "clang/AST/TemplateBase.h" #include "clang/Lex/ExternalPreprocessorSource.h" #include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/PPMutationListener.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" @@ -33,6 +34,7 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" @@ -61,6 +63,7 @@ class ASTUnit; // FIXME: Layering violation and egregious hack. class Attr; class Decl; class DeclContext; +class DiagnosticOptions; class NestedNameSpecifier; class CXXBaseSpecifier; class CXXConstructorDecl; @@ -70,6 +73,7 @@ class MacroDefinition; class NamedDecl; class OpaqueValueExpr; class Preprocessor; +class PreprocessorOptions; class Sema; class SwitchCase; class ASTDeserializationListener; @@ -80,15 +84,7 @@ class ASTStmtReader; class TypeLocReader; struct HeaderFileInfo; class VersionTuple; - -struct PCHPredefinesBlock { - /// \brief The file ID for this predefines buffer in a PCH file. - FileID BufferID; - - /// \brief This predefines buffer in a PCH file. - StringRef Data; -}; -typedef SmallVector<PCHPredefinesBlock, 2> PCHPredefinesBlocks; +class TargetOptions; /// \brief Abstract interface for callback invocations by the ASTReader. /// @@ -103,32 +99,58 @@ public: /// \brief Receives the language options. /// /// \returns true to indicate the options are invalid or false otherwise. - virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { + virtual bool ReadLanguageOptions(const LangOptions &LangOpts, + bool Complain) { return false; } - /// \brief Receives the target triple. + /// \brief Receives the target options. /// - /// \returns true to indicate the target triple is invalid or false otherwise. - virtual bool ReadTargetTriple(StringRef Triple) { + /// \returns true to indicate the target options are invalid, or false + /// otherwise. + virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, + bool Complain) { return false; } - /// \brief Receives the contents of the predefines buffer. + /// \brief Receives the diagnostic options. /// - /// \param Buffers Information about the predefines buffers. + /// \returns true to indicate the diagnostic options are invalid, or false + /// otherwise. + virtual bool ReadDiagnosticOptions(const DiagnosticOptions &DiagOpts, + bool Complain) { + return false; + } + + /// \brief Receives the file system options. /// - /// \param OriginalFileName The original file name for the AST file, which - /// will appear as an entry in the predefines buffer. + /// \returns true to indicate the file system options are invalid, or false + /// otherwise. + virtual bool ReadFileSystemOptions(const FileSystemOptions &FSOpts, + bool Complain) { + return false; + } + + /// \brief Receives the header search options. + /// + /// \returns true to indicate the header search options are invalid, or false + /// otherwise. + virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + bool Complain) { + return false; + } + + /// \brief Receives the preprocessor options. /// - /// \param SuggestedPredefines If necessary, additional definitions are added - /// here. + /// \param SuggestedPredefines Can be filled in with the set of predefines + /// that are suggested by the preprocessor options. Typically only used when + /// loading a precompiled header. /// - /// \returns true to indicate the predefines are invalid or false otherwise. - virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, - StringRef OriginalFileName, - std::string &SuggestedPredefines, - FileManager &FileMgr) { + /// \returns true to indicate the preprocessor options are invalid, or false + /// otherwise. + virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, + bool Complain, + std::string &SuggestedPredefines) { return false; } @@ -136,7 +158,8 @@ public: virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) {} /// \brief Receives __COUNTER__ value. - virtual void ReadCounter(unsigned Value) {} + virtual void ReadCounter(const serialization::ModuleFile &M, + unsigned Value) {} }; /// \brief ASTReaderListener implementation to validate the information of @@ -151,14 +174,15 @@ public: PCHValidator(Preprocessor &PP, ASTReader &Reader) : PP(PP), Reader(Reader), NumHeaderInfos(0) {} - virtual bool ReadLanguageOptions(const LangOptions &LangOpts); - virtual bool ReadTargetTriple(StringRef Triple); - virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, - StringRef OriginalFileName, - std::string &SuggestedPredefines, - FileManager &FileMgr); + virtual bool ReadLanguageOptions(const LangOptions &LangOpts, + bool Complain); + virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, + bool Complain); + virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, + bool Complain, + std::string &SuggestedPredefines); virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID); - virtual void ReadCounter(unsigned Value); + virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value); private: void Error(const char *Msg); @@ -201,7 +225,26 @@ class ASTReader public: typedef SmallVector<uint64_t, 64> RecordData; - enum ASTReadResult { Success, Failure, IgnorePCH }; + /// \brief The result of reading the control block of an AST file, which + /// can fail for various reasons. + enum ASTReadResult { + /// \brief The control block was read successfully. Aside from failures, + /// the AST file is safe to read into the current context. + Success, + /// \brief The AST file itself appears corrupted. + Failure, + /// \brief The AST file is out-of-date relative to its input files, + /// and needs to be regenerated. + OutOfDate, + /// \brief The AST file was written by a different version of Clang. + VersionMismatch, + /// \brief The AST file was writtten with a different language/target + /// configuration. + ConfigurationMismatch, + /// \brief The AST file has errors. + HadErrors + }; + /// \brief Types of AST files. friend class PCHValidator; friend class ASTDeclReader; @@ -341,7 +384,15 @@ private: /// \brief The set of C++ or Objective-C classes that have forward /// declarations that have not yet been linked to their definitions. llvm::SmallPtrSet<Decl *, 4> PendingDefinitions; - + + typedef llvm::MapVector<Decl *, uint64_t, + llvm::SmallDenseMap<Decl *, unsigned, 4>, + llvm::SmallVector<std::pair<Decl *, uint64_t>, 4> > + PendingBodiesMap; + + /// \brief Functions or methods that have bodies that will be attached. + PendingBodiesMap PendingBodies; + /// \brief Read the records that describe the contents of declcontexts. bool ReadDeclContextStorage(ModuleFile &M, llvm::BitstreamCursor &Cursor, @@ -359,11 +410,36 @@ private: typedef ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4> GlobalIdentifierMapType; - /// \brief Mapping from global identifer IDs to the module in which the + /// \brief Mapping from global identifier IDs to the module in which the /// identifier resides along with the offset that should be added to the /// global identifier ID to produce a local ID. GlobalIdentifierMapType GlobalIdentifierMap; + /// \brief A vector containing macros that have already been + /// loaded. + /// + /// If the pointer at index I is non-NULL, then it refers to the + /// MacroInfo for the identifier with ID=I+1 that has already + /// been loaded. + std::vector<MacroInfo *> MacrosLoaded; + + typedef ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4> + GlobalMacroMapType; + + /// \brief Mapping from global macro IDs to the module in which the + /// macro resides along with the offset that should be added to the + /// global macro ID to produce a local ID. + GlobalMacroMapType GlobalMacroMap; + + typedef llvm::DenseMap<serialization::MacroID, + llvm::SmallVector<std::pair<serialization::SubmoduleID, + MacroUpdate>, 1> > + MacroUpdatesMap; + + /// \brief Mapping from (global) macro IDs to the set of updates to be + /// performed to the corresponding macro. + MacroUpdatesMap MacroUpdates; + /// \brief A vector containing submodules that have already been loaded. /// /// This vector is indexed by the Submodule ID (-1). NULL submodule entries @@ -378,8 +454,55 @@ private: /// global submodule ID to produce a local ID. GlobalSubmoduleMapType GlobalSubmoduleMap; + /// \brief An entity that has been hidden. + class HiddenName { + public: + enum NameKind { + Declaration, + MacroVisibility, + MacroUndef + } Kind; + + private: + unsigned Loc; + + union { + Decl *D; + MacroInfo *MI; + }; + + IdentifierInfo *Id; + + public: + HiddenName(Decl *D) : Kind(Declaration), Loc(), D(D), Id() { } + + HiddenName(IdentifierInfo *II, MacroInfo *MI) + : Kind(MacroVisibility), Loc(), MI(MI), Id(II) { } + + HiddenName(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc) + : Kind(MacroUndef), Loc(Loc.getRawEncoding()), MI(MI), Id(II) { } + + NameKind getKind() const { return Kind; } + + Decl *getDecl() const { + assert(getKind() == Declaration && "Hidden name is not a declaration"); + return D; + } + + std::pair<IdentifierInfo *, MacroInfo *> getMacro() const { + assert((getKind() == MacroUndef || getKind() == MacroVisibility) + && "Hidden name is not a macro!"); + return std::make_pair(Id, MI); + } + + SourceLocation getMacroUndefLoc() const { + assert(getKind() == MacroUndef && "Hidden name is not an undef!"); + return SourceLocation::getFromRawEncoding(Loc); + } +}; + /// \brief A set of hidden declarations. - typedef llvm::SmallVector<llvm::PointerUnion<Decl *, IdentifierInfo *>, 2> + typedef llvm::SmallVector<HiddenName, 2> HiddenNames; typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType; @@ -431,10 +554,13 @@ private: /// global method pool for this selector. llvm::DenseMap<Selector, unsigned> SelectorGeneration; - /// \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; + typedef llvm::MapVector<IdentifierInfo *, + llvm::SmallVector<serialization::MacroID, 2> > + PendingMacroIDsMap; + + /// \brief Mapping from identifiers that have a macro history to the global + /// IDs have not yet been deserialized to the global IDs of those macros. + PendingMacroIDsMap PendingMacroIDs; typedef ContinuousRangeMap<unsigned, ModuleFile *, 4> GlobalPreprocessedEntityMapType; @@ -553,28 +679,9 @@ private: SmallVector<serialization::SubmoduleID, 2> ImportedModules; //@} - /// \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; - - /// \brief The actual original file name that was used to build the primary - /// AST file. - std::string ActualOriginalFileName; - - /// \brief The file ID for the original file that was used to build the - /// primary AST file. - FileID OriginalFileID; - - /// \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; - /// \brief The system include root to be used when loading the /// precompiled header. std::string isysroot; @@ -583,9 +690,6 @@ private: /// headers when they are loaded. bool DisableValidation; - /// \brief Whether to disable the use of stat caches in AST files. - bool DisableStatCache; - /// \brief Whether to accept an AST file with compiler errors. bool AllowASTWithCompilerErrors; @@ -602,10 +706,6 @@ private: SwitchCaseMapTy *CurrSwitchCaseStmts; - /// \brief The number of stat() calls that hit/missed the stat - /// cache. - unsigned NumStatHits, NumStatMisses; - /// \brief The number of source location entries de-serialized from /// the PCH file. unsigned NumSLocEntriesRead; @@ -687,7 +787,7 @@ private: /// Objective-C protocols. std::deque<Decl *> InterestingDecls; - /// \brief The set of redeclarable declaraations that have been deserialized + /// \brief The set of redeclarable declarations that have been deserialized /// since the last time the declaration chains were linked. llvm::SmallPtrSet<Decl *, 16> RedeclsDeserialized; @@ -758,8 +858,8 @@ private: ASTReader &Reader; enum ReadingKind PrevKind; - ReadingKindTracker(const ReadingKindTracker&); // do not implement - ReadingKindTracker &operator=(const ReadingKindTracker&);// do not implement + ReadingKindTracker(const ReadingKindTracker &) LLVM_DELETED_FUNCTION; + void operator=(const ReadingKindTracker &) LLVM_DELETED_FUNCTION; public: ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader) @@ -770,10 +870,6 @@ private: ~ReadingKindTracker() { Reader.ReadingKind = PrevKind; } }; - /// \brief All predefines buffers in the chain, to be treated as if - /// concatenated. - PCHPredefinesBlocks PCHPredefinesBuffers; - /// \brief Suggested contents of the predefines buffer, after this /// PCH file has been processed. /// @@ -787,24 +883,45 @@ private: /// \brief Reads a statement from the specified cursor. Stmt *ReadStmtFromStream(ModuleFile &F); + typedef llvm::PointerIntPair<const FileEntry *, 1, bool> InputFile; + + /// \brief Retrieve the file entry and 'overridden' bit for an input + /// file in the given module file. + InputFile getInputFile(ModuleFile &F, unsigned ID, bool Complain = true); + /// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take /// into account all the necessary relocations. const FileEntry *getFileEntry(StringRef filename); - void MaybeAddSystemRootToFilename(std::string &Filename); + void MaybeAddSystemRootToFilename(ModuleFile &M, std::string &Filename); ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type, - ModuleFile *ImportedBy); - ASTReadResult ReadASTBlock(ModuleFile &F); - bool CheckPredefinesBuffers(); + ModuleFile *ImportedBy, + llvm::SmallVectorImpl<ModuleFile *> &Loaded, + unsigned ClientLoadCapabilities); + ASTReadResult ReadControlBlock(ModuleFile &F, + llvm::SmallVectorImpl<ModuleFile *> &Loaded, + unsigned ClientLoadCapabilities); + bool ReadASTBlock(ModuleFile &F); bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record); - ASTReadResult ReadSourceManagerBlock(ModuleFile &F); - ASTReadResult ReadSLocEntryRecord(int ID); + bool ReadSourceManagerBlock(ModuleFile &F); llvm::BitstreamCursor &SLocCursorForID(int ID); SourceLocation getImportLocation(ModuleFile *F); - ASTReadResult ReadSubmoduleBlock(ModuleFile &F); - bool ParseLanguageOptions(const RecordData &Record); - + bool ReadSubmoduleBlock(ModuleFile &F); + static bool ParseLanguageOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParseTargetOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParseDiagnosticOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParseFileSystemOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParseHeaderSearchOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParsePreprocessorOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener, + std::string &SuggestedPredefines); + struct RecordLocation { RecordLocation(ModuleFile *M, uint64_t O) : F(M), Offset(O) {} @@ -836,18 +953,82 @@ private: /// \brief Find the next module that contains entities and return the ID /// of the first entry. - /// \arg SLocMapI points at a chunk of a module that contains no + /// + /// \param SLocMapI points at a chunk of a module that contains no /// preprocessed entities or the entities it contains are not the /// ones we are looking for. serialization::PreprocessedEntityID findNextPreprocessedEntity( GlobalSLocOffsetMapType::const_iterator SLocMapI) const; - /// \brief Returns (ModuleFile, Local index) pair for \arg GlobalIndex of a + /// \brief Returns (ModuleFile, Local index) pair for \p GlobalIndex of a /// preprocessed entity. std::pair<ModuleFile *, unsigned> getModulePreprocessedEntity(unsigned GlobalIndex); + /// \brief Returns (begin, end) pair for the preprocessed entities of a + /// particular module. + std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> + getModulePreprocessedEntities(ModuleFile &Mod) const; + + class ModuleDeclIterator { + ASTReader *Reader; + ModuleFile *Mod; + const serialization::LocalDeclID *Pos; + + public: + typedef const Decl *value_type; + typedef value_type& reference; + typedef value_type* pointer; + + ModuleDeclIterator() : Reader(0), Mod(0), Pos(0) { } + + ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod, + const serialization::LocalDeclID *Pos) + : Reader(Reader), Mod(Mod), Pos(Pos) { } + + value_type operator*() const { + return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *Pos)); + } + + ModuleDeclIterator &operator++() { + ++Pos; + return *this; + } + + ModuleDeclIterator operator++(int) { + ModuleDeclIterator Prev(*this); + ++Pos; + return Prev; + } + + ModuleDeclIterator &operator--() { + --Pos; + return *this; + } + + ModuleDeclIterator operator--(int) { + ModuleDeclIterator Prev(*this); + --Pos; + return Prev; + } + + friend bool operator==(const ModuleDeclIterator &LHS, + const ModuleDeclIterator &RHS) { + assert(LHS.Reader == RHS.Reader && LHS.Mod == RHS.Mod); + return LHS.Pos == RHS.Pos; + } + + friend bool operator!=(const ModuleDeclIterator &LHS, + const ModuleDeclIterator &RHS) { + assert(LHS.Reader == RHS.Reader && LHS.Mod == RHS.Mod); + return LHS.Pos != RHS.Pos; + } + }; + + std::pair<ModuleDeclIterator, ModuleDeclIterator> + getModuleFileLevelDecls(ModuleFile &Mod); + void PassInterestingDeclsToConsumer(); void PassInterestingDeclToConsumer(Decl *D); @@ -861,8 +1042,8 @@ private: void Error(unsigned DiagID, StringRef Arg1 = StringRef(), StringRef Arg2 = StringRef()); - ASTReader(const ASTReader&); // do not implement - ASTReader &operator=(const ASTReader &); // do not implement + ASTReader(const ASTReader &) LLVM_DELETED_FUNCTION; + void operator=(const ASTReader &) LLVM_DELETED_FUNCTION; public: /// \brief Load the AST file and validate its contents against the given /// Preprocessor. @@ -881,29 +1062,49 @@ public: /// 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. - /// /// \param AllowASTWithCompilerErrors If true, the AST reader will accept an /// AST file the was created out of an AST with compiler errors, /// otherwise it will reject it. ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "", - bool DisableValidation = false, bool DisableStatCache = false, + bool DisableValidation = false, bool AllowASTWithCompilerErrors = false); ~ASTReader(); SourceManager &getSourceManager() const { return SourceMgr; } - /// \brief Load the AST file designated by the given file name. - ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type); + /// \brief Flags that indicate what kind of AST loading failures the client + /// of the AST reader can directly handle. + /// + /// When a client states that it can handle a particular kind of failure, + /// the AST reader will not emit errors when producing that kind of failure. + enum LoadFailureCapabilities { + /// \brief The client can't handle any AST loading failures. + ARR_None = 0, + /// \brief The client can handle an AST file that cannot load because it + /// is out-of-date relative to its input files. + ARR_OutOfDate = 0x1, + /// \brief The client can handle an AST file that cannot load because it + /// was built with a different version of Clang. + ARR_VersionMismatch = 0x2, + /// \brief The client can handle an AST file that cannot load because it's + /// compiled configuration doesn't match that of the context it was + /// loaded into. + ARR_ConfigurationMismatch = 0x4 + }; - /// \brief Checks that no file that is stored in PCH is out-of-sync with - /// the actual file in the file system. - ASTReadResult validateFileEntries(ModuleFile &M); + /// \brief Load the AST file designated by the given file name. + /// + /// \param FileName The name of the AST file to load. + /// + /// \param Type The kind of AST being loaded, e.g., PCH, module, main file, + /// or preamble. + /// + /// \param ClientLoadCapabilities The set of client load-failure + /// capabilities, represented as a bitset of the enumerators of + /// LoadFailureCapabilities. + ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type, + unsigned ClientLoadCapabilities); /// \brief Make the entities in the given module and any of its (non-explicit) /// submodules visible to name lookup. @@ -947,8 +1148,11 @@ public: /// \brief Retrieve the preprocessor. Preprocessor &getPreprocessor() const { return PP; } - /// \brief Retrieve the name of the original source file name - const std::string &getOriginalSourceFile() { return OriginalFileName; } + /// \brief Retrieve the name of the original source file name for the primary + /// module file. + StringRef getOriginalSourceFile() { + return ModuleMgr.getPrimaryModule().OriginalSourceFileName; + } /// \brief Retrieve the name of the original source file name directly from /// the AST file, without actually loading the AST file. @@ -956,6 +1160,21 @@ public: FileManager &FileMgr, DiagnosticsEngine &Diags); + /// \brief Read the control block for the named AST file. + /// + /// \returns true if an error occurred, false otherwise. + static bool readASTFileControlBlock(StringRef Filename, + FileManager &FileMgr, + ASTReaderListener &Listener); + + /// \brief Determine whether the given AST file is acceptable to load into a + /// translation unit with the given language and target options. + static bool isAcceptableASTFile(StringRef Filename, + FileManager &FileMgr, + const LangOptions &LangOpts, + const TargetOptions &TargetOpts, + const PreprocessorOptions &PPOpts); + /// \brief Returns the suggested contents of the predefines buffer, /// which contains a (typically-empty) subset of the predefines /// build prior to including the precompiled header. @@ -968,12 +1187,12 @@ public: virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index); /// \brief Returns a pair of [Begin, End) indices of preallocated - /// preprocessed entities that \arg Range encompasses. + /// preprocessed entities that \p Range encompasses. virtual std::pair<unsigned, unsigned> findPreprocessedEntitiesInRange(SourceRange Range); /// \brief Optionally returns true or false if the preallocated preprocessed - /// entity with index \arg Index came from file \arg FID. + /// entity with index \p Index came from file \p FID. virtual llvm::Optional<bool> isPreprocessedEntityInFileID(unsigned Index, FileID FID); @@ -992,6 +1211,11 @@ public: return static_cast<unsigned>(IdentifiersLoaded.size()); } + /// \brief Returns the number of macros found in the chain. + unsigned getTotalNumMacros() const { + return static_cast<unsigned>(MacrosLoaded.size()); + } + /// \brief Returns the number of types found in the chain. unsigned getTotalNumTypes() const { return static_cast<unsigned>(TypesLoaded.size()); @@ -1065,17 +1289,17 @@ public: /// \brief Map from a local declaration ID within a given module to a /// global declaration ID. - serialization::DeclID getGlobalDeclID(ModuleFile &F, unsigned LocalID) const; + serialization::DeclID getGlobalDeclID(ModuleFile &F, + serialization::LocalDeclID LocalID) const; - /// \brief Returns true if global DeclID \arg ID originated from module - /// \arg M. + /// \brief Returns true if global DeclID \p ID originated from module \p M. bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const; /// \brief Retrieve the module file that owns the given declaration, or NULL /// if the declaration is not from a module file. ModuleFile *getOwningModuleFile(Decl *D); - /// \brief Returns the source location for the decl \arg ID. + /// \brief Returns the source location for the decl \p ID. SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID); /// \brief Resolve a declaration ID into a declaration, potentially @@ -1172,7 +1396,7 @@ public: SmallVectorImpl<Decl*> &Decls); /// \brief Get the decls that are contained in a file in the Offset/Length - /// range. \arg Length can be 0 to indicate a point at \arg Offset instead of + /// range. \p Length can be 0 to indicate a point at \p Offset instead of /// a range. virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length, SmallVectorImpl<Decl *> &Decls); @@ -1285,6 +1509,9 @@ public: } virtual IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) { + // Note that we are loading an identifier. + Deserializing AnIdentifier(this); + return DecodeIdentifierInfo(ID); } @@ -1293,6 +1520,13 @@ public: serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M, unsigned LocalID); + /// \brief Retrieve the macro with the given ID. + MacroInfo *getMacro(serialization::MacroID ID, MacroInfo *Hint = 0); + + /// \brief Retrieve the global macro ID corresponding to the given local + /// ID within the given module file. + serialization::MacroID getGlobalMacroID(ModuleFile &M, unsigned LocalID); + /// \brief Read the source location entry with index ID. virtual bool ReadSLocEntry(int ID); @@ -1404,10 +1638,10 @@ public: llvm::APFloat ReadAPFloat(const RecordData &Record, unsigned &Idx); // \brief Read a string - std::string ReadString(const RecordData &Record, unsigned &Idx); + static std::string ReadString(const RecordData &Record, unsigned &Idx); /// \brief Read a version tuple. - VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx); + static VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx); CXXTemporary *ReadCXXTemporary(ModuleFile &F, const RecordData &Record, unsigned &Idx); @@ -1436,43 +1670,29 @@ public: Expr *ReadSubExpr(); /// \brief Reads the macro record located at the given offset. - void ReadMacroRecord(ModuleFile &F, uint64_t Offset); + void ReadMacroRecord(ModuleFile &F, uint64_t Offset, MacroInfo *Hint = 0); /// \brief Determine the global preprocessed entity ID that corresponds to /// the given local ID within the given module. serialization::PreprocessedEntityID getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const; - /// \brief Note that the identifier is a macro whose record will be loaded - /// from the given AST file at the given (file-local) offset. + /// \brief Note that the identifier has a macro history. /// /// \param II The name of the macro. /// - /// \param F The module file from which the macro definition was deserialized. - /// - /// \param Offset The offset into the module file at which the macro - /// definition is located. - /// - /// \param Visible Whether the macro should be made visible. - void setIdentifierIsMacro(IdentifierInfo *II, ModuleFile &F, - uint64_t Offset, bool Visible); + /// \param IDs The global macro IDs that are associated with this identifier. + void setIdentifierIsMacro(IdentifierInfo *II, + ArrayRef<serialization::MacroID> IDs); /// \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 Update an out-of-date identifier. virtual void updateOutOfDateIdentifier(IdentifierInfo &II); /// \brief Note that this identifier is up-to-date. void markIdentifierUpToDate(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 Load all external visible decls in the given DeclContext. void completeVisibleDeclsMap(const DeclContext *DC); diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index d038d58..ac81e21 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -18,6 +18,7 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/ASTMutationListener.h" +#include "clang/Lex/PPMutationListener.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTDeserializationListener.h" #include "clang/Sema/SemaConsumer.h" @@ -25,6 +26,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SetVector.h" #include "llvm/Bitcode/BitstreamWriter.h" #include <map> @@ -43,14 +45,15 @@ class ASTContext; class NestedNameSpecifier; class CXXBaseSpecifier; class CXXCtorInitializer; +class FileEntry; class FPOptions; class HeaderSearch; class IdentifierResolver; class MacroDefinition; -class MemorizeStatCalls; class OpaqueValueExpr; class OpenCLOptions; class ASTReader; +class MacroInfo; class Module; class PreprocessedEntity; class PreprocessingRecord; @@ -70,6 +73,7 @@ namespace SrcMgr { class SLocEntry; } /// data structures. This bitstream can be de-serialized via an /// instance of the ASTReader class. class ASTWriter : public ASTDeserializationListener, + public PPMutationListener, public ASTMutationListener { public: typedef SmallVector<uint64_t, 64> RecordData; @@ -117,6 +121,10 @@ private: /// \brief Indicates that the AST contained compiler errors. bool ASTHasCompilerErrors; + /// \brief Mapping from input file entries to the index into the + /// offset table where information about that input file is stored. + llvm::DenseMap<const FileEntry *, uint32_t> InputFileIDs; + /// \brief Stores a declaration or a type to be written to the AST file. class DeclOrType { public: @@ -171,8 +179,7 @@ private: /// indicates the index that this particular vector has in the global one. unsigned FirstDeclIndex; }; - typedef llvm::DenseMap<const SrcMgr::SLocEntry *, - DeclIDInFileInfo *> FileDeclIDsTy; + typedef llvm::DenseMap<FileID, DeclIDInFileInfo *> FileDeclIDsTy; /// \brief Map from file SLocEntries to info about the file-level declarations /// that it contains. @@ -215,6 +222,15 @@ private: /// IdentifierInfo. llvm::DenseMap<const IdentifierInfo *, serialization::IdentID> IdentifierIDs; + /// \brief The first ID number we can use for our own macros. + serialization::MacroID FirstMacroID; + + /// \brief The identifier ID that will be assigned to the next new identifier. + serialization::MacroID NextMacroID; + + /// \brief Map that provides the ID numbers of each macro. + llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs; + /// @name FlushStmt Caches /// @{ @@ -250,16 +266,10 @@ private: /// table, indexed by the Selector ID (-1). std::vector<uint32_t> SelectorOffsets; - /// \brief Offsets of each of the macro identifiers into the - /// bitstream. - /// - /// For each identifier that is associated with a macro, this map - /// provides the offset into the bitstream where that macro is - /// defined. - llvm::DenseMap<const IdentifierInfo *, uint64_t> MacroOffsets; + typedef llvm::MapVector<MacroInfo *, MacroUpdate> MacroUpdatesMap; - /// \brief The set of identifiers that had macro definitions at some point. - std::vector<const IdentifierInfo *> DeserializedMacroNames; + /// \brief Updates to macro definitions that were loaded from an AST file. + MacroUpdatesMap MacroUpdates; /// \brief Mapping from macro definitions (as they occur in the preprocessing /// record) to the macro IDs. @@ -403,10 +413,9 @@ private: llvm::DenseSet<Stmt *> &ParentStmts); void WriteBlockInfoBlock(); - void WriteMetadata(ASTContext &Context, StringRef isysroot, - const std::string &OutputFile); - void WriteLanguageOptions(const LangOptions &LangOpts); - void WriteStatCache(MemorizeStatCalls &StatCalls); + void WriteControlBlock(Preprocessor &PP, ASTContext &Context, + StringRef isysroot, const std::string &OutputFile); + void WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot); void WriteSourceManagerBlock(SourceManager &SourceMgr, const Preprocessor &PP, StringRef isysroot); @@ -428,6 +437,7 @@ private: void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver, bool IsModule); void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record); + void WriteMacroUpdates(); void ResolveDeclUpdatesBlocks(); void WriteDeclUpdatesBlocks(); void WriteDeclReplacementsBlock(); @@ -455,7 +465,7 @@ private: void WriteDeclsBlockAbbrevs(); void WriteDecl(ASTContext &Context, Decl *D); - void WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, + void WriteASTCore(Sema &SemaRef, StringRef isysroot, const std::string &OutputFile, Module *WritingModule); @@ -470,15 +480,12 @@ public: /// \param SemaRef a reference to the semantic analysis object that processed /// the AST to be written into the precompiled header. /// - /// \param StatCalls the object that cached all of the stat() calls made while - /// searching for source files and headers. - /// /// \param WritingModule The module that we are writing. If null, we are /// writing a precompiled header. /// /// \param isysroot if non-empty, write a relocatable file whose headers /// are relative to the given system root. - void WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, + void WriteAST(Sema &SemaRef, const std::string &OutputFile, Module *WritingModule, StringRef isysroot, bool hasErrors = false); @@ -501,6 +508,9 @@ public: /// \brief Emit a reference to an identifier. void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record); + /// \brief Emit a reference to a macro. + void addMacroRef(MacroInfo *MI, RecordDataImpl &Record); + /// \brief Emit a Selector (which is a smart pointer reference). void AddSelectorRef(Selector, RecordDataImpl &Record); @@ -518,15 +528,8 @@ public: /// \brief Get the unique number used to refer to the given identifier. serialization::IdentID getIdentifierRef(const IdentifierInfo *II); - /// \brief Retrieve the offset of the macro definition for the given - /// identifier. - /// - /// The identifier must refer to a macro. - uint64_t getMacroOffset(const IdentifierInfo *II) { - assert(MacroOffsets.find(II) != MacroOffsets.end() && - "Identifier does not name a macro"); - return MacroOffsets[II]; - } + /// \brief Get the unique number used to refer to the given macro. + serialization::MacroID getMacroRef(MacroInfo *MI); /// \brief Emit a reference to a type. void AddTypeRef(QualType T, RecordDataImpl &Record); @@ -689,13 +692,16 @@ public: // ASTDeserializationListener implementation void ReaderInitialized(ASTReader *Reader); void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II); + void MacroRead(serialization::MacroID ID, MacroInfo *MI); void TypeRead(serialization::TypeIdx Idx, QualType T); void SelectorRead(serialization::SelectorID ID, Selector Sel); void MacroDefinitionRead(serialization::PreprocessedEntityID ID, MacroDefinition *MD); - void MacroVisible(IdentifierInfo *II); void ModuleRead(serialization::SubmoduleID ID, Module *Mod); - + + // PPMutationListener implementation. + virtual void UndefinedMacro(MacroInfo *MI); + // ASTMutationListener implementation. virtual void CompletedTagDefinition(const TagDecl *D); virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D); @@ -722,7 +728,6 @@ class PCHGenerator : public SemaConsumer { std::string isysroot; raw_ostream *Out; Sema *SemaPtr; - MemorizeStatCalls *StatCalls; // owned by the FileManager llvm::SmallVector<char, 128> Buffer; llvm::BitstreamWriter Stream; ASTWriter Writer; @@ -738,6 +743,7 @@ public: ~PCHGenerator(); virtual void InitializeSema(Sema &S) { SemaPtr = &S; } virtual void HandleTranslationUnit(ASTContext &Ctx); + virtual PPMutationListener *GetPPMutationListener(); virtual ASTMutationListener *GetASTMutationListener(); virtual ASTDeserializationListener *GetASTDeserializationListener(); }; diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h index f368a80..d89cd02 100644 --- a/include/clang/Serialization/ContinuousRangeMap.h +++ b/include/clang/Serialization/ContinuousRangeMap.h @@ -108,8 +108,8 @@ public: class Builder { ContinuousRangeMap &Self; - Builder(const Builder&); // DO NOT IMPLEMENT - Builder &operator=(const Builder&); // DO NOT IMPLEMENT + Builder(const Builder&) LLVM_DELETED_FUNCTION; + Builder &operator=(const Builder&) LLVM_DELETED_FUNCTION; public: explicit Builder(ContinuousRangeMap &Self) : Self(Self) { } diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h index 786ecd3..39fa3d9 100644 --- a/include/clang/Serialization/Module.h +++ b/include/clang/Serialization/Module.h @@ -25,6 +25,7 @@ namespace clang { +class FileEntry; class DeclContext; class Module; template<typename Info> class OnDiskChainedHashTable; @@ -74,6 +75,29 @@ public: /// \brief The file name of the module file. std::string FileName; + /// \brief The original source file name that was used to build the + /// primary AST file, which may have been modified for + /// relocatable-pch support. + std::string OriginalSourceFileName; + + /// \brief The actual original source file name that was used to + /// build this AST file. + std::string ActualOriginalSourceFileName; + + /// \brief The file ID for the original source file that was used to + /// build this AST file. + FileID OriginalSourceFileID; + + /// \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 Whether this precompiled header is a relocatable PCH file. + bool RelocatablePCH; + + /// \brief The file entry for the module file. + const FileEntry *File; + /// \brief Whether this module has been directly imported by the /// user. bool DirectlyImported; @@ -98,11 +122,24 @@ public: llvm::BitstreamCursor Stream; /// \brief The source location where this module was first imported. + /// FIXME: This is not properly initialized yet. SourceLocation ImportLoc; /// \brief The first source location in this module. SourceLocation FirstLoc; + // === Input Files === + /// \brief The cursor to the start of the input-files block. + llvm::BitstreamCursor InputFilesCursor; + + /// \brief Offsets for all of the input file entries in the AST file. + const uint32_t *InputFileOffsets; + + /// \brief The input files that have been loaded from this AST file, along + /// with a bool indicating whether this was an overridden buffer. + std::vector<llvm::PointerIntPair<const FileEntry *, 1, bool> > + InputFilesLoaded; + // === Source Locations === /// \brief Cursor used to read source location entries. @@ -124,13 +161,6 @@ public: /// \brief SLocEntries that we're going to preload. SmallVector<uint64_t, 4> PreloadSLocEntries; - /// \brief The number of source location file entries in this AST file. - unsigned LocalNumSLocFileEntries; - - /// \brief Offsets for all of the source location file entries in the - /// AST file. - const uint32_t *SLocFileOffsets; - /// \brief Remapping table for source locations in this module. ContinuousRangeMap<uint32_t, int, 2> SLocRemap; @@ -168,6 +198,22 @@ public: /// all of the macro definitions. llvm::BitstreamCursor MacroCursor; + /// \brief The number of macros in this AST file. + unsigned LocalNumMacros; + + /// \brief Offsets of macros in the preprocessor block. + /// + /// This array is indexed by the macro ID (-1), and provides + /// the offset into the preprocessor block where macro definitions are + /// stored. + const uint32_t *MacroOffsets; + + /// \brief Base macro ID for macros local to this module. + serialization::MacroID BaseMacroID; + + /// \brief Remapping table for macro IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> MacroRemap; + /// \brief The offset of the start of the set of defined macros. uint64_t MacroStartOffset; @@ -294,6 +340,7 @@ public: /// \brief Array of file-level DeclIDs sorted by file. const serialization::DeclID *FileSortedDecls; + unsigned NumFileSortedDecls; /// \brief Array of redeclaration chain location information within this /// module file, sorted by the first declaration ID. @@ -338,11 +385,6 @@ public: /// \brief Diagnostic IDs and their mappings that the user changed. SmallVector<uint64_t, 8> PragmaDiagMappings; - /// \brief The AST stat cache installed for this file, if any. - /// - /// The dynamic type of this stat cache is always ASTStatCache - void *StatCache; - /// \brief List of modules which depend on this module llvm::SetVector<ModuleFile *> ImportedBy; diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h index 6ff0640..6dcaa21 100644 --- a/include/clang/Serialization/ModuleManager.h +++ b/include/clang/Serialization/ModuleManager.h @@ -34,7 +34,7 @@ class ModuleManager { /// \brief FileManager that handles translating between filenames and /// FileEntry *. - FileManager FileMgr; + FileManager &FileMgr; /// \brief A lookup of in-memory (virtual file) buffers llvm::DenseMap<const FileEntry *, llvm::MemoryBuffer *> InMemoryBuffers; @@ -45,7 +45,7 @@ public: typedef SmallVector<ModuleFile*, 2>::reverse_iterator ModuleReverseIterator; typedef std::pair<uint32_t, StringRef> ModuleOffset; - ModuleManager(const FileSystemOptions &FSO); + explicit ModuleManager(FileManager &FileMgr); ~ModuleManager(); /// \brief Forward iterator to traverse all loaded modules. This is reverse @@ -105,7 +105,10 @@ public: std::pair<ModuleFile *, bool> addModule(StringRef FileName, ModuleKind Type, ModuleFile *ImportedBy, unsigned Generation, std::string &ErrorStr); - + + /// \brief Remove the given set of modules. + void removeModules(ModuleIterator first, ModuleIterator last); + /// \brief Add an in-memory buffer the list of known buffers void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer); |