summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-09-26 18:37:55 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-09-26 18:37:55 +0000
commit67ef14fe486e169f937737672d687032122d4637 (patch)
tree2c137a7dcade43e44be85dcd5773d9b755fb05be /clang/lib/Sema
parentafd34c6df76a68b581205a21733ceedf8676932d (diff)
downloadbcm5719-llvm-67ef14fe486e169f937737672d687032122d4637.tar.gz
bcm5719-llvm-67ef14fe486e169f937737672d687032122d4637.zip
Resolve a defect in C++17 copy omission.
When selecting constructors for initializing an object of type T from a single expression of class type U, also consider conversion functions of U that convert to T (rather than modeling such conversions as calling a conversion function and then calling a constructor). This approach is proposed as the resolution for the defect, and is also already implemented by GCC. llvm-svn: 314231
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp3
-rw-r--r--clang/lib/Sema/SemaInit.cpp87
-rw-r--r--clang/lib/Sema/SemaOverload.cpp86
3 files changed, 133 insertions, 43 deletions
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index d3138a96501..90a15e17a2f 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -4293,7 +4293,8 @@ static void mergeCandidatesWithResults(Sema &SemaRef,
std::stable_sort(
CandidateSet.begin(), CandidateSet.end(),
[&](const OverloadCandidate &X, const OverloadCandidate &Y) {
- return isBetterOverloadCandidate(SemaRef, X, Y, Loc);
+ return isBetterOverloadCandidate(SemaRef, X, Y, Loc,
+ CandidateSet.getKind());
});
// Add the remaining viable overload candidates as code-completion results.
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 8aa60bcef07..59ec9e28516 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3531,12 +3531,13 @@ static OverloadingResult
ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
MultiExprArg Args,
OverloadCandidateSet &CandidateSet,
+ QualType DestType,
DeclContext::lookup_result Ctors,
OverloadCandidateSet::iterator &Best,
bool CopyInitializing, bool AllowExplicit,
bool OnlyListConstructors, bool IsListInit,
bool SecondStepOfCopyInit = false) {
- CandidateSet.clear();
+ CandidateSet.clear(OverloadCandidateSet::CSK_InitByConstructor);
for (NamedDecl *D : Ctors) {
auto Info = getConstructorInfo(D);
@@ -3587,6 +3588,50 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
}
}
+ // FIXME: Work around a bug in C++17 guaranteed copy elision.
+ //
+ // When initializing an object of class type T by constructor
+ // ([over.match.ctor]) or by list-initialization ([over.match.list])
+ // from a single expression of class type U, conversion functions of
+ // U that convert to the non-reference type cv T are candidates.
+ // Explicit conversion functions are only candidates during
+ // direct-initialization.
+ //
+ // Note: SecondStepOfCopyInit is only ever true in this case when
+ // evaluating whether to produce a C++98 compatibility warning.
+ if (S.getLangOpts().CPlusPlus1z && Args.size() == 1 &&
+ !SecondStepOfCopyInit) {
+ Expr *Initializer = Args[0];
+ auto *SourceRD = Initializer->getType()->getAsCXXRecordDecl();
+ if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) {
+ const auto &Conversions = SourceRD->getVisibleConversionFunctions();
+ for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
+ NamedDecl *D = *I;
+ CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
+ D = D->getUnderlyingDecl();
+
+ FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
+ CXXConversionDecl *Conv;
+ if (ConvTemplate)
+ Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
+ else
+ Conv = cast<CXXConversionDecl>(D);
+
+ if ((AllowExplicit && !CopyInitializing) || !Conv->isExplicit()) {
+ if (ConvTemplate)
+ S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
+ ActingDC, Initializer, DestType,
+ CandidateSet, AllowExplicit,
+ /*AllowResultConversion*/false);
+ else
+ S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Initializer,
+ DestType, CandidateSet, AllowExplicit,
+ /*AllowResultConversion*/false);
+ }
+ }
+ }
+ }
+
// Perform overload resolution and return the result.
return CandidateSet.BestViableFunction(S, DeclLoc, Best);
}
@@ -3686,7 +3731,7 @@ static void TryConstructorInitialization(Sema &S,
// the first phase is omitted.
if (!(UnwrappedArgs.empty() && DestRecordDecl->hasDefaultConstructor()))
Result = ResolveConstructorOverload(S, Kind.getLocation(), Args,
- CandidateSet, Ctors, Best,
+ CandidateSet, DestType, Ctors, Best,
CopyInitialization, AllowExplicit,
/*OnlyListConstructor=*/true,
IsListInit);
@@ -3700,7 +3745,7 @@ static void TryConstructorInitialization(Sema &S,
if (Result == OR_No_Viable_Function) {
AsInitializerList = false;
Result = ResolveConstructorOverload(S, Kind.getLocation(), UnwrappedArgs,
- CandidateSet, Ctors, Best,
+ CandidateSet, DestType, Ctors, Best,
CopyInitialization, AllowExplicit,
/*OnlyListConstructors=*/false,
IsListInit);
@@ -3713,6 +3758,24 @@ static void TryConstructorInitialization(Sema &S,
return;
}
+ bool HadMultipleCandidates = (CandidateSet.size() > 1);
+
+ // In C++17, ResolveConstructorOverload can select a conversion function
+ // instead of a constructor.
+ if (auto *CD = dyn_cast<CXXConversionDecl>(Best->Function)) {
+ // Add the user-defined conversion step that calls the conversion function.
+ QualType ConvType = CD->getConversionType();
+ assert(S.Context.hasSameUnqualifiedType(ConvType, DestType) &&
+ "should not have selected this conversion function");
+ Sequence.AddUserConversionStep(CD, Best->FoundDecl, ConvType,
+ HadMultipleCandidates);
+ if (!S.Context.hasSameType(ConvType, DestType))
+ Sequence.AddQualificationConversionStep(DestType, VK_RValue);
+ if (IsListInit)
+ Sequence.RewrapReferenceInitList(Entity.getType(), ILE);
+ return;
+ }
+
// C++11 [dcl.init]p6:
// If a program calls for the default initialization of an object
// of a const-qualified type T, T shall be a class type with a
@@ -3741,7 +3804,6 @@ static void TryConstructorInitialization(Sema &S,
// Add the constructor initialization step. Any cv-qualification conversion is
// subsumed by the initialization.
- bool HadMultipleCandidates = (CandidateSet.size() > 1);
Sequence.AddConstructorInitializationStep(
Best->FoundDecl, CtorDecl, DestArrayType, HadMultipleCandidates,
IsListInit | IsInitListCopy, AsInitializerList);
@@ -4087,7 +4149,7 @@ static OverloadingResult TryRefInitWithConversionFunction(
// Build the candidate set directly in the initialization sequence
// structure, so that it will persist if we fail.
OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
- CandidateSet.clear();
+ CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion);
// Determine whether we are allowed to call explicit constructors or
// explicit conversion operators.
@@ -4173,7 +4235,7 @@ static OverloadingResult TryRefInitWithConversionFunction(
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
- = CandidateSet.BestViableFunction(S, DeclLoc, Best, true))
+ = CandidateSet.BestViableFunction(S, DeclLoc, Best))
return Result;
FunctionDecl *Function = Best->Function;
@@ -4687,7 +4749,7 @@ static void TryUserDefinedConversion(Sema &S,
// Build the candidate set directly in the initialization sequence
// structure, so that it will persist if we fail.
OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
- CandidateSet.clear();
+ CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion);
// Determine whether we are allowed to call explicit constructors or
// explicit conversion operators.
@@ -4766,7 +4828,7 @@ static void TryUserDefinedConversion(Sema &S,
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
- = CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) {
+ = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
Sequence.SetOverloadFailure(
InitializationSequence::FK_UserConversionOverloadFailed,
Result);
@@ -5657,7 +5719,7 @@ static ExprResult CopyObject(Sema &S,
OverloadCandidateSet::iterator Best;
switch (ResolveConstructorOverload(
- S, Loc, CurInitExpr, CandidateSet, Ctors, Best,
+ S, Loc, CurInitExpr, CandidateSet, T, Ctors, Best,
/*CopyInitializing=*/false, /*AllowExplicit=*/true,
/*OnlyListConstructors=*/false, /*IsListInit=*/false,
/*SecondStepOfCopyInit=*/true)) {
@@ -5797,7 +5859,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
OverloadingResult OR = ResolveConstructorOverload(
- S, Loc, CurInitExpr, CandidateSet, Ctors, Best,
+ S, Loc, CurInitExpr, CandidateSet, CurInitExpr->getType(), Ctors, Best,
/*CopyInitializing=*/false, /*AllowExplicit=*/true,
/*OnlyListConstructors=*/false, /*IsListInit=*/false,
/*SecondStepOfCopyInit=*/true);
@@ -7535,8 +7597,7 @@ bool InitializationSequence::Diagnose(Sema &S,
<< Args[0]->getSourceRange();
OverloadCandidateSet::iterator Best;
OverloadingResult Ovl
- = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best,
- true);
+ = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
if (Ovl == OR_Deleted) {
S.NoteDeletedFunction(Best->Function);
} else {
@@ -8415,7 +8476,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
OverloadCandidateSet::iterator Best;
auto tryToResolveOverload =
[&](bool OnlyListConstructors) -> OverloadingResult {
- Candidates.clear();
+ Candidates.clear(OverloadCandidateSet::CSK_Normal);
for (auto I = Guides.begin(), E = Guides.end(); I != E; ++I) {
NamedDecl *D = (*I)->getUnderlyingDecl();
if (D->isInvalidDecl())
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 8f28ec2fb8a..66f0fad138a 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -837,12 +837,13 @@ void OverloadCandidateSet::destroyCandidates() {
}
}
-void OverloadCandidateSet::clear() {
+void OverloadCandidateSet::clear(CandidateSetKind CSK) {
destroyCandidates();
SlabAllocator.Reset();
NumInlineBytesUsed = 0;
Candidates.clear();
Functions.clear();
+ Kind = CSK;
}
namespace {
@@ -3175,6 +3176,7 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
UserDefinedConversionSequence &User,
OverloadCandidateSet &CandidateSet,
bool AllowExplicit) {
+ CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion);
for (auto *D : S.LookupConstructors(To)) {
auto Info = getConstructorInfo(D);
if (!Info)
@@ -3203,7 +3205,7 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
OverloadCandidateSet::iterator Best;
switch (auto Result =
CandidateSet.BestViableFunction(S, From->getLocStart(),
- Best, true)) {
+ Best)) {
case OR_Deleted:
case OR_Success: {
// Record the standard conversion we used and the conversion function.
@@ -3250,6 +3252,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
bool AllowExplicit,
bool AllowObjCConversionOnExplicit) {
assert(AllowExplicit || !AllowObjCConversionOnExplicit);
+ CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion);
// Whether we will only visit constructors.
bool ConstructorsOnly = false;
@@ -3285,7 +3288,8 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
if (Result != OR_No_Viable_Function)
return Result;
// Never mind.
- CandidateSet.clear();
+ CandidateSet.clear(
+ OverloadCandidateSet::CSK_InitByUserDefinedConversion);
// If we're list-initializing, we pass the individual elements as
// arguments, not the entire list.
@@ -3375,7 +3379,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
OverloadCandidateSet::iterator Best;
switch (auto Result = CandidateSet.BestViableFunction(S, From->getLocStart(),
- Best, true)) {
+ Best)) {
case OR_Success:
case OR_Deleted:
// Record the standard conversion we used and the conversion function.
@@ -4309,7 +4313,8 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
CXXRecordDecl *T2RecordDecl
= dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
- OverloadCandidateSet CandidateSet(DeclLoc, OverloadCandidateSet::CSK_Normal);
+ OverloadCandidateSet CandidateSet(
+ DeclLoc, OverloadCandidateSet::CSK_InitByUserDefinedConversion);
const auto &Conversions = T2RecordDecl->getVisibleConversionFunctions();
for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
NamedDecl *D = *I;
@@ -4379,7 +4384,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
bool HadMultipleCandidates = (CandidateSet.size() > 1);
OverloadCandidateSet::iterator Best;
- switch (CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) {
+ switch (CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
case OR_Success:
// C++ [over.ics.ref]p1:
//
@@ -6788,7 +6793,8 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
CXXRecordDecl *ActingContext,
Expr *From, QualType ToType,
OverloadCandidateSet& CandidateSet,
- bool AllowObjCConversionOnExplicit) {
+ bool AllowObjCConversionOnExplicit,
+ bool AllowResultConversion) {
assert(!Conversion->getDescribedFunctionTemplate() &&
"Conversion function templates use AddTemplateConversionCandidate");
QualType ConvType = Conversion->getConversionType().getNonReferenceType();
@@ -6803,6 +6809,12 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
ConvType = Conversion->getConversionType().getNonReferenceType();
}
+ // If we don't allow any conversion of the result type, ignore conversion
+ // functions that don't convert to exactly (possibly cv-qualified) T.
+ if (!AllowResultConversion &&
+ !Context.hasSameUnqualifiedType(Conversion->getConversionType(), ToType))
+ return;
+
// Per C++ [over.match.conv]p1, [over.match.ref]p1, an explicit conversion
// operator is only a candidate if its return type is the target type or
// can be converted to the target type with a qualification conversion.
@@ -6956,7 +6968,8 @@ Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
CXXRecordDecl *ActingDC,
Expr *From, QualType ToType,
OverloadCandidateSet &CandidateSet,
- bool AllowObjCConversionOnExplicit) {
+ bool AllowObjCConversionOnExplicit,
+ bool AllowResultConversion) {
assert(isa<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl()) &&
"Only conversion function templates permitted here");
@@ -6985,7 +6998,8 @@ Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
// template argument deduction as a candidate.
assert(Specialization && "Missing function template specialization?");
AddConversionCandidate(Specialization, FoundDecl, ActingDC, From, ToType,
- CandidateSet, AllowObjCConversionOnExplicit);
+ CandidateSet, AllowObjCConversionOnExplicit,
+ AllowResultConversion);
}
/// AddSurrogateCandidate - Adds a "surrogate" candidate function that
@@ -8844,10 +8858,9 @@ static Comparison compareEnableIfAttrs(const Sema &S, const FunctionDecl *Cand1,
/// isBetterOverloadCandidate - Determines whether the first overload
/// candidate is a better candidate than the second (C++ 13.3.3p1).
-bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1,
- const OverloadCandidate &Cand2,
- SourceLocation Loc,
- bool UserDefinedConversion) {
+bool clang::isBetterOverloadCandidate(
+ Sema &S, const OverloadCandidate &Cand1, const OverloadCandidate &Cand2,
+ SourceLocation Loc, OverloadCandidateSet::CandidateSetKind Kind) {
// Define viable functions to be better candidates than non-viable
// functions.
if (!Cand2.Viable)
@@ -8929,7 +8942,8 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1,
// the type of the entity being initialized) is a better
// conversion sequence than the standard conversion sequence
// from the return type of F2 to the destination type.
- if (UserDefinedConversion && Cand1.Function && Cand2.Function &&
+ if (Kind == OverloadCandidateSet::CSK_InitByUserDefinedConversion &&
+ Cand1.Function && Cand2.Function &&
isa<CXXConversionDecl>(Cand1.Function) &&
isa<CXXConversionDecl>(Cand2.Function)) {
// First check whether we prefer one of the conversion functions over the
@@ -9001,6 +9015,18 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1,
// Inherited from sibling base classes: still ambiguous.
}
+ // FIXME: Work around a defect in the C++17 guaranteed copy elision wording,
+ // as combined with the resolution to CWG issue 243.
+ //
+ // When the context is initialization by constructor ([over.match.ctor] or
+ // either phase of [over.match.list]), a constructor is preferred over
+ // a conversion function.
+ if (Kind == OverloadCandidateSet::CSK_InitByConstructor && NumArgs == 1 &&
+ Cand1.Function && Cand2.Function &&
+ isa<CXXConstructorDecl>(Cand1.Function) !=
+ isa<CXXConstructorDecl>(Cand2.Function))
+ return isa<CXXConstructorDecl>(Cand1.Function);
+
// Check for enable_if value-based overload resolution.
if (Cand1.Function && Cand2.Function) {
Comparison Cmp = compareEnableIfAttrs(S, Cand1.Function, Cand2.Function);
@@ -9100,8 +9126,7 @@ void Sema::diagnoseEquivalentInternalLinkageDeclarations(
/// \returns The result of overload resolution.
OverloadingResult
OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
- iterator &Best,
- bool UserDefinedConversion) {
+ iterator &Best) {
llvm::SmallVector<OverloadCandidate *, 16> Candidates;
std::transform(begin(), end(), std::back_inserter(Candidates),
[](OverloadCandidate &Cand) { return &Cand; });
@@ -9135,8 +9160,8 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
Best = end();
for (auto *Cand : Candidates)
if (Cand->Viable)
- if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc,
- UserDefinedConversion))
+ if (Best == end() ||
+ isBetterOverloadCandidate(S, *Cand, *Best, Loc, Kind))
Best = Cand;
// If we didn't find any viable functions, abort.
@@ -9148,10 +9173,8 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
// Make sure that this function is better than every other viable
// function. If not, we have an ambiguity.
for (auto *Cand : Candidates) {
- if (Cand->Viable &&
- Cand != Best &&
- !isBetterOverloadCandidate(S, *Best, *Cand, Loc,
- UserDefinedConversion)) {
+ if (Cand->Viable && Cand != Best &&
+ !isBetterOverloadCandidate(S, *Best, *Cand, Loc, Kind)) {
if (S.isEquivalentInternalLinkageDeclaration(Best->Function,
Cand->Function)) {
EquivalentCands.push_back(Cand->Function);
@@ -10243,9 +10266,12 @@ struct CompareOverloadCandidatesForDisplay {
Sema &S;
SourceLocation Loc;
size_t NumArgs;
+ OverloadCandidateSet::CandidateSetKind CSK;
- CompareOverloadCandidatesForDisplay(Sema &S, SourceLocation Loc, size_t nArgs)
- : S(S), NumArgs(nArgs) {}
+ CompareOverloadCandidatesForDisplay(
+ Sema &S, SourceLocation Loc, size_t NArgs,
+ OverloadCandidateSet::CandidateSetKind CSK)
+ : S(S), NumArgs(NArgs) {}
bool operator()(const OverloadCandidate *L,
const OverloadCandidate *R) {
@@ -10259,8 +10285,10 @@ struct CompareOverloadCandidatesForDisplay {
// TODO: introduce a tri-valued comparison for overload
// candidates. Would be more worthwhile if we had a sort
// that could exploit it.
- if (isBetterOverloadCandidate(S, *L, *R, SourceLocation())) return true;
- if (isBetterOverloadCandidate(S, *R, *L, SourceLocation())) return false;
+ if (isBetterOverloadCandidate(S, *L, *R, SourceLocation(), CSK))
+ return true;
+ if (isBetterOverloadCandidate(S, *R, *L, SourceLocation(), CSK))
+ return false;
} else if (R->Viable)
return false;
@@ -10468,7 +10496,7 @@ void OverloadCandidateSet::NoteCandidates(
}
std::sort(Cands.begin(), Cands.end(),
- CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size()));
+ CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size(), Kind));
bool ReportedAmbiguousConversions = false;
@@ -12917,7 +12945,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(*this, Object.get()->getLocStart(),
- Best)) {
+ Best)) {
case OR_Success:
// Overload resolution succeeded; we'll build the appropriate call
// below.
@@ -13311,7 +13339,7 @@ Sema::BuildForRangeBeginEndCall(SourceLocation Loc,
Expr *Range, ExprResult *CallExpr) {
Scope *S = nullptr;
- CandidateSet->clear();
+ CandidateSet->clear(OverloadCandidateSet::CSK_Normal);
if (!MemberLookup.empty()) {
ExprResult MemberRef =
BuildMemberReferenceExpr(Range, Range->getType(), Loc,
OpenPOWER on IntegriCloud