1 //===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the LookupResult class, which is integral to
11 // Sema's name-lookup subsystem.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_SEMA_LOOKUP_H
16 #define LLVM_CLANG_SEMA_LOOKUP_H
17 
18 #include "clang/AST/DeclCXX.h"
19 #include "clang/Sema/Sema.h"
20 
21 namespace clang {
22 
23 /// @brief Represents the results of name lookup.
24 ///
25 /// An instance of the LookupResult class captures the results of a
26 /// single name lookup, which can return no result (nothing found),
27 /// a single declaration, a set of overloaded functions, or an
28 /// ambiguity. Use the getKind() method to determine which of these
29 /// results occurred for a given lookup.
30 class LookupResult {
31 public:
32   enum LookupResultKind {
33     /// @brief No entity found met the criteria.
34     NotFound = 0,
35 
36     /// @brief No entity found met the criteria within the current
37     /// instantiation,, but there were dependent base classes of the
38     /// current instantiation that could not be searched.
39     NotFoundInCurrentInstantiation,
40 
41     /// @brief Name lookup found a single declaration that met the
42     /// criteria.  getFoundDecl() will return this declaration.
43     Found,
44 
45     /// @brief Name lookup found a set of overloaded functions that
46     /// met the criteria.
47     FoundOverloaded,
48 
49     /// @brief Name lookup found an unresolvable value declaration
50     /// and cannot yet complete.  This only happens in C++ dependent
51     /// contexts with dependent using declarations.
52     FoundUnresolvedValue,
53 
54     /// @brief Name lookup results in an ambiguity; use
55     /// getAmbiguityKind to figure out what kind of ambiguity
56     /// we have.
57     Ambiguous
58   };
59 
60   enum AmbiguityKind {
61     /// Name lookup results in an ambiguity because multiple
62     /// entities that meet the lookup criteria were found in
63     /// subobjects of different types. For example:
64     /// @code
65     /// struct A { void f(int); }
66     /// struct B { void f(double); }
67     /// struct C : A, B { };
68     /// void test(C c) {
69     ///   c.f(0); // error: A::f and B::f come from subobjects of different
70     ///           // types. overload resolution is not performed.
71     /// }
72     /// @endcode
73     AmbiguousBaseSubobjectTypes,
74 
75     /// Name lookup results in an ambiguity because multiple
76     /// nonstatic entities that meet the lookup criteria were found
77     /// in different subobjects of the same type. For example:
78     /// @code
79     /// struct A { int x; };
80     /// struct B : A { };
81     /// struct C : A { };
82     /// struct D : B, C { };
83     /// int test(D d) {
84     ///   return d.x; // error: 'x' is found in two A subobjects (of B and C)
85     /// }
86     /// @endcode
87     AmbiguousBaseSubobjects,
88 
89     /// Name lookup results in an ambiguity because multiple definitions
90     /// of entity that meet the lookup criteria were found in different
91     /// declaration contexts.
92     /// @code
93     /// namespace A {
94     ///   int i;
95     ///   namespace B { int i; }
96     ///   int test() {
97     ///     using namespace B;
98     ///     return i; // error 'i' is found in namespace A and A::B
99     ///    }
100     /// }
101     /// @endcode
102     AmbiguousReference,
103 
104     /// Name lookup results in an ambiguity because an entity with a
105     /// tag name was hidden by an entity with an ordinary name from
106     /// a different context.
107     /// @code
108     /// namespace A { struct Foo {}; }
109     /// namespace B { void Foo(); }
110     /// namespace C {
111     ///   using namespace A;
112     ///   using namespace B;
113     /// }
114     /// void test() {
115     ///   C::Foo(); // error: tag 'A::Foo' is hidden by an object in a
116     ///             // different namespace
117     /// }
118     /// @endcode
119     AmbiguousTagHiding
120   };
121 
122   /// A little identifier for flagging temporary lookup results.
123   enum TemporaryToken {
124     Temporary
125   };
126 
127   typedef UnresolvedSetImpl::iterator iterator;
128 
129   LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo,
130                Sema::LookupNameKind LookupKind,
131                Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
ResultKind(NotFound)132     : ResultKind(NotFound),
133       Paths(nullptr),
134       NamingClass(nullptr),
135       SemaPtr(&SemaRef),
136       NameInfo(NameInfo),
137       LookupKind(LookupKind),
138       IDNS(0),
139       Redecl(Redecl != Sema::NotForRedeclaration),
140       HideTags(true),
141       Diagnose(Redecl == Sema::NotForRedeclaration),
142       AllowHidden(false),
143       Shadowed(false)
144   {
145     configure();
146   }
147 
148   // TODO: consider whether this constructor should be restricted to take
149   // as input a const IndentifierInfo* (instead of Name),
150   // forcing other cases towards the constructor taking a DNInfo.
151   LookupResult(Sema &SemaRef, DeclarationName Name,
152                SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
153                Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
ResultKind(NotFound)154     : ResultKind(NotFound),
155       Paths(nullptr),
156       NamingClass(nullptr),
157       SemaPtr(&SemaRef),
158       NameInfo(Name, NameLoc),
159       LookupKind(LookupKind),
160       IDNS(0),
161       Redecl(Redecl != Sema::NotForRedeclaration),
162       HideTags(true),
163       Diagnose(Redecl == Sema::NotForRedeclaration),
164       AllowHidden(false),
165       Shadowed(false)
166   {
167     configure();
168   }
169 
170   /// Creates a temporary lookup result, initializing its core data
171   /// using the information from another result.  Diagnostics are always
172   /// disabled.
LookupResult(TemporaryToken _,const LookupResult & Other)173   LookupResult(TemporaryToken _, const LookupResult &Other)
174     : ResultKind(NotFound),
175       Paths(nullptr),
176       NamingClass(nullptr),
177       SemaPtr(Other.SemaPtr),
178       NameInfo(Other.NameInfo),
179       LookupKind(Other.LookupKind),
180       IDNS(Other.IDNS),
181       Redecl(Other.Redecl),
182       HideTags(Other.HideTags),
183       Diagnose(false),
184       AllowHidden(Other.AllowHidden),
185       Shadowed(false)
186   {}
187 
~LookupResult()188   ~LookupResult() {
189     if (Diagnose) diagnose();
190     if (Paths) deletePaths(Paths);
191   }
192 
193   /// Gets the name info to look up.
getLookupNameInfo()194   const DeclarationNameInfo &getLookupNameInfo() const {
195     return NameInfo;
196   }
197 
198   /// \brief Sets the name info to look up.
setLookupNameInfo(const DeclarationNameInfo & NameInfo)199   void setLookupNameInfo(const DeclarationNameInfo &NameInfo) {
200     this->NameInfo = NameInfo;
201   }
202 
203   /// Gets the name to look up.
getLookupName()204   DeclarationName getLookupName() const {
205     return NameInfo.getName();
206   }
207 
208   /// \brief Sets the name to look up.
setLookupName(DeclarationName Name)209   void setLookupName(DeclarationName Name) {
210     NameInfo.setName(Name);
211   }
212 
213   /// Gets the kind of lookup to perform.
getLookupKind()214   Sema::LookupNameKind getLookupKind() const {
215     return LookupKind;
216   }
217 
218   /// True if this lookup is just looking for an existing declaration.
isForRedeclaration()219   bool isForRedeclaration() const {
220     return Redecl;
221   }
222 
223   /// \brief Specify whether hidden declarations are visible, e.g.,
224   /// for recovery reasons.
setAllowHidden(bool AH)225   void setAllowHidden(bool AH) {
226     AllowHidden = AH;
227   }
228 
229   /// \brief Determine whether this lookup is permitted to see hidden
230   /// declarations, such as those in modules that have not yet been imported.
isHiddenDeclarationVisible(NamedDecl * ND)231   bool isHiddenDeclarationVisible(NamedDecl *ND) const {
232     return AllowHidden ||
233            (isForRedeclaration() && ND->isExternallyVisible());
234   }
235 
236   /// Sets whether tag declarations should be hidden by non-tag
237   /// declarations during resolution.  The default is true.
setHideTags(bool Hide)238   void setHideTags(bool Hide) {
239     HideTags = Hide;
240   }
241 
isAmbiguous()242   bool isAmbiguous() const {
243     return getResultKind() == Ambiguous;
244   }
245 
246   /// Determines if this names a single result which is not an
247   /// unresolved value using decl.  If so, it is safe to call
248   /// getFoundDecl().
isSingleResult()249   bool isSingleResult() const {
250     return getResultKind() == Found;
251   }
252 
253   /// Determines if the results are overloaded.
isOverloadedResult()254   bool isOverloadedResult() const {
255     return getResultKind() == FoundOverloaded;
256   }
257 
isUnresolvableResult()258   bool isUnresolvableResult() const {
259     return getResultKind() == FoundUnresolvedValue;
260   }
261 
getResultKind()262   LookupResultKind getResultKind() const {
263     assert(sanity());
264     return ResultKind;
265   }
266 
getAmbiguityKind()267   AmbiguityKind getAmbiguityKind() const {
268     assert(isAmbiguous());
269     return Ambiguity;
270   }
271 
asUnresolvedSet()272   const UnresolvedSetImpl &asUnresolvedSet() const {
273     return Decls;
274   }
275 
begin()276   iterator begin() const { return iterator(Decls.begin()); }
end()277   iterator end() const { return iterator(Decls.end()); }
278 
279   /// \brief Return true if no decls were found
empty()280   bool empty() const { return Decls.empty(); }
281 
282   /// \brief Return the base paths structure that's associated with
283   /// these results, or null if none is.
getBasePaths()284   CXXBasePaths *getBasePaths() const {
285     return Paths;
286   }
287 
288   /// \brief Determine whether the given declaration is visible to the
289   /// program.
isVisible(Sema & SemaRef,NamedDecl * D)290   static bool isVisible(Sema &SemaRef, NamedDecl *D) {
291     // If this declaration is not hidden, it's visible.
292     if (!D->isHidden())
293       return true;
294 
295     // During template instantiation, we can refer to hidden declarations, if
296     // they were visible in any module along the path of instantiation.
297     return isVisibleSlow(SemaRef, D);
298   }
299 
300   /// \brief Retrieve the accepted (re)declaration of the given declaration,
301   /// if there is one.
getAcceptableDecl(NamedDecl * D)302   NamedDecl *getAcceptableDecl(NamedDecl *D) const {
303     if (!D->isInIdentifierNamespace(IDNS))
304       return nullptr;
305 
306     if (isVisible(getSema(), D) || isHiddenDeclarationVisible(D))
307       return D;
308 
309     return getAcceptableDeclSlow(D);
310   }
311 
312 private:
313   static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D);
314   NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const;
315 
316 public:
317   /// \brief Returns the identifier namespace mask for this lookup.
getIdentifierNamespace()318   unsigned getIdentifierNamespace() const {
319     return IDNS;
320   }
321 
322   /// \brief Returns whether these results arose from performing a
323   /// lookup into a class.
isClassLookup()324   bool isClassLookup() const {
325     return NamingClass != nullptr;
326   }
327 
328   /// \brief Returns the 'naming class' for this lookup, i.e. the
329   /// class which was looked into to find these results.
330   ///
331   /// C++0x [class.access.base]p5:
332   ///   The access to a member is affected by the class in which the
333   ///   member is named. This naming class is the class in which the
334   ///   member name was looked up and found. [Note: this class can be
335   ///   explicit, e.g., when a qualified-id is used, or implicit,
336   ///   e.g., when a class member access operator (5.2.5) is used
337   ///   (including cases where an implicit "this->" is added). If both
338   ///   a class member access operator and a qualified-id are used to
339   ///   name the member (as in p->T::m), the class naming the member
340   ///   is the class named by the nested-name-specifier of the
341   ///   qualified-id (that is, T). -- end note ]
342   ///
343   /// This is set by the lookup routines when they find results in a class.
getNamingClass()344   CXXRecordDecl *getNamingClass() const {
345     return NamingClass;
346   }
347 
348   /// \brief Sets the 'naming class' for this lookup.
setNamingClass(CXXRecordDecl * Record)349   void setNamingClass(CXXRecordDecl *Record) {
350     NamingClass = Record;
351   }
352 
353   /// \brief Returns the base object type associated with this lookup;
354   /// important for [class.protected].  Most lookups do not have an
355   /// associated base object.
getBaseObjectType()356   QualType getBaseObjectType() const {
357     return BaseObjectType;
358   }
359 
360   /// \brief Sets the base object type for this lookup.
setBaseObjectType(QualType T)361   void setBaseObjectType(QualType T) {
362     BaseObjectType = T;
363   }
364 
365   /// \brief Add a declaration to these results with its natural access.
366   /// Does not test the acceptance criteria.
addDecl(NamedDecl * D)367   void addDecl(NamedDecl *D) {
368     addDecl(D, D->getAccess());
369   }
370 
371   /// \brief Add a declaration to these results with the given access.
372   /// Does not test the acceptance criteria.
addDecl(NamedDecl * D,AccessSpecifier AS)373   void addDecl(NamedDecl *D, AccessSpecifier AS) {
374     Decls.addDecl(D, AS);
375     ResultKind = Found;
376   }
377 
378   /// \brief Add all the declarations from another set of lookup
379   /// results.
addAllDecls(const LookupResult & Other)380   void addAllDecls(const LookupResult &Other) {
381     Decls.append(Other.Decls.begin(), Other.Decls.end());
382     ResultKind = Found;
383   }
384 
385   /// \brief Determine whether no result was found because we could not
386   /// search into dependent base classes of the current instantiation.
wasNotFoundInCurrentInstantiation()387   bool wasNotFoundInCurrentInstantiation() const {
388     return ResultKind == NotFoundInCurrentInstantiation;
389   }
390 
391   /// \brief Note that while no result was found in the current instantiation,
392   /// there were dependent base classes that could not be searched.
setNotFoundInCurrentInstantiation()393   void setNotFoundInCurrentInstantiation() {
394     assert(ResultKind == NotFound && Decls.empty());
395     ResultKind = NotFoundInCurrentInstantiation;
396   }
397 
398   /// \brief Determine whether the lookup result was shadowed by some other
399   /// declaration that lookup ignored.
isShadowed()400   bool isShadowed() const { return Shadowed; }
401 
402   /// \brief Note that we found and ignored a declaration while performing
403   /// lookup.
setShadowed()404   void setShadowed() { Shadowed = true; }
405 
406   /// \brief Resolves the result kind of the lookup, possibly hiding
407   /// decls.
408   ///
409   /// This should be called in any environment where lookup might
410   /// generate multiple lookup results.
411   void resolveKind();
412 
413   /// \brief Re-resolves the result kind of the lookup after a set of
414   /// removals has been performed.
resolveKindAfterFilter()415   void resolveKindAfterFilter() {
416     if (Decls.empty()) {
417       if (ResultKind != NotFoundInCurrentInstantiation)
418         ResultKind = NotFound;
419 
420       if (Paths) {
421         deletePaths(Paths);
422         Paths = nullptr;
423       }
424     } else {
425       AmbiguityKind SavedAK;
426       bool WasAmbiguous = false;
427       if (ResultKind == Ambiguous) {
428         SavedAK = Ambiguity;
429         WasAmbiguous = true;
430       }
431       ResultKind = Found;
432       resolveKind();
433 
434       // If we didn't make the lookup unambiguous, restore the old
435       // ambiguity kind.
436       if (ResultKind == Ambiguous) {
437         (void)WasAmbiguous;
438         assert(WasAmbiguous);
439         Ambiguity = SavedAK;
440       } else if (Paths) {
441         deletePaths(Paths);
442         Paths = nullptr;
443       }
444     }
445   }
446 
447   template <class DeclClass>
getAsSingle()448   DeclClass *getAsSingle() const {
449     if (getResultKind() != Found) return nullptr;
450     return dyn_cast<DeclClass>(getFoundDecl());
451   }
452 
453   /// \brief Fetch the unique decl found by this lookup.  Asserts
454   /// that one was found.
455   ///
456   /// This is intended for users who have examined the result kind
457   /// and are certain that there is only one result.
getFoundDecl()458   NamedDecl *getFoundDecl() const {
459     assert(getResultKind() == Found
460            && "getFoundDecl called on non-unique result");
461     return (*begin())->getUnderlyingDecl();
462   }
463 
464   /// Fetches a representative decl.  Useful for lazy diagnostics.
getRepresentativeDecl()465   NamedDecl *getRepresentativeDecl() const {
466     assert(!Decls.empty() && "cannot get representative of empty set");
467     return *begin();
468   }
469 
470   /// \brief Asks if the result is a single tag decl.
isSingleTagDecl()471   bool isSingleTagDecl() const {
472     return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
473   }
474 
475   /// \brief Make these results show that the name was found in
476   /// base classes of different types.
477   ///
478   /// The given paths object is copied and invalidated.
479   void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
480 
481   /// \brief Make these results show that the name was found in
482   /// distinct base classes of the same type.
483   ///
484   /// The given paths object is copied and invalidated.
485   void setAmbiguousBaseSubobjects(CXXBasePaths &P);
486 
487   /// \brief Make these results show that the name was found in
488   /// different contexts and a tag decl was hidden by an ordinary
489   /// decl in a different context.
setAmbiguousQualifiedTagHiding()490   void setAmbiguousQualifiedTagHiding() {
491     setAmbiguous(AmbiguousTagHiding);
492   }
493 
494   /// \brief Clears out any current state.
clear()495   void clear() {
496     ResultKind = NotFound;
497     Decls.clear();
498     if (Paths) deletePaths(Paths);
499     Paths = nullptr;
500     NamingClass = nullptr;
501     Shadowed = false;
502   }
503 
504   /// \brief Clears out any current state and re-initializes for a
505   /// different kind of lookup.
clear(Sema::LookupNameKind Kind)506   void clear(Sema::LookupNameKind Kind) {
507     clear();
508     LookupKind = Kind;
509     configure();
510   }
511 
512   /// \brief Change this lookup's redeclaration kind.
setRedeclarationKind(Sema::RedeclarationKind RK)513   void setRedeclarationKind(Sema::RedeclarationKind RK) {
514     Redecl = RK;
515     configure();
516   }
517 
518   void print(raw_ostream &);
519 
520   /// Suppress the diagnostics that would normally fire because of this
521   /// lookup.  This happens during (e.g.) redeclaration lookups.
suppressDiagnostics()522   void suppressDiagnostics() {
523     Diagnose = false;
524   }
525 
526   /// Determines whether this lookup is suppressing diagnostics.
isSuppressingDiagnostics()527   bool isSuppressingDiagnostics() const {
528     return !Diagnose;
529   }
530 
531   /// Sets a 'context' source range.
setContextRange(SourceRange SR)532   void setContextRange(SourceRange SR) {
533     NameContextRange = SR;
534   }
535 
536   /// Gets the source range of the context of this name; for C++
537   /// qualified lookups, this is the source range of the scope
538   /// specifier.
getContextRange()539   SourceRange getContextRange() const {
540     return NameContextRange;
541   }
542 
543   /// Gets the location of the identifier.  This isn't always defined:
544   /// sometimes we're doing lookups on synthesized names.
getNameLoc()545   SourceLocation getNameLoc() const {
546     return NameInfo.getLoc();
547   }
548 
549   /// \brief Get the Sema object that this lookup result is searching
550   /// with.
getSema()551   Sema &getSema() const { return *SemaPtr; }
552 
553   /// A class for iterating through a result set and possibly
554   /// filtering out results.  The results returned are possibly
555   /// sugared.
556   class Filter {
557     LookupResult &Results;
558     LookupResult::iterator I;
559     bool Changed;
560     bool CalledDone;
561 
562     friend class LookupResult;
Filter(LookupResult & Results)563     Filter(LookupResult &Results)
564       : Results(Results), I(Results.begin()), Changed(false), CalledDone(false)
565     {}
566 
567   public:
Filter(Filter && F)568     Filter(Filter &&F)
569         : Results(F.Results), I(F.I), Changed(F.Changed),
570           CalledDone(F.CalledDone) {
571       F.CalledDone = true;
572     }
~Filter()573     ~Filter() {
574       assert(CalledDone &&
575              "LookupResult::Filter destroyed without done() call");
576     }
577 
hasNext()578     bool hasNext() const {
579       return I != Results.end();
580     }
581 
next()582     NamedDecl *next() {
583       assert(I != Results.end() && "next() called on empty filter");
584       return *I++;
585     }
586 
587     /// Restart the iteration.
restart()588     void restart() {
589       I = Results.begin();
590     }
591 
592     /// Erase the last element returned from this iterator.
erase()593     void erase() {
594       Results.Decls.erase(--I);
595       Changed = true;
596     }
597 
598     /// Replaces the current entry with the given one, preserving the
599     /// access bits.
replace(NamedDecl * D)600     void replace(NamedDecl *D) {
601       Results.Decls.replace(I-1, D);
602       Changed = true;
603     }
604 
605     /// Replaces the current entry with the given one.
replace(NamedDecl * D,AccessSpecifier AS)606     void replace(NamedDecl *D, AccessSpecifier AS) {
607       Results.Decls.replace(I-1, D, AS);
608       Changed = true;
609     }
610 
done()611     void done() {
612       assert(!CalledDone && "done() called twice");
613       CalledDone = true;
614 
615       if (Changed)
616         Results.resolveKindAfterFilter();
617     }
618   };
619 
620   /// Create a filter for this result set.
makeFilter()621   Filter makeFilter() {
622     return Filter(*this);
623   }
624 
setFindLocalExtern(bool FindLocalExtern)625   void setFindLocalExtern(bool FindLocalExtern) {
626     if (FindLocalExtern)
627       IDNS |= Decl::IDNS_LocalExtern;
628     else
629       IDNS &= ~Decl::IDNS_LocalExtern;
630   }
631 
632 private:
diagnose()633   void diagnose() {
634     if (isAmbiguous())
635       getSema().DiagnoseAmbiguousLookup(*this);
636     else if (isClassLookup() && getSema().getLangOpts().AccessControl)
637       getSema().CheckLookupAccess(*this);
638   }
639 
setAmbiguous(AmbiguityKind AK)640   void setAmbiguous(AmbiguityKind AK) {
641     ResultKind = Ambiguous;
642     Ambiguity = AK;
643   }
644 
645   void addDeclsFromBasePaths(const CXXBasePaths &P);
646   void configure();
647 
648   // Sanity checks.
649   bool sanity() const;
650 
sanityCheckUnresolved()651   bool sanityCheckUnresolved() const {
652     for (iterator I = begin(), E = end(); I != E; ++I)
653       if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl()))
654         return true;
655     return false;
656   }
657 
658   static void deletePaths(CXXBasePaths *);
659 
660   // Results.
661   LookupResultKind ResultKind;
662   AmbiguityKind Ambiguity; // ill-defined unless ambiguous
663   UnresolvedSet<8> Decls;
664   CXXBasePaths *Paths;
665   CXXRecordDecl *NamingClass;
666   QualType BaseObjectType;
667 
668   // Parameters.
669   Sema *SemaPtr;
670   DeclarationNameInfo NameInfo;
671   SourceRange NameContextRange;
672   Sema::LookupNameKind LookupKind;
673   unsigned IDNS; // set by configure()
674 
675   bool Redecl;
676 
677   /// \brief True if tag declarations should be hidden if non-tags
678   ///   are present
679   bool HideTags;
680 
681   bool Diagnose;
682 
683   /// \brief True if we should allow hidden declarations to be 'visible'.
684   bool AllowHidden;
685 
686   /// \brief True if the found declarations were shadowed by some other
687   /// declaration that we skipped. This only happens when \c LookupKind
688   /// is \c LookupRedeclarationWithLinkage.
689   bool Shadowed;
690 };
691 
692 /// \brief Consumes visible declarations found when searching for
693 /// all visible names within a given scope or context.
694 ///
695 /// This abstract class is meant to be subclassed by clients of \c
696 /// Sema::LookupVisibleDecls(), each of which should override the \c
697 /// FoundDecl() function to process declarations as they are found.
698 class VisibleDeclConsumer {
699 public:
700   /// \brief Destroys the visible declaration consumer.
701   virtual ~VisibleDeclConsumer();
702 
703   /// \brief Determine whether hidden declarations (from unimported
704   /// modules) should be given to this consumer. By default, they
705   /// are not included.
706   virtual bool includeHiddenDecls() const;
707 
708   /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a
709   /// declaration visible from the current scope or context.
710   ///
711   /// \param ND the declaration found.
712   ///
713   /// \param Hiding a declaration that hides the declaration \p ND,
714   /// or NULL if no such declaration exists.
715   ///
716   /// \param Ctx the original context from which the lookup started.
717   ///
718   /// \param InBaseClass whether this declaration was found in base
719   /// class of the context we searched.
720   virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
721                          bool InBaseClass) = 0;
722 };
723 
724 /// \brief A class for storing results from argument-dependent lookup.
725 class ADLResult {
726 private:
727   /// A map from canonical decls to the 'most recent' decl.
728   llvm::DenseMap<NamedDecl*, NamedDecl*> Decls;
729 
730 public:
731   /// Adds a new ADL candidate to this map.
732   void insert(NamedDecl *D);
733 
734   /// Removes any data associated with a given decl.
erase(NamedDecl * D)735   void erase(NamedDecl *D) {
736     Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
737   }
738 
739   class iterator
740       : public llvm::iterator_adaptor_base<
741             iterator, llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator,
742             std::forward_iterator_tag, NamedDecl *> {
743     friend class ADLResult;
744 
iterator(llvm::DenseMap<NamedDecl *,NamedDecl * >::iterator Iter)745     iterator(llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator Iter)
746         : iterator_adaptor_base(std::move(Iter)) {}
747 
748   public:
iterator()749     iterator() {}
750 
751     value_type operator*() const { return I->second; }
752   };
753 
begin()754   iterator begin() { return iterator(Decls.begin()); }
end()755   iterator end() { return iterator(Decls.end()); }
756 };
757 
758 }
759 
760 #endif
761