[cfe-commits] r83674 - in /cfe/trunk: lib/AST/Decl.cpp lib/Sema/Sema.h lib/Sema/SemaAttr.cpp lib/Sema/SemaCXXScopeSpec.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaLookup.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaCXX/class-names.cpp

John McCall rjmccall at apple.com
Fri Oct 9 14:13:30 PDT 2009


Author: rjmccall
Date: Fri Oct  9 16:13:30 2009
New Revision: 83674

URL: http://llvm.org/viewvc/llvm-project?rev=83674&view=rev
Log:
Refactor the LookupResult API to simplify most common operations.  Require users to 
pass a LookupResult reference to lookup routines.  Call out uses which assume a single
result.


Modified:
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaAttr.cpp
    cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/SemaCXX/class-names.cpp

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=83674&r1=83673&r2=83674&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri Oct  9 16:13:30 2009
@@ -299,6 +299,9 @@
   if (isa<ObjCMethodDecl>(this))
     return false;
 
+  if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
+    return true;
+
   // For non-function declarations, if the declarations are of the
   // same kind then this must be a redeclaration, or semantic analysis
   // would not have given us the new declaration.

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Oct  9 16:13:30 2009
@@ -1045,63 +1045,13 @@
   /// results occurred for a given lookup.
   ///
   /// Any non-ambiguous lookup can be converted into a single
-  /// (possibly NULL) @c NamedDecl* via a conversion function or the
-  /// getAsDecl() method. This conversion permits the common-case
-  /// usage in C and Objective-C where name lookup will always return
-  /// a single declaration.
-  struct LookupResult {
-    /// The kind of entity that is actually stored within the
-    /// LookupResult object.
-    enum {
-      /// First is a single declaration (a NamedDecl*), which may be NULL.
-      SingleDecl,
-
-      /// First is a single declaration (an OverloadedFunctionDecl*).
-      OverloadedDeclSingleDecl,
-
-      /// [First, Last) is an iterator range represented as opaque
-      /// pointers used to reconstruct IdentifierResolver::iterators.
-      OverloadedDeclFromIdResolver,
-
-      /// [First, Last) is an iterator range represented as opaque
-      /// pointers used to reconstruct DeclContext::lookup_iterators.
-      OverloadedDeclFromDeclContext,
-
-      /// First is a pointer to a CXXBasePaths structure, which is owned
-      /// by the LookupResult. Last is non-zero to indicate that the
-      /// ambiguity is caused by two names found in base class
-      /// subobjects of different types.
-      AmbiguousLookupStoresBasePaths,
-
-      /// [First, Last) is an iterator range represented as opaque
-      /// pointers used to reconstruct new'ed Decl*[] array containing
-      /// found ambiguous decls. LookupResult is owner of this array.
-      AmbiguousLookupStoresDecls
-    } StoredKind;
-
-    /// The first lookup result, whose contents depend on the kind of
-    /// lookup result. This may be a NamedDecl* (if StoredKind ==
-    /// SingleDecl), OverloadedFunctionDecl* (if StoredKind ==
-    /// OverloadedDeclSingleDecl), the opaque pointer from an
-    /// IdentifierResolver::iterator (if StoredKind ==
-    /// OverloadedDeclFromIdResolver), a DeclContext::lookup_iterator
-    /// (if StoredKind == OverloadedDeclFromDeclContext), or a
-    /// CXXBasePaths pointer (if StoredKind == AmbiguousLookupStoresBasePaths).
-    mutable uintptr_t First;
-
-    /// The last lookup result, whose contents depend on the kind of
-    /// lookup result. This may be unused (if StoredKind ==
-    /// SingleDecl), it may have the same type as First (for
-    /// overloaded function declarations), or is may be used as a
-    /// Boolean value (if StoredKind == AmbiguousLookupStoresBasePaths).
-    mutable uintptr_t Last;
-
-    /// Context - The context in which we will build any
-    /// OverloadedFunctionDecl nodes needed by the conversion to
-    /// Decl*.
-    ASTContext *Context;
-
-    /// @brief The kind of entity found by name lookup.
+  /// (possibly NULL) @c NamedDecl* via the getAsSingleDecl() method.
+  /// This permits the common-case usage in C and Objective-C where
+  /// name lookup will always return a single declaration.  Use of
+  /// this is largely deprecated; callers should handle the possibility
+  /// of multiple declarations.
+  class LookupResult {
+  public:
     enum LookupKind {
       /// @brief No entity found met the criteria.
       NotFound = 0,
@@ -1156,122 +1106,119 @@
       ///    }
       /// }
       /// @endcode
-      AmbiguousReference
+      AmbiguousReference,
+
+      FirstAmbiguous = AmbiguousBaseSubobjectTypes
     };
 
-    static LookupResult CreateLookupResult(ASTContext &Context, NamedDecl *D);
+    typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
+    typedef DeclsTy::const_iterator iterator;
 
-    static LookupResult CreateLookupResult(ASTContext &Context,
-                                           IdentifierResolver::iterator F,
-                                           IdentifierResolver::iterator L);
-
-    static LookupResult CreateLookupResult(ASTContext &Context,
-                                           DeclContext::lookup_iterator F,
-                                           DeclContext::lookup_iterator L);
-
-    static LookupResult CreateLookupResult(ASTContext &Context, 
-                                           CXXBasePaths *Paths,
-                                           bool DifferentSubobjectTypes) {
-      LookupResult Result;
-      Result.StoredKind = AmbiguousLookupStoresBasePaths;
-      Result.First = reinterpret_cast<uintptr_t>(Paths);
-      Result.Last = DifferentSubobjectTypes? 1 : 0;
-      Result.Context = &Context;
-      return Result;
+    LookupResult()
+      : Kind(NotFound),
+        Paths(0)
+    {}
+    ~LookupResult() {
+      if (Paths) deletePaths(Paths);
     }
 
-    template <typename Iterator>
-    static LookupResult CreateLookupResult(ASTContext &Context,
-                                           Iterator B, std::size_t Len) {
-      NamedDecl ** Array = new NamedDecl*[Len];
-      for (std::size_t Idx = 0; Idx < Len; ++Idx, ++B)
-        Array[Idx] = *B;
-      LookupResult Result;
-      Result.StoredKind = AmbiguousLookupStoresDecls;
-      Result.First = reinterpret_cast<uintptr_t>(Array);
-      Result.Last = reinterpret_cast<uintptr_t>(Array + Len);
-      Result.Context = &Context;
-      return Result;
+    bool isAmbiguous() const {
+      return getKind() >= FirstAmbiguous;
+    }
+
+    LookupKind getKind() const {
+      sanity();
+      return Kind;
     }
 
-    LookupKind getKind() const;
+    iterator begin() const { return Decls.begin(); }
+    iterator end() const { return Decls.end(); }
 
-    /// @brief Determine whether name look found something.
-    operator bool() const { return getKind() != NotFound; }
+    /// \brief Return true if no decls were found
+    bool empty() const { return Decls.empty(); }
 
-    /// @brief Determines whether the lookup resulted in an ambiguity.
-    bool isAmbiguous() const {
-      return StoredKind == AmbiguousLookupStoresBasePaths ||
-             StoredKind == AmbiguousLookupStoresDecls;
+    /// \brief Return the base paths structure that's associated with
+    /// these results, or null if none is.
+    CXXBasePaths *getBasePaths() const {
+      return Paths;
     }
 
-    /// @brief Allows conversion of a lookup result into a
-    /// declaration, with the same behavior as getAsDecl.
-    operator NamedDecl*() const { return getAsDecl(); }
+    /// \brief Add a declaration to these results.
+    void addDecl(NamedDecl *D) {
+      Decls.push_back(D->getUnderlyingDecl());
+      Kind = Found;
+    }
 
-    NamedDecl* getAsDecl() const;
+    /// \brief Resolves the kind of the lookup, possibly hiding decls.
+    ///
+    /// This should be called in any environment where lookup might
+    /// generate multiple lookup results.
+    void resolveKind();
 
-    CXXBasePaths *getBasePaths() const;
+    /// \brief Fetch this as an unambiguous single declaration
+    /// (possibly an overloaded one).
+    ///
+    /// This is deprecated; users should be written to handle
+    /// ambiguous and overloaded lookups.
+    NamedDecl *getAsSingleDecl(ASTContext &Context) const;
 
-    /// \brief Iterate over the results of name lookup.
+    /// \brief Fetch the unique decl found by this lookup.  Asserts
+    /// that one was found.
     ///
-    /// The @c iterator class provides iteration over the results of a
-    /// non-ambiguous name lookup.
-    class iterator {
-      /// The LookupResult structure we're iterating through.
-      LookupResult *Result;
-
-      /// The current position of this iterator within the sequence of
-      /// results. This value will have the same representation as the
-      /// @c First field in the LookupResult structure.
-      mutable uintptr_t Current;
-
-    public:
-      typedef NamedDecl *                value_type;
-      typedef NamedDecl *                reference;
-      typedef NamedDecl *                pointer;
-      typedef std::ptrdiff_t             difference_type;
-      typedef std::forward_iterator_tag  iterator_category;
-
-      iterator() : Result(0), Current(0) { }
-
-      iterator(LookupResult *Res, uintptr_t Cur) : Result(Res), Current(Cur) { }
-
-      reference operator*() const;
-
-      pointer operator->() const { return **this; }
-
-      iterator &operator++();
-
-      iterator operator++(int) {
-        iterator tmp(*this);
-        ++(*this);
-        return tmp;
-      }
+    /// This is intended for users who have examined the result kind
+    /// and are certain that there is only one result.
+    NamedDecl *getFoundDecl() const {
+      assert(getKind() == Found && "getFoundDecl called on non-unique result");
+      return *Decls.begin();
+    }
 
-      friend inline bool operator==(iterator const& x, iterator const& y) {
-        return x.Current == y.Current;
-      }
+    /// \brief Make these results show that the name was found in
+    /// base classes of different types.
+    ///
+    /// The given paths object is copied and invalidated.
+    void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
 
-      friend inline bool operator!=(iterator const& x, iterator const& y) {
-        return x.Current != y.Current;
-      }
-    };
-    friend class iterator;
+    /// \brief Make these results show that the name was found in
+    /// distinct base classes of the same type.
+    ///
+    /// The given paths object is copied and invalidated.
+    void setAmbiguousBaseSubobjects(CXXBasePaths &P);
+
+    /// \brief Clears out any current state.
+    void clear() {
+      Kind = NotFound;
+      Decls.clear();
+      if (Paths) deletePaths(Paths);
+      Paths = NULL;
+    }
 
-    iterator begin();
-    iterator end();
+    void print(llvm::raw_ostream &);
 
-    /// \brief Free the memory associated with this lookup.
-    void Destroy();
+  private:
+    void addDeclsFromBasePaths(const CXXBasePaths &P);
+
+    // Sanity checks.
+    void sanity() const {
+      assert(Kind != NotFound || Decls.size() == 0);
+      assert(Kind != Found || Decls.size() == 1);
+      assert(Kind == NotFound || Kind == Found ||
+             Kind == AmbiguousBaseSubobjects || Decls.size() > 1);
+      assert((Paths != NULL) == (Kind == AmbiguousBaseSubobjectTypes ||
+                                 Kind == AmbiguousBaseSubobjects));
+    }
+
+    static void deletePaths(CXXBasePaths *);
+
+    LookupKind Kind;
+    DeclsTy Decls;
+    CXXBasePaths *Paths;
   };
 
 private:
   typedef llvm::SmallVector<LookupResult, 3> LookupResultsVecTy;
 
-  std::pair<bool, LookupResult> CppLookupName(Scope *S, DeclarationName Name,
-                                              LookupNameKind NameKind,
-                                              bool RedeclarationOnly);
+  bool CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
+                     LookupNameKind NameKind, bool RedeclarationOnly);
 public:
   /// Determines whether D is a suitable lookup result according to the
   /// lookup criteria.
@@ -1303,24 +1250,38 @@
     return false;
   }
 
-  LookupResult LookupName(Scope *S, DeclarationName Name,
-                          LookupNameKind NameKind,
-                          bool RedeclarationOnly = false,
-                          bool AllowBuiltinCreation = false,
-                          SourceLocation Loc = SourceLocation());
-  LookupResult LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
-                                   LookupNameKind NameKind,
-                                   bool RedeclarationOnly = false);
+  /// \brief Look up a name, looking for a single declaration.  Return
+  /// null if no unambiguous results were found.
+  ///
+  /// It is preferable to use the elaborated form and explicitly handle
+  /// ambiguity and overloaded.
+  NamedDecl *LookupSingleName(Scope *S, DeclarationName Name,
+                              LookupNameKind NameKind,
+                              bool RedeclarationOnly = false) {
+    LookupResult R;
+    LookupName(R, S, Name, NameKind, RedeclarationOnly);
+    return R.getAsSingleDecl(Context);
+  }
+  bool LookupName(LookupResult &R, Scope *S,
+                  DeclarationName Name,
+                  LookupNameKind NameKind,
+                  bool RedeclarationOnly = false,
+                  bool AllowBuiltinCreation = false,
+                  SourceLocation Loc = SourceLocation());
+  bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
+                           DeclarationName Name,
+                           LookupNameKind NameKind,
+                           bool RedeclarationOnly = false);
   Decl *LookupQualifiedNameWithType(DeclContext *LookupCtx,
                                     DeclarationName Name,
                                     QualType T);
