Get name of MemberExpr expression

Hi all,

I’m new to clang and currently working on a project where I need to rewrite some codes in CUDA source file.

For example, if I have the following CUDA code:

int bx = blockIdx.x;
int by = blockIdx.y;

I want to rewrite the blockIdx and blockIdx.x and blockIdx.y to some other code:
int bx = something else;
int by = something else;

My problem is that how do I find the MemberExpr blockIdx,x and blockIdx.y?

I know how to get the MemberExpr, but I have no clue how to extract the name of the MemberExpr in order to know that it is the right MemberExpr for me to rewrite.

Any help is appreciated.

Patrick

Hi,
Do you mean finding AST corresponding to MemberExpr or you already found then and trying to figure out SourceLocation for them?

Regards, Alexey K

Hello,

You can use getBase() method to retrieve 'blockIdx' and getMemberDecl() to find out what declaration is being referred.

07.12.2017 11:40, Qiufeng Yu via cfe-dev пишет:

With getBase(), I will get an Expr, but how do I get the actual base? In other words, all I want is a string “blockIdx” so that I can perform something like
if(string == “blockIdx”){
Rewrite.replaceText()…
}

Say the original code is int bx = blockIdx.x, I already found the MemberExpr of this line of code, which is blockIdx.x. But all I have is only this MemberExpr. What I need is the actual string representation of this MemberExpr so that I can perform the string comparison to make sure that this MemberExpr is indeed blockIdx.x, and perform the rewriting process.

I can also use the ASTMatcher to find all MemberExprs, but still can’t narrow them down to those only called blockIdx.x and blockIdx.y.
My Matcher is following:

Matcher.addMatcher(memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName(“blockIdx.x”))))));
Matcher.addMatcher(memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName(“blockIdx.y”))))));

You should not check RecordDecl in this manner as soon as it MemberExpr is “composite”. I mean you should separately check base & memberDecl.

According to docs for MeberExpr::getMemberDecl
The returned declaration will be a FieldDecl or (in C++) a VarDecl (for

/// static data members), a CXXMethodDecl, or an EnumConstantDecl.

Hi Alexey,

As far as checking the base. What’s the best way to check if the base is actually “blockIdx”?

Here is the ast dump for the MemberExpr that I’m interested in.

MemberExpr 0x55deb5e87188 ‘unsigned int (void)’ lvalue .__fetch_builtin_x 0x55deb5001b60
-OpaqueValueExpr 0x55deb5e87130 'const struct __cuda_builtin_blockIdx_t' lvalue -DeclRefExpr 0x55deb5e870d0 ‘const struct __cuda_builtin_blockIdx_t’ lvalue Var 0x55deb5097940 ‘blockIdx’ ‘const struct __cuda_builtin_blockIdx_t’

MemberExpr 0x55deb5e87388 ‘unsigned int (void)’ lvalue .__fetch_builtin_y 0x55deb5001d50
-OpaqueValueExpr 0x55deb5e87330 'const struct __cuda_builtin_blockIdx_t' lvalue -DeclRefExpr 0x55deb5e872d0 ‘const struct __cuda_builtin_blockIdx_t’ lvalue Var 0x55deb5097940 ‘blockIdx’ ‘const struct __cuda_builtin_blockIdx_t’

I think the member name should be __fetch_builting_x or __fetch_buildin_y, and the base name should be found in a DeclRefExpr.
The problem is that, all I have is a Stmt pointer Stmt *s, which can be casted to MemberExpr *me, then I do if(MemberExpr *me = dyn_cast(s)) to see if the Stmt is a MemberExpr.
If yes, how do I cast this *me to OpaqueValueExpr or DeclRefExpr to retrieve the actually name in the DeclRefExpr?

  1. Get base: E = MemberExpr->getBase();
  2. Clear it from parens and casts (optional): E = E->Ignore*() // various variants from Expr (I don’t know actually if you need this and if so, what you actually need in your case)
  3. Make sure it is DeclRefExpr (via dyn_cast_or_null) and get its declaration via getDecl / getFoundDecl depending on your needs.

If all you want is a string, you might also consider using Stmt::printPretty().

This is rarely what people actually want though. Usually assuring that this is the kind of expression you're looking for might be necessary as well, i.e. the thing after the dot is actually a variable.