summaryrefslogtreecommitdiffstats
path: root/include/clang/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Serialization')
-rw-r--r--include/clang/Serialization/ASTBitCodes.h260
-rw-r--r--include/clang/Serialization/ASTReader.h167
-rw-r--r--include/clang/Serialization/ASTWriter.h106
-rw-r--r--include/clang/Serialization/GlobalModuleIndex.h3
-rw-r--r--include/clang/Serialization/Module.h48
-rw-r--r--include/clang/Serialization/ModuleFileExtension.h149
-rw-r--r--include/clang/Serialization/ModuleManager.h88
7 files changed, 534 insertions, 287 deletions
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 4b66207..16bda6e 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -17,6 +17,7 @@
#ifndef LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
#define LLVM_CLANG_SERIALIZATION_ASTBITCODES_H
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Bitcode/BitCodes.h"
@@ -61,9 +62,6 @@ namespace clang {
/// used for the translation unit declaration.
typedef uint32_t DeclID;
- /// \brief a Decl::Kind/DeclID pair.
- typedef std::pair<uint32_t, DeclID> KindDeclIDPair;
-
// FIXME: Turn these into classes so we can have some type safety when
// we go from local ID to global and vice-versa.
typedef DeclID LocalDeclID;
@@ -235,7 +233,17 @@ namespace clang {
/// to create this AST file.
///
/// This block is part of the control block.
- INPUT_FILES_BLOCK_ID
+ INPUT_FILES_BLOCK_ID,
+
+ /// \brief The block of configuration options, used to check that
+ /// a module is being used in a configuration compatible with the
+ /// configuration in which it was built.
+ ///
+ /// This block is part of the control block.
+ OPTIONS_BLOCK_ID,
+
+ /// \brief A block containing a module file extension.
+ EXTENSION_BLOCK_ID,
};
/// \brief Record types that occur within the control block.
@@ -246,63 +254,72 @@ namespace clang {
/// \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,
+ IMPORTS,
/// \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,
+ ORIGINAL_FILE,
/// \brief The directory that the PCH was originally created in.
- ORIGINAL_PCH_DIR = 6,
+ ORIGINAL_PCH_DIR,
/// \brief Record code for file ID of the file or buffer that was used to
/// generate the AST file.
- ORIGINAL_FILE_ID = 7,
+ ORIGINAL_FILE_ID,
/// \brief Offsets into the input-files block where input files
/// reside.
- INPUT_FILE_OFFSETS = 8,
-
- /// \brief Record code for the diagnostic options table.
- DIAGNOSTIC_OPTIONS = 9,
-
- /// \brief Record code for the filesystem options table.
- FILE_SYSTEM_OPTIONS = 10,
-
- /// \brief Record code for the headers search options table.
- HEADER_SEARCH_OPTIONS = 11,
-
- /// \brief Record code for the preprocessor options table.
- PREPROCESSOR_OPTIONS = 12,
+ INPUT_FILE_OFFSETS,
/// \brief Record code for the module name.
- MODULE_NAME = 13,
+ MODULE_NAME,
/// \brief Record code for the module map file that was used to build this
/// AST file.
- MODULE_MAP_FILE = 14,
+ MODULE_MAP_FILE,
/// \brief Record code for the signature that identifiers this AST file.
- SIGNATURE = 15,
+ SIGNATURE,
/// \brief Record code for the module build directory.
- MODULE_DIRECTORY = 16,
+ MODULE_DIRECTORY,
+ };
+
+ /// \brief Record types that occur within the options block inside
+ /// the control block.
+ enum OptionsRecordTypes {
+ /// \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 = 1,
- /// \brief Record code for the list of other AST files made available by
- /// this AST file but not actually used by it.
- KNOWN_MODULE_FILES = 17,
+ /// \brief Record code for the target options table.
+ TARGET_OPTIONS,
+
+ /// \brief Record code for the diagnostic options table.
+ DIAGNOSTIC_OPTIONS,
+
+ /// \brief Record code for the filesystem options table.
+ FILE_SYSTEM_OPTIONS,
+
+ /// \brief Record code for the headers search options table.
+ HEADER_SEARCH_OPTIONS,
+
+ /// \brief Record code for the preprocessor options table.
+ PREPROCESSOR_OPTIONS,
+ };
+
+ /// \brief Record code for extension blocks.
+ enum ExtensionBlockRecordTypes {
+ /// Metadata describing this particular extension.
+ EXTENSION_METADATA = 1,
+
+ /// The first record ID allocated to the extensions themselves.
+ FIRST_EXTENSION_RECORD_ID = 4
};
/// \brief Record types that occur within the input-files block
@@ -350,7 +367,7 @@ namespace clang {
/// \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*.
+ /// *DON'T CHANGE THIS NUMBER*.
METADATA_OLD_FORMAT = 4,
/// \brief Record code for the identifier table.
@@ -440,10 +457,7 @@ namespace clang {
/// declarations.
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 = 23,
+ // ID 23 used to be for a list of local redeclarations.
/// \brief Record code for declarations that Sema keeps references of.
SEMA_DECL_REFS = 24,
@@ -521,13 +535,8 @@ namespace clang {
/// imported by the AST file.
IMPORTED_MODULES = 43,
- // ID 40 used to be a table of merged canonical declarations.
-
- /// \brief Record code for the array of redeclaration chains.
- ///
- /// This array can only be interpreted properly using the local
- /// redeclarations map.
- LOCAL_REDECLARATIONS = 45,
+ // ID 44 used to be a table of merged canonical declarations.
+ // ID 45 used to be a list of declaration IDs of local redeclarations.
/// \brief Record code for the array of Objective-C categories (including
/// extensions).
@@ -543,7 +552,10 @@ namespace clang {
/// macro definition.
MACRO_OFFSET = 47,
- // ID 48 used to be a table of macros.
+ /// \brief A list of "interesting" identifiers. Only used in C++ (where we
+ /// don't normally do lookups into the serialized identifier table). These
+ /// are eagerly deserialized.
+ INTERESTING_IDENTIFIERS = 48,
/// \brief Record code for undefined but used functions and variables that
/// need a definition in this TU.
@@ -758,26 +770,46 @@ namespace clang {
PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34,
/// \brief The pseudo-object placeholder type.
PREDEF_TYPE_PSEUDO_OBJECT = 35,
- /// \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 = 36,
/// \brief OpenCL 1d image type.
- PREDEF_TYPE_IMAGE1D_ID = 38,
+ PREDEF_TYPE_IMAGE1D_ID = 37,
/// \brief OpenCL 1d image array type.
- PREDEF_TYPE_IMAGE1D_ARR_ID = 39,
+ PREDEF_TYPE_IMAGE1D_ARR_ID = 38,
/// \brief OpenCL 1d image buffer type.
- PREDEF_TYPE_IMAGE1D_BUFF_ID = 40,
+ PREDEF_TYPE_IMAGE1D_BUFF_ID = 39,
/// \brief OpenCL 2d image type.
- PREDEF_TYPE_IMAGE2D_ID = 41,
+ PREDEF_TYPE_IMAGE2D_ID = 40,
/// \brief OpenCL 2d image array type.
- PREDEF_TYPE_IMAGE2D_ARR_ID = 42,
+ PREDEF_TYPE_IMAGE2D_ARR_ID = 41,
+ /// \brief OpenCL 2d image depth type.
+ PREDEF_TYPE_IMAGE2D_DEP_ID = 42,
+ /// \brief OpenCL 2d image array depth type.
+ PREDEF_TYPE_IMAGE2D_ARR_DEP_ID = 43,
+ /// \brief OpenCL 2d image MSAA type.
+ PREDEF_TYPE_IMAGE2D_MSAA_ID = 44,
+ /// \brief OpenCL 2d image array MSAA type.
+ PREDEF_TYPE_IMAGE2D_ARR_MSAA_ID = 45,
+ /// \brief OpenCL 2d image MSAA depth type.
+ PREDEF_TYPE_IMAGE2D_MSAA_DEP_ID = 46,
+ /// \brief OpenCL 2d image array MSAA depth type.
+ PREDEF_TYPE_IMAGE2D_ARR_MSAA_DEPTH_ID = 47,
/// \brief OpenCL 3d image type.
- PREDEF_TYPE_IMAGE3D_ID = 43,
+ PREDEF_TYPE_IMAGE3D_ID = 48,
/// \brief OpenCL event type.
- PREDEF_TYPE_EVENT_ID = 44,
+ PREDEF_TYPE_EVENT_ID = 49,
+ /// \brief OpenCL clk event type.
+ PREDEF_TYPE_CLK_EVENT_ID = 50,
/// \brief OpenCL sampler type.
- PREDEF_TYPE_SAMPLER_ID = 45
+ PREDEF_TYPE_SAMPLER_ID = 51,
+ /// \brief OpenCL queue type.
+ PREDEF_TYPE_QUEUE_ID = 52,
+ /// \brief OpenCL ndrange type.
+ PREDEF_TYPE_NDRANGE_ID = 53,
+ /// \brief OpenCL reserve_id type.
+ PREDEF_TYPE_RESERVE_ID_ID = 54,
+ /// \brief The placeholder type for OpenMP array section.
+ PREDEF_TYPE_OMP_ARRAY_SECTION = 55
};
/// \brief The number of predefined type IDs that are reserved for
@@ -913,44 +945,56 @@ namespace clang {
/// it is created.
enum PredefinedDeclIDs {
/// \brief The NULL declaration.
- PREDEF_DECL_NULL_ID = 0,
-
+ PREDEF_DECL_NULL_ID = 0,
+
/// \brief The translation unit.
PREDEF_DECL_TRANSLATION_UNIT_ID = 1,
-
+
/// \brief The Objective-C 'id' type.
PREDEF_DECL_OBJC_ID_ID = 2,
-
+
/// \brief The Objective-C 'SEL' type.
PREDEF_DECL_OBJC_SEL_ID = 3,
-
+
/// \brief The Objective-C 'Class' type.
PREDEF_DECL_OBJC_CLASS_ID = 4,
-
+
/// \brief The Objective-C 'Protocol' type.
PREDEF_DECL_OBJC_PROTOCOL_ID = 5,
-
+
/// \brief The signed 128-bit integer type.
PREDEF_DECL_INT_128_ID = 6,
/// \brief The unsigned 128-bit integer type.
PREDEF_DECL_UNSIGNED_INT_128_ID = 7,
-
+
/// \brief The internal 'instancetype' typedef.
PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8,
/// \brief The internal '__builtin_va_list' typedef.
PREDEF_DECL_BUILTIN_VA_LIST_ID = 9,
+ /// \brief The internal '__va_list_tag' struct, if any.
+ PREDEF_DECL_VA_LIST_TAG = 10,
+
+ /// \brief The internal '__builtin_ms_va_list' typedef.
+ PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11,
+
/// \brief The extern "C" context.
- PREDEF_DECL_EXTERN_C_CONTEXT_ID = 10,
+ PREDEF_DECL_EXTERN_C_CONTEXT_ID = 12,
+
+ /// \brief The internal '__make_integer_seq' template.
+ PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 13,
};
/// \brief The number of declaration IDs that are predefined.
///
/// For more information about predefined declarations, see the
/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
- const unsigned int NUM_PREDEF_DECL_IDS = 11;
+ const unsigned int NUM_PREDEF_DECL_IDS = 14;
+
+ /// \brief Record code for a list of local redeclarations of a declaration.
+ const unsigned int LOCAL_REDECLARATIONS = 50;
/// \brief Record codes for each kind of declaration.
///
@@ -1369,6 +1413,7 @@ namespace clang {
// Microsoft
EXPR_CXX_PROPERTY_REF_EXPR, // MSPropertyRefExpr
+ EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR, // MSPropertySubscriptExpr
EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr).
EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type).
STMT_SEH_LEAVE, // SEHLeaveStmt
@@ -1397,10 +1442,15 @@ namespace clang {
STMT_OMP_ORDERED_DIRECTIVE,
STMT_OMP_ATOMIC_DIRECTIVE,
STMT_OMP_TARGET_DIRECTIVE,
+ STMT_OMP_TARGET_DATA_DIRECTIVE,
STMT_OMP_TEAMS_DIRECTIVE,
STMT_OMP_TASKGROUP_DIRECTIVE,
STMT_OMP_CANCELLATION_POINT_DIRECTIVE,
STMT_OMP_CANCEL_DIRECTIVE,
+ STMT_OMP_TASKLOOP_DIRECTIVE,
+ STMT_OMP_TASKLOOP_SIMD_DIRECTIVE,
+ STMT_OMP_DISTRIBUTE_DIRECTIVE,
+ EXPR_OMP_ARRAY_SECTION,
// ARC
EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr
@@ -1484,8 +1534,72 @@ namespace clang {
}
};
+ /// \brief A key used when looking up entities by \ref DeclarationName.
+ ///
+ /// Different \ref DeclarationNames are mapped to different keys, but the
+ /// same key can occasionally represent multiple names (for names that
+ /// contain types, in particular).
+ class DeclarationNameKey {
+ typedef unsigned NameKind;
+
+ NameKind Kind;
+ uint64_t Data;
+
+ public:
+ DeclarationNameKey() : Kind(), Data() {}
+ DeclarationNameKey(DeclarationName Name);
+
+ DeclarationNameKey(NameKind Kind, uint64_t Data)
+ : Kind(Kind), Data(Data) {}
+
+ NameKind getKind() const { return Kind; }
+
+ IdentifierInfo *getIdentifier() const {
+ assert(Kind == DeclarationName::Identifier ||
+ Kind == DeclarationName::CXXLiteralOperatorName);
+ return (IdentifierInfo *)Data;
+ }
+ Selector getSelector() const {
+ assert(Kind == DeclarationName::ObjCZeroArgSelector ||
+ Kind == DeclarationName::ObjCOneArgSelector ||
+ Kind == DeclarationName::ObjCMultiArgSelector);
+ return Selector(Data);
+ }
+ OverloadedOperatorKind getOperatorKind() const {
+ assert(Kind == DeclarationName::CXXOperatorName);
+ return (OverloadedOperatorKind)Data;
+ }
+
+ /// Compute a fingerprint of this key for use in on-disk hash table.
+ unsigned getHash() const;
+
+ friend bool operator==(const DeclarationNameKey &A,
+ const DeclarationNameKey &B) {
+ return A.Kind == B.Kind && A.Data == B.Data;
+ }
+ };
+
/// @}
}
} // end namespace clang
+namespace llvm {
+ template <> struct DenseMapInfo<clang::serialization::DeclarationNameKey> {
+ static clang::serialization::DeclarationNameKey getEmptyKey() {
+ return clang::serialization::DeclarationNameKey(-1, 1);
+ }
+ static clang::serialization::DeclarationNameKey getTombstoneKey() {
+ return clang::serialization::DeclarationNameKey(-1, 2);
+ }
+ static unsigned
+ getHashValue(const clang::serialization::DeclarationNameKey &Key) {
+ return Key.getHash();
+ }
+ static bool isEqual(const clang::serialization::DeclarationNameKey &L,
+ const clang::serialization::DeclarationNameKey &R) {
+ return L == R;
+ }
+ };
+}
+
#endif
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 840655e..588a6a9 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -30,6 +30,7 @@
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ContinuousRangeMap.h"
#include "clang/Serialization/Module.h"
+#include "clang/Serialization/ModuleFileExtension.h"
#include "clang/Serialization/ModuleManager.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
@@ -38,6 +39,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Bitcode/BitstreamReader.h"
@@ -179,7 +181,8 @@ public:
unsigned Value) {}
/// This is called for each AST file loaded.
- virtual void visitModuleFile(StringRef Filename) {}
+ virtual void visitModuleFile(StringRef Filename,
+ serialization::ModuleKind Kind) {}
/// \brief Returns true if this \c ASTReaderListener wants to receive the
/// input files of the AST file via \c visitInputFile, false otherwise.
@@ -194,7 +197,7 @@ public:
///
/// \returns true to continue receiving the next input file, false to stop.
virtual bool visitInputFile(StringRef Filename, bool isSystem,
- bool isOverridden) {
+ bool isOverridden, bool isExplicitModule) {
return true;
}
@@ -204,6 +207,10 @@ public:
/// \brief If needsImportVisitation returns \c true, this is called for each
/// AST file imported by this AST file.
virtual void visitImport(StringRef Filename) {}
+
+ /// Indicates that a particular module file extension has been read.
+ virtual void readModuleFileExtension(
+ const ModuleFileExtensionMetadata &Metadata) {}
};
/// \brief Simple wrapper class for chaining listeners.
@@ -242,9 +249,12 @@ public:
void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
bool needsInputFileVisitation() override;
bool needsSystemInputFileVisitation() override;
- void visitModuleFile(StringRef Filename) override;
+ void visitModuleFile(StringRef Filename,
+ serialization::ModuleKind Kind) override;
bool visitInputFile(StringRef Filename, bool isSystem,
- bool isOverridden) override;
+ bool isOverridden, bool isExplicitModule) override;
+ void readModuleFileExtension(
+ const ModuleFileExtensionMetadata &Metadata) override;
};
/// \brief ASTReaderListener implementation to validate the information of
@@ -280,9 +290,8 @@ class ReadMethodPoolVisitor;
namespace reader {
class ASTIdentifierLookupTrait;
- /// \brief The on-disk hash table used for the DeclContext's Name lookup table.
- typedef llvm::OnDiskIterableChainedHashTable<ASTDeclContextNameLookupTrait>
- ASTDeclContextNameLookupTable;
+ /// \brief The on-disk hash table(s) used for DeclContext name lookup.
+ struct DeclContextLookupTable;
}
} // end namespace serialization
@@ -381,6 +390,9 @@ private:
/// \brief The module manager which manages modules and their dependencies
ModuleManager ModuleMgr;
+ /// A mapping from extension block names to module file extensions.
+ llvm::StringMap<IntrusiveRefCntPtr<ModuleFileExtension>> ModuleFileExtensions;
+
/// \brief A timer used to track the time spent deserializing.
std::unique_ptr<llvm::Timer> ReadTimer;
@@ -494,20 +506,36 @@ private:
/// \brief Map from a FileID to the file-level declarations that it contains.
llvm::DenseMap<FileID, FileDeclsInfo> FileDeclIDs;
+ /// \brief An array of lexical contents of a declaration context, as a sequence of
+ /// Decl::Kind, DeclID pairs.
+ typedef ArrayRef<llvm::support::unaligned_uint32_t> LexicalContents;
+
+ /// \brief Map from a DeclContext to its lexical contents.
+ llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>>
+ LexicalDecls;
+
+ /// \brief Map from the TU to its lexical contents from each module file.
+ std::vector<std::pair<ModuleFile*, LexicalContents>> TULexicalDecls;
+
+ /// \brief Map from a DeclContext to its lookup tables.
+ llvm::DenseMap<const DeclContext *,
+ serialization::reader::DeclContextLookupTable> Lookups;
+
// Updates for visible decls can occur for other contexts than just the
- // TU, and when we read those update records, the actual context will not
- // be available yet (unless it's the TU), so have this pending map using the
- // ID as a key. It will be realized when the context is actually loaded.
- typedef
- SmallVector<std::pair<serialization::reader::ASTDeclContextNameLookupTable *,
- ModuleFile*>, 1> DeclContextVisibleUpdates;
- typedef llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates>
- DeclContextVisibleUpdatesPending;
+ // TU, and when we read those update records, the actual context may not
+ // be available yet, so have this pending map using the ID as a key. It
+ // will be realized when the context is actually loaded.
+ struct PendingVisibleUpdate {
+ ModuleFile *Mod;
+ const unsigned char *Data;
+ };
+ typedef SmallVector<PendingVisibleUpdate, 1> DeclContextVisibleUpdates;
/// \brief Updates to the visible declarations of declaration contexts that
/// haven't been loaded yet.
- DeclContextVisibleUpdatesPending PendingVisibleUpdates;
-
+ llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates>
+ PendingVisibleUpdates;
+
/// \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;
@@ -524,11 +552,14 @@ private:
/// performed deduplication.
llvm::SetVector<NamedDecl*> PendingMergedDefinitionsToDeduplicate;
- /// \brief Read the records that describe the contents of declcontexts.
- bool ReadDeclContextStorage(ModuleFile &M,
- llvm::BitstreamCursor &Cursor,
- const std::pair<uint64_t, uint64_t> &Offsets,
- serialization::DeclContextInfo &Info);
+ /// \brief Read the record that describes the lexical contents of a DC.
+ bool ReadLexicalDeclContextStorage(ModuleFile &M,
+ llvm::BitstreamCursor &Cursor,
+ uint64_t Offset, DeclContext *DC);
+ /// \brief Read the record that describes the visible contents of a DC.
+ bool ReadVisibleDeclContextStorage(ModuleFile &M,
+ llvm::BitstreamCursor &Cursor,
+ uint64_t Offset, serialization::DeclID ID);
/// \brief A vector containing identifiers that have already been
/// loaded.
@@ -914,20 +945,10 @@ private:
/// Objective-C protocols.
std::deque<Decl *> InterestingDecls;
- /// \brief The set of redeclarable declarations that have been deserialized
- /// since the last time the declaration chains were linked.
- llvm::SmallPtrSet<Decl *, 16> RedeclsDeserialized;
-
/// \brief The list of redeclaration chains that still need to be
- /// reconstructed.
- ///
- /// Each element is the canonical declaration of the chain.
- /// Elements in this vector should be unique; use
- /// PendingDeclChainsKnown to ensure uniqueness.
- SmallVector<Decl *, 16> PendingDeclChains;
-
- /// \brief Keeps track of the elements added to PendingDeclChains.
- llvm::SmallSet<Decl *, 16> PendingDeclChainsKnown;
+ /// reconstructed, and the local offset to the corresponding list
+ /// of redeclarations.
+ SmallVector<std::pair<Decl *, uint64_t>, 16> PendingDeclChains;
/// \brief The list of canonical declarations whose redeclaration chains
/// need to be marked as incomplete once we're done deserializing things.
@@ -972,13 +993,6 @@ private:
/// module is loaded.
SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
- /// \brief A mapping from a primary context for a declaration chain to the
- /// other declarations of that entity that also have name lookup tables.
- /// Used when we merge together two class definitions that have different
- /// sets of declared special member functions.
- llvm::DenseMap<const DeclContext*, SmallVector<const DeclContext*, 2>>
- MergedLookups;
-
typedef llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2> >
KeyDeclsMap;
@@ -1044,12 +1058,11 @@ private:
off_t StoredSize;
time_t StoredTime;
bool Overridden;
+ bool Transient;
};
/// \brief Reads the stored information about an input file.
InputFileInfo readInputFileInfo(ModuleFile &F, unsigned ID);
- /// \brief A convenience method to read the filename from an input file.
- std::string getInputFileName(ModuleFile &F, unsigned ID);
/// \brief Retrieve the file entry and 'overridden' bit for an input
/// file in the given module file.
@@ -1090,6 +1103,10 @@ public:
Visit(GetExistingDecl(ID));
}
+ /// \brief Get the loaded lookup tables for \p Primary, if any.
+ const serialization::reader::DeclContextLookupTable *
+ getLoadedLookupTables(DeclContext *Primary) const;
+
private:
struct ImportedModule {
ModuleFile *Mod;
@@ -1112,7 +1129,12 @@ private:
SmallVectorImpl<ImportedModule> &Loaded,
const ModuleFile *ImportedBy,
unsigned ClientLoadCapabilities);
+ static ASTReadResult ReadOptionsBlock(
+ llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
+ bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
+ std::string &SuggestedPredefines);
ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
+ ASTReadResult ReadExtensionBlock(ModuleFile &F);
bool ParseLineTable(ModuleFile &F, const RecordData &Record);
bool ReadSourceManagerBlock(ModuleFile &F);
llvm::BitstreamCursor &SLocCursorForID(int ID);
@@ -1163,7 +1185,7 @@ private:
RecordLocation DeclCursorForID(serialization::DeclID ID,
unsigned &RawLocation);
void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D);
- void loadPendingDeclChain(Decl *D);
+ void loadPendingDeclChain(Decl *D, uint64_t LocalOffset);
void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D,
unsigned PreviousGeneration = 0);
@@ -1261,9 +1283,12 @@ public:
/// \param Context the AST context that this precompiled header will be
/// loaded into.
///
- /// \param PCHContainerOps the PCHContainerOperations to use for loading and
+ /// \param PCHContainerRdr the PCHContainerOperations to use for loading and
/// creating modules.
///
+ /// \param Extensions the list of module file extensions that can be loaded
+ /// from the AST files.
+ ///
/// \param isysroot If non-NULL, the system include path specified by the
/// user. This is only used with relocatable PCH files. If non-NULL,
/// a relocatable PCH file will use the default path "/".
@@ -1290,6 +1315,7 @@ public:
/// deserializing.
ASTReader(Preprocessor &PP, ASTContext &Context,
const PCHContainerReader &PCHContainerRdr,
+ ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
StringRef isysroot = "", bool DisableValidation = false,
bool AllowASTWithCompilerErrors = false,
bool AllowConfigurationMismatch = false,
@@ -1300,6 +1326,7 @@ public:
SourceManager &getSourceManager() const { return SourceMgr; }
FileManager &getFileManager() const { return FileMgr; }
+ DiagnosticsEngine &getDiags() const { return Diags; }
/// \brief Flags that indicate what kind of AST loading failures the client
/// of the AST reader can directly handle.
@@ -1467,6 +1494,7 @@ public:
static bool
readASTFileControlBlock(StringRef Filename, FileManager &FileMgr,
const PCHContainerReader &PCHContainerRdr,
+ bool FindModuleFileExtensions,
ASTReaderListener &Listener);
/// \brief Determine whether the given AST file is acceptable to load into a
@@ -1684,7 +1712,7 @@ public:
/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
/// specified cursor. Read the abbreviations that are at the top of the block
/// and then leave the cursor pointing into the block.
- bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID);
+ static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID);
/// \brief Finds all the visible declarations with a given name.
/// The current implementation of this method just loads the entire
@@ -1698,16 +1726,17 @@ public:
/// \param DC The declaration context whose declarations will be
/// read.
///
+ /// \param IsKindWeWant A predicate indicating which declaration kinds
+ /// we are interested in.
+ ///
/// \param Decls Vector that will contain the declarations loaded
/// from the external source. The caller is responsible for merging
/// these declarations with any declarations already stored in the
/// declaration context.
- ///
- /// \returns true if there was an error while reading the
- /// declarations for this declaration context.
- ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
- bool (*isKindWeWant)(Decl::Kind),
- SmallVectorImpl<Decl*> &Decls) override;
+ void
+ FindExternalLexicalDecls(const DeclContext *DC,
+ llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
+ SmallVectorImpl<Decl *> &Decls) override;
/// \brief Get the decls that are contained in a file in the Offset/Length
/// range. \p Length can be 0 to indicate a point at \p Offset instead of
@@ -1755,10 +1784,7 @@ public:
/// declarations with this name are visible from translation unit scope, their
/// declarations will be deserialized and introduced into the declaration
/// chain of the identifier.
- virtual IdentifierInfo *get(const char *NameStart, const char *NameEnd);
- IdentifierInfo *get(StringRef Name) override {
- return get(Name.begin(), Name.end());
- }
+ IdentifierInfo *get(StringRef Name) override;
/// \brief Retrieve an iterator into the set of all identifiers
/// in all loaded AST files.
@@ -1873,10 +1899,15 @@ public:
/// Note: overrides method in ExternalASTSource
Module *getModule(unsigned ID) override;
+ /// \brief Retrieve the module file with a given local ID within the specified
+ /// ModuleFile.
+ ModuleFile *getLocalModuleFile(ModuleFile &M, unsigned ID);
+
+ /// \brief Get an ID for the given module file.
+ unsigned getModuleFileID(ModuleFile *M);
+
/// \brief Return a descriptor for the corresponding module.
llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override;
- /// \brief Return a descriptor for the module.
- ASTSourceDescriptor getSourceDescriptor(const Module &M) override;
/// \brief Retrieve a selector from the given module with its local ID
/// number.
@@ -1921,8 +1952,9 @@ public:
unsigned &Idx);
/// \brief Read a template argument.
- TemplateArgument ReadTemplateArgument(ModuleFile &F,
- const RecordData &Record,unsigned &Idx);
+ TemplateArgument ReadTemplateArgument(ModuleFile &F, const RecordData &Record,
+ unsigned &Idx,
+ bool Canonicalize = false);
/// \brief Read a template parameter list.
TemplateParameterList *ReadTemplateParameterList(ModuleFile &F,
@@ -1930,10 +1962,9 @@ public:
unsigned &Idx);
/// \brief Read a template argument array.
- void
- ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
- ModuleFile &F, const RecordData &Record,
- unsigned &Idx);
+ void ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
+ ModuleFile &F, const RecordData &Record,
+ unsigned &Idx, bool Canonicalize = false);
/// \brief Read a UnresolvedSet structure.
void ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set,
@@ -2082,12 +2113,8 @@ public:
SmallVector<std::pair<llvm::BitstreamCursor,
serialization::ModuleFile *>, 8> CommentsCursors;
- //RIDErief Loads comments ranges.
+ /// \brief Loads comments ranges.
void ReadComments() override;
-
- /// Return all input files for the given module file.
- void getInputFiles(ModuleFile &F,
- SmallVectorImpl<serialization::InputFile> &Files);
};
/// \brief Helper class that saves the current stream position and
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index e830fdc..ed34547 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -58,6 +58,8 @@ class OpaqueValueExpr;
class OpenCLOptions;
class ASTReader;
class Module;
+class ModuleFileExtension;
+class ModuleFileExtensionWriter;
class PreprocessedEntity;
class PreprocessingRecord;
class Preprocessor;
@@ -84,6 +86,7 @@ class ASTWriter : public ASTDeserializationListener,
public:
typedef SmallVector<uint64_t, 64> RecordData;
typedef SmallVectorImpl<uint64_t> RecordDataImpl;
+ typedef ArrayRef<uint64_t> RecordDataRef;
friend class ASTDeclWriter;
friend class ASTStmtWriter;
@@ -119,6 +122,12 @@ private:
/// \brief The base directory for any relative paths we emit.
std::string BaseDirectory;
+ /// \brief Indicates whether timestamps should be written to the produced
+ /// module file. This is the case for files implicitly written to the
+ /// module cache, where we need the timestamps to determine if the module
+ /// file is up to date, but not otherwise.
+ bool IncludeTimestamps;
+
/// \brief Indicates when the AST writing is actively performing
/// serialization, rather than just queueing updates.
bool WritingAST;
@@ -369,10 +378,6 @@ private:
/// coming from another AST file.
SmallVector<const Decl *, 16> UpdatingVisibleDecls;
- typedef llvm::SmallSetVector<const Decl *, 16> DeclsToRewriteTy;
- /// \brief Decls that will be replaced in the current dependent AST file.
- DeclsToRewriteTy DeclsToRewrite;
-
/// \brief The set of Objective-C class that have categories we
/// should serialize.
llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories;
@@ -399,6 +404,10 @@ private:
/// \brief The set of declarations that may have redeclaration chains that
/// need to be serialized.
llvm::SmallVector<const Decl *, 16> Redeclarations;
+
+ /// \brief A cache of the first local declaration for "interesting"
+ /// redeclaration chains.
+ llvm::DenseMap<const Decl *, const Decl *> FirstLocalDeclCache;
/// \brief Statements that we've encountered while serializing a
/// declaration or type.
@@ -484,20 +493,23 @@ private:
/// \brief A mapping from each known submodule to its ID number, which will
/// be a positive integer.
llvm::DenseMap<Module *, unsigned> SubmoduleIDs;
-
+
+ /// \brief A list of the module file extension writers.
+ std::vector<std::unique_ptr<ModuleFileExtensionWriter>>
+ ModuleFileExtensionWriters;
+
/// \brief Retrieve or create a submodule ID for this module.
unsigned getSubmoduleID(Module *Mod);
-
+
/// \brief Write the given subexpression to the bitstream.
void WriteSubStmt(Stmt *S,
llvm::DenseMap<Stmt *, uint64_t> &SubStmtEntries,
llvm::DenseSet<Stmt *> &ParentStmts);
void WriteBlockInfoBlock();
- void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
- StringRef isysroot, const std::string &OutputFile);
- void WriteInputFiles(SourceManager &SourceMgr,
- HeaderSearchOptions &HSOpts,
+ uint64_t WriteControlBlock(Preprocessor &PP, ASTContext &Context,
+ StringRef isysroot, const std::string &OutputFile);
+ void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts,
bool Modules);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP);
@@ -519,8 +531,8 @@ private:
bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC);
- uint32_t GenerateNameLookupTable(const DeclContext *DC,
- llvm::SmallVectorImpl<char> &LookupTable);
+ void GenerateNameLookupTable(const DeclContext *DC,
+ llvm::SmallVectorImpl<char> &LookupTable);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
void WriteTypeDeclOffsets();
@@ -537,9 +549,10 @@ private:
void WriteFPPragmaOptions(const FPOptions &Opts);
void WriteOpenCLExtensions(Sema &SemaRef);
void WriteObjCCategories();
- void WriteRedeclarations();
void WriteLateParsedTemplates(Sema &SemaRef);
void WriteOptimizePragmaOptions(Sema &SemaRef);
+ void WriteModuleFileExtension(Sema &SemaRef,
+ ModuleFileExtensionWriter &Writer);
unsigned DeclParmVarAbbrev;
unsigned DeclContextLexicalAbbrev;
@@ -562,18 +575,25 @@ private:
void WriteDecl(ASTContext &Context, Decl *D);
void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record);
- void WriteASTCore(Sema &SemaRef,
- StringRef isysroot, const std::string &OutputFile,
- Module *WritingModule);
+ uint64_t WriteASTCore(Sema &SemaRef,
+ StringRef isysroot, const std::string &OutputFile,
+ Module *WritingModule);
public:
/// \brief Create a new precompiled header writer that outputs to
/// the given bitstream.
- ASTWriter(llvm::BitstreamWriter &Stream);
+ ASTWriter(llvm::BitstreamWriter &Stream,
+ ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
+ bool IncludeTimestamps = true);
~ASTWriter() override;
const LangOptions &getLangOpts() const;
+ /// \brief Get a timestamp for output into the AST file. The actual timestamp
+ /// of the specified file may be ignored if we have been instructed to not
+ /// include timestamps in the output file.
+ time_t getTimestampForOutput(const FileEntry *E) const;
+
/// \brief Write a precompiled header for the given semantic analysis.
///
/// \param SemaRef a reference to the semantic analysis object that processed
@@ -585,10 +605,12 @@ public:
/// \param isysroot if non-empty, write a relocatable file whose headers
/// are relative to the given system root. If we're writing a module, its
/// build directory will be used in preference to this if both are available.
- void WriteAST(Sema &SemaRef,
- const std::string &OutputFile,
- Module *WritingModule, StringRef isysroot,
- bool hasErrors = false);
+ ///
+ /// \return the module signature, which eventually will be a hash of
+ /// the module but currently is merely a random 32-bit number.
+ uint64_t WriteAST(Sema &SemaRef, const std::string &OutputFile,
+ Module *WritingModule, StringRef isysroot,
+ bool hasErrors = false);
/// \brief Emit a token.
void AddToken(const Token &Tok, RecordDataImpl &Record);
@@ -665,6 +687,10 @@ public:
const ASTTemplateArgumentListInfo *ASTTemplArgList,
RecordDataImpl &Record);
+ /// \brief Find the first local declaration of a given local redeclarable
+ /// decl.
+ const Decl *getFirstLocalDecl(const Decl *D);
+
/// \brief Emit a reference to a declaration.
void AddDeclRef(const Decl *D, RecordDataImpl &Record);
@@ -738,27 +764,20 @@ public:
void AddPath(StringRef Path, RecordDataImpl &Record);
/// \brief Emit the current record with the given path as a blob.
- void EmitRecordWithPath(unsigned Abbrev, RecordDataImpl &Record,
+ void EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record,
StringRef Path);
/// \brief Add a version tuple to the given record
void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record);
- void RewriteDecl(const Decl *D) {
- DeclsToRewrite.insert(D);
- }
-
- bool isRewritten(const Decl *D) const {
- return DeclsToRewrite.count(D);
- }
-
/// \brief Infer the submodule ID that contains an entity at the given
/// 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 Retrieve or create a submodule ID for this module, or return 0 if
+ /// the submodule is neither local (a submodle of the currently-written module)
+ /// nor from an imported module.
+ unsigned getLocalOrImportedSubmoduleID(Module *Mod);
/// \brief Note that the identifier II occurs at the given offset
/// within the identifier table.
@@ -830,6 +849,7 @@ public:
unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; }
bool hasChain() const { return Chain; }
+ ASTReader *getChain() const { return Chain; }
// ASTDeserializationListener implementation
void ReaderInitialized(ASTReader *Reader) override;
@@ -845,12 +865,6 @@ public:
void CompletedTagDefinition(const TagDecl *D) override;
void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override;
void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override;
- void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
- const ClassTemplateSpecializationDecl *D) override;
- void AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
- const VarTemplateSpecializationDecl *D) override;
- void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
- const FunctionDecl *D) override;
void ResolvedExceptionSpec(const FunctionDecl *FD) override;
void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
@@ -860,9 +874,6 @@ public:
void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) override;
- void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
- const ObjCPropertyDecl *OrigProp,
- const ObjCCategoryDecl *ClassExt) override;
void DeclarationMarkedUsed(const Decl *D) override;
void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override;
@@ -889,10 +900,13 @@ protected:
SmallVectorImpl<char> &getPCH() const { return Buffer->Data; }
public:
- PCHGenerator(const Preprocessor &PP, StringRef OutputFile,
- clang::Module *Module, StringRef isysroot,
- std::shared_ptr<PCHBuffer> Buffer,
- bool AllowASTWithErrors = false);
+ PCHGenerator(
+ const Preprocessor &PP, StringRef OutputFile,
+ clang::Module *Module, StringRef isysroot,
+ std::shared_ptr<PCHBuffer> Buffer,
+ ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
+ bool AllowASTWithErrors = false,
+ bool IncludeTimestamps = true);
~PCHGenerator() override;
void InitializeSema(Sema &S) override { SemaPtr = &S; }
void HandleTranslationUnit(ASTContext &Ctx) override;
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
index ba4f7e2..0f14eca 100644
--- a/include/clang/Serialization/GlobalModuleIndex.h
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -36,6 +36,7 @@ class FileEntry;
class FileManager;
class IdentifierIterator;
class PCHContainerOperations;
+class PCHContainerReader;
namespace serialization {
class ModuleFile;
@@ -193,7 +194,7 @@ public:
/// \brief Write a global index into the given
///
/// \param FileMgr The file manager to use to load module files.
- /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
+ /// \param PCHContainerRdr - The PCHContainerOperations to use for loading and
/// creating modules.
/// \param Path The path to the directory containing module files, into
/// which the global index will be written.
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index c98ced4..d6d16a0 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -15,9 +15,11 @@
#ifndef LLVM_CLANG_SERIALIZATION_MODULE_H
#define LLVM_CLANG_SERIALIZATION_MODULE_H
+#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ContinuousRangeMap.h"
+#include "clang/Serialization/ModuleFileExtension.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/Endian.h"
@@ -31,7 +33,6 @@ template <typename Info> class OnDiskIterableChainedHashTable;
namespace clang {
-class FileEntry;
class DeclContext;
class Module;
@@ -50,17 +51,6 @@ enum ModuleKind {
MK_MainFile ///< File is a PCH file treated as the actual main file.
};
-/// \brief Information about the contents of a DeclContext.
-struct DeclContextInfo {
- DeclContextInfo()
- : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {}
-
- llvm::OnDiskIterableChainedHashTable<reader::ASTDeclContextNameLookupTrait>
- *NameLookupTableData; // an ASTDeclContextNameLookupTable.
- const KindDeclIDPair *LexicalDecls;
- 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 or not-found.
@@ -155,6 +145,9 @@ public:
/// \brief Whether this precompiled header is a relocatable PCH file.
bool RelocatablePCH;
+ /// \brief Whether timestamps are included in this module file.
+ bool HasTimestamps;
+
/// \brief The file entry for the module file.
const FileEntry *File;
@@ -202,6 +195,10 @@ public:
/// \brief The first source location in this module.
SourceLocation FirstLoc;
+ /// The list of extension readers that are attached to this module
+ /// file.
+ std::vector<std::unique_ptr<ModuleFileExtensionReader>> ExtensionReaders;
+
// === Input Files ===
/// \brief The cursor to the start of the input-files block.
llvm::BitstreamCursor InputFilesCursor;
@@ -270,6 +267,10 @@ public:
/// IdentifierHashTable.
void *IdentifierLookupTable;
+ /// \brief Offsets of identifiers that we're going to preload within
+ /// IdentifierTableData.
+ std::vector<unsigned> PreloadIdentifierOffsets;
+
// === Macros ===
/// \brief The cursor to the start of the preprocessor block, which stores
@@ -412,28 +413,10 @@ public:
/// indexed by the C++ ctor initializer list ID minus 1.
const uint32_t *CXXCtorInitializersOffsets;
- typedef llvm::DenseMap<const DeclContext *, DeclContextInfo>
- DeclContextInfosMap;
-
- /// \brief Information about the lexical and visible declarations
- /// for each DeclContext.
- DeclContextInfosMap DeclContextInfos;
-
/// \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.
- const serialization::LocalRedeclarationsInfo *RedeclarationsMap;
-
- /// \brief The number of redeclaration info entries in RedeclarationsMap.
- unsigned LocalNumRedeclarationsInMap;
-
- /// \brief The redeclaration chains for declarations local to this
- /// module file.
- SmallVector<uint64_t, 1> RedeclarationChains;
-
/// \brief Array of category list location information within this
/// module file, sorted by the definition ID.
const serialization::ObjCCategoriesInfo *ObjCCategoriesMap;
@@ -476,6 +459,11 @@ public:
/// any point during translation.
bool isDirectlyImported() const { return DirectlyImported; }
+ /// \brief Is this a module file for a module (rather than a PCH or similar).
+ bool isModule() const {
+ return Kind == MK_ImplicitModule || Kind == MK_ExplicitModule;
+ }
+
/// \brief Dump debugging output for this module.
void dump();
};
diff --git a/include/clang/Serialization/ModuleFileExtension.h b/include/clang/Serialization/ModuleFileExtension.h
new file mode 100644
index 0000000..ba2e2fd
--- /dev/null
+++ b/include/clang/Serialization/ModuleFileExtension.h
@@ -0,0 +1,149 @@
+//===-- ModuleFileExtension.h - Module File Extensions ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H
+#define LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include <memory>
+#include <string>
+
+namespace llvm {
+class BitstreamCursor;
+class BitstreamWriter;
+class hash_code;
+class raw_ostream;
+}
+
+namespace clang {
+
+class ASTReader;
+class ASTWriter;
+class Sema;
+
+namespace serialization {
+ class ModuleFile;
+} // end namespace serialization
+
+/// Metadata for a module file extension.
+struct ModuleFileExtensionMetadata {
+ /// The name used to identify this particular extension block within
+ /// the resulting module file. It should be unique to the particular
+ /// extension, because this name will be used to match the name of
+ /// an extension block to the appropriate reader.
+ std::string BlockName;
+
+ /// The major version of the extension data.
+ unsigned MajorVersion;
+
+ /// The minor version of the extension data.
+ unsigned MinorVersion;
+
+ /// A string containing additional user information that will be
+ /// stored with the metadata.
+ std::string UserInfo;
+};
+
+class ModuleFileExtensionReader;
+class ModuleFileExtensionWriter;
+
+/// An abstract superclass that describes a custom extension to the
+/// module/precompiled header file format.
+///
+/// A module file extension can introduce additional information into
+/// compiled module files (.pcm) and precompiled headers (.pch) via a
+/// custom writer that can then be accessed via a custom reader when
+/// the module file or precompiled header is loaded.
+class ModuleFileExtension : public llvm::RefCountedBase<ModuleFileExtension> {
+public:
+ virtual ~ModuleFileExtension();
+
+ /// Retrieves the metadata for this module file extension.
+ virtual ModuleFileExtensionMetadata getExtensionMetadata() const = 0;
+
+ /// Hash information about the presence of this extension into the
+ /// module hash code.
+ ///
+ /// The module hash code is used to distinguish different variants
+ /// of a module that are incompatible. If the presence, absence, or
+ /// version of the module file extension should force the creation
+ /// of a separate set of module files, override this method to
+ /// combine that distinguishing information into the module hash
+ /// code.
+ ///
+ /// The default implementation of this function simply returns the
+ /// hash code as given, so the presence/absence of this extension
+ /// does not distinguish module files.
+ virtual llvm::hash_code hashExtension(llvm::hash_code c) const;
+
+ /// Create a new module file extension writer, which will be
+ /// responsible for writing the extension contents into a particular
+ /// module file.
+ virtual std::unique_ptr<ModuleFileExtensionWriter>
+ createExtensionWriter(ASTWriter &Writer) = 0;
+
+ /// Create a new module file extension reader, given the
+ /// metadata read from the block and the cursor into the extension
+ /// block.
+ ///
+ /// May return null to indicate that an extension block with the
+ /// given metadata cannot be read.
+ virtual std::unique_ptr<ModuleFileExtensionReader>
+ createExtensionReader(const ModuleFileExtensionMetadata &Metadata,
+ ASTReader &Reader, serialization::ModuleFile &Mod,
+ const llvm::BitstreamCursor &Stream) = 0;
+};
+
+/// Abstract base class that writes a module file extension block into
+/// a module file.
+class ModuleFileExtensionWriter {
+ ModuleFileExtension *Extension;
+
+protected:
+ ModuleFileExtensionWriter(ModuleFileExtension *Extension)
+ : Extension(Extension) { }
+
+public:
+ virtual ~ModuleFileExtensionWriter();
+
+ /// Retrieve the module file extension with which this writer is
+ /// associated.
+ ModuleFileExtension *getExtension() const { return Extension; }
+
+ /// Write the contents of the extension block into the given bitstream.
+ ///
+ /// Responsible for writing the contents of the extension into the
+ /// given stream. All of the contents should be written into custom
+ /// records with IDs >= FIRST_EXTENSION_RECORD_ID.
+ virtual void writeExtensionContents(Sema &SemaRef,
+ llvm::BitstreamWriter &Stream) = 0;
+};
+
+/// Abstract base class that reads a module file extension block from
+/// a module file.
+///
+/// Subclasses
+class ModuleFileExtensionReader {
+ ModuleFileExtension *Extension;
+
+protected:
+ ModuleFileExtensionReader(ModuleFileExtension *Extension)
+ : Extension(Extension) { }
+
+public:
+ /// Retrieve the module file extension with which this reader is
+ /// associated.
+ ModuleFileExtension *getExtension() const { return Extension; }
+
+ virtual ~ModuleFileExtensionReader();
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_FRONTEND_MODULEFILEEXTENSION_H
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index ab39aef..08e7d40 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -30,23 +30,22 @@ 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.
+ /// \brief The chain of AST files, in the order in which we started to load
+ /// them (this order isn't really useful for anything).
SmallVector<ModuleFile *, 2> Chain;
+ /// \brief The chain of non-module PCH files. The first entry is the one named
+ /// by the user, the last one is the one that doesn't depend on anything
+ /// further.
+ SmallVector<ModuleFile *, 2> PCHChain;
+
// \brief The roots of the dependency DAG of AST files. This is used
// to implement short-circuiting logic when running DFS over the dependencies.
SmallVector<ModuleFile *, 2> Roots;
-
+
/// \brief All loaded modules, indexed by name.
llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
- typedef llvm::SetVector<const FileEntry *> AdditionalKnownModuleFileSet;
-
- /// \brief Additional module files that are known but not loaded. Tracked
- /// here so that we can re-export them if necessary.
- AdditionalKnownModuleFileSet AdditionalKnownModuleFiles;
-
/// \brief FileManager that handles translating between filenames and
/// FileEntry *.
FileManager &FileMgr;
@@ -121,24 +120,26 @@ public:
const PCHContainerReader &PCHContainerRdr);
~ModuleManager();
- /// \brief Forward iterator to traverse all loaded modules. This is reverse
- /// source-order.
+ /// \brief Forward iterator to traverse all loaded modules.
ModuleIterator begin() { return Chain.begin(); }
/// \brief Forward iterator end-point to traverse all loaded modules
ModuleIterator end() { return Chain.end(); }
- /// \brief Const forward iterator to traverse all loaded modules. This is
- /// in reverse source-order.
+ /// \brief Const forward iterator to traverse all loaded modules.
ModuleConstIterator begin() const { return Chain.begin(); }
/// \brief Const forward iterator end-point to traverse all loaded modules
ModuleConstIterator end() const { return Chain.end(); }
- /// \brief Reverse iterator to traverse all loaded modules. This is in
- /// source order.
+ /// \brief Reverse iterator to traverse all loaded modules.
ModuleReverseIterator rbegin() { return Chain.rbegin(); }
/// \brief Reverse iterator end-point to traverse all loaded modules.
ModuleReverseIterator rend() { return Chain.rend(); }
-
+
+ /// \brief A range covering the PCH and preamble module files loaded.
+ llvm::iterator_range<ModuleConstIterator> pch_modules() const {
+ return llvm::make_range(PCHChain.begin(), PCHChain.end());
+ }
+
/// \brief Returns the primary module associated with the manager, that is,
/// the first module loaded
ModuleFile &getPrimaryModule() { return *Chain[0]; }
@@ -235,19 +236,6 @@ public:
/// has been "accepted", and will not (can not) be unloaded.
void moduleFileAccepted(ModuleFile *MF);
- /// \brief Notification from the frontend that the given module file is
- /// part of this compilation (even if not imported) and, if this compilation
- /// is exported, should be made available to importers of it.
- bool addKnownModuleFile(StringRef FileName);
-
- /// \brief Get a list of additional module files that are not currently
- /// loaded but are considered to be part of the current compilation.
- llvm::iterator_range<AdditionalKnownModuleFileSet::const_iterator>
- getAdditionalKnownModuleFiles() {
- return llvm::make_range(AdditionalKnownModuleFiles.begin(),
- AdditionalKnownModuleFiles.end());
- }
-
/// \brief Visit each of the modules.
///
/// This routine visits each of the modules, starting with the
@@ -259,51 +247,17 @@ public:
/// operations that can find data in any of the loaded modules.
///
/// \param Visitor A visitor function that will be invoked with each
- /// module and the given user data pointer. The return value must be
- /// convertible to bool; when false, the visitation continues to
- /// modules that the current module depends on. When true, the
- /// visitation skips any modules that the current module depends on.
- ///
- /// \param UserData User data associated with the visitor object, which
- /// will be passed along to the visitor.
+ /// module. The return value must be convertible to bool; when false, the
+ /// visitation continues to modules that the current module depends on. When
+ /// true, the visitation skips any modules that the current module depends on.
///
/// \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,
+ void visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr);
- /// \brief Control DFS behavior during preorder visitation.
- enum DFSPreorderControl {
- Continue, /// Continue visiting all nodes.
- Abort, /// Stop the visitation immediately.
- SkipImports, /// Do not visit imports of the current node.
- };
-
- /// \brief Visit each of the modules with a depth-first traversal.
- ///
- /// This routine visits each of the modules known to the module
- /// manager using a depth-first search, starting with the first
- /// loaded module. The traversal invokes one callback before
- /// traversing the imports (preorder traversal) and one after
- /// traversing the imports (postorder traversal).
- ///
- /// \param PreorderVisitor A visitor function that will be invoked with each
- /// module before visiting its imports. The visitor can control how to
- /// continue the visitation through its return value.
- ///
- /// \param PostorderVisitor A visitor function taht will be invoked with each
- /// module after visiting its imports. The visitor may return true at any time
- /// to abort the depth-first visitation.
- ///
- /// \param UserData User data ssociated with the visitor object,
- /// which will be passed along to the user.
- void visitDepthFirst(DFSPreorderControl (*PreorderVisitor)(ModuleFile &M,
- void *UserData),
- bool (*PostorderVisitor)(ModuleFile &M, 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.
OpenPOWER on IntegriCloud