Why qualifiers for array elements on the array itself?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Why qualifiers for array elements on the array itself?

Manas via cfe-dev
Hi,

I'm currently working on a clang cast tool and ran into a small oddity. This might be a stupid mistake but I'd love some pointers(no pun intended) or insight into it:

const int arr[2] {1,2};

should be "an array of fixed size 2 of constant integers". The QualType associated with arr is an array type, and we can observe that with Expr->isArrayType(). I checked the qualifiers and found that the qualifier for const is actually on this level, and not for the individual elements of ints. I found the elements inside of the array with the following:

const ArrayType* ArrType = dyn_cast<ArrayType>(MyQualType);
ArrType->getElementType();

which I was hoping could give me the const qualifier for the integers. If it helps at all, I'm using the getLocalFastQualifiers() function to return an unsigned int, and I'm seeing if 0x1 is masked for constness.

Since arrays can't really have qualifiers(the only example I see is on the standards for function parameters for C99 and not C++), was there a reason for why clang decided to put the qualifiers on the array qualtype rather than the elements' qualtype?

If I made any unreasonable assumptions to reach this conclusion, please let me know :)

Best,
Ray

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Why qualifiers for array elements on the array itself?

Manas via cfe-dev
On Fri, Oct 9, 2020 at 4:23 AM Ray Zhang via cfe-dev
<[hidden email]> wrote:

>
> Hi,
>
> I'm currently working on a clang cast tool and ran into a small oddity. This might be a stupid mistake but I'd love some pointers(no pun intended) or insight into it:
>
> const int arr[2] {1,2};
>
> should be "an array of fixed size 2 of constant integers". The QualType associated with arr is an array type, and we can observe that with Expr->isArrayType(). I checked the qualifiers and found that the qualifier for const is actually on this level, and not for the individual elements of ints. I found the elements inside of the array with the following:
>
> const ArrayType* ArrType = dyn_cast<ArrayType>(MyQualType);
> ArrType->getElementType();
>
> which I was hoping could give me the const qualifier for the integers. If it helps at all, I'm using the getLocalFastQualifiers() function to return an unsigned int, and I'm seeing if 0x1 is masked for constness.
>
> Since arrays can't really have qualifiers(the only example I see is on the standards for function parameters for C99 and not C++), was there a reason for why clang decided to put the qualifiers on the array qualtype rather than the elements' qualtype?

In C++, the array and its elements are both qualified per
http://eel.is/c++draft/dcl.array#5 and
http://eel.is/c++draft/basic.type.qualifier#3. (Note, this is
different than in C where the array type should be unqualified and the
element type qualified per C17 6.7.3p10.)

Rather than getLocalFastQualifiers(), I think you want to check
isConstQualified() to check the canonical type as well as the local
qualifiers.

~Aaron

> If I made any unreasonable assumptions to reach this conclusion, please let me know :)
>
> Best,
> Ray
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Why qualifiers for array elements on the array itself?

Manas via cfe-dev
In reply to this post by Manas via cfe-dev

The reason it’s represented this way is to preserve the source as written.  Suppose you have something like the following:

 

typedef int a[10];

typedef const a b;

 

We want to preserve the TypedefType, so the const has to stay outside it.

 

Because of this, you usually want to use ASTContext:: getAsArrayType(), not dyn_cast<ArrayType>(MyQualType).  The ASTContext method will rewrite the element type so it has the right qualifiers.

 

-Eli

 

From: cfe-dev <[hidden email]> On Behalf Of Ray Zhang via cfe-dev
Sent: Friday, October 9, 2020 1:23 AM
To: Clang Dev <[hidden email]>
Subject: [EXT] [cfe-dev] Why qualifiers for array elements on the array itself?

 

Hi,

 

I'm currently working on a clang cast tool and ran into a small oddity. This might be a stupid mistake but I'd love some pointers(no pun intended) or insight into it:

 

const int arr[2] {1,2};

 

should be "an array of fixed size 2 of constant integers". The QualType associated with arr is an array type, and we can observe that with Expr->isArrayType(). I checked the qualifiers and found that the qualifier for const is actually on this level, and not for the individual elements of ints. I found the elements inside of the array with the following:

 

const ArrayType* ArrType = dyn_cast<ArrayType>(MyQualType);

ArrType->getElementType();

 

which I was hoping could give me the const qualifier for the integers. If it helps at all, I'm using the getLocalFastQualifiers() function to return an unsigned int, and I'm seeing if 0x1 is masked for constness.

 

Since arrays can't really have qualifiers(the only example I see is on the standards for function parameters for C99 and not C++), was there a reason for why clang decided to put the qualifiers on the array qualtype rather than the elements' qualtype?

 

If I made any unreasonable assumptions to reach this conclusion, please let me know :)

 

Best,

Ray


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Why qualifiers for array elements on the array itself?

Manas via cfe-dev
Hi Eli and Aaron,

Thank you for your help! This makes a lot of sense, and thank you for citing the standard :). For pointer types I used dyn_cast (and so far it's been working well) and so in my opinion the getAsArrayType() function seems a bit of an unintuitive edge case (but I'm sure there were justifiable reasons for it). For anyone who might run into this issue in the future, if you perform dyn_cast instead of getAsArrayType(), the qualifiers on the elements will be dropped.

Thanks!
Ray

On Fri, Oct 9, 2020 at 1:02 PM Eli Friedman <[hidden email]> wrote:

The reason it’s represented this way is to preserve the source as written.  Suppose you have something like the following:

 

typedef int a[10];

typedef const a b;

 

We want to preserve the TypedefType, so the const has to stay outside it.

 

Because of this, you usually want to use ASTContext:: getAsArrayType(), not dyn_cast<ArrayType>(MyQualType).  The ASTContext method will rewrite the element type so it has the right qualifiers.

 

-Eli

 

From: cfe-dev <[hidden email]> On Behalf Of Ray Zhang via cfe-dev
Sent: Friday, October 9, 2020 1:23 AM
To: Clang Dev <[hidden email]>
Subject: [EXT] [cfe-dev] Why qualifiers for array elements on the array itself?

 

Hi,

 

I'm currently working on a clang cast tool and ran into a small oddity. This might be a stupid mistake but I'd love some pointers(no pun intended) or insight into it:

 

const int arr[2] {1,2};

 

should be "an array of fixed size 2 of constant integers". The QualType associated with arr is an array type, and we can observe that with Expr->isArrayType(). I checked the qualifiers and found that the qualifier for const is actually on this level, and not for the individual elements of ints. I found the elements inside of the array with the following:

 

const ArrayType* ArrType = dyn_cast<ArrayType>(MyQualType);

ArrType->getElementType();

 

which I was hoping could give me the const qualifier for the integers. If it helps at all, I'm using the getLocalFastQualifiers() function to return an unsigned int, and I'm seeing if 0x1 is masked for constness.

 

Since arrays can't really have qualifiers(the only example I see is on the standards for function parameters for C99 and not C++), was there a reason for why clang decided to put the qualifiers on the array qualtype rather than the elements' qualtype?

 

If I made any unreasonable assumptions to reach this conclusion, please let me know :)

 

Best,

Ray


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev