From: Aaron Ballman Date: Tue, 24 Mar 2015 15:07:53 +0000 (+0000) Subject: Track the source location of the dot or arrow operator in a MemberExpr. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=480b111b1722545287d12907b79f40002b87c3c1;p=clang Track the source location of the dot or arrow operator in a MemberExpr. Patch by Joe Ranieri! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@233085 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index c8f121bc19..097605fa25 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -2325,6 +2325,9 @@ class MemberExpr : public Expr { /// MemberLoc - This is the location of the member name. SourceLocation MemberLoc; + /// This is the location of the -> or . in the expression. + SourceLocation OperatorLoc; + /// IsArrow - True if this is "X->F", false if this is "X.F". bool IsArrow : 1; @@ -2359,18 +2362,16 @@ class MemberExpr : public Expr { } public: - MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, - const DeclarationNameInfo &NameInfo, QualType ty, - ExprValueKind VK, ExprObjectKind OK) - : Expr(MemberExprClass, ty, VK, OK, - base->isTypeDependent(), - base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()), - MemberLoc(NameInfo.getLoc()), IsArrow(isarrow), - HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), - HadMultipleCandidates(false) { + MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc, + ValueDecl *memberdecl, const DeclarationNameInfo &NameInfo, + QualType ty, ExprValueKind VK, ExprObjectKind OK) + : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), + base->isValueDependent(), base->isInstantiationDependent(), + base->containsUnexpandedParameterPack()), + Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()), + MemberLoc(NameInfo.getLoc()), OperatorLoc(operatorloc), + IsArrow(isarrow), HasQualifierOrFoundDecl(false), + HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) { assert(memberdecl->getDeclName() == NameInfo.getName()); } @@ -2378,25 +2379,25 @@ public: // the member name can not provide additional syntactic info // (i.e., source locations for C++ operator names or type source info // for constructors, destructors and conversion operators). - MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, - SourceLocation l, QualType ty, + MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc, + ValueDecl *memberdecl, SourceLocation l, QualType ty, ExprValueKind VK, ExprObjectKind OK) - : Expr(MemberExprClass, ty, VK, OK, - base->isTypeDependent(), base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l), - IsArrow(isarrow), - HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), - HadMultipleCandidates(false) {} + : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), + base->isValueDependent(), base->isInstantiationDependent(), + base->containsUnexpandedParameterPack()), + Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l), + OperatorLoc(operatorloc), IsArrow(isarrow), + HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), + HadMultipleCandidates(false) {} static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow, + SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - ValueDecl *memberdecl, DeclAccessPair founddecl, + SourceLocation TemplateKWLoc, ValueDecl *memberdecl, + DeclAccessPair founddecl, DeclarationNameInfo MemberNameInfo, - const TemplateArgumentListInfo *targs, - QualType ty, ExprValueKind VK, ExprObjectKind OK); + const TemplateArgumentListInfo *targs, QualType ty, + ExprValueKind VK, ExprObjectKind OK); void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast(Base); } @@ -2540,6 +2541,8 @@ public: MemberLoc, MemberDNLoc); } + SourceLocation getOperatorLoc() const LLVM_READONLY { return OperatorLoc; } + bool isArrow() const { return IsArrow; } void setArrow(bool A) { IsArrow = A; } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 8006d2be3c..d13a11c4a3 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1376,16 +1376,12 @@ UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr( } } -MemberExpr *MemberExpr::Create(const ASTContext &C, Expr *base, bool isarrow, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - ValueDecl *memberdecl, - DeclAccessPair founddecl, - DeclarationNameInfo nameinfo, - const TemplateArgumentListInfo *targs, - QualType ty, - ExprValueKind vk, - ExprObjectKind ok) { +MemberExpr *MemberExpr::Create( + const ASTContext &C, Expr *base, bool isarrow, SourceLocation OperatorLoc, + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, + ValueDecl *memberdecl, DeclAccessPair founddecl, + DeclarationNameInfo nameinfo, const TemplateArgumentListInfo *targs, + QualType ty, ExprValueKind vk, ExprObjectKind ok) { std::size_t Size = sizeof(MemberExpr); bool hasQualOrFound = (QualifierLoc || @@ -1400,8 +1396,8 @@ MemberExpr *MemberExpr::Create(const ASTContext &C, Expr *base, bool isarrow, Size += ASTTemplateKWAndArgsInfo::sizeFor(0); void *Mem = C.Allocate(Size, llvm::alignOf()); - MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo, - ty, vk, ok); + MemberExpr *E = new (Mem) + MemberExpr(base, isarrow, OperatorLoc, memberdecl, nameinfo, ty, vk, ok); if (hasQualOrFound) { // FIXME: Wrong. We should be looking at the member declaration we found. diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp index 47f8189f23..12c57cdced 100644 --- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -886,15 +886,15 @@ RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) { FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get(D->getNameAsString()), - IvarT, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), - FD->getType(), VK_LValue, - OK_Ordinary); - IvarT = Context->getDecltypeType(ME, ME->getType()); - } - } + IvarT, nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/true, + ICIS_NoInit); + MemberExpr *ME = new (Context) + MemberExpr(PE, true, SourceLocation(), FD, SourceLocation(), + FD->getType(), VK_LValue, OK_Ordinary); + IvarT = Context->getDecltypeType(ME, ME->getType()); + } + } convertObjCTypeToCStyleType(IvarT); QualType castT = Context->getPointerType(IvarT); std::string TypeString(castT.getAsString(Context->getPrintingPolicy())); @@ -2764,17 +2764,15 @@ Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) { FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get("arr"), - Context->getPointerType(Context->VoidPtrTy), - nullptr, /*BitWidth=*/nullptr, - /*Mutable=*/true, ICIS_NoInit); - MemberExpr *ArrayLiteralME = - new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD, - SourceLocation(), - ARRFD->getType(), VK_LValue, - OK_Ordinary); - QualType ConstIdT = Context->getObjCIdType().withConst(); - CStyleCastExpr * ArrayLiteralObjects = - NoTypeInfoCStyleCastExpr(Context, + Context->getPointerType(Context->VoidPtrTy), + nullptr, /*BitWidth=*/nullptr, + /*Mutable=*/true, ICIS_NoInit); + MemberExpr *ArrayLiteralME = new (Context) + MemberExpr(NSArrayCallExpr, false, SourceLocation(), ARRFD, + SourceLocation(), ARRFD->getType(), VK_LValue, OK_Ordinary); + QualType ConstIdT = Context->getObjCIdType().withConst(); + CStyleCastExpr * ArrayLiteralObjects = + NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(ConstIdT), CK_BitCast, ArrayLiteralME); @@ -2901,34 +2899,30 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get("arr"), - Context->getPointerType(Context->VoidPtrTy), - nullptr, /*BitWidth=*/nullptr, - /*Mutable=*/true, ICIS_NoInit); - MemberExpr *DictLiteralValueME = - new (Context) MemberExpr(NSValueCallExpr, false, ARRFD, - SourceLocation(), - ARRFD->getType(), VK_LValue, - OK_Ordinary); - QualType ConstIdT = Context->getObjCIdType().withConst(); - CStyleCastExpr * DictValueObjects = - NoTypeInfoCStyleCastExpr(Context, + Context->getPointerType(Context->VoidPtrTy), + nullptr, /*BitWidth=*/nullptr, + /*Mutable=*/true, ICIS_NoInit); + MemberExpr *DictLiteralValueME = new (Context) + MemberExpr(NSValueCallExpr, false, SourceLocation(), ARRFD, + SourceLocation(), ARRFD->getType(), VK_LValue, OK_Ordinary); + QualType ConstIdT = Context->getObjCIdType().withConst(); + CStyleCastExpr * DictValueObjects = + NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(ConstIdT), CK_BitCast, DictLiteralValueME); // (const id [])keys - Expr *NSKeyCallExpr = - new (Context) CallExpr(*Context, NSDictDRE, KeyExprs, - NSDictFType, VK_LValue, SourceLocation()); - - MemberExpr *DictLiteralKeyME = - new (Context) MemberExpr(NSKeyCallExpr, false, ARRFD, - SourceLocation(), - ARRFD->getType(), VK_LValue, - OK_Ordinary); - - CStyleCastExpr * DictKeyObjects = - NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(ConstIdT), + Expr *NSKeyCallExpr = + new (Context) CallExpr(*Context, NSDictDRE, KeyExprs, + NSDictFType, VK_LValue, SourceLocation()); + + MemberExpr *DictLiteralKeyME = new (Context) + MemberExpr(NSKeyCallExpr, false, SourceLocation(), ARRFD, + SourceLocation(), ARRFD->getType(), VK_LValue, OK_Ordinary); + + CStyleCastExpr * DictKeyObjects = + NoTypeInfoCStyleCastExpr(Context, + Context->getPointerType(ConstIdT), CK_BitCast, DictLiteralKeyME); @@ -3231,15 +3225,15 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla FieldDecl *FieldD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get("s"), - returnType, nullptr, - /*BitWidth=*/nullptr, - /*Mutable=*/true, ICIS_NoInit); - MemberExpr *ME = new (Context) MemberExpr(STCE, false, FieldD, SourceLocation(), - FieldD->getType(), VK_LValue, - OK_Ordinary); - - return ME; -} + returnType, nullptr, + /*BitWidth=*/nullptr, + /*Mutable=*/true, ICIS_NoInit); + MemberExpr *ME = new (Context) + MemberExpr(STCE, false, SourceLocation(), FieldD, SourceLocation(), + FieldD->getType(), VK_LValue, OK_Ordinary); + + return ME; +} Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SourceLocation StartLoc, @@ -4729,17 +4723,16 @@ Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get("FuncPtr"), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), - FD->getType(), VK_LValue, - OK_Ordinary); - - - CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, - CK_BitCast, ME); - PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); + Context->VoidPtrTy, nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/true, + ICIS_NoInit); + MemberExpr *ME = + new (Context) MemberExpr(PE, true, SourceLocation(), FD, SourceLocation(), + FD->getType(), VK_LValue, OK_Ordinary); + + CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, + CK_BitCast, ME); + PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); SmallVector BlkExprs; // Add the implicit argument. @@ -4778,28 +4771,26 @@ Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get("__forwarding"), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow, - FD, SourceLocation(), - FD->getType(), VK_LValue, - OK_Ordinary); - - StringRef Name = VD->getName(); - FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), + Context->VoidPtrTy, nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/true, + ICIS_NoInit); + MemberExpr *ME = new (Context) + MemberExpr(DeclRefExp, isArrow, SourceLocation(), FD, SourceLocation(), + FD->getType(), VK_LValue, OK_Ordinary); + + StringRef Name = VD->getName(); + FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get(Name), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(), - DeclRefExp->getType(), VK_LValue, OK_Ordinary); - - - - // Need parens to enforce precedence. - ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), - DeclRefExp->getExprLoc(), + Context->VoidPtrTy, nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/true, + ICIS_NoInit); + ME = + new (Context) MemberExpr(ME, true, SourceLocation(), FD, SourceLocation(), + DeclRefExp->getType(), VK_LValue, OK_Ordinary); + + // Need parens to enforce precedence. + ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), + DeclRefExp->getExprLoc(), ME); ReplaceStmt(DeclRefExp, PE); return PE; @@ -7691,15 +7682,15 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get(D->getNameAsString()), - IvarT, nullptr, - /*BitWidth=*/nullptr, - /*Mutable=*/true, ICIS_NoInit); - MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), - FD->getType(), VK_LValue, - OK_Ordinary); - IvarT = Context->getDecltypeType(ME, ME->getType()); - } - } + IvarT, nullptr, + /*BitWidth=*/nullptr, + /*Mutable=*/true, ICIS_NoInit); + MemberExpr *ME = new (Context) + MemberExpr(PE, true, SourceLocation(), FD, SourceLocation(), + FD->getType(), VK_LValue, OK_Ordinary); + IvarT = Context->getDecltypeType(ME, ME->getType()); + } + } convertObjCTypeToCStyleType(IvarT); QualType castT = Context->getPointerType(IvarT); @@ -7720,15 +7711,15 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get(D->getNameAsString()), - D->getType(), nullptr, - /*BitWidth=*/D->getBitWidth(), - /*Mutable=*/true, ICIS_NoInit); - MemberExpr *ME = new (Context) MemberExpr(PE, /*isArrow*/false, FD, SourceLocation(), - FD->getType(), VK_LValue, - OK_Ordinary); - Replacement = ME; - - } + D->getType(), nullptr, + /*BitWidth=*/D->getBitWidth(), + /*Mutable=*/true, ICIS_NoInit); + MemberExpr *ME = new (Context) + MemberExpr(PE, /*isArrow*/ false, SourceLocation(), FD, + SourceLocation(), FD->getType(), VK_LValue, OK_Ordinary); + Replacement = ME; + + } else Replacement = PE; } diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp index 519681085f..5802ba7784 100644 --- a/lib/Frontend/Rewrite/RewriteObjC.cpp +++ b/lib/Frontend/Rewrite/RewriteObjC.cpp @@ -3818,17 +3818,16 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get("FuncPtr"), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), - FD->getType(), VK_LValue, - OK_Ordinary); - - - CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, - CK_BitCast, ME); - PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); + Context->VoidPtrTy, nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/true, + ICIS_NoInit); + MemberExpr *ME = + new (Context) MemberExpr(PE, true, SourceLocation(), FD, SourceLocation(), + FD->getType(), VK_LValue, OK_Ordinary); + + CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, + CK_BitCast, ME); + PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); SmallVector BlkExprs; // Add the implicit argument. @@ -3867,28 +3866,26 @@ Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get("__forwarding"), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow, - FD, SourceLocation(), - FD->getType(), VK_LValue, - OK_Ordinary); - - StringRef Name = VD->getName(); - FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), + Context->VoidPtrTy, nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/true, + ICIS_NoInit); + MemberExpr *ME = new (Context) + MemberExpr(DeclRefExp, isArrow, SourceLocation(), FD, SourceLocation(), + FD->getType(), VK_LValue, OK_Ordinary); + + StringRef Name = VD->getName(); + FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), &Context->Idents.get(Name), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(), - DeclRefExp->getType(), VK_LValue, OK_Ordinary); - - - - // Need parens to enforce precedence. - ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), - DeclRefExp->getExprLoc(), + Context->VoidPtrTy, nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/true, + ICIS_NoInit); + ME = + new (Context) MemberExpr(ME, true, SourceLocation(), FD, SourceLocation(), + DeclRefExp->getType(), VK_LValue, OK_Ordinary); + + // Need parens to enforce precedence. + ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), + DeclRefExp->getExprLoc(), ME); ReplaceStmt(DeclRefExp, PE); return PE; @@ -5877,16 +5874,15 @@ Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { // Don't forget the parens to enforce the proper binding. ParenExpr *PE = new (Context) ParenExpr(OldRange.getBegin(), OldRange.getEnd(), - castExpr); - if (IV->isFreeIvar() && - declaresSameEntity(CurMethodDef->getClassInterface(), iFaceDecl->getDecl())) { - MemberExpr *ME = new (Context) MemberExpr(PE, true, D, - IV->getLocation(), - D->getType(), - VK_LValue, OK_Ordinary); - Replacement = ME; - } else { - IV->setBase(PE); + castExpr); + if (IV->isFreeIvar() && + declaresSameEntity(CurMethodDef->getClassInterface(), iFaceDecl->getDecl())) { + MemberExpr *ME = new (Context) + MemberExpr(PE, true, SourceLocation(), D, IV->getLocation(), + D->getType(), VK_LValue, OK_Ordinary); + Replacement = ME; + } else { + IV->setBase(PE); } } } else { // we are outside a method. diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index bdd92c041c..5c43e0cd9c 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -5771,10 +5771,9 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, if (Exp.isInvalid()) return true; - MemberExpr *ME = - new (Context) MemberExpr(Exp.get(), /*IsArrow=*/false, Method, - SourceLocation(), Context.BoundMemberTy, - VK_RValue, OK_Ordinary); + MemberExpr *ME = new (Context) MemberExpr( + Exp.get(), /*IsArrow=*/false, SourceLocation(), Method, SourceLocation(), + Context.BoundMemberTy, VK_RValue, OK_Ordinary); if (HadMultipleCandidates) ME->setHadMultipleCandidates(true); MarkMemberReferenced(ME); diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 002c823e3a..b3efa70b43 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -732,8 +732,8 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, static ExprResult BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow, - const CXXScopeSpec &SS, FieldDecl *Field, - DeclAccessPair FoundDecl, + SourceLocation OpLoc, const CXXScopeSpec &SS, + FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo); ExprResult @@ -820,10 +820,10 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, // Make a nameInfo that properly uses the anonymous name. DeclarationNameInfo memberNameInfo(field->getDeclName(), loc); - + result = BuildFieldReferenceExpr(*this, result, baseObjectIsPointer, - EmptySS, field, foundDecl, - memberNameInfo).get(); + SourceLocation(), EmptySS, field, + foundDecl, memberNameInfo).get(); if (!result) return ExprError(); @@ -841,9 +841,10 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, DeclAccessPair fakeFoundDecl = DeclAccessPair::make(field, field->getAccess()); - result = BuildFieldReferenceExpr(*this, result, /*isarrow*/ false, - (FI == FEnd? SS : EmptySS), field, - fakeFoundDecl, memberNameInfo).get(); + result = + BuildFieldReferenceExpr(*this, result, /*isarrow*/ false, + SourceLocation(), (FI == FEnd ? SS : EmptySS), + field, fakeFoundDecl, memberNameInfo).get(); } return result; @@ -863,18 +864,16 @@ BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow, } /// \brief Build a MemberExpr AST node. -static MemberExpr * -BuildMemberExpr(Sema &SemaRef, ASTContext &C, Expr *Base, bool isArrow, - const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, - ValueDecl *Member, DeclAccessPair FoundDecl, - const DeclarationNameInfo &MemberNameInfo, QualType Ty, - ExprValueKind VK, ExprObjectKind OK, - const TemplateArgumentListInfo *TemplateArgs = nullptr) { +static MemberExpr *BuildMemberExpr( + Sema &SemaRef, ASTContext &C, Expr *Base, bool isArrow, + SourceLocation OpLoc, const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, + ValueDecl *Member, DeclAccessPair FoundDecl, + const DeclarationNameInfo &MemberNameInfo, QualType Ty, ExprValueKind VK, + ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs = nullptr) { assert((!isArrow || Base->isRValue()) && "-> base must be a pointer rvalue"); - MemberExpr *E = - MemberExpr::Create(C, Base, isArrow, SS.getWithLocInContext(C), - TemplateKWLoc, Member, FoundDecl, MemberNameInfo, - TemplateArgs, Ty, VK, OK); + MemberExpr *E = MemberExpr::Create( + C, Base, isArrow, OpLoc, SS.getWithLocInContext(C), TemplateKWLoc, Member, + FoundDecl, MemberNameInfo, TemplateArgs, Ty, VK, OK); SemaRef.MarkMemberReferenced(E); return E; } @@ -1057,8 +1056,8 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, return ExprError(); if (FieldDecl *FD = dyn_cast(MemberDecl)) - return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow, - SS, FD, FoundDecl, MemberNameInfo); + return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow, OpLoc, SS, FD, + FoundDecl, MemberNameInfo); if (MSPropertyDecl *PD = dyn_cast(MemberDecl)) return BuildMSPropertyRefExpr(*this, BaseExpr, IsArrow, SS, PD, @@ -1072,8 +1071,8 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, OpLoc); if (VarDecl *Var = dyn_cast(MemberDecl)) { - return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc, - Var, FoundDecl, MemberNameInfo, + return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS, + TemplateKWLoc, Var, FoundDecl, MemberNameInfo, Var->getType().getNonReferenceType(), VK_LValue, OK_Ordinary); } @@ -1089,16 +1088,16 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, type = MemberFn->getType(); } - return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc, - MemberFn, FoundDecl, MemberNameInfo, type, valueKind, - OK_Ordinary); + return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS, + TemplateKWLoc, MemberFn, FoundDecl, MemberNameInfo, + type, valueKind, OK_Ordinary); } assert(!isa(MemberDecl) && "member function not C++ method?"); if (EnumConstantDecl *Enum = dyn_cast(MemberDecl)) { - return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc, - Enum, FoundDecl, MemberNameInfo, Enum->getType(), - VK_RValue, OK_Ordinary); + return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS, + TemplateKWLoc, Enum, FoundDecl, MemberNameInfo, + Enum->getType(), VK_RValue, OK_Ordinary); } // We found something that we didn't expect. Complain. @@ -1643,8 +1642,8 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, static ExprResult BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow, - const CXXScopeSpec &SS, FieldDecl *Field, - DeclAccessPair FoundDecl, + SourceLocation OpLoc, const CXXScopeSpec &SS, + FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo) { // x.a is an l-value if 'a' has a reference type. Otherwise: // x.a is an l-value/x-value/pr-value if the base is (and note @@ -1697,7 +1696,7 @@ BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow, FoundDecl, Field); if (Base.isInvalid()) return ExprError(); - return BuildMemberExpr(S, S.Context, Base.get(), IsArrow, SS, + return BuildMemberExpr(S, S.Context, Base.get(), IsArrow, OpLoc, SS, /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl, MemberNameInfo, MemberType, VK, OK); } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 469787606f..77c5310aa4 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -12485,21 +12485,17 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, type = Fn->getType(); } else { valueKind = VK_RValue; - type = Context.BoundMemberTy; - } - - MemberExpr *ME = MemberExpr::Create(Context, Base, - MemExpr->isArrow(), - MemExpr->getQualifierLoc(), - MemExpr->getTemplateKeywordLoc(), - Fn, - Found, - MemExpr->getMemberNameInfo(), - TemplateArgs, - type, valueKind, OK_Ordinary); - ME->setHadMultipleCandidates(true); - MarkMemberReferenced(ME); - return ME; + type = Context.BoundMemberTy; + } + + MemberExpr *ME = MemberExpr::Create( + Context, Base, MemExpr->isArrow(), MemExpr->getOperatorLoc(), + MemExpr->getQualifierLoc(), MemExpr->getTemplateKeywordLoc(), Fn, Found, + MemExpr->getMemberNameInfo(), TemplateArgs, type, valueKind, + OK_Ordinary); + ME->setHadMultipleCandidates(true); + MarkMemberReferenced(ME); + return ME; } llvm_unreachable("Invalid reference to overloaded function"); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 351dacd256..1b0080a05f 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1870,11 +1870,9 @@ public: return ExprError(); Base = BaseResult.get(); ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind(); - MemberExpr *ME = - new (getSema().Context) MemberExpr(Base, isArrow, - Member, MemberNameInfo, - cast(Member)->getType(), - VK, OK_Ordinary); + MemberExpr *ME = new (getSema().Context) + MemberExpr(Base, isArrow, OpLoc, Member, MemberNameInfo, + cast(Member)->getType(), VK, OK_Ordinary); return ME; } diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 216764f19e..c7b49dee2e 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -2447,17 +2447,18 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { ExprObjectKind OK = static_cast(Record[Idx++]); Expr *Base = ReadSubExpr(); ValueDecl *MemberD = ReadDeclAs(F, Record, Idx); - SourceLocation MemberLoc = ReadSourceLocation(F, Record, Idx); - DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc); - bool IsArrow = Record[Idx++]; - - S = MemberExpr::Create(Context, Base, IsArrow, QualifierLoc, - TemplateKWLoc, MemberD, FoundDecl, MemberNameInfo, - HasTemplateKWAndArgsInfo ? &ArgInfo : nullptr, - T, VK, OK); - ReadDeclarationNameLoc(F, cast(S)->MemberDNLoc, - MemberD->getDeclName(), Record, Idx); - if (HadMultipleCandidates) + SourceLocation MemberLoc = ReadSourceLocation(F, Record, Idx); + DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc); + bool IsArrow = Record[Idx++]; + SourceLocation OperatorLoc = ReadSourceLocation(F, Record, Idx); + + S = MemberExpr::Create(Context, Base, IsArrow, OperatorLoc, QualifierLoc, + TemplateKWLoc, MemberD, FoundDecl, MemberNameInfo, + HasTemplateKWAndArgsInfo ? &ArgInfo : nullptr, T, + VK, OK); + ReadDeclarationNameLoc(F, cast(S)->MemberDNLoc, + MemberD->getDeclName(), Record, Idx); + if (HadMultipleCandidates) cast(S)->setHadMultipleCandidates(true); break; } diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index cf0314a4b1..6e647c3195 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -550,12 +550,13 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { Record.push_back(E->getValueKind()); Record.push_back(E->getObjectKind()); Writer.AddStmt(E->getBase()); - Writer.AddDeclRef(E->getMemberDecl(), Record); - Writer.AddSourceLocation(E->getMemberLoc(), Record); - Record.push_back(E->isArrow()); - Writer.AddDeclarationNameLoc(E->MemberDNLoc, - E->getMemberDecl()->getDeclName(), Record); - Code = serialization::EXPR_MEMBER; + Writer.AddDeclRef(E->getMemberDecl(), Record); + Writer.AddSourceLocation(E->getMemberLoc(), Record); + Record.push_back(E->isArrow()); + Writer.AddSourceLocation(E->getOperatorLoc(), Record); + Writer.AddDeclarationNameLoc(E->MemberDNLoc, + E->getMemberDecl()->getDeclName(), Record); + Code = serialization::EXPR_MEMBER; } void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) { diff --git a/unittests/AST/SourceLocationTest.cpp b/unittests/AST/SourceLocationTest.cpp index 98460d959c..c1f7b18143 100644 --- a/unittests/AST/SourceLocationTest.cpp +++ b/unittests/AST/SourceLocationTest.cpp @@ -106,12 +106,44 @@ TEST(MemberExpr, ImplicitMemberRange) { Verifier.expectRange(2, 30, 2, 30); EXPECT_TRUE(Verifier.match("struct S { operator int() const; };\n" "int foo(const S& s) { return s; }", - memberExpr())); -} - -TEST(VarDecl, VMTypeFixedVarDeclRange) { - RangeVerifier Verifier; - Verifier.expectRange(1, 1, 1, 23); + memberExpr())); +} + +class MemberExprArrowLocVerifier : public RangeVerifier { +protected: + virtual SourceRange getRange(const MemberExpr &Node) { + return Node.getOperatorLoc(); + } +}; + +TEST(MemberExpr, ArrowRange) { + MemberExprArrowLocVerifier Verifier; + Verifier.expectRange(2, 19, 2, 19); + EXPECT_TRUE(Verifier.match("struct S { int x; };\n" + "void foo(S *s) { s->x = 0; }", + memberExpr())); +} + +TEST(MemberExpr, MacroArrowRange) { + MemberExprArrowLocVerifier Verifier; + Verifier.expectRange(1, 24, 1, 24); + EXPECT_TRUE(Verifier.match("#define MEMBER(a, b) (a->b)\n" + "struct S { int x; };\n" + "void foo(S *s) { MEMBER(s, x) = 0; }", + memberExpr())); +} + +TEST(MemberExpr, ImplicitArrowRange) { + MemberExprArrowLocVerifier Verifier; + Verifier.expectRange(0, 0, 0, 0); + EXPECT_TRUE(Verifier.match("struct S { int x; void Test(); };\n" + "void S::Test() { x = 1; }", + memberExpr())); +} + +TEST(VarDecl, VMTypeFixedVarDeclRange) { + RangeVerifier Verifier; + Verifier.expectRange(1, 1, 1, 23); EXPECT_TRUE(Verifier.match("int a[(int)(void*)1234];", varDecl(), Lang_C89)); }