Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
//===- ASTDeserializationListener.h - Decl/Type PCH Read Events -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the ASTDeserializationListener class, which is notified
// by the ASTReader whenever a type or declaration is deserialized.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SERIALIZATION_ASTDESERIALIZATIONLISTENER_H
#define LLVM_CLANG_SERIALIZATION_ASTDESERIALIZATIONLISTENER_H
#include "clang/Basic/IdentifierTable.h"
#include "clang/Serialization/ASTBitCodes.h"
namespace clang {
class Decl;
class ASTReader;
class QualType;
class MacroDefinitionRecord;
class MacroInfo;
class Module;
class SourceLocation;
class ASTDeserializationListener {
public:
virtual ~ASTDeserializationListener();
/// \brief The ASTReader was initialized.
virtual void ReaderInitialized(ASTReader *Reader) { }
/// \brief An identifier was deserialized from the AST file.
virtual void IdentifierRead(serialization::IdentID ID,
IdentifierInfo *II) { }
/// \brief A macro was read from the AST file.
virtual void MacroRead(serialization::MacroID ID, MacroInfo *MI) { }
/// \brief A type was deserialized from the AST file. The ID here has the
/// qualifier bits already removed, and T is guaranteed to be locally
/// unqualified.
virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { }
/// \brief A decl was deserialized from the AST file.
virtual void DeclRead(serialization::DeclID ID, const Decl *D) { }
/// \brief A selector was read from the AST file.
virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {}
/// \brief A macro definition was read from the AST file.
virtual void MacroDefinitionRead(serialization::PreprocessedEntityID,
MacroDefinitionRecord *MD) {}
/// \brief A module definition was read from the AST file.
virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) {}
/// \brief A module import was read from the AST file.
virtual void ModuleImportRead(serialization::SubmoduleID ID,
SourceLocation ImportLoc) {}
};
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
clang_tablegen(AttrPCHRead.inc -gen-clang-attr-pch-read
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
TARGET ClangAttrPCHRead)
clang_tablegen(AttrPCHWrite.inc -gen-clang-attr-pch-write
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
TARGET ClangAttrPCHWrite)

View File

@ -0,0 +1,141 @@
//===- ContinuousRangeMap.h - Map with int range as key ---------*- 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 ContinuousRangeMap class, which is a highly
// specialized container used by serialization.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H
#define LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
#include <cassert>
#include <utility>
namespace clang {
/// \brief A map from continuous integer ranges to some value, with a very
/// specialized interface.
///
/// CRM maps from integer ranges to values. The ranges are continuous, i.e.
/// where one ends, the next one begins. So if the map contains the stops I0-3,
/// the first range is from I0 to I1, the second from I1 to I2, the third from
/// I2 to I3 and the last from I3 to infinity.
///
/// Ranges must be inserted in order. Inserting a new stop I4 into the map will
/// shrink the fourth range to I3 to I4 and add the new range I4 to inf.
template <typename Int, typename V, unsigned InitialCapacity>
class ContinuousRangeMap {
public:
using value_type = std::pair<Int, V>;
using reference = value_type &;
using const_reference = const value_type &;
using pointer = value_type *;
using const_pointer = const value_type *;
private:
using Representation = SmallVector<value_type, InitialCapacity>;
Representation Rep;
struct Compare {
bool operator ()(const_reference L, Int R) const {
return L.first < R;
}
bool operator ()(Int L, const_reference R) const {
return L < R.first;
}
bool operator ()(Int L, Int R) const {
return L < R;
}
bool operator ()(const_reference L, const_reference R) const {
return L.first < R.first;
}
};
public:
void insert(const value_type &Val) {
if (!Rep.empty() && Rep.back() == Val)
return;
assert((Rep.empty() || Rep.back().first < Val.first) &&
"Must insert keys in order.");
Rep.push_back(Val);
}
void insertOrReplace(const value_type &Val) {
iterator I = std::lower_bound(Rep.begin(), Rep.end(), Val, Compare());
if (I != Rep.end() && I->first == Val.first) {
I->second = Val.second;
return;
}
Rep.insert(I, Val);
}
using iterator = typename Representation::iterator;
using const_iterator = typename Representation::const_iterator;
iterator begin() { return Rep.begin(); }
iterator end() { return Rep.end(); }
const_iterator begin() const { return Rep.begin(); }
const_iterator end() const { return Rep.end(); }
iterator find(Int K) {
iterator I = std::upper_bound(Rep.begin(), Rep.end(), K, Compare());
// I points to the first entry with a key > K, which is the range that
// follows the one containing K.
if (I == Rep.begin())
return Rep.end();
--I;
return I;
}
const_iterator find(Int K) const {
return const_cast<ContinuousRangeMap*>(this)->find(K);
}
reference back() { return Rep.back(); }
const_reference back() const { return Rep.back(); }
/// \brief An object that helps properly build a continuous range map
/// from a set of values.
class Builder {
ContinuousRangeMap &Self;
public:
explicit Builder(ContinuousRangeMap &Self) : Self(Self) {}
Builder(const Builder&) = delete;
Builder &operator=(const Builder&) = delete;
~Builder() {
std::sort(Self.Rep.begin(), Self.Rep.end(), Compare());
std::unique(Self.Rep.begin(), Self.Rep.end(),
[](const_reference A, const_reference B) {
// FIXME: we should not allow any duplicate keys, but there are a lot of
// duplicate 0 -> 0 mappings to remove first.
assert((A == B || A.first != B.first) &&
"ContinuousRangeMap::Builder given non-unique keys");
return A == B;
});
}
void insert(const value_type &Val) {
Self.Rep.push_back(Val);
}
};
friend class Builder;
};
} // namespace clang
#endif // LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H

