Refactor: use the DeclarationNameInfo form of BuildMemberReferenceExpr

consistently, rather than sometimes performing lookup and calling the
LookupResult form. No functionality change intended.

llvm-svn: 209941
This commit is contained in:
Richard Smith 2014-05-31 00:18:32 +00:00
parent 5c8ce21a6c
commit a0edd30715
3 changed files with 162 additions and 212 deletions

View File

@ -3493,14 +3493,6 @@ public:
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
Expr *Idx, SourceLocation RLoc);
ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
SourceLocation OpLoc, bool IsArrow,
CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
NamedDecl *FirstQualifierInScope,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs);
// This struct is for use by ActOnMemberAccess to allow
// BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after
// changing the access operator from a '.' to a '->' (to see if that is the
@ -3513,6 +3505,13 @@ public:
bool HasTrailingLParen;
};
ExprResult BuildMemberReferenceExpr(
Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow,
CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs,
ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
ExprResult
BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc,
bool IsArrow, const CXXScopeSpec &SS,
@ -3523,11 +3522,6 @@ public:
ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow);
ExprResult LookupMemberExpr(LookupResult &R, ExprResult &Base,
bool &IsArrow, SourceLocation OpLoc,
CXXScopeSpec &SS,
Decl *ObjCImpDecl,
bool HasTemplateArgs);
bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
const CXXScopeSpec &SS,

View File

