diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Sema.h | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 88 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 261 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 105 |
4 files changed, 430 insertions, 40 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 6360dcc44f1..3143b5c4829 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -499,6 +499,9 @@ public: void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet); + void AddArgumentDependentLookupCandidates(DeclarationName Name, + Expr **Args, unsigned NumArgs, + OverloadCandidateSet& CandidateSet); void AddOverloadCandidates(const OverloadedFunctionDecl *Ovl, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, @@ -514,11 +517,12 @@ public: bool Complain); void FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn); - FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, OverloadedFunctionDecl *Ovl, + FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Func, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, SourceLocation *CommaLocs, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + bool ArgumentDependentLookup); ExprResult BuildCallToMemberFunction(Scope *S, Expr *MemExpr, SourceLocation LParenLoc, Expr **Args, @@ -856,6 +860,14 @@ public: DeclarationName Name, LookupNameKind NameKind, bool RedeclarationOnly = false); + + typedef llvm::SmallPtrSet<NamespaceDecl *, 16> AssociatedNamespaceSet; + typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet; + + void FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs, + AssociatedNamespaceSet &AssociatedNamespaces, + AssociatedClassSet &AssociatedClasses); + bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name, SourceLocation NameLoc, SourceRange LookupRange = SourceRange()); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 36107e88ddd..24f7965b63c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1839,7 +1839,6 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, Expr **Args = reinterpret_cast<Expr**>(args.release()); assert(Fn && "no function call expression"); FunctionDecl *FDecl = NULL; - OverloadedFunctionDecl *Ovl = NULL; // Determine whether this is a dependent call inside a C++ template, // in which case we won't do any semantic analysis now. @@ -1851,6 +1850,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, else { // Resolve the CXXDependentNameExpr to an actual identifier; // it wasn't really a dependent name after all. + // FIXME: in the presence of ADL, this resolves too early. OwningExprResult Resolved = ActOnDeclarationNameExpr(S, FnName->getLocation(), FnName->getName(), @@ -1880,8 +1880,8 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, return Owned(BuildCallToObjectOfClassType(S, Fn, LParenLoc, Args, NumArgs, CommaLocs, RParenLoc)); - // Determine whether this is a call to a member function. if (getLangOptions().CPlusPlus) { + // Determine whether this is a call to a member function. if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(Fn->IgnoreParens())) if (isa<OverloadedFunctionDecl>(MemExpr->getMemberDecl()) || isa<CXXMethodDecl>(MemExpr->getMemberDecl())) @@ -1889,36 +1889,66 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, CommaLocs, RParenLoc)); } - // If we're directly calling a function or a set of overloaded - // functions, get the appropriate declaration. + // If we're directly calling a function, get the appropriate declaration. DeclRefExpr *DRExpr = NULL; - if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(Fn)) - DRExpr = dyn_cast<DeclRefExpr>(IcExpr->getSubExpr()); - else - DRExpr = dyn_cast<DeclRefExpr>(Fn); - - if (DRExpr) { - FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl()); - Ovl = dyn_cast<OverloadedFunctionDecl>(DRExpr->getDecl()); + Expr *FnExpr = Fn; + bool ADL = true; + while (true) { + if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(FnExpr)) + FnExpr = IcExpr->getSubExpr(); + else if (ParenExpr *PExpr = dyn_cast<ParenExpr>(FnExpr)) { + // FIXME: Where does the C++ standard say this? + ADL = false; + FnExpr = PExpr->getSubExpr(); + } else if (isa<UnaryOperator>(FnExpr) && + cast<UnaryOperator>(FnExpr)->getOpcode() + == UnaryOperator::AddrOf) { + FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr(); + } else { + DRExpr = dyn_cast<DeclRefExpr>(FnExpr); + break; + } } + + if (DRExpr) + FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl()); - if (Ovl) { - FDecl = ResolveOverloadedCallFn(Fn, Ovl, LParenLoc, Args, NumArgs, - CommaLocs, RParenLoc); - if (!FDecl) - return ExprError(); - - // Update Fn to refer to the actual function selected. - Expr *NewFn = 0; - if (QualifiedDeclRefExpr *QDRExpr = dyn_cast<QualifiedDeclRefExpr>(DRExpr)) - NewFn = new (Context) QualifiedDeclRefExpr(FDecl, FDecl->getType(), - QDRExpr->getLocation(), false, false, - QDRExpr->getSourceRange().getBegin()); - else - NewFn = new (Context) DeclRefExpr(FDecl, FDecl->getType(), - Fn->getSourceRange().getBegin()); - Fn->Destroy(Context); - Fn = NewFn; + if (getLangOptions().CPlusPlus && DRExpr && + (FDecl || isa<OverloadedFunctionDecl>(DRExpr->getDecl()))) { + // C++ [basic.lookup.argdep]p1: + // When an unqualified name is used as the postfix-expression in + // a function call (5.2.2), other namespaces not considered + // during the usual unqualified lookup (3.4.1) may be searched, + // and namespace-scope friend func- tion declarations (11.4) not + // otherwise visible may be found. + if (DRExpr && isa<QualifiedDeclRefExpr>(DRExpr)) + ADL = false; + + // We don't perform ADL for builtins. + if (FDecl && FDecl->getIdentifier() && + FDecl->getIdentifier()->getBuiltinID()) + ADL = false; + + if ((DRExpr && isa<OverloadedFunctionDecl>(DRExpr->getDecl())) || ADL) { + FDecl = ResolveOverloadedCallFn(Fn, DRExpr->getDecl(), LParenLoc, Args, + NumArgs, CommaLocs, RParenLoc, ADL); + if (!FDecl) + return ExprError(); + + // Update Fn to refer to the actual function selected. + Expr *NewFn = 0; + if (QualifiedDeclRefExpr *QDRExpr + = dyn_cast<QualifiedDeclRefExpr>(DRExpr)) + NewFn = new (Context) QualifiedDeclRefExpr(FDecl, FDecl->getType(), + QDRExpr->getLocation(), + false, false, + QDRExpr->getSourceRange().getBegin()); + else + NewFn = new (Context) DeclRefExpr(FDecl, FDecl->getType(), + Fn->getSourceRange().getBegin()); + Fn->Destroy(Context); + Fn = NewFn; + } } // Promote the function operand. diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index c8ecc171fd5..09431492b9c 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -17,9 +17,11 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/Expr.h" #include "clang/Parse/DeclSpec.h" #include "clang/Basic/LangOptions.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" #include <set> #include <vector> #include <iterator> @@ -1143,3 +1145,262 @@ bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name, // We can't reach here. return true; } + +// \brief Add the associated classes and namespaces for +// argument-dependent lookup with an argument of class type +// (C++ [basic.lookup.koenig]p2). +static void +addAssociatedClassesAndNamespaces(CXXRecordDecl *Class, + ASTContext &Context, + Sema::AssociatedNamespaceSet &AssociatedNamespaces, + Sema::AssociatedClassSet &AssociatedClasses) { + // C++ [basic.lookup.koenig]p2: + // [...] + // -- If T is a class type (including unions), its associated + // classes are: the class itself; the class of which it is a + // member, if any; and its direct and indirect base + // classes. Its associated namespaces are the namespaces in + // which its associated classes are defined. + + // Add the class of which it is a member, if any. + DeclContext *Ctx = Class->getDeclContext(); + if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx)) + AssociatedClasses.insert(EnclosingClass); + + // Add the associated namespace for this class. + while (Ctx->isRecord()) + Ctx = Ctx->getParent(); + if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx)) + AssociatedNamespaces.insert(EnclosingNamespace); + + // Add the class itself. If we've already seen this class, we don't + // need to visit base classes. + if (!AssociatedClasses.insert(Class)) + return; + + // FIXME: Handle class template specializations + + // Add direct and indirect base classes along with their associated + // namespaces. + llvm::SmallVector<CXXRecordDecl *, 32> Bases; + Bases.push_back(Class); + while (!Bases.empty()) { + // Pop this class off the stack. + Class = Bases.back(); + Bases.pop_back(); + + // Visit the base classes. + for (CXXRecordDecl::base_class_iterator Base = Class->bases_begin(), + BaseEnd = Class->bases_end(); + Base != BaseEnd; ++Base) { + const RecordType *BaseType = Base->getType()->getAsRecordType(); + CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(BaseType->getDecl()); + if (AssociatedClasses.insert(BaseDecl)) { + // Find the associated namespace for this base class. + DeclContext *BaseCtx = BaseDecl->getDeclContext(); + while (BaseCtx->isRecord()) + BaseCtx = BaseCtx->getParent(); + if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(BaseCtx)) + AssociatedNamespaces.insert(EnclosingNamespace); + + // Make sure we visit the bases of this base class. + if (BaseDecl->bases_begin() != BaseDecl->bases_end()) + Bases.push_back(BaseDecl); + } + } + } +} + +// \brief Add the associated classes and namespaces for +// argument-dependent lookup with an argument of type T +// (C++ [basic.lookup.koenig]p2). +static void +addAssociatedClassesAndNamespaces(QualType T, + ASTContext &Context, + Sema::AssociatedNamespaceSet &AssociatedNamespaces, + Sema::AssociatedClassSet &AssociatedClasses) { + // C++ [basic.lookup.koenig]p2: + // + // For each argument type T in the function call, there is a set + // of zero or more associated namespaces and a set of zero or more + // associated classes to be considered. The sets of namespaces and + // classes is determined entirely by the types of the function + // arguments (and the namespace of any template template + // argument). Typedef names and using-declarations used to specify + // the types do not contribute to this set. The sets of namespaces + // and classes are determined in the following way: + T = Context.getCanonicalType(T).getUnqualifiedType(); + + // -- If T is a pointer to U or an array of U, its associated + // namespaces and classes are those associated with U. + // + // We handle this by unwrapping pointer and array types immediately, + // to avoid unnecessary recursion. + while (true) { + if (const PointerType *Ptr = T->getAsPointerType()) + T = Ptr->getPointeeType(); + else if (const ArrayType *Ptr = Context.getAsArrayType(T)) + T = Ptr->getElementType(); + else + break; + } + + // -- If T is a fundamental type, its associated sets of + // namespaces and classes are both empty. + if (T->getAsBuiltinType()) + return; + + // -- If T is a class type (including unions), its associated + // classes are: the class itself; the class of which it is a + // member, if any; and its direct and indirect base + // classes. Its associated namespaces are the namespaces in + // which its associated classes are defined. + if (const CXXRecordType *ClassType + = dyn_cast_or_null<CXXRecordType>(T->getAsRecordType())) { + addAssociatedClassesAndNamespaces(ClassType->getDecl(), + Context, AssociatedNamespaces, + AssociatedClasses); + return; + } + + // -- If T is an enumeration type, its associated namespace is + // the namespace in which it is defined. If it is class + // member, its associated class is the member’s class; else + // it has no associated class. + if (const EnumType *EnumT = T->getAsEnumType()) { + EnumDecl *Enum = EnumT->getDecl(); + + DeclContext *Ctx = Enum->getDeclContext(); + if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx)) + AssociatedClasses.insert(EnclosingClass); + + // Add the associated namespace for this class. + while (Ctx->isRecord()) + Ctx = Ctx->getParent(); + if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx)) + AssociatedNamespaces.insert(EnclosingNamespace); + + return; + } + + // -- If T is a function type, its associated namespaces and + // classes are those associated with the function parameter + // types and those associated with the return type. + if (const FunctionType *FunctionType = T->getAsFunctionType()) { + // Return type + addAssociatedClassesAndNamespaces(FunctionType->getResultType(), + Context, + AssociatedNamespaces, AssociatedClasses); + + const FunctionTypeProto *Proto = dyn_cast<FunctionTypeProto>(FunctionType); + if (!Proto) + return; + + // Argument types + for (FunctionTypeProto::arg_type_iterator Arg = Proto->arg_type_begin(), + ArgEnd = Proto->arg_type_end(); + Arg != ArgEnd; ++Arg) + addAssociatedClassesAndNamespaces(*Arg, Context, + AssociatedNamespaces, AssociatedClasses); + + return; + } + + // -- If T is a pointer to a member function of a class X, its + // associated namespaces and classes are those associated + // with the function parameter types and return type, + // together with those associated with X. + // + // -- If T is a pointer to a data member of class X, its + // associated namespaces and classes are those associated + // with the member type together with those associated with + // X. + if (const MemberPointerType *MemberPtr = T->getAsMemberPointerType()) { + // Handle the type that the pointer to member points to. + addAssociatedClassesAndNamespaces(MemberPtr->getPointeeType(), + Context, + AssociatedNamespaces, AssociatedClasses); + + // Handle the class type into which this points. + if (const RecordType *Class = MemberPtr->getClass()->getAsRecordType()) + addAssociatedClassesAndNamespaces(cast<CXXRecordDecl>(Class->getDecl()), + Context, + AssociatedNamespaces, AssociatedClasses); + + return; + } + + // FIXME: What about block pointers? + // FIXME: What about Objective-C message sends? +} + +/// \brief Find the associated classes and namespaces for +/// argument-dependent lookup for a call with the given set of +/// arguments. +/// +/// This routine computes the sets of associated classes and associated +/// namespaces searched by argument-dependent lookup +/// (C++ [basic.lookup.argdep]) for a given set of arguments. +void +Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs, + AssociatedNamespaceSet &AssociatedNamespaces, + AssociatedClassSet &AssociatedClasses) { + AssociatedNamespaces.clear(); + AssociatedClasses.clear(); + + // C++ [basic.lookup.koenig]p2: + // For each argument type T in the function call, there is a set + // of zero or more associated namespaces and a set of zero or more + // associated classes to be considered. The sets of namespaces and + // classes is determined entirely by the types of the function + // arguments (and the namespace of any template template + // argument). + for (unsigned ArgIdx = 0; ArgIdx != NumArgs; ++ArgIdx) { + Expr *Arg = Args[ArgIdx]; + + if (Arg->getType() != Context.OverloadTy) { + addAssociatedClassesAndNamespaces(Arg->getType(), Context, + AssociatedNamespaces, AssociatedClasses); + continue; + } + + // [...] In addition, if the argument is the name or address of a + // set of overloaded functions and/or function templates, its + // associated classes and namespaces are the union of those + // associated with each of the members of the set: the namespace + // in which the function or function template is defined and the + // classes and namespaces associated with its (non-dependent) + // parameter types and return type. + DeclRefExpr *DRE = 0; + if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg)) { + if (unaryOp->getOpcode() == UnaryOperator::AddrOf) + DRE = dyn_cast<DeclRefExpr>(unaryOp->getSubExpr()); + } else + DRE = dyn_cast<DeclRefExpr>(Arg); + if (!DRE) + continue; + + OverloadedFunctionDecl *Ovl + = dyn_cast<OverloadedFunctionDecl>(DRE->getDecl()); + if (!Ovl) + continue; + + for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(), + FuncEnd = Ovl->function_end(); + Func != FuncEnd; ++Func) { + FunctionDecl *FDecl = cast<FunctionDecl>(*Func); + + // Add the namespace in which this function was defined. Note + // that, if this is a member function, we do *not* consider the + // enclosing namespace of its class. + DeclContext *Ctx = FDecl->getDeclContext(); + if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx)) + AssociatedNamespaces.insert(EnclosingNamespace); + + // Add the classes and namespaces associated with the parameter + // types and return type of this function. + addAssociatedClassesAndNamespaces(FDecl->getType(), Context, + AssociatedNamespaces, AssociatedClasses); + } + } +} diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 7219f19a97c..293e9c3c24b 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -2301,6 +2301,9 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S, // of type T2 or “reference to (possibly cv-qualified) T2”, // when T2 is an enumeration type, are candidate functions. { + // FIXME: Don't use the IdentifierResolver here! We need to + // perform proper, unqualified lookup starting with the first + // enclosing non-class scope. IdentifierResolver::iterator I = IdResolver.begin(OpName), IEnd = IdResolver.end(); for (; I != IEnd; ++I) { @@ -2327,6 +2330,11 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S, /*SuppressUserConversions=*/false); } } + + // Since the set of non-member candidates corresponds to + // *unqualified* lookup of the operator name, we also perform + // argument-dependent lookup. + AddArgumentDependentLookupCandidates(OpName, Args, NumArgs, CandidateSet); } // Add builtin overload candidates (C++ [over.built]). @@ -3153,6 +3161,75 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, } } +/// \brief Add function candidates found via argument-dependent lookup +/// to the set of overloading candidates. +/// +/// This routine performs argument-dependent name lookup based on the +/// given function name (which may also be an operator name) and adds +/// all of the overload candidates found by ADL to the overload +/// candidate set (C++ [basic.lookup.argdep]). +void +Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, + Expr **Args, unsigned NumArgs, + OverloadCandidateSet& CandidateSet) { + // Find all of the associated namespaces and classes based on the + // arguments we have. + AssociatedNamespaceSet AssociatedNamespaces; + AssociatedClassSet AssociatedClasses; + FindAssociatedClassesAndNamespaces(Args, NumArgs, + AssociatedNamespaces, AssociatedClasses); + + // C++ [basic.lookup.argdep]p3: + // + // Let X be the lookup set produced by unqualified lookup (3.4.1) + // and let Y be the lookup set produced by argument dependent + // lookup (defined as follows). If X contains [...] then Y is + // empty. Otherwise Y is the set of declarations found in the + // namespaces associated with the argument types as described + // below. The set of declarations found by the lookup of the name + // is the union of X and Y. + // + // Here, we compute Y and add its members to the overloaded + // candidate set. + llvm::SmallPtrSet<FunctionDecl *, 16> KnownCandidates; + for (AssociatedNamespaceSet::iterator NS = AssociatedNamespaces.begin(), + NSEnd = AssociatedNamespaces.end(); + NS != NSEnd; ++NS) { + // When considering an associated namespace, the lookup is the + // same as the lookup performed when the associated namespace is + // used as a qualifier (3.4.3.2) except that: + // + // -- Any using-directives in the associated namespace are + // ignored. + // + // -- FIXME: Any namespace-scope friend functions declared in + // associated classes are visible within their respective + // namespaces even if they are not visible during an ordinary + // lookup (11.4). + DeclContext::lookup_iterator I, E; + for (llvm::tie(I, E) = (*NS)->lookup(Name); I != E; ++I) { + FunctionDecl *Func = dyn_cast<FunctionDecl>(*I); + if (!Func) + break; + + if (KnownCandidates.empty()) { + // Record all of the function candidates that we've already + // added to the overload set, so that we don't add those same + // candidates a second time. + for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(), + CandEnd = CandidateSet.end(); + Cand != CandEnd; ++Cand) + KnownCandidates.insert(Cand->Function); + } + + // If we haven't seen this function before, add it as a + // candidate. + if (KnownCandidates.insert(Func)) + AddOverloadCandidate(Func, Args, NumArgs, CandidateSet); + } + } +} + /// AddOverloadCandidates - Add all of the function overloads in Ovl /// to the candidate set. void @@ -3419,19 +3496,29 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, } /// ResolveOverloadedCallFn - Given the call expression that calls Fn -/// (which eventually refers to the set of overloaded functions in -/// Ovl) and the call arguments Args/NumArgs, attempt to resolve the -/// function call down to a specific function. If overload resolution -/// succeeds, returns the function declaration produced by overload +/// (which eventually refers to the declaration Func) and the call +/// arguments Args/NumArgs, attempt to resolve the function call down +/// to a specific function. If overload resolution succeeds, returns +/// the function declaration produced by overload /// resolution. Otherwise, emits diagnostics, deletes all of the /// arguments and Fn, and returns NULL. -FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, OverloadedFunctionDecl *Ovl, +FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, SourceLocation *CommaLocs, - SourceLocation RParenLoc) { + SourceLocation RParenLoc, + bool ArgumentDependentLookup) { OverloadCandidateSet CandidateSet; - AddOverloadCandidates(Ovl, Args, NumArgs, CandidateSet); + if (OverloadedFunctionDecl *Ovl + = dyn_cast_or_null<OverloadedFunctionDecl>(Callee)) + AddOverloadCandidates(Ovl, Args, NumArgs, CandidateSet); + else if (FunctionDecl *Func = dyn_cast_or_null<FunctionDecl>(Callee)) + AddOverloadCandidate(cast<FunctionDecl>(Func), Args, NumArgs, CandidateSet); + + if (ArgumentDependentLookup) + AddArgumentDependentLookupCandidates(Callee->getDeclName(), Args, NumArgs, + CandidateSet); + OverloadCandidateSet::iterator Best; switch (BestViableFunction(CandidateSet, Best)) { case OR_Success: @@ -3440,14 +3527,14 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, OverloadedFunctionDecl *Ov case OR_No_Viable_Function: Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_no_viable_function_in_call) - << Ovl->getDeclName() << (unsigned)CandidateSet.size() + << Callee->getDeclName() << (unsigned)CandidateSet.size() << Fn->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false); break; case OR_Ambiguous: Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_ambiguous_call) - << Ovl->getDeclName() << Fn->getSourceRange(); + << Callee->getDeclName() << Fn->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); break; } |