summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprMember.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExprMember.cpp')
-rw-r--r--lib/Sema/SemaExprMember.cpp101
1 files changed, 59 insertions, 42 deletions
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index b2b21ba9eefa..c856e37e99e7 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -1,9 +1,8 @@
//===--- SemaExprMember.cpp - Semantic Analysis for Expressions -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -591,7 +590,7 @@ namespace {
// Callback to only accept typo corrections that are either a ValueDecl or a
// FunctionTemplateDecl and are declared in the current record or, for a C++
// classes, one of its base classes.
-class RecordMemberExprValidatorCCC : public CorrectionCandidateCallback {
+class RecordMemberExprValidatorCCC final : public CorrectionCandidateCallback {
public:
explicit RecordMemberExprValidatorCCC(const RecordType *RTy)
: Record(RTy->getDecl()) {
@@ -629,6 +628,10 @@ public:
return false;
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<RecordMemberExprValidatorCCC>(*this);
+ }
+
private:
const RecordDecl *const Record;
};
@@ -697,9 +700,9 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
};
QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(),
R.redeclarationKind()};
+ RecordMemberExprValidatorCCC CCC(RTy);
TE = SemaRef.CorrectTypoDelayed(
- R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS,
- llvm::make_unique<RecordMemberExprValidatorCCC>(RTy),
+ R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, CCC,
[=, &SemaRef](const TypoCorrection &TC) {
if (TC) {
assert(!TC.isKeyword() &&
@@ -890,18 +893,32 @@ BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
NameInfo.getLoc());
}
-/// Build a MemberExpr AST node.
-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, OpLoc, SS.getWithLocInContext(C), TemplateKWLoc, Member,
- FoundDecl, MemberNameInfo, TemplateArgs, Ty, VK, OK);
- SemaRef.MarkMemberReferenced(E);
+MemberExpr *Sema::BuildMemberExpr(
+ Expr *Base, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec *SS,
+ SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl,
+ bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo,
+ QualType Ty, ExprValueKind VK, ExprObjectKind OK,
+ const TemplateArgumentListInfo *TemplateArgs) {
+ NestedNameSpecifierLoc NNS =
+ SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc();
+ return BuildMemberExpr(Base, IsArrow, OpLoc, NNS, TemplateKWLoc, Member,
+ FoundDecl, HadMultipleCandidates, MemberNameInfo, Ty,
+ VK, OK, TemplateArgs);
+}
+
+MemberExpr *Sema::BuildMemberExpr(
+ Expr *Base, bool IsArrow, SourceLocation OpLoc, NestedNameSpecifierLoc NNS,
+ SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl,
+ bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo,
+ QualType Ty, ExprValueKind VK, ExprObjectKind OK,
+ const TemplateArgumentListInfo *TemplateArgs) {
+ assert((!IsArrow || Base->isRValue()) && "-> base must be a pointer rvalue");
+ MemberExpr *E =
+ MemberExpr::Create(Context, Base, IsArrow, OpLoc, NNS, TemplateKWLoc,
+ Member, FoundDecl, MemberNameInfo, TemplateArgs, Ty,
+ VK, OK, getNonOdrUseReasonInCurrentContext(Member));
+ E->setHadMultipleCandidates(HadMultipleCandidates);
+ MarkMemberReferenced(E);
return E;
}
@@ -1089,8 +1106,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
SourceLocation Loc = R.getNameLoc();
if (SS.getRange().isValid())
Loc = SS.getRange().getBegin();
- CheckCXXThisCapture(Loc);
- BaseExpr = new (Context) CXXThisExpr(Loc, BaseExprType,/*isImplicit=*/true);
+ BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*IsImplicit=*/true);
}
// Check the use of this member.
@@ -1113,10 +1129,10 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
OpLoc);
if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
- return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
- TemplateKWLoc, Var, FoundDecl, MemberNameInfo,
- Var->getType().getNonReferenceType(), VK_LValue,
- OK_Ordinary);
+ return BuildMemberExpr(BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, Var,
+ FoundDecl, /*HadMultipleCandidates=*/false,
+ MemberNameInfo, Var->getType().getNonReferenceType(),
+ VK_LValue, OK_Ordinary);
}
if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
@@ -1130,24 +1146,25 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
type = MemberFn->getType();
}
- return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
- TemplateKWLoc, MemberFn, FoundDecl, MemberNameInfo,
- type, valueKind, OK_Ordinary);
+ return BuildMemberExpr(BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc,
+ MemberFn, FoundDecl, /*HadMultipleCandidates=*/false,
+ 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, OpLoc, SS,
- TemplateKWLoc, Enum, FoundDecl, MemberNameInfo,
- Enum->getType(), VK_RValue, OK_Ordinary);
+ return BuildMemberExpr(BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, Enum,
+ FoundDecl, /*HadMultipleCandidates=*/false,
+ MemberNameInfo, Enum->getType(), VK_RValue,
+ OK_Ordinary);
}
if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) {
if (VarDecl *Var = getVarTemplateSpecialization(
*this, VarTempl, TemplateArgs, MemberNameInfo, TemplateKWLoc))
- return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
- TemplateKWLoc, Var, FoundDecl, MemberNameInfo,
- Var->getType().getNonReferenceType(), VK_LValue,
- OK_Ordinary);
+ return BuildMemberExpr(
+ BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, Var, FoundDecl,
+ /*HadMultipleCandidates=*/false, MemberNameInfo,
+ Var->getType().getNonReferenceType(), VK_LValue, OK_Ordinary);
return ExprError();
}
@@ -1332,11 +1349,11 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
if (!IV) {
// Attempt to correct for typos in ivar names.
- auto Validator = llvm::make_unique<DeclFilterCCC<ObjCIvarDecl>>();
- Validator->IsObjCIvarLookup = IsArrow;
+ DeclFilterCCC<ObjCIvarDecl> Validator{};
+ Validator.IsObjCIvarLookup = IsArrow;
if (TypoCorrection Corrected = S.CorrectTypo(
R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
- std::move(Validator), Sema::CTK_ErrorRecovery, IDecl)) {
+ Validator, Sema::CTK_ErrorRecovery, IDecl)) {
IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
S.diagnoseTypo(
Corrected,
@@ -1803,9 +1820,10 @@ Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
}
}
- return BuildMemberExpr(*this, Context, Base.get(), IsArrow, OpLoc, SS,
+ return BuildMemberExpr(Base.get(), IsArrow, OpLoc, &SS,
/*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl,
- MemberNameInfo, MemberType, VK, OK);
+ /*HadMultipleCandidates=*/false, MemberNameInfo,
+ MemberType, VK, OK);
}
/// Builds an implicit member access expression. The current context
@@ -1833,8 +1851,7 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
SourceLocation Loc = R.getNameLoc();
if (SS.getRange().isValid())
Loc = SS.getRange().getBegin();
- CheckCXXThisCapture(Loc);
- baseExpr = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/true);
+ baseExpr = BuildCXXThisExpr(loc, ThisTy, /*IsImplicit=*/true);
}
return BuildMemberReferenceExpr(baseExpr, ThisTy,