View File

@ -0,0 +1,207 @@
//===--- 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_GLOBALMODULEINDEX_H
#define LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <memory>
#include <utility>
namespace llvm {
class BitstreamCursor;
class MemoryBuffer;
}
namespace clang {
class DirectoryEntry;
class FileEntry;
class FileManager;
class IdentifierIterator;
class PCHContainerOperations;
class PCHContainerReader;
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.
std::unique_ptr<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(std::unique_ptr<llvm::MemoryBuffer> Buffer,
llvm::BitstreamCursor Cursor);
GlobalModuleIndex(const GlobalModuleIndex &) = delete;
GlobalModuleIndex &operator=(const GlobalModuleIndex &) = delete;
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 Returns an iterator for identifiers stored in the index table.
///
/// The caller accepts ownership of the returned object.
IdentifierIterator *createIdentifierIterator() const;
/// \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 Print debugging view to standard error.
void dump();
/// \brief Write a global index into the given
///
/// \param FileMgr The file manager to use to load module files.
/// \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.
static ErrorCode writeIndex(FileManager &FileMgr,
const PCHContainerReader &PCHContainerRdr,
StringRef Path);
};
}
#endif

View File

@ -0,0 +1,471 @@
//===--- Module.h - Module description --------------------------*- 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 Module class, which describes a module that has
// been loaded from an AST file.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SERIALIZATION_MODULE_H
#define LLVM_CLANG_SERIALIZATION_MODULE_H
#include "clang/Basic/FileManager.h"
#include "clang/Basic/Module.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"
#include <memory>
#include <string>
namespace llvm {
template <typename Info> class OnDiskChainedHashTable;
template <typename Info> class OnDiskIterableChainedHashTable;
}
namespace clang {
class DeclContext;
class Module;
namespace serialization {
namespace reader {
class ASTDeclContextNameLookupTrait;
}
/// \brief Specifies the kind of module that has been loaded.
enum ModuleKind {
MK_ImplicitModule, ///< File is an implicitly-loaded module.
MK_ExplicitModule, ///< File is an explicitly-loaded module.
MK_PCH, ///< File is a PCH file treated as such.
MK_Preamble, ///< File is a PCH file treated as the preamble.
MK_MainFile, ///< File is a PCH file treated as the actual main file.
MK_PrebuiltModule ///< File is from a prebuilt module path.
};
/// \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.
class InputFile {
enum {
Overridden = 1,
OutOfDate = 2,
NotFound = 3
};
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);
}
static InputFile getNotFound() {
InputFile File;
File.Val.setInt(NotFound);
return File;
}
const FileEntry *getFile() const { return Val.getPointer(); }
bool isOverridden() const { return Val.getInt() == Overridden; }
bool isOutOfDate() const { return Val.getInt() == OutOfDate; }
bool isNotFound() const { return Val.getInt() == NotFound; }
};
/// \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
/// may be a precompiled header, precompiled preamble, a module, or an AST file
/// of some sort loaded as the main file, all of which are specific formulations
/// of the general notion of a "module". A module may depend on any number of
/// other modules.
class ModuleFile {
public:
ModuleFile(ModuleKind Kind, unsigned Generation)
: Kind(Kind), Generation(Generation) {}
~ModuleFile();
// === General information ===
/// \brief The index of this module in the list of modules.
unsigned Index = 0;
/// \brief The type of this module.
ModuleKind Kind;
/// \brief The file name of the module file.
std::string FileName;
/// \brief The name of the module.
std::string ModuleName;
/// \brief The base directory of the module.
std::string BaseDirectory;
std::string getTimestampFilename() const {
return FileName + ".timestamp";
}
/// \brief The original source file name that was used to build the
/// primary AST file, which may have been modified for
/// relocatable-pch support.
std::string OriginalSourceFileName;
/// \brief The actual original source file name that was used to
/// build this AST file.
std::string ActualOriginalSourceFileName;
/// \brief The file ID for the original source file that was used to
/// build this AST file.
FileID OriginalSourceFileID;
/// \brief The directory that the PCH was originally created in. Used to
/// allow resolving headers even after headers+PCH was moved to a new path.
std::string OriginalDir;
std::string ModuleMapPath;
/// \brief Whether this precompiled header is a relocatable PCH file.
bool RelocatablePCH = false;
/// \brief Whether timestamps are included in this module file.
bool HasTimestamps = false;
/// \brief The file entry for the module file.
const FileEntry *File = nullptr;
/// The signature of the module file, which may be used instead of the size
/// and modification time to identify this particular file.
ASTFileSignature Signature;
/// \brief Whether this module has been directly imported by the
/// user.
bool DirectlyImported = false;
/// \brief The generation of which this module file is a part.
unsigned Generation;
/// The memory buffer that stores the data associated with
/// this AST file, owned by the PCMCache in the ModuleManager.
llvm::MemoryBuffer *Buffer;
/// \brief The size of this file, in bits.
uint64_t SizeInBits = 0;
/// \brief The global bit offset (or base) of this module
uint64_t GlobalBitOffset = 0;
/// \brief The serialized bitstream data for this file.
StringRef Data;
/// \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).
///
/// WARNING: This is largely useless. It doesn't tell you when a module was
/// made visible, just when the first submodule of that module was imported.
SourceLocation DirectImportLoc;
/// \brief The source location where this module was first imported.
SourceLocation ImportLoc;
/// \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;
/// The module offset map data for this file. If non-empty, the various
/// ContinuousRangeMaps described below have not yet been populated.
StringRef ModuleOffsetMap;
// === Input Files ===
/// \brief The cursor to the start of the input-files block.
llvm::BitstreamCursor InputFilesCursor;
/// \brief Offsets for all of the input file entries in the AST file.
const llvm::support::unaligned_uint64_t *InputFileOffsets = nullptr;
/// \brief The input files that have been loaded from this AST file.
std::vector<InputFile> InputFilesLoaded;
// All user input files reside at the index range [0, NumUserInputFiles), and
// system input files reside at [NumUserInputFiles, InputFilesLoaded.size()).
unsigned NumUserInputFiles = 0;
/// \brief If non-zero, specifies the time when we last validated input
/// files. Zero means we never validated them.
///
/// The time is specified in seconds since the start of the Epoch.
uint64_t InputFilesValidationTimestamp = 0;
// === Source Locations ===
/// \brief Cursor used to read source location entries.
llvm::BitstreamCursor SLocEntryCursor;
/// \brief The number of source location entries in this AST file.
unsigned LocalNumSLocEntries = 0;
/// \brief The base ID in the source manager's view of this module.
int SLocEntryBaseID = 0;
/// \brief The base offset in the source manager's view of this module.
unsigned SLocEntryBaseOffset = 0;
/// \brief Offsets for all of the source location entries in the
/// AST file.
const uint32_t *SLocEntryOffsets = nullptr;
/// \brief SLocEntries that we're going to preload.
SmallVector<uint64_t, 4> PreloadSLocEntries;
/// \brief Remapping table for source locations in this module.
ContinuousRangeMap<uint32_t, int, 2> SLocRemap;
// === Identifiers ===
/// \brief The number of identifiers in this AST file.
unsigned LocalNumIdentifiers = 0;
/// \brief Offsets into the identifier table data.
///
/// This array is indexed by the identifier ID (-1), and provides
/// the offset into IdentifierTableData where the string data is
/// stored.
const uint32_t *IdentifierOffsets = nullptr;
/// \brief Base identifier ID for identifiers local to this module.
serialization::IdentID BaseIdentifierID = 0;
/// \brief Remapping table for identifier IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap;
/// \brief Actual data for the on-disk hash table of identifiers.
///
/// This pointer points into a memory buffer, where the on-disk hash
/// table for identifiers actually lives.
const char *IdentifierTableData = nullptr;
/// \brief A pointer to an on-disk hash table of opaque type
/// IdentifierHashTable.
void *IdentifierLookupTable = nullptr;
/// \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
/// all of the macro definitions.
llvm::BitstreamCursor MacroCursor;
/// \brief The number of macros in this AST file.
unsigned LocalNumMacros = 0;
/// \brief Offsets of macros in the preprocessor block.
///
/// This array is indexed by the macro ID (-1), and provides
/// the offset into the preprocessor block where macro definitions are
/// stored.
const uint32_t *MacroOffsets = nullptr;
/// \brief Base macro ID for macros local to this module.
serialization::MacroID BaseMacroID = 0;
/// \brief Remapping table for macro IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> MacroRemap;
/// \brief The offset of the start of the set of defined macros.
uint64_t MacroStartOffset = 0;
// === Detailed PreprocessingRecord ===
/// \brief The cursor to the start of the (optional) detailed preprocessing
/// record block.
llvm::BitstreamCursor PreprocessorDetailCursor;
/// \brief The offset of the start of the preprocessor detail cursor.
uint64_t PreprocessorDetailStartOffset = 0;
/// \brief Base preprocessed entity ID for preprocessed entities local to
/// this module.
serialization::PreprocessedEntityID BasePreprocessedEntityID = 0;
/// \brief Remapping table for preprocessed entity IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap;
const PPEntityOffset *PreprocessedEntityOffsets = nullptr;
unsigned NumPreprocessedEntities = 0;
// === Header search information ===
/// \brief The number of local HeaderFileInfo structures.
unsigned LocalNumHeaderFileInfos = 0;
/// \brief Actual data for the on-disk hash table of header file
/// information.
///
/// This pointer points into a memory buffer, where the on-disk hash
/// table for header file information actually lives.
const char *HeaderFileInfoTableData = nullptr;
/// \brief The on-disk hash table that contains information about each of
/// the header files.
void *HeaderFileInfoTable = nullptr;
// === Submodule information ===
/// \brief The number of submodules in this module.
unsigned LocalNumSubmodules = 0;
/// \brief Base submodule ID for submodules local to this module.
serialization::SubmoduleID BaseSubmoduleID = 0;
/// \brief Remapping table for submodule IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> SubmoduleRemap;
// === Selectors ===
/// \brief The number of selectors new to this file.
///
/// This is the number of entries in SelectorOffsets.
unsigned LocalNumSelectors = 0;
/// \brief Offsets into the selector lookup table's data array
/// where each selector resides.
const uint32_t *SelectorOffsets = nullptr;
/// \brief Base selector ID for selectors local to this module.
serialization::SelectorID BaseSelectorID = 0;
/// \brief Remapping table for selector IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> SelectorRemap;
/// \brief A pointer to the character data that comprises the selector table
///
/// The SelectorOffsets table refers into this memory.
const unsigned char *SelectorLookupTableData = nullptr;
/// \brief A pointer to an on-disk hash table of opaque type
/// ASTSelectorLookupTable.
///
/// This hash table provides the IDs of all selectors, and the associated
/// instance and factory methods.
void *SelectorLookupTable = nullptr;
// === Declarations ===
/// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It
/// has read all the abbreviations at the start of the block and is ready to
/// jump around with these in context.
llvm::BitstreamCursor DeclsCursor;
/// \brief The number of declarations in this AST file.
unsigned LocalNumDecls = 0;
/// \brief Offset of each declaration within the bitstream, indexed
/// by the declaration ID (-1).
const DeclOffset *DeclOffsets = nullptr;
/// \brief Base declaration ID for declarations local to this module.
serialization::DeclID BaseDeclID = 0;
/// \brief Remapping table for declaration IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> DeclRemap;
/// \brief Mapping from the module files that this module file depends on
/// to the base declaration ID for that module as it is understood within this
/// module.
///
/// This is effectively a reverse global-to-local mapping for declaration
/// IDs, so that we can interpret a true global ID (for this translation unit)
/// as a local ID (for this module file).
llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs;
/// \brief Array of file-level DeclIDs sorted by file.
const serialization::DeclID *FileSortedDecls = nullptr;
unsigned NumFileSortedDecls = 0;
/// \brief Array of category list location information within this
/// module file, sorted by the definition ID.
const serialization::ObjCCategoriesInfo *ObjCCategoriesMap = nullptr;
/// \brief The number of redeclaration info entries in ObjCCategoriesMap.
unsigned LocalNumObjCCategoriesInMap = 0;
/// \brief The Objective-C category lists for categories known to this
/// module.
SmallVector<uint64_t, 1> ObjCCategories;
// === Types ===
/// \brief The number of types in this AST file.
unsigned LocalNumTypes = 0;
/// \brief Offset of each type within the bitstream, indexed by the
/// type ID, or the representation of a Type*.
const uint32_t *TypeOffsets = nullptr;
/// \brief Base type ID for types local to this module as represented in
/// the global type ID space.
serialization::TypeID BaseTypeIndex = 0;
/// \brief Remapping table for type IDs in this module.
ContinuousRangeMap<uint32_t, int, 2> TypeRemap;
// === Miscellaneous ===
/// \brief Diagnostic IDs and their mappings that the user changed.
SmallVector<uint64_t, 8> PragmaDiagMappings;
/// \brief List of modules which depend on this module
llvm::SetVector<ModuleFile *> ImportedBy;
/// \brief List of modules which this module depends on
llvm::SetVector<ModuleFile *> Imports;
/// \brief Determine whether this module was directly imported at
/// 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 ||
Kind == MK_PrebuiltModule;
}
/// \brief Dump debugging output for this module.
void dump();
};
} // end namespace serialization
} // end namespace clang
#endif