-  LookupResult LookupParsedName(Scope *S, const CXXScopeSpec *SS,
-                                DeclarationName Name,
-                                LookupNameKind NameKind,
-                                bool RedeclarationOnly = false,
-                                bool AllowBuiltinCreation = false,
-                                SourceLocation Loc = SourceLocation(),
-                                bool EnteringContext = false);
+  bool LookupParsedName(LookupResult &R, Scope *S, const CXXScopeSpec *SS,
+                        DeclarationName Name,
+                        LookupNameKind NameKind,
+                        bool RedeclarationOnly = false,
+                        bool AllowBuiltinCreation = false,
+                        SourceLocation Loc = SourceLocation(),
+                        bool EnteringContext = false);
 
   ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II);
   ObjCCategoryImplDecl *LookupObjCCategoryImpl(IdentifierInfo *II);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Fri Oct  9 16:13:30 2009
@@ -179,13 +179,12 @@
   for (unsigned i = 0; i < NumIdentifiers; ++i) {
     const Token &Tok = Identifiers[i];
     IdentifierInfo *Name = Tok.getIdentifierInfo();
-    const LookupResult &Lookup = LookupParsedName(curScope, NULL, Name,
-                                                  LookupOrdinaryName,
-                                                  false, true,
-                                                  Tok.getLocation());
+    LookupResult Lookup;
+    LookupParsedName(Lookup, curScope, NULL, Name,LookupOrdinaryName,
+                     false, true, Tok.getLocation());
     // FIXME: Handle Lookup.isAmbiguous?
 
-    NamedDecl *ND = Lookup.getAsDecl();
+    NamedDecl *ND = Lookup.getAsSingleDecl(Context);
 
     if (!ND) {
       Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Fri Oct  9 16:13:30 2009
@@ -302,11 +302,11 @@
   if (NNS->getKind() != NestedNameSpecifier::Identifier)
     return 0;
 
-  LookupResult Found
-    = LookupName(S, NNS->getAsIdentifier(), LookupNestedNameSpecifierName);
+  LookupResult Found;
+  LookupName(Found, S, NNS->getAsIdentifier(), LookupNestedNameSpecifierName);
   assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet");
 
-  NamedDecl *Result = Found;
+  NamedDecl *Result = Found.getAsSingleDecl(Context);
   if (isAcceptableNestedNameSpecifier(Result))
     return Result;
 
@@ -359,8 +359,8 @@
     if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
       return 0;
 
-    Found = LookupQualifiedName(LookupCtx, &II, LookupNestedNameSpecifierName,
-                                false);
+    LookupQualifiedName(Found, LookupCtx, &II, LookupNestedNameSpecifierName,
+                        false);
 
     if (!ObjectType.isNull() && Found.getKind() == LookupResult::NotFound) {
       // C++ [basic.lookup.classref]p4:
@@ -384,9 +384,9 @@
       // reconstruct the result from when name lookup was performed at template
       // definition time.
       if (S)
-        Found = LookupName(S, &II, LookupNestedNameSpecifierName);
-      else
-        Found = LookupResult::CreateLookupResult(Context, ScopeLookupResult);
+        LookupName(Found, S, &II, LookupNestedNameSpecifierName);
+      else if (ScopeLookupResult)
+        Found.addDecl(ScopeLookupResult);
 
       ObjectTypeSearchedInScope = true;
     }
@@ -401,11 +401,11 @@
     return NestedNameSpecifier::Create(Context, Prefix, &II);
   } else {
     // Perform unqualified name lookup in the current scope.
-    Found = LookupName(S, &II, LookupNestedNameSpecifierName);
+    LookupName(Found, S, &II, LookupNestedNameSpecifierName);
   }
 
   // FIXME: Deal with ambiguities cleanly.
-  NamedDecl *SD = Found;
+  NamedDecl *SD = Found.getAsSingleDecl(Context);
   if (isAcceptableNestedNameSpecifier(SD)) {
     if (!ObjectType.isNull() && !ObjectTypeSearchedInScope) {
       // C++ [basic.lookup.classref]p4:
@@ -416,15 +416,15 @@
       // into the current scope (the scope of the postfix-expression) to
       // see if we can find the same name there. As above, if there is no
       // scope, reconstruct the result from the template instantiation itself.
-      LookupResult FoundOuter;
-      if (S)
-        FoundOuter = LookupName(S, &II, LookupNestedNameSpecifierName);
-      else
-        FoundOuter = LookupResult::CreateLookupResult(Context,
-                                                      ScopeLookupResult);
+      NamedDecl *OuterDecl;
+      if (S) {
+        LookupResult FoundOuter;
+        LookupName(FoundOuter, S, &II, LookupNestedNameSpecifierName);
+        // FIXME: Handle ambiguities!
+        OuterDecl = FoundOuter.getAsSingleDecl(Context);
+      } else
+        OuterDecl = ScopeLookupResult;
 
-      // FIXME: Handle ambiguities in FoundOuter!
-      NamedDecl *OuterDecl = FoundOuter;
       if (isAcceptableNestedNameSpecifier(OuterDecl) &&
           OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() &&
           (!isa<TypeDecl>(OuterDecl) || !isa<TypeDecl>(SD) ||
@@ -461,8 +461,11 @@
   // If we didn't find anything during our lookup, try again with
   // ordinary name lookup, which can help us produce better error
   // messages.
-  if (!SD)
-    SD = LookupName(S, &II, LookupOrdinaryName);
+  if (!SD) {
+    Found.clear();
+    LookupName(Found, S, &II, LookupOrdinaryName);
+    SD = Found.getAsSingleDecl(Context);
+  }
 
   unsigned DiagID;
   if (SD)

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Oct  9 16:13:30 2009
@@ -85,8 +85,8 @@
                              II, SS->getRange()).getAsOpaquePtr();
   }
 
-  LookupResult Result
-    = LookupParsedName(S, SS, &II, LookupOrdinaryName, false, false);
+  LookupResult Result;
+  LookupParsedName(Result, S, SS, &II, LookupOrdinaryName, false, false);
 
   NamedDecl *IIDecl = 0;
   switch (Result.getKind()) {
@@ -115,7 +115,6 @@
       // perform this lookup again (e.g., as an object name), which
       // will produce the ambiguity, or will complain that it expected
       // a type name.
-      Result.Destroy();
       return 0;
     }
 
@@ -128,7 +127,7 @@
   }
 
   case LookupResult::Found:
-    IIDecl = Result.getAsDecl();
+    IIDecl = Result.getFoundDecl();
     break;
   }
 
@@ -179,9 +178,10 @@
 /// where the user forgot to specify the tag.
 DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {
   // Do a tag name lookup in this scope.
-  LookupResult R = LookupName(S, &II, LookupTagName, false, false);
+  LookupResult R;
+  LookupName(R, S, &II, LookupTagName, false, false);
   if (R.getKind() == LookupResult::Found)
-    if (const TagDecl *TD = dyn_cast<TagDecl>(R.getAsDecl())) {
+    if (const TagDecl *TD = dyn_cast<TagDecl>(R.getAsSingleDecl(Context))) {
       switch (TD->getTagKind()) {
       case TagDecl::TK_struct: return DeclSpec::TST_struct;
       case TagDecl::TK_union:  return DeclSpec::TST_union;
@@ -303,84 +303,20 @@
       (isa<VarDecl>(D) && cast<VarDecl>(D)->isOutOfLine()))
     return;
 
-  S->AddDecl(DeclPtrTy::make(D));
-  
-  // C++ [basic.scope]p4:
-  //   -- exactly one declaration shall declare a class name or
-  //   enumeration name that is not a typedef name and the other
-  //   declarations shall all refer to the same object or
-  //   enumerator, or all refer to functions and function templates;
-  //   in this case the class name or enumeration name is hidden.
-  if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
-    // We are pushing the name of a tag (enum or class).
-    if (CurContext->getLookupContext()
-          == TD->getDeclContext()->getLookupContext()) {
-      // We're pushing the tag into the current context, which might
-      // require some reshuffling in the identifier resolver.
-      IdentifierResolver::iterator
-        I = IdResolver.begin(TD->getDeclName()),
-        IEnd = IdResolver.end();
-      NamedDecl *ID = *I;
-      if (I != IEnd && isDeclInScope(ID, CurContext, S)) {
-        NamedDecl *PrevDecl = *I;
-        for (; I != IEnd && isDeclInScope(ID, CurContext, S);
-             PrevDecl = *I, ++I) {
-          if (TD->declarationReplaces(*I)) {
-            // This is a redeclaration. Remove it from the chain and
-            // break out, so that we'll add in the shadowed
-            // declaration.
-            S->RemoveDecl(DeclPtrTy::make(*I));
-            if (PrevDecl == *I) {
-              IdResolver.RemoveDecl(*I);
-              IdResolver.AddDecl(TD);
-              return;
-            } else {
-              IdResolver.RemoveDecl(*I);
-              break;
-            }
-          }
-        }
-
-        // There is already a declaration with the same name in the same
-        // scope, which is not a tag declaration. It must be found
-        // before we find the new declaration, so insert the new
-        // declaration at the end of the chain.
-        IdResolver.AddShadowedDecl(TD, PrevDecl);
+  // If this replaces anything in the current scope, 
+  IdentifierResolver::iterator I = IdResolver.begin(D->getDeclName()),
+                               IEnd = IdResolver.end();
+  for (; I != IEnd; ++I) {
+    if (S->isDeclScope(DeclPtrTy::make(*I)) && D->declarationReplaces(*I)) {
+      S->RemoveDecl(DeclPtrTy::make(*I));
+      IdResolver.RemoveDecl(*I);
 
-        return;
-      }
-    }
-  } else if ((isa<FunctionDecl>(D) &&
-              AllowOverloadingOfFunction(D, Context)) ||
-             isa<FunctionTemplateDecl>(D)) {
-    // We are pushing the name of a function or function template,
-    // which might be an overloaded name.
-    IdentifierResolver::iterator Redecl
-      = std::find_if(IdResolver.begin(D->getDeclName()),
-                     IdResolver.end(),
-                     std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
-                                  D));
-    if (Redecl != IdResolver.end() &&
-        S->isDeclScope(DeclPtrTy::make(*Redecl))) {
-      // There is already a declaration of a function on our
-      // IdResolver chain. Replace it with this declaration.
-      S->RemoveDecl(DeclPtrTy::make(*Redecl));
-      IdResolver.RemoveDecl(*Redecl);
-    }
-  } else if (isa<ObjCInterfaceDecl>(D)) {
-    // We're pushing an Objective-C interface into the current
-    // context. If there is already an alias declaration, remove it first.
-    for (IdentifierResolver::iterator
-           I = IdResolver.begin(D->getDeclName()), IEnd = IdResolver.end();
-         I != IEnd; ++I) {
-      if (isa<ObjCCompatibleAliasDecl>(*I)) {
-        S->RemoveDecl(DeclPtrTy::make(*I));
-        IdResolver.RemoveDecl(*I);
-        break;
-      }
+      // Should only need to replace one decl.
+      break;
     }
   }
 
+  S->AddDecl(DeclPtrTy::make(D));
   IdResolver.AddDecl(D);
 }
 
@@ -450,7 +386,7 @@
 ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
   // The third "scope" argument is 0 since we aren't enabling lazy built-in
   // creation from this context.
-  NamedDecl *IDecl = LookupName(TUScope, Id, LookupOrdinaryName);
+  NamedDecl *IDecl = LookupSingleName(TUScope, Id, LookupOrdinaryName);
 
   return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl);
 }
@@ -492,7 +428,7 @@
     return;
 
   IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
-  NamedDecl *VaDecl = LookupName(TUScope, VaIdent, LookupOrdinaryName);
+  NamedDecl *VaDecl = LookupSingleName(TUScope, VaIdent, LookupOrdinaryName);
   TypedefDecl *VaTypedef = cast<TypedefDecl>(VaDecl);
   Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
 }
