//------------------------------------------------------------------------------ // CLING - the C++ LLVM-based InterpreterG :) // version: $Id$ // author: Vassil Vassilev //------------------------------------------------------------------------------ #include "DynamicLookup.h" #include "ASTUtils.h" #include "cling/Interpreter/Interpreter.h" #include "cling/Interpreter/InterpreterCallbacks.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Scope.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Template.h" using namespace clang; namespace cling { // Constructor DynamicIDHandler::DynamicIDHandler(Sema* Sema) : Callbacks(0), m_Sema(Sema), m_Context(Sema->getASTContext()) {} // pin the vtable to this file DynamicIDHandler::~DynamicIDHandler(){ delete Callbacks; Callbacks = 0; } bool DynamicIDHandler::LookupUnqualified(LookupResult& R, Scope* S) { if (!IsDynamicLookup(R, S)) return false; if (Callbacks && Callbacks->isEnabled()) { return Callbacks->LookupObject(R, S); } DeclarationName Name = R.getLookupName(); IdentifierInfo* II = Name.getAsIdentifierInfo(); SourceLocation Loc = R.getNameLoc(); VarDecl* Result = VarDecl::Create(m_Context, R.getSema().getFunctionLevelDeclContext(), Loc, Loc, II, m_Context.DependentTy, /*TypeSourceInfo*/0, SC_None, SC_None); if (Result) { R.addDecl(Result); // Say that we can handle the situation. Clang should try to recover return true; } // We cannot handle the situation. Give up return false; } bool DynamicIDHandler::IsDynamicLookup (LookupResult& R, Scope* S) { if (R.getLookupKind() != Sema::LookupOrdinaryName) return false; if (R.isForRedeclaration()) return false; // FIXME: Figure out better way to handle: // C++ [basic.lookup.classref]p1: // In a class member access expression (5.2.5), if the . or -> token is // immediately followed by an identifier followed by a <, the // identifier must be looked up to determine whether the < is the // beginning of a template argument list (14.2) or a less-than operator. // The identifier is first looked up in the class of the object // expression. If the identifier is not found, it is then looked up in // the context of the entire postfix-expression and shall name a class // or function template. // // We want to ignore object(.|->)member