blob: e2134a2683d6ef3c20e0d4a2211944d78d34d932 [file] [log] [blame]
John McCall7d384dd2009-11-18 07:57:50 +00001//===--- 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
20namespace 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///
30/// Any non-ambiguous lookup can be converted into a single
31/// (possibly NULL) @c NamedDecl* via the getAsSingleDecl() method.
32/// This permits the common-case usage in C and Objective-C where
33/// name lookup will always return a single declaration. Use of
34/// this is largely deprecated; callers should handle the possibility
35/// of multiple declarations.
36class LookupResult {
37public:
38 enum LookupResultKind {
39 /// @brief No entity found met the criteria.
40 NotFound = 0,
41
42 /// @brief Name lookup found a single declaration that met the
43 /// criteria. getAsDecl will return this declaration.
44 Found,
45
46 /// @brief Name lookup found a set of overloaded functions that
47 /// met the criteria. getAsDecl will turn this set of overloaded
48 /// functions into an OverloadedFunctionDecl.
49 FoundOverloaded,
50
51 /// @brief Name lookup found an unresolvable value declaration
52 /// and cannot yet complete. This only happens in C++ dependent
53 /// contexts with dependent using declarations.
54 FoundUnresolvedValue,
55
56 /// @brief Name lookup results in an ambiguity; use
57 /// getAmbiguityKind to figure out what kind of ambiguity
58 /// we have.
59 Ambiguous
60 };
61
62 enum AmbiguityKind {
63 /// Name lookup results in an ambiguity because multiple
64 /// entities that meet the lookup criteria were found in
65 /// subobjects of different types. For example:
66 /// @code
67 /// struct A { void f(int); }
68 /// struct B { void f(double); }
69 /// struct C : A, B { };
70 /// void test(C c) {
71 /// c.f(0); // error: A::f and B::f come from subobjects of different
72 /// // types. overload resolution is not performed.
73 /// }
74 /// @endcode
75 AmbiguousBaseSubobjectTypes,
76
77 /// Name lookup results in an ambiguity because multiple
78 /// nonstatic entities that meet the lookup criteria were found
79 /// in different subobjects of the same type. For example:
80 /// @code
81 /// struct A { int x; };
82 /// struct B : A { };
83 /// struct C : A { };
84 /// struct D : B, C { };
85 /// int test(D d) {
86 /// return d.x; // error: 'x' is found in two A subobjects (of B and C)
87 /// }
88 /// @endcode
89 AmbiguousBaseSubobjects,
90
91 /// Name lookup results in an ambiguity because multiple definitions
92 /// of entity that meet the lookup criteria were found in different
93 /// declaration contexts.
94 /// @code
95 /// namespace A {
96 /// int i;
97 /// namespace B { int i; }
98 /// int test() {
99 /// using namespace B;
100 /// return i; // error 'i' is found in namespace A and A::B
101 /// }
102 /// }
103 /// @endcode
104 AmbiguousReference,
105
106 /// Name lookup results in an ambiguity because an entity with a
107 /// tag name was hidden by an entity with an ordinary name from
108 /// a different context.
109 /// @code
110 /// namespace A { struct Foo {}; }
111 /// namespace B { void Foo(); }
112 /// namespace C {
113 /// using namespace A;
114 /// using namespace B;
115 /// }
116 /// void test() {
117 /// C::Foo(); // error: tag 'A::Foo' is hidden by an object in a
118 /// // different namespace
119 /// }
120 /// @endcode
121 AmbiguousTagHiding
122 };
123
124 /// A little identifier for flagging temporary lookup results.
125 enum TemporaryToken {
126 Temporary
127 };
128
129 typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
130 typedef DeclsTy::const_iterator iterator;
131
132 LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
133 Sema::LookupNameKind LookupKind,
134 Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
135 : ResultKind(NotFound),
136 Paths(0),
137 SemaRef(SemaRef),
138 Name(Name),
139 NameLoc(NameLoc),
140 LookupKind(LookupKind),
141 IDNS(0),
142 Redecl(Redecl != Sema::NotForRedeclaration),
143 HideTags(true),
144 Diagnose(Redecl == Sema::NotForRedeclaration)
145 {}
146
147 /// Creates a temporary lookup result, initializing its core data
148 /// using the information from another result. Diagnostics are always
149 /// disabled.
150 LookupResult(TemporaryToken _, const LookupResult &Other)
151 : ResultKind(NotFound),
152 Paths(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 /// Gets the kind of lookup to perform.
174 Sema::LookupNameKind getLookupKind() const {
175 return LookupKind;
176 }
177
178 /// True if this lookup is just looking for an existing declaration.
179 bool isForRedeclaration() const {
180 return Redecl;
181 }
182
183 /// Sets whether tag declarations should be hidden by non-tag
184 /// declarations during resolution. The default is true.
185 void setHideTags(bool Hide) {
186 HideTags = Hide;
187 }
188
189 /// The identifier namespace of this lookup. This information is
190 /// private to the lookup routines.
191 unsigned getIdentifierNamespace() const {
192 assert(IDNS);
193 return IDNS;
194 }
195
196 void setIdentifierNamespace(unsigned NS) {
197 IDNS = NS;
198 }
199
200 bool isAmbiguous() const {
201 return getResultKind() == Ambiguous;
202 }
203
John McCall68263142009-11-18 22:49:29 +0000204 /// Determines if this names a single result which is not an
205 /// unresolved value using decl. If so, it is safe to call
206 /// getFoundDecl().
207 bool isSingleResult() const {
208 return getResultKind() == Found;
209 }
210
John McCall7453ed42009-11-22 00:44:51 +0000211 /// Determines if the results are overloaded.
212 bool isOverloadedResult() const {
213 return getResultKind() == FoundOverloaded;
214 }
215
John McCall129e2df2009-11-30 22:42:35 +0000216 bool isUnresolvableResult() const {
217 return getResultKind() == FoundUnresolvedValue;
218 }
219
John McCall7d384dd2009-11-18 07:57:50 +0000220 LookupResultKind getResultKind() const {
221 sanity();
222 return ResultKind;
223 }
224
225 AmbiguityKind getAmbiguityKind() const {
226 assert(isAmbiguous());
227 return Ambiguity;
228 }
229
230 iterator begin() const { return Decls.begin(); }
231 iterator end() const { return Decls.end(); }
232
233 /// \brief Return true if no decls were found
234 bool empty() const { return Decls.empty(); }
235
236 /// \brief Return the base paths structure that's associated with
237 /// these results, or null if none is.
238 CXXBasePaths *getBasePaths() const {
239 return Paths;
240 }
241
242 /// \brief Add a declaration to these results.
243 void addDecl(NamedDecl *D) {
244 Decls.push_back(D);
245 ResultKind = Found;
246 }
247
248 /// \brief Add all the declarations from another set of lookup
249 /// results.
250 void addAllDecls(const LookupResult &Other) {
251 Decls.append(Other.begin(), Other.end());
252 ResultKind = Found;
253 }
254
255 /// \brief Hides a set of declarations.
256 template <class NamedDeclSet> void hideDecls(const NamedDeclSet &Set) {
257 unsigned I = 0, N = Decls.size();
258 while (I < N) {
259 if (Set.count(Decls[I]))
260 Decls[I] = Decls[--N];
261 else
262 I++;
263 }
264 Decls.set_size(N);
265 }
266
John McCall68263142009-11-18 22:49:29 +0000267 /// \brief Resolves the result kind of the lookup, possibly hiding
268 /// decls.
John McCall7d384dd2009-11-18 07:57:50 +0000269 ///
270 /// This should be called in any environment where lookup might
271 /// generate multiple lookup results.
272 void resolveKind();
273
John McCall68263142009-11-18 22:49:29 +0000274 /// \brief Re-resolves the result kind of the lookup after a set of
275 /// removals has been performed.
276 void resolveKindAfterFilter() {
277 if (Decls.empty())
278 ResultKind = NotFound;
279 else {
280 ResultKind = Found;
281 resolveKind();
282 }
283 }
284
John McCall7d384dd2009-11-18 07:57:50 +0000285 /// \brief Fetch this as an unambiguous single declaration
286 /// (possibly an overloaded one).
287 ///
288 /// This is deprecated; users should be written to handle
289 /// ambiguous and overloaded lookups.
290 NamedDecl *getAsSingleDecl(ASTContext &Context) const;
291
John McCallba135432009-11-21 08:51:07 +0000292 template <class DeclClass>
293 DeclClass *getAsSingle() const {
294 if (getResultKind() != Found) return 0;
295 return dyn_cast<DeclClass>(getFoundDecl());
296 }
297
John McCall7d384dd2009-11-18 07:57:50 +0000298 /// \brief Fetch the unique decl found by this lookup. Asserts
299 /// that one was found.
300 ///
301 /// This is intended for users who have examined the result kind
302 /// and are certain that there is only one result.
303 NamedDecl *getFoundDecl() const {
304 assert(getResultKind() == Found
305 && "getFoundDecl called on non-unique result");
306 return Decls[0]->getUnderlyingDecl();
307 }
308
John McCall68263142009-11-18 22:49:29 +0000309 /// Fetches a representative decl. Useful for lazy diagnostics.
310 NamedDecl *getRepresentativeDecl() const {
311 assert(!Decls.empty() && "cannot get representative of empty set");
312 return Decls[0];
313 }
314
John McCall7d384dd2009-11-18 07:57:50 +0000315 /// \brief Asks if the result is a single tag decl.
316 bool isSingleTagDecl() const {
317 return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
318 }
319
320 /// \brief Make these results show that the name was found in
321 /// base classes of different types.
322 ///
323 /// The given paths object is copied and invalidated.
324 void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
325
326 /// \brief Make these results show that the name was found in
327 /// distinct base classes of the same type.
328 ///
329 /// The given paths object is copied and invalidated.
330 void setAmbiguousBaseSubobjects(CXXBasePaths &P);
331
332 /// \brief Make these results show that the name was found in
333 /// different contexts and a tag decl was hidden by an ordinary
334 /// decl in a different context.
335 void setAmbiguousQualifiedTagHiding() {
336 setAmbiguous(AmbiguousTagHiding);
337 }
338
339 /// \brief Clears out any current state.
340 void clear() {
341 ResultKind = NotFound;
342 Decls.clear();
343 if (Paths) deletePaths(Paths);
344 Paths = NULL;
345 }
346
347 /// \brief Clears out any current state and re-initializes for a
348 /// different kind of lookup.
349 void clear(Sema::LookupNameKind Kind) {
350 clear();
351 LookupKind = Kind;
352 }
353
354 void print(llvm::raw_ostream &);
355
356 /// Suppress the diagnostics that would normally fire because of this
357 /// lookup. This happens during (e.g.) redeclaration lookups.
358 void suppressDiagnostics() {
359 Diagnose = false;
360 }
361
362 /// Sets a 'context' source range.
363 void setContextRange(SourceRange SR) {
364 NameContextRange = SR;
365 }
366
367 /// Gets the source range of the context of this name; for C++
368 /// qualified lookups, this is the source range of the scope
369 /// specifier.
370 SourceRange getContextRange() const {
371 return NameContextRange;
372 }
373
374 /// Gets the location of the identifier. This isn't always defined:
375 /// sometimes we're doing lookups on synthesized names.
376 SourceLocation getNameLoc() const {
377 return NameLoc;
378 }
379
John McCall68263142009-11-18 22:49:29 +0000380 /// A class for iterating through a result set and possibly
381 /// filtering out results. The results returned are possibly
382 /// sugared.
383 class Filter {
384 LookupResult &Results;
385 unsigned I;
John McCallf7a1a742009-11-24 19:00:30 +0000386 bool Changed;
John McCall68263142009-11-18 22:49:29 +0000387#ifndef NDEBUG
388 bool CalledDone;
389#endif
390
391 friend class LookupResult;
392 Filter(LookupResult &Results)
John McCallf7a1a742009-11-24 19:00:30 +0000393 : Results(Results), I(0), Changed(false)
John McCall68263142009-11-18 22:49:29 +0000394#ifndef NDEBUG
395 , CalledDone(false)
396#endif
397 {}
398
399 public:
400#ifndef NDEBUG
401 ~Filter() {
402 assert(CalledDone &&
403 "LookupResult::Filter destroyed without done() call");
404 }
405#endif
406
407 bool hasNext() const {
408 return I != Results.Decls.size();
409 }
410
411 NamedDecl *next() {
412 assert(I < Results.Decls.size() && "next() called on empty filter");
413 return Results.Decls[I++];
414 }
415
416 /// Erase the last element returned from this iterator.
417 void erase() {
418 Results.Decls[--I] = Results.Decls.back();
419 Results.Decls.pop_back();
John McCallf7a1a742009-11-24 19:00:30 +0000420 Changed = true;
421 }
422
423 void replace(NamedDecl *D) {
424 Results.Decls[I-1] = D;
425 Changed = true;
John McCall68263142009-11-18 22:49:29 +0000426 }
427
428 void done() {
429#ifndef NDEBUG
430 assert(!CalledDone && "done() called twice");
431 CalledDone = true;
432#endif
433
John McCallf7a1a742009-11-24 19:00:30 +0000434 if (Changed)
John McCall68263142009-11-18 22:49:29 +0000435 Results.resolveKindAfterFilter();
436 }
437 };
438
439 /// Create a filter for this result set.
440 Filter makeFilter() {
441 return Filter(*this);
442 }
443
John McCall7d384dd2009-11-18 07:57:50 +0000444private:
445 void diagnose() {
446 if (isAmbiguous())
447 SemaRef.DiagnoseAmbiguousLookup(*this);
448 }
449
450 void setAmbiguous(AmbiguityKind AK) {
451 ResultKind = Ambiguous;
452 Ambiguity = AK;
453 }
454
455 void addDeclsFromBasePaths(const CXXBasePaths &P);
456
457 // Sanity checks.
458 void sanity() const {
459 assert(ResultKind != NotFound || Decls.size() == 0);
460 assert(ResultKind != Found || Decls.size() == 1);
John McCall7453ed42009-11-22 00:44:51 +0000461 assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
John McCall97d9e212009-11-22 20:57:36 +0000462 (Decls.size() == 1 &&
463 isa<FunctionTemplateDecl>(Decls[0]->getUnderlyingDecl())));
John McCall7453ed42009-11-22 00:44:51 +0000464 assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
465 assert(ResultKind != Ambiguous || Decls.size() > 1 ||
466 (Decls.size() == 1 && Ambiguity == AmbiguousBaseSubobjects));
John McCall7d384dd2009-11-18 07:57:50 +0000467 assert((Paths != NULL) == (ResultKind == Ambiguous &&
468 (Ambiguity == AmbiguousBaseSubobjectTypes ||
469 Ambiguity == AmbiguousBaseSubobjects)));
470 }
471
John McCall7453ed42009-11-22 00:44:51 +0000472 bool sanityCheckUnresolved() const {
473 for (DeclsTy::const_iterator I = Decls.begin(), E = Decls.end();
474 I != E; ++I)
475 if (isa<UnresolvedUsingValueDecl>(*I))
476 return true;
477 return false;
478 }
479
John McCall7d384dd2009-11-18 07:57:50 +0000480 static void deletePaths(CXXBasePaths *);
481
482 // Results.
483 LookupResultKind ResultKind;
484 AmbiguityKind Ambiguity; // ill-defined unless ambiguous
485 DeclsTy Decls;
486 CXXBasePaths *Paths;
487
488 // Parameters.
489 Sema &SemaRef;
490 DeclarationName Name;
491 SourceLocation NameLoc;
492 SourceRange NameContextRange;
493 Sema::LookupNameKind LookupKind;
494 unsigned IDNS; // ill-defined until set by lookup
495 bool Redecl;
496
497 /// \brief True if tag declarations should be hidden if non-tags
498 /// are present
499 bool HideTags;
500
501 bool Diagnose;
502};
503
504}
505
506#endif