@@ -1414,8 +1350,10 @@
                                FEnd = AnonRecord->field_end();
        F != FEnd; ++F) {
     if ((*F)->getDeclName()) {
-      NamedDecl *PrevDecl = LookupQualifiedName(Owner, (*F)->getDeclName(),
-                                                LookupOrdinaryName, true);
+      LookupResult R;
+      LookupQualifiedName(R, Owner, (*F)->getDeclName(),
+                          LookupOrdinaryName, true);
+      NamedDecl *PrevDecl = R.getAsSingleDecl(Context);
       if (PrevDecl && !isa<TagDecl>(PrevDecl)) {
         // C++ [class.union]p2:
         //   The names of the members of an anonymous union shall be
@@ -1771,9 +1709,11 @@
       NameKind = LookupRedeclarationWithLinkage;
 
     DC = CurContext;
-    PrevDecl = LookupName(S, Name, NameKind, true,
-                          NameKind == LookupRedeclarationWithLinkage,
-                          D.getIdentifierLoc());
+    LookupResult R;
+    LookupName(R, S, Name, NameKind, true,
+               NameKind == LookupRedeclarationWithLinkage,
+               D.getIdentifierLoc());
+    PrevDecl = R.getAsSingleDecl(Context);
   } else { // Something like "int foo::x;"
     DC = computeDeclContext(D.getCXXScopeSpec(), true);
 
@@ -1789,7 +1729,9 @@
       return DeclPtrTy();
     }
 
-    PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true);
+    LookupResult Res;
+    LookupQualifiedName(Res, DC, Name, LookupOrdinaryName, true);
+    PrevDecl = Res.getAsSingleDecl(Context);
 
     // C++ 7.3.1.2p2:
     // Members (including explicit specializations of templates) of a named
@@ -2885,8 +2827,8 @@
         << cast<NamedDecl>(DC) << D.getCXXScopeSpec().getRange();
       NewFD->setInvalidDecl();
 
-      LookupResult Prev = LookupQualifiedName(DC, Name, LookupOrdinaryName,
-                                              true);
+      LookupResult Prev;
+      LookupQualifiedName(Prev, DC, Name, LookupOrdinaryName, true);
       assert(!Prev.isAmbiguous() &&
              "Cannot have an ambiguity in previous-declaration lookup");
       for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
@@ -3603,7 +3545,7 @@
   // among each other.  Here they can only shadow globals, which is ok.
   IdentifierInfo *II = D.getIdentifier();
   if (II) {
-    if (NamedDecl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) {
+    if (NamedDecl *PrevDecl = LookupSingleName(S, II, LookupOrdinaryName)) {
       if (PrevDecl->isTemplateParameter()) {
         // Maybe we will complain about the shadowed template parameter.
         DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
@@ -4212,9 +4154,9 @@
     DC = computeDeclContext(SS, true);
     SearchDC = DC;
     // Look-up name inside 'foo::'.
-    PrevDecl
-      = dyn_cast_or_null<TagDecl>(
-               LookupQualifiedName(DC, Name, LookupTagName, true).getAsDecl());
+    LookupResult R;
+    LookupQualifiedName(R, DC, Name, LookupTagName, true);
+    PrevDecl = dyn_cast_or_null<TagDecl>(R.getAsSingleDecl(Context));
 
     // A tag 'foo::bar' must already exist.
     if (PrevDecl == 0) {
@@ -4229,7 +4171,8 @@
     // FIXME: We're looking into outer scopes here, even when we
     // shouldn't be. Doing so can result in ambiguities that we
     // shouldn't be diagnosing.
-    LookupResult R = LookupName(S, Name, LookupTagName,
+    LookupResult R;
+    LookupName(R, S, Name, LookupTagName,
                                 /*RedeclarationOnly=*/(TUK != TUK_Reference));
     if (R.isAmbiguous()) {
       DiagnoseAmbiguousLookup(R, Name, NameLoc);
@@ -4242,7 +4185,7 @@
       PrevDecl = 0;
       Invalid = true;
     } else
-      PrevDecl = R;
+      PrevDecl = R.getAsSingleDecl(Context);
 
     if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) {
       // FIXME: This makes sure that we ignore the contexts associated
@@ -4489,10 +4432,11 @@
     //   shall not be declared with the same name as a typedef-name
     //   that is declared in that scope and refers to a type other
     //   than the class or enumeration itself.
-    LookupResult Lookup = LookupName(S, Name, LookupOrdinaryName, true);
+    LookupResult Lookup;
+    LookupName(Lookup, S, Name, LookupOrdinaryName, true);
     TypedefDecl *PrevTypedef = 0;
-    if (Lookup.getKind() == LookupResult::Found)
-      PrevTypedef = dyn_cast<TypedefDecl>(Lookup.getAsDecl());
+    if (NamedDecl *Prev = Lookup.getAsSingleDecl(Context))
+      PrevTypedef = dyn_cast<TypedefDecl>(Prev);
 
     NamedDecl *PrevTypedefNamed = PrevTypedef;
     if (PrevTypedef && isDeclInScope(PrevTypedefNamed, SearchDC, S) &&
@@ -4708,7 +4652,7 @@
   if (D.getDeclSpec().isThreadSpecified())
     Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
 
-  NamedDecl *PrevDecl = LookupName(S, II, LookupMemberName, true);
+  NamedDecl *PrevDecl = LookupSingleName(S, II, LookupMemberName, true);
 
   if (PrevDecl && PrevDecl->isTemplateParameter()) {
     // Maybe we will complain about the shadowed template parameter.
@@ -5089,7 +5033,7 @@
                                              DInfo, ac, (Expr *)BitfieldWidth);
 
   if (II) {
-    NamedDecl *PrevDecl = LookupName(S, II, LookupMemberName, true);
+    NamedDecl *PrevDecl = LookupSingleName(S, II, LookupMemberName, true);
     if (PrevDecl && isDeclInScope(PrevDecl, EnclosingContext, S)
         && !isa<TagDecl>(PrevDecl)) {
       Diag(Loc, diag::err_duplicate_member) << II;
@@ -5342,7 +5286,7 @@
 
   // Verify that there isn't already something declared with this name in this
   // scope.
-  NamedDecl *PrevDecl = LookupName(S, Id, LookupOrdinaryName);
+  NamedDecl *PrevDecl = LookupSingleName(S, Id, LookupOrdinaryName);
   if (PrevDecl && PrevDecl->isTemplateParameter()) {
     // Maybe we will complain about the shadowed template parameter.
     DiagnoseTemplateParameterShadow(IdLoc, PrevDecl);
@@ -5585,7 +5529,7 @@
 void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
                              SourceLocation PragmaLoc,
                              SourceLocation NameLoc) {
-  Decl *PrevDecl = LookupName(TUScope, Name, LookupOrdinaryName);
+  Decl *PrevDecl = LookupSingleName(TUScope, Name, LookupOrdinaryName);
 
   if (PrevDecl) {
     PrevDecl->addAttr(::new (Context) WeakAttr());
@@ -5601,7 +5545,7 @@
                                 SourceLocation PragmaLoc,
                                 SourceLocation NameLoc,
                                 SourceLocation AliasNameLoc) {
-  Decl *PrevDecl = LookupName(TUScope, AliasName, LookupOrdinaryName);
+  Decl *PrevDecl = LookupSingleName(TUScope, AliasName, LookupOrdinaryName);
   WeakInfo W = WeakInfo(Name, NameLoc);
 
   if (PrevDecl) {

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Oct  9 16:13:30 2009
@@ -1104,8 +1104,9 @@
   }
 
   // Look up the function
-  NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
-                                        Sema::LookupOrdinaryName);
+  NamedDecl *CleanupDecl
+    = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
+                         Sema::LookupOrdinaryName);
   if (!CleanupDecl) {
     S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
       Attr.getParameterName();

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Oct  9 16:13:30 2009
@@ -2490,8 +2490,8 @@
     // original-namespace-definition is the name of the namespace. Subsequently
     // in that declarative region, it is treated as an original-namespace-name.
 
-    NamedDecl *PrevDecl = LookupName(DeclRegionScope, II, LookupOrdinaryName,
-                                     true);
+    NamedDecl *PrevDecl
+      = LookupSingleName(DeclRegionScope, II, LookupOrdinaryName, true);
 
     if (NamespaceDecl *OrigNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl)) {
       // This is an extended namespace definition.
@@ -2599,13 +2599,14 @@
   UsingDirectiveDecl *UDir = 0;
 
   // Lookup namespace name.
-  LookupResult R = LookupParsedName(S, &SS, NamespcName,
-                                    LookupNamespaceName, false);
+  LookupResult R;
+  LookupParsedName(R, S, &SS, NamespcName, LookupNamespaceName, false);
   if (R.isAmbiguous()) {
     DiagnoseAmbiguousLookup(R, NamespcName, IdentLoc);
     return DeclPtrTy();
   }
-  if (NamedDecl *NS = R) {
+  if (!R.empty()) {
+    NamedDecl *NS = R.getFoundDecl();
     assert(isa<NamespaceDecl>(NS) && "expected namespace decl");
     // C++ [namespace.udir]p1:
     //   A using-directive specifies that the names in the nominated
@@ -2746,15 +2747,16 @@
 
 
   // Lookup target name.
-  LookupResult R = LookupQualifiedName(LookupContext,
-                                       Name, LookupOrdinaryName);
+  LookupResult R;
+  LookupQualifiedName(R, LookupContext, Name, LookupOrdinaryName);
 
-  if (!R) {
+  if (R.empty()) {
     DiagnoseMissingMember(IdentLoc, Name, NNS, SS.getRange());
     return 0;
   }
 
-  NamedDecl *ND = R.getAsDecl();
+  // FIXME: handle ambiguity?
+  NamedDecl *ND = R.getAsSingleDecl(Context);
 
   if (IsTypeName && !isa<TypeDecl>(ND)) {
     Diag(IdentLoc, diag::err_using_typename_non_type);
@@ -2790,14 +2792,17 @@
                                              IdentifierInfo *Ident) {
 
   // Lookup the namespace name.
-  LookupResult R = LookupParsedName(S, &SS, Ident, LookupNamespaceName, false);
+  LookupResult R;
+  LookupParsedName(R, S, &SS, Ident, LookupNamespaceName, false);
 
   // Check if we have a previous declaration with the same name.
-  if (NamedDecl *PrevDecl = LookupName(S, Alias, LookupOrdinaryName, true)) {
+  if (NamedDecl *PrevDecl
+        = LookupSingleName(S, Alias, LookupOrdinaryName, true)) {
     if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(PrevDecl)) {
       // We already have an alias with the same name that points to the same
       // namespace, so don't create a new one.
-      if (!R.isAmbiguous() && AD->getNamespace() == getNamespaceDecl(R))
+      if (!R.isAmbiguous() && !R.empty() &&
+          AD->getNamespace() == getNamespaceDecl(R.getFoundDecl()))
         return DeclPtrTy();
     }
 
@@ -2813,7 +2818,7 @@
     return DeclPtrTy();
   }
 
-  if (!R) {
+  if (R.empty()) {
     Diag(NamespaceLoc, diag::err_expected_namespace_name) << SS.getRange();
     return DeclPtrTy();
   }
@@ -2822,7 +2827,7 @@
     NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc,
                                Alias, SS.getRange(),
                                (NestedNameSpecifier *)SS.getScopeRep(),
-                               IdentLoc, R);
+                               IdentLoc, R.getFoundDecl());
 
   CurContext->addDecl(AliasDecl);
   return DeclPtrTy::make(AliasDecl);
@@ -4151,7 +4156,7 @@
 
   bool Invalid = D.isInvalidType();
   IdentifierInfo *II = D.getIdentifier();
-  if (NamedDecl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) {
+  if (NamedDecl *PrevDecl = LookupSingleName(S, II, LookupOrdinaryName)) {
     // The scope should be freshly made just for us. There is just no way
     // it contains any previous declaration.
     assert(!S->isDeclScope(DeclPtrTy::make(PrevDecl)));
@@ -4398,7 +4403,9 @@
     // FIXME: handle dependent contexts
     if (!DC) return DeclPtrTy();
 
-    PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true);
+    LookupResult R;
+    LookupQualifiedName(R, DC, Name, LookupOrdinaryName, true);
+    PrevDecl = R.getAsSingleDecl(Context);
 
     // If searching in that context implicitly found a declaration in
     // a different context, treat it like it wasn't found at all.
@@ -4431,7 +4438,9 @@
       while (DC->isRecord()) 
         DC = DC->getParent();
 
-      PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true);
+      LookupResult R;
+      LookupQualifiedName(R, DC, Name, LookupOrdinaryName, true);
+      PrevDecl = R.getAsSingleDecl(Context);
 
       // TODO: decide what we think about using declarations.
       if (PrevDecl)

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri Oct  9 16:13:30 2009
@@ -84,7 +84,7 @@
   assert(ClassName && "Missing class identifier");
 
   // Check for another declaration kind with the same name.
-  NamedDecl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName);
+  NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
   if (PrevDecl && PrevDecl->isTemplateParameter()) {
     // Maybe we will complain about the shadowed template parameter.
     DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl);
@@ -124,7 +124,7 @@
 
   if (SuperName) {
     // Check if a different kind of symbol declared in this scope.
-    PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName);
+    PrevDecl = LookupSingleName(TUScope, SuperName, LookupOrdinaryName);
     if (PrevDecl == IDecl) {
       Diag(SuperLoc, diag::err_recursive_superclass)
         << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
@@ -195,7 +195,7 @@
                                              IdentifierInfo *ClassName,
                                              SourceLocation ClassLocation) {
   // Look for previous declaration of alias name
-  NamedDecl *ADecl = LookupName(TUScope, AliasName, LookupOrdinaryName);
+  NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, LookupOrdinaryName);
   if (ADecl) {
     if (isa<ObjCCompatibleAliasDecl>(ADecl))
       Diag(AliasLocation, diag::warn_previous_alias_decl);
@@ -205,13 +205,13 @@
     return DeclPtrTy();
   }
   // Check for class declaration
-  NamedDecl *CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
+  NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
   if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(CDeclU)) {
     QualType T = TDecl->getUnderlyingType();
     if (T->isObjCInterfaceType()) {
       if (NamedDecl *IDecl = T->getAs<ObjCInterfaceType>()->getDecl()) {
         ClassName = IDecl->getIdentifier();
-        CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
+        CDeclU = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
       }
     }
   }
@@ -654,7 +654,8 @@
                       SourceLocation SuperClassLoc) {
   ObjCInterfaceDecl* IDecl = 0;
   // Check for another declaration kind with the same name.
-  NamedDecl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName);
+  NamedDecl *PrevDecl
+    = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
   if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
     Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
@@ -671,7 +672,7 @@
   ObjCInterfaceDecl* SDecl = 0;
   if (SuperClassname) {
     // Check if a different kind of symbol declared in this scope.
-    PrevDecl = LookupName(TUScope, SuperClassname, LookupOrdinaryName);
+    PrevDecl = LookupSingleName(TUScope, SuperClassname, LookupOrdinaryName);
     if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
       Diag(SuperClassLoc, diag::err_redefinition_different_kind)
         << SuperClassname;
@@ -1121,7 +1122,8 @@
 
   for (unsigned i = 0; i != NumElts; ++i) {
     // Check for another declaration kind with the same name.
-    NamedDecl *PrevDecl = LookupName(TUScope, IdentList[i], LookupOrdinaryName);
+    NamedDecl *PrevDecl
+      = LookupSingleName(TUScope, IdentList[i], LookupOrdinaryName);
     if (PrevDecl && PrevDecl->isTemplateParameter()) {
       // Maybe we will complain about the shadowed template parameter.
       DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Oct  9 16:13:30 2009
@@ -695,8 +695,8 @@
                                                      isAddressOfOperand));
   }
 
-  LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName,
-                                         false, true, Loc);
+  LookupResult Lookup;
+  LookupParsedName(Lookup, S, SS, Name, LookupOrdinaryName, false, true, Loc);
 
   if (Lookup.isAmbiguous()) {
     DiagnoseAmbiguousLookup(Lookup, Name, Loc,
@@ -705,7 +705,7 @@
     return ExprError();
   }
 
-  NamedDecl *D = Lookup.getAsDecl();
+  NamedDecl *D = Lookup.getAsSingleDecl(Context);
 
   // If this reference is in an Objective-C method, then ivar lookup happens as
   // well.
@@ -2181,10 +2181,10 @@
     }
 
     // The record definition is complete, now make sure the member is valid.
-    LookupResult Result
-      = LookupQualifiedName(DC, MemberName, LookupMemberName, false);
+    LookupResult Result;
+    LookupQualifiedName(Result, DC, MemberName, LookupMemberName, false);
 
-    if (!Result)
+    if (Result.empty())
       return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member_deprecated)
                << MemberName << BaseExpr->getSourceRange());
     if (Result.isAmbiguous()) {
@@ -2193,13 +2193,14 @@
       return ExprError();
     }
 
+    NamedDecl *MemberDecl = Result.getAsSingleDecl(Context);
+
     if (SS && SS->isSet()) {
+      TypeDecl* TyD = cast<TypeDecl>(MemberDecl->getDeclContext());
       QualType BaseTypeCanon
         = Context.getCanonicalType(BaseType).getUnqualifiedType();
       QualType MemberTypeCanon
-        = Context.getCanonicalType(
-                  Context.getTypeDeclType(
-                    dyn_cast<TypeDecl>(Result.getAsDecl()->getDeclContext())));
+        = Context.getCanonicalType(Context.getTypeDeclType(TyD));
 
       if (BaseTypeCanon != MemberTypeCanon &&
           !IsDerivedFrom(BaseTypeCanon, MemberTypeCanon))
@@ -2208,8 +2209,6 @@
                          << MemberTypeCanon << BaseTypeCanon);
     }
 
-    NamedDecl *MemberDecl = Result;
-
     // If the decl being referenced had an error, return an error for this
     // sub-expr without emitting another error, in order to avoid cascading
     // error cases.
@@ -5685,10 +5684,11 @@
         }
       }
 
+      LookupResult R;
+      LookupQualifiedName(R, RD, OC.U.IdentInfo, LookupMemberName);
+
       FieldDecl *MemberDecl
-        = dyn_cast_or_null<FieldDecl>(LookupQualifiedName(RD, OC.U.IdentInfo,
-                                                          LookupMemberName)
-                                        .getAsDecl());
+        = dyn_cast_or_null<FieldDecl>(R.getAsSingleDecl(Context));
       // FIXME: Leaks Res
       if (!MemberDecl)
         return ExprError(Diag(BuiltinLoc, diag::err_typecheck_no_member_deprecated)

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Oct  9 16:13:30 2009
@@ -69,8 +69,9 @@
     TyOrExpr = GetTypeFromParser(TyOrExpr).getAsOpaquePtr();
 
   IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
-  Decl *TypeInfoDecl = LookupQualifiedName(StdNamespace, TypeInfoII, 
-                                           LookupTagName);
+  LookupResult R;
+  LookupQualifiedName(R, StdNamespace, TypeInfoII, LookupTagName);  
+  Decl *TypeInfoDecl = R.getAsSingleDecl(Context);
   RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null<RecordDecl>(TypeInfoDecl);
   if (!TypeInfoRecordDecl)
     return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
@@ -589,14 +590,17 @@
                                   DeclarationName Name, Expr** Args,
                                   unsigned NumArgs, DeclContext *Ctx,
                                   bool AllowMissing, FunctionDecl *&Operator) {
-  LookupResult R = LookupQualifiedName(Ctx, Name, LookupOrdinaryName);
-  if (!R) {
+  LookupResult R;
+  LookupQualifiedName(R, Ctx, Name, LookupOrdinaryName);
+  if (R.empty()) {
     if (AllowMissing)
       return false;
     return Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
       << Name << Range;
   }
 
+  // FIXME: handle ambiguity
+
   OverloadCandidateSet Candidates;
   for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end(); 
        Alloc != AllocEnd; ++Alloc) {
@@ -868,8 +872,8 @@
         = cast<CXXRecordDecl>(Pointee->getAs<RecordType>()->getDecl());
       
       // Try to find operator delete/operator delete[] in class scope.
-      LookupResult Found = LookupQualifiedName(Record, DeleteName, 
-                                               LookupOrdinaryName);
+      LookupResult Found;
+      LookupQualifiedName(Found, Record, DeleteName, LookupOrdinaryName);
       // FIXME: Diagnose ambiguity properly
       assert(!Found.isAmbiguous() && "Ambiguous delete/delete[] not handled");
       for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Fri Oct  9 16:13:30 2009
@@ -77,7 +77,7 @@
     Ty = Context.getObjCObjectPointerType(Ty);
   } else {
     IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
-    NamedDecl *IF = LookupName(TUScope, NSIdent, LookupOrdinaryName);
+    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, LookupOrdinaryName);
     if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
       Context.setObjCConstantStringInterface(StrIF);
       Ty = Context.getObjCConstantStringInterface();
@@ -387,7 +387,8 @@
     } else {
       // 'super' has been used outside a method context. If a variable named
       // 'super' has been declared, redirect. If not, produce a diagnostic.
-      NamedDecl *SuperDecl = LookupName(S, receiverName, LookupOrdinaryName);
+      NamedDecl *SuperDecl
+        = LookupSingleName(S, receiverName, LookupOrdinaryName);
       ValueDecl *VD = dyn_cast_or_null<ValueDecl>(SuperDecl);
       if (VD) {
         ExprResult ReceiverExpr = new (Context) DeclRefExpr(VD, VD->getType(),
@@ -412,7 +413,8 @@
   //
   // If necessary, the following lookup could move to getObjCInterfaceDecl().
   if (!ClassDecl) {
-    NamedDecl *IDecl = LookupName(TUScope, receiverName, LookupOrdinaryName);
+    NamedDecl *IDecl
+      = LookupSingleName(TUScope, receiverName, LookupOrdinaryName);
     if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) {
       const ObjCInterfaceType *OCIT;
       OCIT = OCTD->getUnderlyingType()->getAs<ObjCInterfaceType>();

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Fri Oct  9 16:13:30 2009
@@ -35,7 +35,6 @@
 
 typedef llvm::SmallVector<UsingDirectiveDecl*, 4> UsingDirectivesTy;
 typedef llvm::DenseSet<NamespaceDecl*> NamespaceSet;
-typedef llvm::SmallVector<Sema::LookupResult, 3> LookupResultsTy;
 
 /// UsingDirAncestorCompare - Implements strict weak ordering of
 /// UsingDirectives. It orders them by address of its common ancestor.
@@ -107,178 +106,6 @@
   }
 }
 
-/// MaybeConstructOverloadSet - Name lookup has determined that the
-/// elements in [I, IEnd) have the name that we are looking for, and
-/// *I is a match for the namespace. This routine returns an
-/// appropriate Decl for name lookup, which may either be *I or an
-/// OverloadedFunctionDecl that represents the overloaded functions in
-/// [I, IEnd).
-///
-/// The existance of this routine is temporary; users of LookupResult
-/// should be able to handle multiple results, to deal with cases of
-/// ambiguity and overloaded functions without needing to create a
-/// Decl node.
-template<typename DeclIterator>
-static NamedDecl *
-MaybeConstructOverloadSet(ASTContext &Context,
-                          DeclIterator I, DeclIterator IEnd) {
-  assert(I != IEnd && "Iterator range cannot be empty");
-  assert(!isa<OverloadedFunctionDecl>(*I) &&
-         "Cannot have an overloaded function");
-
-  if ((*I)->isFunctionOrFunctionTemplate()) {
-    // If we found a function, there might be more functions. If
-    // so, collect them into an overload set.
-    DeclIterator Last = I;
-    OverloadedFunctionDecl *Ovl = 0;
-    for (++Last;
-         Last != IEnd && (*Last)->isFunctionOrFunctionTemplate();
-         ++Last) {
-      if (!Ovl) {
-        // FIXME: We leak this overload set. Eventually, we want to stop
-        // building the declarations for these overload sets, so there will be
-        // nothing to leak.
-        Ovl = OverloadedFunctionDecl::Create(Context, (*I)->getDeclContext(),
-                                             (*I)->getDeclName());
-        NamedDecl *ND = (*I)->getUnderlyingDecl();
-        if (isa<FunctionDecl>(ND))
-          Ovl->addOverload(cast<FunctionDecl>(ND));
-        else
-          Ovl->addOverload(cast<FunctionTemplateDecl>(ND));
-      }
-
-      NamedDecl *ND = (*Last)->getUnderlyingDecl();
-      if (isa<FunctionDecl>(ND))
-        Ovl->addOverload(cast<FunctionDecl>(ND));
-      else
-        Ovl->addOverload(cast<FunctionTemplateDecl>(ND));
-    }
-
-    // If we had more than one function, we built an overload
-    // set. Return it.
-    if (Ovl)
-      return Ovl;
-  }
-
-  return *I;
-}
-
-/// Merges together multiple LookupResults dealing with duplicated Decl's.
-static Sema::LookupResult
-MergeLookupResults(ASTContext &Context, LookupResultsTy &Results) {
-  typedef Sema::LookupResult LResult;
-  typedef llvm::SmallPtrSet<NamedDecl*, 4> DeclsSetTy;
-
-  // Remove duplicated Decl pointing at same Decl, by storing them in
-  // associative collection. This might be case for code like:
-  //
-  //    namespace A { int i; }
-  //    namespace B { using namespace A; }
-  //    namespace C { using namespace A; }
-  //
-  //    void foo() {
-  //      using namespace B;
-  //      using namespace C;
-  //      ++i; // finds A::i, from both namespace B and C at global scope
-  //    }
-  //
-  //  C++ [namespace.qual].p3:
-  //    The same declaration found more than once is not an ambiguity
-  //    (because it is still a unique declaration).
-  DeclsSetTy FoundDecls;
-
-  // Counter of tag names, and functions for resolving ambiguity
-  // and name hiding.
-  std::size_t TagNames = 0, Functions = 0, OrdinaryNonFunc = 0;
-
-  LookupResultsTy::iterator I = Results.begin(), End = Results.end();
-
-  // No name lookup results, return early.
-  if (I == End) return LResult::CreateLookupResult(Context, 0);
-
-  // Keep track of the tag declaration we found. We only use this if
-  // we find a single tag declaration.
-  TagDecl *TagFound = 0;
-
-  for (; I != End; ++I) {
-    switch (I->getKind()) {
-    case LResult::NotFound:
-      assert(false &&
-             "Should be always successful name lookup result here.");
-      break;
-
-    case LResult::AmbiguousReference:
-    case LResult::AmbiguousBaseSubobjectTypes:
-    case LResult::AmbiguousBaseSubobjects:
-      assert(false && "Shouldn't get ambiguous lookup here.");
-      break;
-
-    case LResult::Found: {
-      NamedDecl *ND = I->getAsDecl()->getUnderlyingDecl();
-
-      if (TagDecl *TD = dyn_cast<TagDecl>(ND)) {
-        TagFound = TD->getCanonicalDecl();
-        TagNames += FoundDecls.insert(TagFound)?  1 : 0;
-      } else if (ND->isFunctionOrFunctionTemplate())
-        Functions += FoundDecls.insert(ND)? 1 : 0;
-      else
-        FoundDecls.insert(ND);
-      break;
-    }
-
-    case LResult::FoundOverloaded:
-      for (LResult::iterator FI = I->begin(), FEnd = I->end(); FI != FEnd; ++FI)
-        Functions += FoundDecls.insert(*FI)? 1 : 0;
-      break;
-    }
-  }
-  OrdinaryNonFunc = FoundDecls.size() - TagNames - Functions;
-  bool Ambiguous = false, NameHidesTags = false;
-
-  if (FoundDecls.size() == 1) {
-    // 1) Exactly one result.
-  } else if (TagNames > 1) {
-    // 2) Multiple tag names (even though they may be hidden by an
-    // object name).
-    Ambiguous = true;
-  } else if (FoundDecls.size() - TagNames == 1) {
-    // 3) Ordinary name hides (optional) tag.
-    NameHidesTags = TagFound;
-  } else if (Functions) {
-    // C++ [basic.lookup].p1:
-    // ... Name lookup may associate more than one declaration with
-    // a name if it finds the name to be a function name; the declarations
-    // are said to form a set of overloaded functions (13.1).
-    // Overload resolution (13.3) takes place after name lookup has succeeded.
-    //
-    if (!OrdinaryNonFunc) {
-      // 4) Functions hide tag names.
-      NameHidesTags = TagFound;
-    } else {
-      // 5) Functions + ordinary names.
-      Ambiguous = true;
-    }
-  } else {
-    // 6) Multiple non-tag names
-    Ambiguous = true;
-  }
-
-  if (Ambiguous)
-    return LResult::CreateLookupResult(Context,
-                                       FoundDecls.begin(), FoundDecls.size());
-  if (NameHidesTags) {
-    // There's only one tag, TagFound. Remove it.
-    assert(TagFound && FoundDecls.count(TagFound) && "No tag name found?");
-    FoundDecls.erase(TagFound);
-  }
-
-  // Return successful name lookup result.
-  return LResult::CreateLookupResult(Context,
-                                MaybeConstructOverloadSet(Context,
-                                                          FoundDecls.begin(),
-                                                          FoundDecls.end()));
-}
-
 // Retrieve the set of identifier namespaces that correspond to a
 // specific kind of name lookup.
 inline unsigned
@@ -324,97 +151,78 @@
   return IDNS;
 }
 
-Sema::LookupResult
-Sema::LookupResult::CreateLookupResult(ASTContext &Context, NamedDecl *D) {
-  if (D)
-    D = D->getUnderlyingDecl();
-
-  LookupResult Result;
-  Result.StoredKind = (D && isa<OverloadedFunctionDecl>(D))?
-    OverloadedDeclSingleDecl : SingleDecl;
-  Result.First = reinterpret_cast<uintptr_t>(D);
-  Result.Last = 0;
-  Result.Context = &Context;
-  return Result;
-}
-
-/// @brief Moves the name-lookup results from Other to this LookupResult.
-Sema::LookupResult
-Sema::LookupResult::CreateLookupResult(ASTContext &Context,
-                                       IdentifierResolver::iterator F,
-                                       IdentifierResolver::iterator L) {
-  LookupResult Result;
-  Result.Context = &Context;
-
-  if (F != L && (*F)->isFunctionOrFunctionTemplate()) {
-    IdentifierResolver::iterator Next = F;
-    ++Next;
-    if (Next != L && (*Next)->isFunctionOrFunctionTemplate()) {
-      Result.StoredKind = OverloadedDeclFromIdResolver;
-      Result.First = F.getAsOpaqueValue();
-      Result.Last = L.getAsOpaqueValue();
-      return Result;
-    }
-  }
+// Necessary because CXXBasePaths is not complete in Sema.h
+void Sema::LookupResult::deletePaths(CXXBasePaths *Paths) {
+  delete Paths;
+}
 
-  NamedDecl *D = *F;
-  if (D)
-    D = D->getUnderlyingDecl();
-
-  Result.StoredKind = SingleDecl;
-  Result.First = reinterpret_cast<uintptr_t>(D);
-  Result.Last = 0;
-  return Result;
-}
-
-Sema::LookupResult
-Sema::LookupResult::CreateLookupResult(ASTContext &Context,
-                                       DeclContext::lookup_iterator F,
-                                       DeclContext::lookup_iterator L) {
-  LookupResult Result;
-  Result.Context = &Context;
-
-  if (F != L && (*F)->isFunctionOrFunctionTemplate()) {
-    DeclContext::lookup_iterator Next = F;
-    ++Next;
-    if (Next != L && (*Next)->isFunctionOrFunctionTemplate()) {
-      Result.StoredKind = OverloadedDeclFromDeclContext;
-      Result.First = reinterpret_cast<uintptr_t>(F);
-      Result.Last = reinterpret_cast<uintptr_t>(L);
-      return Result;
-    }
-  }
+void Sema::LookupResult::resolveKind() {
+  unsigned N = Decls.size();
 
-  NamedDecl *D = *F;
-  if (D)
-    D = D->getUnderlyingDecl();
+  // Fast case: no possible ambiguity.
+  if (N <= 1) return;
 
-  Result.StoredKind = SingleDecl;
-  Result.First = reinterpret_cast<uintptr_t>(D);
-  Result.Last = 0;
-  return Result;
-}
+  llvm::SmallPtrSet<NamedDecl*, 16> Unique;
+
+  bool Ambiguous = false;
+  bool HasTag = false, HasFunction = false, HasNonFunction = false;
 
-/// @brief Determine the result of name lookup.
-Sema::LookupResult::LookupKind Sema::LookupResult::getKind() const {
-  switch (StoredKind) {
-  case SingleDecl:
-    return (reinterpret_cast<Decl *>(First) != 0)? Found : NotFound;
+  unsigned UniqueTagIndex = 0;
+  
+  unsigned I = 0;
+  while (I < N) {
+    NamedDecl *D = Decls[I];
+    assert(D == D->getUnderlyingDecl());
+
+    NamedDecl *CanonD = cast<NamedDecl>(D->getCanonicalDecl());
+    if (!Unique.insert(CanonD)) {
+      // 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.
+      Decls[I] = Decls[--N];
+    } else {
+      // Otherwise, do some decl type analysis and then continue.
+      if (isa<TagDecl>(D)) {
+        if (HasTag)
+          Ambiguous = true;
+        UniqueTagIndex = I;
+        HasTag = true;
+      } else if (D->isFunctionOrFunctionTemplate()) {
+        HasFunction = true;
+      } else {
+        if (HasNonFunction)
+          Ambiguous = true;
+        HasNonFunction = true;
+      }
+      I++;
+    }
+  }
 
-  case OverloadedDeclSingleDecl:
-  case OverloadedDeclFromIdResolver:
-  case OverloadedDeclFromDeclContext:
-    return FoundOverloaded;
+  // 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
+  //   scope. If a class or enumeration name and an object, function,
+  //   or enumerator are declared in the same scope (in any order)
+  //   with the same name, the class or enumeration name is hidden
+  //   wherever the object, function, or enumerator name is visible.
+  // But it's still an error if there are distinct tag types found,
+  // even if they're not visible. (ref?)
+  if (HasTag && !Ambiguous && (HasFunction || HasNonFunction))
+    Decls[UniqueTagIndex] = Decls[--N];
 
-  case AmbiguousLookupStoresBasePaths:
-    return Last? AmbiguousBaseSubobjectTypes : AmbiguousBaseSubobjects;
+  Decls.set_size(N);
 
-  case AmbiguousLookupStoresDecls:
-    return AmbiguousReference;
-  }
+  if (HasFunction && HasNonFunction)
+    Ambiguous = true;
 
-  // We can't ever get here.
-  return NotFound;
+  if (Ambiguous)
+    Kind = AmbiguousReference;
+  else if (N > 1)
+    Kind = FoundOverloaded;
+  else
+    Kind = Found;
 }
 
 /// @brief Converts the result of name lookup into a single (possible
@@ -430,191 +238,93 @@
 /// solution, since it causes the OverloadedFunctionDecl to be
 /// leaked. FIXME: Eventually, there will be a better way to iterate
 /// over the set of overloaded functions returned by name lookup.
-NamedDecl *Sema::LookupResult::getAsDecl() const {
-  switch (StoredKind) {
-  case SingleDecl:
-    return reinterpret_cast<NamedDecl *>(First);
-
-  case OverloadedDeclFromIdResolver:
-    return MaybeConstructOverloadSet(*Context,
-                         IdentifierResolver::iterator::getFromOpaqueValue(First),
-                         IdentifierResolver::iterator::getFromOpaqueValue(Last));
-
-  case OverloadedDeclFromDeclContext:
-    return MaybeConstructOverloadSet(*Context,
-                           reinterpret_cast<DeclContext::lookup_iterator>(First),
-                           reinterpret_cast<DeclContext::lookup_iterator>(Last));
-
-  case OverloadedDeclSingleDecl:
-    return reinterpret_cast<OverloadedFunctionDecl*>(First);
-
-  case AmbiguousLookupStoresDecls:
-  case AmbiguousLookupStoresBasePaths:
-    assert(false &&
-           "Name lookup returned an ambiguity that could not be handled");
-    break;
+NamedDecl *Sema::LookupResult::getAsSingleDecl(ASTContext &C) const {
+  size_t size = Decls.size();
+  if (size == 0) return 0;
+  if (size == 1) return *begin();
+
+  if (isAmbiguous()) return 0;
+
+  iterator I = begin(), E = end();
+
+  OverloadedFunctionDecl *Ovl
+    = 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");
+    assert(ND->isFunctionOrFunctionTemplate());
+    if (isa<FunctionDecl>(ND))
+      Ovl->addOverload(cast<FunctionDecl>(ND));
+    else
+      Ovl->addOverload(cast<FunctionTemplateDecl>(ND));
+    // FIXME: UnresolvedUsingDecls.
   }
-
-  return 0;
+  
+  return Ovl;
 }
 
-/// @brief Retrieves the BasePaths structure describing an ambiguous
-/// name lookup, or null.
-CXXBasePaths *Sema::LookupResult::getBasePaths() const {
-  if (StoredKind == AmbiguousLookupStoresBasePaths)
-      return reinterpret_cast<CXXBasePaths *>(First);
-  return 0;
+void Sema::LookupResult::addDeclsFromBasePaths(const CXXBasePaths &P) {
+  CXXBasePaths::paths_iterator I, E;
+  DeclContext::lookup_iterator DI, DE;
+  for (I = P.begin(), E = P.end(); I != E; ++I)
+    for (llvm::tie(DI,DE) = I->Decls; DI != DE; ++DI)
+      addDecl(*DI);
 }
 
-Sema::LookupResult::iterator::reference
-Sema::LookupResult::iterator::operator*() const {
-  switch (Result->StoredKind) {
-  case SingleDecl:
-    return reinterpret_cast<NamedDecl*>(Current);
-
-  case OverloadedDeclSingleDecl:
-    return *reinterpret_cast<NamedDecl**>(Current);
-
-  case OverloadedDeclFromIdResolver:
-    return *IdentifierResolver::iterator::getFromOpaqueValue(Current);
-
-  case AmbiguousLookupStoresBasePaths:
-    if (Result->Last)
-      return *reinterpret_cast<NamedDecl**>(Current);
-
-    // Fall through to handle the DeclContext::lookup_iterator we're
-    // storing.
-
-  case OverloadedDeclFromDeclContext:
-  case AmbiguousLookupStoresDecls:
-    return *reinterpret_cast<DeclContext::lookup_iterator>(Current);
-  }
-
-  return 0;
+void Sema::LookupResult::setAmbiguousBaseSubobjects(CXXBasePaths &P) {
+  Paths = new CXXBasePaths;
+  Paths->swap(P);
+  addDeclsFromBasePaths(*Paths);
+  resolveKind();
+  Kind = AmbiguousBaseSubobjects;
 }
 
-Sema::LookupResult::iterator& Sema::LookupResult::iterator::operator++() {
-  switch (Result->StoredKind) {
-  case SingleDecl:
-    Current = reinterpret_cast<uintptr_t>((NamedDecl*)0);
-    break;
-
-  case OverloadedDeclSingleDecl: {
-    NamedDecl ** I = reinterpret_cast<NamedDecl**>(Current);
-    ++I;
-    Current = reinterpret_cast<uintptr_t>(I);
-    break;
-  }
-
-  case OverloadedDeclFromIdResolver: {
-    IdentifierResolver::iterator I
-      = IdentifierResolver::iterator::getFromOpaqueValue(Current);
-    ++I;
-    Current = I.getAsOpaqueValue();
-    break;
-  }
-
-  case AmbiguousLookupStoresBasePaths:
-    if (Result->Last) {
-      NamedDecl ** I = reinterpret_cast<NamedDecl**>(Current);
-      ++I;
-      Current = reinterpret_cast<uintptr_t>(I);
-      break;
-    }
-    // Fall through to handle the DeclContext::lookup_iterator we're
-    // storing.
-
-  case OverloadedDeclFromDeclContext:
-  case AmbiguousLookupStoresDecls: {
-    DeclContext::lookup_iterator I
-      = reinterpret_cast<DeclContext::lookup_iterator>(Current);
-    ++I;
-    Current = reinterpret_cast<uintptr_t>(I);
-    break;
-  }
-  }
-
-  return *this;
+void Sema::LookupResult::setAmbiguousBaseSubobjectTypes(CXXBasePaths &P) {
+  Paths = new CXXBasePaths;
+  Paths->swap(P);
+  addDeclsFromBasePaths(*Paths);
+  resolveKind();
+  Kind = AmbiguousBaseSubobjectTypes;
 }
 
-Sema::LookupResult::iterator Sema::LookupResult::begin() {
-  switch (StoredKind) {
-  case SingleDecl:
-  case OverloadedDeclFromIdResolver:
-  case OverloadedDeclFromDeclContext:
-  case AmbiguousLookupStoresDecls:
-    return iterator(this, First);
-
-  case OverloadedDeclSingleDecl: {
-    OverloadedFunctionDecl * Ovl =
-      reinterpret_cast<OverloadedFunctionDecl*>(First);
-    return iterator(this,
-                    reinterpret_cast<uintptr_t>(&(*Ovl->function_begin())));
-  }
-
-  case AmbiguousLookupStoresBasePaths:
-    if (Last)
-      return iterator(this,
-              reinterpret_cast<uintptr_t>(getBasePaths()->found_decls_begin()));
-    else
-      return iterator(this,
-              reinterpret_cast<uintptr_t>(getBasePaths()->front().Decls.first));
+void Sema::LookupResult::print(llvm::raw_ostream &Out) {
+  Out << Decls.size() << " result(s)";
+  if (isAmbiguous()) Out << ", ambiguous";
+  if (Paths) Out << ", base paths present";
+  
+  for (iterator I = begin(), E = end(); I != E; ++I) {
+    Out << "\n";
+    (*I)->print(Out, 2);
   }
-
-  // Required to suppress GCC warning.
-  return iterator();
 }
 
-Sema::LookupResult::iterator Sema::LookupResult::end() {
-  switch (StoredKind) {
-  case SingleDecl:
-  case OverloadedDeclFromIdResolver:
-  case OverloadedDeclFromDeclContext:
-  case AmbiguousLookupStoresDecls:
-    return iterator(this, Last);
-
-  case OverloadedDeclSingleDecl: {
-    OverloadedFunctionDecl * Ovl =
-      reinterpret_cast<OverloadedFunctionDecl*>(First);
-    return iterator(this,
-                    reinterpret_cast<uintptr_t>(&(*Ovl->function_end())));
-  }
-
-  case AmbiguousLookupStoresBasePaths:
-    if (Last)
-      return iterator(this,
-               reinterpret_cast<uintptr_t>(getBasePaths()->found_decls_end()));
-    else
-      return iterator(this, reinterpret_cast<uintptr_t>(
-                                     getBasePaths()->front().Decls.second));
-  }
+// Adds all qualifying matches for a name within a decl context to the
+// given lookup result.  Returns true if any matches were found.
+static bool LookupDirect(Sema::LookupResult &R, DeclContext *DC,
+                         DeclarationName Name,
+                         Sema::LookupNameKind NameKind,
+                         unsigned IDNS) {
+  bool Found = false;
 
-  // Required to suppress GCC warning.
-  return iterator();
-}
+  DeclContext::lookup_iterator I, E;
+  for (llvm::tie(I, E) = DC->lookup(Name); I != E; ++I)
+    if (Sema::isAcceptableLookupResult(*I, NameKind, IDNS))
+      R.addDecl(*I), Found = true;
 
-void Sema::LookupResult::Destroy() {
-  if (CXXBasePaths *Paths = getBasePaths())
-    delete Paths;
-  else if (getKind() == AmbiguousReference)
-    delete[] reinterpret_cast<NamedDecl **>(First);
+  return Found;
 }
 
-static void
-CppNamespaceLookup(ASTContext &Context, DeclContext *NS,
+static bool
+CppNamespaceLookup(Sema::LookupResult &R, ASTContext &Context, DeclContext *NS,
                    DeclarationName Name, Sema::LookupNameKind NameKind,
-                   unsigned IDNS, LookupResultsTy &Results,
-                   UsingDirectivesTy *UDirs = 0) {
+                   unsigned IDNS, UsingDirectivesTy *UDirs = 0) {
 
   assert(NS && NS->isFileContext() && "CppNamespaceLookup() requires namespace!");
 
   // Perform qualified name lookup into the LookupCtx.
-  DeclContext::lookup_iterator I, E;
-  for (llvm::tie(I, E) = NS->lookup(Name); I != E; ++I)
-    if (Sema::isAcceptableLookupResult(*I, NameKind, IDNS)) {
-      Results.push_back(Sema::LookupResult::CreateLookupResult(Context, I, E));
-      break;
-    }
+  bool Found = LookupDirect(R, NS, Name, NameKind, IDNS);
 
   if (UDirs) {
     // For each UsingDirectiveDecl, which common ancestor is equal
@@ -625,9 +335,13 @@
                        UsingDirAncestorCompare());
 
     for (; UI != UEnd; ++UI)
-      CppNamespaceLookup(Context, (*UI)->getNominatedNamespace(),
-                         Name, NameKind, IDNS, Results);
+      if (LookupDirect(R, (*UI)->getNominatedNamespace(), Name, NameKind, IDNS))
+        Found = true;
   }
+
+  R.resolveKind();
+
+  return Found;
 }
 
 static bool isNamespaceOrTranslationUnitScope(Scope *S) {
@@ -645,8 +359,8 @@
   return 0;
 }
 
-std::pair<bool, Sema::LookupResult>
-Sema::CppLookupName(Scope *S, DeclarationName Name,
+bool
+Sema::CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
                     LookupNameKind NameKind, bool RedeclarationOnly) {
   assert(getLangOptions().CPlusPlus &&
          "Can perform only C++ lookup");
@@ -684,25 +398,19 @@
   //
   for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) {
     // Check whether the IdResolver has anything in this scope.
+    bool Found = false;
     for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
       if (isAcceptableLookupResult(*I, NameKind, IDNS)) {
-        // We found something.  Look for anything else in our scope
-        // with this same name and in an acceptable identifier
-        // namespace, so that we can construct an overload set if we
-        // need to.
-        IdentifierResolver::iterator LastI = I;
-        for (++LastI; LastI != IEnd; ++LastI) {
-          if (!S->isDeclScope(DeclPtrTy::make(*LastI)))
-            break;
-        }
-        LookupResult Result =
-          LookupResult::CreateLookupResult(Context, I, LastI);
-        return std::make_pair(true, Result);
+        Found = true;
+        R.addDecl(*I);
       }
     }
+    if (Found) {
+      R.resolveKind();
+      return true;
+    }
+
     if (DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity())) {
-      LookupResult R;
-      
       DeclContext *OuterCtx = findOuterContext(S);
       for (; Ctx && Ctx->getPrimaryContext() != OuterCtx; 
            Ctx = Ctx->getLookupParent()) {
@@ -715,9 +423,8 @@
         // example, inside a class without any base classes, we never need to
         // perform qualified lookup because all of the members are on top of the
         // identifier chain.
-        R = LookupQualifiedName(Ctx, Name, NameKind, RedeclarationOnly);
-        if (R)
-          return std::make_pair(true, R);
+        if (LookupQualifiedName(R, Ctx, Name, NameKind, RedeclarationOnly))
+          return true;
       }
     }
   }
@@ -740,8 +447,6 @@
   // that aren't strictly lexical, and therefore we walk through the
   // context as well as walking through the scopes.
 
-  LookupResultsTy LookupResults;
-  bool LookedInCtx = false;
   for (; S; S = S->getParent()) {
     DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity());
     if (Ctx->isTransparentContext())
@@ -751,45 +456,32 @@
            "We should have been looking only at file context here already.");
 
     // Check whether the IdResolver has anything in this scope.
+    bool Found = false;
     for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
       if (isAcceptableLookupResult(*I, NameKind, IDNS)) {
         // We found something.  Look for anything else in our scope
         // with this same name and in an acceptable identifier
         // namespace, so that we can construct an overload set if we
         // need to.
-        IdentifierResolver::iterator LastI = I;
-        for (++LastI; LastI != IEnd; ++LastI) {
-          if (!S->isDeclScope(DeclPtrTy::make(*LastI)))
-            break;
-        }
-
-        // We store name lookup result, and continue trying to look into
-        // associated context, and maybe namespaces nominated by
-        // using-directives.
-        LookupResults.push_back(
-          LookupResult::CreateLookupResult(Context, I, LastI));
-        break;
+        Found = true;
+        R.addDecl(*I);
       }
     }
 
-    LookedInCtx = true;
     // Look into context considering using-directives.
-    CppNamespaceLookup(Context, Ctx, Name, NameKind, IDNS,
-                       LookupResults, &UDirs);
+    if (CppNamespaceLookup(R, Context, Ctx, Name, NameKind, IDNS, &UDirs))
+      Found = true;
 
-    LookupResult Result;
-    if ((Result = MergeLookupResults(Context, LookupResults)) ||
-        (RedeclarationOnly && !Ctx->isTransparentContext()))
-      return std::make_pair(true, Result);
-  }
-
-  if (!(LookedInCtx || LookupResults.empty())) {
-    // We didn't Performed lookup in Scope entity, so we return
-    // result form IdentifierResolver.
-    assert((LookupResults.size() == 1) && "Wrong size!");
-    return std::make_pair(true, LookupResults.front());
+    if (Found) {
+      R.resolveKind();
+      return true;
+    }
+
+    if (RedeclarationOnly && !Ctx->isTransparentContext())
+      return false;
   }
-  return std::make_pair(false, LookupResult());
+
+  return !R.empty();
 }
 
 /// @brief Perform unqualified name lookup starting from a given
@@ -823,11 +515,10 @@
 /// @returns The result of name lookup, which includes zero or more
 /// declarations and possibly additional information used to diagnose
 /// ambiguities.
-Sema::LookupResult
-Sema::LookupName(Scope *S, DeclarationName Name, LookupNameKind NameKind,
-                 bool RedeclarationOnly, bool AllowBuiltinCreation,
-                 SourceLocation Loc) {
-  if (!Name) return LookupResult::CreateLookupResult(Context, 0);
+bool Sema::LookupName(LookupResult &R, Scope *S, DeclarationName Name,
+                      LookupNameKind NameKind, bool RedeclarationOnly,
+                      bool AllowBuiltinCreation, SourceLocation Loc) {
+  if (!Name) return false;
 
   if (!getLangOptions().CPlusPlus) {
     // Unqualified name lookup in C/Objective-C is purely lexical, so
@@ -897,6 +588,8 @@
             continue;
         }
 
+        R.addDecl(*I);
+
         if ((*I)->getAttr<OverloadableAttr>()) {
           // If this declaration has the "overloadable" attribute, we
           // might have a set of overloaded functions.
@@ -912,20 +605,18 @@
           for (++LastI; LastI != IEnd; ++LastI) {
             if (!S->isDeclScope(DeclPtrTy::make(*LastI)))
               break;
+            R.addDecl(*LastI);
           }
-
-          return LookupResult::CreateLookupResult(Context, I, LastI);
         }
 
-        // We have a single lookup result.
-        return LookupResult::CreateLookupResult(Context, *I);
+        R.resolveKind();
+
+        return true;
       }
   } else {
     // Perform C++ unqualified name lookup.
-    std::pair<bool, LookupResult> MaybeResult =
-      CppLookupName(S, Name, NameKind, RedeclarationOnly);
-    if (MaybeResult.first)
-      return MaybeResult.second;
+    if (CppLookupName(R, S, Name, NameKind, RedeclarationOnly))
+      return true;
   }
 
   // If we didn't find a use of this identifier, and if the identifier
@@ -941,15 +632,16 @@
         // 'malloc'. Instead, we'll just error.
         if (getLangOptions().CPlusPlus &&
             Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
-          return LookupResult::CreateLookupResult(Context, 0);
+          return false;
 
-        return LookupResult::CreateLookupResult(Context,
-                            LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID,
-                                                S, RedeclarationOnly, Loc));
+        NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID,
+                                           S, RedeclarationOnly, Loc);
+        if (D) R.addDecl(D);
+        return (D != NULL);
       }
     }
   }
-  return LookupResult::CreateLookupResult(Context, 0);
+  return false;
 }
 
 /// @brief Perform qualified name lookup into a given context.
@@ -982,13 +674,13 @@
 /// @returns The result of name lookup, which includes zero or more
 /// declarations and possibly additional information used to diagnose
 /// ambiguities.
-Sema::LookupResult
-Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
-                          LookupNameKind NameKind, bool RedeclarationOnly) {
+bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
+                               DeclarationName Name, LookupNameKind NameKind,
+                               bool RedeclarationOnly) {
   assert(LookupCtx && "Sema::LookupQualifiedName requires a lookup context");
 
   if (!Name)
-    return LookupResult::CreateLookupResult(Context, 0);
+    return false;
 
   // If we're performing qualified name lookup (e.g., lookup into a
   // struct), find fields as part of ordinary name lookup.
@@ -1007,15 +699,15 @@
          "Declaration context must already be complete!");
 
   // Perform qualified name lookup into the LookupCtx.
-  DeclContext::lookup_iterator I, E;
-  for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I)
-    if (isAcceptableLookupResult(*I, NameKind, IDNS))
-      return LookupResult::CreateLookupResult(Context, I, E);
+  if (LookupDirect(R, LookupCtx, Name, NameKind, IDNS)) {
+    R.resolveKind();
+    return true;
+  }
 
   // If this isn't a C++ class, we aren't allowed to look into base
   // classes, we're done.
   if (RedeclarationOnly || !isa<CXXRecordDecl>(LookupCtx))
-    return LookupResult::CreateLookupResult(Context, 0);
+    return false;
 
   // Perform lookup into our base classes.
   CXXRecordDecl *LookupRec = cast<CXXRecordDecl>(LookupCtx);
@@ -1041,7 +733,7 @@
     case LookupObjCImplementationName:
     case LookupObjCCategoryImplName:
       // These lookups will never find a member in a C++ class (or base class).
-      return LookupResult::CreateLookupResult(Context, 0);
+      return false;
       
     case LookupNestedNameSpecifierName:
       BaseCallback = &CXXRecordDecl::FindNestedNameSpecifierMember;
@@ -1049,7 +741,7 @@
   }
   
   if (!LookupRec->lookupInBases(BaseCallback, Name.getAsOpaquePtr(), Paths))
