|
71 | 71 | #include <unistd.h>
|
72 | 72 | #endif // WIN32
|
73 | 73 |
|
74 |
| -#include <stack> |
75 |
| - |
76 | 74 | namespace Cpp {
|
77 | 75 |
|
78 | 76 | using namespace clang;
|
79 | 77 | using namespace llvm;
|
80 | 78 | using namespace std;
|
81 | 79 |
|
82 |
| -// Flag to indicate ownership when an external interpreter instance is used. |
83 |
| -static bool OwningSInterpreter = true; |
84 |
| -static compat::Interpreter* sInterpreter = nullptr; |
85 |
| -// Valgrind complains about __cxa_pure_virtual called when deleting |
86 |
| -// llvm::SectionMemoryManager::~SectionMemoryManager as part of the dtor chain |
87 |
| -// of the Interpreter. |
88 |
| -// This might fix the issue https://reviews.llvm.org/D107087 |
89 |
| -// FIXME: For now we just leak the Interpreter. |
90 |
| -struct InterpDeleter { |
91 |
| - ~InterpDeleter() = default; |
92 |
| -} Deleter; |
| 80 | +struct InterpreterInfo { |
| 81 | + compat::Interpreter* Interpreter = nullptr; |
| 82 | + bool isOwned = true; |
| 83 | + |
| 84 | + // Valgrind complains about __cxa_pure_virtual called when deleting |
| 85 | + // llvm::SectionMemoryManager::~SectionMemoryManager as part of the dtor |
| 86 | + // chain of the Interpreter. |
| 87 | + // This might fix the issue https://reviews.llvm.org/D107087 |
| 88 | + // FIXME: For now we just leak the Interpreter. |
| 89 | + ~InterpreterInfo() {} |
| 90 | +}; |
| 91 | +static llvm::SmallVector<InterpreterInfo, 8> sInterpreters; |
93 | 92 |
|
94 | 93 | static compat::Interpreter& getInterp() {
|
95 |
| - assert(sInterpreter && |
| 94 | + assert(!sInterpreters.empty() && |
96 | 95 | "Interpreter instance must be set before calling this!");
|
97 |
| - return *sInterpreter; |
| 96 | + return *sInterpreters.back().Interpreter; |
98 | 97 | }
|
99 | 98 | static clang::Sema& getSema() { return getInterp().getCI()->getSema(); }
|
100 | 99 | static clang::ASTContext& getASTContext() { return getSema().getASTContext(); }
|
@@ -2922,17 +2921,50 @@ TInterp_t CreateInterpreter(const std::vector<const char*>& Args /*={}*/,
|
2922 | 2921 | }
|
2923 | 2922 | // FIXME: Enable this assert once we figure out how to fix the multiple
|
2924 | 2923 | // calls to CreateInterpreter.
|
2925 |
| - // assert(!sInterpreter && "Interpreter already set."); |
2926 |
| - sInterpreter = I; |
| 2924 | + // assert(sInterpreters.empty() && "Interpreter already set."); |
| 2925 | + sInterpreters.push_back({I, /*isOwned=*/true}); |
| 2926 | + |
2927 | 2927 | return I;
|
2928 | 2928 | }
|
2929 | 2929 |
|
2930 |
| -TInterp_t GetInterpreter() { return sInterpreter; } |
| 2930 | +bool DeleteInterpreter(TInterp_t I /*=nullptr*/) { |
| 2931 | + if (!I) { |
| 2932 | + sInterpreters.pop_back(); |
| 2933 | + return true; |
| 2934 | + } |
| 2935 | + |
| 2936 | + auto found = |
| 2937 | + std::find_if(sInterpreters.begin(), sInterpreters.end(), |
| 2938 | + [&I](const auto& Info) { return Info.Interpreter == I; }); |
| 2939 | + if (found == sInterpreters.end()) |
| 2940 | + return false; // failure |
| 2941 | + |
| 2942 | + sInterpreters.erase(found); |
| 2943 | + return true; |
| 2944 | +} |
| 2945 | + |
| 2946 | +bool ActivateInterpreter(TInterp_t I) { |
| 2947 | + if (!I) |
| 2948 | + return false; |
| 2949 | + |
| 2950 | + auto found = |
| 2951 | + std::find_if(sInterpreters.begin(), sInterpreters.end(), |
| 2952 | + [&I](const auto& Info) { return Info.Interpreter == I; }); |
| 2953 | + if (found == sInterpreters.end()) |
| 2954 | + return false; |
| 2955 | + |
| 2956 | + if (std::next(found) != sInterpreters.end()) // if not already last element. |
| 2957 | + std::rotate(found, found + 1, sInterpreters.end()); |
| 2958 | + |
| 2959 | + return true; // success |
| 2960 | +} |
| 2961 | + |
| 2962 | +TInterp_t GetInterpreter() { return sInterpreters.back().Interpreter; } |
2931 | 2963 |
|
2932 | 2964 | void UseExternalInterpreter(TInterp_t I) {
|
2933 |
| - assert(!sInterpreter && "sInterpreter already in use!"); |
2934 |
| - sInterpreter = static_cast<compat::Interpreter*>(I); |
2935 |
| - OwningSInterpreter = false; |
| 2965 | + assert(sInterpreters.empty() && "sInterpreter already in use!"); |
| 2966 | + sInterpreters.push_back( |
| 2967 | + {static_cast<compat::Interpreter*>(I), /*isOwned=*/false}); |
2936 | 2968 | }
|
2937 | 2969 |
|
2938 | 2970 | void AddSearchPath(const char* dir, bool isUser, bool prepend) {
|
|
0 commit comments