[LLVMdev] Question about insert call func with pionter parameter

Chris Lattner sabre at nondot.org
Thu Dec 9 08:11:57 PST 2004


On Wed, 8 Dec 2004, Zhang Qiuyu wrote:

> Hi,
>
> I got a problem when I am trying to insert a call function with pointer arguments.
>
> The function C proto-type is the following,
>
> void stat_func(char *);
>
>> ConstantArray *Cstr = dyn_cast<ConstantArray>(gI->getInitializer());
> ......
>> Function *exFunc = M->getOrInsertFunction("stat_func", Type::VoidTy, PointerType::get(Type::SByteTy),0);
>> std::vector<Value*> Args(1);
>> Args[0] = constantArray::get(Cstr->getAsString());
>> CallInst *call = new CallInst(exFunc, Args,"",InsertPos);
>
> If the code look like the above, it could compile successfully. But once I run this pass, finally, I got errors as the following.
>
> " Call parameter type does not match function signature!"
> [21 x sbyte] c"This a example\00\00\00\00\00\00"
> sbyte* call void %stat_func( [21 x sbyte] c "this a example\00\00\00\00"
> ...........
> Broken module found, comilation aborted!
> ........
>
> The information comes from verifier.cpp which mean the type of parameter 
> of the function differ with the type of parameter the code passed.

Yes, this analysis is exactly right.

> I knew that the constantarry differ from sbyte pointer ( sbyte*), but I 
> tried to change the code to
>
>> Function *exFunc = M->getOrInsertFunction("stat_func", Type::VoidTy, Cstr->getType(),0);
> or
>> Function *exFunc = M->getOrInsertFunction("stat_func", Type::VoidTy, Type::ArrayTyID,0);
>
> and once I run the pass, it is worse than the above. the error information is
>
> " llvm::FunctionType::FunctionType(const llvm::Type*, const std::vector<const llvm::Type*, std::allocator<const llvm::Type::>>&,bool): Assertion ..............Function arguments must be value types!"

Frankly, I'm suprised this compiles.  "TyID"'s are not types.  In 
particular, there is no way to say "pass any array as this argument".

> Finally, I tried to change the code of arguments like this
>
>> Function *exFunc = M->getOrInsertFunction("stat_func", Type::VoidTy, PointerType::get(Type::SByteTy),0);
>> std::vector<Value*> Args(1);
>> Args[0] = constantExpr::getGetElementPtr(constantArray::get(Cstr->getAsString()), 0);
>
> But I failed to pass the compilation.  How could I fix this problem?

Here you're definitely on the right track.  To get to [n x sbyte]* to 
sbyte*, you need to use a 'getelementptr Ptr, 0, 0' instruction or 
constant expr.  The problem with the code above is that the 
getGetElementPtr method takes a vector as the second argument (of the 
indexes), and that ConstantExpr is capitalized.  You can certainly create 
a vector<Value*>, and pass in two Constant 0's (not literal C integer 
0's).  Alternatively, you can just *cast* the pointer to array to pointer 
to sbyte, and VMCore should notice that it can create the getelementptr 
constantexpr instead, saving you the trouble.

The second problem with this is that ConstantArray's cannot be used as 
normal values, they can only be used to initialize a global variable. 
Given that global variable, you can use the global's address to access the 
contents of the array.

-Chris

-- 
http://nondot.org/sabre/
http://llvm.cs.uiuc.edu/




More information about the llvm-dev mailing list