-    return LookupResult::CreateLookupResult(Context, 0);
+    return false;
 
   // C++ [class.member.lookup]p2:
   //   [...] If the resulting set of declarations are not all from
@@ -1066,16 +758,15 @@
 
     // Determine whether we're looking at a distinct sub-object or not.
     if (SubobjectType.isNull()) {
-      // This is the first subobject we've looked at. Record it's type.
+      // This is the first subobject we've looked at. Record its type.
       SubobjectType = Context.getCanonicalType(PathElement.Base->getType());
       SubobjectNumber = PathElement.SubobjectNumber;
     } else if (SubobjectType
                  != Context.getCanonicalType(PathElement.Base->getType())) {
       // We found members of the given name in two subobjects of
       // different types. This lookup is ambiguous.
-      CXXBasePaths *PathsOnHeap = new CXXBasePaths;
-      PathsOnHeap->swap(Paths);
-      return LookupResult::CreateLookupResult(Context, PathsOnHeap, true);
+      R.setAmbiguousBaseSubobjectTypes(Paths);
+      return true;
     } else if (SubobjectNumber != PathElement.SubobjectNumber) {
       // We have a different subobject of the same type.
 
@@ -1111,21 +802,18 @@
 
       // We have found a nonstatic member name in multiple, distinct
       // subobjects. Name lookup is ambiguous.
-      CXXBasePaths *PathsOnHeap = new CXXBasePaths;
-      PathsOnHeap->swap(Paths);
-      return LookupResult::CreateLookupResult(Context, PathsOnHeap, false);
+      R.setAmbiguousBaseSubobjects(Paths);
+      return true;
     }
   }
 
   // Lookup in a base class succeeded; return these results.
 
