[cfe-dev] Member expression returns type with wrong qualifiers

Steve Naroff snaroff at apple.com
Mon Feb 4 17:54:22 PST 2008


On Feb 4, 2008, at 5:44 PM, Eli Friedman wrote:

> On Feb 4, 2008 4:51 PM, Steve Naroff <snaroff at apple.com> wrote:
>> O.K. Here's a crazy idea...have you considered turning...
>>
>> const struct whatever { int a; };
>>
>> ...into...
>>
>> const struct whatever { const int a; };
>>
>> In other words, pass down the const-ness to ActOnField()? Then the
>> qualifiers could be added to all the FieldDecls...
>>
>> The only downside is distinguishing between "implicit/inherited"
>> qualifiers from qualifiers that are explicit in the source (but that
>> can obviously be fixed by saving the original type, if necessary).
>>
>> This declaration-centric solution has some appeal...MemberExpr/Expr
>> wouldn't need to change.
>>
>> snaroff
>
> Possible, I suppose, but it seems complicated to deal with stuff like
> type compatibility.  Also, probably a bigger issue, it would make
> getUnqualifiedType more expensive.  This would also be throwing out
> the other advantages of QualType's for structs.  I'll have to think
> about it a bit more, though.
>
> Below is something closer to my original line of thought; it's a lot
> shorter than anything involving messing with types.  It's not
> especially clean, but it works for all cases.  (Some extra code will
> be required to deal with address spaces, though.)
>
> The other possibility I was considering was making MemberExpr
> serialize their type, and then moving this logic into sema.
>

The code below looks good.

I think it would be a bit cleaner to fold the getTypeForMemberExpr()  
logic into Sema::ActOnMemberReferenceExpr() and pass in the derived  
type explicitly (just add an argument to the constructor). Passing the  
type in explicitly is more consistent with all the other expr AST's.

snaroff

> -Eli
>
> Index: include/clang/AST/Expr.h
> ===================================================================
> --- include/clang/AST/Expr.h    (revision 46693)
> +++ include/clang/AST/Expr.h    (working copy)
> @@ -651,9 +651,19 @@
>   bool IsArrow;      // True if this is "X->F", false if this is  
> "X.F".
> public:
>   MemberExpr(Expr *base, bool isarrow, FieldDecl *memberdecl,
> SourceLocation l)
> -    : Expr(MemberExprClass, memberdecl->getType()),
> +    : Expr(MemberExprClass, getTypeForMemberExpr(base, memberdecl,  
> isarrow)),
>       Base(base), MemberDecl(memberdecl), MemberLoc(l),  
> IsArrow(isarrow) {}
> -
> +
> +  static QualType getTypeForMemberExpr(Expr* base, FieldDecl *  
> member,
> +                                       bool isArrow) {
> +    QualType baseTy = base->getType();
> +    if (isArrow)
> +      baseTy = baseTy->getAsPointerType()->getPointeeType();
> +    QualType memberTy = member->getType();
> +    return QualType(memberTy.getTypePtr(),
> +                    baseTy.getQualifiers() |  
> memberTy.getQualifiers());
> +  }
> +
>   Expr *getBase() const { return Base; }
>   FieldDecl *getMemberDecl() const { return MemberDecl; }
>   bool isArrow() const { return IsArrow; }




More information about the cfe-dev mailing list