diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 18 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/constructor-init.cpp | 6 |
4 files changed, 24 insertions, 18 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 39ef799cd3e..bf3a0ae8c6c 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/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<FieldDecl>(E->getMemberDecl()); - if (const CXXRecordDecl *BaseClassDecl = - dyn_cast<CXXRecordDecl>(Field->getDeclContext())) - BaseValue = AddressCXXOfBaseClass(BaseValue, ClassDecl, BaseClassDecl); - } } else if (isa<ObjCPropertyRefExpr>(BaseExpr) || isa<ObjCKVCRefExpr>(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<CXXRecordDecl>( - BaseTy->getAsRecordType()->getDecl())) { - FieldDecl *Field = dyn_cast<FieldDecl>(E->getMemberDecl()); - if (const CXXRecordDecl *BaseClassDecl = - dyn_cast<CXXRecordDecl>(Field->getDeclContext())) - BaseValue = - AddressCXXOfBaseClass(BaseValue, ClassDecl, BaseClassDecl); - } } FieldDecl *Field = dyn_cast<FieldDecl>(E->getMemberDecl()); diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 79ea3e13030..1a2c8217c90 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f9abb3dbd93..6d2186325a6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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<FieldDecl>(Member)) + if (CXXRecordDecl *RD = + dyn_cast<CXXRecordDecl>(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/clang/test/CodeGenCXX/constructor-init.cpp b/clang/test/CodeGenCXX/constructor-init.cpp index c46a561c308..a9d5c289e26 100644 --- a/clang/test/CodeGenCXX/constructor-init.cpp +++ b/clang/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; |