how to get array size from an array decl ?

Hello,

if the program is :

void foo()
{
int a[3] = {0,1,2};
}

If I get the ast nodes by the ast matcher: varDecl(hasType(arrayType()))
I will get int a[3] matched, the matched node is a VarDecl type.
How can I get the array size (in this example is 3) from the VarDecl node ?

Thank you for any help !

Anders

getType() on the VarDecl returns a QualType. Call ASTContext::getAsConstantArrayType to convert that to a ConstantArrayType*. Call ConstantArrayType::getSize() to return the size. If you need access to the original Expr*, as opposed to the computed size, you might need to dig through the TypeSourceInfo instead. -Eli

Hello,
if the program is :
void foo()
{
int a[3] = {0,1,2};
}
If I get the ast nodes by the ast matcher: varDecl(hasType(arrayType()))
I will get int a[3] matched, the matched node is a VarDecl type.
How can I get the array size (in this example is 3) from the VarDecl node ?
Thank you for any help !
Anders

Hi Anders,

I recommend reading through

https://blogs.msdn.microsoft.com/vcblog/2018/10/23/exploring-clang-tooling-part-2-examining-the-clang-ast-with-clang-query/

which I published yesterday.

It should help you understand some of the issues of discovery when creating an AST Matcher tool.

For your case, you would start with a file like

void foo()
{
    int a[3] = {0,1,2};

    int a2[2 + 1] = {0,1,2};

    constexpr int someSize = 2;
    constexpr int otherSize = 1;

    int a3[someSize + otherSize] = {0,1,2};

    int a4[] = {0,1,2};
}

and run clang-query on it.

Run

  clang-query> match varDecl(hasType(type().bind("t")))

to see what varDecls get matched, then switch to detailed-ast mode to see the AST:

  clang-query> set output detailed-ast
  clang-query> match varDecl(hasType(type().bind("t")))

Binding for "root":
VarDecl <arraysize.cpp:4:4, col:21> col:8 a 'int [3]'
`-InitListExpr <col:15, col:21> 'int [3]'
   >-IntegerLiteral <col:16> 'int' 0
   >-IntegerLiteral <col:18> 'int' 1
   `-IntegerLiteral <col:20> 'int' 2

Binding for "t":
ConstantArrayType 'int [3]' 3
`-BuiltinType 'int'

So, that way you discover that the type to use in your matcher is constantArrayType() instead of arrayType(), and that has the 'hasSize()' matcher.

  match varDecl(hasType(constantArrayType(hasSize(3)).bind("t")))

in your `check` method you can use the getSize() accessor:

  http://clang.llvm.org/doxygen/classclang_1_1ConstantArrayType.html

However, you can see in my example that my computations like `1 + 2` result in `3` in the type system. To access those expressions, you need to know how to access/traverse the TypeLoc system which is a bit less obvious, but will become easier soon.

Thanks,

Stephen.