diff options
Diffstat (limited to 'lib/Sema/Sema.h')
-rw-r--r-- | lib/Sema/Sema.h | 76 |
1 files changed, 71 insertions, 5 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 6c9466f863..9d35f3dd3f 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1074,6 +1074,13 @@ public: /// functions into an OverloadedFunctionDecl. FoundOverloaded, + /// @brief Name lookup results in an ambiguity; use + /// getAmbiguityKind to figure out what kind of ambiguity + /// we have. + Ambiguous + }; + + enum AmbiguityKind { /// Name lookup results in an ambiguity because multiple /// entities that meet the lookup criteria were found in /// subobjects of different types. For example: @@ -1117,7 +1124,22 @@ public: /// @endcode AmbiguousReference, - FirstAmbiguous = AmbiguousBaseSubobjectTypes + /// Name lookup results in an ambiguity because an entity with a + /// tag name was hidden by an entity with an ordinary name from + /// a different context. + /// @code + /// namespace A { struct Foo {}; } + /// namespace B { void Foo(); } + /// namespace C { + /// using namespace A; + /// using namespace B; + /// } + /// void test() { + /// C::Foo(); // error: tag 'A::Foo' is hidden by an object in a + /// // different namespace + /// } + /// @endcode + AmbiguousTagHiding }; typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy; @@ -1132,7 +1154,7 @@ public: } bool isAmbiguous() const { - return getKind() >= FirstAmbiguous; + return getKind() == Ambiguous; } LookupKind getKind() const { @@ -1140,6 +1162,11 @@ public: return Kind; } + AmbiguityKind getAmbiguityKind() const { + assert(isAmbiguous()); + return Ambiguity; + } + iterator begin() const { return Decls.begin(); } iterator end() const { return Decls.end(); } @@ -1158,6 +1185,25 @@ public: Kind = Found; } + /// \brief Add all the declarations from another set of lookup + /// results. + void addAllDecls(const LookupResult &Other) { + Decls.append(Other.begin(), Other.end()); + Kind = Found; + } + + /// \brief Hides a set of declarations. + template <class NamedDeclSet> void hideDecls(const NamedDeclSet &Set) { + unsigned I = 0, N = Decls.size(); + while (I < N) { + if (Set.count(Decls[I])) + Decls[I] = Decls[--N]; + else + I++; + } + Decls.set_size(N); + } + /// \brief Resolves the kind of the lookup, possibly hiding decls. /// /// This should be called in any environment where lookup might @@ -1181,6 +1227,11 @@ public: return *Decls.begin(); } + /// \brief Asks if the result is a single tag decl. + bool isSingleTagDecl() const { + return getKind() == Found && isa<TagDecl>(getFoundDecl()); + } + /// \brief Make these results show that the name was found in /// base classes of different types. /// @@ -1193,6 +1244,13 @@ public: /// The given paths object is copied and invalidated. void setAmbiguousBaseSubobjects(CXXBasePaths &P); + /// \brief Make these results show that the name was found in + /// different contexts and a tag decl was hidden by an ordinary + /// decl in a different context. + void setAmbiguousQualifiedTagHiding() { + setAmbiguous(AmbiguousTagHiding); + } + /// \brief Clears out any current state. void clear() { Kind = NotFound; @@ -1204,6 +1262,11 @@ public: void print(llvm::raw_ostream &); private: + void setAmbiguous(AmbiguityKind AK) { + Kind = Ambiguous; + Ambiguity = AK; + } + void addDeclsFromBasePaths(const CXXBasePaths &P); // Sanity checks. @@ -1211,14 +1274,17 @@ public: 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)); + (Kind == Ambiguous && Ambiguity == AmbiguousBaseSubobjects) + || Decls.size() > 1); + assert((Paths != NULL) == (Kind == Ambiguous && + (Ambiguity == AmbiguousBaseSubobjectTypes || + Ambiguity == AmbiguousBaseSubobjects))); } static void deletePaths(CXXBasePaths *); LookupKind Kind; + AmbiguityKind Ambiguity; // ill-defined unless ambiguous DeclsTy Decls; CXXBasePaths *Paths; }; |