IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an
email to Administrator. User accounts are meant only to access repo
and report issues and/or generate pull requests.
This is a purpose-specific Git hosting for
BaseALT
projects. Thank you for your understanding!
Только зарегистрированные пользователи имеют доступ к сервису!
Для получения аккаунта, обратитесь к администратору.
If we preload modules using cling::Interpreter::loadModule the
deserializations of the module initializers (such as global variables).
We want the behavior of clang::Sema::ActOnModuleImport, however, it requires
valid source locations.
This patch ignores the ImportDecls which presumably came from loadModule.
Original commit message:
"Over the years we have a pathological issue with cling when it calls directly
compiler API. Most of the API assume they are called from code residing in a
text file. This code has valid source locations which can be used for
comparisons and things like point of instantiation for template instantiations.
This means that whenever a clang API requires a valid source location, cling
should have an interface which gives a pseudo-valid, commonly-rooted unique
source location.
We are bitten by this fact when preloading modules as if we have diagnostics
they cannot be ordered due to the fact that the compared decls from two
different modules do not have a common includer.
This patch avoids using an API and relies on a textual form which does not have
this problem at the cost of synthesizing an extra string."
Over the years we have a pathological issue with cling when it calls directly
compiler API. Most of the API assume they are called from code residing in a
text file. This code has valid source locations which can be used for
comparisons and things like point of instantiation for template instantiations.
This means that whenever a clang API requires a valid source location, cling
should have an interface which gives a pseudo-valid, commonly-rooted unique
source location.
We are bitten by this fact when preloading modules as if we have diagnostics
they cannot be ordered due to the fact that the compared decls from two
different modules do not have a common includer.
This patch avoids using an API and relies on a textual form which does not have
this problem at the cost of synthesizing an extra string.
If the ValuePrinter runtime header gets included,
a transaction might be emitted, and the transaction
containing the function body cannot be found anymore.
This causes roottest/root/meta/getFuncBody.C to fail
with runtime modules.
Assuming that page_size is a power of 2, the calculation of the
base address of the page can be simplified and avoid a division.
According to POSIX, either MS_SYNC or MS_ASYNC must be specified
when calling msync(). Failure to include one of these flags will
cause msync() to fail on some systems.
When msync() returns -1, the pointer is only considered invalid
when errno is set to ENOMEM. In principle, the other possible
values for errno won't happen, but if they do, that should be
considered an error, hence the assert condition needed an update.
EBUSY shouldn't happen since we do not add MS_INVALIDATE to flags,
and EINVAL shouldn't happen because we always pass a multiple of
the page size to msync(). EFAULT is only used in Linux 2.4.18 and
earlier instead of ENOMEM.
libc++ comes with a builtin modulemap and is using "std" as the
module name for the STL. To stay consistent we should use the same
name (and "std" is anyway a better name).
We have user library search paths which come from LD_LIBRARY_PATH or similar;
and system library search paths which are coming from the platform.
This patch enables external users performing symbol resolution to filter out
system search paths when they know the symbol cannot be there.
Now, TClingCallbacks can merge the modules vs non-modules code paths, where
the modules prebuilt path is essentially our LD_LIBRARY_PATH.
If the constructor of the contained object is not run (e.g. because
assembling its arguments triggered an exception), the dtor must not
be run when destructing the cling::Value. Detect this case by imprinting
canary bytes into the contained object bytes: if they have changed,
run the dtor, if not assume that the constructor has failed.
This will cause false positives in those cases where the constructor
is not modifying the first object bytes: in these cases, the dtor
is not run even though the ctor is run. That is still better than
the other case (where the dtor crashes because no ctor was run).
ACLiC now synthesizes a modulemap with a suffix _ACLiC_dict.modulemap. The file
contains the source file to be compiled and the corresponding library.
The modulemap is then passed to rootcling via -fmodule-map-file= flag to avoid
naming clashes with possibly existing other modulemap files.
This patch teaches cling to work with the -fmodule-map-file= flag.
ACLiC supports automatic inclusion of Rtypes.h (making ClassDef macro
available). Modules are built in isolation and are resilient to #include
of Rtypes.h at rootcling startup time. We make module Core (containing Rtypes.h)
visible via a newly implemented callback.
The transactions are useful to buffer Decls before sending them to CodeGen,
to verify semantic validity before emitting. If there is no codegen,
DeclCollecting them wastes CPU cycles during PCH generation time
because all headers are in one single transaction. Of course this also
speeds up regular rootcling invocations.
This patch moves the ROOT-specific rdict.pcm optimization in the EXTENSION_BLOCK
of a C++ module file.
This reduces the generated artifacts and simplifies the loading of a rdict pcm
file as it is now part of the C++ module file. This patch paves our way to
using the global module indexing.
This should solve the problem we have been seeing with cmsUnload. The problem stems from the fact that TCling::AutoParseImplRecurse
uses the address of the current transactions has an index/key when registering a class in fTransactionHeadersMap.
On some platforms TInterpreter.h is parsed late, i.e. during the compilation of:
gInterpreter->AutoParse("SiStripCluster");
consequently (as AutoParse does not create its own transaction), the transactions that contains
the parsin of TInterpreter is the last one committed before AutoParseImplRecurse is executed.
Without the parsing of TInterpreter.h then that transaction is return by fInterpreter->getCurrentTransaction().
With the parsing of TInterpreter.h, during the commit of the transaction of the callbacks are triggered
and one of the decl is a constant (kFALSE) and thus, in TCling::HandleNewDecl, provokes the execution of
if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
return;
which will triggered the creation of a Transaction, however since the last top level transaction was
just switch to the state 'Committed', the new transaction will not be nested and thus
IncrementalParser::endTransaction will set the current transaction to 'nullptr'.
And this value of nullptr for the key of fTransactionHeadersMap is neither guaranteed to be unique
nor handled properly by the rest of the code.
It is unclear why this problem have surfaced recently.
On a failing machine, rebuilding with a 2 month old commit (ad9e5c42cb) still exhibits the problem.
The implementation of class->library mapping makes a call to the
LookupHelper::findScope. This makes the recursive invocations to
LookupHelper::findScope -> ... -> LookupHelper::findScope happen more often.
Dropbox folders (among others) can contain parentheses.
Without this patch, ROOT and cling misinterpret those directories as arguments.
Instead, first find the end of the ".x" line.
If the previous token was a closing paren, we assume that the preceding
tokens (up to the non-nested opening paren) belong to the argument.
On my systems (RHEL7 and Android Termux) PAGE_SIZE is defined to 4096 in /usr/include/sys/user.h . The enum then produces a compile-term error.
Adding this change resolves this error for me.
The getNameAsString interface causes a lot of temporary allocations.
The analysis if a decl is a cling-style wrapper can work only on a
simple declarations on the global scope.
This patch filters out complex declarations (eg in namespaces) and
checks only the identifier content.
The patch reduces the memory footprint difference shown in root-project/root#3012.
The user might use utilities which print on cout and expects the output
to be shown immediately.
This patch automatically flushes std::cout after each execution of a wrapper.
This patch includes:
- Remove existing modulemap.overlay files
Cling now can generate virtual overlay files on-demand.
- Implement `-modulemap_overlay` flag to Cling
This flag is used to tell Cling the location of modulemaps to be
overlayed. (eg. stl.modulemap, libc.modulemap)
- Generate and load virtual modulemap in Cling
It is in Interpreter constructor, happens as part of cxxmodules
initialization step.
- Implement an interface to Clang CompilerInvocation which can take FileSystem pointer
Previously, Clang only took a "string of filenames" which clearly doesn't
work for our usecase. We already discussed this new interface at
modules meeting, so this change will land upstream.
- Add a file existence check in Clang
When compiling a pcm and when Clang saw the #include with which pcm was available
(or being generated implicitly), Clang was putting a notation of the full path to this pcm.
This caused an error when build directory was deleted, because the path didn't exist anymore.
This patch enables modules to be binary distributed, and to make it
work in CMSSW enviroment.
This patch contains two functionality:
1. Autoloading of dynamic symbols for system headers
There is three kind of symbols in shared object file, which is 1
normal symbols, 2 dynamic symbols, and 3 hidden visibility symbols.
Linker doesn't care about 3, but should take care (of course) 1 and
2. For system headers, often symbols are defined in .dynsym section
which means they are 2 dynamic symbols. This patch adds support of
autoloading those symbols. We fallback to resolving dynamic symbols
from system headers only if we couldn't resolve from normal symbol
table, as the initialization of header search is expensive (iterating
through all system headers)
2. Register callback from IncrementalExecutor
Previously, LazyFunctionCreatorAutoload was getting callback only
from DynamicLibraryManager::loadLibrary. This was enough for fixing
tests, but is insufficient to handle "symbol <something> unresolved
while linking function" errors as those errors are emitted from
IncrementalExecutor. Adding a callback from IncrementalExecutor
enables us to unresolved symbols.
It fixes these kind of errors:
`IncrementalExecutor::executeFunction: symbol '_ZN7TCanvasC1EPKcS1_iiii' unresolved while linking function '_GLOBAL__sub_I_cling_module_8'!`
When cling is embedded and the plugins are linked statically we can rely
on the initialization of the Preprocessor to register the pragmas.
Currently, due to the current implementation deficiency we cannot rely
on the same mechanism when loading the plugins as shared objects.
This patch fixes the failing cling test.
This reverts commit 0f583c7ef0173fba1caa7680188e7bc767f5d97d.
We need this change because whoever uses MetaParser.h will not be
able to compile their program. MetaParser.h includes MetaLexer.h.
This feature can be enabled by setting an env variable ROOT_CLING_TIMING.
It prints some information about how much time different parts of clang
take.
We use the target clingInterpreter in a few places as a
general dependency rule making sure the cling infrastructure is
already built.
In some cases, such as clad, the highly parallel builds trigger
build of clad before clangSema, clangBasic and clangAST are built.
This patch ensures the right dependencies are in order.
This fixes https://sft.its.cern.ch/jira/browse/ROOT-9672 by having
cling::Interpreter::DeclareCFunction return the transaction containing the
compiled code.
With the previous code, cling::Interpreter::compileFunction will get confused by
transaction created during the callbacks executed during the
cling::IncrementalParser::commitTransaction of the main transaction.
Reproducer:
With a main composed of 'only':
int main(int argc, char ** argv)
{
char const * class_string = (argc == 2) ? argv[1] : "std::vector<int>";
auto const result [[gnu::unused]] = TClass::GetClass(class_string);
return 0;
}
which is a representation of real use case (in a more complex setup) in ART.
We were getting:
Error in <TClingCallFunc::make_wrapper>: Failed to compile
==== SOURCE BEGIN ====
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-security"
__attribute__((used)) extern "C" void __cf_0(void* obj, int nargs, void** args, void* ret)
{
if (ret) {
(*(TStreamerInfo**)ret) = new TStreamerInfo();
return;
}
else {
new TStreamerInfo();
return;
}
}
#pragma clang diagnostic pop
==== SOURCE END ====
Error in <TClingCallFunc::ExecT>: Called with no wrapper, not implemented!
Error in <TVirtualStreamerInfo::Factory>: The plugin handler for TVirtualStreamerInfo was found but failed to create the factory object!
The reason is that during TClingCallFunc::make_wrapper, the call to cling::Interpreter::compileFunction ends with:
if (const llvm::GlobalValue* GV
= getLastTransaction()->getModule()->getNamedValue(name))
However in the 'broken' case, the getLastTransaction does not return the transaction for the code being compiled by DeclareCFunction but instead the one used/created at:
#0 cling::IncrementalParser::endTransaction (this=0x4a2980, T=0x8c0fb0) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/IncrementalParser.cpp:345
#1 0x00007fffeebc7899 in cling::Interpreter::PushTransactionRAII::pop (this=0x7fffffffcb00) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/Interpreter.cpp:111
#2 0x00007fffeebc785e in cling::Interpreter::PushTransactionRAII::~PushTransactionRAII (this=0x7fffffffcb00, __in_chrg=<optimized out>)
at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/Interpreter.cpp:106
#3 0x00007fffeebeb659 in cling::LookupHelper::findScope (this=0x4a9dd0, className=..., diagOnOff=cling::LookupHelper::NoDiagnostics, resultType=0x7fffffffcd08, instantiateTemplate=false)
at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/LookupHelper.cpp:466
#4 0x00007fffeeabe0df in TCling::CheckClassInfo (this=0x4a0550, name=<optimized out>, autoload=<optimized out>, isClassOrNamespaceOnly=<optimized out>)
at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/metacling/src/TCling.cxx:3630
#5 0x00007ffff7c3040d in TClass::Init (this=this@entry=0xdafd20, name=name@entry=0x7ffff7cb7638 "TGlobal", cversion=cversion@entry=2, typeinfo=typeinfo@entry=0x7ffff7d8b6d8 <typeinfo for TGlobal>, isa=isa@entry=0x477430,
dfil=dfil@entry=0x7ffff7cb8cab "TGlobal.h", ifil=<optimized out>, dl=<optimized out>, il=<optimized out>, givenInfo=<optimized out>, silent=<optimized out>)
at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/meta/src/TClass.cxx:1431
#6 0x00007ffff7c3a1b8 in TClass::TClass (this=0xdafd20, name=0x7ffff7cb7638 "TGlobal", cversion=<optimized out>, info=..., isa=0x477430, dfil=0x7ffff7cb8cab "TGlobal.h",
ifil=0x7ffff7cccf88 "/local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/meta/src/TGlobal.cxx", dl=27, il=25, silent=false) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/meta/src/TClass.cxx:1273
#7 0x00007ffff7c3a72a in ROOT::CreateClass (cname=0x7ffff7cb7638 "TGlobal", id=id@entry=2, info=..., isa=isa@entry=0x477430, dfil=dfil@entry=0x7ffff7cb8cab "TGlobal.h",
ifil=ifil@entry=0x7ffff7cccf88 "/local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/meta/src/TGlobal.cxx", dl=27, il=25) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/meta/src/TClass.cxx:5607
#8 0x00007ffff7c4b552 in ROOT::Internal::TDefaultInitBehavior::CreateClass (il=25, dl=27, ifil=0x7ffff7cccf88 "/local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/meta/src/TGlobal.cxx", dfil=0x7ffff7cb8cab "TGlobal.h",
isa=0x477430, info=..., id=2, cname=<optimized out>, this=0x7ffff7da7508 <ROOT::Internal::DefineBehavior(void*, void*)::theDefault>) at /home/pcanal/root_builds/v6-14-00-patches/opt/include/Rtypes.h:176
#9 ROOT::TGenericClassInfo::GetClass (this=0x7ffff7dab660 <ROOT::GenerateInitInstanceLocal(TGlobal const*)::instance>) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/meta/src/TGenericClassInfo.cxx:250
#10 0x00007ffff7b1a2d8 in TGlobal::Class () at /home/pcanal/root_builds/v6-14-00-patches/opt/core/base/G__Core.cxx:17156
#11 0x00007ffff7ac01de in TGlobal::IsA (this=0xee3bc0) at /home/pcanal/root_builds/v6-14-00-patches/opt/include/TGlobal.h:48
#12 TGlobal::CheckTObjectHashConsistency (this=0xee3bc0) at /home/pcanal/root_builds/v6-14-00-patches/opt/include/TGlobal.h:48
#13 0x00007ffff7be9dcd in TObject::CheckedHash (this=0xee3bc0) at /home/pcanal/root_builds/v6-14-00-patches/opt/include/TObject.h:314
#14 THashTable::GetCheckedHashValue (this=0xe65a20, obj=0xee3bc0) at /home/pcanal/root_builds/v6-14-00-patches/opt/include/THashTable.h:94
#15 THashTable::Add (this=0xe65a20, obj=0xee3bc0) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/cont/src/THashTable.cxx:96
#16 0x00007ffff7be6bf1 in THashList::AddLast (this=this@entry=0x5be690, obj=obj@entry=0xee3bc0) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/cont/src/THashList.cxx:100
#17 0x00007ffff7c4e0d1 in TListOfDataMembers::AddLast (this=0x5be690, obj=0xee3bc0) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/meta/src/TListOfDataMembers.cxx:103
#18 0x00007ffff7ab8785 in TList::Add (obj=0xee3bc0, this=0x5be690) at /home/pcanal/root_builds/v6-14-00-patches/opt/include/TList.h:87
#19 TROOT::GetListOfGlobals (this=0x7ffff7da7a60 <ROOT::Internal::GetROOT1()::alloc>, load=load@entry=false) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/base/src/TROOT.cxx:1767
#20 0x00007fffeeab1058 in TCling::HandleNewDecl (this=0x4a0550, DV=0xedf238, isDeserialized=isDeserialized@entry=true, modifiedTClasses=...) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/metacling/src/TCling.cxx:555
#21 0x00007fffeeabb785 in TCling::UpdateListsOnCommitted (this=0x4a0550, T=...) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/metacling/src/TCling.cxx:6115
#22 0x00007fffeebd0103 in cling::MultiplexInterpreterCallbacks::TransactionCommitted (this=0x57fe20, T=...) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/MultiplexInterpreterCallbacks.h:76
#23 0x00007fffeed05d71 in cling::IncrementalParser::commitTransaction (this=0x4a2980, PRT=..., ClearDiagClient=true) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/IncrementalParser.cpp:532
#24 0x00007fffeed06399 in cling::IncrementalParser::Compile (this=0x4a2980, input=..., Opts=...) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/IncrementalParser.cpp:663
#25 0x00007fffeebcbc4e in cling::Interpreter::DeclareInternal (this=0x4a0f30, input=..., CO=..., T=0x7fffffffd680) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/Interpreter.cpp:1195
#26 0x00007fffeebca8e8 in cling::Interpreter::declare (this=0x4a0f30, input=..., T=0x7fffffffd680) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/Interpreter.cpp:823
#27 0x00007fffeebcb560 in cling::Interpreter::DeclareCFunction (this=0x4a0f30, name=..., code=..., withAccessControl=true) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/Interpreter.cpp:1096
#28 0x00007fffeebcb862 in cling::Interpreter::compileFunction (this=0x4a0f30, name=..., code=..., ifUnique=false, withAccessControl=true)
at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/interpreter/cling/lib/Interpreter/Interpreter.cpp:1140
#29 0x00007fffeeafb83c in TClingCallFunc::compile_wrapper (withAccessControl=true, wrapper=..., wrapper_name=..., this=0xcf3c10) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/metacling/src/TClingCallFunc.cxx:270
#30 TClingCallFunc::make_wrapper (this=this@entry=0xcf3c10) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/metacling/src/TClingCallFunc.cxx:1096
#31 0x00007fffeeafbcb8 in TClingCallFunc::IFacePtr (this=this@entry=0xcf3c10) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/metacling/src/TClingCallFunc.cxx:2233
#32 0x00007fffeeafbe83 in TClingCallFunc::ExecT<long> (address=0x0, this=0xcf3c10) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/metacling/src/TClingCallFunc.cxx:2045
#33 TClingCallFunc::ExecInt (this=0xcf3c10, address=0x0) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/metacling/src/TClingCallFunc.cxx:2065
#34 0x00007ffff7c56e8d in TMethodCall::Execute (this=0xd97710, object=<optimized out>, retLong=@0x7fffffffd958: 0) at /local2/pcanal/cint_working/rootcling/v6-14-00-patches/core/meta/src/TMethodCall.cxx:457
#35 0x0000000000401009 in TMethodCall::Execute(long&) ()
#36 0x00000000004010ea in long TPluginHandler::ExecPluginImpl<>() ()
#37 0x000000000040106d in long TPluginHandler::ExecPlugin<>(int) ()
#38 0x0000000000400e21 in mytest() ()
#39 0x0000000000400e92 in main ()
This is the final version of "printValue" discussion.
We agreed that printValue interface should be altered to ToString
interface, which can be invoked `gInterpreter->ToString(XYZ)`. (ToString is in TCling and toString is in Interpreter :D)
This patch contains:
- Implementation of toString in Interpreter.cpp
- Re-Implementation of ClingPrintValue to use ToString because I changed to use Evaluate some time ago.
- Removing of RVec version of printValue which wasn't used at all
- Fix test/vecops_rvec.cxx, printValue is never supposed to be called by a normal user.
Calling VirtualQuery() is very expansive. For example, the testUnfold5a.C tutorial (interpreted) times out after 3600 seconds, and runs in about 60 seconds without calling VirtualQuery(). So just bypass it and return true for the time being
Visual Studio 2017 doesn't use the registry anymore, so no need to try to find keys. This prevent picking wrong directories in the case there is another version installed on the computer, and prevent also the following errors when starting ROOT:
RegQueryValueEx: returned 2: The system cannot find the file specified.
RegOpenKeyEx: returned 2: The system cannot find the file specified.
The operations done by the LookupHelper are costly in both memory and
performance. Almost every operation requires memory allocation and parsing
of often non-trivial C++ code.
Unfortunately, the LookupHelper is used very intensively by rootcling and
ROOT. The callers usually do not use any caching mechanisms and redo the
expensive operations over and over even though the answer is known to be
the same as before. For instance, building the dictionary of shows:
```
MathCore:
Cached entries: 217
Total parse requests: 54051
Cache hits: 53834
TreePlayer:
Cached entries: 183
Total parse requests: 57697
Cache hits: 57514
```
This patch introduces the first set of caching functionality. In
particular, each LookupHelper::find* function allocates a memory buffer
which is then stored in the clang::SourceManager. We hash the buffer
content and keep a mapping between a hash and FileID and next time we
encounter the same content we do not allocate a new FileID but reuse the
old one. We see decrease in memory footprint by 7% for non-cxxmodules ROOT.
For cxxmodules we see significant reduction of the pcm sizes (by half)
which translates into rss improvements:
```
master before:
cpu time = 0.291462 seconds
sys time = 0.064409 seconds
res memory = 345.816 Mbytes
vir memory = 573.508 Mbytes
master after:
cpu time = 0.235828 seconds
sys time = 0.098327 seconds
res memory = 260.012 Mbytes
vir memory = 377.945 Mbytes
```
Patch by Yuka Takahashi and me.
Clang allows third party shared libraries to provide user-defined
extensions. For example, a custom libTemplateInstantiation.so can
visualize all template instantiation chains in clang. To enable it
one needs to pass a set of options such as -fplugin.
Cling should be able to inherently work with clang plugins. However,
cling still does not make full use of the clang driver where the plugin
setup is handled.
This patch enables plugins in cling and extends them in some aspects.
In particular, cling allows loading of plugins from shared libraries
but also if they are linked to the same library where cling is. This is
very useful in cases where cling runs itself in a shared library (eg
libCling). Users of libCling (such as ROOT) prefer to keep all llvm and
clang related symbols local to avoid symbol clashes if there is another
version of clang and llvm linked against a package. This can be done by
dlopen-ing libCling with RTLD_LOCAL visibility mode. Then the only way
for clang plugins to work in this scenario is to be linked to libCling.
Patch by Aleksandr Efremov and me.
Problem:
If a c++ statement with a concrete template parameter will type in, cling pass the (unwrapped) input line and the specialization of the statement, generated by compilerinstance to the clang nvptx. This causes an explicit-specialization-after-instantiation-error.
Solution:
Template specialization declaration will be save two times at a transaction. Once with the type kCCIHandleCXXImplicitFunctionInstantiation and once with the type kCCIHandleTopLevelDecl. To avoid sending a template specialization to the clang nvptx and causing an explicit-specialization-after-instantiation-error it have to check, which kCCIHandleTopLevelDecl declaration is also a kCCIHandleCXXImplicitFunctionInstantiation declaration.
As input of clang nvptx there are two possible sources. The raw input of `IncrementalParser::parseInternal()` or the AST-Printer of the `llvm::module`. Now, to decide, which input source should be use, I use the value `Transaction::ConsumerCallInfo::kCCIHandleTopLevelDecl`. This allows more C++ constructs to use.
Fixed a small bug. The AST-printer prints `setValueNoAlloc()` without the scope `cling::runtime::internal`. This caused an error, because clang could not find the declaration in the global space. The solution are dummy declaration in the global space.
At the moment, templates doesn't works.
- little changes at comments and code style
- try to use const in IncrementalCUDADeviceCompiler, where is possible
- move CUDA device code compiler instance to IncrementalParser
- change the members of CuArgs to const and adjust the setCuArgs method
- use std::vector<string> instead llvm::Smallvector<const char *> to build argv for executeAndWait
- improve the error messages of generatePCH(), generatePTX() and generateFatbinary()
- replace m_Counter with a copy in IncrementalCUDADeviceCompiler to avoid involuntary changes
Before this commit, the CUDA device code Compiler class overwrited source code .cu files, if the translation get wrong. Now, it renames the faulty files, so you can check, which source code cause compiler errors.
Before, it was not possible to find the clang++, which is contained in the cling, if we don't start the clang from the bin folder ('./cling -xcuda'). Now, for example it is possible to start the cling with 'bin/cling -xcuda' .
Fix a Bug, which avoid to start './cling -xcuda -fsyntax-only'.
In some cases, the path of the cling temp folder contains some non printable chars at the end.
Change the handling of the path string, to solve this problem.
Now, it is possible to declare variables on the prompt, which are visible for other statements.
The problems was, that cling wrapped all statements in a function, to get valid input. So, every variable is just visible inside in its own wrapper function. To solve the problem, cling change the local variable declaration to a global declaration.
The implementation for the CUDA compiler checks, if the unwrapping is happened. If it happened, the c++ code of the unwrapped variable declaration (AST-printer) instead the raw input will be written to the .cu-file.
At the moment, to extend the AST-tree of the device code, we use PCH-files to extend the exist device code with new lines of code. In detail, if we want to create a new PTX-file, we use the CUDA code (.cu file) and a PCH-file with the existing AST as input and generate an new PCH-file, which contains the whole AST. Then, the PCH-file will compiled to a PTX-file.
A bug in clang prevent, that we can’t generate more than 5 new PCH-files. The bug is not easy to fix, so I write a small workaround. Instead using a PCH-file, which contains the AST, we generate a new complete AST from all .cu-files every time.
The workaround is temporary and should removed, if clang is patched.
Now, it is possible to set some arguments of the clang nvptx and fatbinary via arguments at cling start. The arguments are filtered. So not every argument is possible at the moment. The Arguments can’t changed during runtime, because the PCH-files forbid it. For Example, the calng nvptx use the optimization level, which is set at start of cling.
At the moment, the debug options of clang nvptx are simple. If any debug option is detected, just a -g will add to the clang nvptx.
Additional PTX options for clang nvptx doesn’t works at the moment. There is a problem at parsing at the start of cling.
I replaced copies of the include paths with a pointer to the headerSearchOptions. Now, explicit handling of the include paths is not more necessary. Add include paths, which was declared via argument at start also works.
The class IncrementalCUDADeviceCompiler use external tools to generate PTX and cuda fatbin files. It runs the tools clang and fatbinary via llvm::sys::ExecuteAndWait. The class also handle to include new code in existing code. The steps of the compiler pipeline are:
- clang: CUDA C++ + previous PCH -> PCH
- clang: PCH -> PTX
- fatbinary: PTX -> fatbin
There is no selection of code. Every input of the cling will pass to the IncrementalCUDADeviceCompiler.
Now, it is possible to define functions with c++ attributes without the .rawInput mode. For example functions like `[[ noreturn ]] foo() { ... }` or `[[deprecated]] [[nodiscard]] int bar(){ … }`.
This reverts commit 011aa8200277cd31957e222afd9b37415458b31f.
This is a revert of revert. I reverted the first commit because adding
"." to prebuiltmodulepath was causing failure in runtime modules, but
now we're skipping "." in TCling::LazyFunctionCreatorAutoloadForModule so
doesn't matter even if we have ".".
We had test failures in runtime nightlies such as this one:
https://epsft-jenkins.cern.ch/view/ROOT/job/root-nightly-runtime-cxxmodules/95/BUILDTYPE=Debug,COMPILER=gcc62,LABEL=slc6/testReport/junit/projectroot.roottest.root.math/smatrix/roottest_root_math_smatrix_testKalman/
Failures were due to what @pcanal commented in #2135, that some so files in
roottest doesn't have external linkage. (It means that if you call
dlopen(libfoo.so), linux kernel can't find dependency libraries and it
emits "undefined symbol" error when they try to initialize global
variables in libfoo.so but couldn't find symbol definition)
With pch, rootmap files were providing information about the depending library.
However we stopped generating rootmap files in #2127 and that's why we
got these failures. To fix this issue, I implemented a callback to
TCling which gets called when DynamicLibraryManager fails. The callback
pass error message to TCling and it handles message if it contains "undefined error".
This reverts commit 5298b418eec4129351888f41cb7c3bfc90161e22.
This commit was mistakenly committed. PR was opened in #1730, but it was
closed and moved to #1761. I didn't notice this and created another PR
in #1980.
This change was causing 100+ failures in runtime cxxmodules nightlies.
(Eg. https://epsft-jenkins.cern.ch/job/root-pullrequests-build/29183/testReport/junit/projectroot/runtutorials/tutorial_fit_FittingDemo/)
We want to have **proper** PrebuildModulesPaths which information were
extracted from LD_LIBRARY_PATH and DYLD_LIBRARY_PATH, not a random ".".
Because of this commit, we were trying to autoload libraries generated
by roottest on-demand (for example "./h1analysisTreeReader_C.so") This
is not an intentional behavior, these autogenerated libraries are
already loaded by roottest and what we want to do is to load **proper**
libraries like libHist.so instead.
In previous allmodules&autoloading patch, we used callback from
DeserializationListener to get Decl and loaded corresponding libraries.
It worked, but the performance was bad because ROOT was loading
excessive libraries.
In this patch, we use TCling::LazyFunctionCreatorAutoloadForModule. This
function gets callback when "mangled_name" was not found in loaded
libraries thus we have to the load corresponding library and lookup
again.
I used unordered_map to store mangled identifier and library pair. I'm
doing an optimization by hashing mangled name and storing library not by
name but by uint8 and hold uint8-name information in another vector.
Also tried std::map but unorderd_map was more performant. There are
better hash table like:
https://probablydance.com/2018/05/28/a-new-fast-hash-table-in-response-to-googles-new-fast-hash-table/
we can try to use them if this part gets crucial.
With this patch:
```
Processing tutorials/hsimple.C...
hsimple : Real Time = 0.04 seconds Cpu Time = 0.03 seconds
(TFile *) 0x562b37a14fe0
Processing /home/yuka/CERN/ROOT/memory.C...
cpu time = 0.362307 seconds
sys time = 0.039741 seconds
res memory = 278.215 Mbytes
vir memory = 448.973 Mbytes
```
W/o this patch:
```
Processing tutorials/hsimple.C...
hsimple : Real Time = 0.08 seconds Cpu Time = 0.07 seconds
(TFile *) 0x5563018a1d30
Processing /home/yuka/CERN/ROOT/memory.C...
cpu time = 1.524314 seconds
sys time = 0.157075 seconds
res memory = 546.867 Mbytes
vir memory = 895.184 Mbytes
```
So it improves time by 4x times and memory by 2x.
Add llvm module pass to generate unique cuda module ctor/dtor names.
This llvm module pass address the follow problem. Every llvm module has a cuda ctor and dtor (if a cuda fatbinary exist), with at least a function call to register the fatbinary. The ctor/dtor can also include function calls to register global functions and variables at runtime, depending on user's code. The lazy compilation detects functions by the name. If the name (symbol) already exists it uses the existing translation. Otherwise it translates the function on first use (but it never translates twice). Without the module pass, Cling will always use the translation of the first module.
The testcase use the reflection of the gCling interpreter object. It takes two random modules and compare the symbols of the cuda module ctor and dtor.
Also add function, which change the symbol of the cuda module ctor and dtor to preprocessor compliant symbols.
Preloading all the modules has several advantages. 1. We do not have to
rely on rootmap files which don't support some features (namespaces and
templates) 2. Lookup would be faster because we don't have to do
trampoline via rootmap files.
Autoloading libraries when decls are deserialized gives us correctness.
However we still need to optimize the performance by reducing the amount
of loaded libraries and improving Clang performance.
Unloading the enum forward decl has tragic consequences e.g. for template
specializations relying on that decl (as template type parameter): the
enum definition will not be associated with teh forward decl, and any
subsequent template specialization will not recognize the type identity
of the enum forward declaration and its definition.
Instead, silence the diagnostic. This is not nice, but will be fixed by
C++ modules.
Fix compilation errors with the latest version of Visual Studio (15.7.0)
- Prevent compilation error G47C585C4: STL1000: Unexpected compiler version, expected Clang 6 or newer
- Fix exported symbols
Late parsed templated are parsed from a token chain, as if expanding a macro. This confuses subsequent parses. Make sure that the token quere is emptied, which is exactly what ParseInternal() does after parsing.
In case of TProtoClass.cxx, all the loop was doing
is to copy the collection (loop body with comments
only - and those don't compile when removing the //.
Thus comment out the whole loop.
In TDFNodes.cxx remove the redundant get() as well.
To do so one needs to pass -Dbuiltin_llvm=Off -Dbuiltin_clang=Off and the
PATH should contain the path to llvm-config.
Note this is not enabling ROOT to work with vanilla clang!
This patch allows ROOT to be built against a prebuilt clang and llvm from
https://root.cern.ch/git/{llvm.git,clang.git}. It allows to reduce ROOT's
build times (in cases when cmake decides to rebuild the in-tree llvm for
no good reason). It moves the common denominator of different ROOT builds
in one place to save space. It also allows easy switch between LLVM in
debug and release mode.
To build the external clang and llvm exactly in the same way as the
in-tree builds use:
CMAKE_FLAGS="\
-DLLVM_ENABLE_WARNINGS=OFF \
-DLLVM_INCLUDE_TESTS=OFF \
-DCLANG_INCLUDE_TESTS=OFF \
-DLLVM_INCLUDE_EXAMPLES=OFF \
-DCLANG_BUILD_TOOLS=OFF \
-DCLANG_TOOL_ARCMT_TEST_BUILD=OFF \
-DCLANG_TOOL_CLANG_CHECK_BUILD=OFF \
-DCLANG_TOOL_CLANG_FORMAT_BUILD=OFF \
-DCLANG_TOOL_CLANG_FORMAT_VS_BUILD=OFF \
-DCLANG_TOOL_CLANG_FUZZER_BUILD=OFF \
-DCLANG_TOOL_CLANG_IMPORT_TEST_BUILD=OFF \
-DCLANG_TOOL_CLANG_OFFLOAD_BUNDLER_BUILD=OFF \
-DCLANG_TOOL_CLANG_RENAME_BUILD=OFF \
-DCLANG_TOOL_C_ARCMT_TEST_BUILD=OFF \
-DCLANG_TOOL_C_INDEX_TEST_BUILD=OFF \
-DCLANG_TOOL_DIAGTOOL_BUILD=OFF \
-DCLANG_TOOL_LIBCLANG_BUILD=OFF \
-DCLANG_TOOL_SCAN_BUILD_BUILD=OFF \
-DCLANG_TOOL_SCAN_VIEW_BUILD=OFF \
-DLLVM_BUILD_TOOLS=OFF \
-DLLVM_TOOL_LLVM_AR_BUILD=OFF \
-DCLANG_TOOL_CLANG_OFFLOAD_BUNDLER_BUILD=OFF \
-DLLVM_FORCE_USE_OLD_TOOLCHAIN=ON \
-DCLANG_ENABLE_STATIC_ANALYZER=OFF \
-DCLANG_ENABLE_ARCMT=OFF \
-DCLANG_ENABLE_FORMAT=OFF \
-DLLVM_TARGETS_TO_BUILD=host \
-DLLVM_ABI_BREAKING_CHECKS=FORCE_OFF \
-DLLVM_ENABLE_ABI_BREAKING_CHECKS=OFF \
-DCMAKE_INSTALL_PREFIX=.. \
-DCMAKE_BUILD_TYPE=Debug"
cmake "$CMAKE_FLAGS" ../../../sources/root-llvm/
set the AuxTarget, if the LangOpt CUDA is true and enable the compilation of cuda runtime code
needs a preload of the libcudart.so and the arguments -std=c++11 and --cuda-host-only at start of cling
Using unary operator address of (eg. MyClass m; &m) takes into account
overloaded operators which may not give us the precide address of the
allocated storage.
This patch teaches cling to use std::addressof instead.
in CIFactory:
- Add -fno-threadsafe-statics flag (for Windows only), to prevent potential unresolved symbols at run-time
in MetaProcessor::readInputFromFile:
- add required std::ifstream::binary flag when opening the std::ifstream
- add missing backslashes
in PlatformWin:
- properly format error messages
- in IsDLL(): check and return false if the file size is 0
- fix _CxxThrowException symbol name (not fully understood - to be reviewed)
- filter out a couple of system dlls when looking for symbols
We rely on clang's plugin infrastructure for loading, argument processing
and unloading plugins.
This patch teaches cling to work with clang plugins such as clad -- a
clang plugin implementing automatic differentiation facilities.
TClingClassInfo has a constructor that is supposed to be used for TU
scope lookups. However, it iterates over decls and causes lots of
deserializations. It does not respect the C++ lookup rules because it
returns the first decl with the name it finds.
This patch tries to keep the original behavior by first trying to do
a regular lookup and if the result is unambigious it returns the found
decl. If the result was ambiguous we try to disambiguate it (by turning
off the using directives) and return the found result.
The getSpecialization interface now deserializes lazily template
specializations. While unloading we trigger creation of new specializations
which does not make sense.
On Linux, the same adjustments are needed as for libstdc++ and libc++,
so turn the condition into just #ifdef __linux__. However, since the
__cxa_atexit function is declared as extern "C" in libc++, we cannot
add "noexcept" to it, as is done for libstdc++.
With the attribute after "enum" and before the name, the name itself gets annotated
and subsequent lookups fail to identify the front-end token.
By moving the attribute behind the decl, the identifier is unmodified.
This marks all files in the PCH/PCM transient. This allows clang to
stream them back within the zip in the PCH rather than requiring the
files to be physically present on disk.
This should resolve an introduced regression which materializes if
the files are moved/deleted after the generation of the PCH.
- Switch object format from ELF (Linux) to COFF (Windows)
- Fix mangled symbols lookup on Windows: remove leading '_' and use malloc to simulate __imp_ variables (that are indirection pointers)
We need to disable the validation of PCM files because rootcling
serializes what it sees. For instance, we even serialize in the PCM
file some temporary lookup buffers and the contents of the module maps.
We disable the PCH validation but that is not sufficient for PCM. The
TCling code `fInterpreter->getCI()->getPreprocessorOpts().DisablePCHValidation = true`
is not enough because we rely more on the clang driver to setup correctly
our modules-aware interpreter.
This patch just uses the correct flag when setting up cling.
A proper fix to this issue is thoroughly described in RE-0003 (rootcling
refactor proposal).
For now, do not decorate enums, this leads to some errors, likely
due to incorrect merging. See https://sft.its.cern.ch/jira/browse/ROOT-9114
Note: that passing the set of forward declare and then actual declaration
to clang (both official and ROOT's custom version), there is no problem
seen.
We need to respect the existing ExternalASTSource when setting up the
interpreter. Otherwise the ASTReader (which is the existing source)
doesn't receive the required callbacks to properly load C++ modules.
This patch now creates a multiplexer that contains our new
ASTSource and the existing one if it's necessary. We also
no longer attach the existing sema source which seemingly
was only a workaround that only works for the special case
were the external sema source and the external AST source
are the same object.
TLS is currently not suppored in the JIT on some platforms.
However, it's possible to enable emulated TLS support in LLVM
which means that we now support TLS across many architectures.
The performance downsides of this are the overhead of accessing
the variable due to the additional indirection by the emulation.
However, this overhead is minimal and shouldn't affect most
programs. It also can be easily worked around from the user side.
This can be donefFor example by wrapping TLS variables into a single
TLS struct variable that then contains the other variables. Or just
minimizing referencing the TLS variable and use a normal copy of
the variable instead and write it back later.
Patch created with a lot of help from Lang Hames and Pavel Labath!
The orc jit API evolved as follows:
* Use better error handling via llvm::Error and llvm::Expected<>
* Switch back to the single llvm::Module concept as opposed to sets.
* Use more expressive ownership model: extensive use of smart ptrs.
Initializing the module manager overwrites the external Sema/AST sources
with the ASTReader.
As we are using our own sources in cling, we should manually initalize
the module manager when we are in the module mode before we set our
own custom sources (which respect any existing sources like the ones
created by the module manager).
We should setup our callbacks for ExternalASTSource/ExternalSemaSource
before we parse *any* code to prevent that any part of the code
stores a reference to a non-cling external sources. If this happens,
then the clang data structures such redecl chain could go out of
sync if they reference different sources and produce errors like failing
to merge declarations correctly or creating invalid redecl chains.
To fix this, we move this initalization before the initalization of
the incremental parser which is the first part that can generate
any AST nodes. We only do this for the modules case because in
the non-modules case the clang PCH overwrites our callback
in the ExternalASTSource and therefore would destroy our external
source.
We actually need those callbacks as they are responsible for
loading decls from unresolved identifiers, which then actually
triggers the loading of the specific header (or in our case
the specific C++ modules).
For now we need this as long as the modules are based on the
rootmap mechanism.
Initializing the module manager overwrites the external Sema/AST sources
with the ASTReader.
As we are using our own sources in cling, we should manually initalize
the module manager when we are in the module mode before we set our
own custom sources (which respect any existing sources like the ones
created by the module manager).
We should setup our callbacks for ExternalASTSource/ExternalSemaSource
before we parse *any* code to prevent that any part of the code
stores a reference to a non-cling external sources. If this happens,
then the clang data structures such redecl chain could go out of
sync if they reference different sources and produce errors like failing
to merge declarations correctly or creating invalid redecl chains.
To fix this, we move this initalization before the initalization of
the incremental parser which is the first part that can generate
any AST nodes.
Right now we always start generating a module in the CIFactory
when modules are enabled. However, we should only do that when
we actually want to generate a module according to the COpts
(e.g. the user has given a module that we should generate).
When generating the GQt module in rootcling, we hit the assertions
in forceAppend assertions about "Duplicates?!" with this declaration:
```
CXXRecordDecl 0x55555643fae8 </usr/include/qt4/QtCore/qglobal.h:1658:1, line:1794:1> line:1658:21 in GQt.TGQt.h hidden class QSysInfo definition
|-also in GQt.TQtClientWidget.h
|-CXXRecordDecl 0x55555643fc30 <col:1, col:21> col:21 in GQt.TGQt.h hidden implicit class QSysInfo
|-AccessSpecDecl 0x55555643fce8 <line:1659:1, col:7> col:1 in GQt.TGQt.h public
|-EnumDecl 0x55555643fd18 <line:1660:5, line:1662:5> line:1660:10 in GQt.TGQt.h hidden Sizes
| `-EnumConstantDecl 0x55555643fe98 <line:1661:9, col:38> col:9 in GQt.TGQt.h hidden WordSize 'enum QSysInfo::Sizes'
| `-ImplicitCastExpr 0x55555643fee0 <col:20, col:38> 'unsigned int' <IntegralCast>
| `-ParenExpr 0x55555643fe70 <col:20, col:38> 'unsigned long'
| `-BinaryOperator 0x55555643fe48 <col:21, col:37> 'unsigned long' '<<'
| |-UnaryExprOrTypeTraitExpr 0x55555643fe08 <col:21, col:34> 'unsigned long' sizeof 'void *'
| `-IntegerLiteral 0x55555643fe28 <col:37> 'int' 3
`-EnumDecl 0x55555643ff00 <line:1672:5, line:1685:5> line:1672:10 in GQt.TGQt.h hidden Endian
|-EnumConstantDecl 0x55555643ffd8 <line:1673:9> col:9 in GQt.TGQt.h hidden referenced BigEndian 'enum QSysInfo::Endian'
|-EnumConstantDecl 0x555556440028 <line:1674:9> col:9 in GQt.TGQt.h hidden referenced LittleEndian 'enum QSysInfo::Endian'
`-EnumConstantDecl 0x5555564400a0 <line:1681:11, col:23> col:11 in GQt.TGQt.h hidden ByteOrder 'enum QSysInfo::Endian'
`-ImplicitCastExpr 0x5555564400e8 <col:23> 'unsigned int' <IntegralCast>
`-DeclRefExpr 0x555556440070 <col:23> 'int' EnumConstant 0x555556440028 'LittleEndian' 'enum QSysInfo::Endian'
```
The reason for this is that we have QSysInfo both in the TQtClientWidget
and TGQt submodules and our current translation (which is supposed to
parse all header in the module) sees them both in one transaction.
As we also don't recognize that this decl is from a module, the code
fires the assert even though duplictes are expected with modules.
The reason why we don't recognize it as a declaration form an ASTFile
which disables the assert is that FromASTFile for the decls is
not set. This is because they haven't been loaded by the ASTFileReader
but are directly parsed as submodules in our special case where we
directly parse a module content from rootcling to generate it.
We just workaround in this patch by checking that if the decl is from
the currently generated module, we are pretending it's as if it was
loaded from an AST file.
This reverts commit 79ed4963868c758757c25b7d93ef98fac0e34774.
The commit tried to bring back the optimisation level to O0 but 2 tests fail
if this is done:
- roottest-cling-specialobj-reread
- roottest-root-io-datamodelevolution-make
Revert https://github.com/root-project/root/commit/548eca7 bringing back
optimisation level to O0 given the very long time needed to JIT simple
pieces of code.
This takes tens of seconds versus a few seconds:
using namespace ROOT::Experimental;
int test() {
// build a TDF with 1 event and 1 column "x" that is always equal 42
TDataFrame dd(1);
auto d = dd.Define("x", []() { return 42; });
// book nHistos histograms
// all with the same cut and filled with the same variable in this simple example
std::vector<TDF::TResultProxy<TH1D>> histos;
const auto nHistos = 1000u;
histos.reserve(nHistos);
for (auto i = 0u; i < nHistos; ++i)
histos.emplace_back(d.Histo1D("x"));
// run event loop, print something to be sure everything is ok
std::cout << histos.front()->GetMean() << std::endl;
return 0;
}
This teaches again the IncrementalExecutor to emit only one module at a time.
In the old MCJIT days, the API worked with module sets and cling assumed llvm's
jit infrastructure is moving in this direction.
LLVM 5.0 moves away from this concept and works with single llvm::Modules. This
patch will make the upgrade to LLVM 5.0 smoother.
The Visual Studio 2017 path is very different than the previous versions, and even the registry entries are completely different, so for now let's try the trivial way first (using the %VCToolsInstallDir% environment variable)
This is in prepare for the upcoming llvm upgrade. The future orc jit compile
layer needs a std::shared_ptr<llvm::Module>. The current design passes a
llvm::Module* around and any conversions to a shared_ptr cause the
destruction of the llvm::Module which is a long-lived object in cling.
With C++ modules we fail here because we get this extra 'include '
text before the actual header. As the header itself is correct
it seems, we just skip this extra text with modules enabled as
this code is anyway supposed to be replaced with modules
functionality.
We will probably see an increasing amount of these failures with
C++ modules as we now deserialize all declarations instead of just
the PCH ones. To safe us a lot of debugging time on where to push
the needed transaction, let's directly print the stack trace here
in the rare case that we crash here.
With the module generation in rootcling Clang rlies on AST consumers
to do the module generation work for it. Right now this doesn't work
however with the interpreter, as we just overwrite the deserialization
listener that clang added which will cause strange errors during
the module generation (the most prompinent error is that the number
of recorded submodules will be incorrect, as this it the first thing
that Clang checks before writing a module and which is recorded by
an ASTDeserializationListener).
This patch just adds a multiplexer here that allows us to keep the
old listener while also adding the one we have.
This patch adds support for writing out modules to the CIFactory.
If the user has passed -fmodule-name and -fmodules, we start
extending the CI instance with support for C++ modules and also
optionally setup AST consumers for writing out modules files
alongside the interpreter.
Without throwing cling cannot communicate to the caller that the code has failed,
as the user code is currently running when failing the dynamic expression evaluation.
Fixes gROOT->ProcessLine("doesNotExist", &res) not signalling any error through res.
Well, it still does not set res to an error - but at least it now throws.
Fixes an issue for ATLAS, where Property<string>::Property<string&> cannot be instantiated by ROOT.
ROOT is trying to do that because the function is templated, with all template parameters having defaults.
(This "let us instantiate if all template params have defaults" is needed e.g. to see pair::pair() which is sfinae protected.)
This is a preparation because we want to ship module configuration
files in the future in the cling resource directory (Clang VFS overlay
files and modulemaps). This means that we will need to know this path
in a few other places (e.g. where we specify the -ivfsoverlayPATH
arguments and potential -fmodule-map-file=PATH args)
It also makes this giant function a bit easier on the eyes.