From: Fariborz Jahanian Date: Wed, 29 Jul 2009 18:40:24 +0000 (+0000) Subject: Patch to provide cast of objects in member access X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=98a541e80848d3b7d1131237ac04e698faffd151;p=clang Patch to provide cast of objects in member access excpression, if needed, and remove some ir-gen code now unnencessary. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77490 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 39ef799cd3..bf3a0ae8c6 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -993,13 +993,6 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { if (PTy->getPointeeType()->isUnionType()) isUnion = true; CVRQualifiers = PTy->getPointeeType().getCVRQualifiers(); - if (const CXXRecordDecl *ClassDecl = - BaseExpr->getType()->getCXXRecordDeclForPointerType()) { - FieldDecl *Field = dyn_cast(E->getMemberDecl()); - if (const CXXRecordDecl *BaseClassDecl = - dyn_cast(Field->getDeclContext())) - BaseValue = AddressCXXOfBaseClass(BaseValue, ClassDecl, BaseClassDecl); - } } else if (isa(BaseExpr) || isa(BaseExpr)) { RValue RV = EmitObjCPropertyGet(BaseExpr); @@ -1019,15 +1012,6 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { if (BaseTy->isUnionType()) isUnion = true; CVRQualifiers = BaseTy.getCVRQualifiers(); - if (const CXXRecordDecl *ClassDecl = - dyn_cast( - BaseTy->getAsRecordType()->getDecl())) { - FieldDecl *Field = dyn_cast(E->getMemberDecl()); - if (const CXXRecordDecl *BaseClassDecl = - dyn_cast(Field->getDeclContext())) - BaseValue = - AddressCXXOfBaseClass(BaseValue, ClassDecl, BaseClassDecl); - } } FieldDecl *Field = dyn_cast(E->getMemberDecl()); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 79ea3e1303..1a2c8217c9 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -690,6 +690,8 @@ public: ImplicitConversionSequence TryContextuallyConvertToBool(Expr *From); bool PerformContextuallyConvertToBool(Expr *&From); + + void PerformObjectMemberConversion(Expr *&From, NamedDecl *Member); /// OverloadingResult - Capture the result of performing overload /// resolution. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index f9abb3dbd9..6d2186325a 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1023,6 +1023,22 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, return BuildDeclarationNameExpr(Loc, D, HasTrailingLParen, SS, isAddressOfOperand); } +/// \brief Cast member's object to its own class if necessary. +void +Sema::PerformObjectMemberConversion(Expr *&From, NamedDecl *Member) { + if (FieldDecl *FD = dyn_cast(Member)) + if (CXXRecordDecl *RD = + dyn_cast(FD->getDeclContext())) { + QualType DestType = + Context.getCanonicalType(Context.getTypeDeclType(RD)); + if (!DestType->isDependentType() && + !From->getType()->isDependentType()) { + if (From->getType()->getAsPointerType()) + DestType = Context.getPointerType(DestType); + ImpCastExprToType(From, DestType, /*isLvalue=*/true); + } + } +} /// \brief Complete semantic analysis for a reference to the given declaration. Sema::OwningExprResult @@ -1114,6 +1130,7 @@ Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D, Expr *This = new (Context) CXXThisExpr(SourceLocation(), MD->getThisType(Context)); MarkDeclarationReferenced(Loc, D); + PerformObjectMemberConversion(This, D); return Owned(new (Context) MemberExpr(This, true, D, Loc, MemberType)); } @@ -2190,6 +2207,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, } MarkDeclarationReferenced(MemberLoc, FD); + PerformObjectMemberConversion(BaseExpr, FD); return Owned(new (Context) MemberExpr(BaseExpr, OpKind == tok::arrow, FD, MemberLoc, MemberType)); } diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp index c46a561c30..a9d5c289e2 100644 --- a/test/CodeGenCXX/constructor-init.cpp +++ b/test/CodeGenCXX/constructor-init.cpp @@ -38,8 +38,10 @@ struct N : M , P, Q { printf("iQ = %d\n", iQ); printf("iP = %d\n", iP); printf("iM = %d\n", iM); - printf("iQ = %d\n", (*this).iQ); - printf("iP = %d\n", ((*this)).iP); + // FIXME. We don't yet support this syntax. + // printf("iQ = %d\n", (*this).iQ); + printf("iQ = %d\n", this->iQ); + printf("iP = %d\n", this->iP); printf("iM = %d\n", this->iM); } float ld;