Track the source location of the dot or arrow operator in a MemberExpr.

Patch by Joe Ranieri!

llvm-svn: 233085
This commit is contained in:
Aaron Ballman 2015-03-24 15:07:53 +00:00
parent 667ef22920
commit f4cb2be05a
11 changed files with 274 additions and 262 deletions

View File

@ -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<Expr>(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; }

View File

@ -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>());
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.

View File

@ -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 <NSCopying> [])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<Expr*, 8> 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;
}

View File

@ -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<Expr*, 8> 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.

View File

@ -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);

View File

@ -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<FieldDecl>(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<MSPropertyDecl>(MemberDecl))
return BuildMSPropertyRefExpr(*this, BaseExpr, IsArrow, SS, PD,
@ -1072,8 +1071,8 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
OpLoc);
if (VarDecl *Var = dyn_cast<VarDecl>(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<FunctionDecl>(MemberDecl) && "member function not C++ method?");
if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(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);
}

View File

@ -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");

View File

@ -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<FieldDecl>(Member)->getType(),
VK, OK_Ordinary);
MemberExpr *ME = new (getSema().Context)
MemberExpr(Base, isArrow, OpLoc, Member, MemberNameInfo,
cast<FieldDecl>(Member)->getType(), VK, OK_Ordinary);
return ME;
}

View File

@ -2447,17 +2447,18 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
ExprObjectKind OK = static_cast<ExprObjectKind>(Record[Idx++]);
Expr *Base = ReadSubExpr();
ValueDecl *MemberD = ReadDeclAs<ValueDecl>(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<MemberExpr>(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<MemberExpr>(S)->MemberDNLoc,
MemberD->getDeclName(), Record, Idx);
if (HadMultipleCandidates)
cast<MemberExpr>(S)->setHadMultipleCandidates(true);
break;
}

View File

@ -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) {

View File

@ -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<VarDecl> Verifier;
Verifier.expectRange(1, 1, 1, 23);
memberExpr()));
}
class MemberExprArrowLocVerifier : public RangeVerifier<MemberExpr> {
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<VarDecl> Verifier;
Verifier.expectRange(1, 1, 1, 23);
EXPECT_TRUE(Verifier.match("int a[(int)(void*)1234];",
varDecl(), Lang_C89));
}