Semantic analysis, ASTs, and unqualified name lookup support for C++
using directives, from Piotr Rak!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63646 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index b0a0a5e..0969cd0 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -539,10 +539,6 @@
   void CheckCXXDefaultArguments(FunctionDecl *FD);
   void CheckExtraCXXDefaultArguments(Declarator &D);
 
-  // FIXME: NamespaceNameOnly parameter is added temporarily
-  // we will need a better way to specify lookup criteria for things
-  // like template specializations, explicit template instantiations, etc.
-
   Scope *getNonFieldDeclScope(Scope *S);
 
   /// \name Name lookup
@@ -614,6 +610,9 @@
       /// First is a single declaration (a Decl*), 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,
@@ -626,7 +625,13 @@
       /// 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.
-      AmbiguousLookup
+      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
@@ -635,14 +640,14 @@
     /// IdentifierResolver::iterator (if StoredKind ==
     /// OverloadedDeclFromIdResolver), a DeclContext::lookup_iterator
     /// (if StoredKind == OverloadedDeclFromDeclContext), or a
-    /// BasePaths pointer (if StoredKind == AmbiguousLookup).
+    /// BasePaths 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 == AmbiguousLookup).
+    /// Boolean value (if StoredKind == AmbiguousLookupStoresBasePaths).
     mutable uintptr_t Last;
 
     /// Context - The context in which we will build any
@@ -690,17 +695,25 @@
       ///   return d.x; // error: 'x' is found in two A subobjects (of B and C)
       /// }
       /// @endcode
-      AmbiguousBaseSubobjects
+      AmbiguousBaseSubobjects,
+
+      /// Name lookup results in an ambiguity because multiple definitions
+      /// of entity that meet the lookup criteria were found in different
+      /// declaration contexts.
+      /// @code
+      /// namespace A {
+      ///   int i;
+      ///   namespace B { int i; }
+      ///   int test() {
+      ///     using namespace B;
+      ///     return i; // error 'i' is found in namespace A and A::B
+      ///    }
+      /// }
+      /// @endcode
+      AmbiguousReference
     };
 
-    static LookupResult CreateLookupResult(ASTContext &Context, Decl *D) {
-      LookupResult Result;
-      Result.StoredKind = SingleDecl;
-      Result.First = reinterpret_cast<uintptr_t>(D);
-      Result.Last = 0;
-      Result.Context = &Context;
-      return Result;
-    }
+    static LookupResult CreateLookupResult(ASTContext &Context, Decl *D);
 
     static LookupResult CreateLookupResult(ASTContext &Context, 
                                            IdentifierResolver::iterator F, 
@@ -713,20 +726,37 @@
     static LookupResult CreateLookupResult(ASTContext &Context, BasePaths *Paths, 
                                            bool DifferentSubobjectTypes) {
       LookupResult Result;
-      Result.StoredKind = AmbiguousLookup;
+      Result.StoredKind = AmbiguousLookupStoresBasePaths;
       Result.First = reinterpret_cast<uintptr_t>(Paths);
       Result.Last = DifferentSubobjectTypes? 1 : 0;
       Result.Context = &Context;
       return Result;
     }
 
+    template <typename Iterator>
+    static LookupResult CreateLookupResult(ASTContext &Context,
+                                           Iterator B, std::size_t Len) {
+      Decl ** Array = new Decl*[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;
+    }
+
     LookupKind getKind() const;
 
     /// @brief Determine whether name look found something.
     operator bool() const { return getKind() != NotFound; }
 
     /// @brief Determines whether the lookup resulted in an ambiguity.
-    bool isAmbiguous() const { return StoredKind == AmbiguousLookup; }
+    bool isAmbiguous() const {
+      return StoredKind == AmbiguousLookupStoresBasePaths ||
+             StoredKind == AmbiguousLookupStoresDecls;
+    }
 
     /// @brief Allows conversion of a lookup result into a
     /// declaration, with the same behavior as getAsDecl.
@@ -786,6 +816,14 @@
     iterator end();
   };
 
+private:
+  typedef llvm::SmallVector<LookupResult, 3> LookupResultsVecTy;
+
+  std::pair<bool, LookupResult> CppLookupName(Scope *S, DeclarationName Name,
+                                              LookupNameKind NameKind,
+                                              bool RedeclarationOnly);
+
+public:
   /// Determines whether D is a suitable lookup result according to the
   /// lookup criteria.
   bool isAcceptableLookupResult(Decl *D, LookupNameKind NameKind,
@@ -1171,6 +1209,8 @@
                                       IdentifierInfo *NamespcName,
                                       AttributeList *AttrList);
 
+  void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
+
   /// AddCXXDirectInitializerToDecl - This action is called immediately after 
   /// ActOnDeclarator, when a C++ direct initializer is present.
   /// e.g: "int x(1);"