blob: c7b574fd66171428a3679cbe07307355f8239df3 [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 McCall7d384dd2009-11-18 07:57:50 +0000216 LookupResultKind getResultKind() const {
217 sanity();
218 return ResultKind;
219 }
220
221 AmbiguityKind getAmbiguityKind() const {
222 assert(isAmbiguous());
223 return Ambiguity;
224 }
225
226 iterator begin() const { return Decls.begin(); }
227 iterator end() const { return Decls.end(); }
228
229 /// \brief Return true if no decls were found
230 bool empty() const { return Decls.empty(); }
231
232 /// \brief Return the base paths structure that's associated with
233 /// these results, or null if none is.
234 CXXBasePaths *getBasePaths() const {
235 return Paths;
236 }
237
238 /// \brief Add a declaration to these results.
239 void addDecl(NamedDecl *D) {
240 Decls.push_back(D);
241 ResultKind = Found;
242 }
243
244 /// \brief Add all the declarations from another set of lookup
245 /// results.
246 void addAllDecls(const LookupResult &Other) {
247 Decls.append(Other.begin(), Other.end());
248 ResultKind = Found;
249 }
250
251 /// \brief Hides a set of declarations.
252 template <class NamedDeclSet> void hideDecls(const NamedDeclSet &Set) {
253 unsigned I = 0, N = Decls.size();
254 while (I < N) {
255 if (Set.count(Decls[I]))
256 Decls[I] = Decls[--N];
257 else
258 I++;
259 }
260 Decls.set_size(N);
261 }
262
John McCall68263142009-11-18 22:49:29 +0000263 /// \brief Resolves the result kind of the lookup, possibly hiding
264 /// decls.
John McCall7d384dd2009-11-18 07:57:50 +0000265 ///
266 /// This should be called in any environment where lookup might
267 /// generate multiple lookup results.
268 void resolveKind();
269
John McCall68263142009-11-18 22:49:29 +0000270 /// \brief Re-resolves the result kind of the lookup after a set of
271 /// removals has been performed.
272 void resolveKindAfterFilter() {
273 if (Decls.empty())
274 ResultKind = NotFound;
275 else {
276 ResultKind = Found;
277 resolveKind();
278 }
279 }
280
John McCall7d384dd2009-11-18 07:57:50 +0000281 /// \brief Fetch this as an unambiguous single declaration
282 /// (possibly an overloaded one).
283 ///
284 /// This is deprecated; users should be written to handle
285 /// ambiguous and overloaded lookups.
286 NamedDecl *getAsSingleDecl(ASTContext &Context) const;
287
John McCallba135432009-11-21 08:51:07 +0000288 template <class DeclClass>
289 DeclClass *getAsSingle() const {
290 if (getResultKind() != Found) return 0;
291 return dyn_cast<DeclClass>(getFoundDecl());
292 }
293
John McCall7d384dd2009-11-18 07:57:50 +0000294 /// \brief Fetch the unique decl found by this lookup. Asserts
295 /// that one was found.
296 ///
297 /// This is intended for users who have examined the result kind
298 /// and are certain that there is only one result.
299 NamedDecl *getFoundDecl() const {
300 assert(getResultKind() == Found
301 && "getFoundDecl called on non-unique result");
302 return Decls[0]->getUnderlyingDecl();
303 }
304
John McCall68263142009-11-18 22:49:29 +0000305 /// Fetches a representative decl. Useful for lazy diagnostics.
306 NamedDecl *getRepresentativeDecl() const {
307 assert(!Decls.empty() && "cannot get representative of empty set");
308 return Decls[0];
309 }
310
John McCall7d384dd2009-11-18 07:57:50 +0000311 /// \brief Asks if the result is a single tag decl.
312 bool isSingleTagDecl() const {
313 return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
314 }
315
316 /// \brief Make these results show that the name was found in
317 /// base classes of different types.
318 ///
319 /// The given paths object is copied and invalidated.
320 void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
321
322 /// \brief Make these results show that the name was found in
323 /// distinct base classes of the same type.
324 ///
325 /// The given paths object is copied and invalidated.
326 void setAmbiguousBaseSubobjects(CXXBasePaths &P);
327
328 /// \brief Make these results show that the name was found in
329 /// different contexts and a tag decl was hidden by an ordinary
330 /// decl in a different context.
331 void setAmbiguousQualifiedTagHiding() {
332 setAmbiguous(AmbiguousTagHiding);
333 }
334
335 /// \brief Clears out any current state.
336 void clear() {
337 ResultKind = NotFound;
338 Decls.clear();
339 if (Paths) deletePaths(Paths);
340 Paths = NULL;
341 }
342
343 /// \brief Clears out any current state and re-initializes for a
344 /// different kind of lookup.
345 void clear(Sema::LookupNameKind Kind) {
346 clear();
347 LookupKind = Kind;
348 }
349
350 void print(llvm::raw_ostream &);
351
352 /// Suppress the diagnostics that would normally fire because of this
353 /// lookup. This happens during (e.g.) redeclaration lookups.
354 void suppressDiagnostics() {
355 Diagnose = false;
356 }
357
358 /// Sets a 'context' source range.
359 void setContextRange(SourceRange SR) {
360 NameContextRange = SR;
361 }
362
363 /// Gets the source range of the context of this name; for C++
364 /// qualified lookups, this is the source range of the scope
365 /// specifier.
366 SourceRange getContextRange() const {
367 return NameContextRange;
368 }
369
370 /// Gets the location of the identifier. This isn't always defined:
371 /// sometimes we're doing lookups on synthesized names.
372 SourceLocation getNameLoc() const {
373 return NameLoc;
374 }
375
John McCall68263142009-11-18 22:49:29 +0000376 /// A class for iterating through a result set and possibly
377 /// filtering out results. The results returned are possibly
378 /// sugared.
379 class Filter {
380 LookupResult &Results;
381 unsigned I;
John McCallf7a1a742009-11-24 19:00:30 +0000382 bool Changed;
John McCall68263142009-11-18 22:49:29 +0000383#ifndef NDEBUG
384 bool CalledDone;
385#endif
386
387 friend class LookupResult;
388 Filter(LookupResult &Results)
John McCallf7a1a742009-11-24 19:00:30 +0000389 : Results(Results), I(0), Changed(false)
John McCall68263142009-11-18 22:49:29 +0000390#ifndef NDEBUG
391 , CalledDone(false)
392#endif
393 {}
394
395 public:
396#ifndef NDEBUG
397 ~Filter() {
398 assert(CalledDone &&
399 "LookupResult::Filter destroyed without done() call");
400 }
401#endif
402
403 bool hasNext() const {
404 return I != Results.Decls.size();
405 }
406
407 NamedDecl *next() {
408 assert(I < Results.Decls.size() && "next() called on empty filter");
409 return Results.Decls[I++];
410 }
411
412 /// Erase the last element returned from this iterator.
413 void erase() {
414 Results.Decls[--I] = Results.Decls.back();
415 Results.Decls.pop_back();
John McCallf7a1a742009-11-24 19:00:30 +0000416 Changed = true;
417 }
418
419 void replace(NamedDecl *D) {
420 Results.Decls[I-1] = D;
421 Changed = true;
John McCall68263142009-11-18 22:49:29 +0000422 }
423
424 void done() {
425#ifndef NDEBUG
426 assert(!CalledDone && "done() called twice");
427 CalledDone = true;
428#endif
429
John McCallf7a1a742009-11-24 19:00:30 +0000430 if (Changed)
John McCall68263142009-11-18 22:49:29 +0000431 Results.resolveKindAfterFilter();
432 }
433 };
434
435 /// Create a filter for this result set.
436 Filter makeFilter() {
437 return Filter(*this);
438 }
439
John McCall7d384dd2009-11-18 07:57:50 +0000440private:
441 void diagnose() {
442 if (isAmbiguous())
443 SemaRef.DiagnoseAmbiguousLookup(*this);
444 }
445
446 void setAmbiguous(AmbiguityKind AK) {
447 ResultKind = Ambiguous;
448 Ambiguity = AK;
449 }
450
451 void addDeclsFromBasePaths(const CXXBasePaths &P);
452
453 // Sanity checks.
454 void sanity() const {
455 assert(ResultKind != NotFound || Decls.size() == 0);
456 assert(ResultKind != Found || Decls.size() == 1);
John McCall7453ed42009-11-22 00:44:51 +0000457 assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
John McCall97d9e212009-11-22 20:57:36 +0000458 (Decls.size() == 1 &&
459 isa<FunctionTemplateDecl>(Decls[0]->getUnderlyingDecl())));
John McCall7453ed42009-11-22 00:44:51 +0000460 assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
461 assert(ResultKind != Ambiguous || Decls.size() > 1 ||
462 (Decls.size() == 1 && Ambiguity == AmbiguousBaseSubobjects));
John McCall7d384dd2009-11-18 07:57:50 +0000463 assert((Paths != NULL) == (ResultKind == Ambiguous &&
464 (Ambiguity == AmbiguousBaseSubobjectTypes ||
465 Ambiguity == AmbiguousBaseSubobjects)));
466 }
467
John McCall7453ed42009-11-22 00:44:51 +0000468 bool sanityCheckUnresolved() const {
469 for (DeclsTy::const_iterator I = Decls.begin(), E = Decls.end();
470 I != E; ++I)
471 if (isa<UnresolvedUsingValueDecl>(*I))
472 return true;
473 return false;
474 }
475
John McCall7d384dd2009-11-18 07:57:50 +0000476 static void deletePaths(CXXBasePaths *);
477
478 // Results.
479 LookupResultKind ResultKind;
480 AmbiguityKind Ambiguity; // ill-defined unless ambiguous
481 DeclsTy Decls;
482 CXXBasePaths *Paths;
483
484 // Parameters.
485 Sema &SemaRef;
486 DeclarationName Name;
487 SourceLocation NameLoc;
488 SourceRange NameContextRange;
489 Sema::LookupNameKind LookupKind;
490 unsigned IDNS; // ill-defined until set by lookup
491 bool Redecl;
492
493 /// \brief True if tag declarations should be hidden if non-tags
494 /// are present
495 bool HideTags;
496
497 bool Diagnose;
498};
499
500}
501
502#endif