Create a BlockAddress array from LLVM Pass


Good day. For the following function local static constant array:

static const __attribute__((used))
__attribute__((section("data"))) void *codetable[] = {

I have the following in the LLVM IR.

@sampleCode.codetable = internal global [5 x i8*] [i8* blockaddress(@sampleCode, %19), i8* blockaddress(@sampleCode, %22), i8* blockaddress(@sampleCode, %25), i8* blockaddress(@sampleCode, %28), i8* blockaddress(@sampleCode, %31)], section “data”, align 16

Here the array elements are labels in c code. I have done following to create the same array from LLVM pass.


std::vector<BlockAddress *> tmp;

Function *fn = ...
BasicBlock *bb = ...

BlockAddress *bba = BlockAddress::get(fn, bb);

GlobalVariable *gvar_ptr_abc = new GlobalVariable(
/*Initializer=*/0, // has initializer, specified below
Constant *blockItems = ConstantDataArray::get(fn->getContext(), tmp);

I get error with following: Unsupported type in Type::getScalarTy`

Can anyone suggest what I suppose to do? It is definitely related to my type declaration and BlockAddress items, but I don't know what it is exactly.

Please don’t send questions to both cfe-dev and llvm-dev; usually one or the other is more appropriate (in this case, it’s llvm-dev, since there’s no clang code involved).

I think you meant to call ConstantArray::get, not ConstantDataArray::get. (We should probably fix ConstantDataArray::get() to use enable_if or something like that, so your example fails to compile instead of generating a weird runtime error.)


Sorry for emailing both group.

As I will have a constant array of BlockAddress, what type I should use in Constant Array for its ArrayType declaration?
I am creating the list in following way:

unsigned int nBr = fit->second.size();
llvm::Constant *listBA[nBr];
unsigned int Idx = 0;
for (std::set<llvm::BasicBlock *>::iterator it = fit->second.begin();
it != fit->second.end(); ++it) {
BlockAddress *bba = BlockAddress::get(fn, *it);
listBA[Idx] = bba;
Constant *blockItems =
ConstantArray::get(ArrayType::get(?, 8), listBA);


More specifically, this is what I have right now.


unsigned int nBr = fit->second.size();
// integer pointer type
PointerType *PointerTy =
PointerType::get(IntegerType::get(fn->getContext(), 8), 8);

// list the BlockAddress from BasicBlock
std::vector<Constant *> listBA;
for (std::set<llvm::BasicBlock *>::iterator it = fit->second.begin();
it != fit->second.end(); ++it) {
BlockAddress *bba = BlockAddress::get(fn, *it);
ArrayRef<llvm::Constant *> blockArray(listBA);

// create the constant type and array
ArrayType *pArrTy = ArrayType::get(PointerTy, nBr);
Constant *blockItems = ConstantArray::get(pArrTy, blockArray);

// Global Variable Declarations
GlobalVariable *gvar_ptr_abc = new GlobalVariable(
*fn->getParent(), pArrTy, true, GlobalValue::InternalLinkage,
blockItems, "labelTracker");


And I received following message when try to disassemble the .bc.
LLVM ERROR: Type mismatch in constant table!

Thanks, I have solved it with this:
PointerType *intPtTy = Type::getInt8PtrTy(fn->getContext());