5454#include " llvm/Support/CommandLine.h"
5555#include " llvm/Support/Debug.h"
5656#include " llvm/Support/Error.h"
57+ #include " llvm/Support/ErrorHandling.h"
5758#include " llvm/Support/ManagedStatic.h"
5859#include " llvm/Support/Path.h"
5960#include " llvm/Support/raw_ostream.h"
@@ -138,16 +139,16 @@ struct InterpreterInfo {
138139 InterpreterInfo& operator =(const InterpreterInfo&) = delete ;
139140};
140141
141- // NOLINTBEGIN
142+ // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
142143// std::deque avoids relocations and calling the dtor of InterpreterInfo.
143- static llvm::ManagedStatic<std::deque<std::shared_ptr <InterpreterInfo>>>
144+ static llvm::ManagedStatic<std::deque<std::unique_ptr <InterpreterInfo>>>
144145 sInterpreters ;
145146static llvm::ManagedStatic<
146- std::unordered_map<clang::ASTContext*, std::weak_ptr< InterpreterInfo> >>
147+ std::unordered_map<clang::ASTContext*, InterpreterInfo* >>
147148 sInterpreterASTMap ;
148149static std::recursive_mutex InterpreterStackLock;
149150static std::recursive_mutex LLVMLock;
150- // NOLINTEND
151+ // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
151152
152153static InterpreterInfo& getInterpInfo () {
153154 std::lock_guard<std::recursive_mutex> Lock (InterpreterStackLock);
@@ -161,17 +162,20 @@ static InterpreterInfo& getInterpInfo(const clang::Decl* D) {
161162 return getInterpInfo ();
162163 if (sInterpreters ->size () == 1 )
163164 return *sInterpreters ->back ();
164- return *(*sInterpreterASTMap )[&D->getASTContext ()]. lock () ;
165+ return *(*sInterpreterASTMap )[&D->getASTContext ()];
165166}
166167static InterpreterInfo& getInterpInfo (const void * D) {
167168 std::lock_guard<std::recursive_mutex> Lock (InterpreterStackLock);
169+ QualType QT = QualType::getFromOpaquePtr (D);
170+ if (auto * D = QT->getAsTagDecl ())
171+ return getInterpInfo (D);
168172 if (!D)
169173 return getInterpInfo ();
170174 if (sInterpreters ->size () == 1 )
171175 return *sInterpreters ->back ();
172176 for (auto & item : *sInterpreterASTMap ) {
173177 if (item.first ->getAllocator ().identifyObject (D))
174- return *item.second . lock () ;
178+ return *item.second ;
175179 }
176180 llvm_unreachable (
177181 " This pointer does not belong to any interpreter instance.\n " );
@@ -189,7 +193,7 @@ static compat::Interpreter& getInterp(const clang::Decl* D) {
189193 return getInterp ();
190194 if (sInterpreters ->size () == 1 )
191195 return *sInterpreters ->back ()->Interpreter ;
192- return *(*sInterpreterASTMap )[&D->getASTContext ()]. lock () ->Interpreter ;
196+ return *(*sInterpreterASTMap )[&D->getASTContext ()]->Interpreter ;
193197}
194198static compat::Interpreter& getInterp (const void * D) {
195199 return *getInterpInfo (D).Interpreter ;
@@ -3338,6 +3342,8 @@ static std::string MakeResourcesPath() {
33383342TInterp_t CreateInterpreter (const std::vector<const char *>& Args /* ={}*/ ,
33393343 const std::vector<const char *>& GpuArgs /* ={}*/ ) {
33403344 std::lock_guard<std::recursive_mutex> Lock (InterpreterStackLock);
3345+ assert (sInterpreters ->size () == sInterpreterASTMap ->size ());
3346+
33413347 std::string MainExecutableName = sys::fs::getMainExecutable (nullptr , nullptr );
33423348 std::string ResourceDir = MakeResourcesPath ();
33433349 std::vector<const char *> ClingArgv = {" -resource-dir" , ResourceDir.c_str (),
@@ -3414,42 +3420,73 @@ TInterp_t CreateInterpreter(const std::vector<const char*>& Args /*={}*/,
34143420 )" );
34153421
34163422 sInterpreters ->emplace_back (
3417- std::make_shared <InterpreterInfo>(I, /* Owned=*/ true ));
3423+ std::make_unique <InterpreterInfo>(I, /* Owned=*/ true ));
34183424 sInterpreterASTMap ->insert (
34193425 {&sInterpreters ->back ()->Interpreter ->getSema ().getASTContext (),
3420- sInterpreters ->back ()});
3426+ sInterpreters ->back (). get () });
34213427
3428+ assert (sInterpreters ->size () == sInterpreterASTMap ->size ());
34223429 return I;
34233430}
34243431
3432+ static inline auto find_interpreter_in_stack (TInterp_t I) {
3433+ return std::find_if (
3434+ sInterpreters ->begin (), sInterpreters ->end (),
3435+ [&I](const auto & Info) { return Info->Interpreter == I; });
3436+ }
3437+
3438+ static inline auto find_interpreter_in_map (InterpreterInfo* I) {
3439+ return std::find_if (sInterpreterASTMap ->begin (), sInterpreterASTMap ->end (),
3440+ [&](const auto & Item) { return Item.second == I; });
3441+ }
3442+
34253443bool DeleteInterpreter (TInterp_t I /* =nullptr*/ ) {
34263444 std::lock_guard<std::recursive_mutex> Lock (InterpreterStackLock);
3445+ assert (sInterpreters ->size () == sInterpreterASTMap ->size ());
34273446
34283447 if (!I) {
3429- auto foundAST =
3430- std::find_if (sInterpreterASTMap ->begin (), sInterpreterASTMap ->end (),
3431- [](const auto & Item) {
3432- return Item.second .lock () == sInterpreters ->back ();
3433- });
3448+ auto foundAST = find_interpreter_in_map (sInterpreters ->back ().get ());
3449+ assert (foundAST != sInterpreterASTMap ->end ());
34343450 sInterpreterASTMap ->erase (foundAST);
34353451 sInterpreters ->pop_back ();
34363452 return true ;
34373453 }
34383454
3439- auto found =
3440- std::find_if (sInterpreters ->begin (), sInterpreters ->end (),
3441- [&I](const auto & Info) { return Info->Interpreter == I; });
3455+ auto found = find_interpreter_in_stack (I);
34423456 if (found == sInterpreters ->end ())
34433457 return false ; // failure
34443458
3445- auto foundAST = std::find_if (
3446- sInterpreterASTMap ->begin (), sInterpreterASTMap ->end (),
3447- [&found](const auto & Item) { return Item.second .lock () == *found; });
3459+ auto foundAST = find_interpreter_in_map ((*found).get ());
3460+ assert (foundAST != sInterpreterASTMap ->end ());
34483461 sInterpreterASTMap ->erase (foundAST);
34493462 sInterpreters ->erase (found);
34503463 return true ;
34513464}
34523465
3466+ TInterp_t TakeInterpreter (TInterp_t I /* =nullptr*/ ) {
3467+ std::lock_guard<std::recursive_mutex> Lock (InterpreterStackLock);
3468+ assert (sInterpreters ->size () == sInterpreterASTMap ->size ());
3469+
3470+ if (!I) {
3471+ auto foundAST = find_interpreter_in_map (sInterpreters ->back ().get ());
3472+ sInterpreterASTMap ->erase (foundAST);
3473+ InterpreterInfo* res = sInterpreters ->back ().release ();
3474+ sInterpreters ->pop_back ();
3475+ return res->Interpreter ;
3476+ }
3477+
3478+ auto found = find_interpreter_in_stack (I);
3479+ if (found == sInterpreters ->end ())
3480+ return nullptr ; // failure
3481+
3482+ auto foundAST = find_interpreter_in_map ((*found).get ());
3483+ sInterpreterASTMap ->erase (foundAST);
3484+ InterpreterInfo* res = (*found).release ();
3485+ sInterpreters ->erase (found);
3486+ assert (sInterpreters ->size () == sInterpreterASTMap ->size ());
3487+ return res->Interpreter ;
3488+ }
3489+
34533490bool ActivateInterpreter (TInterp_t I) {
34543491 std::lock_guard<std::recursive_mutex> Lock (InterpreterStackLock);
34553492
@@ -3477,10 +3514,13 @@ TInterp_t GetInterpreter() {
34773514
34783515void UseExternalInterpreter (TInterp_t I) {
34793516 std::lock_guard<std::recursive_mutex> Lock (InterpreterStackLock);
3480- assert (sInterpreters ->empty () && " sInterpreter already in use!" );
34813517 sInterpreters ->emplace_back (
3482- std::make_shared <InterpreterInfo>(static_cast <compat::Interpreter*>(I),
3518+ std::make_unique <InterpreterInfo>(static_cast <compat::Interpreter*>(I),
34833519 /* isOwned=*/ false ));
3520+ sInterpreterASTMap ->insert (
3521+ {&sInterpreters ->back ()->Interpreter ->getSema ().getASTContext (),
3522+ sInterpreters ->back ().get ()});
3523+ assert (sInterpreters ->size () == sInterpreterASTMap ->size ());
34843524}
34853525
34863526void AddSearchPath (const char * dir, bool isUser, bool prepend) {
@@ -3734,9 +3774,9 @@ std::string ObjToString(const char* type, void* obj) {
37343774 return getInterp ().toString (type, obj);
37353775}
37363776
3737- Decl* InstantiateTemplate (TemplateDecl* TemplateD,
3738- TemplateArgumentListInfo& TLI, Sema& S,
3739- bool instantiate_body) {
3777+ static Decl* InstantiateTemplate (TemplateDecl* TemplateD,
3778+ TemplateArgumentListInfo& TLI, Sema& S,
3779+ bool instantiate_body) {
37403780 LOCK (getInterpInfo ());
37413781 // This is not right but we don't have a lot of options to choose from as a
37423782 // template instantiation requires a valid source location.
0 commit comments