aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-03-12 01:48:56 +0000
committerDouglas Gregor <dgregor@apple.com>2011-03-12 01:48:56 +0000
commitfadb53b351977ca7f99a9a613596cba6531979a3 (patch)
tree62eb086a53b3804a617c98061b19b12fe45b911c /lib/Sema
parent5a5b38f4afaf4f203b96a11ba79890c7cd4cc4b8 (diff)
Fixes for some more expressions containing function templateids that
should be resolvable, from Faisal Vali! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127521 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaCXXCast.cpp62
-rw-r--r--lib/Sema/SemaExpr.cpp40
-rw-r--r--lib/Sema/SemaOverload.cpp38
3 files changed, 83 insertions, 57 deletions
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index 5b28bc3d9f..557d27a943 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -128,17 +128,6 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr,
CastKind &Kind);
-static ExprResult
-ResolveAndFixSingleFunctionTemplateSpecialization(
- Sema &Self, Expr *SrcExpr,
- bool DoFunctionPointerConverion = false,
- bool Complain = false,
- const SourceRange& OpRangeForComplaining = SourceRange(),
- QualType DestTypeForComplaining = QualType(),
- unsigned DiagIDForComplaining = 0);
-
-
-
/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
ExprResult
Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
@@ -617,7 +606,7 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
Self.IgnoredValueConversions(SrcExpr);
if (SrcExpr->getType() == Self.Context.OverloadTy) {
ExprResult SingleFunctionExpression =
- ResolveAndFixSingleFunctionTemplateSpecialization(Self, SrcExpr,
+ Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
false, // Decay Function to ptr
true, // Complain
OpRange, DestType, diag::err_bad_static_cast_overload);
@@ -1260,41 +1249,8 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
return TC_Success;
}
-// A helper function to resolve and fix an overloaded expression that
-// can be resolved because it identifies a single function
-// template specialization
-// Last three arguments should only be supplied if Complain = true
-static ExprResult ResolveAndFixSingleFunctionTemplateSpecialization(
- Sema &Self, Expr *SrcExpr,
- bool DoFunctionPointerConverion,
- bool Complain,
- const SourceRange& OpRangeForComplaining,
- QualType DestTypeForComplaining,
- unsigned DiagIDForComplaining) {
- assert(SrcExpr->getType() == Self.Context.OverloadTy);
- DeclAccessPair Found;
- Expr* SingleFunctionExpression = 0;
- if (FunctionDecl* Fn = Self.ResolveSingleFunctionTemplateSpecialization(
- SrcExpr, false, // false -> Complain
- &Found)) {
- if (!Self.DiagnoseUseOfDecl(Fn, SrcExpr->getSourceRange().getBegin())) {
- // mark the expression as resolved to Fn
- SingleFunctionExpression = Self.FixOverloadedFunctionReference(SrcExpr,
- Found, Fn);
-
- if (DoFunctionPointerConverion)
- Self.DefaultFunctionArrayLvalueConversion(SingleFunctionExpression);
- }
- }
- if (!SingleFunctionExpression && Complain) {
- OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression;
- Self.Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining)
- << oe->getName() << DestTypeForComplaining << OpRangeForComplaining
- << oe->getQualifierLoc().getSourceRange();
- Self.NoteAllOverloadCandidates(SrcExpr);
- }
- return SingleFunctionExpression;
-}
+
+
static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr,
QualType DestType, bool CStyle,
@@ -1311,7 +1267,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr,
if (SrcType == Self.Context.OverloadTy) {
// ... unless foo<int> resolves to an lvalue unambiguously
ExprResult SingleFunctionExpr =
- ResolveAndFixSingleFunctionTemplateSpecialization(Self, SrcExpr,
+ Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
Expr::getValueKindForType(DestType) == VK_RValue // Convert Fun to Ptr
);
if (SingleFunctionExpr.isUsable()) {
@@ -1544,11 +1500,11 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
bool ret = false; // false is 'able to convert'
if (CastExpr->getType() == Context.OverloadTy) {
ExprResult SingleFunctionExpr =
- ResolveAndFixSingleFunctionTemplateSpecialization(*this,
- CastExpr,
- /* Decay Function to ptr */ false,
- /* Complain */ true,
- R, CastTy, diag::err_bad_cstyle_cast_overload);
+ ResolveAndFixSingleFunctionTemplateSpecialization(
+ CastExpr, /* Decay Function to ptr */ false,
+ /* Complain */ true, R, CastTy,
+ diag::err_bad_cstyle_cast_overload);
+
if (SingleFunctionExpr.isUsable()) {
CastExpr = SingleFunctionExpr.release();
Kind = CK_ToVoid;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 8a532f0363..546d2e7e38 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -5321,9 +5321,10 @@ bool Sema::DiagnoseConditionalForNull(Expr *LHS, Expr *RHS,
QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
ExprValueKind &VK, ExprObjectKind &OK,
SourceLocation QuestionLoc) {
- // If both LHS and RHS are overloaded functions, try to resolve them.
- if (Context.hasSameType(LHS->getType(), RHS->getType()) &&
- LHS->getType()->isSpecificBuiltinType(BuiltinType::Overload)) {
+
+ // If either LHS or RHS are overloaded functions, try to resolve them.
+ if (LHS->getType() == Context.OverloadTy ||
+ RHS->getType() == Context.OverloadTy) {
ExprResult LHSResult = CheckPlaceholderExpr(LHS, QuestionLoc);
if (LHSResult.isInvalid())
return QualType();
@@ -6313,6 +6314,10 @@ QualType Sema::InvalidOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
Diag(Loc, diag::err_typecheck_invalid_operands)
<< lex->getType() << rex->getType()
<< lex->getSourceRange() << rex->getSourceRange();
+ if (lex->getType() == Context.OverloadTy)
+ NoteAllOverloadCandidates(lex);
+ if (rex->getType() == Context.OverloadTy)
+ NoteAllOverloadCandidates(rex);
return QualType();
}
@@ -6789,12 +6794,14 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
QualType lType = lex->getType();
QualType rType = rex->getType();
-
+
Expr *LHSStripped = lex->IgnoreParenImpCasts();
Expr *RHSStripped = rex->IgnoreParenImpCasts();
QualType LHSStrippedType = LHSStripped->getType();
QualType RHSStrippedType = RHSStripped->getType();
+
+
// Two different enums will raise a warning when compared.
if (const EnumType *LHSEnumType = LHSStrippedType->getAs<EnumType>()) {
if (const EnumType *RHSEnumType = RHSStrippedType->getAs<EnumType>()) {
@@ -8033,6 +8040,26 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
ExprValueKind VK = VK_RValue;
ExprObjectKind OK = OK_Ordinary;
+ // Check if a 'foo<int>' involved in a binary op, identifies a single
+ // function unambiguously (i.e. an lvalue ala 13.4)
+ // But since an assignment can trigger target based overload, exclude it in
+ // our blind search. i.e:
+ // template<class T> void f(); template<class T, class U> void f(U);
+ // f<int> == 0; // resolve f<int> blindly
+ // void (*p)(int); p = f<int>; // resolve f<int> using target
+ if (Opc != BO_Assign) {
+ if (lhs->getType() == Context.OverloadTy) {
+ ExprResult resolvedLHS =
+ ResolveAndFixSingleFunctionTemplateSpecialization(lhs);
+ if (resolvedLHS.isUsable()) lhs = resolvedLHS.release();
+ }
+ if (rhs->getType() == Context.OverloadTy) {
+ ExprResult resolvedRHS =
+ ResolveAndFixSingleFunctionTemplateSpecialization(rhs);
+ if (resolvedRHS.isUsable()) rhs = resolvedRHS.release();
+ }
+ }
+
switch (Opc) {
case BO_Assign:
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, QualType());
@@ -8390,6 +8417,11 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
resultType = CheckAddressOfOperand(*this, Input, OpLoc);
break;
case UO_Deref:
+ if (Input->getType() == Context.OverloadTy ) {
+ ExprResult er = ResolveAndFixSingleFunctionTemplateSpecialization(Input);
+ if (er.isUsable())
+ Input = er.release();
+ }
DefaultFunctionArrayLvalueConversion(Input);
resultType = CheckIndirectionOperand(*this, Input, VK, OpLoc);
break;
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index bf24b74848..d746c7bb1e 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -7490,6 +7490,44 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From,
return Matched;
}
+
+
+
+// Resolve and fix an overloaded expression that
+// can be resolved because it identifies a single function
+// template specialization
+// Last three arguments should only be supplied if Complain = true
+ExprResult Sema::ResolveAndFixSingleFunctionTemplateSpecialization(
+ Expr *SrcExpr, bool DoFunctionPointerConverion, bool Complain,
+ const SourceRange& OpRangeForComplaining,
+ QualType DestTypeForComplaining,
+ unsigned DiagIDForComplaining ) {
+
+ assert(SrcExpr->getType() == Context.OverloadTy);
+
+ DeclAccessPair Found;
+ Expr* SingleFunctionExpression = 0;
+ if (FunctionDecl* Fn = ResolveSingleFunctionTemplateSpecialization(
+ SrcExpr, false, // false -> Complain
+ &Found)) {
+ if (!DiagnoseUseOfDecl(Fn, SrcExpr->getSourceRange().getBegin())) {
+ // mark the expression as resolved to Fn
+ SingleFunctionExpression = FixOverloadedFunctionReference(SrcExpr,
+ Found, Fn);
+ if (DoFunctionPointerConverion)
+ DefaultFunctionArrayLvalueConversion(SingleFunctionExpression);
+ }
+ }
+ if (!SingleFunctionExpression && Complain) {
+ OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression;
+ Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining)
+ << oe->getName() << DestTypeForComplaining << OpRangeForComplaining
+ << oe->getQualifierLoc().getSourceRange();
+ NoteAllOverloadCandidates(SrcExpr);
+ }
+ return SingleFunctionExpression;
+}
+
/// \brief Add a single candidate to the overload set.
static void AddOverloadedCallCandidate(Sema &S,
DeclAccessPair FoundDecl,