Skip to content

Commit e9060b6

Browse files
committed
Add initial implementation of the semantic GMI.
1 parent f532151 commit e9060b6

File tree

5 files changed

+138
-49
lines changed

5 files changed

+138
-49
lines changed

core/metacling/src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ endif()
3131

3232
ROOT_OBJECT_LIBRARY(MetaCling
3333
rootclingTCling.cxx
34+
TCling.cxx
3435
TClingBaseClassInfo.cxx
3536
TClingCallbacks.cxx
3637
TClingCallFunc.cxx
3738
TClingClassInfo.cxx
38-
TCling.cxx
3939
TClingDataMemberInfo.cxx
4040
TClingDeclInfo.cxx
4141
TClingMethodArgInfo.cxx

core/metacling/src/TCling.cxx

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,63 @@ static GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc, cling
11221122
RecreateIndex = true;
11231123
}
11241124
if (RecreateIndex) {
1125-
GlobalModuleIndex::writeIndex(CI.getFileManager(), CI.getPCHContainerReader(), ModuleIndexPath);
1125+
cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1126+
clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1127+
1128+
struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1129+
DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1130+
clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1131+
TraverseDecl(TU);
1132+
}
1133+
bool VisitNamedDecl(NamedDecl *ND) {
1134+
for (auto R : ND->redecls()) {
1135+
if (!R->isFromASTFile())
1136+
continue;
1137+
if (TagDecl *TD = llvm::dyn_cast<TagDecl>(R)) {
1138+
if (TD->isCompleteDefinition())
1139+
Register(TD);
1140+
} else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(R))
1141+
Register(NSD, /*AddSingleEntry=*/ false);
1142+
else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(R))
1143+
Register(TND);
1144+
// FIXME: Add the rest...
1145+
}
1146+
return true; // continue decending
1147+
}
1148+
private:
1149+
clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1150+
void Register(NamedDecl* ND, bool AddSingleEntry = true) {
1151+
assert(ND->isFromASTFile());
1152+
// FIXME: All decls should have an owning module once rootcling
1153+
// updates its generated decls from within the LookupHelper & co.
1154+
if (!ND->hasOwningModule()) {
1155+
#ifndef NDEBUG
1156+
SourceManager &SM = ND->getASTContext().getSourceManager();
1157+
SourceLocation Loc = ND->getLocation();
1158+
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
1159+
(void)FE;
1160+
assert(FE->getName().contains("input_line_"));
1161+
#endif
1162+
return;
1163+
}
1164+
1165+
Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1166+
assert(OwningModule);
1167+
if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1168+
return;
1169+
// FIXME: The FileEntry in not stable to serialize.
1170+
// FIXME: We might end up with many times with the same module.
1171+
// FIXME: We might end up two modules containing a definition.
1172+
// FIXME: What do we do if no definition is found.
1173+
DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1174+
}
1175+
};
1176+
DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1177+
1178+
GlobalModuleIndex::writeIndex(CI.getFileManager(),
1179+
CI.getPCHContainerReader(),
1180+
ModuleIndexPath,
1181+
&IDs);
11261182
ModuleManager->resetForReload();
11271183
ModuleManager->loadGlobalIndex();
11281184
GlobalIndex = ModuleManager->getGlobalIndex();
@@ -1171,19 +1227,27 @@ static void RegisterCxxModules(cling::Interpreter &clingInterp)
11711227
LoadModules(CommonModules, clingInterp);
11721228

11731229
// These modules should not be preloaded but they fix issues.
1174-
std::vector<std::string> FIXMEModules = {"Hist", "Gpad", "Graf",
1175-
"GenVector", "Smatrix", "Tree",
1176-
"TreePlayer", "Physics",
1177-
"Proof", "Geom"};
1230+
// FIXME: Hist is not a core module but is very entangled to MathCore and
1231+
// causes issues.
1232+
std::vector<std::string> FIXMEModules = {"Hist"};
11781233
LoadModules(FIXMEModules, clingInterp);
11791234

11801235
clang::CompilerInstance &CI = *clingInterp.getCI();
11811236
GlobalModuleIndex *GlobalIndex = nullptr;
1237+
// Conservatively enable platform by platform.
1238+
bool supportedPlatform = false;
1239+
// Allow forcefully enabling the GMI.
11821240
const char *experimentalGMI = gSystem->Getenv("ROOT_EXPERIMENTAL_GMI");
1183-
if (experimentalGMI && strcmp(experimentalGMI,"false") != 0) {
1241+
if (experimentalGMI && strcmp(experimentalGMI,"false") != 0)
1242+
supportedPlatform = true;
1243+
1244+
if (supportedPlatform && !gSystem->Getenv("ROOT_DISABLE_GMI")) {
11841245
loadGlobalModuleIndex(SourceLocation(), clingInterp);
1246+
// FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1247+
// We should investigate how to suppress it completely.
11851248
GlobalIndex = CI.getModuleManager()->getGlobalIndex();
11861249
}
1250+
11871251
llvm::StringSet<> KnownModuleFileNames;
11881252
if (GlobalIndex)
11891253
GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);

