Hi Óscar,<br><div class="gmail_quote"><span name="Óscar Fuentes"></span><br>Thank you for your prompt reply. Unfortunately, I still need more guidance as using the Demo page to generate C++ code didn't result in a global variable being used.<br>

<br>Basically, I'm following your advice to use a LoadInst:<div class="im"><br><br>
Value *v = new LoadInst(result, "", theBasicBlock);<br>
Function *myfn = cast<Function>(v);<br><br></div>I was not sure how I could get a BasicBlock for the LoadInst, so I created a dummy function (which was never called).<br>Casting was successful as myfn->getType()->dump() produced i32 (i32, i32)*. However, I'm getting a "bus error" when trying to run the retrieved function using an ExecutionEngine (not sure if this is the proper way to run a function). <br>

<br>Here is my code:<br><br>// includes omitted<br>using namespace llvm;<br>using namespace std;<br><br>static Function *CreateAddFunction(Module *module) {<br>    Function *func_add = cast<Function> (<br>            module->getOrInsertFunction("add",<br>

                    Type::getInt32Ty(module->getContext()),<br>                    Type::getInt32Ty(module->getContext()),<br>                    Type::getInt32Ty(module->getContext()), (Type *) 0));<br><br>    BasicBlock *BB = BasicBlock::Create(module->getContext(), "Start", func_add);<br>

    Function::arg_iterator args = func_add->arg_begin();<br>    Value* arg1 = args++;<br>    Value* arg2 = args++;<br>    Value *Sum = BinaryOperator::CreateAdd(arg1, arg2, "sum", BB);<br>    ReturnInst::Create(module->getContext(), Sum, BB);<br>

    return func_add;<br>}<br><br>int main() {<br>    // basically what I want is create a function (func_add), store it in a global variable, retrieves it from the global var, and run it.<br><br>    Module *module = new Module("myModule", getGlobalContext());<br>

    module->setDataLayout(<br>            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128");<br>    module->setTargetTriple("x86_64-unknown-linux-gnu");<br>

<br>    Function *func_add = CreateAddFunction(module);<br><br>    // create a StructType to contain func_add<br>    StructType *myStructType = StructType::create(module->getContext(), "myStruct");<br>    std::vector<Type*> fields;<br>

    fields.push_back(func_add->getType());<br><br>    if (myStructType->isOpaque()) {<br>        myStructType->setBody(fields, /*isPacked=*/false);<br>    }<br><br>    string myGVName = "myGV";<br><br>
    // create a GlobalVariable to store myStruct<br>
    GlobalVariable* mainGV = new GlobalVariable(<br>    /*Module=*/*module,<br>    /*Type=*/myStructType,<br>    /*isConstant=*/false,<br>    /*Linkage=*/GlobalValue::ExternalLinkage,<br>    /*Initializer=*/0, // has initializer, specified below<br>

            /*Name=*/myGVName);<br><br>    Constant* ptr_to_func_add = ConstantStruct::get(myStructType, func_add);<br>    mainGV->setInitializer(ptr_to_func_add);<br><br>    // now try to retrieve func_add from the global variable<br>

        GlobalVariable* retrieved = module->getGlobalVariable(myGVName);<br><br>    if (retrieved) {<br>        std::vector<Constant*> indices;<br>        ConstantInt* constI32_0 = ConstantInt::get(module->getContext(),<br>

                APInt(32, StringRef("0"), 10));<br>        indices.push_back(constI32_0);<br>        indices.push_back(constI32_0);<div class="im"><br>        Constant* result = ConstantExpr::getGetElementPtr(retrieved, indices);<br>

<br></div>        Function *func_dummy = cast<Function> (<br>                module->getOrInsertFunction("dummy",<br>                        Type::getVoidTy(module->getContext()),<br>                        Type::getInt32Ty(module->getContext()), (Type *) 0));<br>

<br>        // Add a basic block to the function.<br>        BasicBlock *BB = BasicBlock::Create(module->getContext(), "EntryBlock", func_dummy);<br>        Value *v = new LoadInst(result, "", BB);<br>

        ReturnInst::Create(module->getContext(), BB);<div class="im"><br>        Function *myfn = cast<Function> (v);<br><br></div>        // let's see if module verifies<br>        if (verifyModule(*module)) {<br>
            return 1;<br>
        } else {<br>            module->dump();<br>        }<br><br>        if (myfn && isa<Function>(myfn)) {<br>                ExecutionEngine *EE = EngineBuilder(module).create();<br>                if (!EE) {<br>

                    return 1;<br>                }<br><br>                std::vector<GenericValue> Args(2);<br>                Args[0].IntVal = APInt(32, 5);<br>                Args[1].IntVal = APInt(32, 10);<br>                outs() << "\ntype of myfn:";<br>

                myfn->getType()->dump();<br>                GenericValue GV = EE->runFunction(func_add, Args);<br>                outs() << "\nResult: " << GV.IntVal << "\n";<br>

        }<br>    }<br>    return 0;<br>}<br><br>However, if I replace the retrieved function ponter<br><br>                GenericValue GV = EE->runFunction(myfn, Args);<br><br>with the original function pointer<br>                GenericValue GV = EE->runFunction(func_add, Args);<br>

