summaryrefslogtreecommitdiffstats
path: root/include/clang/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Serialization')
-rw-r--r--include/clang/Serialization/ASTBitCodes.h103
-rw-r--r--include/clang/Serialization/ASTReader.h347
-rw-r--r--include/clang/Serialization/ASTWriter.h62
-rw-r--r--include/clang/Serialization/ContinuousRangeMap.h1
-rw-r--r--include/clang/Serialization/GlobalModuleIndex.h194
-rw-r--r--include/clang/Serialization/Module.h53
-rw-r--r--include/clang/Serialization/ModuleManager.h148
7 files changed, 730 insertions, 178 deletions
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 8c58fb2..9b685ba 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -18,9 +18,9 @@
#define LLVM_CLANG_FRONTEND_PCHBITCODES_H
#include "clang/AST/Type.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/Bitcode/BitCodes.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/ADT/DenseMap.h"
namespace clang {
namespace serialization {
@@ -35,7 +35,7 @@ namespace clang {
/// Version 4 of AST files also requires that the version control branch and
/// revision match exactly, since there is no backward compatibility of
/// AST files at this time.
- const unsigned VERSION_MAJOR = 4;
+ const unsigned VERSION_MAJOR = 5;
/// \brief AST file minor version number supported by this version of
/// Clang.
@@ -129,7 +129,14 @@ namespace clang {
/// \brief An ID number that refers to a macro in an AST file.
typedef uint32_t MacroID;
-
+
+ /// \brief A global ID number that refers to a macro in an AST file.
+ typedef uint32_t GlobalMacroID;
+
+ /// \brief A local to a module ID number that refers to a macro in an
+ /// AST file.
+ typedef uint32_t LocalMacroID;
+
/// \brief The number of predefined macro IDs.
const unsigned int NUM_PREDEF_MACRO_IDS = 1;
@@ -259,21 +266,25 @@ namespace clang {
/// \brief The directory that the PCH was originally created in.
ORIGINAL_PCH_DIR = 6,
+ /// \brief Record code for file ID of the file or buffer that was used to
+ /// generate the AST file.
+ ORIGINAL_FILE_ID = 7,
+
/// \brief Offsets into the input-files block where input files
/// reside.
- INPUT_FILE_OFFSETS = 7,
+ INPUT_FILE_OFFSETS = 8,
/// \brief Record code for the diagnostic options table.
- DIAGNOSTIC_OPTIONS = 8,
+ DIAGNOSTIC_OPTIONS = 9,
/// \brief Record code for the filesystem options table.
- FILE_SYSTEM_OPTIONS = 9,
+ FILE_SYSTEM_OPTIONS = 10,
/// \brief Record code for the headers search options table.
- HEADER_SEARCH_OPTIONS = 10,
+ HEADER_SEARCH_OPTIONS = 11,
/// \brief Record code for the preprocessor options table.
- PREPROCESSOR_OPTIONS = 11
+ PREPROCESSOR_OPTIONS = 12
};
/// \brief Record types that occur within the input-files block
@@ -319,6 +330,11 @@ namespace clang {
/// NULL-terminated string that corresponds to that identifier.
IDENTIFIER_OFFSET = 3,
+ /// \brief This is so that older clang versions, before the introduction
+ /// of the control block, can read and reject the newer PCH format.
+ /// *DON"T CHANGE THIS NUMBER*.
+ METADATA_OLD_FORMAT = 4,
+
/// \brief Record code for the identifier table.
///
/// The identifier table is a simple blob that contains
@@ -331,7 +347,7 @@ namespace clang {
/// between offsets (for unresolved identifier IDs) and
/// IdentifierInfo pointers (for already-resolved identifier
/// IDs).
- IDENTIFIER_TABLE = 4,
+ IDENTIFIER_TABLE = 5,
/// \brief Record code for the array of external definitions.
///
@@ -341,7 +357,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 = 5,
+ EXTERNAL_DEFINITIONS = 6,
/// \brief Record code for the set of non-builtin, special
/// types.
@@ -350,33 +366,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 = 6,
+ SPECIAL_TYPES = 7,
/// \brief Record code for the extra statistics we gather while
/// generating an AST file.
- STATISTICS = 7,
+ STATISTICS = 8,
/// \brief Record code for the array of tentative definitions.
- TENTATIVE_DEFINITIONS = 8,
+ TENTATIVE_DEFINITIONS = 9,
- /// \brief Record code for the array of locally-scoped external
+ /// \brief Record code for the array of locally-scoped extern "C"
/// declarations.
- LOCALLY_SCOPED_EXTERNAL_DECLS = 9,
+ LOCALLY_SCOPED_EXTERN_C_DECLS = 10,
/// \brief Record code for the table of offsets into the
/// Objective-C method pool.
- SELECTOR_OFFSETS = 10,
+ SELECTOR_OFFSETS = 11,
/// \brief Record code for the Objective-C method pool,
- METHOD_POOL = 11,
+ METHOD_POOL = 12,
/// \brief The value of the next __COUNTER__ to dispense.
/// [PP_COUNTER_VALUE, Val]
- PP_COUNTER_VALUE = 12,
+ PP_COUNTER_VALUE = 13,
/// \brief Record code for the table of offsets into the block
/// of source-location information.
- SOURCE_LOCATION_OFFSETS = 13,
+ SOURCE_LOCATION_OFFSETS = 14,
/// \brief Record code for the set of source location entries
/// that need to be preloaded by the AST reader.
@@ -384,7 +400,7 @@ 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 = 14,
+ SOURCE_LOCATION_PRELOADS = 15,
/// \brief Record code for the set of ext_vector type names.
EXT_VECTOR_DECLS = 16,
@@ -513,9 +529,13 @@ namespace clang {
/// macro definition.
MACRO_OFFSET = 47,
- /// \brief Record of updates for a macro that was modified after
- /// being deserialized.
- MACRO_UPDATES = 48
+ /// \brief Mapping table from the identifier ID to the offset of the
+ /// macro directive history for the identifier.
+ MACRO_TABLE = 48,
+
+ /// \brief Record code for undefined but used functions and variables that
+ /// need a definition in this TU.
+ UNDEFINED_BUT_USED = 49
};
/// \brief Record types used within a source manager block.
@@ -552,7 +572,10 @@ namespace clang {
/// \brief Describes one token.
/// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
- PP_TOKEN = 3
+ PP_TOKEN = 3,
+
+ /// \brief The macro directives history for a particular identifier.
+ PP_MACRO_DIRECTIVE_HISTORY = 4
};
/// \brief Record types used within a preprocessor detail block.
@@ -594,7 +617,13 @@ namespace clang {
SUBMODULE_REQUIRES = 8,
/// \brief Specifies a header that has been explicitly excluded
/// from this submodule.
- SUBMODULE_EXCLUDED_HEADER = 9
+ SUBMODULE_EXCLUDED_HEADER = 9,
+ /// \brief Specifies a library or framework to link against.
+ SUBMODULE_LINK_LIBRARY = 10,
+ /// \brief Specifies a configuration macro for this module.
+ SUBMODULE_CONFIG_MACRO = 11,
+ /// \brief Specifies a conflict with another module.
+ SUBMODULE_CONFLICT = 12
};
/// \brief Record types used within a comments block.
@@ -692,7 +721,23 @@ namespace clang {
/// \brief The __va_list_tag placeholder type.
PREDEF_TYPE_VA_LIST_TAG = 36,
/// \brief The placeholder type for builtin functions.
- PREDEF_TYPE_BUILTIN_FN = 37
+ PREDEF_TYPE_BUILTIN_FN = 37,
+ /// \brief OpenCL 1d image type.
+ PREDEF_TYPE_IMAGE1D_ID = 38,
+ /// \brief OpenCL 1d image array type.
+ PREDEF_TYPE_IMAGE1D_ARR_ID = 39,
+ /// \brief OpenCL 1d image buffer type.
+ PREDEF_TYPE_IMAGE1D_BUFF_ID = 40,
+ /// \brief OpenCL 2d image type.
+ PREDEF_TYPE_IMAGE2D_ID = 41,
+ /// \brief OpenCL 2d image array type.
+ PREDEF_TYPE_IMAGE2D_ARR_ID = 42,
+ /// \brief OpenCL 3d image type.
+ PREDEF_TYPE_IMAGE3D_ID = 43,
+ /// \brief OpenCL event type.
+ PREDEF_TYPE_EVENT_ID = 44,
+ /// \brief OpenCL sampler type.
+ PREDEF_TYPE_SAMPLER_ID = 45
};
/// \brief The number of predefined type IDs that are reserved for
@@ -1000,7 +1045,11 @@ namespace clang {
/// function specialization. (Microsoft extension).
DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION,
/// \brief An ImportDecl recording a module import.
- DECL_IMPORT
+ DECL_IMPORT,
+ /// \brief A OMPThreadPrivateDecl record.
+ DECL_OMP_THREADPRIVATE,
+ /// \brief An EmptyDecl record.
+ DECL_EMPTY
};
/// \brief Record codes for each kind of statement or expression.
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index e23ea5c..9255336 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -14,33 +14,33 @@
#ifndef LLVM_CLANG_FRONTEND_AST_READER_H
#define LLVM_CLANG_FRONTEND_AST_READER_H
-#include "clang/Serialization/ASTBitCodes.h"
-#include "clang/Serialization/ContinuousRangeMap.h"
-#include "clang/Serialization/Module.h"
-#include "clang/Serialization/ModuleManager.h"
-#include "clang/Sema/ExternalSemaSource.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclarationName.h"
#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"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Version.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Serialization/ASTBitCodes.h"
+#include "clang/Serialization/ContinuousRangeMap.h"
+#include "clang/Serialization/Module.h"
+#include "clang/Serialization/ModuleManager.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/DataTypes.h"
#include <deque>
@@ -48,6 +48,7 @@
#include <string>
#include <utility>
#include <vector>
+#include <sys/stat.h>
namespace llvm {
class MemoryBuffer;
@@ -68,8 +69,10 @@ class NestedNameSpecifier;
class CXXBaseSpecifier;
class CXXConstructorDecl;
class CXXCtorInitializer;
+class GlobalModuleIndex;
class GotoStmt;
class MacroDefinition;
+class MacroDirective;
class NamedDecl;
class OpaqueValueExpr;
class Preprocessor;
@@ -85,6 +88,7 @@ class TypeLocReader;
struct HeaderFileInfo;
class VersionTuple;
class TargetOptions;
+class ASTUnresolvedSet;
/// \brief Abstract interface for callback invocations by the ASTReader.
///
@@ -96,6 +100,14 @@ class ASTReaderListener {
public:
virtual ~ASTReaderListener();
+ /// \brief Receives the full Clang version information.
+ ///
+ /// \returns true to indicate that the version is invalid. Subclasses should
+ /// generally defer to this implementation.
+ virtual bool ReadFullVersionInformation(StringRef FullVersion) {
+ return FullVersion != getClangFullRepositoryVersion();
+ }
+
/// \brief Receives the language options.
///
/// \returns true to indicate the options are invalid or false otherwise.
@@ -233,6 +245,8 @@ public:
Success,
/// \brief The AST file itself appears corrupted.
Failure,
+ /// \brief The AST file was missing.
+ Missing,
/// \brief The AST file is out-of-date relative to its input files,
/// and needs to be regenerated.
OutOfDate,
@@ -291,6 +305,9 @@ private:
/// \brief The module manager which manages modules and their dependencies
ModuleManager ModuleMgr;
+ /// \brief The global module index, if loaded.
+ llvm::OwningPtr<GlobalModuleIndex> GlobalIndex;
+
/// \brief A map of global bit offsets to the module that stores entities
/// at those bit offsets.
ContinuousRangeMap<uint64_t, ModuleFile*, 4> GlobalBitOffsetsMap;
@@ -387,7 +404,7 @@ private:
typedef llvm::MapVector<Decl *, uint64_t,
llvm::SmallDenseMap<Decl *, unsigned, 4>,
- llvm::SmallVector<std::pair<Decl *, uint64_t>, 4> >
+ SmallVector<std::pair<Decl *, uint64_t>, 4> >
PendingBodiesMap;
/// \brief Functions or methods that have bodies that will be attached.
@@ -431,15 +448,6 @@ private:
/// 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
@@ -459,28 +467,22 @@ private:
public:
enum NameKind {
Declaration,
- MacroVisibility,
- MacroUndef
+ MacroVisibility
} Kind;
private:
- unsigned Loc;
-
union {
Decl *D;
- MacroInfo *MI;
+ MacroDirective *MD;
};
IdentifierInfo *Id;
public:
- HiddenName(Decl *D) : Kind(Declaration), Loc(), D(D), Id() { }
+ HiddenName(Decl *D) : Kind(Declaration), 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) { }
+ HiddenName(IdentifierInfo *II, MacroDirective *MD)
+ : Kind(MacroVisibility), MD(MD), Id(II) { }
NameKind getKind() const { return Kind; }
@@ -489,21 +491,14 @@ private:
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);
+ std::pair<IdentifierInfo *, MacroDirective *> getMacro() const {
+ assert(getKind() == MacroVisibility && "Hidden name is not a macro!");
+ return std::make_pair(Id, MD);
}
};
/// \brief A set of hidden declarations.
- typedef llvm::SmallVector<HiddenName, 2>
- HiddenNames;
+ typedef SmallVector<HiddenName, 2> HiddenNames;
typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType;
@@ -512,28 +507,30 @@ private:
HiddenNamesMapType HiddenNamesMap;
- /// \brief A module import or export that hasn't yet been resolved.
- struct UnresolvedModuleImportExport {
+ /// \brief A module import, export, or conflict that hasn't yet been resolved.
+ struct UnresolvedModuleRef {
/// \brief The file in which this module resides.
ModuleFile *File;
/// \brief The module that is importing or exporting.
Module *Mod;
-
+
+ /// \brief The kind of module reference.
+ enum { Import, Export, Conflict } Kind;
+
/// \brief The local ID of the module that is being exported.
unsigned ID;
-
- /// \brief Whether this is an import (vs. an export).
- unsigned IsImport : 1;
-
+
/// \brief Whether this is a wildcard export.
unsigned IsWildcard : 1;
+
+ /// \brief String data.
+ StringRef String;
};
/// \brief The set of module imports and exports that still need to be
/// resolved.
- llvm::SmallVector<UnresolvedModuleImportExport, 2>
- UnresolvedModuleImportExports;
+ SmallVector<UnresolvedModuleRef, 2> UnresolvedModuleRefs;
/// \brief A vector containing selectors that have already been loaded.
///
@@ -546,7 +543,7 @@ private:
GlobalSelectorMapType;
/// \brief Mapping from global selector IDs to the module in which the
- /// selector resides along with the offset that should be added to the
+
/// global selector ID to produce a local ID.
GlobalSelectorMapType GlobalSelectorMap;
@@ -554,8 +551,35 @@ private:
/// global method pool for this selector.
llvm::DenseMap<Selector, unsigned> SelectorGeneration;
- typedef llvm::MapVector<IdentifierInfo *,
- llvm::SmallVector<serialization::MacroID, 2> >
+ struct PendingMacroInfo {
+ ModuleFile *M;
+
+ struct ModuleMacroDataTy {
+ serialization::GlobalMacroID GMacID;
+ unsigned ImportLoc;
+ };
+ struct PCHMacroDataTy {
+ uint64_t MacroDirectivesOffset;
+ };
+
+ union {
+ ModuleMacroDataTy ModuleMacroData;
+ PCHMacroDataTy PCHMacroData;
+ };
+
+ PendingMacroInfo(ModuleFile *M,
+ serialization::GlobalMacroID GMacID,
+ SourceLocation ImportLoc) : M(M) {
+ ModuleMacroData.GMacID = GMacID;
+ ModuleMacroData.ImportLoc = ImportLoc.getRawEncoding();
+ }
+
+ PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) : M(M) {
+ PCHMacroData.MacroDirectivesOffset = MacroDirectivesOffset;
+ }
+ };
+
+ typedef llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2> >
PendingMacroIDsMap;
/// \brief Mapping from identifiers that have a macro history to the global
@@ -637,11 +661,11 @@ private:
/// \brief Fields containing data that is used for semantic analysis
//@{
- /// \brief The IDs of all locally scoped external decls in the chain.
+ /// \brief The IDs of all locally scoped extern "C" decls in the chain.
///
/// Sema tracks these to validate that the types are consistent across all
- /// local external declarations.
- SmallVector<uint64_t, 16> LocallyScopedExternalDecls;
+ /// local extern "C" declarations.
+ SmallVector<uint64_t, 16> LocallyScopedExternCDecls;
/// \brief The IDs of all dynamic class declarations in the chain.
///
@@ -674,6 +698,10 @@ private:
/// \brief A list of the namespaces we've seen.
SmallVector<uint64_t, 4> KnownNamespaces;
+ /// \brief A list of undefined decls with internal linkage followed by the
+ /// SourceLocation of a matching ODR-use.
+ SmallVector<uint64_t, 8> UndefinedButUsed;
+
/// \brief A list of modules that were imported by precompiled headers or
/// any other non-module AST file.
SmallVector<serialization::SubmoduleID, 2> ImportedModules;
@@ -693,6 +721,12 @@ private:
/// \brief Whether to accept an AST file with compiler errors.
bool AllowASTWithCompilerErrors;
+ /// \brief Whether we are allowed to use the global module index.
+ bool UseGlobalIndex;
+
+ /// \brief Whether we have tried loading the global module index yet.
+ bool TriedLoadingGlobalIndex;
+
/// \brief The current "generation" of the module file import stack, which
/// indicates how many separate module file load operations have occurred.
unsigned CurrentGeneration;
@@ -727,6 +761,12 @@ private:
/// \brief The total number of macros stored in the chain.
unsigned TotalNumMacros;
+ /// \brief The number of lookups into identifier tables.
+ unsigned NumIdentifierLookups;
+
+ /// \brief The number of lookups into identifier tables that succeed.
+ unsigned NumIdentifierLookupHits;
+
/// \brief The number of selectors that have been read.
unsigned NumSelectorsRead;
@@ -734,8 +774,20 @@ private:
unsigned NumMethodPoolEntriesRead;
/// \brief The number of times we have looked up a selector in the method
- /// pool and not found anything interesting.
- unsigned NumMethodPoolMisses;
+ /// pool.
+ unsigned NumMethodPoolLookups;
+
+ /// \brief The number of times we have looked up a selector in the method
+ /// pool and found something.
+ unsigned NumMethodPoolHits;
+
+ /// \brief The number of times we have looked up a selector in the method
+ /// pool within a specific module.
+ unsigned NumMethodPoolTableLookups;
+
+ /// \brief The number of times we have looked up a selector in the method
+ /// pool within a specific module and found something.
+ unsigned NumMethodPoolTableHits;
/// \brief The total number of method pool entries in the selector table.
unsigned TotalNumMethodPoolEntries;
@@ -761,19 +813,13 @@ private:
/// Number of CXX base specifiers currently loaded
unsigned NumCXXBaseSpecifiersLoaded;
- /// \brief An IdentifierInfo that has been loaded but whose top-level
- /// declarations of the same name have not (yet) been loaded.
- struct PendingIdentifierInfo {
- IdentifierInfo *II;
- SmallVector<uint32_t, 4> DeclIDs;
- };
-
/// \brief The set of identifiers that were read while the AST reader was
/// (recursively) loading declarations.
///
/// The declarations on the identifier chain for these identifiers will be
/// loaded once the recursive loading has completed.
- std::deque<PendingIdentifierInfo> PendingIdentifierInfos;
+ llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4> >
+ PendingIdentifierInfos;
/// \brief The generation number of each identifier, which keeps track of
/// the last time we loaded information about this identifier.
@@ -797,11 +843,26 @@ private:
/// Each element is the global declaration ID of the first declaration in
/// the chain. Elements in this vector should be unique; use
/// PendingDeclChainsKnown to ensure uniqueness.
- llvm::SmallVector<serialization::DeclID, 16> PendingDeclChains;
+ SmallVector<serialization::DeclID, 16> PendingDeclChains;
/// \brief Keeps track of the elements added to PendingDeclChains.
llvm::SmallSet<serialization::DeclID, 16> PendingDeclChainsKnown;
+ /// \brief The Decl IDs for the Sema/Lexical DeclContext of a Decl that has
+ /// been loaded but its DeclContext was not set yet.
+ struct PendingDeclContextInfo {
+ Decl *D;
+ serialization::GlobalDeclID SemaDC;
+ serialization::GlobalDeclID LexicalDC;
+ };
+
+ /// \brief The set of Decls that have been loaded but their DeclContexts are
+ /// not set yet.
+ ///
+ /// The DeclContexts for these Decls will be set once recursive loading has
+ /// been completed.
+ std::deque<PendingDeclContextInfo> PendingDeclContextInfos;
+
/// \brief The set of Objective-C categories that have been deserialized
/// since the last time the declaration chains were linked.
llvm::SmallPtrSet<ObjCCategoryDecl *, 16> CategoriesDeserialized;
@@ -809,9 +870,9 @@ private:
/// \brief The set of Objective-C class definitions that have already been
/// loaded, for which we will need to check for categories whenever a new
/// module is loaded.
- llvm::SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
+ SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
- typedef llvm::DenseMap<Decl *, llvm::SmallVector<serialization::DeclID, 2> >
+ typedef llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2> >
MergedDeclsMap;
/// \brief A mapping from canonical declarations to the set of additional
@@ -820,7 +881,7 @@ private:
MergedDeclsMap MergedDecls;
typedef llvm::DenseMap<serialization::GlobalDeclID,
- llvm::SmallVector<serialization::DeclID, 2> >
+ SmallVector<serialization::DeclID, 2> >
StoredMergedDeclsMap;
/// \brief A mapping from canonical declaration IDs to the set of additional
@@ -883,11 +944,10 @@ 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);
+ serialization::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.
@@ -895,12 +955,24 @@ private:
void MaybeAddSystemRootToFilename(ModuleFile &M, std::string &Filename);
+ struct ImportedModule {
+ ModuleFile *Mod;
+ ModuleFile *ImportedBy;
+ SourceLocation ImportLoc;
+
+ ImportedModule(ModuleFile *Mod,
+ ModuleFile *ImportedBy,
+ SourceLocation ImportLoc)
+ : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) { }
+ };
+
ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type,
- ModuleFile *ImportedBy,
- llvm::SmallVectorImpl<ModuleFile *> &Loaded,
+ SourceLocation ImportLoc, ModuleFile *ImportedBy,
+ SmallVectorImpl<ImportedModule> &Loaded,
+ off_t ExpectedSize, time_t ExpectedModTime,
unsigned ClientLoadCapabilities);
ASTReadResult ReadControlBlock(ModuleFile &F,
- llvm::SmallVectorImpl<ModuleFile *> &Loaded,
+ SmallVectorImpl<ImportedModule> &Loaded,
unsigned ClientLoadCapabilities);
bool ReadASTBlock(ModuleFile &F);
bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record);
@@ -1034,6 +1106,14 @@ private:
void finishPendingActions();
+ void addPendingDeclContextInfo(Decl *D,
+ serialization::GlobalDeclID SemaDC,
+ serialization::GlobalDeclID LexicalDC) {
+ assert(D);
+ PendingDeclContextInfo Info = { D, SemaDC, LexicalDC };
+ PendingDeclContextInfos.push_back(Info);
+ }
+
/// \brief Produce an error diagnostic and return true.
///
/// This routine should only be used for fatal errors that have to
@@ -1065,13 +1145,18 @@ public:
/// \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.
+ ///
+ /// \param UseGlobalIndex If true, the AST reader will try to load and use
+ /// the global module index.
ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "",
bool DisableValidation = false,
- bool AllowASTWithCompilerErrors = false);
+ bool AllowASTWithCompilerErrors = false,
+ bool UseGlobalIndex = true);
~ASTReader();
SourceManager &getSourceManager() const { return SourceMgr; }
+ FileManager &getFileManager() const { return FileMgr; }
/// \brief Flags that indicate what kind of AST loading failures the client
/// of the AST reader can directly handle.
@@ -1082,15 +1167,18 @@ public:
/// \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 missing.
+ ARR_Missing = 0x1,
+ /// \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,
+ ARR_OutOfDate = 0x2,
/// \brief The client can handle an AST file that cannot load because it
/// was built with a different version of Clang.
- ARR_VersionMismatch = 0x2,
+ ARR_VersionMismatch = 0x4,
/// \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
+ ARR_ConfigurationMismatch = 0x8
};
/// \brief Load the AST file designated by the given file name.
@@ -1100,10 +1188,14 @@ public:
/// \param Type The kind of AST being loaded, e.g., PCH, module, main file,
/// or preamble.
///
+ /// \param ImportLoc the location where the module file will be considered as
+ /// imported from. For non-module AST types it should be invalid.
+ ///
/// \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,
+ SourceLocation ImportLoc,
unsigned ClientLoadCapabilities);
/// \brief Make the entities in the given module and any of its (non-explicit)
@@ -1113,11 +1205,17 @@ public:
///
/// \param NameVisibility The level of visibility to give the names in the
/// module. Visibility can only be increased over time.
+ ///
+ /// \param ImportLoc The location at which the import occurs.
+ ///
+ /// \param Complain Whether to complain about conflicting module imports.
void makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind NameVisibility);
+ Module::NameVisibilityKind NameVisibility,
+ SourceLocation ImportLoc,
+ bool Complain);
/// \brief Make the names within this set of hidden names visible.
- void makeNamesVisible(const HiddenNames &Names);
+ void makeNamesVisible(const HiddenNames &Names, Module *Owner);
/// \brief Set the AST callbacks listener.
void setListener(ASTReaderListener *listener) {
@@ -1127,6 +1225,18 @@ public:
/// \brief Set the AST deserialization listener.
void setDeserializationListener(ASTDeserializationListener *Listener);
+ /// \brief Determine whether this AST reader has a global index.
+ bool hasGlobalIndex() const { return GlobalIndex; }
+
+ /// \brief Attempts to load the global index.
+ ///
+ /// \returns true if loading the global index has failed for any reason.
+ bool loadGlobalIndex();
+
+ /// \brief Determine whether we tried to load the global index, but failed,
+ /// e.g., because it is out-of-date or does not exist.
+ bool isGlobalIndexUnavailable() const;
+
/// \brief Initializes the ASTContext
void InitializeContext();
@@ -1193,8 +1303,8 @@ public:
/// \brief Optionally returns true or false if the preallocated preprocessed
/// entity with index \p Index came from file \p FID.
- virtual llvm::Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
- FileID FID);
+ virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+ FileID FID);
/// \brief Read the header file information for the given file entry.
virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE);
@@ -1297,7 +1407,7 @@ public:
/// \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);
+ ModuleFile *getOwningModuleFile(const Decl *D);
/// \brief Returns the source location for the decl \p ID.
SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
@@ -1374,7 +1484,7 @@ public:
/// \brief Finds all the visible declarations with a given name.
/// The current implementation of this method just loads the entire
/// lookup table as unmaterialized references.
- virtual DeclContext::lookup_result
+ virtual bool
FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name);
@@ -1459,6 +1569,9 @@ public:
virtual void ReadKnownNamespaces(
SmallVectorImpl<NamespaceDecl *> &Namespaces);
+ virtual void ReadUndefinedButUsed(
+ llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined);
+
virtual void ReadTentativeDefinitions(
SmallVectorImpl<VarDecl *> &TentativeDefs);
@@ -1472,7 +1585,7 @@ public:
virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls);
- virtual void ReadLocallyScopedExternalDecls(
+ virtual void ReadLocallyScopedExternCDecls(
SmallVectorImpl<NamedDecl *> &Decls);
virtual void ReadReferencedSelectors(
@@ -1493,7 +1606,7 @@ public:
void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
void SetGloballyVisibleDecls(IdentifierInfo *II,
const SmallVectorImpl<uint32_t> &DeclIDs,
- bool Nonrecursive = false);
+ SmallVectorImpl<Decl *> *Decls = 0);
/// \brief Report a diagnostic.
DiagnosticBuilder Diag(unsigned DiagID);
@@ -1520,8 +1633,16 @@ public:
serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M,
unsigned LocalID);
+ void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
+
+ void installPCHMacroDirectives(IdentifierInfo *II,
+ ModuleFile &M, uint64_t Offset);
+
+ void installImportedMacro(IdentifierInfo *II, MacroDirective *MD,
+ Module *Owner);
+
/// \brief Retrieve the macro with the given ID.
- MacroInfo *getMacro(serialization::MacroID ID, MacroInfo *Hint = 0);
+ MacroInfo *getMacro(serialization::MacroID ID);
/// \brief Retrieve the global macro ID corresponding to the given local
/// ID within the given module file.
@@ -1530,6 +1651,10 @@ public:
/// \brief Read the source location entry with index ID.
virtual bool ReadSLocEntry(int ID);
+ /// \brief Retrieve the module import location and module name for the
+ /// given source manager entry ID.
+ virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID);
+
/// \brief Retrieve the global submodule ID given a module and its local ID
/// number.
serialization::SubmoduleID
@@ -1538,7 +1663,12 @@ public:
/// \brief Retrieve the submodule that corresponds to a global submodule ID.
///
Module *getSubmodule(serialization::SubmoduleID GlobalID);
-
+
+ /// \brief Retrieve the module that corresponds to the given module ID.
+ ///
+ /// Note: overrides method in ExternalASTSource
+ virtual Module *getModule(unsigned ID);
+
/// \brief Retrieve a selector from the given module with its local ID
/// number.
Selector getLocalSelector(ModuleFile &M, unsigned LocalID);
@@ -1597,7 +1727,7 @@ public:
unsigned &Idx);
/// \brief Read a UnresolvedSet structure.
- void ReadUnresolvedSet(ModuleFile &F, UnresolvedSetImpl &Set,
+ void ReadUnresolvedSet(ModuleFile &F, ASTUnresolvedSet &Set,
const RecordData &Record, unsigned &Idx);
/// \brief Read a C++ base specifier.
@@ -1620,13 +1750,13 @@ public:
/// \brief Read a source location.
SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
- const RecordData &Record, unsigned& Idx) {
+ const RecordData &Record, unsigned &Idx) {
return ReadSourceLocation(ModuleFile, Record[Idx++]);
}
/// \brief Read a source range.
SourceRange ReadSourceRange(ModuleFile &F,
- const RecordData &Record, unsigned& Idx);
+ const RecordData &Record, unsigned &Idx);
/// \brief Read an integral value
llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
@@ -1635,7 +1765,8 @@ public:
llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx);
/// \brief Read a floating-point value
- llvm::APFloat ReadAPFloat(const RecordData &Record, unsigned &Idx);
+ llvm::APFloat ReadAPFloat(const RecordData &Record,
+ const llvm::fltSemantics &Sem, unsigned &Idx);
// \brief Read a string
static std::string ReadString(const RecordData &Record, unsigned &Idx);
@@ -1670,20 +1801,32 @@ public:
Expr *ReadSubExpr();
/// \brief Reads the macro record located at the given offset.
- void ReadMacroRecord(ModuleFile &F, uint64_t Offset, MacroInfo *Hint = 0);
+ MacroInfo *ReadMacroRecord(ModuleFile &F, uint64_t Offset);
/// \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 has a macro history.
+ /// \brief Add a macro to resolve imported from a module.
///
/// \param II The name of the macro.
+ /// \param M The module file.
+ /// \param GMacID The global macro ID that is associated with this identifier.
+ /// \param ImportLoc The location where the module is imported.
+ void addPendingMacroFromModule(IdentifierInfo *II,
+ ModuleFile *M,
+ serialization::GlobalMacroID GMacID,
+ SourceLocation ImportLoc);
+
+ /// \brief Add a macro to deserialize its macro directive history from a PCH.
///
- /// \param IDs The global macro IDs that are associated with this identifier.
- void setIdentifierIsMacro(IdentifierInfo *II,
- ArrayRef<serialization::MacroID> IDs);
+ /// \param II The name of the macro.
+ /// \param M The module file.
+ /// \param MacroDirectivesOffset Offset of the serialized macro directive
+ /// history.
+ void addPendingMacroFromPCH(IdentifierInfo *II,
+ ModuleFile *M, uint64_t MacroDirectivesOffset);
/// \brief Read the set of macros defined by this external macro source.
virtual void ReadDefinedMacros();
@@ -1734,7 +1877,7 @@ public:
/// then restores it when destroyed.
struct SavedStreamPosition {
explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
- : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) { }
+ : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) { }
~SavedStreamPosition() {
Cursor.JumpToBit(Offset);
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index ac81e21..2938dc7 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -14,20 +14,19 @@
#ifndef LLVM_CLANG_FRONTEND_AST_WRITER_H
#define LLVM_CLANG_FRONTEND_AST_WRITER_H
+#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/TemplateBase.h"
-#include "clang/AST/ASTMutationListener.h"
-#include "clang/Lex/PPMutationListener.h"
+#include "clang/Sema/SemaConsumer.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/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include <map>
#include <queue>
@@ -48,12 +47,14 @@ class CXXCtorInitializer;
class FileEntry;
class FPOptions;
class HeaderSearch;
+class HeaderSearchOptions;
class IdentifierResolver;
class MacroDefinition;
+class MacroDirective;
+class MacroInfo;
class OpaqueValueExpr;
class OpenCLOptions;
class ASTReader;
-class MacroInfo;
class Module;
class PreprocessedEntity;
class PreprocessingRecord;
@@ -63,6 +64,7 @@ class SourceManager;
class SwitchCase;
class TargetInfo;
class VersionTuple;
+class ASTUnresolvedSet;
namespace SrcMgr { class SLocEntry; }
@@ -73,7 +75,6 @@ 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;
@@ -231,6 +232,16 @@ private:
/// \brief Map that provides the ID numbers of each macro.
llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs;
+ struct MacroInfoToEmitData {
+ const IdentifierInfo *Name;
+ MacroInfo *MI;
+ serialization::MacroID ID;
+ };
+ /// \brief The macro infos to emit.
+ std::vector<MacroInfoToEmitData> MacroInfosToEmit;
+
+ llvm::DenseMap<const IdentifierInfo *, uint64_t> IdentMacroDirectivesOffsetMap;
+
/// @name FlushStmt Caches
/// @{
@@ -266,11 +277,6 @@ private:
/// table, indexed by the Selector ID (-1).
std::vector<uint32_t> SelectorOffsets;
- typedef llvm::MapVector<MacroInfo *, MacroUpdate> MacroUpdatesMap;
-
- /// \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.
llvm::DenseMap<const MacroDefinition *, serialization::PreprocessedEntityID>
@@ -343,7 +349,7 @@ private:
/// \brief The set of declarations that may have redeclaration chains that
/// need to be serialized.
- llvm::SetVector<Decl *, llvm::SmallVector<Decl *, 4>,
+ llvm::SetVector<Decl *, SmallVector<Decl *, 4>,
llvm::SmallPtrSet<Decl *, 4> > Redeclarations;
/// \brief Statements that we've encountered while serializing a
@@ -415,7 +421,9 @@ private:
void WriteBlockInfoBlock();
void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, const std::string &OutputFile);
- void WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot);
+ void WriteInputFiles(SourceManager &SourceMgr,
+ HeaderSearchOptions &HSOpts,
+ StringRef isysroot);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP,
StringRef isysroot);
@@ -424,7 +432,8 @@ private:
void WritePreprocessorDetail(PreprocessingRecord &PPRec);
void WriteSubmodules(Module *WritingModule);
- void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag);
+ void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
+ bool isModule);
void WriteCXXBaseSpecifiersOffsets();
void WriteType(QualType T);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
@@ -437,7 +446,6 @@ 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();
@@ -508,9 +516,6 @@ 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);
@@ -529,7 +534,12 @@ public:
serialization::IdentID getIdentifierRef(const IdentifierInfo *II);
/// \brief Get the unique number used to refer to the given macro.
- serialization::MacroID getMacroRef(MacroInfo *MI);
+ serialization::MacroID getMacroRef(MacroInfo *MI, const IdentifierInfo *Name);
+
+ /// \brief Determine the ID of an already-emitted macro.
+ serialization::MacroID getMacroID(MacroInfo *MI);
+
+ uint64_t getMacroDirectivesOffset(const IdentifierInfo *Name);
/// \brief Emit a reference to a type.
void AddTypeRef(QualType T, RecordDataImpl &Record);
@@ -603,7 +613,7 @@ public:
RecordDataImpl &Record);
/// \brief Emit a UnresolvedSet structure.
- void AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordDataImpl &Record);
+ void AddUnresolvedSet(const ASTUnresolvedSet &Set, RecordDataImpl &Record);
/// \brief Emit a C++ base specifier.
void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
@@ -640,6 +650,10 @@ public:
/// source location.
serialization::SubmoduleID inferSubmoduleIDFromLocation(SourceLocation Loc);
+ /// \brief Retrieve a submodule ID for this module.
+ /// Returns 0 If no ID has been associated with the module.
+ unsigned getExistingSubmoduleID(Module *Mod) const;
+
/// \brief Note that the identifier II occurs at the given offset
/// within the identifier table.
void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset);
@@ -699,9 +713,6 @@ public:
MacroDefinition *MD);
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);
@@ -728,7 +739,7 @@ class PCHGenerator : public SemaConsumer {
std::string isysroot;
raw_ostream *Out;
Sema *SemaPtr;
- llvm::SmallVector<char, 128> Buffer;
+ SmallVector<char, 128> Buffer;
llvm::BitstreamWriter Stream;
ASTWriter Writer;
@@ -743,7 +754,6 @@ 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 d89cd02..f8ef8a1 100644
--- a/include/clang/Serialization/ContinuousRangeMap.h
+++ b/include/clang/Serialization/ContinuousRangeMap.h
@@ -15,6 +15,7 @@
#ifndef LLVM_CLANG_SERIALIZATION_CONTINUOUS_RANGE_MAP_H
#define LLVM_CLANG_SERIALIZATION_CONTINUOUS_RANGE_MAP_H
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
#include <utility>
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
new file mode 100644
index 0000000..eaf26d1
--- /dev/null
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -0,0 +1,194 @@
+//===--- GlobalModuleIndex.h - Global Module Index --------------*- 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 GlobalModuleIndex class, which manages a global index
+// containing all of the identifiers known to the various modules within a given
+// subdirectory of the module cache. It is used to improve the performance of
+// queries such as "do any modules know about this identifier?"
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H
+#define LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <utility>
+
+namespace llvm {
+class BitstreamCursor;
+class MemoryBuffer;
+}
+
+namespace clang {
+
+class DirectoryEntry;
+class FileEntry;
+class FileManager;
+
+namespace serialization {
+ class ModuleFile;
+}
+
+using llvm::SmallVector;
+using llvm::SmallVectorImpl;
+using llvm::StringRef;
+using serialization::ModuleFile;
+
+/// \brief A global index for a set of module files, providing information about
+/// the identifiers within those module files.
+///
+/// The global index is an aid for name lookup into modules, offering a central
+/// place where one can look for identifiers determine which
+/// module files contain any information about that identifier. This
+/// allows the client to restrict the search to only those module files known
+/// to have a information about that identifier, improving performance. Moreover,
+/// the global module index may know about module files that have not been
+/// imported, and can be queried to determine which modules the current
+/// translation could or should load to fix a problem.
+class GlobalModuleIndex {
+ /// \brief Buffer containing the index file, which is lazily accessed so long
+ /// as the global module index is live.
+ llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
+
+ /// \brief The hash table.
+ ///
+ /// This pointer actually points to a IdentifierIndexTable object,
+ /// but that type is only accessible within the implementation of
+ /// GlobalModuleIndex.
+ void *IdentifierIndex;
+
+ /// \brief Information about a given module file.
+ struct ModuleInfo {
+ ModuleInfo() : File(), Size(), ModTime() { }
+
+ /// \brief The module file, once it has been resolved.
+ ModuleFile *File;
+
+ /// \brief The module file name.
+ std::string FileName;
+
+ /// \brief Size of the module file at the time the global index was built.
+ off_t Size;
+
+ /// \brief Modification time of the module file at the time the global
+ /// index was built.
+ time_t ModTime;
+
+ /// \brief The module IDs on which this module directly depends.
+ /// FIXME: We don't really need a vector here.
+ llvm::SmallVector<unsigned, 4> Dependencies;
+ };
+
+ /// \brief A mapping from module IDs to information about each module.
+ ///
+ /// This vector may have gaps, if module files have been removed or have
+ /// been updated since the index was built. A gap is indicated by an empty
+ /// file name.
+ llvm::SmallVector<ModuleInfo, 16> Modules;
+
+ /// \brief Lazily-populated mapping from module files to their
+ /// corresponding index into the \c Modules vector.
+ llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile;
+
+ /// \brief The set of modules that have not yet been resolved.
+ ///
+ /// The string is just the name of the module itself, which maps to the
+ /// module ID.
+ llvm::StringMap<unsigned> UnresolvedModules;
+
+ /// \brief The number of identifier lookups we performed.
+ unsigned NumIdentifierLookups;
+
+ /// \brief The number of identifier lookup hits, where we recognize the
+ /// identifier.
+ unsigned NumIdentifierLookupHits;
+
+ /// \brief Internal constructor. Use \c readIndex() to read an index.
+ explicit GlobalModuleIndex(llvm::MemoryBuffer *Buffer,
+ llvm::BitstreamCursor Cursor);
+
+ GlobalModuleIndex(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION;
+ GlobalModuleIndex &operator=(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION;
+
+public:
+ ~GlobalModuleIndex();
+
+ /// \brief An error code returned when trying to read an index.
+ enum ErrorCode {
+ /// \brief No error occurred.
+ EC_None,
+ /// \brief No index was found.
+ EC_NotFound,
+ /// \brief Some other process is currently building the index; it is not
+ /// available yet.
+ EC_Building,
+ /// \brief There was an unspecified I/O error reading or writing the index.
+ EC_IOError
+ };
+
+ /// \brief Read a global index file for the given directory.
+ ///
+ /// \param Path The path to the specific module cache where the module files
+ /// for the intended configuration reside.
+ ///
+ /// \returns A pair containing the global module index (if it exists) and
+ /// the error code.
+ static std::pair<GlobalModuleIndex *, ErrorCode>
+ readIndex(StringRef Path);
+
+ /// \brief Retrieve the set of modules that have up-to-date indexes.
+ ///
+ /// \param ModuleFiles Will be populated with the set of module files that
+ /// have been indexed.
+ void getKnownModules(SmallVectorImpl<ModuleFile *> &ModuleFiles);
+
+ /// \brief Retrieve the set of module files on which the given module file
+ /// directly depends.
+ void getModuleDependencies(ModuleFile *File,
+ SmallVectorImpl<ModuleFile *> &Dependencies);
+
+ /// \brief A set of module files in which we found a result.
+ typedef llvm::SmallPtrSet<ModuleFile *, 4> HitSet;
+
+ /// \brief Look for all of the module files with information about the given
+ /// identifier, e.g., a global function, variable, or type with that name.
+ ///
+ /// \param Name The identifier to look for.
+ ///
+ /// \param Hits Will be populated with the set of module files that have
+ /// information about this name.
+ ///
+ /// \returns true if the identifier is known to the index, false otherwise.
+ bool lookupIdentifier(StringRef Name, HitSet &Hits);
+
+ /// \brief Note that the given module file has been loaded.
+ ///
+ /// \returns false if the global module index has information about this
+ /// module file, and true otherwise.
+ bool loadedModuleFile(ModuleFile *File);
+
+ /// \brief Print statistics to standard error.
+ void printStats();
+
+ /// \brief Write a global index into the given
+ ///
+ /// \param FileMgr The file manager to use to load module files.
+ ///
+ /// \param Path The path to the directory containing module files, into
+ /// which the global index will be written.
+ static ErrorCode writeIndex(FileManager &FileMgr, StringRef Path);
+};
+
+}
+
+#endif
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 39fa3d9..89c604f 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -15,9 +15,9 @@
#ifndef LLVM_CLANG_SERIALIZATION_MODULE_H
#define LLVM_CLANG_SERIALIZATION_MODULE_H
+#include "clang/Basic/SourceLocation.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ContinuousRangeMap.h"
-#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Bitcode/BitstreamReader.h"
@@ -55,6 +55,35 @@ struct DeclContextInfo {
unsigned NumLexicalDecls;
};
+/// \brief The input file that has been loaded from this AST file, along with
+/// bools indicating whether this was an overridden buffer or if it was
+/// out-of-date.
+class InputFile {
+ enum {
+ Overridden = 1,
+ OutOfDate = 2
+ };
+ llvm::PointerIntPair<const FileEntry *, 2, unsigned> Val;
+
+public:
+ InputFile() {}
+ InputFile(const FileEntry *File,
+ bool isOverridden = false, bool isOutOfDate = false) {
+ assert(!(isOverridden && isOutOfDate) &&
+ "an overridden cannot be out-of-date");
+ unsigned intVal = 0;
+ if (isOverridden)
+ intVal = Overridden;
+ else if (isOutOfDate)
+ intVal = OutOfDate;
+ Val.setPointerAndInt(File, intVal);
+ }
+
+ const FileEntry *getFile() const { return Val.getPointer(); }
+ bool isOverridden() const { return Val.getInt() == Overridden; }
+ bool isOutOfDate() const { return Val.getInt() == OutOfDate; }
+};
+
/// \brief Information about a module that has been loaded by the ASTReader.
///
/// Each instance of the Module class corresponds to a single AST file, which
@@ -69,6 +98,9 @@ public:
// === General information ===
+ /// \brief The index of this module in the list of modules.
+ unsigned Index;
+
/// \brief The type of this module.
ModuleKind Kind;
@@ -121,8 +153,15 @@ public:
/// \brief The main bitstream cursor for the main block.
llvm::BitstreamCursor Stream;
+ /// \brief The source location where the module was explicitly or implicitly
+ /// imported in the local translation unit.
+ ///
+ /// If module A depends on and imports module B, both modules will have the
+ /// same DirectImportLoc, but different ImportLoc (B's ImportLoc will be a
+ /// source location inside module A).
+ SourceLocation DirectImportLoc;
+
/// \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.
@@ -135,10 +174,8 @@ public:
/// \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;
+ /// \brief The input files that have been loaded from this AST file.
+ std::vector<InputFile> InputFilesLoaded;
// === Source Locations ===
@@ -252,10 +289,6 @@ public:
/// the header files.
void *HeaderFileInfoTable;
- /// \brief Actual data for the list of framework names used in the header
- /// search information.
- const char *HeaderFileFrameworkStrings;
-
// === Submodule information ===
/// \brief The number of submodules in this module.
unsigned LocalNumSubmodules;
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index 6dcaa21..b2c4063 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -15,19 +15,22 @@
#ifndef LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H
#define LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H
-#include "clang/Serialization/Module.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Serialization/Module.h"
#include "llvm/ADT/DenseMap.h"
namespace clang {
+class GlobalModuleIndex;
+class ModuleMap;
+
namespace serialization {
-
+
/// \brief Manages the set of modules loaded by an AST reader.
class ModuleManager {
/// \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.
- llvm::SmallVector<ModuleFile*, 2> Chain;
+ SmallVector<ModuleFile *, 2> Chain;
/// \brief All loaded modules, indexed by name.
llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
@@ -38,7 +41,60 @@ class ModuleManager {
/// \brief A lookup of in-memory (virtual file) buffers
llvm::DenseMap<const FileEntry *, llvm::MemoryBuffer *> InMemoryBuffers;
-
+
+ /// \brief The visitation order.
+ SmallVector<ModuleFile *, 4> VisitOrder;
+
+ /// \brief The list of module files that both we and the global module index
+ /// know about.
+ ///
+ /// Either the global index or the module manager may have modules that the
+ /// other does not know about, because the global index can be out-of-date
+ /// (in which case the module manager could have modules it does not) and
+ /// this particular translation unit might not have loaded all of the modules
+ /// known to the global index.
+ SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex;
+
+ /// \brief The global module index, if one is attached.
+ ///
+ /// The global module index will actually be owned by the ASTReader; this is
+ /// just an non-owning pointer.
+ GlobalModuleIndex *GlobalIndex;
+
+ /// \brief State used by the "visit" operation to avoid malloc traffic in
+ /// calls to visit().
+ struct VisitState {
+ explicit VisitState(unsigned N)
+ : VisitNumber(N, 0), NextVisitNumber(1), NextState(0)
+ {
+ Stack.reserve(N);
+ }
+
+ ~VisitState() {
+ delete NextState;
+ }
+
+ /// \brief The stack used when marking the imports of a particular module
+ /// as not-to-be-visited.
+ SmallVector<ModuleFile *, 4> Stack;
+
+ /// \brief The visit number of each module file, which indicates when
+ /// this module file was last visited.
+ SmallVector<unsigned, 4> VisitNumber;
+
+ /// \brief The next visit number to use to mark visited module files.
+ unsigned NextVisitNumber;
+
+ /// \brief The next visit state.
+ VisitState *NextState;
+ };
+
+ /// \brief The first visit() state in the chain.
+ VisitState *FirstVisitState;
+
+ VisitState *allocateVisitState();
+ void returnVisitState(VisitState *State);
+
public:
typedef SmallVector<ModuleFile*, 2>::iterator ModuleIterator;
typedef SmallVector<ModuleFile*, 2>::const_iterator ModuleConstIterator;
@@ -79,12 +135,28 @@ public:
/// \brief Returns the module associated with the given name
ModuleFile *lookup(StringRef Name);
-
+
+ /// \brief Returns the module associated with the given module file.
+ ModuleFile *lookup(const FileEntry *File);
+
/// \brief Returns the in-memory (virtual file) buffer with the given name
llvm::MemoryBuffer *lookupBuffer(StringRef Name);
/// \brief Number of modules loaded
unsigned size() const { return Chain.size(); }
+
+ /// \brief The result of attempting to add a new module.
+ enum AddModuleResult {
+ /// \brief The module file had already been loaded.
+ AlreadyLoaded,
+ /// \brief The module file was just loaded in response to this call.
+ NewlyLoaded,
+ /// \brief The module file is missing.
+ Missing,
+ /// \brief The module file is out-of-date.
+ OutOfDate
+ };
+
/// \brief Attempts to create a new module and add it to the list of known
/// modules.
///
@@ -92,26 +164,48 @@ public:
///
/// \param Type The kind of module being loaded.
///
+ /// \param ImportLoc The location at which the module is imported.
+ ///
/// \param ImportedBy The module that is importing this module, or NULL if
/// this module is imported directly by the user.
///
/// \param Generation The generation in which this module was loaded.
///
+ /// \param ExpectedSize The expected size of the module file, used for
+ /// validation. This will be zero if unknown.
+ ///
+ /// \param ExpectedModTime The expected modification time of the module
+ /// file, used for validation. This will be zero if unknown.
+ ///
+ /// \param Module A pointer to the module file if the module was successfully
+ /// loaded.
+ ///
/// \param ErrorStr Will be set to a non-empty string if any errors occurred
/// while trying to load the module.
///
/// \return A pointer to the module that corresponds to this file name,
- /// and a boolean indicating whether the module was newly added.
- std::pair<ModuleFile *, bool>
- addModule(StringRef FileName, ModuleKind Type, ModuleFile *ImportedBy,
- unsigned Generation, std::string &ErrorStr);
+ /// and a value indicating whether the module was loaded.
+ AddModuleResult addModule(StringRef FileName, ModuleKind Type,
+ SourceLocation ImportLoc,
+ ModuleFile *ImportedBy, unsigned Generation,
+ off_t ExpectedSize, time_t ExpectedModTime,
+ ModuleFile *&Module,
+ std::string &ErrorStr);
/// \brief Remove the given set of modules.
- void removeModules(ModuleIterator first, ModuleIterator last);
+ void removeModules(ModuleIterator first, ModuleIterator last,
+ ModuleMap *modMap);
/// \brief Add an in-memory buffer the list of known buffers
void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer);
-
+
+ /// \brief Set the global module index.
+ void setGlobalIndex(GlobalModuleIndex *Index);
+
+ /// \brief Notification from the AST reader that the given module file
+ /// has been "accepted", and will not (can not) be unloaded.
+ void moduleFileAccepted(ModuleFile *MF);
+
/// \brief Visit each of the modules.
///
/// This routine visits each of the modules, starting with the
@@ -130,7 +224,13 @@ public:
///
/// \param UserData User data associated with the visitor object, which
/// will be passed along to the visitor.
- void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData);
+ ///
+ /// \param ModuleFilesHit If non-NULL, contains the set of module files
+ /// that we know we need to visit because the global module index told us to.
+ /// Any module that is known to both the global module index and the module
+ /// manager that is *not* in this set can be skipped.
+ void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData,
+ llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit = 0);
/// \brief Visit each of the modules with a depth-first traversal.
///
@@ -151,7 +251,29 @@ public:
void visitDepthFirst(bool (*Visitor)(ModuleFile &M, bool Preorder,
void *UserData),
void *UserData);
-
+
+ /// \brief Attempt to resolve the given module file name to a file entry.
+ ///
+ /// \param FileName The name of the module file.
+ ///
+ /// \param ExpectedSize The size that the module file is expected to have.
+ /// If the actual size differs, the resolver should return \c true.
+ ///
+ /// \param ExpectedModTime The modification time that the module file is
+ /// expected to have. If the actual modification time differs, the resolver
+ /// should return \c true.
+ ///
+ /// \param File Will be set to the file if there is one, or null
+ /// otherwise.
+ ///
+ /// \returns True if a file exists but does not meet the size/
+ /// modification time criteria, false if the file is either available and
+ /// suitable, or is missing.
+ bool lookupModuleFile(StringRef FileName,
+ off_t ExpectedSize,
+ time_t ExpectedModTime,
+ const FileEntry *&File);
+
/// \brief View the graphviz representation of the module graph.
void viewGraph();
};
OpenPOWER on IntegriCloud