core/metacling/src/TClingCallbacks.cxx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ bool TClingCallbacks::LookupObject(LookupResult &R, Scope *S) {
288288

289289
bool TClingCallbacks::findInGlobalModuleIndex(DeclarationName Name, bool loadFirstMatchOnly /*=true*/)
290290
{
291+
if (::getenv("ROOT_DISABLE_GMI"))
292+
return false;
293+
291294
const CompilerInstance *CI = m_Interpreter->getCI();
292295
const LangOptions &LangOpts = CI->getPreprocessor().getLangOpts();
293296

@@ -315,6 +318,10 @@ bool TClingCallbacks::findInGlobalModuleIndex(DeclarationName Name, bool loadFir
315318
for (auto FileName : FoundModules) {
316319
StringRef ModuleName = llvm::sys::path::stem(*FileName);
317320
fIsLoadingModule = true;
321+
if (gDebug > 2)
322+
llvm::errs() << "Loading " << ModuleName << " on demand"
323+
<< " for " << Name.getAsString() << "\n";
324+
318325
m_Interpreter->loadModule(ModuleName);
319326
fIsLoadingModule = false;
320327
if (loadFirstMatchOnly)

interpreter/llvm/src/tools/clang/include/clang/Serialization/GlobalModuleIndex.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ class GlobalModuleIndex {
141141
EC_IOError
142142
};
143143

144+
using UserDefinedInterestingIDs =
145+
llvm::StringMap<llvm::SmallVector<const FileEntry*, 2>>;
146+
144147
/// \brief Read a global index file for the given directory.
145148
///
146149
/// \param Path The path to the specific module cache where the module files
@@ -205,9 +208,11 @@ class GlobalModuleIndex {
205208
/// creating modules.
206209
/// \param Path The path to the directory containing module files, into
207210
/// which the global index will be written.
211+
/// \param Optionally pass already precomputed interesting identifiers.
208212
static ErrorCode writeIndex(FileManager &FileMgr,
209213
const PCHContainerReader &PCHContainerRdr,
210-
StringRef Path);
214+
StringRef Path,
215+
UserDefinedInterestingIDs *ExternalIDs = nullptr);
211216
};
212217
}
213218

interpreter/llvm/src/tools/clang/lib/Serialization/GlobalModuleIndex.cpp

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -422,9 +422,6 @@ namespace {
422422

423423
/// \brief Builder that generates the global module index file.
424424
class GlobalModuleIndexBuilder {
425-
FileManager &FileMgr;
426-
const PCHContainerReader &PCHContainerRdr;
427-
428425
/// Mapping from files to module file information.
429426
typedef llvm::MapVector<const FileEntry *, ModuleFileInfo> ModuleFilesMap;
430427

@@ -464,14 +461,20 @@ namespace {
464461
}
465462

466463
public:
467-
explicit GlobalModuleIndexBuilder(
468-
FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr)
469-
: FileMgr(FileMgr), PCHContainerRdr(PCHContainerRdr) {}
464+
explicit GlobalModuleIndexBuilder(GlobalModuleIndex::UserDefinedInterestingIDs* ExternalIDs) {
465+
if (!ExternalIDs)
466+
return;
467+
468+
for (const auto & I : *ExternalIDs)
469+
for (const FileEntry * J : I.getValue())
470+
InterestingIdentifiers[I.getKey()].push_back(getModuleFileInfo(J).ID);
471+
}
470472

471473
/// \brief Load the contents of the given module file into the builder.
472474
///
473475
/// \returns true if an error occurred, false otherwise.
474-
bool loadModuleFile(const FileEntry *File);
476+
bool loadModuleFile(const FileEntry *File, FileManager &FileMgr,
477+
const PCHContainerReader &PCHContainerRdr);
475478

476479
/// \brief Write the index to the given bitstream.
477480
/// \returns true if an error occurred, false otherwise.
@@ -542,7 +545,9 @@ namespace {
542545
};
543546
}
544547

545-
bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
548+
bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File,
549+
FileManager &FileMgr,
550+
const PCHContainerReader &PCHContainerRdr) {
546551
// Open the module file.
547552

548553
auto Buffer = FileMgr.getBufferForFile(File, /*isVolatile=*/true);
@@ -693,7 +698,10 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
693698
DEnd = Table->data_end();
694699
D != DEnd; ++D) {
695700
std::pair<StringRef, bool> Ident = *D;
696-
InterestingIdentifiers[Ident.first].push_back(ID);
701+
if (Ident.second)
702+
InterestingIdentifiers[Ident.first].push_back(ID);
703+
else
704+
(void)InterestingIdentifiers[Ident.first];
697705
}
698706
}
699707

@@ -755,14 +763,15 @@ bool GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
755763
for (auto MapEntry : ImportedModuleFiles) {
756764
auto *File = MapEntry.first;
757765
ImportedModuleFileInfo &Info = MapEntry.second;
758-
// if (getModuleFileInfo(File).Signature) {
759-
// if (getModuleFileInfo(File).Signature != Info.StoredSignature)
760-
// // Verify Signature.
761-
// return true;
762-
// } else if (Info.StoredSize != File->getSize() ||
763-
// Info.StoredModTime != File->getModificationTime())
764-
// // Verify Size and ModTime.
765-
// return true;
766+
if (getModuleFileInfo(File).Signature) {
767+
if (getModuleFileInfo(File).Signature != Info.StoredSignature)
768+
// Verify Signature.
769+
return true;
770+
} else if (Info.StoredSize != File->getSize() ||
771+
(Info.StoredModTime &&
772+
Info.StoredModTime != File->getModificationTime()))
773+
// Verify Size and ModTime.
774+
return true;
766775
}
767776

768777
using namespace llvm;
@@ -846,7 +855,9 @@ bool GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
846855
GlobalModuleIndex::ErrorCode
847856
GlobalModuleIndex::writeIndex(FileManager &FileMgr,
848857
const PCHContainerReader &PCHContainerRdr,
849-
StringRef Path) {
858+
StringRef Path,
859+
UserDefinedInterestingIDs *ExternalIDs /* = nullptr */) {
860+
850861
llvm::SmallString<128> IndexPath;
851862
IndexPath += Path;
852863
llvm::sys::path::append(IndexPath, IndexFileName);
@@ -869,32 +880,34 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr,
869880
}
870881

871882
// The module index builder.
872-
GlobalModuleIndexBuilder Builder(FileMgr, PCHContainerRdr);
873-
874-
// Load each of the module files.
875-
std::error_code EC;
876-
for (llvm::sys::fs::directory_iterator D(Path, EC), DEnd;
877-
D != DEnd && !EC;
878-
D.increment(EC)) {
879-
// If this isn't a module file, we don't care.
880-
if (llvm::sys::path::extension(D->path()) != ".pcm") {
881-
// ... unless it's a .pcm.lock file, which indicates that someone is
882-
// in the process of rebuilding a module. They'll rebuild the index
883-
// at the end of that translation unit, so we don't have to.
884-
if (llvm::sys::path::extension(D->path()) == ".pcm.lock")
885-
return EC_Building;
883+
GlobalModuleIndexBuilder Builder(ExternalIDs);
884+
885+
if (!ExternalIDs) {
886+
// Load each of the module files.
887+
std::error_code EC;
888+
for (llvm::sys::fs::directory_iterator D(Path, EC), DEnd;
889+
D != DEnd && !EC;
890+
D.increment(EC)) {
891+
// If this isn't a module file, we don't care.
892+
if (llvm::sys::path::extension(D->path()) != ".pcm") {
893+
// ... unless it's a .pcm.lock file, which indicates that someone is
894+
// in the process of rebuilding a module. They'll rebuild the index
895+
// at the end of that translation unit, so we don't have to.
896+
if (llvm::sys::path::extension(D->path()) == ".pcm.lock")
897+
return EC_Building;
886898

887-
continue;
888-
}
899+
continue;
900+
}
889901

890-
// If we can't find the module file, skip it.
891-
const FileEntry *ModuleFile = FileMgr.getFile(D->path());
892-
if (!ModuleFile)
893-
continue;
902+
// If we can't find the module file, skip it.
903+
const FileEntry *ModuleFile = FileMgr.getFile(D->path());
904+
if (!ModuleFile)
905+
continue;
894906

895-
// Load this module file.
896-
if (Builder.loadModuleFile(ModuleFile))
897-
return EC_IOError;
907+
// Load this module file.
908+
if (Builder.loadModuleFile(ModuleFile, FileMgr, PCHContainerRdr))
909+
return EC_IOError;
910+
}
898911
}
899912

900913
// The output buffer, into which the global index will be written.

0 commit comments

Comments
 (0)