diff --git a/interpreter/cling/include/cling/Interpreter/Interpreter.h b/interpreter/cling/include/cling/Interpreter/Interpreter.h index 2ffed6a844bcf9a2964bcbdefa8fa7b1439d7bc2..2ee10064c882816a0584d07e7206c449f6ba0123 100644 --- a/interpreter/cling/include/cling/Interpreter/Interpreter.h +++ b/interpreter/cling/include/cling/Interpreter/Interpreter.h @@ -38,6 +38,7 @@ namespace clang { class DiagnosticsEngine; class FunctionDecl; class GlobalDecl; + class MacroInfo; class NamedDecl; class Parser; class Preprocessor; @@ -714,6 +715,14 @@ namespace cling { /// void* getAddressOfGlobal(llvm::StringRef SymName, bool* fromJIT = 0) const; + ///\brief Get a given macro definition by name. + /// + ///\param[in] Name - the name of the macro to look for + /// + ///\returns the MacroInfo if the macro was defined, otherwise null + /// + const clang::MacroInfo* getMacro(llvm::StringRef Name) const; + ///\brief Add an atexit function. /// ///\param[in] Func - Function to be called. diff --git a/interpreter/cling/lib/Interpreter/IncrementalParser.cpp b/interpreter/cling/lib/Interpreter/IncrementalParser.cpp index 60c7d16f8693e5ecc1cb8389655b24b6a6ddb15c..77cd691a65055c0da9afa01a81fc15c0bda66318 100644 --- a/interpreter/cling/lib/Interpreter/IncrementalParser.cpp +++ b/interpreter/cling/lib/Interpreter/IncrementalParser.cpp @@ -57,22 +57,9 @@ using namespace clang; namespace { - static const Token* getMacroToken(const Preprocessor& PP, const char* Macro) { - if (const IdentifierInfo* II = PP.getIdentifierInfo(Macro)) { - if (const DefMacroDirective* MD = llvm::dyn_cast_or_null - <DefMacroDirective>(PP.getLocalMacroDirective(II))) { - if (const clang::MacroInfo* MI = MD->getMacroInfo()) { - if (MI->getNumTokens() == 1) - return MI->tokens_begin(); - } - } - } - return nullptr; - } - ///\brief Check the compile-time C++ ABI version vs the run-time ABI version, /// a mismatch could cause havoc. Reports if ABI versions differ. - static bool CheckABICompatibility(clang::CompilerInstance* CI) { + static bool CheckABICompatibility(cling::Interpreter& Interp) { #if defined(__GLIBCXX__) #define CLING_CXXABI_VERS std::to_string(__GLIBCXX__) const char* CLING_CXXABI_NAME = "__GLIBCXX__"; @@ -87,16 +74,18 @@ namespace { #endif llvm::StringRef CurABI; - const clang::Preprocessor& PP = CI->getPreprocessor(); - const clang::Token* Tok = getMacroToken(PP, CLING_CXXABI_NAME); - if (Tok && Tok->isLiteral()) { - // Tok::getLiteralData can fail even if Tok::isLiteral is true! - SmallString<64> Buffer; - CurABI = PP.getSpelling(*Tok, Buffer); - // Strip any quotation marks. - CurABI = CurABI.trim("\""); - if (CurABI.equals(CLING_CXXABI_VERS)) - return true; + if (const clang::MacroInfo* MI = Interp.getMacro(CLING_CXXABI_NAME)) { + const clang::Token* Tok = MI->getNumTokens() == 1 ? + MI->tokens_begin() : nullptr; + if (Tok && Tok->isLiteral()) { + // Tok::getLiteralData can fail even if Tok::isLiteral is true! + SmallString<64> Buffer; + CurABI = Interp.getCI()->getPreprocessor().getSpelling(*Tok, Buffer); + // Strip any quotation marks. + CurABI = CurABI.trim("\""); + if (CurABI.equals(CLING_CXXABI_VERS)) + return true; + } } cling::errs() << @@ -284,7 +273,7 @@ namespace cling { // library implementation. ParseInternal("#include <new>"); // That's really C++ ABI compatibility. C has other problems ;-) - CheckABICompatibility(m_CI.get()); + CheckABICompatibility(*m_Interpreter); } // DO NOT commit the transactions here: static initialization in these diff --git a/interpreter/cling/lib/Interpreter/Interpreter.cpp b/interpreter/cling/lib/Interpreter/Interpreter.cpp index 6c2dfb145a34d6b936e04d6a1358a4075d4338a0..70d55dc9e6172631defa5f985b11d54967542c70 100644 --- a/interpreter/cling/lib/Interpreter/Interpreter.cpp +++ b/interpreter/cling/lib/Interpreter/Interpreter.cpp @@ -549,6 +549,17 @@ namespace cling { return getCI()->getDiagnostics(); } + const MacroInfo* Interpreter::getMacro(llvm::StringRef Macro) const { + const clang::Preprocessor& PP = getCI()->getPreprocessor(); + if (const IdentifierInfo* II = PP.getIdentifierInfo(Macro)) { + if (const DefMacroDirective* MD = llvm::dyn_cast_or_null + <DefMacroDirective>(PP.getLocalMacroDirective(II))) { + return MD->getMacroInfo(); + } + } + return nullptr; + } + ///\brief Maybe transform the input line to implement cint command line /// semantics (declarations are global) and compile to produce a module. ///