[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