-  // If we found a function declaration, return an overload set.
-  if ((*Paths.front().Decls.first)->isFunctionOrFunctionTemplate())
-    return LookupResult::CreateLookupResult(Context,
-                        Paths.front().Decls.first, Paths.front().Decls.second);
-
-  // We found a non-function declaration; return a single declaration.
-  return LookupResult::CreateLookupResult(Context, *Paths.front().Decls.first);
+  DeclContext::lookup_iterator I, E;
+  for (llvm::tie(I,E) = Paths.front().Decls; I != E; ++I)
+    R.addDecl(*I);
+  R.resolveKind();
+  return true;
 }
 
 /// @brief Performs name lookup for a name that was parsed in the
@@ -1152,17 +840,16 @@
 /// @param EnteringContext Indicates whether we are going to enter the
 /// context of the scope-specifier SS (if present).
 ///
-/// @returns The result of qualified or unqualified name lookup.
-Sema::LookupResult
-Sema::LookupParsedName(Scope *S, const CXXScopeSpec *SS,
-                       DeclarationName Name, LookupNameKind NameKind,
-                       bool RedeclarationOnly, bool AllowBuiltinCreation,
-                       SourceLocation Loc,
-                       bool EnteringContext) {
+/// @returns True if any decls were found (but possibly ambiguous)
+bool Sema::LookupParsedName(LookupResult &R, Scope *S, const CXXScopeSpec *SS,
+                            DeclarationName Name, LookupNameKind NameKind,
+                            bool RedeclarationOnly, bool AllowBuiltinCreation,
+                            SourceLocation Loc,
+                            bool EnteringContext) {
   if (SS && SS->isInvalid()) {
     // When the scope specifier is invalid, don't even look for
     // anything.
-    return LookupResult::CreateLookupResult(Context, 0);
+    return false;
   }
 
   if (SS && SS->isSet()) {
@@ -1170,20 +857,20 @@
       // We have resolved the scope specifier to a particular declaration
       // contex, and will perform name lookup in that context.
       if (!DC->isDependentContext() && RequireCompleteDeclContext(*SS))
-        return LookupResult::CreateLookupResult(Context, 0);
+        return false;
 
-      return LookupQualifiedName(DC, Name, NameKind, RedeclarationOnly);
+      return LookupQualifiedName(R, DC, Name, NameKind, RedeclarationOnly);
     }
 
     // We could not resolve the scope specified to a specific declaration
     // context, which means that SS refers to an unknown specialization.
     // Name lookup can't find anything in this case.
-    return LookupResult::CreateLookupResult(Context, 0);
+    return false;
   }
 
   // Perform unqualified name lookup starting in the given scope.
-  return LookupName(S, Name, NameKind, RedeclarationOnly, AllowBuiltinCreation,
-                    Loc);
+  return LookupName(R, S, Name, NameKind, RedeclarationOnly,
+                    AllowBuiltinCreation, Loc);
 }
 
 
