How to get the string value?

Hi, if I have some LLVM code like this:

@.str = private unnamed_addr constant [7 x i8] c"in_arr\00", align 1
@.str1 = private unnamed_addr constant [8 x i8] c"in_arr2\00", align 1
@.str2 = private unnamed_addr constant [8 x i8] c"out_arr\00", align 1


call void (…)* @_Z16fooz(i8* getelementptr inbounds ([7 x i8]* @.str, i64 0, i64 0), i32 0, i32 1024)

I would like to get the string value of the bold argument, but how? I know it’s a llvm::Value pointer, but it is not a llvm::GetElementPtrInst?

Thanks,

Hi Welson Sun,

Hi, if I have some LLVM code like this:

@.str = private unnamed_addr constant [7 x i8] c"in_arr\00", align 1
@.str1 = private unnamed_addr constant [8 x i8] c"in_arr2\00", align 1
@.str2 = private unnamed_addr constant [8 x i8] c"out_arr\00", align 1
...

   call void (...)* @_Z16fooz(i8* *getelementptr inbounds ([7 x i8]* @.str, i64
0, i64 0)*, i32 0, i32 1024)
...

I would like to get the string value of the bold argument, but how? I know it's
a llvm::Value pointer, but it is not a llvm::GetElementPtrInst?

it is a ConstantExpr getelementptr. Whenever you see something that looks like
an instruction but is printed inline inside another instruction then that means
it is actually a constant, a ConstantExpr.

Ciao, Duncan.

Thanks Duncan,

Yes, it is a ConstantExpr! Thank you!

Now trying to find a clue in ConstantExpr’s functions to get that string :slight_smile:

Regards,
Welson

OK, I guess I need further help. Out of these member functions:

DECLARE_TRANSPARENT_OPERAND_ACCESSORS (Constant) |

  • | - |

Transparently provide more efficient getOperand methods.
|
bool | isCast () const |
Return true if this is a convert constant expression.
|
bool | isCompare () const |
Return true if this is a compare constant expression.
|
bool | hasIndices () const |
Return true if this is an insertvalue or extractvalue expression, and the getIndices() method may be used.
|
bool | isGEPWithNoNotionalOverIndexing () const |
Return true if this is a getelementptr expression and all the index operands are compile-time known integers within the corresponding notional static array extents. Note that this is not equivalant to, a subset of, or a superset of the “inbounds” property.
|
unsigned | getOpcode () const |
getOpcode - Return the opcode at the root of this constant expression
|
unsigned | getPredicate () const |
ArrayRef<unsigned > | getIndices () const |
const char * | getOpcodeName () const |
getOpcodeName - Return a string representation for an opcode.
|
Constant * | getWithOperandReplaced (unsigned OpNo, Constant *Op) const |
Constant * | getWithOperands (ArrayRef< Constant * > Ops) const |
Constant * | getWithOperands (ArrayRef< Constant * > Ops, Type *Ty) const |
virtual void | destroyConstant () |
virtual void | replaceUsesOfWithOnConstant (Value *From, Value *To, Use *U) |

Only isGEPWithNoNotionalOverIndexing () returns true. But how are you supposed to use others to get the constant value?

Hi Welson,

Yes, it is a ConstantExpr! Thank you!

Now trying to find a clue in ConstantExpr's functions to get that string :slight_smile:

you can get the pointer operand by doing: getOperand(0)
The i'th index is getOperand(i+1).

Ciao, Duncan.

Hey Duncan,

Thanks! I figured out this piece of code finally:

Value *gep = call->getArgOperand(0);
if ( ConstantExpr *pCE = dyn_cast(gep) ) {
Value *firstop = pCE->getOperand(0);
if (GlobalVariable *GV = dyn_cast(firstop)){
Constant *v = GV->getInitializer();
if (ConstantArray *CA = dyn_cast(v)) {
StringRef portName(CA->getAsString());

That’s some learning experience :slight_smile:

Regards,
Welson

Hi Welson,

Thanks! I figured out this piece of code finally:

             Value *gep = call->getArgOperand(0);
             if ( ConstantExpr *pCE = dyn_cast<ConstantExpr>(gep) ) {
               Value *firstop = pCE->getOperand(0);
               if (GlobalVariable *GV = dyn_cast<GlobalVariable>(firstop)){
                 Constant *v = GV->getInitializer();
                 if (ConstantArray *CA = dyn_cast<ConstantArray>(v)) {
                   StringRef portName(CA->getAsString());

you can use stripPointerCasts to get rid of the GEP and similar pointer casts.

Ciao, Duncan.