[WIP][Cling] Refactor CIFactory and add incremental action support#21903
[WIP][Cling] Refactor CIFactory and add incremental action support#21903SahilPatidar wants to merge 1 commit intoroot-project:masterfrom
Conversation
Test Results 6 files 6 suites 1d 8h 23m 4s ⏱️ For more details on these failures, see this check. Results for commit 3dd5414. |
|
@vgvassilev Some of them show errors like: This may be happening because I made rough changes in Previously, I mentioned an issue related to the Clad plugin consumer. There was a problem with If we allow the plugin consumer, then during In the original Cling implementation, as far as I can see, we never call We need to find a way (to pass plugin into |
|
When clad is OFF we should not run these tests. This means that we need to suppress them in cmake. cc: @guitargeek Are the related llvm/clang changes really required? I think we should do extra effort to avoid them.. |
|
Those are in CodeGenAction.cpp. On my local system, they were causing a segmentation fault. I’m not sure why, but after commenting them out, the crash stopped: And another change related to CompilerInstance and SourceManager initialization. As I mentioned, in Cling we use one large virtual source file to keep source locations consistent. For now, I added a temporary helper: |
Sounds suspicious. Maybe we should run valgrind. |
|
We need to address these issues in the current setup:
For So, I tried overriding the MainFileID inside I also tried another approach (just to test how it behaves). I let BeginSourceFile initialize the SourceManager as usual, and then I created a new virtual file. This file uses the end location of the main file when creating its FileID, so it acts like an includer instead of the main file. const char* Filename = "<<< includer >>>";
FileEntryRef FE = FM.getVirtualFileRef(Filename, 1U << 15U, time(0));
SM.setFileIsTransient(FE);
SourceLocation Result = SM.getLocForEndOfFile(SM.getMainFileID());
m_VirtualFileID =
SM.createFileID(FE, Result, SrcMgr::C_User);
auto Buffer = llvm::MemoryBuffer::getMemBufferCopy("/*CLING DEFAULT MEMBUF*/;\n");
SM.overrideFileContents(FE, std::move(Buffer));After this, I did not see any issue while building. But when I ran roottest-root-tree, a few tests started failing. One of them failed with this error: This error happens inside bool DeclExtractor::CheckForClashingNames(
const llvm::SmallVector<NamedDecl*, 4>& Decls,
DeclContext* DC) {
for (size_t i = 0; i < Decls.size(); ++i) {
...
else if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
LookupResult Previous(*m_Sema, ND->getDeclName(), ND->getLocation(),
Sema::LookupOrdinaryName,
RedeclarationKind::ForVisibleRedeclaration);
m_Sema->LookupQualifiedName(Previous, DC);
m_Sema->CheckVariableDeclaration(VD, Previous);
...I am not sure why this is happening, and I am also not sure any of these way is correct? Can we do something better? |
|
Can you debug side by side with the working version? |
|
I found the issue. The second approach (using a different virtual file instead of the main file) was failing because of a check in It uses In my case, since I used another virtual file instead of the main file, this function returned false. Because of that, the declaration was not added to the namespace, which caused the name collision error. static bool typedInClingPrompt(FullSourceLoc L) {
if (L.isInvalid())
return false;
const SourceManager &SM = L.getManager();
const FileID FID = SM.getFileID(L);
return SM.isFileOverridden(SM.getFileEntryForID(FID)) &&
(SM.getFileID(SM.getIncludeLoc(FID)) == SM.getMainFileID());
} |
Maybe we can add a check to see if the buffer name starts with Something similar to what we have here: root/core/metacling/src/TCling.cxx Line 1186 in 20705fe |
|
I tried it, and now the tests match the working version on my machine. If second approach is correct to do in Cling, then the only remaining issue is the Clad plugin. |
|
For Clad, here is where we steal the consumers and tune them: https://github.com/vgvassilev/clad/blob/db7f52fafcb45bf8cbaa8b0c7256c664c553e940/tools/ClangPlugin.cpp#L154 and here https://github.com/vgvassilev/clad/blob/db7f52fafcb45bf8cbaa8b0c7256c664c553e940/tools/ClangPlugin.h#L173 I suspect some of these assumptions are incorrect after your patch. |
|
From the code, I see that in the original setup we never called In the original version, we just passed the plugin to the DeclCollector consumer here: In the new version, we pass the plugin consumer in CI during That’s why I directly return the consumer from |
Ok, we will need to think how to circumvent the stealing on clad’s side. Can you think of a way? EDIT: Maybe we steal only when the preprocessor has no CLING macro defined? Or even if we don’t have incremental extensions defined. |
|
I need to understand the behavior when we make changes on the Clad side. How can I modify the Clad plugin and recompile it on root side? |
Not easy. One is edit the source in the build folder clad-prefix, then go to the build directory clad-prefix/…/build and do “make install”. Then cd to the top-most root_build and call “make Cling”. That should be all you need. |
This Pull request:
This PR refactors CIFactory and adds support for IncrementalAction (from
Clang-Repl). The goal is to reduce the amount of Clang-specific logic handled inside CIFactory and rely more on Clang’s existing infrastructure.Changes or fixes:
Checklist:
This PR fixes #