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

Eli Friedman eli.friedman at gmail.com
Mon Feb 4 17:44:21 PST 2008

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.


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".
   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