View File

@ -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:
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

View File

@ -0,0 +1,328 @@
//===- ModuleManager.cpp - Module Manager -----------------------*- 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 ModuleManager class, which manages a set of loaded
// modules for the ASTReader.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
#define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Serialization/Module.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include <cstdint>
#include <ctime>
#include <memory>
#include <string>
#include <utility>
namespace clang {
class FileEntry;
class FileManager;
class GlobalModuleIndex;
class HeaderSearch;
class MemoryBufferCache;
class ModuleMap;
class PCHContainerReader;
namespace serialization {
/// \brief Manages the set of modules loaded by an AST reader.
class ModuleManager {
/// \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<std::unique_ptr<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;
/// \brief FileManager that handles translating between filenames and
/// FileEntry *.
FileManager &FileMgr;
/// Cache of PCM files.
IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
/// \brief Knows how to unwrap module containers.
const PCHContainerReader &PCHContainerRdr;
/// \brief Preprocessor's HeaderSearchInfo containing the module map.
const HeaderSearch &HeaderSearchInfo;
/// \brief A lookup of in-memory (virtual file) buffers
llvm::DenseMap<const FileEntry *, std::unique_ptr<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 = nullptr;
/// \brief State used by the "visit" operation to avoid malloc traffic in
/// calls to visit().
struct VisitState {
explicit VisitState(unsigned N) : VisitNumber(N, 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 = 1;
/// \brief The next visit state.
VisitState *NextState = nullptr;
};
/// \brief The first visit() state in the chain.
VisitState *FirstVisitState = nullptr;
VisitState *allocateVisitState();
void returnVisitState(VisitState *State);
public:
using ModuleIterator = llvm::pointee_iterator<
SmallVectorImpl<std::unique_ptr<ModuleFile>>::iterator>;
using ModuleConstIterator = llvm::pointee_iterator<
SmallVectorImpl<std::unique_ptr<ModuleFile>>::const_iterator>;
using ModuleReverseIterator = llvm::pointee_iterator<
SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>;
using ModuleOffset = std::pair<uint32_t, StringRef>;
explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
const PCHContainerReader &PCHContainerRdr,
const HeaderSearch &HeaderSearchInfo);
~ModuleManager();
/// \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.
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.
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<SmallVectorImpl<ModuleFile *>::const_iterator>
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]; }
/// \brief Returns the primary module associated with the manager, that is,
/// the first module loaded.
ModuleFile &getPrimaryModule() const { return *Chain[0]; }
/// \brief Returns the module associated with the given index
ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
/// \brief Returns the module associated with the given file name.
ModuleFile *lookupByFileName(StringRef FileName) const;
/// \brief Returns the module associated with the given module name.
ModuleFile *lookupByModuleName(StringRef ModName) const;
/// \brief Returns the module associated with the given module file.
ModuleFile *lookup(const FileEntry *File) const;
/// \brief Returns the in-memory (virtual file) buffer with the given name
std::unique_ptr<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
};
using ASTFileSignatureReader = ASTFileSignature (*)(StringRef);
/// \brief Attempts to create a new module and add it to the list of known
/// modules.
///
/// \param FileName The file name of the module to be loaded.
///
/// \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 ExpectedSignature The expected signature of the module file, used
/// for validation. This will be zero if unknown.
///
/// \param ReadSignature Reads the signature from an AST file without actually
/// loading it.
///
/// \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 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,
ASTFileSignature ExpectedSignature,
ASTFileSignatureReader ReadSignature,
ModuleFile *&Module,
std::string &ErrorStr);
/// \brief Remove the modules starting from First (to the end).
void removeModules(ModuleIterator First,
llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
ModuleMap *modMap);
/// \brief Add an in-memory buffer the list of known buffers
void addInMemoryBuffer(StringRef FileName,
std::unique_ptr<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
/// "root" modules that no other loaded modules depend on, and
/// proceeding to the leaf modules, visiting each module only once
/// during the traversal.
///
/// This traversal is intended to support various "lookup"
/// operations that can find data in any of the loaded modules.
///
/// \param Visitor A visitor function that will be invoked with each
/// 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(llvm::function_ref<bool(ModuleFile &M)> Visitor,
llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr);
/// \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();
MemoryBufferCache &getPCMCache() const { return *PCMCache; }
};
} // namespace serialization
} // namespace clang
#endif // LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H

View File

@ -0,0 +1,28 @@
//===--- SerializationDiagnostic.h - Serialization Diagnostics -*- 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_SERIALIZATIONDIAGNOSTIC_H
#define LLVM_CLANG_SERIALIZATION_SERIALIZATIONDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
namespace clang {
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define SERIALIZATIONSTART
#include "clang/Basic/DiagnosticSerializationKinds.inc"
#undef DIAG
NUM_BUILTIN_SERIALIZATION_DIAGNOSTICS
};
} // end namespace diag
} // end namespace clang
#endif