@@ -1222,7 +909,6 @@
 
       Diag((*Found)->getLocation(), diag::note_ambiguous_member_found);
 
-      Result.Destroy();
       return true;
     }
 
@@ -1240,24 +926,18 @@
         Diag(D->getLocation(), diag::note_ambiguous_member_found);
     }
 
-    Result.Destroy();
-    return true;
-  } else if (Result.getKind() == LookupResult::AmbiguousReference) {
-    Diag(NameLoc, diag::err_ambiguous_reference) << Name << LookupRange;
-
-    NamedDecl **DI = reinterpret_cast<NamedDecl **>(Result.First),
-            **DEnd = reinterpret_cast<NamedDecl **>(Result.Last);
-
-    for (; DI != DEnd; ++DI)
-      Diag((*DI)->getLocation(), diag::note_ambiguous_candidate) << *DI;
-
-    Result.Destroy();
     return true;
   }
 
-  assert(false && "Unhandled form of name lookup ambiguity");
+  assert(Result.getKind() == LookupResult::AmbiguousReference &&
+         "unhandled form of name lookup ambiguity");
+  Diag(NameLoc, diag::err_ambiguous_reference) << Name << LookupRange;
+
+  
+  LookupResult::iterator DI = Result.begin(), DE = Result.end();
+  for (; DI != DE; ++DI)
+    Diag((*DI)->getLocation(), diag::note_ambiguous_candidate) << *DI;
 