@ -653,6 +653,11 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
return false;
}
static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
ExprResult &BaseExpr, bool &IsArrow,
SourceLocation OpLoc, CXXScopeSpec &SS,
Decl *ObjCImpDecl, bool HasTemplateArgs);
ExprResult
Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
SourceLocation OpLoc, bool IsArrow,
@ -660,7 +665,8 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
SourceLocation TemplateKWLoc,
NamedDecl *FirstQualifierInScope,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
const TemplateArgumentListInfo *TemplateArgs,
ActOnMemberAccessExtraArgs *ExtraArgs) {
if (BaseType->isDependentType() ||
(SS.isSet() && isDependentScopeSpecifier(SS)))
return ActOnDependentMemberExpr(Base, BaseType,
@ -682,9 +688,10 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
// Explicit member accesses.
} else {
ExprResult BaseResult = Base;
ExprResult Result =
LookupMemberExpr(R, BaseResult, IsArrow, OpLoc,
SS, /*ObjCImpDecl*/ nullptr, TemplateArgs != nullptr);
ExprResult Result = LookupMemberExpr(
*this, R, BaseResult, IsArrow, OpLoc, SS,
ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr,
TemplateArgs != nullptr);
if (BaseResult.isInvalid())
return ExprError();
@ -702,7 +709,8 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
return BuildMemberReferenceExpr(Base, BaseType,
OpLoc, IsArrow, SS, TemplateKWLoc,
FirstQualifierInScope, R, TemplateArgs);
FirstQualifierInScope, R, TemplateArgs,
false, ExtraArgs);
}
static ExprResult
@ -1151,15 +1159,14 @@ Sema::PerformMemberExprBaseConversion(Expr *Base, bool IsArrow) {
///
/// The ObjCImpDecl bit is a gross hack that will need to be properly
/// fixed for ObjC++.
ExprResult
Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
bool &IsArrow, SourceLocation OpLoc,
CXXScopeSpec &SS,
Decl *ObjCImpDecl, bool HasTemplateArgs) {
static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
ExprResult &BaseExpr, bool &IsArrow,
SourceLocation OpLoc, CXXScopeSpec &SS,
Decl *ObjCImpDecl, bool HasTemplateArgs) {
assert(BaseExpr.get() && "no base expression");
// Perform default conversions.
BaseExpr = PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
if (BaseExpr.isInvalid())
return ExprError();
@ -1187,8 +1194,8 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
// overloaded operator->, but that should have been dealt with
// by now--or a diagnostic message already issued if a problem
// was encountered while looking for the overloaded operator->.
if (!getLangOpts().CPlusPlus) {
Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
if (!S.getLangOpts().CPlusPlus) {
S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
<< BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
<< FixItHint::CreateReplacement(OpLoc, ".");
}
@ -1196,7 +1203,7 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
} else if (BaseType->isFunctionType()) {
goto fail;
} else {
Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
<< BaseType << BaseExpr.get()->getSourceRange();
return ExprError();
}
@ -1204,7 +1211,7 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
// Handle field access to simple records.
if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
if (LookupMemberExprInRecord(*this, R, BaseExpr.get()->getSourceRange(),
if (LookupMemberExprInRecord(S, R, BaseExpr.get()->getSourceRange(),
RTy, OpLoc, SS, HasTemplateArgs))
return ExprError();
@ -1216,12 +1223,12 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
// Handle ivar access to Objective-C objects.
if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) {
if (!SS.isEmpty() && !SS.isInvalid()) {
Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
<< 1 << SS.getScopeRep()
<< FixItHint::CreateRemoval(SS.getRange());
SS.clear();
}
IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
// There are three cases for the base type:
@ -1230,23 +1237,24 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
// - an interface
ObjCInterfaceDecl *IDecl = OTy->getInterface();
if (!IDecl) {
if (getLangOpts().ObjCAutoRefCount &&
if (S.getLangOpts().ObjCAutoRefCount &&
(OTy->isObjCId() || OTy->isObjCClass()))
goto fail;
// There's an implicit 'isa' ivar on all objects.
// But we only actually find it this way on objects of type 'id',
// apparently.
if (OTy->isObjCId() && Member->isStr("isa"))
return new (Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
OpLoc, Context.getObjCClassType());
if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
OpLoc, S.Context.getObjCClassType());
if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
goto fail;
}
if (RequireCompleteType(OpLoc, BaseType, diag::err_typecheck_incomplete_tag,
BaseExpr.get()))
if (S.RequireCompleteType(OpLoc, BaseType,
diag::err_typecheck_incomplete_tag,
BaseExpr.get()))
return ExprError();
ObjCInterfaceDecl *ClassDeclared = nullptr;
@ -1256,14 +1264,14 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
// Attempt to correct for typos in ivar names.
DeclFilterCCC<ObjCIvarDecl> Validator;
Validator.IsObjCIvarLookup = IsArrow;
if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
LookupMemberName, nullptr,
nullptr, Validator,
CTK_ErrorRecovery, IDecl)) {
if (TypoCorrection Corrected = S.CorrectTypo(
R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
Validator, Sema::CTK_ErrorRecovery, IDecl)) {
IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
diagnoseTypo(Corrected,
PDiag(diag::err_typecheck_member_reference_ivar_suggest)
<< IDecl->getDeclName() << MemberName);
S.diagnoseTypo(
Corrected,
S.PDiag(diag::err_typecheck_member_reference_ivar_suggest)
<< IDecl->getDeclName() << MemberName);
// Figure out the class that declares the ivar.
assert(!ClassDeclared);
@ -1273,20 +1281,19 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
ClassDeclared = cast<ObjCInterfaceDecl>(D);
} else {
if (IsArrow && IDecl->FindPropertyDeclaration(Member)) {
Diag(MemberLoc,
diag::err_property_found_suggest)
<< Member << BaseExpr.get()->getType()
<< FixItHint::CreateReplacement(OpLoc, ".");
S.Diag(MemberLoc, diag::err_property_found_suggest)
<< Member << BaseExpr.get()->getType()
<< FixItHint::CreateReplacement(OpLoc, ".");
return ExprError();
}
Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
<< IDecl->getDeclName() << MemberName
<< BaseExpr.get()->getSourceRange();
S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
<< IDecl->getDeclName() << MemberName
<< BaseExpr.get()->getSourceRange();
return ExprError();
}
}
assert(ClassDeclared);
// If the decl being referenced had an error, return an error for this
@ -1296,14 +1303,14 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
return ExprError();
// Check whether we can reference this field.
if (DiagnoseUseOfDecl(IV, MemberLoc))
if (S.DiagnoseUseOfDecl(IV, MemberLoc))
return ExprError();
if (IV->getAccessControl() != ObjCIvarDecl::Public &&
IV->getAccessControl() != ObjCIvarDecl::Package) {
ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
if (ObjCMethodDecl *MD = getCurMethodDecl())
if (ObjCMethodDecl *MD = S.getCurMethodDecl())
ClassOfMethodDecl = MD->getClassInterface();
else if (ObjCImpDecl && getCurFunctionDecl()) {
else if (ObjCImpDecl && S.getCurFunctionDecl()) {
// Case of a c-function declared inside an objc implementation.
// FIXME: For a c-style function nested inside an objc implementation
// class, there is no implementation context available, so we pass
@ -1317,20 +1324,20 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
ClassOfMethodDecl = CatImplClass->getClassInterface();
}
if (!getLangOpts().DebuggerSupport) {
if (!S.getLangOpts().DebuggerSupport) {
if (IV->getAccessControl() == ObjCIvarDecl::Private) {
if (!declaresSameEntity(ClassDeclared, IDecl) ||
!declaresSameEntity(ClassOfMethodDecl, ClassDeclared))
Diag(MemberLoc, diag::error_private_ivar_access)
S.Diag(MemberLoc, diag::error_private_ivar_access)
<< IV->getDeclName();
} else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
// @protected
Diag(MemberLoc, diag::error_protected_ivar_access)
<< IV->getDeclName();
S.Diag(MemberLoc, diag::error_protected_ivar_access)
<< IV->getDeclName();
}
}
bool warn = true;
if (getLangOpts().ObjCAutoRefCount) {
if (S.getLangOpts().ObjCAutoRefCount) {
Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
if (UO->getOpcode() == UO_Deref)
@ -1338,33 +1345,30 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
Diag(DE->getLocation(), diag::error_arc_weak_ivar_access);
S.Diag(DE->getLocation(), diag::error_arc_weak_ivar_access);
warn = false;
}
}
if (warn) {
if (ObjCMethodDecl *MD = getCurMethodDecl()) {
if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
ObjCMethodFamily MF = MD->getMethodFamily();
warn = (MF != OMF_init && MF != OMF_dealloc &&
MF != OMF_finalize &&
!IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
!S.IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
}
if (warn)
Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
}
ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
MemberLoc, OpLoc,
BaseExpr.get(),
IsArrow);
ObjCIvarRefExpr *Result = new (S.Context) ObjCIvarRefExpr(
IV, IV->getType(), MemberLoc, OpLoc, BaseExpr.get(), IsArrow);
if (getLangOpts().ObjCAutoRefCount) {
if (S.getLangOpts().ObjCAutoRefCount) {
if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
DiagnosticsEngine::Level Level =
Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
MemberLoc);
DiagnosticsEngine::Level Level = S.Diags.getDiagnosticLevel(
diag::warn_arc_repeated_use_of_weak, MemberLoc);
if (Level != DiagnosticsEngine::Ignored)
recordUseOfEvaluatedWeak(Result);
S.recordUseOfEvaluatedWeak(Result);
}
}
@ -1375,18 +1379,18 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
const ObjCObjectPointerType *OPT;
if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) {
if (!SS.isEmpty() && !SS.isInvalid()) {
Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
<< 0 << SS.getScopeRep()
<< FixItHint::CreateRemoval(SS.getRange());
S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
<< 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
SS.clear();
}
// This actually uses the base as an r-value.
BaseExpr = DefaultLvalueConversion(BaseExpr.get());
BaseExpr = S.DefaultLvalueConversion(BaseExpr.get());
if (BaseExpr.isInvalid())
return ExprError();
assert(Context.hasSameUnqualifiedType(BaseType, BaseExpr.get()->getType()));
assert(S.Context.hasSameUnqualifiedType(BaseType,
BaseExpr.get()->getType()));
IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
@ -1395,74 +1399,75 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
// id, with and without qualifiers.
if (OT->isObjCId()) {
// Check protocols on qualified interfaces.
Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
if (Decl *PMDecl = FindGetterSetterNameDecl(OPT, Member, Sel, Context)) {
Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
if (Decl *PMDecl =
FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) {
if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
// Check the use of this declaration
if (DiagnoseUseOfDecl(PD, MemberLoc))
if (S.DiagnoseUseOfDecl(PD, MemberLoc))
return ExprError();
return new (Context)
ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
return new (S.Context)
ObjCPropertyRefExpr(PD, S.Context.PseudoObjectTy, VK_LValue,
OK_ObjCProperty, MemberLoc, BaseExpr.get());
}
if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
// Check the use of this method.
if (DiagnoseUseOfDecl(OMD, MemberLoc))
if (S.DiagnoseUseOfDecl(OMD, MemberLoc))
return ExprError();
Selector SetterSel =
SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
PP.getSelectorTable(),
SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
S.PP.getSelectorTable(),
Member);
ObjCMethodDecl *SMD = nullptr;
if (Decl *SDecl = FindGetterSetterNameDecl(OPT,
/*Property id*/nullptr,
SetterSel, Context))
/*Property id*/ nullptr,
SetterSel, S.Context))
SMD = dyn_cast<ObjCMethodDecl>(SDecl);
return new (Context)
ObjCPropertyRefExpr(OMD, SMD, Context.PseudoObjectTy, VK_LValue,
return new (S.Context)
ObjCPropertyRefExpr(OMD, SMD, S.Context.PseudoObjectTy, VK_LValue,
OK_ObjCProperty, MemberLoc, BaseExpr.get());
}
}
// Use of id.member can only be for a property reference. Do not
// use the 'id' redefinition in this case.
if (IsArrow && ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr))
return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
return ExprError(Diag(MemberLoc, diag::err_property_not_found)
return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
<< MemberName << BaseType);
}
// 'Class', unqualified only.
if (OT->isObjCClass()) {
// Only works in a method declaration (??!).
ObjCMethodDecl *MD = getCurMethodDecl();
ObjCMethodDecl *MD = S.getCurMethodDecl();
if (!MD) {
if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
goto fail;
}
// Also must look for a getter name which uses property syntax.
Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
ObjCInterfaceDecl *IFace = MD->getClassInterface();
ObjCMethodDecl *Getter;
if ((Getter = IFace->lookupClassMethod(Sel))) {
// Check the use of this method.
if (DiagnoseUseOfDecl(Getter, MemberLoc))
if (S.DiagnoseUseOfDecl(Getter, MemberLoc))
return ExprError();
} else
Getter = IFace->lookupPrivateMethod(Sel, false);
// If we found a getter then this may be a valid dot-reference, we
// will look for the matching setter, in case it is needed.
Selector SetterSel =
SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
PP.getSelectorTable(),
SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
S.PP.getSelectorTable(),
Member);
ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
if (!Setter) {
@ -1471,27 +1476,27 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
Setter = IFace->lookupPrivateMethod(SetterSel, false);
}
if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc))
return ExprError();
if (Getter || Setter) {
return new (Context) ObjCPropertyRefExpr(
Getter, Setter, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty,
MemberLoc, BaseExpr.get());
return new (S.Context) ObjCPropertyRefExpr(
Getter, Setter, S.Context.PseudoObjectTy, VK_LValue,
OK_ObjCProperty, MemberLoc, BaseExpr.get());
}
if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
return ExprError(Diag(MemberLoc, diag::err_property_not_found)
return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
<< MemberName << BaseType);
}
// Normal property access.
return HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc,
MemberName, MemberLoc,
SourceLocation(), QualType(), false);
return S.HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName,
MemberLoc, SourceLocation(), QualType(),
false);
}
// Handle 'field access' to vectors, such as 'V.xx'.
@ -1499,24 +1504,22 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
// FIXME: this expr should store IsArrow.
IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
ExprValueKind VK = (IsArrow ? VK_LValue : BaseExpr.get()->getValueKind());
QualType ret = CheckExtVectorComponent(*this, BaseType, VK, OpLoc,
QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
Member, MemberLoc);
if (ret.isNull())
return ExprError();
return new (Context)
return new (S.Context)
ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);
}
// Adjust builtin-sel to the appropriate redefinition type if that's
// not just a pointer to builtin-sel again.
if (IsArrow &&
BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
!Context.getObjCSelRedefinitionType()->isObjCSelType()) {
BaseExpr = ImpCastExprToType(BaseExpr.get(),
Context.getObjCSelRedefinitionType(),
CK_BitCast);
return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
if (IsArrow && BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
!S.Context.getObjCSelRedefinitionType()->isObjCSelType()) {
BaseExpr = S.ImpCastExprToType(
BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast);
return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
}
@ -1533,31 +1536,31 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
if (!IsArrow && Ptr->getPointeeType()->isRecordType() &&
MemberName.getNameKind() != DeclarationName::CXXDestructorName) {
Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
<< BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
<< BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
<< FixItHint::CreateReplacement(OpLoc, "->");
// Recurse as an -> access.
IsArrow = true;
return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
}
}
// If the user is trying to apply -> or . to a function name, it's probably
// because they forgot parentheses to call that function.
if (tryToRecoverWithCall(BaseExpr,
PDiag(diag::err_member_reference_needs_call),
/*complain*/ false,
IsArrow ? &isPointerToRecordType : &isRecordType)) {
if (S.tryToRecoverWithCall(
BaseExpr, S.PDiag(diag::err_member_reference_needs_call),
/*complain*/ false,
IsArrow ? &isPointerToRecordType : &isRecordType)) {
if (BaseExpr.isInvalid())
return ExprError();
BaseExpr = DefaultFunctionArrayConversion(BaseExpr.get());
return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get());
return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
}
Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
<< BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
return ExprError();
@ -1587,6 +1590,19 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
if (SS.isSet() && SS.isInvalid())
return ExprError();
// The only way a reference to a destructor can be used is to
// immediately call it. If the next token is not a '(', produce
// a diagnostic and build the call now.
if (!HasTrailingLParen &&
Id.getKind() == UnqualifiedId::IK_DestructorName) {
ExprResult DtorAccess =
ActOnMemberAccessExpr(S, Base, OpLoc, OpKind, SS, TemplateKWLoc, Id,
ObjCImpDecl, /*HasTrailingLParen*/true);
if (DtorAccess.isInvalid())
return DtorAccess;
return DiagnoseDtorReference(Id.getLocStart(), DtorAccess.get());
}
// Warn about the explicit constructor calls Microsoft extension.
if (getLangOpts().MicrosoftExt &&
Id.getKind() == UnqualifiedId::IK_ConstructorName)
@ -1614,42 +1630,16 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
if (Base->getType()->isDependentType() || Name.isDependentName() ||
isDependentScopeSpecifier(SS)) {
Result = ActOnDependentMemberExpr(Base, Base->getType(),
IsArrow, OpLoc,
SS, TemplateKWLoc, FirstQualifierInScope,
NameInfo, TemplateArgs);
} else {
LookupResult R(*this, NameInfo, LookupMemberName);
ExprResult BaseResult = Base;
Result = LookupMemberExpr(R, BaseResult, IsArrow, OpLoc,
SS, ObjCImpDecl, TemplateArgs != nullptr);
if (BaseResult.isInvalid())
return ExprError();
Base = BaseResult.get();
if (Result.isInvalid())
return ExprError();
if (Result.get()) {
// The only way a reference to a destructor can be used is to
// immediately call it, which falls into this case. If the
// next token is not a '(', produce a diagnostic and build the
// call now.
if (!HasTrailingLParen &&
Id.getKind() == UnqualifiedId::IK_DestructorName)
return DiagnoseDtorReference(NameInfo.getLoc(), Result.get());
return Result;
}
ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl, HasTrailingLParen};
Result = BuildMemberReferenceExpr(Base, Base->getType(),
OpLoc, IsArrow, SS, TemplateKWLoc,
FirstQualifierInScope, R, TemplateArgs,
false, &ExtraArgs);
return ActOnDependentMemberExpr(Base, Base->getType(), IsArrow, OpLoc, SS,
TemplateKWLoc, FirstQualifierInScope,
NameInfo, TemplateArgs);
}
return Result;
ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl,
HasTrailingLParen};
return BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, IsArrow, SS,
TemplateKWLoc, FirstQualifierInScope,
NameInfo, TemplateArgs, &ExtraArgs);
}
static ExprResult

