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),
133276479Sdim      Paths(nullptr),
134276479Sdim      NamingClass(nullptr),
135280031Sdim      SemaPtr(&SemaRef),
136212795Sdim      NameInfo(NameInfo),
137212795Sdim      LookupKind(LookupKind),
138212795Sdim      IDNS(0),
139212795Sdim      Redecl(Redecl != Sema::NotForRedeclaration),
140212795Sdim      HideTags(true),
141249423Sdim      Diagnose(Redecl == Sema::NotForRedeclaration),
142296417Sdim      AllowHidden(false),
143261991Sdim      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),
155276479Sdim      Paths(nullptr),
156276479Sdim      NamingClass(nullptr),
157280031Sdim      SemaPtr(&SemaRef),
158212795Sdim      NameInfo(Name, NameLoc),
159212795Sdim      LookupKind(LookupKind),
160212795Sdim      IDNS(0),
161212795Sdim      Redecl(Redecl != Sema::NotForRedeclaration),
162212795Sdim      HideTags(true),
163249423Sdim      Diagnose(Redecl == Sema::NotForRedeclaration),
164296417Sdim      AllowHidden(false),
165261991Sdim      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),
175276479Sdim      Paths(nullptr),
176276479Sdim      NamingClass(nullptr),
177280031Sdim      SemaPtr(Other.SemaPtr),
178212795Sdim      NameInfo(Other.NameInfo),
179212795Sdim      LookupKind(Other.LookupKind),
180212795Sdim      IDNS(Other.IDNS),
181212795Sdim      Redecl(Other.Redecl),
182212795Sdim      HideTags(Other.HideTags),
183249423Sdim      Diagnose(false),
184261991Sdim      AllowHidden(Other.AllowHidden),
185261991Sdim      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.
231296417Sdim  bool isHiddenDeclarationVisible(NamedDecl *ND) const {
232296417Sdim    return AllowHidden ||
233296417Sdim           (isForRedeclaration() && ND->isExternallyVisible());
234234353Sdim  }
235296417Sdim
236212795Sdim  /// Sets whether tag declarations should be hidden by non-tag
237212795Sdim  /// declarations during resolution.  The default is true.
238212795Sdim  void setHideTags(bool Hide) {
239212795Sdim    HideTags = Hide;
240212795Sdim  }
241212795Sdim
242212795Sdim  bool isAmbiguous() const {
243212795Sdim    return getResultKind() == Ambiguous;
244212795Sdim  }
245212795Sdim
246212795Sdim  /// Determines if this names a single result which is not an
247212795Sdim  /// unresolved value using decl.  If so, it is safe to call
248212795Sdim  /// getFoundDecl().
249212795Sdim  bool isSingleResult() const {
250212795Sdim    return getResultKind() == Found;
251212795Sdim  }
252212795Sdim
253212795Sdim  /// Determines if the results are overloaded.
254212795Sdim  bool isOverloadedResult() const {
255212795Sdim    return getResultKind() == FoundOverloaded;
256212795Sdim  }
257212795Sdim
258212795Sdim  bool isUnresolvableResult() const {
259212795Sdim    return getResultKind() == FoundUnresolvedValue;
260212795Sdim  }
261212795Sdim
262212795Sdim  LookupResultKind getResultKind() const {
263276479Sdim    assert(sanity());
264212795Sdim    return ResultKind;
265212795Sdim  }
266212795Sdim
267212795Sdim  AmbiguityKind getAmbiguityKind() const {
268212795Sdim    assert(isAmbiguous());
269212795Sdim    return Ambiguity;
270212795Sdim  }
271212795Sdim
272212795Sdim  const UnresolvedSetImpl &asUnresolvedSet() const {
273212795Sdim    return Decls;
274212795Sdim  }
275212795Sdim
276212795Sdim  iterator begin() const { return iterator(Decls.begin()); }
277212795Sdim  iterator end() const { return iterator(Decls.end()); }
278212795Sdim
279212795Sdim  /// \brief Return true if no decls were found
280212795Sdim  bool empty() const { return Decls.empty(); }
281212795Sdim
282212795Sdim  /// \brief Return the base paths structure that's associated with
283212795Sdim  /// these results, or null if none is.
284212795Sdim  CXXBasePaths *getBasePaths() const {
285212795Sdim    return Paths;
286212795Sdim  }
287212795Sdim
288234353Sdim  /// \brief Determine whether the given declaration is visible to the
289234353Sdim  /// program.
290261991Sdim  static bool isVisible(Sema &SemaRef, NamedDecl *D) {
291234353Sdim    // If this declaration is not hidden, it's visible.
292234353Sdim    if (!D->isHidden())
293234353Sdim      return true;
294261991Sdim
295261991Sdim    // During template instantiation, we can refer to hidden declarations, if
296261991Sdim    // they were visible in any module along the path of instantiation.
297261991Sdim    return isVisibleSlow(SemaRef, D);
298212795Sdim  }
299261991Sdim
300234353Sdim  /// \brief Retrieve the accepted (re)declaration of the given declaration,
301234353Sdim  /// if there is one.
302234353Sdim  NamedDecl *getAcceptableDecl(NamedDecl *D) const {
303234353Sdim    if (!D->isInIdentifierNamespace(IDNS))
304276479Sdim      return nullptr;
305261991Sdim
306296417Sdim    if (isVisible(getSema(), D) || isHiddenDeclarationVisible(D))
307234353Sdim      return D;
308261991Sdim
309234353Sdim    return getAcceptableDeclSlow(D);
310234353Sdim  }
311261991Sdim
312234353Sdimprivate:
313261991Sdim  static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D);
314234353Sdim  NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const;
315261991Sdim
316234353Sdimpublic:
317212795Sdim  /// \brief Returns the identifier namespace mask for this lookup.
318212795Sdim  unsigned getIdentifierNamespace() const {
319212795Sdim    return IDNS;
320212795Sdim  }
321212795Sdim
322212795Sdim  /// \brief Returns whether these results arose from performing a
323212795Sdim  /// lookup into a class.
324212795Sdim  bool isClassLookup() const {
325276479Sdim    return NamingClass != nullptr;
326212795Sdim  }
327212795Sdim
328212795Sdim  /// \brief Returns the 'naming class' for this lookup, i.e. the
329212795Sdim  /// class which was looked into to find these results.
330212795Sdim  ///
331212795Sdim  /// C++0x [class.access.base]p5:
332212795Sdim  ///   The access to a member is affected by the class in which the
333212795Sdim  ///   member is named. This naming class is the class in which the
334212795Sdim  ///   member name was looked up and found. [Note: this class can be
335212795Sdim  ///   explicit, e.g., when a qualified-id is used, or implicit,
336212795Sdim  ///   e.g., when a class member access operator (5.2.5) is used
337212795Sdim  ///   (including cases where an implicit "this->" is added). If both
338212795Sdim  ///   a class member access operator and a qualified-id are used to
339212795Sdim  ///   name the member (as in p->T::m), the class naming the member
340212795Sdim  ///   is the class named by the nested-name-specifier of the
341212795Sdim  ///   qualified-id (that is, T). -- end note ]
342212795Sdim  ///
343212795Sdim  /// This is set by the lookup routines when they find results in a class.
344212795Sdim  CXXRecordDecl *getNamingClass() const {
345212795Sdim    return NamingClass;
346212795Sdim  }
347212795Sdim
348212795Sdim  /// \brief Sets the 'naming class' for this lookup.
349212795Sdim  void setNamingClass(CXXRecordDecl *Record) {
350212795Sdim    NamingClass = Record;
351212795Sdim  }
352212795Sdim
353212795Sdim  /// \brief Returns the base object type associated with this lookup;
354212795Sdim  /// important for [class.protected].  Most lookups do not have an
355212795Sdim  /// associated base object.
356212795Sdim  QualType getBaseObjectType() const {
357212795Sdim    return BaseObjectType;
358212795Sdim  }
359212795Sdim
360212795Sdim  /// \brief Sets the base object type for this lookup.
361212795Sdim  void setBaseObjectType(QualType T) {
362212795Sdim    BaseObjectType = T;
363212795Sdim  }
364212795Sdim
365212795Sdim  /// \brief Add a declaration to these results with its natural access.
366212795Sdim  /// Does not test the acceptance criteria.
367212795Sdim  void addDecl(NamedDecl *D) {
368212795Sdim    addDecl(D, D->getAccess());
369212795Sdim  }
370212795Sdim
371212795Sdim  /// \brief Add a declaration to these results with the given access.
372212795Sdim  /// Does not test the acceptance criteria.
373212795Sdim  void addDecl(NamedDecl *D, AccessSpecifier AS) {
374212795Sdim    Decls.addDecl(D, AS);
375212795Sdim    ResultKind = Found;
376212795Sdim  }
377212795Sdim
378212795Sdim  /// \brief Add all the declarations from another set of lookup
379212795Sdim  /// results.
380212795Sdim  void addAllDecls(const LookupResult &Other) {
381212795Sdim    Decls.append(Other.Decls.begin(), Other.Decls.end());
382212795Sdim    ResultKind = Found;
383212795Sdim  }
384212795Sdim
385212795Sdim  /// \brief Determine whether no result was found because we could not
386212795Sdim  /// search into dependent base classes of the current instantiation.
387212795Sdim  bool wasNotFoundInCurrentInstantiation() const {
388212795Sdim    return ResultKind == NotFoundInCurrentInstantiation;
389212795Sdim  }
390212795Sdim
391212795Sdim  /// \brief Note that while no result was found in the current instantiation,
392212795Sdim  /// there were dependent base classes that could not be searched.
393212795Sdim  void setNotFoundInCurrentInstantiation() {
394212795Sdim    assert(ResultKind == NotFound && Decls.empty());
395212795Sdim    ResultKind = NotFoundInCurrentInstantiation;
396212795Sdim  }
397261991Sdim
398261991Sdim  /// \brief Determine whether the lookup result was shadowed by some other
399261991Sdim  /// declaration that lookup ignored.
400261991Sdim  bool isShadowed() const { return Shadowed; }
401261991Sdim
402261991Sdim  /// \brief Note that we found and ignored a declaration while performing
403261991Sdim  /// lookup.
404261991Sdim  void setShadowed() { Shadowed = true; }
405261991Sdim
406212795Sdim  /// \brief Resolves the result kind of the lookup, possibly hiding
407212795Sdim  /// decls.
408212795Sdim  ///
409212795Sdim  /// This should be called in any environment where lookup might
410212795Sdim  /// generate multiple lookup results.
411212795Sdim  void resolveKind();
412212795Sdim
413212795Sdim  /// \brief Re-resolves the result kind of the lookup after a set of
414212795Sdim  /// removals has been performed.
415212795Sdim  void resolveKindAfterFilter() {
416212795Sdim    if (Decls.empty()) {
417212795Sdim      if (ResultKind != NotFoundInCurrentInstantiation)
418212795Sdim        ResultKind = NotFound;
419218893Sdim
420218893Sdim      if (Paths) {
421218893Sdim        deletePaths(Paths);
422276479Sdim        Paths = nullptr;
423218893Sdim      }
424212795Sdim    } else {
425280031Sdim      AmbiguityKind SavedAK;
426280031Sdim      bool WasAmbiguous = false;
427280031Sdim      if (ResultKind == Ambiguous) {
428280031Sdim        SavedAK = Ambiguity;
429280031Sdim        WasAmbiguous = true;
430280031Sdim      }
431212795Sdim      ResultKind = Found;
432212795Sdim      resolveKind();
433212795Sdim
434212795Sdim      // If we didn't make the lookup unambiguous, restore the old
435212795Sdim      // ambiguity kind.
436212795Sdim      if (ResultKind == Ambiguous) {
437280031Sdim        (void)WasAmbiguous;
438280031Sdim        assert(WasAmbiguous);
439212795Sdim        Ambiguity = SavedAK;
440212795Sdim      } else if (Paths) {
441212795Sdim        deletePaths(Paths);
442276479Sdim        Paths = nullptr;
443212795Sdim      }
444212795Sdim    }
445212795Sdim  }
446212795Sdim
447212795Sdim  template <class DeclClass>
448212795Sdim  DeclClass *getAsSingle() const {
449276479Sdim    if (getResultKind() != Found) return nullptr;
450212795Sdim    return dyn_cast<DeclClass>(getFoundDecl());
451212795Sdim  }
452212795Sdim
453212795Sdim  /// \brief Fetch the unique decl found by this lookup.  Asserts
454212795Sdim  /// that one was found.
455212795Sdim  ///
456212795Sdim  /// This is intended for users who have examined the result kind
457212795Sdim  /// and are certain that there is only one result.
458212795Sdim  NamedDecl *getFoundDecl() const {
459212795Sdim    assert(getResultKind() == Found
460212795Sdim           && "getFoundDecl called on non-unique result");
461212795Sdim    return (*begin())->getUnderlyingDecl();
462212795Sdim  }
463212795Sdim
464212795Sdim  /// Fetches a representative decl.  Useful for lazy diagnostics.
465212795Sdim  NamedDecl *getRepresentativeDecl() const {
466212795Sdim    assert(!Decls.empty() && "cannot get representative of empty set");
467212795Sdim    return *begin();
468212795Sdim  }
469212795Sdim
470212795Sdim  /// \brief Asks if the result is a single tag decl.
471212795Sdim  bool isSingleTagDecl() const {
472212795Sdim    return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
473212795Sdim  }
474212795Sdim
475212795Sdim  /// \brief Make these results show that the name was found in
476212795Sdim  /// base classes of different types.
477212795Sdim  ///
478212795Sdim  /// The given paths object is copied and invalidated.
479212795Sdim  void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
480212795Sdim
481212795Sdim  /// \brief Make these results show that the name was found in
482212795Sdim  /// distinct base classes of the same type.
483212795Sdim  ///
484212795Sdim  /// The given paths object is copied and invalidated.
485212795Sdim  void setAmbiguousBaseSubobjects(CXXBasePaths &P);
486212795Sdim
487212795Sdim  /// \brief Make these results show that the name was found in
488212795Sdim  /// different contexts and a tag decl was hidden by an ordinary
489212795Sdim  /// decl in a different context.
490212795Sdim  void setAmbiguousQualifiedTagHiding() {
491212795Sdim    setAmbiguous(AmbiguousTagHiding);
492212795Sdim  }
493212795Sdim
494212795Sdim  /// \brief Clears out any current state.
495212795Sdim  void clear() {
496212795Sdim    ResultKind = NotFound;
497212795Sdim    Decls.clear();
498212795Sdim    if (Paths) deletePaths(Paths);
499276479Sdim    Paths = nullptr;
500276479Sdim    NamingClass = nullptr;
501261991Sdim    Shadowed = false;
502212795Sdim  }
503212795Sdim
504212795Sdim  /// \brief Clears out any current state and re-initializes for a
505212795Sdim  /// different kind of lookup.
506212795Sdim  void clear(Sema::LookupNameKind Kind) {
507212795Sdim    clear();
508212795Sdim    LookupKind = Kind;
509212795Sdim    configure();
510212795Sdim  }
511212795Sdim
512212795Sdim  /// \brief Change this lookup's redeclaration kind.
513212795Sdim  void setRedeclarationKind(Sema::RedeclarationKind RK) {
514212795Sdim    Redecl = RK;
515212795Sdim    configure();
516212795Sdim  }
517212795Sdim
518296417Sdim  void dump();
519226633Sdim  void print(raw_ostream &);
520212795Sdim
521212795Sdim  /// Suppress the diagnostics that would normally fire because of this
522212795Sdim  /// lookup.  This happens during (e.g.) redeclaration lookups.
523212795Sdim  void suppressDiagnostics() {
524212795Sdim    Diagnose = false;
525212795Sdim  }
526212795Sdim
527212795Sdim  /// Determines whether this lookup is suppressing diagnostics.
528212795Sdim  bool isSuppressingDiagnostics() const {
529212795Sdim    return !Diagnose;
530212795Sdim  }
531212795Sdim
532212795Sdim  /// Sets a 'context' source range.
533212795Sdim  void setContextRange(SourceRange SR) {
534212795Sdim    NameContextRange = SR;
535212795Sdim  }
536212795Sdim
537212795Sdim  /// Gets the source range of the context of this name; for C++
538212795Sdim  /// qualified lookups, this is the source range of the scope
539212795Sdim  /// specifier.
540212795Sdim  SourceRange getContextRange() const {
541212795Sdim    return NameContextRange;
542212795Sdim  }
543212795Sdim
544212795Sdim  /// Gets the location of the identifier.  This isn't always defined:
545212795Sdim  /// sometimes we're doing lookups on synthesized names.
546212795Sdim  SourceLocation getNameLoc() const {
547212795Sdim    return NameInfo.getLoc();
548212795Sdim  }
549212795Sdim
550212795Sdim  /// \brief Get the Sema object that this lookup result is searching
551212795Sdim  /// with.
552280031Sdim  Sema &getSema() const { return *SemaPtr; }
553212795Sdim
554212795Sdim  /// A class for iterating through a result set and possibly
555212795Sdim  /// filtering out results.  The results returned are possibly
556212795Sdim  /// sugared.
557212795Sdim  class Filter {
558212795Sdim    LookupResult &Results;
559212795Sdim    LookupResult::iterator I;
560212795Sdim    bool Changed;
561212795Sdim    bool CalledDone;
562212795Sdim
563212795Sdim    friend class LookupResult;
564212795Sdim    Filter(LookupResult &Results)
565218893Sdim      : Results(Results), I(Results.begin()), Changed(false), CalledDone(false)
566212795Sdim    {}
567212795Sdim
568212795Sdim  public:
569296417Sdim    Filter(Filter &&F)
570296417Sdim        : Results(F.Results), I(F.I), Changed(F.Changed),
571296417Sdim          CalledDone(F.CalledDone) {
572296417Sdim      F.CalledDone = true;
573296417Sdim    }
574212795Sdim    ~Filter() {
575212795Sdim      assert(CalledDone &&
576212795Sdim             "LookupResult::Filter destroyed without done() call");
577212795Sdim    }
578212795Sdim
579212795Sdim    bool hasNext() const {
580212795Sdim      return I != Results.end();
581212795Sdim    }
582212795Sdim
583212795Sdim    NamedDecl *next() {
584212795Sdim      assert(I != Results.end() && "next() called on empty filter");
585212795Sdim      return *I++;
586212795Sdim    }
587212795Sdim
588234353Sdim    /// Restart the iteration.
589234353Sdim    void restart() {
590234353Sdim      I = Results.begin();
591234353Sdim    }
592234353Sdim
593212795Sdim    /// Erase the last element returned from this iterator.
594212795Sdim    void erase() {
595212795Sdim      Results.Decls.erase(--I);
596212795Sdim      Changed = true;
597212795Sdim    }
598212795Sdim
599212795Sdim    /// Replaces the current entry with the given one, preserving the
600212795Sdim    /// access bits.
601212795Sdim    void replace(NamedDecl *D) {
602212795Sdim      Results.Decls.replace(I-1, D);
603212795Sdim      Changed = true;
604212795Sdim    }
605212795Sdim
606212795Sdim    /// Replaces the current entry with the given one.
607212795Sdim    void replace(NamedDecl *D, AccessSpecifier AS) {
608212795Sdim      Results.Decls.replace(I-1, D, AS);
609212795Sdim      Changed = true;
610212795Sdim    }
611212795Sdim
612212795Sdim    void done() {
613212795Sdim      assert(!CalledDone && "done() called twice");
614212795Sdim      CalledDone = true;
615212795Sdim
616212795Sdim      if (Changed)
617212795Sdim        Results.resolveKindAfterFilter();
618212795Sdim    }
619212795Sdim  };
620212795Sdim
621212795Sdim  /// Create a filter for this result set.
622212795Sdim  Filter makeFilter() {
623212795Sdim    return Filter(*this);
624212795Sdim  }
625212795Sdim
626261991Sdim  void setFindLocalExtern(bool FindLocalExtern) {
627261991Sdim    if (FindLocalExtern)
628261991Sdim      IDNS |= Decl::IDNS_LocalExtern;
629261991Sdim    else
630261991Sdim      IDNS &= ~Decl::IDNS_LocalExtern;
631261991Sdim  }
632261991Sdim
633212795Sdimprivate:
634212795Sdim  void diagnose() {
635212795Sdim    if (isAmbiguous())
636280031Sdim      getSema().DiagnoseAmbiguousLookup(*this);
637280031Sdim    else if (isClassLookup() && getSema().getLangOpts().AccessControl)
638280031Sdim      getSema().CheckLookupAccess(*this);
639212795Sdim  }
640212795Sdim
641212795Sdim  void setAmbiguous(AmbiguityKind AK) {
642212795Sdim    ResultKind = Ambiguous;
643212795Sdim    Ambiguity = AK;
644212795Sdim  }
645212795Sdim
646212795Sdim  void addDeclsFromBasePaths(const CXXBasePaths &P);
647212795Sdim  void configure();
648212795Sdim
649212795Sdim  // Sanity checks.
650276479Sdim  bool sanity() const;
651212795Sdim
652212795Sdim  bool sanityCheckUnresolved() const {
653212795Sdim    for (iterator I = begin(), E = end(); I != E; ++I)
654249423Sdim      if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl()))
655212795Sdim        return true;
656212795Sdim    return false;
657212795Sdim  }
658212795Sdim
659212795Sdim  static void deletePaths(CXXBasePaths *);
660212795Sdim
661212795Sdim  // Results.
662212795Sdim  LookupResultKind ResultKind;
663212795Sdim  AmbiguityKind Ambiguity; // ill-defined unless ambiguous
664212795Sdim  UnresolvedSet<8> Decls;
665212795Sdim  CXXBasePaths *Paths;
666212795Sdim  CXXRecordDecl *NamingClass;
667212795Sdim  QualType BaseObjectType;
668212795Sdim
669212795Sdim  // Parameters.
670280031Sdim  Sema *SemaPtr;
671212795Sdim  DeclarationNameInfo NameInfo;
672212795Sdim  SourceRange NameContextRange;
673212795Sdim  Sema::LookupNameKind LookupKind;
674212795Sdim  unsigned IDNS; // set by configure()
675212795Sdim
676212795Sdim  bool Redecl;
677212795Sdim
678212795Sdim  /// \brief True if tag declarations should be hidden if non-tags
679212795Sdim  ///   are present
680212795Sdim  bool HideTags;
681212795Sdim
682212795Sdim  bool Diagnose;
683249423Sdim
684249423Sdim  /// \brief True if we should allow hidden declarations to be 'visible'.
685249423Sdim  bool AllowHidden;
686261991Sdim
687261991Sdim  /// \brief True if the found declarations were shadowed by some other
688261991Sdim  /// declaration that we skipped. This only happens when \c LookupKind
689261991Sdim  /// is \c LookupRedeclarationWithLinkage.
690261991Sdim  bool Shadowed;
691212795Sdim};
692212795Sdim
693261991Sdim/// \brief Consumes visible declarations found when searching for
694261991Sdim/// all visible names within a given scope or context.
695261991Sdim///
696261991Sdim/// This abstract class is meant to be subclassed by clients of \c
697261991Sdim/// Sema::LookupVisibleDecls(), each of which should override the \c
698261991Sdim/// FoundDecl() function to process declarations as they are found.
699261991Sdimclass VisibleDeclConsumer {
700261991Sdimpublic:
701261991Sdim  /// \brief Destroys the visible declaration consumer.
702261991Sdim  virtual ~VisibleDeclConsumer();
703261991Sdim
704261991Sdim  /// \brief Determine whether hidden declarations (from unimported
705261991Sdim  /// modules) should be given to this consumer. By default, they
706261991Sdim  /// are not included.
707261991Sdim  virtual bool includeHiddenDecls() const;
708261991Sdim
709261991Sdim  /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a
710261991Sdim  /// declaration visible from the current scope or context.
711212795Sdim  ///
712261991Sdim  /// \param ND the declaration found.
713261991Sdim  ///
714261991Sdim  /// \param Hiding a declaration that hides the declaration \p ND,
715261991Sdim  /// or NULL if no such declaration exists.
716261991Sdim  ///
717261991Sdim  /// \param Ctx the original context from which the lookup started.
718261991Sdim  ///
719261991Sdim  /// \param InBaseClass whether this declaration was found in base
720261991Sdim  /// class of the context we searched.
721261991Sdim  virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
722261991Sdim                         bool InBaseClass) = 0;
723261991Sdim};
724212795Sdim
725212795Sdim/// \brief A class for storing results from argument-dependent lookup.
726212795Sdimclass ADLResult {
727212795Sdimprivate:
728212795Sdim  /// A map from canonical decls to the 'most recent' decl.
729212795Sdim  llvm::DenseMap<NamedDecl*, NamedDecl*> Decls;
730212795Sdim
731212795Sdimpublic:
732212795Sdim  /// Adds a new ADL candidate to this map.
733212795Sdim  void insert(NamedDecl *D);
734212795Sdim
735212795Sdim  /// Removes any data associated with a given decl.
736212795Sdim  void erase(NamedDecl *D) {
737212795Sdim    Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
738212795Sdim  }
739212795Sdim
740261991Sdim  class iterator
741288943Sdim      : public llvm::iterator_adaptor_base<
742288943Sdim            iterator, llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator,
743288943Sdim            std::forward_iterator_tag, NamedDecl *> {
744288943Sdim    friend class ADLResult;
745212795Sdim
746288943Sdim    iterator(llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator Iter)
747288943Sdim        : iterator_adaptor_base(std::move(Iter)) {}
748288943Sdim
749212795Sdim  public:
750212795Sdim    iterator() {}
751212795Sdim
752288943Sdim    value_type operator*() const { return I->second; }
753212795Sdim  };
754212795Sdim
755212795Sdim  iterator begin() { return iterator(Decls.begin()); }
756212795Sdim  iterator end() { return iterator(Decls.end()); }
757212795Sdim};
758212795Sdim
759212795Sdim}
760212795Sdim
761212795Sdim#endif
762