/// \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.
SmallVector<Module*, 2> Chain;
+
+ /// \brief All loaded modules, indexed by name.
+ llvm::StringMap<Module*> Modules;
+
public:
typedef SmallVector<Module*, 2>::iterator ModuleIterator;
typedef SmallVector<Module*, 2>::const_iterator ModuleConstIterator;
typedef SmallVector<Module*, 2>::reverse_iterator ModuleReverseIterator;
+ typedef std::pair<uint32_t, StringRef> ModuleOffset;
+ ~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(); }
- const std::string &getPrimaryFileName() const { return Chain[0]->FileName; }
-
+ /// \brief Returns the primary module associated with the manager, that is,
+ /// the first module loaded
Module &getPrimaryModule() { return *Chain[0]; }
+
+ /// \brief Returns the primary module associated with the manager, that is,
+ /// the first module loaded.
+ Module &getPrimaryModule() const { return *Chain[0]; }
+
+ /// \brief Returns the latest module associated with the manager, that is,
+ /// the last module loaded
Module &getLastModule() { return *Chain.back(); }
+
+ /// \brief Returns the module associated with the given index
Module &operator[](unsigned Index) const { return *Chain[Index]; }
+ /// \brief Returns the module associated with the given name
+ Module *lookup(StringRef Name) { return Modules.lookup(Name); }
+
+ /// \brief Number of modules loaded
unsigned size() const { return Chain.size(); }
- Module &addModule(ModuleKind Type) {
- Module *newModule = new Module(Type);
- Chain.push_back(newModule);
- return *newModule;
- }
+ /// \brief Creates a new module and adds it to the list of known modules
+ Module &addModule(StringRef FileName, ModuleKind Type);
- ~ModuleManager() {
- for (unsigned i = 0, e = Chain.size(); i != e; ++i)
- delete Chain[e - i - 1];
- }
+ /// \brief Exports the list of loaded modules with their corresponding names
+ void exportLookup(SmallVector<ModuleOffset, 16> &Target);
};
} // end namespace serialization
/// \brief AST buffers for chained PCHs created and stored in memory.
/// First (not depending on another) PCH in chain is in front.
std::vector<llvm::MemoryBuffer *> ASTBuffers;
-
- /// \brief All loaded modules, indexed by name.
- llvm::StringMap<Module*> Modules;
-
- /// \brief The first module in source order.
- Module *FirstInSource;
/// \brief The module manager which manages modules and their dependencies
ModuleManager ModuleMgr;
std::pair<Module *, int32_t>, 4>
GlobalCXXBaseSpecifiersMapType;
- /// \brief Mapping from global CXX base specifier IDs to the module in which the
- /// CXX base specifier resides along with the offset that should be added to the
- /// global CXX base specifer ID to produce a local ID.
+ /// \brief Mapping from global CXX base specifier IDs to the module in which
+ /// the CXX base specifier resides along with the offset that should be added
+ /// to the global CXX base specifer ID to produce a local ID.
GlobalCXXBaseSpecifiersMapType GlobalCXXBaseSpecifiersMap;
/// \name CodeGen-relevant special data
/// \brief Retrieve the name of the named (primary) AST file
const std::string &getFileName() const {
- return ModuleMgr.getPrimaryFileName();
+ return ModuleMgr.getPrimaryModule().FileName;
}
/// \brief Retrieve the name of the original source file name
SmallVector<StoredDiagnostic, 4> Result;
Result.reserve(Diags.size());
assert(MMan && "Don't have a module manager");
- serialization::Module *Mod = MMan->Modules.lookup(ModName);
+ serialization::Module *Mod = MMan->ModuleMgr.lookup(ModName);
assert(Mod && "Don't have preamble module");
SLocRemap &Remap = Mod->SLocRemap;
for (unsigned I = 0, N = Diags.size(); I != N; ++I) {
uint32_t Offset = io::ReadUnalignedLE32(Data);
uint16_t Len = io::ReadUnalignedLE16(Data);
StringRef Name = StringRef((const char*)Data, Len);
- Module *OM = Modules.lookup(Name);
+ Module *OM = ModuleMgr.lookup(Name);
if (!OM) {
Error("SourceLocation remap refers to unknown module");
return Failure;
break;
}
-
case SOURCE_MANAGER_LINE_TABLE:
if (ParseLineTable(F, Record))
return Failure;
ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName,
ModuleKind Type) {
- Module *Prev = !ModuleMgr.size() ? 0 : &ModuleMgr.getLastModule();
- ModuleMgr.addModule(Type);
- Module &F = ModuleMgr.getLastModule();
- if (Prev)
- Prev->NextInSource = &F;
- else
- FirstInSource = &F;
- F.Loaders.push_back(Prev);
-
- Modules[FileName.str()] = &F;
-
- // Set the AST file name.
- F.FileName = FileName;
+ Module &F = ModuleMgr.addModule(FileName, Type);
if (FileName != "-") {
CurrentDir = llvm::sys::path::parent_path(FileName);
SemaObj->StdBadAlloc = SemaDeclRefs[1];
}
- for (Module *F = FirstInSource; F; F = F->NextInSource) {
+ for (Module *F = &ModuleMgr.getPrimaryModule(); F; F = F->NextInSource) {
// If there are @selector references added them to its pool. This is for
// implementation of -Wselector.
: Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
- Consumer(0), FirstInSource(0), RelocatablePCH(false), isysroot(isysroot),
+ Consumer(0), RelocatablePCH(false), isysroot(isysroot),
DisableValidation(DisableValidation),
DisableStatCache(DisableStatCache), NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), TotalNumSLocEntries(0),
Diagnostic &Diags, StringRef isysroot,
bool DisableValidation, bool DisableStatCache)
: DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
- Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0), FirstInSource(0),
+ Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
RelocatablePCH(false), isysroot(isysroot),
DisableValidation(DisableValidation), DisableStatCache(DisableStatCache),
NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0),
delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
}
+
+/// \brief Creates a new module and adds it to the list of known modules
+Module &ModuleManager::addModule(StringRef FileName, ModuleKind Type) {
+ Module *Prev = !size() ? 0 : &getLastModule();
+ Module *Current = new Module(Type);
+
+ Current->FileName = FileName.str();
+
+ Chain.push_back(Current);
+ Modules[FileName.str()] = Current;
+
+ if (Prev)
+ Prev->NextInSource = Current;
+ Current->Loaders.push_back(Prev);
+
+ return *Current;
+}
+
+/// \brief Exports the list of loaded modules with their corresponding names
+void ModuleManager::exportLookup(SmallVector<ModuleOffset, 16> &Target) {
+ Target.reserve(size());
+ for (llvm::StringMap<Module*>::const_iterator
+ I = Modules.begin(), E = Modules.end();
+ I != E; ++I) {
+ Target.push_back(ModuleOffset(I->getValue()->SLocEntryBaseOffset,
+ I->getKey()));
+ }
+ std::sort(Target.begin(), Target.end());
+}
+
+ModuleManager::~ModuleManager() {
+ for (unsigned i = 0, e = Chain.size(); i != e; ++i)
+ delete Chain[e - i - 1];
+}
Record.push_back(CLANG_VERSION_MINOR);
Record.push_back(!isysroot.empty());
// FIXME: This writes the absolute path for chained headers.
- const std::string &BlobStr = Chain ? Chain->getFileName() : Target.getTriple().getTriple();
+ const std::string &BlobStr =
+ Chain ? Chain->getFileName() : Target.getTriple().getTriple();
Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, BlobStr);
// Original file name and file ID
// Sorted by offset.
typedef std::pair<uint32_t, StringRef> ModuleOffset;
SmallVector<ModuleOffset, 16> Modules;
- Modules.reserve(Chain->Modules.size());
- for (llvm::StringMap<Module*>::const_iterator
- I = Chain->Modules.begin(), E = Chain->Modules.end();
- I != E; ++I) {
- Modules.push_back(ModuleOffset(I->getValue()->SLocEntryBaseOffset,
- I->getKey()));
- }
- std::sort(Modules.begin(), Modules.end());
+
+ Chain->ModuleMgr.exportLookup(Modules);
Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_MAP));