Re-apply r45839; got lost during move of cling
git-svn-id: http://root.cern.ch/svn/root/trunk@45870 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
@ -1,73 +0,0 @@
|
||||
//--------------------------------------------------------------------*- C++ -*-
|
||||
// CLING - the C++ LLVM-based InterpreterG :)
|
||||
// version: $Id$
|
||||
// author: Axel Naumann <axel@cern.ch>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef CLING_CALLABLE_H
|
||||
#define CLING_CALLABLE_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class ExecutionEngine;
|
||||
class Function;
|
||||
struct GenericValue;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
class FunctionDecl;
|
||||
}
|
||||
|
||||
namespace cling {
|
||||
class Interpreter;
|
||||
class Value;
|
||||
|
||||
///\brief A representation of a function.
|
||||
//
|
||||
/// A callable combines a clang::FunctionDecl for AST-based reflection
|
||||
/// with the llvm::Function to call the function. It uses the
|
||||
/// interpreter's ExecutionContext to place the call passing in the
|
||||
/// normalized arguments. As no lookup is performed after constructing
|
||||
/// a Callable, calls are very efficient.
|
||||
class Callable {
|
||||
protected:
|
||||
/// \brief declaration; can also be a clang::CXXMethodDecl
|
||||
const clang::FunctionDecl* decl;
|
||||
/// \brief llvm::ExecutionEngine's function representation
|
||||
llvm::Function* func;
|
||||
/// \brief Interpreter that will run the function
|
||||
llvm::ExecutionEngine* exec;
|
||||
|
||||
public:
|
||||
/// \brief Default constructor, creates a Callable that IsInvalid().
|
||||
Callable(): decl(0), func(0) {}
|
||||
/// \brief Construct a valid Value.
|
||||
Callable(const clang::FunctionDecl& Decl,
|
||||
const cling::Interpreter& Interp);
|
||||
|
||||
/// \brief Determine whether the Callable can be invoked.
|
||||
//
|
||||
/// Determine whether the Callable can be invoked. Checking
|
||||
/// whether the llvm::Function pointer is valid.
|
||||
bool isValid() const { return func; }
|
||||
|
||||
/// \brief Get the declaration of the function.
|
||||
//
|
||||
/// Retrieve the Callable's function declaration.
|
||||
const clang::FunctionDecl* getDecl() const { return decl; }
|
||||
|
||||
/// \brief Invoke a function passing arguments, possibly getting result.
|
||||
//
|
||||
/// Invoke the function. Pass in the parameters ArgValues; the return
|
||||
/// value of the function call ends up in Result.
|
||||
/// If the function represents a CXXMethodDecl, the first argument is
|
||||
/// expected to be the this pointer of the object to un the function on.
|
||||
/// \return true if the call was successful.
|
||||
bool Invoke(const std::vector<llvm::GenericValue>& ArgValues,
|
||||
Value* Result = 0) const;
|
||||
};
|
||||
|
||||
} // end namespace cling
|
||||
|
||||
#endif // CLING_CALLABLE_H
|
@ -22,7 +22,6 @@ set( LLVM_LINK_COMPONENTS
|
||||
add_cling_library(clingInterpreter
|
||||
ASTDumper.cpp
|
||||
ASTNodeEraser.cpp
|
||||
Callable.cpp
|
||||
CIFactory.cpp
|
||||
DeclCollector.cpp
|
||||
DeclExtractor.cpp
|
||||
|
@ -1,50 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// CLING - the C++ LLVM-based InterpreterG :)
|
||||
// version: $Id: Interpreter.cpp 44226 2012-05-11 16:41:08Z vvassilev $
|
||||
// author: Axel Naumann <axel@cern.ch>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "cling/Interpreter/Callable.h"
|
||||
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
|
||||
#include "cling/Interpreter/Interpreter.h"
|
||||
#include "cling/Interpreter/Value.h"
|
||||
|
||||
cling::Callable::Callable(const clang::FunctionDecl& Decl,
|
||||
const cling::Interpreter& Interp):
|
||||
decl(&Decl),
|
||||
func(0),
|
||||
exec(Interp.getExecutionEngine())
|
||||
{
|
||||
if (exec) {
|
||||
std::string mangledName;
|
||||
llvm::raw_string_ostream RawStr(mangledName);
|
||||
llvm::OwningPtr<clang::MangleContext>
|
||||
Mangle(Interp.getCI()->getASTContext().createMangleContext());
|
||||
Mangle->mangleName(decl, RawStr);
|
||||
RawStr.flush();
|
||||
func = exec->FindFunctionNamed(mangledName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool cling::Callable::Invoke(const std::vector<llvm::GenericValue>& ArgValues,
|
||||
Value* Result /*= 0*/) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
if (Result) {
|
||||
*Result = Value(exec->runFunction(func, ArgValues),
|
||||
decl->getCallResultType());
|
||||
} else {
|
||||
exec->runFunction(func, ArgValues);
|
||||
}
|
||||
return true;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
// RUN: cat %s | %cling | FileCheck %s
|
||||
#include "cling/Interpreter/Interpreter.h"
|
||||
#include "cling/Interpreter/LookupHelper.h"
|
||||
#include "cling/Interpreter/Value.h"
|
||||
#include "cling/Interpreter/Callable.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
|
||||
.rawInput
|
||||
extern "C" int printf(const char*,...);
|
||||
void Bogus(int i) { printf("Bogus got a %d!\n", i);}
|
||||
class Smart {
|
||||
public:
|
||||
Smart(): I(42) {}
|
||||
int Inline() { printf("Inline!\n"); return I + 1; }
|
||||
int TheAnswer() const;
|
||||
int I;
|
||||
};
|
||||
int Smart::TheAnswer() const{ printf("TheAnswer!\n"); return I; }
|
||||
.rawInput
|
||||
|
||||
const clang::Decl* TU = gCling->getCI()->getASTContext().getTranslationUnitDecl();
|
||||
const cling::LookupHelper& lookup = gCling->getLookupHelper();
|
||||
|
||||
const clang::FunctionDecl* FBogus = lookup.findFunctionProto(TU, "Bogus", "int");
|
||||
assert(FBogus && "Bogus() not found");
|
||||
cling::Callable CBogus(*FBogus, *gCling);
|
||||
std::vector<llvm::GenericValue> ArgVs;
|
||||
ArgVs.push_back(llvm::GenericValue());
|
||||
ArgVs[0].IntVal = llvm::APInt(sizeof(int)*8, 12);
|
||||
CBogus.Invoke(ArgVs); // CHECK: Bogus got a 12!
|
||||
cling::Value V;
|
||||
++ArgVs[0].IntVal;
|
||||
CBogus.Invoke(ArgVs, &V); // CHECK: Bogus got a 13!
|
||||
V // CHECK: (cling::Value) boxes [(void) ]
|
||||
|
||||
const clang::Decl* DSmart = lookup.findScope("Smart");
|
||||
assert(DSmart && "Smart not found");
|
||||
const clang::FunctionDecl* FAnswer = lookup.findFunctionProto(DSmart, "TheAnswer", "");
|
||||
assert(FAnswer && "Smart::TheAnswer() not found");
|
||||
cling::Callable CAnswer(*FAnswer,*gCling);
|
||||
Smart s;
|
||||
ArgVs[0] = llvm::GenericValue(&s);
|
||||
if (!CAnswer.Invoke(ArgVs, &V)) {printf("CAnswer failed!\n");} // CHECK: TheAnswer!
|
||||
V // CHECK: (cling::Value) boxes [(int) 42]
|
||||
|
||||
const clang::FunctionDecl* FInline = lookup.findFunctionProto(DSmart, "Inline", "");
|
||||
assert(FInline && "Smart::Inline() not found");
|
||||
cling::Callable CInline(*FInline,*gCling);
|
||||
if (!CInline.Invoke(ArgVs, &V)) {printf("CInline failed!\n");} // CHECK: CInline failed!
|
||||
V // CHECK: (cling::Value) boxes [(int) 42]
|
@ -1,6 +1,5 @@
|
||||
// request symbols
|
||||
#include "cling/Interpreter/Interpreter.h"
|
||||
#include "cling/Interpreter/Callable.h"
|
||||
#include "cling/Interpreter/CValuePrinter.h"
|
||||
#include "cling/Interpreter/DynamicExprInfo.h"
|
||||
#include "cling/Interpreter/LookupHelper.h"
|
||||
@ -22,7 +21,6 @@ void libcling__symbol_requester(const clang::FunctionDecl& Decl,
|
||||
printValueDefault(llvm::outs(), 0, VPI);
|
||||
cling_PrintValue(0, 0, 0);
|
||||
flushOStream(llvm::outs());
|
||||
Callable C(Decl,Interp);
|
||||
LookupHelper h(0);
|
||||
h.findType("");
|
||||
h.findScope("");
|
||||
|
Reference in New Issue
Block a user