Add Interpreter::getMacro method.

This commit is contained in:
Frederich Munch 2017-02-22 15:35:36 -05:00 committed by sftnight
parent 5229194db4
commit 9b3084f955
3 changed files with 34 additions and 25 deletions

View File

@ -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.

View File

@ -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

View File

@ -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.
///