aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Sema/Initialization.h4
-rw-r--r--include/clang/Sema/Overload.h31
-rw-r--r--include/clang/Sema/Sema.h61
-rw-r--r--lib/Sema/SemaCodeComplete.cpp3
-rw-r--r--lib/Sema/SemaExprCXX.cpp12
-rw-r--r--lib/Sema/SemaInit.cpp55
-rw-r--r--lib/Sema/SemaOverload.cpp701
7 files changed, 437 insertions, 430 deletions
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index a532076340..4cdea13d9d 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_SEMA_INITIALIZATION_H
#define LLVM_CLANG_SEMA_INITIALIZATION_H
-#include "clang/Sema/Action.h"
+#include "clang/Sema/Ownership.h"
#include "clang/Sema/Overload.h"
#include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h"
@@ -628,7 +628,7 @@ public:
ExprResult Perform(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
- Action::MultiExprArg Args,
+ MultiExprArg Args,
QualType *ResultType = 0);
/// \brief Diagnose an potentially-invalid initialization sequence.
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index eb4fc65817..6c4da14b36 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -29,6 +29,7 @@ namespace clang {
class CXXConstructorDecl;
class CXXConversionDecl;
class FunctionDecl;
+ class Sema;
/// OverloadingResult - Capture the result of performing overload
/// resolution.
@@ -38,7 +39,16 @@ namespace clang {
OR_Ambiguous, ///< Ambiguous candidates found.
OR_Deleted ///< Succeeded, but refers to a deleted function.
};
-
+
+ enum OverloadCandidateDisplayKind {
+ /// Requests that all candidates be shown. Viable candidates will
+ /// be printed first.
+ OCD_AllCandidates,
+
+ /// Requests that only viable candidates be shown.
+ OCD_ViableCandidates
+ };
+
/// ImplicitConversionKind - The kind of implicit conversion used to
/// convert an argument to a parameter's type. The enumerator values
/// match with Table 9 of (C++ 13.3.3.1.1) and are listed such that
@@ -461,6 +471,10 @@ namespace clang {
Worse = 1
};
+ void DiagnoseAmbiguousConversion(Sema &S,
+ SourceLocation CaretLoc,
+ const PartialDiagnostic &PDiag) const;
+
void DebugPrint() const;
};
@@ -611,7 +625,22 @@ namespace clang {
void clear();
~OverloadCandidateSet() { clear(); }
+
+ /// Find the best viable function on this overload set, if it exists.
+ OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
+ OverloadCandidateSet::iterator& Best);
+
+ void NoteCandidates(Sema &S,
+ OverloadCandidateDisplayKind OCD,
+ Expr **Args, unsigned NumArgs,
+ const char *Opc = 0,
+ SourceLocation Loc = SourceLocation());
};
+
+ bool isBetterOverloadCandidate(Sema &S,
+ const OverloadCandidate& Cand1,
+ const OverloadCandidate& Cand2,
+ SourceLocation Loc);
} // end namespace clang
#endif // LLVM_CLANG_SEMA_OVERLOAD_H
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 1ad6ca690a..c7a83ef662 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1135,14 +1135,6 @@ public:
bool AllowExplicit,
bool InOverloadResolution);
- ImplicitConversionSequence
- TryImplicitConversion(Expr* From, QualType ToType,
- bool SuppressUserConversions,
- bool AllowExplicit,
- bool InOverloadResolution);
- bool IsStandardConversion(Expr *From, QualType ToType,
- bool InOverloadResolution,
- StandardConversionSequence& SCS);
bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType);
bool IsFloatingPointPromotion(QualType FromType, QualType ToType);
bool IsComplexPromotion(QualType FromType, QualType ToType);
@@ -1166,44 +1158,18 @@ public:
CXXCastPath &BasePath,
bool IgnoreBaseAccess);
bool IsQualificationConversion(QualType FromType, QualType ToType);
- OverloadingResult IsUserDefinedConversion(Expr *From, QualType ToType,
- UserDefinedConversionSequence& User,
- OverloadCandidateSet& Conversions,
- bool AllowExplicit);
bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
- ImplicitConversionSequence::CompareKind
- CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
- const ImplicitConversionSequence& ICS2);
-
- ImplicitConversionSequence::CompareKind
- CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
- const StandardConversionSequence& SCS2);
-
- ImplicitConversionSequence::CompareKind
- CompareQualificationConversions(const StandardConversionSequence& SCS1,
- const StandardConversionSequence& SCS2);
-
- ImplicitConversionSequence::CompareKind
- CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
- const StandardConversionSequence& SCS2);
-
ExprResult PerformCopyInitialization(const InitializedEntity &Entity,
- SourceLocation EqualLoc,
- ExprResult Init);
- ImplicitConversionSequence
- TryObjectArgumentInitialization(QualType FromType, CXXMethodDecl *Method,
- CXXRecordDecl *ActingContext);
+ SourceLocation EqualLoc,
+ ExprResult Init);
bool PerformObjectArgumentInitialization(Expr *&From,
NestedNameSpecifier *Qualifier,
NamedDecl *FoundDecl,
CXXMethodDecl *Method);
- ImplicitConversionSequence TryContextuallyConvertToBool(Expr *From);
bool PerformContextuallyConvertToBool(Expr *&From);
-
- ImplicitConversionSequence TryContextuallyConvertToObjCId(Expr *From);
bool PerformContextuallyConvertToObjCId(Expr *&From);
ExprResult
@@ -1302,31 +1268,8 @@ public:
const TemplateArgumentListInfo *ExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet,
bool PartialOverloading = false);
- bool isBetterOverloadCandidate(const OverloadCandidate& Cand1,
- const OverloadCandidate& Cand2,
- SourceLocation Loc);
- OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet,
- SourceLocation Loc,
- OverloadCandidateSet::iterator& Best);
-
- enum OverloadCandidateDisplayKind {
- /// Requests that all candidates be shown. Viable candidates will
- /// be printed first.
- OCD_AllCandidates,
-
- /// Requests that only viable candidates be shown.
- OCD_ViableCandidates
- };
- void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
- OverloadCandidateDisplayKind OCD,
- Expr **Args, unsigned NumArgs,
- const char *Opc = 0,
- SourceLocation Loc = SourceLocation());
void NoteOverloadCandidate(FunctionDecl *Fn);
- void DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS,
- SourceLocation CaretLoc,
- const PartialDiagnostic &PDiag);
FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
bool Complain,
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 97742654ae..06e65784e8 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Sema/Sema.h"
#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Overload.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Sema/Scope.h"
@@ -2837,7 +2838,7 @@ namespace {
bool
operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
- return S.isBetterOverloadCandidate(X, Y, Loc);
+ return isBetterOverloadCandidate(S, X, Y, Loc);
}
};
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 0e53a47b18..a547fc289f 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1124,7 +1124,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
// Do the resolution.
OverloadCandidateSet::iterator Best;
- switch(BestViableFunction(Candidates, StartLoc, Best)) {
+ switch (Candidates.BestViableFunction(*this, StartLoc, Best)) {
case OR_Success: {
// Got one!
FunctionDecl *FnDecl = Best->Function;
@@ -1152,20 +1152,20 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
case OR_No_Viable_Function:
Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
<< Name << Range;
- PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+ Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
return true;
case OR_Ambiguous:
Diag(StartLoc, diag::err_ovl_ambiguous_call)
<< Name << Range;
- PrintOverloadCandidates(Candidates, OCD_ViableCandidates, Args, NumArgs);
+ Candidates.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
return true;
case OR_Deleted:
Diag(StartLoc, diag::err_ovl_deleted_call)
<< Best->Function->isDeleted()
<< Name << Range;
- PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+ Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
return true;
}
assert(false && "Unreachable, bad result from BestViableFunction");
@@ -1674,7 +1674,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
}
case ImplicitConversionSequence::AmbiguousConversion:
- DiagnoseAmbiguousConversion(ICS, From->getExprLoc(),
+ ICS.DiagnoseAmbiguousConversion(*this, From->getExprLoc(),
PDiag(diag::err_typecheck_ambiguous_condition)
<< From->getSourceRange());
return true;
@@ -2140,7 +2140,7 @@ static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS,
Self.AddBuiltinOperatorCandidates(OO_Conditional, Loc, Args, 2, CandidateSet);
OverloadCandidateSet::iterator Best;
- switch (Self.BestViableFunction(CandidateSet, Loc, Best)) {
+ switch (CandidateSet.BestViableFunction(Self, Loc, Best)) {
case OR_Success:
// We found a match. Perform the conversions on the arguments and move on.
if (Self.PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0],
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 5851580b19..034099eac4 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2392,7 +2392,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
- = S.BestViableFunction(CandidateSet, DeclLoc, Best))
+ = CandidateSet.BestViableFunction(S, DeclLoc, Best))
return Result;
FunctionDecl *Function = Best->Function;
@@ -2777,7 +2777,7 @@ static void TryConstructorInitialization(Sema &S,
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
- = S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+ = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
Sequence.SetOverloadFailure(
InitializationSequence::FK_ConstructorOverloadFailed,
Result);
@@ -2987,7 +2987,7 @@ static void TryUserDefinedConversion(Sema &S,
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
- = S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+ = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
Sequence.SetOverloadFailure(
InitializationSequence::FK_UserConversionOverloadFailed,
Result);
@@ -3029,24 +3029,6 @@ static void TryUserDefinedConversion(Sema &S,
}
}
-bool Sema::TryImplicitConversion(InitializationSequence &Sequence,
- const InitializedEntity &Entity,
- Expr *Initializer,
- bool SuppressUserConversions,
- bool AllowExplicitConversions,
- bool InOverloadResolution) {
- ImplicitConversionSequence ICS
- = TryImplicitConversion(Initializer, Entity.getType(),
- SuppressUserConversions,
- AllowExplicitConversions,
- InOverloadResolution);
- if (ICS.isBad()) return true;
-
- // Perform the actual conversion.
- Sequence.AddConversionSequenceStep(ICS, Entity.getType());
- return false;
-}
-
InitializationSequence::InitializationSequence(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
@@ -3378,7 +3360,7 @@ static ExprResult CopyObject(Sema &S,
}
OverloadCandidateSet::iterator Best;
- switch (S.BestViableFunction(CandidateSet, Loc, Best)) {
+ switch (CandidateSet.BestViableFunction(S, Loc, Best)) {
case OR_Success:
break;
@@ -3388,8 +3370,7 @@ static ExprResult CopyObject(Sema &S,
: diag::err_temp_copy_no_viable)
<< (int)Entity.getKind() << CurInitExpr->getType()
<< CurInitExpr->getSourceRange();
- S.PrintOverloadCandidates(CandidateSet, Sema::OCD_AllCandidates,
- &CurInitExpr, 1);
+ CandidateSet.NoteCandidates(S, OCD_AllCandidates, &CurInitExpr, 1);
if (!IsExtraneousCopy || S.isSFINAEContext())
return S.ExprError();
return move(CurInit);
@@ -3398,8 +3379,7 @@ static ExprResult CopyObject(Sema &S,
S.Diag(Loc, diag::err_temp_copy_ambiguous)
<< (int)Entity.getKind() << CurInitExpr->getType()
<< CurInitExpr->getSourceRange();
- S.PrintOverloadCandidates(CandidateSet, Sema::OCD_ViableCandidates,
- &CurInitExpr, 1);
+ CandidateSet.NoteCandidates(S, OCD_ViableCandidates, &CurInitExpr, 1);
return S.ExprError();
case OR_Deleted:
@@ -4034,16 +4014,14 @@ bool InitializationSequence::Diagnose(Sema &S,
<< DestType << Args[0]->getType()
<< Args[0]->getSourceRange();
- S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_ViableCandidates,
- Args, NumArgs);
+ FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args, NumArgs);
break;
case OR_No_Viable_Function:
S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
<< Args[0]->getType() << DestType.getNonReferenceType()
<< Args[0]->getSourceRange();
- S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates,
- Args, NumArgs);
+ FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs);
break;
case OR_Deleted: {
@@ -4051,9 +4029,8 @@ bool InitializationSequence::Diagnose(Sema &S,
<< Args[0]->getType() << DestType.getNonReferenceType()
<< Args[0]->getSourceRange();
OverloadCandidateSet::iterator Best;
- OverloadingResult Ovl = S.BestViableFunction(FailedCandidateSet,
- Kind.getLocation(),
- Best);
+ OverloadingResult Ovl
+ = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
if (Ovl == OR_Deleted) {
S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
<< Best->Function->isDeleted();
@@ -4146,8 +4123,8 @@ bool InitializationSequence::Diagnose(Sema &S,
case OR_Ambiguous:
S.Diag(Kind.getLocation(), diag::err_ovl_ambiguous_init)
<< DestType << ArgsRange;
- S.PrintOverloadCandidates(FailedCandidateSet,
- Sema::OCD_ViableCandidates, Args, NumArgs);
+ FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates,
+ Args, NumArgs);
break;
case OR_No_Viable_Function:
@@ -4192,17 +4169,15 @@ bool InitializationSequence::Diagnose(Sema &S,
S.Diag(Kind.getLocation(), diag::err_ovl_no_viable_function_in_init)
<< DestType << ArgsRange;
- S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates,
- Args, NumArgs);
+ FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs);
break;
case OR_Deleted: {
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
<< true << DestType << ArgsRange;
OverloadCandidateSet::iterator Best;
- OverloadingResult Ovl = S.BestViableFunction(FailedCandidateSet,
- Kind.getLocation(),
- Best);
+ OverloadingResult Ovl
+ = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
if (Ovl == OR_Deleted) {
S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
<< Best->Function->isDeleted();
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 7458a24dc8..fd22ad93a0 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -30,6 +30,33 @@
namespace clang {
+static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
+ bool InOverloadResolution,
+ StandardConversionSequence &SCS);
+static OverloadingResult
+IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
+ UserDefinedConversionSequence& User,
+ OverloadCandidateSet& Conversions,
+ bool AllowExplicit);
+
+
+static ImplicitConversionSequence::CompareKind
+CompareStandardConversionSequences(Sema &S,
+ const StandardConversionSequence& SCS1,
+ const StandardConversionSequence& SCS2);
+
+static ImplicitConversionSequence::CompareKind
+CompareQualificationConversions(Sema &S,
+ const StandardConversionSequence& SCS1,
+ const StandardConversionSequence& SCS2);
+
+static ImplicitConversionSequence::CompareKind
+CompareDerivedToBaseConversions(Sema &S,
+ const StandardConversionSequence& SCS1,
+ const StandardConversionSequence& SCS2);
+
+
+
/// GetConversionCategory - Retrieve the implicit conversion
/// category corresponding to the given implicit conversion kind.
ImplicitConversionCategory
@@ -676,18 +703,19 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
/// not permitted.
/// If @p AllowExplicit, then explicit user-defined conversions are
/// permitted.
-ImplicitConversionSequence
-Sema::TryImplicitConversion(Expr* From, QualType ToType,
- bool SuppressUserConversions,
- bool AllowExplicit,
- bool InOverloadResolution) {
+static ImplicitConversionSequence
+TryImplicitConversion(Sema &S, Expr *From, QualType ToType,
+ bool SuppressUserConversions,
+ bool AllowExplicit,
+ bool InOverloadResolution) {
ImplicitConversionSequence ICS;
- if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard)) {
+ if (IsStandardConversion(S, From, ToType, InOverloadResolution,
+ ICS.Standard)) {
ICS.setStandard();
return ICS;
}
- if (!getLangOptions().CPlusPlus) {
+ if (!S.getLangOptions().CPlusPlus) {
ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
return ICS;
}
@@ -701,8 +729,8 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
// called for those cases.
QualType FromType = From->getType();
if (ToType->getAs<RecordType>() && FromType->getAs<RecordType>() &&
- (Context.hasSameUnqualifiedType(FromType, ToType) ||
- IsDerivedFrom(FromType, ToType))) {
+ (S.Context.hasSameUnqualifiedType(FromType, ToType) ||
+ S.IsDerivedFrom(FromType, ToType))) {
ICS.setStandard();
ICS.Standard.setAsIdentityConversion();
ICS.Standard.setFromType(FromType);
@@ -715,7 +743,7 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
ICS.Standard.CopyConstructor = 0;
// Determine whether this is considered a derived-to-base conversion.
- if (!Context.hasSameUnqualifiedType(FromType, ToType))
+ if (!S.Context.hasSameUnqualifiedType(FromType, ToType))
ICS.Standard.Second = ICK_Derived_To_Base;
return ICS;
@@ -731,7 +759,7 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
// Attempt user-defined conversion.
OverloadCandidateSet Conversions(From->getExprLoc());
OverloadingResult UserDefResult
- = IsUserDefinedConversion(From, ToType, ICS.UserDefined, Conversions,
+ = IsUserDefinedConversion(S, From, ToType, ICS.UserDefined, Conversions,
AllowExplicit);
if (UserDefResult == OR_Success) {
@@ -746,10 +774,11 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
if (CXXConstructorDecl *Constructor
= dyn_cast<CXXConstructorDecl>(ICS.UserDefined.ConversionFunction)) {
QualType FromCanon
- = Context.getCanonicalType(From->getType().getUnqualifiedType());
- QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType();
+ = S.Context.getCanonicalType(From->getType().getUnqualifiedType());
+ QualType ToCanon
+ = S.Context.getCanonicalType(ToType).getUnqualifiedType();
if (Constructor->isCopyConstructor() &&
- (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon))) {
+ (FromCanon == ToCanon || S.IsDerivedFrom(FromCanon, ToCanon))) {
// Turn this into a "standard" conversion sequence, so that it
// gets ranked with standard conversion sequences.
ICS.setStandard();
@@ -787,6 +816,24 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
return ICS;
}
+bool Sema::TryImplicitConversion(InitializationSequence &Sequence,
+ const InitializedEntity &Entity,
+ Expr *Initializer,
+ bool SuppressUserConversions,
+ bool AllowExplicitConversions,
+ bool InOverloadResolution) {
+ ImplicitConversionSequence ICS
+ = clang::TryImplicitConversion(*this, Initializer, Entity.getType(),
+ SuppressUserConversions,
+ AllowExplicitConversions,
+ InOverloadResolution);
+ if (ICS.isBad()) return true;
+
+ // Perform the actual conversion.
+ Sequence.AddConversionSequenceStep(ICS, Entity.getType());
+ return false;
+}
+
/// PerformImplicitConversion - Perform an implicit conversion of the
/// expression From to the type ToType. Returns true if there was an
/// error, false otherwise. The expression From is replaced with the
@@ -804,10 +851,10 @@ bool
Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
AssignmentAction Action, bool AllowExplicit,
ImplicitConversionSequence& ICS) {
- ICS = TryImplicitConversion(From, ToType,
- /*SuppressUserConversions=*/false,
- AllowExplicit,
- /*InOverloadResolution=*/false);
+ ICS = clang::TryImplicitConversion(*this, From, ToType,
+ /*SuppressUserConversions=*/false,
+ AllowExplicit,
+ /*InOverloadResolution=*/false);
return PerformImplicitConversion(From, ToType, ICS, Action);
}
@@ -882,12 +929,11 @@ static bool IsVectorConversion(ASTContext &Context, QualType FromType,
/// contain the standard conversion sequence required to perform this
/// conversion and this routine will return true. Otherwise, this
/// routine will return false and the value of SCS is unspecified.
-bool
-Sema::IsStandardConversion(Expr* From, QualType ToType,
- bool InOverloadResolution,
- StandardConversionSequence &SCS) {
+static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
+ bool InOverloadResolution,
+ StandardConversionSequence &SCS) {
QualType FromType = From->getType();
-
+
// Standard conversions (C++ [conv])
SCS.setAsIdentityConversion();
SCS.DeprecatedStringLiteralToCharPtr = false;
@@ -898,7 +944,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// There are no standard conversions for class types in C++, so
// abort early. When overloading in C, however, we do permit
if (FromType->isRecordType() || ToType->isRecordType()) {
- if (getLangOptions().CPlusPlus)
+ if (S.getLangOptions().CPlusPlus)
return false;
// When we're overloading in C, we allow, as standard conversions,
@@ -908,19 +954,19 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// array-to-pointer conversion, or function-to-pointer conversion
// (C++ 4p1).
- if (FromType == Context.OverloadTy) {
+ if (FromType == S.Context.OverloadTy) {
DeclAccessPair AccessPair;
if (FunctionDecl *Fn
- = ResolveAddressOfOverloadedFunction(From, ToType, false,
- AccessPair)) {
+ = S.ResolveAddressOfOverloadedFunction(From, ToType, false,
+ AccessPair)) {
// We were able to resolve the address of the overloaded function,
// so we can convert to the type of that function.
FromType = Fn->getType();
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
if (!Method->isStatic()) {
Type *ClassType
- = Context.getTypeDeclType(Method->getParent()).getTypePtr();
- FromType = Context.getMemberPointerType(FromType, ClassType);
+ = S.Context.getTypeDeclType(Method->getParent()).getTypePtr();
+ FromType = S.Context.getMemberPointerType(FromType, ClassType);
}
}
@@ -929,11 +975,11 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
if (FromType->getAs<FunctionType>())
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(From->IgnoreParens()))
if (UnOp->getOpcode() == UnaryOperator::AddrOf)
- FromType = Context.getPointerType(FromType);
+ FromType = S.Context.getPointerType(FromType);
// Check that we've computed the proper type after overload resolution.
- assert(Context.hasSameType(FromType,
- FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
+ assert(S.Context.hasSameType(FromType,
+ S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
} else {
return false;
}
@@ -941,10 +987,10 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// Lvalue-to-rvalue conversion (C++ 4.1):
// An lvalue (3.10) of a non-function, non-array type T can be
// converted to an rvalue.
- Expr::isLvalueResult argIsLvalue = From->isLvalue(Context);
+ Expr::isLvalueResult argIsLvalue = From->isLvalue(S.Context);
if (argIsLvalue == Expr::LV_Valid &&
!FromType->isFunctionType() && !FromType->isArrayType() &&
- Context.getCanonicalType(FromType) != Context.OverloadTy) {
+ S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) {
SCS.First = ICK_Lvalue_To_Rvalue;
// If T is a non-class type, the type of the rvalue is the
@@ -959,9 +1005,9 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// An lvalue or rvalue of type "array of N T" or "array of unknown
// bound of T" can be converted to an rvalue of type "pointer to
// T" (C++ 4.2p1).
- FromType = Context.getArrayDecayedType(FromType);
+ FromType = S.Context.getArrayDecayedType(FromType);
- if (IsStringLiteralToNonConstPointerConversion(From, ToType)) {
+ if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) {
// This conversion is deprecated. (C++ D.4).
SCS.DeprecatedStringLiteralToCharPtr = true;
@@ -981,7 +1027,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// An lvalue of function type T can be converted to an rvalue of
// type "pointer to T." The result is a pointer to the
// function. (C++ 4.3p1).
- FromType = Context.getPointerType(FromType);
+ FromType = S.Context.getPointerType(FromType);
} else {
// We don't require any conversions for the first step.
SCS.First = ICK_Identity;
@@ -996,24 +1042,24 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// conversion.
bool IncompatibleObjC = false;
ImplicitConversionKind SecondICK = ICK_Identity;
- if (Context.hasSameUnqualifiedType(FromType, ToType)) {
+ if (S.Context.hasSameUnqualifiedType(FromType, ToType)) {
// The unqualified versions of the types are the same: there's no
// conversion to do.
SCS.Second = ICK_Identity;
- } else if (IsIntegralPromotion(From, FromType, ToType)) {
+ } else if (S.IsIntegralPromotion(From, FromType, ToType)) {
// Integral promotion (C++ 4.5).
SCS.Second = ICK_Integral_Promotion;
FromType = ToType.getUnqualifiedType();
- } else if (IsFloatingPointPromotion(FromType, ToType)) {
+ } else if (S.IsFloatingPointPromotion(FromType, ToType)) {
// Floating point promotion (C++ 4.6).
SCS.Second = ICK_Floating_Promotion;
FromType = ToType.getUnqualifiedType();
- } else if (IsComplexPromotion(FromType, ToType)) {
+ } else if (S.IsComplexPromotion(FromType, ToType)) {
// Complex promotion (Clang extension)
SCS.Second = ICK_Complex_Promotion;
FromType = ToType.getUnqualifiedType();
} else if (FromType->isIntegralOrEnumerationType() &&
- ToType->isIntegralType(Context)) {
+ ToType->isIntegralType(S.Context)) {
// Integral conversions (C++ 4.7).
SCS.Second = ICK_Integral_Conversion;
FromType = ToType.getUnqualifiedType();
@@ -1031,19 +1077,19 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
SCS.Second = ICK_Floating_Conversion;
FromType = ToType.getUnqualifiedType();
} else if ((FromType->isRealFloatingType() &&
- ToType->isIntegralType(Context) && !ToType->isBooleanType()) ||
+ ToType->isIntegralType(S.Context) && !ToType->isBooleanType()) ||
(FromType->isIntegralOrEnumerationType() &&
ToType->isRealFloatingType())) {
// Floating-integral conversions (C++ 4.9).
SCS.Second = ICK_Floating_Integral;
FromType = ToType.getUnqualifiedType();
- } else if (IsPointerConversion(From, FromType, ToType, InOverloadResolution,
- FromType, IncompatibleObjC)) {
+ } else if (S.IsPointerConversion(From, FromType, ToType, InOverloadResolution,
+ FromType, IncompatibleObjC)) {
// Pointer conversions (C++ 4.10).
SCS.Second = ICK_Pointer_Conversion;
SCS.IncompatibleObjC = IncompatibleObjC;
- } else if (IsMemberPointerConversion(From, FromType, ToType,
- InOverloadResolution, FromType)) {
+ } else if (S.IsMemberPointerConversion(From, FromType, ToType,
+ InOverloadResolution, FromType)) {
// Pointer to member conversions (4.11).
SCS.Second = ICK_Pointer_Member;
} else if (ToType->isBooleanType() &&
@@ -1055,16 +1101,16 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
FromType->isNullPtrType())) {
// Boolean conversions (C++ 4.12).
SCS.Second = ICK_Boolean_Conversion;
- FromType = Context.BoolTy;
- } else if (IsVectorConversion(Context, FromType, ToType, SecondICK)) {
+ FromType = S.Context.BoolTy;
+ } else if (IsVectorConversion(S.Context, FromType, ToType, SecondICK)) {
SCS.Second = SecondICK;
FromType = ToType.getUnqualifiedType();
- } else if (!getLangOptions().CPlusPlus &&
- Context.typesAreCompatible(ToType, FromType)) {
+ } else if (!S.getLangOptions().CPlusPlus &&
+ S.Context.typesAreCompatible(ToType, FromType)) {
// Compatible conversions (Clang extension for C function overloading)
SCS.Second = ICK_Compatible_Conversion;
FromType = ToType.getUnqualifiedType();
- } else if (IsNoReturnConversion(Context, FromType, ToType, FromType)) {
+ } else if (IsNoReturnConversion(S.Context, FromType, ToType, FromType)) {
// Treat a conversion that strips "noreturn" as an identity conversion.
SCS.Second = ICK_NoReturn_Adjustment;
} else {
@@ -1076,11 +1122,11 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
QualType CanonFrom;
QualType CanonTo;
// The third conversion can be a qualification conversion (C++ 4p1).
- if (IsQualificationConversion(FromType, ToType)) {
+ if (S.IsQualificationConversion(FromType, ToType)) {
SCS.Third = ICK_Qualification;
FromType = ToType;
- CanonFrom = Context.getCanonicalType(FromType);
- CanonTo = Context.getCanonicalType(ToType);
+ CanonFrom = S.Context.getCanonicalType(FromType);
+ CanonTo = S.Context.getCanonicalType(ToType);
} else {
// No conversion required
SCS.Third = ICK_Identity;
@@ -1089,8 +1135,8 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// [...] Any difference in top-level cv-qualification is
// subsumed by the initialization itself and does not constitute
// a conversion. [...]
- CanonFrom = Context.getCanonicalType(FromType);
- CanonTo = Context.getCanonicalType(ToType);
+ CanonFrom = S.Context.getCanonicalType(FromType);
+ CanonTo = S.Context.getCanonicalType(ToType);
if (CanonFrom.getLocalUnqualifiedType()
== CanonTo.getLocalUnqualifiedType() &&
(CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers()
@@ -1886,10 +1932,11 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) {
/// \param AllowExplicit true if the conversion should consider C++0x
/// "explicit" conversion functions as well as non-explicit conversion
/// functions (C++0x [class.conv.fct]p2).
-OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
- UserDefinedConversionSequence& User,
- OverloadCandidateSet& CandidateSet,
- bool AllowExplicit) {
+static OverloadingResult
+IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
+ UserDefinedConversionSequence& User,
+ OverloadCandidateSet& CandidateSet,
+ bool AllowExplicit) {
// Whether we will only visit constructors.
bool ConstructorsOnly = false;
@@ -1904,17 +1951,17 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
// functions are all the converting constructors (12.3.1) of
// that class. The argument list is the expression-list within
// the parentheses of the initializer.
- if (Context.hasSameUnqualifiedType(ToType, From->getType()) ||
+ if (S.Context.hasSameUnqualifiedType(ToType, From->getType()) ||
(From->getType()->getAs<RecordType>() &&
- IsDerivedFrom(From->getType(), ToType)))
+ S.IsDerivedFrom(From->getType(), ToType)))
ConstructorsOnly = true;
- if (RequireCompleteType(From->getLocStart(), ToType, PDiag())) {
+ if (S.RequireCompleteType(From->getLocStart(), ToType, S.PDiag())) {
// We're not going to find any constructors.
} else if (CXXRecordDecl *ToRecordDecl
= dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
DeclContext::lookup_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd) = LookupConstructors(ToRecordDecl);
+ for (llvm::tie(Con, ConEnd) = S.LookupConstructors(ToRecordDecl);
Con != ConEnd; ++Con) {
NamedDecl *D = *Con;
DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
@@ -1932,16 +1979,18 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
if (!Constructor->isInvalidDecl() &&