1212795Sdim//===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===//
2212795Sdim//
3212795Sdim//                     The LLVM Compiler Infrastructure
4212795Sdim//
5212795Sdim// This file is distributed under the University of Illinois Open Source
6212795Sdim// License. See LICENSE.TXT for details.
7212795Sdim//
8212795Sdim//===----------------------------------------------------------------------===//
9212795Sdim//
10212795Sdim// This file defines the LookupResult class, which is integral to
11212795Sdim// Sema's name-lookup subsystem.
12212795Sdim//
13212795Sdim//===----------------------------------------------------------------------===//
14212795Sdim
15212795Sdim#ifndef LLVM_CLANG_SEMA_LOOKUP_H
16212795Sdim#define LLVM_CLANG_SEMA_LOOKUP_H
17212795Sdim
18249423Sdim#include "clang/AST/DeclCXX.h"
19212795Sdim#include "clang/Sema/Sema.h"
20212795Sdim
21212795Sdimnamespace clang {
22212795Sdim
23212795Sdim/// @brief Represents the results of name lookup.
24212795Sdim///
25212795Sdim/// An instance of the LookupResult class captures the results of a
26212795Sdim/// single name lookup, which can return no result (nothing found),
27212795Sdim/// a single declaration, a set of overloaded functions, or an
28212795Sdim/// ambiguity. Use the getKind() method to determine which of these
29212795Sdim/// results occurred for a given lookup.
30212795Sdimclass LookupResult {
31212795Sdimpublic:
32212795Sdim  enum LookupResultKind {
33212795Sdim    /// @brief No entity found met the criteria.
34212795Sdim    NotFound = 0,
35212795Sdim
36212795Sdim    /// @brief No entity found met the criteria within the current
37212795Sdim    /// instantiation,, but there were dependent base classes of the
38212795Sdim    /// current instantiation that could not be searched.
39212795Sdim    NotFoundInCurrentInstantiation,
40212795Sdim
41212795Sdim    /// @brief Name lookup found a single declaration that met the
42212795Sdim    /// criteria.  getFoundDecl() will return this declaration.
43212795Sdim    Found,
44212795Sdim
45212795Sdim    /// @brief Name lookup found a set of overloaded functions that
46212795Sdim    /// met the criteria.
47212795Sdim    FoundOverloaded,
48212795Sdim
49212795Sdim    /// @brief Name lookup found an unresolvable value declaration
50212795Sdim    /// and cannot yet complete.  This only happens in C++ dependent
51212795Sdim    /// contexts with dependent using declarations.
52212795Sdim    FoundUnresolvedValue,
53212795Sdim
54212795Sdim    /// @brief Name lookup results in an ambiguity; use
55212795Sdim    /// getAmbiguityKind to figure out what kind of ambiguity
56212795Sdim    /// we have.
57212795Sdim    Ambiguous
58212795Sdim  };
59212795Sdim
60212795Sdim  enum AmbiguityKind {
61212795Sdim    /// Name lookup results in an ambiguity because multiple
62212795Sdim    /// entities that meet the lookup criteria were found in
63212795Sdim    /// subobjects of different types. For example:
64212795Sdim    /// @code
65212795Sdim    /// struct A { void f(int); }
66212795Sdim    /// struct B { void f(double); }
67212795Sdim    /// struct C : A, B { };
68212795Sdim    /// void test(C c) {
69212795Sdim    ///   c.f(0); // error: A::f and B::f come from subobjects of different
70212795Sdim    ///           // types. overload resolution is not performed.
71212795Sdim    /// }
72212795Sdim    /// @endcode
73212795Sdim    AmbiguousBaseSubobjectTypes,
74212795Sdim
75212795Sdim    /// Name lookup results in an ambiguity because multiple
76212795Sdim    /// nonstatic entities that meet the lookup criteria were found
77212795Sdim    /// in different subobjects of the same type. For example:
78212795Sdim    /// @code
79212795Sdim    /// struct A { int x; };
80212795Sdim    /// struct B : A { };
81212795Sdim    /// struct C : A { };
82212795Sdim    /// struct D : B, C { };
83212795Sdim    /// int test(D d) {
84212795Sdim    ///   return d.x; // error: 'x' is found in two A subobjects (of B and C)
85212795Sdim    /// }
86212795Sdim    /// @endcode
87212795Sdim    AmbiguousBaseSubobjects,
88212795Sdim
89212795Sdim    /// Name lookup results in an ambiguity because multiple definitions
90212795Sdim    /// of entity that meet the lookup criteria were found in different
91212795Sdim    /// declaration contexts.
92212795Sdim    /// @code
93212795Sdim    /// namespace A {
94212795Sdim    ///   int i;
95212795Sdim    ///   namespace B { int i; }
96212795Sdim    ///   int test() {
97212795Sdim    ///     using namespace B;
98212795Sdim    ///     return i; // error 'i' is found in namespace A and A::B
99212795Sdim    ///    }
100212795Sdim    /// }
101212795Sdim    /// @endcode
102212795Sdim    AmbiguousReference,
103212795Sdim
104212795Sdim    /// Name lookup results in an ambiguity because an entity with a
105212795Sdim    /// tag name was hidden by an entity with an ordinary name from
106212795Sdim    /// a different context.
107212795Sdim    /// @code
108212795Sdim    /// namespace A { struct Foo {}; }
109212795Sdim    /// namespace B { void Foo(); }
110212795Sdim    /// namespace C {
111212795Sdim    ///   using namespace A;
112212795Sdim    ///   using namespace B;
113212795Sdim    /// }
114212795Sdim    /// void test() {
115212795Sdim    ///   C::Foo(); // error: tag 'A::Foo' is hidden by an object in a
116212795Sdim    ///             // different namespace
117212795Sdim    /// }
118212795Sdim    /// @endcode
119212795Sdim    AmbiguousTagHiding
120212795Sdim  };
121212795Sdim
122212795Sdim  /// A little identifier for flagging temporary lookup results.
123212795Sdim  enum TemporaryToken {
124212795Sdim    Temporary
125212795Sdim  };
126212795Sdim
127212795Sdim  typedef UnresolvedSetImpl::iterator iterator;
128212795Sdim
129212795Sdim  LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo,
130212795Sdim               Sema::LookupNameKind LookupKind,
131212795Sdim               Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
132212795Sdim    : ResultKind(NotFound),
133212795Sdim      Paths(0),
134212795Sdim      NamingClass(0),
135212795Sdim      SemaRef(SemaRef),
136212795Sdim      NameInfo(NameInfo),
137212795Sdim      LookupKind(LookupKind),
138212795Sdim      IDNS(0),
139212795Sdim      Redecl(Redecl != Sema::NotForRedeclaration),
140212795Sdim      HideTags(true),
141249423Sdim      Diagnose(Redecl == Sema::NotForRedeclaration),
142263508Sdim      AllowHidden(Redecl == Sema::ForRedeclaration),
143263508Sdim      Shadowed(false)
144212795Sdim  {
145212795Sdim    configure();
146212795Sdim  }
147212795Sdim
148212795Sdim  // TODO: consider whether this constructor should be restricted to take
149212795Sdim  // as input a const IndentifierInfo* (instead of Name),
150212795Sdim  // forcing other cases towards the constructor taking a DNInfo.
151212795Sdim  LookupResult(Sema &SemaRef, DeclarationName Name,
152212795Sdim               SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
153212795Sdim               Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
154212795Sdim    : ResultKind(NotFound),
155212795Sdim      Paths(0),
156212795Sdim      NamingClass(0),
157212795Sdim      SemaRef(SemaRef),
158212795Sdim      NameInfo(Name, NameLoc),
159212795Sdim      LookupKind(LookupKind),
160212795Sdim      IDNS(0),
161212795Sdim      Redecl(Redecl != Sema::NotForRedeclaration),
162212795Sdim      HideTags(true),
163249423Sdim      Diagnose(Redecl == Sema::NotForRedeclaration),
164263508Sdim      AllowHidden(Redecl == Sema::ForRedeclaration),
165263508Sdim      Shadowed(false)
166212795Sdim  {
167212795Sdim    configure();
168212795Sdim  }
169212795Sdim
170212795Sdim  /// Creates a temporary lookup result, initializing its core data
171212795Sdim  /// using the information from another result.  Diagnostics are always
172212795Sdim  /// disabled.
173212795Sdim  LookupResult(TemporaryToken _, const LookupResult &Other)
174212795Sdim    : ResultKind(NotFound),
175212795Sdim      Paths(0),
176212795Sdim      NamingClass(0),
177212795Sdim      SemaRef(Other.SemaRef),
178212795Sdim      NameInfo(Other.NameInfo),
179212795Sdim      LookupKind(Other.LookupKind),
180212795Sdim      IDNS(Other.IDNS),
181212795Sdim      Redecl(Other.Redecl),
182212795Sdim      HideTags(Other.HideTags),
183249423Sdim      Diagnose(false),
184263508Sdim      AllowHidden(Other.AllowHidden),
185263508Sdim      Shadowed(false)
186212795Sdim  {}
187212795Sdim
188212795Sdim  ~LookupResult() {
189212795Sdim    if (Diagnose) diagnose();
190212795Sdim    if (Paths) deletePaths(Paths);
191212795Sdim  }
192212795Sdim
193212795Sdim  /// Gets the name info to look up.
194212795Sdim  const DeclarationNameInfo &getLookupNameInfo() const {
195212795Sdim    return NameInfo;
196212795Sdim  }
197212795Sdim
198212795Sdim  /// \brief Sets the name info to look up.
199212795Sdim  void setLookupNameInfo(const DeclarationNameInfo &NameInfo) {
200212795Sdim    this->NameInfo = NameInfo;
201212795Sdim  }
202212795Sdim
203212795Sdim  /// Gets the name to look up.
204212795Sdim  DeclarationName getLookupName() const {
205212795Sdim    return NameInfo.getName();
206212795Sdim  }
207212795Sdim
208212795Sdim  /// \brief Sets the name to look up.
209212795Sdim  void setLookupName(DeclarationName Name) {
210212795Sdim    NameInfo.setName(Name);
211212795Sdim  }
212212795Sdim
213212795Sdim  /// Gets the kind of lookup to perform.
214212795Sdim  Sema::LookupNameKind getLookupKind() const {
215212795Sdim    return LookupKind;
216212795Sdim  }
217212795Sdim
218212795Sdim  /// True if this lookup is just looking for an existing declaration.
219212795Sdim  bool isForRedeclaration() const {
220212795Sdim    return Redecl;
221212795Sdim  }
222212795Sdim
223249423Sdim  /// \brief Specify whether hidden declarations are visible, e.g.,
224249423Sdim  /// for recovery reasons.
225249423Sdim  void setAllowHidden(bool AH) {
226249423Sdim    AllowHidden = AH;
227249423Sdim  }
228249423Sdim
229234353Sdim  /// \brief Determine whether this lookup is permitted to see hidden
230234353Sdim  /// declarations, such as those in modules that have not yet been imported.
231234353Sdim  bool isHiddenDeclarationVisible() const {
232249423Sdim    return AllowHidden || LookupKind == Sema::LookupTagName;
233234353Sdim  }
234234353Sdim
235212795Sdim  /// Sets whether tag declarations should be hidden by non-tag
236212795Sdim  /// declarations during resolution.  The default is true.
237212795Sdim  void setHideTags(bool Hide) {
238212795Sdim    HideTags = Hide;
239212795Sdim  }
240212795Sdim
241212795Sdim  bool isAmbiguous() const {
242212795Sdim    return getResultKind() == Ambiguous;
243212795Sdim  }
244212795Sdim
245212795Sdim  /// Determines if this names a single result which is not an
246212795Sdim  /// unresolved value using decl.  If so, it is safe to call
247212795Sdim  /// getFoundDecl().
248212795Sdim  bool isSingleResult() const {
249212795Sdim    return getResultKind() == Found;
250212795Sdim  }
251212795Sdim
252212795Sdim  /// Determines if the results are overloaded.
253212795Sdim  bool isOverloadedResult() const {
254212795Sdim    return getResultKind() == FoundOverloaded;
255212795Sdim  }
256212795Sdim
257212795Sdim  bool isUnresolvableResult() const {
258212795Sdim    return getResultKind() == FoundUnresolvedValue;
259212795Sdim  }
260212795Sdim
261212795Sdim  LookupResultKind getResultKind() const {
262212795Sdim    sanity();
263212795Sdim    return ResultKind;
264212795Sdim  }
265212795Sdim
266212795Sdim  AmbiguityKind getAmbiguityKind() const {
267212795Sdim    assert(isAmbiguous());
268212795Sdim    return Ambiguity;
269212795Sdim  }
270212795Sdim
271212795Sdim  const UnresolvedSetImpl &asUnresolvedSet() const {
272212795Sdim    return Decls;
273212795Sdim  }
274212795Sdim
275212795Sdim  iterator begin() const { return iterator(Decls.begin()); }
276212795Sdim  iterator end() const { return iterator(Decls.end()); }
277212795Sdim
278212795Sdim  /// \brief Return true if no decls were found
279212795Sdim  bool empty() const { return Decls.empty(); }
280212795Sdim
281212795Sdim  /// \brief Return the base paths structure that's associated with
282212795Sdim  /// these results, or null if none is.
283212795Sdim  CXXBasePaths *getBasePaths() const {
284212795Sdim    return Paths;
285212795Sdim  }
286212795Sdim
287234353Sdim  /// \brief Determine whether the given declaration is visible to the
288234353Sdim  /// program.
289263508Sdim  static bool isVisible(Sema &SemaRef, NamedDecl *D) {
290234353Sdim    // If this declaration is not hidden, it's visible.
291234353Sdim    if (!D->isHidden())
292234353Sdim      return true;
293263508Sdim
294263508Sdim    if (SemaRef.ActiveTemplateInstantiations.empty())
295263508Sdim      return false;
296263508Sdim
297263508Sdim    // During template instantiation, we can refer to hidden declarations, if
298263508Sdim    // they were visible in any module along the path of instantiation.
299263508Sdim    return isVisibleSlow(SemaRef, D);
300212795Sdim  }
301263508Sdim
302234353Sdim  /// \brief Retrieve the accepted (re)declaration of the given declaration,
303234353Sdim  /// if there is one.
304234353Sdim  NamedDecl *getAcceptableDecl(NamedDecl *D) const {
305234353Sdim    if (!D->isInIdentifierNamespace(IDNS))
306234353Sdim      return 0;
307263508Sdim
308263508Sdim    if (isHiddenDeclarationVisible() || isVisible(SemaRef, D))
309234353Sdim      return D;
310263508Sdim
311234353Sdim    return getAcceptableDeclSlow(D);
312234353Sdim  }
313263508Sdim
314234353Sdimprivate:
315263508Sdim  static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D);
316234353Sdim  NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const;
317263508Sdim
318234353Sdimpublic:
319212795Sdim  /// \brief Returns the identifier namespace mask for this lookup.
320212795Sdim  unsigned getIdentifierNamespace() const {
321212795Sdim    return IDNS;
322212795Sdim  }
323212795Sdim
324212795Sdim  /// \brief Returns whether these results arose from performing a
325212795Sdim  /// lookup into a class.
326212795Sdim  bool isClassLookup() const {
327212795Sdim    return NamingClass != 0;
328212795Sdim  }
329212795Sdim
330212795Sdim  /// \brief Returns the 'naming class' for this lookup, i.e. the
331212795Sdim  /// class which was looked into to find these results.
332212795Sdim  ///
333212795Sdim  /// C++0x [class.access.base]p5:
334212795Sdim  ///   The access to a member is affected by the class in which the
335212795Sdim  ///   member is named. This naming class is the class in which the
336212795Sdim  ///   member name was looked up and found. [Note: this class can be
337212795Sdim  ///   explicit, e.g., when a qualified-id is used, or implicit,
338212795Sdim  ///   e.g., when a class member access operator (5.2.5) is used
339212795Sdim  ///   (including cases where an implicit "this->" is added). If both
340212795Sdim  ///   a class member access operator and a qualified-id are used to
341212795Sdim  ///   name the member (as in p->T::m), the class naming the member
342212795Sdim  ///   is the class named by the nested-name-specifier of the
343212795Sdim  ///   qualified-id (that is, T). -- end note ]
344212795Sdim  ///
345212795Sdim  /// This is set by the lookup routines when they find results in a class.
346212795Sdim  CXXRecordDecl *getNamingClass() const {
347212795Sdim    return NamingClass;
348212795Sdim  }
349212795Sdim
350212795Sdim  /// \brief Sets the 'naming class' for this lookup.
351212795Sdim  void setNamingClass(CXXRecordDecl *Record) {
352212795Sdim    NamingClass = Record;
353212795Sdim  }
354212795Sdim
355212795Sdim  /// \brief Returns the base object type associated with this lookup;
356212795Sdim  /// important for [class.protected].  Most lookups do not have an
357212795Sdim  /// associated base object.
358212795Sdim  QualType getBaseObjectType() const {
359212795Sdim    return BaseObjectType;
360212795Sdim  }
361212795Sdim
362212795Sdim  /// \brief Sets the base object type for this lookup.
363212795Sdim  void setBaseObjectType(QualType T) {
364212795Sdim    BaseObjectType = T;
365212795Sdim  }
366212795Sdim
367212795Sdim  /// \brief Add a declaration to these results with its natural access.
368212795Sdim  /// Does not test the acceptance criteria.
369212795Sdim  void addDecl(NamedDecl *D) {
370212795Sdim    addDecl(D, D->getAccess());
371212795Sdim  }
372212795Sdim
373212795Sdim  /// \brief Add a declaration to these results with the given access.
374212795Sdim  /// Does not test the acceptance criteria.
375212795Sdim  void addDecl(NamedDecl *D, AccessSpecifier AS) {
376212795Sdim    Decls.addDecl(D, AS);
377212795Sdim    ResultKind = Found;
378212795Sdim  }
379212795Sdim
380212795Sdim  /// \brief Add all the declarations from another set of lookup
381212795Sdim  /// results.
382212795Sdim  void addAllDecls(const LookupResult &Other) {
383212795Sdim    Decls.append(Other.Decls.begin(), Other.Decls.end());
384212795Sdim    ResultKind = Found;
385212795Sdim  }
386212795Sdim
387212795Sdim  /// \brief Determine whether no result was found because we could not
388212795Sdim  /// search into dependent base classes of the current instantiation.
389212795Sdim  bool wasNotFoundInCurrentInstantiation() const {
390212795Sdim    return ResultKind == NotFoundInCurrentInstantiation;
391212795Sdim  }
392212795Sdim
393212795Sdim  /// \brief Note that while no result was found in the current instantiation,
394212795Sdim  /// there were dependent base classes that could not be searched.
395212795Sdim  void setNotFoundInCurrentInstantiation() {
396212795Sdim    assert(ResultKind == NotFound && Decls.empty());
397212795Sdim    ResultKind = NotFoundInCurrentInstantiation;
398212795Sdim  }
399263508Sdim
400263508Sdim  /// \brief Determine whether the lookup result was shadowed by some other
401263508Sdim  /// declaration that lookup ignored.
402263508Sdim  bool isShadowed() const { return Shadowed; }
403263508Sdim
404263508Sdim  /// \brief Note that we found and ignored a declaration while performing
405263508Sdim  /// lookup.
406263508Sdim  void setShadowed() { Shadowed = true; }
407263508Sdim
408212795Sdim  /// \brief Resolves the result kind of the lookup, possibly hiding
409212795Sdim  /// decls.
410212795Sdim  ///
411212795Sdim  /// This should be called in any environment where lookup might
412212795Sdim  /// generate multiple lookup results.
413212795Sdim  void resolveKind();
414212795Sdim
415212795Sdim  /// \brief Re-resolves the result kind of the lookup after a set of
416212795Sdim  /// removals has been performed.
417212795Sdim  void resolveKindAfterFilter() {
418212795Sdim    if (Decls.empty()) {
419212795Sdim      if (ResultKind != NotFoundInCurrentInstantiation)
420212795Sdim        ResultKind = NotFound;
421218893Sdim
422218893Sdim      if (Paths) {
423218893Sdim        deletePaths(Paths);
424218893Sdim        Paths = 0;
425218893Sdim      }
426212795Sdim    } else {
427212795Sdim      AmbiguityKind SavedAK = Ambiguity;
428212795Sdim      ResultKind = Found;
429212795Sdim      resolveKind();
430212795Sdim
431212795Sdim      // If we didn't make the lookup unambiguous, restore the old
432212795Sdim      // ambiguity kind.
433212795Sdim      if (ResultKind == Ambiguous) {
434212795Sdim        Ambiguity = SavedAK;
435212795Sdim      } else if (Paths) {
436212795Sdim        deletePaths(Paths);
437212795Sdim        Paths = 0;
438212795Sdim      }
439212795Sdim    }
440212795Sdim  }
441212795Sdim
442212795Sdim  template <class DeclClass>
443212795Sdim  DeclClass *getAsSingle() const {
444212795Sdim    if (getResultKind() != Found) return 0;
445212795Sdim    return dyn_cast<DeclClass>(getFoundDecl());
446212795Sdim  }
447212795Sdim
448212795Sdim  /// \brief Fetch the unique decl found by this lookup.  Asserts
449212795Sdim  /// that one was found.
450212795Sdim  ///
451212795Sdim  /// This is intended for users who have examined the result kind
452212795Sdim  /// and are certain that there is only one result.
453212795Sdim  NamedDecl *getFoundDecl() const {
454212795Sdim    assert(getResultKind() == Found
455212795Sdim           && "getFoundDecl called on non-unique result");
456212795Sdim    return (*begin())->getUnderlyingDecl();
457212795Sdim  }
458212795Sdim
459212795Sdim  /// Fetches a representative decl.  Useful for lazy diagnostics.
460212795Sdim  NamedDecl *getRepresentativeDecl() const {
461212795Sdim    assert(!Decls.empty() && "cannot get representative of empty set");
462212795Sdim    return *begin();
463212795Sdim  }
464212795Sdim
465212795Sdim  /// \brief Asks if the result is a single tag decl.
466212795Sdim  bool isSingleTagDecl() const {
467212795Sdim    return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
468212795Sdim  }
469212795Sdim
470212795Sdim  /// \brief Make these results show that the name was found in
471212795Sdim  /// base classes of different types.
472212795Sdim  ///
473212795Sdim  /// The given paths object is copied and invalidated.
474212795Sdim  void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
475212795Sdim
476212795Sdim  /// \brief Make these results show that the name was found in
477212795Sdim  /// distinct base classes of the same type.
478212795Sdim  ///
479212795Sdim  /// The given paths object is copied and invalidated.
480212795Sdim  void setAmbiguousBaseSubobjects(CXXBasePaths &P);
481212795Sdim
482212795Sdim  /// \brief Make these results show that the name was found in
483212795Sdim  /// different contexts and a tag decl was hidden by an ordinary
484212795Sdim  /// decl in a different context.
485212795Sdim  void setAmbiguousQualifiedTagHiding() {
486212795Sdim    setAmbiguous(AmbiguousTagHiding);
487212795Sdim  }
488212795Sdim
489212795Sdim  /// \brief Clears out any current state.
490212795Sdim  void clear() {
491212795Sdim    ResultKind = NotFound;
492212795Sdim    Decls.clear();
493212795Sdim    if (Paths) deletePaths(Paths);
494212795Sdim    Paths = NULL;
495221345Sdim    NamingClass = 0;
496263508Sdim    Shadowed = false;
497212795Sdim  }
498212795Sdim
499212795Sdim  /// \brief Clears out any current state and re-initializes for a
500212795Sdim  /// different kind of lookup.
501212795Sdim  void clear(Sema::LookupNameKind Kind) {
502212795Sdim    clear();
503212795Sdim    LookupKind = Kind;
504212795Sdim    configure();
505212795Sdim  }
506212795Sdim
507212795Sdim  /// \brief Change this lookup's redeclaration kind.
508212795Sdim  void setRedeclarationKind(Sema::RedeclarationKind RK) {
509212795Sdim    Redecl = RK;
510249423Sdim    AllowHidden = (RK == Sema::ForRedeclaration);
511212795Sdim    configure();
512212795Sdim  }
513212795Sdim
514226633Sdim  void print(raw_ostream &);
515212795Sdim
516212795Sdim  /// Suppress the diagnostics that would normally fire because of this
517212795Sdim  /// lookup.  This happens during (e.g.) redeclaration lookups.
518212795Sdim  void suppressDiagnostics() {
519212795Sdim    Diagnose = false;
520212795Sdim  }
521212795Sdim
522212795Sdim  /// Determines whether this lookup is suppressing diagnostics.
523212795Sdim  bool isSuppressingDiagnostics() const {
524212795Sdim    return !Diagnose;
525212795Sdim  }
526212795Sdim
527212795Sdim  /// Sets a 'context' source range.
528212795Sdim  void setContextRange(SourceRange SR) {
529212795Sdim    NameContextRange = SR;
530212795Sdim  }
531212795Sdim
532212795Sdim  /// Gets the source range of the context of this name; for C++
533212795Sdim  /// qualified lookups, this is the source range of the scope
534212795Sdim  /// specifier.
535212795Sdim  SourceRange getContextRange() const {
536212795Sdim    return NameContextRange;
537212795Sdim  }
538212795Sdim
539212795Sdim  /// Gets the location of the identifier.  This isn't always defined:
540212795Sdim  /// sometimes we're doing lookups on synthesized names.
541212795Sdim  SourceLocation getNameLoc() const {
542212795Sdim    return NameInfo.getLoc();
543212795Sdim  }
544212795Sdim
545212795Sdim  /// \brief Get the Sema object that this lookup result is searching
546212795Sdim  /// with.
547212795Sdim  Sema &getSema() const { return SemaRef; }
548212795Sdim
549212795Sdim  /// A class for iterating through a result set and possibly
550212795Sdim  /// filtering out results.  The results returned are possibly
551212795Sdim  /// sugared.
552212795Sdim  class Filter {
553212795Sdim    LookupResult &Results;
554212795Sdim    LookupResult::iterator I;
555212795Sdim    bool Changed;
556212795Sdim    bool CalledDone;
557212795Sdim
558212795Sdim    friend class LookupResult;
559212795Sdim    Filter(LookupResult &Results)
560218893Sdim      : Results(Results), I(Results.begin()), Changed(false), CalledDone(false)
561212795Sdim    {}
562212795Sdim
563212795Sdim  public:
564212795Sdim    ~Filter() {
565212795Sdim      assert(CalledDone &&
566212795Sdim             "LookupResult::Filter destroyed without done() call");
567212795Sdim    }
568212795Sdim
569212795Sdim    bool hasNext() const {
570212795Sdim      return I != Results.end();
571212795Sdim    }
572212795Sdim
573212795Sdim    NamedDecl *next() {
574212795Sdim      assert(I != Results.end() && "next() called on empty filter");
575212795Sdim      return *I++;
576212795Sdim    }
577212795Sdim
578234353Sdim    /// Restart the iteration.
579234353Sdim    void restart() {
580234353Sdim      I = Results.begin();
581234353Sdim    }
582234353Sdim
583212795Sdim    /// Erase the last element returned from this iterator.
584212795Sdim    void erase() {
585212795Sdim      Results.Decls.erase(--I);
586212795Sdim      Changed = true;
587212795Sdim    }
588212795Sdim
589212795Sdim    /// Replaces the current entry with the given one, preserving the
590212795Sdim    /// access bits.
591212795Sdim    void replace(NamedDecl *D) {
592212795Sdim      Results.Decls.replace(I-1, D);
593212795Sdim      Changed = true;
594212795Sdim    }
595212795Sdim
596212795Sdim    /// Replaces the current entry with the given one.
597212795Sdim    void replace(NamedDecl *D, AccessSpecifier AS) {
598212795Sdim      Results.Decls.replace(I-1, D, AS);
599212795Sdim      Changed = true;
600212795Sdim    }
601212795Sdim
602212795Sdim    void done() {
603212795Sdim      assert(!CalledDone && "done() called twice");
604212795Sdim      CalledDone = true;
605212795Sdim
606212795Sdim      if (Changed)
607212795Sdim        Results.resolveKindAfterFilter();
608212795Sdim    }
609212795Sdim  };
610212795Sdim
611212795Sdim  /// Create a filter for this result set.
612212795Sdim  Filter makeFilter() {
613212795Sdim    return Filter(*this);
614212795Sdim  }
615212795Sdim
616263508Sdim  void setFindLocalExtern(bool FindLocalExtern) {
617263508Sdim    if (FindLocalExtern)
618263508Sdim      IDNS |= Decl::IDNS_LocalExtern;
619263508Sdim    else
620263508Sdim      IDNS &= ~Decl::IDNS_LocalExtern;
621263508Sdim  }
622263508Sdim
623212795Sdimprivate:
624212795Sdim  void diagnose() {
625212795Sdim    if (isAmbiguous())
626212795Sdim      SemaRef.DiagnoseAmbiguousLookup(*this);
627234353Sdim    else if (isClassLookup() && SemaRef.getLangOpts().AccessControl)
628212795Sdim      SemaRef.CheckLookupAccess(*this);
629212795Sdim  }
630212795Sdim
631212795Sdim  void setAmbiguous(AmbiguityKind AK) {
632212795Sdim    ResultKind = Ambiguous;
633212795Sdim    Ambiguity = AK;
634212795Sdim  }
635212795Sdim
636212795Sdim  void addDeclsFromBasePaths(const CXXBasePaths &P);
637212795Sdim  void configure();
638212795Sdim
639212795Sdim  // Sanity checks.
640234353Sdim  void sanityImpl() const;
641212795Sdim
642234353Sdim  void sanity() const {
643234353Sdim#ifndef NDEBUG
644234353Sdim    sanityImpl();
645234353Sdim#endif
646234353Sdim  }
647234353Sdim
648212795Sdim  bool sanityCheckUnresolved() const {
649212795Sdim    for (iterator I = begin(), E = end(); I != E; ++I)
650249423Sdim      if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl()))
651212795Sdim        return true;
652212795Sdim    return false;
653212795Sdim  }
654212795Sdim
655212795Sdim  static void deletePaths(CXXBasePaths *);
656212795Sdim
657212795Sdim  // Results.
658212795Sdim  LookupResultKind ResultKind;
659212795Sdim  AmbiguityKind Ambiguity; // ill-defined unless ambiguous
660212795Sdim  UnresolvedSet<8> Decls;
661212795Sdim  CXXBasePaths *Paths;
662212795Sdim  CXXRecordDecl *NamingClass;
663212795Sdim  QualType BaseObjectType;
664212795Sdim
665212795Sdim  // Parameters.
666212795Sdim  Sema &SemaRef;
667212795Sdim  DeclarationNameInfo NameInfo;
668212795Sdim  SourceRange NameContextRange;
669212795Sdim  Sema::LookupNameKind LookupKind;
670212795Sdim  unsigned IDNS; // set by configure()
671212795Sdim
672212795Sdim  bool Redecl;
673212795Sdim
674212795Sdim  /// \brief True if tag declarations should be hidden if non-tags
675212795Sdim  ///   are present
676212795Sdim  bool HideTags;
677212795Sdim
678212795Sdim  bool Diagnose;
679249423Sdim
680249423Sdim  /// \brief True if we should allow hidden declarations to be 'visible'.
681249423Sdim  bool AllowHidden;
682263508Sdim
683263508Sdim  /// \brief True if the found declarations were shadowed by some other
684263508Sdim  /// declaration that we skipped. This only happens when \c LookupKind
685263508Sdim  /// is \c LookupRedeclarationWithLinkage.
686263508Sdim  bool Shadowed;
687212795Sdim};
688212795Sdim
689263508Sdim/// \brief Consumes visible declarations found when searching for
690263508Sdim/// all visible names within a given scope or context.
691263508Sdim///
692263508Sdim/// This abstract class is meant to be subclassed by clients of \c
693263508Sdim/// Sema::LookupVisibleDecls(), each of which should override the \c
694263508Sdim/// FoundDecl() function to process declarations as they are found.
695263508Sdimclass VisibleDeclConsumer {
696263508Sdimpublic:
697263508Sdim  /// \brief Destroys the visible declaration consumer.
698263508Sdim  virtual ~VisibleDeclConsumer();
699263508Sdim
700263508Sdim  /// \brief Determine whether hidden declarations (from unimported
701263508Sdim  /// modules) should be given to this consumer. By default, they
702263508Sdim  /// are not included.
703263508Sdim  virtual bool includeHiddenDecls() const;
704263508Sdim
705263508Sdim  /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a
706263508Sdim  /// declaration visible from the current scope or context.
707212795Sdim  ///
708263508Sdim  /// \param ND the declaration found.
709263508Sdim  ///
710263508Sdim  /// \param Hiding a declaration that hides the declaration \p ND,
711263508Sdim  /// or NULL if no such declaration exists.
712263508Sdim  ///
713263508Sdim  /// \param Ctx the original context from which the lookup started.
714263508Sdim  ///
715263508Sdim  /// \param InBaseClass whether this declaration was found in base
716263508Sdim  /// class of the context we searched.
717263508Sdim  virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
718263508Sdim                         bool InBaseClass) = 0;
719263508Sdim};
720212795Sdim
721212795Sdim/// \brief A class for storing results from argument-dependent lookup.
722212795Sdimclass ADLResult {
723212795Sdimprivate:
724212795Sdim  /// A map from canonical decls to the 'most recent' decl.
725212795Sdim  llvm::DenseMap<NamedDecl*, NamedDecl*> Decls;
726212795Sdim
727212795Sdimpublic:
728212795Sdim  /// Adds a new ADL candidate to this map.
729212795Sdim  void insert(NamedDecl *D);
730212795Sdim
731212795Sdim  /// Removes any data associated with a given decl.
732212795Sdim  void erase(NamedDecl *D) {
733212795Sdim    Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
734212795Sdim  }
735212795Sdim
736263508Sdim  class iterator
737263508Sdim      : public std::iterator<std::forward_iterator_tag, NamedDecl *> {
738212795Sdim    typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator;
739212795Sdim    inner_iterator iter;
740212795Sdim
741212795Sdim    friend class ADLResult;
742212795Sdim    iterator(const inner_iterator &iter) : iter(iter) {}
743212795Sdim  public:
744212795Sdim    iterator() {}
745212795Sdim
746212795Sdim    iterator &operator++() { ++iter; return *this; }
747212795Sdim    iterator operator++(int) { return iterator(iter++); }
748212795Sdim
749263508Sdim    value_type operator*() const { return iter->second; }
750212795Sdim
751212795Sdim    bool operator==(const iterator &other) const { return iter == other.iter; }
752212795Sdim    bool operator!=(const iterator &other) const { return iter != other.iter; }
753212795Sdim  };
754212795Sdim
755212795Sdim  iterator begin() { return iterator(Decls.begin()); }
756212795Sdim  iterator end() { return iterator(Decls.end()); }
757212795Sdim};
758212795Sdim
759212795Sdim}
760212795Sdim
761212795Sdim#endif
762