-  // We can't reach here.
   return true;
 }
 
@@ -1661,14 +1341,14 @@
 
 /// \brief Find the protocol with the given name, if any.
 ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II) {
-  Decl *D = LookupName(TUScope, II, LookupObjCProtocolName).getAsDecl();
+  Decl *D = LookupSingleName(TUScope, II, LookupObjCProtocolName);
   return cast_or_null<ObjCProtocolDecl>(D);
 }
 
 /// \brief Find the Objective-C category implementation with the given
 /// name, if any.
 ObjCCategoryImplDecl *Sema::LookupObjCCategoryImpl(IdentifierInfo *II) {
-  Decl *D = LookupName(TUScope, II, LookupObjCCategoryImplName).getAsDecl();
+  Decl *D = LookupSingleName(TUScope, II, LookupObjCCategoryImplName);
   return cast_or_null<ObjCCategoryImplDecl>(D);
 }
 
@@ -1678,8 +1358,8 @@
 Decl *Sema::LookupQualifiedNameWithType(DeclContext *DC,
                                         DeclarationName Name,
                                         QualType T) {
-  LookupResult result =
-    LookupQualifiedName(DC, Name, LookupOrdinaryName, true);
+  LookupResult result;
+  LookupQualifiedName(result, DC, Name, LookupOrdinaryName, true);
 
   CanQualType CQT = Context.getCanonicalType(T);
 
@@ -1708,11 +1388,12 @@
   //        of type T2 or "reference to (possibly cv-qualified) T2",
   //        when T2 is an enumeration type, are candidate functions.
   DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
-  LookupResult Operators = LookupName(S, OpName, LookupOperatorName);
+  LookupResult Operators;
+  LookupName(Operators, S, OpName, LookupOperatorName);
 
   assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
 
-  if (!Operators)
+  if (Operators.empty())
     return;
 
   for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end();

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Oct  9 16:13:30 2009
@@ -2762,8 +2762,9 @@
     if (RequireCompleteType(OpLoc, T1, PartialDiagnostic(0)))
       return;
 
-    LookupResult Operators = LookupQualifiedName(T1Rec->getDecl(), OpName,
-                                                 LookupOrdinaryName, false);
+    LookupResult Operators;
+    LookupQualifiedName(Operators, T1Rec->getDecl(), OpName,
+                        LookupOrdinaryName, false);
     for (LookupResult::iterator Oper = Operators.begin(),
                              OperEnd = Operators.end();
          Oper != OperEnd;
@@ -5070,8 +5071,8 @@
   OverloadCandidateSet CandidateSet;
   const RecordType *BaseRecord = Base->getType()->getAs<RecordType>();
 
-  LookupResult R = LookupQualifiedName(BaseRecord->getDecl(), OpName, 
-                                       LookupOrdinaryName);
+  LookupResult R;
+  LookupQualifiedName(R, BaseRecord->getDecl(), OpName, LookupOrdinaryName);
 
   for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
        Oper != OperEnd; ++Oper)

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Oct  9 16:13:30 2009
@@ -135,7 +135,7 @@
     if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(*SS))
       return TNK_Non_template;
 
