I am writing a tool using the 3.8.0 source code. My ASTMatcher is callExpr().bind(“callExpr”); I am getting the type of the first argument with auto type = callExpr->getArg(i)->IgnoreImplicit()->getType();
Given this code:
If Func is declared as either of these, then type->getAs() returns a non-null value and type.getAsString() returns “S”:
void Func(const T&);
If Func is declared as this, then type->getAs() returns null and type.getAsString() returns “struct S”:
I would expect all three to return a non-null value and the same result from getAsString. Why do these differ?
If you dump the ast, -Xclang -ast-dump -fsyntax-only, you’ll see that when s is passed by value, an ImplicitCastExpr node is created for the implicit type conversion from “struct S” to “const struct S”, and you are ignoring implicits, IgnoreImplicit():
-CallExpr 0x7fefab076990 <line:44:3, col:9> ‘void’
-ImplicitCastExpr 0x7fefab076978 col:3 ‘void (*)(struct S)’
-DeclRefExpr 0x7fefab0768e8 <col:3> 'void (struct S<int>)' lvalue Function 0x7fefab0767e0 'Func' 'void (struct S<int>)' (FunctionTemplate 0x7fefab06e808 'Func') -CXXConstructExpr 0x7fefab076a28 col:8 ‘struct S’:‘struct S’ ‘void (const struct S &) throw()’
-ImplicitCastExpr 0x7fefab0769c0 <col:8> 'const struct S<int>' lvalue <NoOp> -DeclRefExpr 0x7fefab0765b8 col:8 ‘S’:‘struct S’ lvalue Var 0x7fefab06ee48 ‘s’ ‘S’:‘struct S’
If you made s const instead, i.e., const S s, then clang wouldn’t need to implicitly convert it and you should see it.
You are right that all it does have the implicit cast to const, but all three have an implicit cast to const that are notated as . So, that doesn’t appear to be what is causing my issues.
Yes, you’re correct – I left out the const in my test.
Looks like it’s because RecordTypes aren’t sugared. See Type.cpp line 317.
if (!Ty->isSugared()) return 0;