View File

@ -2510,24 +2510,12 @@ public:
bool IsArrow, bool IsFreeIvar) {
// FIXME: We lose track of the IsFreeIvar bit.
CXXScopeSpec SS;
ExprResult Base = BaseArg;
LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
Sema::LookupMemberName);
ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/IvarLoc,
SS, nullptr,
false);
if (Result.isInvalid() || Base.isInvalid())
return ExprError();
if (Result.get())
return Result;
return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
/*FIXME:*/IvarLoc, IsArrow,
SS, SourceLocation(),
/*FirstQualifierInScope=*/nullptr,
R,
NameInfo,
/*TemplateArgs=*/nullptr);
}
@ -2539,24 +2527,14 @@ public:
ObjCPropertyDecl *Property,
SourceLocation PropertyLoc) {
CXXScopeSpec SS;
ExprResult Base = BaseArg;
LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
Sema::LookupMemberName);
bool IsArrow = false;
ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/PropertyLoc,
SS, nullptr, false);
if (Result.isInvalid() || Base.isInvalid())
return ExprError();
if (Result.get())
return Result;
return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
/*FIXME:*/PropertyLoc, IsArrow,
DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
/*FIXME:*/PropertyLoc,
/*IsArrow=*/false,
SS, SourceLocation(),
/*FirstQualifierInScope=*/nullptr,
R, /*TemplateArgs=*/nullptr);
NameInfo,
/*TemplateArgs=*/nullptr);
}
/// \brief Build a new Objective-C property reference expression.
@ -2580,26 +2558,14 @@ public:
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
SourceLocation OpLoc,
bool IsArrow) {
SourceLocation OpLoc, bool IsArrow) {
CXXScopeSpec SS;
ExprResult Base = BaseArg;
LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
Sema::LookupMemberName);
ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
OpLoc,
SS, nullptr, false);
if (Result.isInvalid() || Base.isInvalid())
return ExprError();
if (Result.get())
return Result;
return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
OpLoc, IsArrow,
SS, SourceLocation(),
/*FirstQualifierInScope=*/nullptr,
R,
NameInfo,
/*TemplateArgs=*/nullptr);
}