I am working on a pass in which I need to define and insert a function with variable arguments. Can I do it with the help of getOrInsertFunction()? If not can someone tell me any other method?
It will be very helpful if anyone can help. Thanks in advance
Akshay Jain <jivan.molu@gmail.com> writes:
I am working on a pass in which I need to define and insert a function with
variable arguments. Can I do it with the help of getOrInsertFunction()?
Sure. There is an overload of getOrInsertFunction that takes a
FunctionType, and there are FunctionType::get static methods where you
say if the function type takes a variable number of arguments. See the
doxygen documentation for FunctionType and Module::getOrInsertFunction.
I have tried it, but I always end up with some kind of error. Can you explain how can I get a function type for function which returns void (nothing) and it’s arguments are (int, int, int, void *, void *, …) ??
Thanks in advance.
Akshay Jain <jivan.molu@gmail.com> writes:
I have tried it, but I always end up with some kind of error. Can you
explain how can I get a function type for function which returns void
(nothing) and it's arguments are (int, int, int, void *, void *, ...) ??
Instead of getting something to cut&paste, you would be much more
enriched if the problematic code and the resulting errors were shown for
examination.
The code that I have written to get the function type is:
const std::vector<Type *> ParamTys;
ParamTys.push_back(IntegerType::getInt32Ty(Context));
ParamTys.push_back(IntegerType::getInt32Ty(Context));
ParamTys.push_back(IntegerType::getInt32Ty(Context));
ParamTys.push_back(PointerType::get(Type::getVoidTy(Context), 0));
ParamTys.push_back(PointerType::get(Type::getVoidTy(Context), 0));
FunctionType *ftype = FunctionType::get(Type::getVoidTy(Context), ParamTys, true);
And the errors are:
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp: In member function ‘virtual bool {anonymous}::Hello2::runOnFunction(llvm::Function&)’:
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:108:62: error: no matching function for call to ‘std::vectorllvm::Type*::push_back(const llvm::IntegerType*) const’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:108:62: note: candidate is:
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = llvm::Type*, _Alloc = std::allocatorllvm::Type*, std::vector<_Tp, _Alloc>::value_type = llvm::Type*]
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: no known conversion for argument 1 from ‘const llvm::IntegerType*’ to ‘llvm::Type* const&’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:109:62: error: no matching function for call to ‘std::vectorllvm::Type*::push_back(const llvm::IntegerType*) const’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:109:62: note: candidate is:
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = llvm::Type*, _Alloc = std::allocatorllvm::Type*, std::vector<_Tp, _Alloc>::value_type = llvm::Type*]
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: no known conversion for argument 1 from ‘const llvm::IntegerType*’ to ‘llvm::Type* const&’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:110:62: error: no matching function for call to ‘std::vectorllvm::Type*::push_back(const llvm::IntegerType*) const’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:110:62: note: candidate is:
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = llvm::Type*, _Alloc = std::allocatorllvm::Type*, std::vector<_Tp, _Alloc>::value_type = llvm::Type*]
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: no known conversion for argument 1 from ‘const llvm::IntegerType*’ to ‘llvm::Type* const&’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:111:75: error: no matching function for call to ‘std::vectorllvm::Type*::push_back(llvm::PointerType*) const’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:111:75: note: candidate is:
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = llvm::Type*, _Alloc = std::allocatorllvm::Type*, std::vector<_Tp, _Alloc>::value_type = llvm::Type*]
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: no known conversion for implicit ‘this’ parameter from ‘const std::vectorllvm::Type*’ to ‘std::vectorllvm::Type*’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:112:75: error: no matching function for call to ‘std::vectorllvm::Type*::push_back(llvm::PointerType*) const’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:112:75: note: candidate is:
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = llvm::Type*, _Alloc = std::allocatorllvm::Type*, std::vector<_Tp, _Alloc>::value_type = llvm::Type*]
/usr/include/c++/4.6/bits/stl_vector.h:826:7: note: no known conversion for implicit ‘this’ parameter from ‘const std::vectorllvm::Type*’ to ‘std::vectorllvm::Type*’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:114:91: error: no matching function for call to ‘llvm::FunctionType::get(const llvm::Type*, const std::vectorllvm::Type*&, bool)’
/home/akshay/llvm/llvm-2.9/lib/Transforms/AliasPass/pass2.cpp:114:91: note: candidates are:
/home/akshay/llvm/llvm-2.9/include/llvm/DerivedTypes.h:157:24: note: static llvm::FunctionType* llvm::FunctionType::get(const llvm::Type*, const std::vector<const llvm::Type*>&, bool)
/home/akshay/llvm/llvm-2.9/include/llvm/DerivedTypes.h:157:24: note: no known conversion for argument 2 from ‘const std::vectorllvm::Type*’ to ‘const std::vector<const llvm::Type*>&’
It may be a silly mistake, but I am quite new to c and c++ coding especially in llvm. So I will be very grateful if you can help out.
Akshay Jain <jivan.molu@gmail.com> writes:
The code that I have written to get the function type is:
const std::vector<Type *> ParamTys;
You are declaring a constant vector...
ParamTys.push_back(IntegerType::getInt32Ty(Context));
... and then you try to modify it by pushing back an element. Remove the
`const' from the std::vector declaration.
ParamTys.push_back(IntegerType::getInt32Ty(Context));
ParamTys.push_back(IntegerType::getInt32Ty(Context));
ParamTys.push_back(PointerType::get(Type::getVoidTy(Context), 0));
There is no "pointer to void" in the LLVM type system. Use a pointer to
byte:
ParamTys.push_back(PointerType::get(Type::getInt8Ty(Context), 0));
ParamTys.push_back(PointerType::get(Type::getVoidTy(Context), 0));
Same.
FunctionType *ftype = FunctionType::get(Type::getVoidTy(Context), ParamTys,
true);
This looks good.
And the errors are:
[snip]
It may be a silly mistake, but I am quite new to c and c++ coding
especially in llvm. So I will be very grateful if you can help out.
Using LLVM without a solid background in C++ is a tough task.
You don't need to know about template metaprogramming, but an
understanding of classes (and the C++ type system in general) and some
familiarity with the idioms of the C++ Standard Library is essential.
A good method for familiarizing yourself with the LLVM API is to feed
clang with some C or C++ source code that uses the feature you are
interested in and then use llc for obtaining the LLVM C++ code that
generates the corresponding LLVM intermediate representation. For this
specific case:
/* foo.c */
void foo(int, int, void*, void*, ...) {
return;
}
/* end of foo.c */
clang -emit-llvm -c foo.c -o foo.ll
llc -march=cpp foo.ll -o foo.ll.cpp
Now look into foo.ll.cpp