-    Found = LookupQualifiedName(LookupCtx, &II, LookupOrdinaryName);
+    LookupQualifiedName(Found, LookupCtx, &II, LookupOrdinaryName);
 
     if (ObjectTypePtr && Found.getKind() == LookupResult::NotFound) {
       // C++ [basic.lookup.classref]p1:
@@ -150,7 +150,7 @@
       //
       // FIXME: When we're instantiating a template, do we actually have to
       // look in the scope of the template? Seems fishy...
-      Found = LookupName(S, &II, LookupOrdinaryName);
+      LookupName(Found, S, &II, LookupOrdinaryName);
       ObjectTypeSearchedInScope = true;
     }
   } else if (isDependent) {
@@ -158,14 +158,15 @@
     return TNK_Non_template;
   } else {
     // Perform unqualified name lookup in the current scope.
-    Found = LookupName(S, &II, LookupOrdinaryName);
+    LookupName(Found, S, &II, LookupOrdinaryName);
   }
 
   // FIXME: Cope with ambiguous name-lookup results.
   assert(!Found.isAmbiguous() &&
          "Cannot handle template name-lookup ambiguities");
 
-  NamedDecl *Template = isAcceptableTemplateName(Context, Found);
+  NamedDecl *Template
+    = isAcceptableTemplateName(Context, Found.getAsSingleDecl(Context));
   if (!Template)
     return TNK_Non_template;
 
@@ -175,9 +176,11 @@
     //   template, the name is also looked up in the context of the entire
     //   postfix-expression and [...]
     //
-    LookupResult FoundOuter = LookupName(S, &II, LookupOrdinaryName);
+    LookupResult FoundOuter;
+    LookupName(FoundOuter, S, &II, LookupOrdinaryName);
     // FIXME: Handle ambiguities in this lookup better
-    NamedDecl *OuterTemplate = isAcceptableTemplateName(Context, FoundOuter);
+    NamedDecl *OuterTemplate
+      = isAcceptableTemplateName(Context, FoundOuter.getAsSingleDecl(Context));
 
     if (!OuterTemplate) {
       //   - if the name is not found, the name found in the class of the
@@ -284,7 +287,7 @@
   bool Invalid = false;
 
   if (ParamName) {
-    NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
+    NamedDecl *PrevDecl = LookupSingleName(S, ParamName, LookupTagName);
     if (PrevDecl && PrevDecl->isTemplateParameter())
       Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
                                                            PrevDecl);
@@ -402,7 +405,7 @@
 
   IdentifierInfo *ParamName = D.getIdentifier();
   if (ParamName) {
-    NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
+    NamedDecl *PrevDecl = LookupSingleName(S, ParamName, LookupTagName);
     if (PrevDecl && PrevDecl->isTemplateParameter())
       Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
                                                            PrevDecl);
@@ -577,11 +580,11 @@
       return true;
     }
 
-    Previous = LookupQualifiedName(SemanticContext, Name, LookupOrdinaryName,
+    LookupQualifiedName(Previous, SemanticContext, Name, LookupOrdinaryName,
                                    true);
   } else {
     SemanticContext = CurContext;
-    Previous = LookupName(S, Name, LookupOrdinaryName, true);
+    LookupName(Previous, S, Name, LookupOrdinaryName, true);
   }
 
   assert(!Previous.isAmbiguous() && "Ambiguity in class template redecl?");
@@ -3581,8 +3584,9 @@
     = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
                            : TSK_ExplicitInstantiationDeclaration;
   
-  LookupResult Previous = LookupParsedName(S, &D.getCXXScopeSpec(),
-                                           Name, LookupOrdinaryName);
+  LookupResult Previous;
+  LookupParsedName(Previous, S, &D.getCXXScopeSpec(),
+                   Name, LookupOrdinaryName);
 
   if (!R->isFunctionType()) {
     // C++ [temp.explicit]p1:
@@ -3594,14 +3598,15 @@
                                      D.getSourceRange());
     }
     
-    VarDecl *Prev = dyn_cast_or_null<VarDecl>(Previous.getAsDecl());
+    VarDecl *Prev = dyn_cast_or_null<VarDecl>(
+        Previous.getAsSingleDecl(Context));
     if (!Prev || !Prev->isStaticDataMember()) {
       // We expect to see a data data member here.
       Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_not_known)
         << Name;
       for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
            P != PEnd; ++P)
-        Diag(P->getLocation(), diag::note_explicit_instantiation_here);
+        Diag((*P)->getLocation(), diag::note_explicit_instantiation_here);
       return true;
     }
     
@@ -3824,8 +3829,8 @@
   assert(Ctx && "No declaration context?");
 
   DeclarationName Name(&II);
-  LookupResult Result = LookupQualifiedName(Ctx, Name, LookupOrdinaryName,
-                                            false);
+  LookupResult Result;
+  LookupQualifiedName(Result, Ctx, Name, LookupOrdinaryName, false);
   unsigned DiagID = 0;
   Decl *Referenced = 0;
   switch (Result.getKind()) {
@@ -3837,7 +3842,7 @@
     break;
 
   case LookupResult::Found:
-    if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getAsDecl())) {
+    if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
       // We found a type. Build a QualifiedNameType, since the
       // typename-specifier was just sugar. FIXME: Tell
       // QualifiedNameType that it has a "typename" prefix.
@@ -3845,7 +3850,7 @@
     }
 
     DiagID = diag::err_typename_nested_not_type;
-    Referenced = Result.getAsDecl();
+    Referenced = Result.getFoundDecl();
     break;
 
   case LookupResult::FoundOverloaded:

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Oct  9 16:13:30 2009
@@ -657,8 +657,9 @@
   NamedDecl *PrevDecl = 0;
 
   if (!FunctionTemplate || TemplateParams) {
-    PrevDecl = SemaRef.LookupQualifiedName(Owner, Name,
-                                           Sema::LookupOrdinaryName, true);
+    Sema::LookupResult R;
+    SemaRef.LookupQualifiedName(R, Owner, Name, Sema::LookupOrdinaryName, true);
+    PrevDecl = R.getAsSingleDecl(SemaRef.Context);
 
     // In C++, the previous declaration we find might be a tag type
     // (class or enum). In this case, the new declaration will hide the

Modified: cfe/trunk/test/SemaCXX/class-names.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class-names.cpp?rev=83674&r1=83673&r2=83674&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/class-names.cpp (original)
+++ cfe/trunk/test/SemaCXX/class-names.cpp Fri Oct  9 16:13:30 2009
@@ -5,7 +5,7 @@
 
 void D(int);
 
-class D {}; // expected-note {{previous use is here}}
+class D {};
 
 void foo()
 {
@@ -13,7 +13,7 @@
   class D d;
 }
 
-class D; 
+class D; // expected-note {{previous use is here}}
 
 enum D; // expected-error {{use of 'D' with tag type that does not match previous declaration}}
 





More information about the cfe-commits mailing list