[cfe-commits] r89061 - in /cfe/trunk/lib/Sema: Sema.h SemaLookup.cpp SemaOverload.cpp

John McCall rjmccall at apple.com
Mon Nov 16 23:50:12 PST 2009


Author: rjmccall
Date: Tue Nov 17 01:50:12 2009
New Revision: 89061

URL: http://llvm.org/viewvc/llvm-project?rev=89061&view=rev
Log:
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.


Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=89061&r1=89060&r2=89061&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Nov 17 01:50:12 2009
@@ -873,6 +873,11 @@
                              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 @@
 
     /// \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 @@
     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.

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=89061&r1=89060&r2=89061&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Nov 17 01:50:12 2009
@@ -254,21 +254,21 @@
 
   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 @@
     }
   }
 
+  // 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 @@
 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 @@
     = 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));

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=89061&r1=89060&r2=89061&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Nov 17 01:50:12 2009
@@ -2367,6 +2367,33 @@
   }
 }
 
+/// 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 @@
     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 @@
 
   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:





More information about the cfe-commits mailing list