Distinguish in the AST constant array declarations which size is set directly and by the initializer.

dear cfe-list,

Source code example:
-------<
const char a1 = "abcd";
const char a2[5] = "abcd";

int* p1 = (int){0,1,2,3,4}
int* p2 = (int[5]){0,1,2,3,4}
------->

Visiting the clang AST, is there a way to distinguish between the arrays a1
and a2 and the two unnamed objects whose address will be stored in p1
and p2?

I need to check that the second form is not used.

It seems that in all cases the type is clang::ConstantArrayType, the storage
modifier is normal and the size 4.

thanks,
pb

No, we don't distinguish those cases at the moment. Patches welcome,
I guess, but I'm not sure where the best place to note it would be.

-Eli

About arrays, I noticed there was still one free bit pattern (2 bit
allocated, 3 possible size modifiers) so I added NormalImplicit
size modifier that has the same meaning of Normal but indicates that the size
was implicitly defined by the initialiser.

When Sema::AddInitializerToDecl notices the change of type from VariableArray
to ConstantArray it creates a new array type with NormalImplicit as size
modifier.

Here is code:

if (ConstantArrayType* T = cast<ConstantArrayType>(DclT.getTypePtr())) {
  if(isa<IncompleteArrayType>(SavT.getTypePtr())) {
    assert(T-> getSizeModifier() == ArrayType::Normal);
    DclT = Context.getConstantArrayType(T->getElementType(),
                                        T->getSize(),
                                        ArrayType::NormalImplicit,
                                        T->getIndexTypeQualifier());
    ConstantArrayType* T1 = cast<ConstantArrayType>(DclT.getTypePtr());
    assert(T1-> getSizeModifier() == ArrayType::NormalImplicit);
  }
}

Unfortunately, it happens that the second assert fails because
getConstantArrayType returns the previous QualType instead of a new one.
This is caused by the fact that two constant array types are considered
identical no matter the storage class.

I enclosed a patch to this message, it should work using patch -p0 in
the llvm directory.

A real code example where you can see the problem is this one:

void f(int b[5][static 5]);
int a[5][5];

the size storage `static' appears also in the latter array definition.

Thanks,
pb

patch.tar.gz (718 Bytes)

About arrays, I noticed there was still one free bit pattern (2 bit
allocated, 3 possible size modifiers) so I added NormalImplicit
size modifier that has the same meaning of Normal but indicates that the size
was implicitly defined by the initialiser.

Hmm, that seems like it'll work. I'll take another look once the bug
below is fixed.

Unfortunately, it happens that the second assert fails because
getConstantArrayType returns the previous QualType instead of a new one.
This is caused by the fact that two constant array types are considered
identical no matter the storage class.

Ouch, that's nasty... would you file a bug? I think the bug is in the
implementations of Profile for ConstantArrayType and
IncompleteArrayType.

-Eli

Here it is, already fixed by Lattner:
http://llvm.org/bugs/show_bug.cgi?id=3619

pb