summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorGeorge Burgess IV <george.burgess.iv@gmail.com>2016-03-19 21:36:10 +0000
committerGeorge Burgess IV <george.burgess.iv@gmail.com>2016-03-19 21:36:10 +0000
commit3cde9bf9d5734820c1f17981fd235ed98772124a (patch)
tree80c9f2a4d458386761b81a6190bb5a1d24865bc1 /clang/lib/Sema/SemaOverload.cpp
parent43165d913aeb61e32877c0d3e9dafa3d926b8c4d (diff)
downloadbcm5719-llvm-3cde9bf9d5734820c1f17981fd235ed98772124a.tar.gz
bcm5719-llvm-3cde9bf9d5734820c1f17981fd235ed98772124a.zip
[Sema] Allow casting of some overloaded functions
Some functions can't have their address taken. If we encounter an overload set where only one of the candidates can have its address taken, we should automatically select that candidate in cast expressions. Differential Revision: http://reviews.llvm.org/D17701 llvm-svn: 263887
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r--clang/lib/Sema/SemaOverload.cpp38
1 files changed, 37 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index a28ded474a7..3bb9a26c438 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10419,7 +10419,7 @@ private:
return false;
QualType ResultTy;
- if (Context.hasSameUnqualifiedType(TargetFunctionType,
+ if (Context.hasSameUnqualifiedType(TargetFunctionType,
FunDecl->getType()) ||
S.IsNoReturnConversion(FunDecl->getType(), TargetFunctionType,
ResultTy) ||
@@ -10652,6 +10652,42 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr,
}
/// \brief Given an expression that refers to an overloaded function, try to
+/// resolve that function to a single function that can have its address taken.
+/// This will modify `Pair` iff it returns non-null.
+///
+/// This routine can only realistically succeed if all but one candidates in the
+/// overload set for SrcExpr cannot have their addresses taken.
+FunctionDecl *
+Sema::resolveAddressOfOnlyViableOverloadCandidate(Expr *E,
+ DeclAccessPair &Pair) {
+ OverloadExpr::FindResult R = OverloadExpr::find(E);
+ OverloadExpr *Ovl = R.Expression;
+ FunctionDecl *Result = nullptr;
+ DeclAccessPair DAP;
+ // Don't use the AddressOfResolver because we're specifically looking for
+ // cases where we have one overload candidate that lacks
+ // enable_if/pass_object_size/...
+ for (auto I = Ovl->decls_begin(), E = Ovl->decls_end(); I != E; ++I) {
+ auto *FD = dyn_cast<FunctionDecl>(I->getUnderlyingDecl());
+ if (!FD)
+ return nullptr;
+
+ if (!checkAddressOfFunctionIsAvailable(FD))
+ continue;
+
+ // We have more than one result; quit.
+ if (Result)
+ return nullptr;
+ DAP = I.getPair();
+ Result = FD;
+ }
+
+ if (Result)
+ Pair = DAP;
+ return Result;
+}
+
+/// \brief Given an expression that refers to an overloaded function, try to
/// resolve that overloaded function expression down to a single function.
///
/// This routine can only resolve template-ids that refer to a single function
OpenPOWER on IntegriCloud