<br>It seems to run okay and prints the correct result.<br><br>Here is the dump of my console:<br><br>===================================================================<br>; ModuleID = 'myModule'<br>target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"<br>

target triple = "x86_64-unknown-linux-gnu"<br><br>%myStruct = type { i32 (i32, i32)* }<br><br>@myGV = global %myStruct { i32 (i32, i32)* @add }<br><br>define i32 @add(i32, i32) {<br>Start:<br>  %sum = add i32 %0, %1<br>

  ret i32 %sum<br>}<br><br>define void @dummy(i32) {<br>EntryBlock:<br>  %1 = load i32 (i32, i32)** getelementptr inbounds (%myStruct* @myGV, i32 0, i32 0)<br>  ret void<br>}<br><br>type of myfn:i32 (i32, i32)*Bus error<br>

===================================================================<br><br>What am I doing wrong here?<br><br>Thank you for your help,<br>Jay<div class="HOEnZb"><div class="h5"><br><br>On Wed, Sep 19, 2012 at 7:02 AM, Óscar Fuentes <span dir="ltr"><<a href="mailto:ofv@wanadoo.es" target="_blank">ofv@wanadoo.es</a>></span> wrote:<br>

<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Jay Gelisah <<a href="mailto:jay.gelisah@gmail.com" target="_blank">jay.gelisah@gmail.com</a>> writes:<br>


<br>
> I'm creating a GlobalVariable that contains a StructType that contains a<br>
> Function. The function returns i32 and takes two i32's.<br>
><br>
> Here is my code:<br>
> GlobalVariable* retrieved = module->getGlobalVariable("myGV");<br>
> ...<br>
> Constant* result = ConstantExpr::getGetElementPtr(retrieved, indices);<br>
><br>
> How do I get my Function back from the Constant* result?<br>
<br>
</div>You already have a pointer to the function pointer stored in `result'.<br>
<div><br>
> I'd like to be able to run the function.<br>
<br>
</div>Use CallInst::Create for creating a CallInst. CallInst will gladly<br>
accept a Value* or one of its derivatives as its argument, as far as it<br>
has the correct type (see below). No need to cast.<br>
<div><br>
> result->dump() shows the following:<br>
> i32 (i32, i32)** getelementptr inbounds (%myStruct* @myGV, i32 0, i32 0)<br>
<br>
</div>Please note that you need to pass the result of the getelementptr<br>
through a LoadInst because, as shown, getelementptr returns a pointer to<br>
the data inside the struct or array.<br>
<br>
Value *v = new LoadInst(result, "", theBasicBlock);<br>
Function *myfn = cast<Function>(v);<br>
<check that `myfn' is not null><br>
<br>
In general, for learning the C++ API it is a good idea to create a<br>
sample of C/C++ code that does what your generated code should do and<br>
pass it through Clang/llc to see the C++ API code. The online demo<br>
available at <a href="http://llvm.org/demo/index.cgi" target="_blank">http://llvm.org/demo/index.cgi</a> is handy for that. In your<br>
specific case, put there the code below, check the C++ radiobutton,<br>
select the C++ API target and push the Compile button.<br>
<br>
struct Foo {<br>
  int dummy;<br>
  double anotherDummy;<br>
  int (*fn)(int, int);<br>
};<br>
<br>
int callIt(Foo foo) {<br>
  return (*foo.fn)(1, 2);<br>
}<br>
</blockquote></div><br>
</div></div></div><br>