diff options
author | John McCall <rjmccall@apple.com> | 2009-11-17 07:50:12 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-11-17 07:50:12 +0000 |
commit | 314be4e7d8ef86202b0ec8e9ff0dcef853db3320 (patch) | |
tree | bc40ef33ff7c555ca0b74e30ca124be4581f2cef | |
parent | c5419cc8655c215c8c0c8dc3976a527ca867f655 (diff) |
Store "sugared" decls in LookupResults (i.e. decl aliases like using declarations);
strip the sugar off in getFoundDecl() and getAsSingleDecl(), but leave it on for
clients like overload resolution who want to use the iterators.
Refactor a few pieces of overload resolution to strip off using declarations in
a single place. Don't do anything useful with the extra context knowledge yet.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89061 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/Sema.h | 22 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 23 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 56 |
3 files changed, 53 insertions, 48 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index fea6f80e54..ab8e58754e 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -873,6 +873,11 @@ public: Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions = false); + void AddMethodCandidate(NamedDecl *Decl, + Expr *Object, Expr **Args, unsigned NumArgs, + OverloadCandidateSet& CandidateSet, + bool SuppressUserConversion = false, + bool ForceRValue = false); void AddMethodCandidate(CXXMethodDecl *Method, Expr *Object, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, @@ -1282,20 +1287,7 @@ public: /// \brief Add a declaration to these results. void addDecl(NamedDecl *D) { - // "Flatten" overloaded function declarations to get the underlying - // functions. - // FIXME: This may not be necessary with the impending using-declarations - // rewrite (11/09). - if (OverloadedFunctionDecl *Ovl - = dyn_cast<OverloadedFunctionDecl>(D->getUnderlyingDecl())) { - for (OverloadedFunctionDecl::function_iterator - F = Ovl->function_begin(), - FEnd = Ovl->function_end(); - F != FEnd; ++F) { - Decls.push_back(*F); - } - } else - Decls.push_back(D->getUnderlyingDecl()); + Decls.push_back(D); ResultKind = Found; } @@ -1339,7 +1331,7 @@ public: NamedDecl *getFoundDecl() const { assert(getResultKind() == Found && "getFoundDecl called on non-unique result"); - return *Decls.begin(); + return Decls[0]->getUnderlyingDecl(); } /// \brief Asks if the result is a single tag decl. diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 58b95fc679..70dca799ae 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -254,21 +254,21 @@ void Sema::LookupResult::resolveKind() { bool Ambiguous = false; bool HasTag = false, HasFunction = false, HasNonFunction = false; + bool HasUnresolved = false; unsigned UniqueTagIndex = 0; unsigned I = 0; while (I < N) { - NamedDecl *D = Decls[I]; - assert(D == D->getUnderlyingDecl()); + NamedDecl *D = Decls[I]->getUnderlyingDecl(); + D = cast<NamedDecl>(D->getCanonicalDecl()); - NamedDecl *CanonD = cast<NamedDecl>(D->getCanonicalDecl()); - if (!Unique.insert(CanonD)) { + if (!Unique.insert(D)) { // If it's not unique, pull something off the back (and // continue at this index). Decls[I] = Decls[--N]; } else if (isa<UnresolvedUsingDecl>(D)) { - // FIXME: proper support for UnresolvedUsingDecls. + HasUnresolved = true; Decls[I] = Decls[--N]; } else { // Otherwise, do some decl type analysis and then continue. @@ -288,6 +288,13 @@ void Sema::LookupResult::resolveKind() { } } + // Postpone all other decisions if we have an unresolved decl, even + // if we can prove ambiguity. We can probably do better than this. + if (HasUnresolved) { + ResultKind = LookupResult::FoundOverloaded; + return; + } + // C++ [basic.scope.hiding]p2: // A class name or enumeration name can be hidden by the name of // an object, function, or enumerator declared in the same @@ -329,7 +336,7 @@ void Sema::LookupResult::resolveKind() { NamedDecl *Sema::LookupResult::getAsSingleDecl(ASTContext &C) const { size_t size = Decls.size(); if (size == 0) return 0; - if (size == 1) return *begin(); + if (size == 1) return (*begin())->getUnderlyingDecl(); if (isAmbiguous()) return 0; @@ -339,9 +346,7 @@ NamedDecl *Sema::LookupResult::getAsSingleDecl(ASTContext &C) const { = OverloadedFunctionDecl::Create(C, (*I)->getDeclContext(), (*I)->getDeclName()); for (; I != E; ++I) { - NamedDecl *ND = *I; - assert(ND->getUnderlyingDecl() == ND - && "decls in lookup result should have redirections stripped"); + NamedDecl *ND = (*I)->getUnderlyingDecl(); assert(ND->isFunctionOrFunctionTemplate()); if (isa<FunctionDecl>(ND)) Ovl->addOverload(cast<FunctionDecl>(ND)); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 804a5fc87c..cae7516012 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -2367,6 +2367,33 @@ void Sema::AddFunctionCandidates(const FunctionSet &Functions, } } +/// AddMethodCandidate - Adds a named decl (which is some kind of +/// method) as a method candidate to the given overload set. +void Sema::AddMethodCandidate(NamedDecl *Decl, Expr *Object, + Expr **Args, unsigned NumArgs, + OverloadCandidateSet& CandidateSet, + bool SuppressUserConversions, bool ForceRValue) { + + // FIXME: use this + //DeclContext *ActingContext = Decl->getDeclContext(); + + if (isa<UsingShadowDecl>(Decl)) + Decl = cast<UsingShadowDecl>(Decl)->getTargetDecl(); + + if (FunctionTemplateDecl *TD = dyn_cast<FunctionTemplateDecl>(Decl)) { + assert(isa<CXXMethodDecl>(TD->getTemplatedDecl()) && + "Expected a member function template"); + AddMethodTemplateCandidate(TD, false, 0, 0, + Object, Args, NumArgs, + CandidateSet, + SuppressUserConversions, + ForceRValue); + } else { + AddMethodCandidate(cast<CXXMethodDecl>(Decl), Object, Args, NumArgs, + CandidateSet, SuppressUserConversions, ForceRValue); + } +} + /// AddMethodCandidate - Adds the given C++ member function to the set /// of candidate functions, using the given function call arguments /// and the object argument (@c Object). For example, in a call @@ -2840,21 +2867,9 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, for (LookupResult::iterator Oper = Operators.begin(), OperEnd = Operators.end(); Oper != OperEnd; - ++Oper) { - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Oper)) { - AddMethodCandidate(Method, Args[0], Args+1, NumArgs - 1, CandidateSet, - /*SuppressUserConversions=*/false); - continue; - } - - assert(isa<FunctionTemplateDecl>(*Oper) && - isa<CXXMethodDecl>(cast<FunctionTemplateDecl>(*Oper) - ->getTemplatedDecl()) && - "Expected a member function template"); - AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(*Oper), false, 0, 0, - Args[0], Args+1, NumArgs - 1, CandidateSet, - /*SuppressUserConversions=*/false); - } + ++Oper) + AddMethodCandidate(*Oper, Args[0], Args + 1, NumArgs - 1, CandidateSet, + /* SuppressUserConversions = */ false); } } @@ -5267,15 +5282,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { - if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*Oper)) { - AddMethodTemplateCandidate(FunTmpl, false, 0, 0, Object, Args, NumArgs, - CandidateSet, - /*SuppressUserConversions=*/false); - continue; - } - - AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs, - CandidateSet, /*SuppressUserConversions=*/false); + AddMethodCandidate(*Oper, Object, Args, NumArgs, CandidateSet, + /*SuppressUserConversions=*/ false); } // C++ [over.call.object]p2: |