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