clang API Documentation
00001 //===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the LookupResult class, which is integral to 00011 // Sema's name-lookup subsystem. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_SEMA_LOOKUP_H 00016 #define LLVM_CLANG_SEMA_LOOKUP_H 00017 00018 #include "clang/AST/DeclCXX.h" 00019 #include "clang/Sema/Sema.h" 00020 00021 namespace clang { 00022 00023 /// @brief Represents the results of name lookup. 00024 /// 00025 /// An instance of the LookupResult class captures the results of a 00026 /// single name lookup, which can return no result (nothing found), 00027 /// a single declaration, a set of overloaded functions, or an 00028 /// ambiguity. Use the getKind() method to determine which of these 00029 /// results occurred for a given lookup. 00030 class LookupResult { 00031 public: 00032 enum LookupResultKind { 00033 /// @brief No entity found met the criteria. 00034 NotFound = 0, 00035 00036 /// @brief No entity found met the criteria within the current 00037 /// instantiation,, but there were dependent base classes of the 00038 /// current instantiation that could not be searched. 00039 NotFoundInCurrentInstantiation, 00040 00041 /// @brief Name lookup found a single declaration that met the 00042 /// criteria. getFoundDecl() will return this declaration. 00043 Found, 00044 00045 /// @brief Name lookup found a set of overloaded functions that 00046 /// met the criteria. 00047 FoundOverloaded, 00048 00049 /// @brief Name lookup found an unresolvable value declaration 00050 /// and cannot yet complete. This only happens in C++ dependent 00051 /// contexts with dependent using declarations. 00052 FoundUnresolvedValue, 00053 00054 /// @brief Name lookup results in an ambiguity; use 00055 /// getAmbiguityKind to figure out what kind of ambiguity 00056 /// we have. 00057 Ambiguous 00058 }; 00059 00060 enum AmbiguityKind { 00061 /// Name lookup results in an ambiguity because multiple 00062 /// entities that meet the lookup criteria were found in 00063 /// subobjects of different types. For example: 00064 /// @code 00065 /// struct A { void f(int); } 00066 /// struct B { void f(double); } 00067 /// struct C : A, B { }; 00068 /// void test(C c) { 00069 /// c.f(0); // error: A::f and B::f come from subobjects of different 00070 /// // types. overload resolution is not performed. 00071 /// } 00072 /// @endcode 00073 AmbiguousBaseSubobjectTypes, 00074 00075 /// Name lookup results in an ambiguity because multiple 00076 /// nonstatic entities that meet the lookup criteria were found 00077 /// in different subobjects of the same type. For example: 00078 /// @code 00079 /// struct A { int x; }; 00080 /// struct B : A { }; 00081 /// struct C : A { }; 00082 /// struct D : B, C { }; 00083 /// int test(D d) { 00084 /// return d.x; // error: 'x' is found in two A subobjects (of B and C) 00085 /// } 00086 /// @endcode 00087 AmbiguousBaseSubobjects, 00088 00089 /// Name lookup results in an ambiguity because multiple definitions 00090 /// of entity that meet the lookup criteria were found in different 00091 /// declaration contexts. 00092 /// @code 00093 /// namespace A { 00094 /// int i; 00095 /// namespace B { int i; } 00096 /// int test() { 00097 /// using namespace B; 00098 /// return i; // error 'i' is found in namespace A and A::B 00099 /// } 00100 /// } 00101 /// @endcode 00102 AmbiguousReference, 00103 00104 /// Name lookup results in an ambiguity because an entity with a 00105 /// tag name was hidden by an entity with an ordinary name from 00106 /// a different context. 00107 /// @code 00108 /// namespace A { struct Foo {}; } 00109 /// namespace B { void Foo(); } 00110 /// namespace C { 00111 /// using namespace A; 00112 /// using namespace B; 00113 /// } 00114 /// void test() { 00115 /// C::Foo(); // error: tag 'A::Foo' is hidden by an object in a 00116 /// // different namespace 00117 /// } 00118 /// @endcode 00119 AmbiguousTagHiding 00120 }; 00121 00122 /// A little identifier for flagging temporary lookup results. 00123 enum TemporaryToken { 00124 Temporary 00125 }; 00126 00127 typedef UnresolvedSetImpl::iterator iterator; 00128 00129 LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo, 00130 Sema::LookupNameKind LookupKind, 00131 Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration) 00132 : ResultKind(NotFound), 00133 Paths(nullptr), 00134 NamingClass(nullptr), 00135 SemaPtr(&SemaRef), 00136 NameInfo(NameInfo), 00137 LookupKind(LookupKind), 00138 IDNS(0), 00139 Redecl(Redecl != Sema::NotForRedeclaration), 00140 HideTags(true), 00141 Diagnose(Redecl == Sema::NotForRedeclaration), 00142 AllowHidden(Redecl == Sema::ForRedeclaration), 00143 Shadowed(false) 00144 { 00145 configure(); 00146 } 00147 00148 // TODO: consider whether this constructor should be restricted to take 00149 // as input a const IndentifierInfo* (instead of Name), 00150 // forcing other cases towards the constructor taking a DNInfo. 00151 LookupResult(Sema &SemaRef, DeclarationName Name, 00152 SourceLocation NameLoc, Sema::LookupNameKind LookupKind, 00153 Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration) 00154 : ResultKind(NotFound), 00155 Paths(nullptr), 00156 NamingClass(nullptr), 00157 SemaPtr(&SemaRef), 00158 NameInfo(Name, NameLoc), 00159 LookupKind(LookupKind), 00160 IDNS(0), 00161 Redecl(Redecl != Sema::NotForRedeclaration), 00162 HideTags(true), 00163 Diagnose(Redecl == Sema::NotForRedeclaration), 00164 AllowHidden(Redecl == Sema::ForRedeclaration), 00165 Shadowed(false) 00166 { 00167 configure(); 00168 } 00169 00170 /// Creates a temporary lookup result, initializing its core data 00171 /// using the information from another result. Diagnostics are always 00172 /// disabled. 00173 LookupResult(TemporaryToken _, const LookupResult &Other) 00174 : ResultKind(NotFound), 00175 Paths(nullptr), 00176 NamingClass(nullptr), 00177 SemaPtr(Other.SemaPtr), 00178 NameInfo(Other.NameInfo), 00179 LookupKind(Other.LookupKind), 00180 IDNS(Other.IDNS), 00181 Redecl(Other.Redecl), 00182 HideTags(Other.HideTags), 00183 Diagnose(false), 00184 AllowHidden(Other.AllowHidden), 00185 Shadowed(false) 00186 {} 00187 00188 ~LookupResult() { 00189 if (Diagnose) diagnose(); 00190 if (Paths) deletePaths(Paths); 00191 } 00192 00193 /// Gets the name info to look up. 00194 const DeclarationNameInfo &getLookupNameInfo() const { 00195 return NameInfo; 00196 } 00197 00198 /// \brief Sets the name info to look up. 00199 void setLookupNameInfo(const DeclarationNameInfo &NameInfo) { 00200 this->NameInfo = NameInfo; 00201 } 00202 00203 /// Gets the name to look up. 00204 DeclarationName getLookupName() const { 00205 return NameInfo.getName(); 00206 } 00207 00208 /// \brief Sets the name to look up. 00209 void setLookupName(DeclarationName Name) { 00210 NameInfo.setName(Name); 00211 } 00212 00213 /// Gets the kind of lookup to perform. 00214 Sema::LookupNameKind getLookupKind() const { 00215 return LookupKind; 00216 } 00217 00218 /// True if this lookup is just looking for an existing declaration. 00219 bool isForRedeclaration() const { 00220 return Redecl; 00221 } 00222 00223 /// \brief Specify whether hidden declarations are visible, e.g., 00224 /// for recovery reasons. 00225 void setAllowHidden(bool AH) { 00226 AllowHidden = AH; 00227 } 00228 00229 /// \brief Determine whether this lookup is permitted to see hidden 00230 /// declarations, such as those in modules that have not yet been imported. 00231 bool isHiddenDeclarationVisible() const { 00232 return AllowHidden || LookupKind == Sema::LookupTagName; 00233 } 00234 00235 /// Sets whether tag declarations should be hidden by non-tag 00236 /// declarations during resolution. The default is true. 00237 void setHideTags(bool Hide) { 00238 HideTags = Hide; 00239 } 00240 00241 bool isAmbiguous() const { 00242 return getResultKind() == Ambiguous; 00243 } 00244 00245 /// Determines if this names a single result which is not an 00246 /// unresolved value using decl. If so, it is safe to call 00247 /// getFoundDecl(). 00248 bool isSingleResult() const { 00249 return getResultKind() == Found; 00250 } 00251 00252 /// Determines if the results are overloaded. 00253 bool isOverloadedResult() const { 00254 return getResultKind() == FoundOverloaded; 00255 } 00256 00257 bool isUnresolvableResult() const { 00258 return getResultKind() == FoundUnresolvedValue; 00259 } 00260 00261 LookupResultKind getResultKind() const { 00262 assert(sanity()); 00263 return ResultKind; 00264 } 00265 00266 AmbiguityKind getAmbiguityKind() const { 00267 assert(isAmbiguous()); 00268 return Ambiguity; 00269 } 00270 00271 const UnresolvedSetImpl &asUnresolvedSet() const { 00272 return Decls; 00273 } 00274 00275 iterator begin() const { return iterator(Decls.begin()); } 00276 iterator end() const { return iterator(Decls.end()); } 00277 00278 /// \brief Return true if no decls were found 00279 bool empty() const { return Decls.empty(); } 00280 00281 /// \brief Return the base paths structure that's associated with 00282 /// these results, or null if none is. 00283 CXXBasePaths *getBasePaths() const { 00284 return Paths; 00285 } 00286 00287 /// \brief Determine whether the given declaration is visible to the 00288 /// program. 00289 static bool isVisible(Sema &SemaRef, NamedDecl *D) { 00290 // If this declaration is not hidden, it's visible. 00291 if (!D->isHidden()) 00292 return true; 00293 00294 if (SemaRef.ActiveTemplateInstantiations.empty()) 00295 return false; 00296 00297 // During template instantiation, we can refer to hidden declarations, if 00298 // they were visible in any module along the path of instantiation. 00299 return isVisibleSlow(SemaRef, D); 00300 } 00301 00302 /// \brief Retrieve the accepted (re)declaration of the given declaration, 00303 /// if there is one. 00304 NamedDecl *getAcceptableDecl(NamedDecl *D) const { 00305 if (!D->isInIdentifierNamespace(IDNS)) 00306 return nullptr; 00307 00308 if (isHiddenDeclarationVisible() || isVisible(getSema(), D)) 00309 return D; 00310 00311 return getAcceptableDeclSlow(D); 00312 } 00313 00314 private: 00315 static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D); 00316 NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const; 00317 00318 public: 00319 /// \brief Returns the identifier namespace mask for this lookup. 00320 unsigned getIdentifierNamespace() const { 00321 return IDNS; 00322 } 00323 00324 /// \brief Returns whether these results arose from performing a 00325 /// lookup into a class. 00326 bool isClassLookup() const { 00327 return NamingClass != nullptr; 00328 } 00329 00330 /// \brief Returns the 'naming class' for this lookup, i.e. the 00331 /// class which was looked into to find these results. 00332 /// 00333 /// C++0x [class.access.base]p5: 00334 /// The access to a member is affected by the class in which the 00335 /// member is named. This naming class is the class in which the 00336 /// member name was looked up and found. [Note: this class can be 00337 /// explicit, e.g., when a qualified-id is used, or implicit, 00338 /// e.g., when a class member access operator (5.2.5) is used 00339 /// (including cases where an implicit "this->" is added). If both 00340 /// a class member access operator and a qualified-id are used to 00341 /// name the member (as in p->T::m), the class naming the member 00342 /// is the class named by the nested-name-specifier of the 00343 /// qualified-id (that is, T). -- end note ] 00344 /// 00345 /// This is set by the lookup routines when they find results in a class. 00346 CXXRecordDecl *getNamingClass() const { 00347 return NamingClass; 00348 } 00349 00350 /// \brief Sets the 'naming class' for this lookup. 00351 void setNamingClass(CXXRecordDecl *Record) { 00352 NamingClass = Record; 00353 } 00354 00355 /// \brief Returns the base object type associated with this lookup; 00356 /// important for [class.protected]. Most lookups do not have an 00357 /// associated base object. 00358 QualType getBaseObjectType() const { 00359 return BaseObjectType; 00360 } 00361 00362 /// \brief Sets the base object type for this lookup. 00363 void setBaseObjectType(QualType T) { 00364 BaseObjectType = T; 00365 } 00366 00367 /// \brief Add a declaration to these results with its natural access. 00368 /// Does not test the acceptance criteria. 00369 void addDecl(NamedDecl *D) { 00370 addDecl(D, D->getAccess()); 00371 } 00372 00373 /// \brief Add a declaration to these results with the given access. 00374 /// Does not test the acceptance criteria. 00375 void addDecl(NamedDecl *D, AccessSpecifier AS) { 00376 Decls.addDecl(D, AS); 00377 ResultKind = Found; 00378 } 00379 00380 /// \brief Add all the declarations from another set of lookup 00381 /// results. 00382 void addAllDecls(const LookupResult &Other) { 00383 Decls.append(Other.Decls.begin(), Other.Decls.end()); 00384 ResultKind = Found; 00385 } 00386 00387 /// \brief Determine whether no result was found because we could not 00388 /// search into dependent base classes of the current instantiation. 00389 bool wasNotFoundInCurrentInstantiation() const { 00390 return ResultKind == NotFoundInCurrentInstantiation; 00391 } 00392 00393 /// \brief Note that while no result was found in the current instantiation, 00394 /// there were dependent base classes that could not be searched. 00395 void setNotFoundInCurrentInstantiation() { 00396 assert(ResultKind == NotFound && Decls.empty()); 00397 ResultKind = NotFoundInCurrentInstantiation; 00398 } 00399 00400 /// \brief Determine whether the lookup result was shadowed by some other 00401 /// declaration that lookup ignored. 00402 bool isShadowed() const { return Shadowed; } 00403 00404 /// \brief Note that we found and ignored a declaration while performing 00405 /// lookup. 00406 void setShadowed() { Shadowed = true; } 00407 00408 /// \brief Resolves the result kind of the lookup, possibly hiding 00409 /// decls. 00410 /// 00411 /// This should be called in any environment where lookup might 00412 /// generate multiple lookup results. 00413 void resolveKind(); 00414 00415 /// \brief Re-resolves the result kind of the lookup after a set of 00416 /// removals has been performed. 00417 void resolveKindAfterFilter() { 00418 if (Decls.empty()) { 00419 if (ResultKind != NotFoundInCurrentInstantiation) 00420 ResultKind = NotFound; 00421 00422 if (Paths) { 00423 deletePaths(Paths); 00424 Paths = nullptr; 00425 } 00426 } else { 00427 AmbiguityKind SavedAK; 00428 bool WasAmbiguous = false; 00429 if (ResultKind == Ambiguous) { 00430 SavedAK = Ambiguity; 00431 WasAmbiguous = true; 00432 } 00433 ResultKind = Found; 00434 resolveKind(); 00435 00436 // If we didn't make the lookup unambiguous, restore the old 00437 // ambiguity kind. 00438 if (ResultKind == Ambiguous) { 00439 (void)WasAmbiguous; 00440 assert(WasAmbiguous); 00441 Ambiguity = SavedAK; 00442 } else if (Paths) { 00443 deletePaths(Paths); 00444 Paths = nullptr; 00445 } 00446 } 00447 } 00448 00449 template <class DeclClass> 00450 DeclClass *getAsSingle() const { 00451 if (getResultKind() != Found) return nullptr; 00452 return dyn_cast<DeclClass>(getFoundDecl()); 00453 } 00454 00455 /// \brief Fetch the unique decl found by this lookup. Asserts 00456 /// that one was found. 00457 /// 00458 /// This is intended for users who have examined the result kind 00459 /// and are certain that there is only one result. 00460 NamedDecl *getFoundDecl() const { 00461 assert(getResultKind() == Found 00462 && "getFoundDecl called on non-unique result"); 00463 return (*begin())->getUnderlyingDecl(); 00464 } 00465 00466 /// Fetches a representative decl. Useful for lazy diagnostics. 00467 NamedDecl *getRepresentativeDecl() const { 00468 assert(!Decls.empty() && "cannot get representative of empty set"); 00469 return *begin(); 00470 } 00471 00472 /// \brief Asks if the result is a single tag decl. 00473 bool isSingleTagDecl() const { 00474 return getResultKind() == Found && isa<TagDecl>(getFoundDecl()); 00475 } 00476 00477 /// \brief Make these results show that the name was found in 00478 /// base classes of different types. 00479 /// 00480 /// The given paths object is copied and invalidated. 00481 void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P); 00482 00483 /// \brief Make these results show that the name was found in 00484 /// distinct base classes of the same type. 00485 /// 00486 /// The given paths object is copied and invalidated. 00487 void setAmbiguousBaseSubobjects(CXXBasePaths &P); 00488 00489 /// \brief Make these results show that the name was found in 00490 /// different contexts and a tag decl was hidden by an ordinary 00491 /// decl in a different context. 00492 void setAmbiguousQualifiedTagHiding() { 00493 setAmbiguous(AmbiguousTagHiding); 00494 } 00495 00496 /// \brief Clears out any current state. 00497 void clear() { 00498 ResultKind = NotFound; 00499 Decls.clear(); 00500 if (Paths) deletePaths(Paths); 00501 Paths = nullptr; 00502 NamingClass = nullptr; 00503 Shadowed = false; 00504 } 00505 00506 /// \brief Clears out any current state and re-initializes for a 00507 /// different kind of lookup. 00508 void clear(Sema::LookupNameKind Kind) { 00509 clear(); 00510 LookupKind = Kind; 00511 configure(); 00512 } 00513 00514 /// \brief Change this lookup's redeclaration kind. 00515 void setRedeclarationKind(Sema::RedeclarationKind RK) { 00516 Redecl = RK; 00517 AllowHidden = (RK == Sema::ForRedeclaration); 00518 configure(); 00519 } 00520 00521 void print(raw_ostream &); 00522 00523 /// Suppress the diagnostics that would normally fire because of this 00524 /// lookup. This happens during (e.g.) redeclaration lookups. 00525 void suppressDiagnostics() { 00526 Diagnose = false; 00527 } 00528 00529 /// Determines whether this lookup is suppressing diagnostics. 00530 bool isSuppressingDiagnostics() const { 00531 return !Diagnose; 00532 } 00533 00534 /// Sets a 'context' source range. 00535 void setContextRange(SourceRange SR) { 00536 NameContextRange = SR; 00537 } 00538 00539 /// Gets the source range of the context of this name; for C++ 00540 /// qualified lookups, this is the source range of the scope 00541 /// specifier. 00542 SourceRange getContextRange() const { 00543 return NameContextRange; 00544 } 00545 00546 /// Gets the location of the identifier. This isn't always defined: 00547 /// sometimes we're doing lookups on synthesized names. 00548 SourceLocation getNameLoc() const { 00549 return NameInfo.getLoc(); 00550 } 00551 00552 /// \brief Get the Sema object that this lookup result is searching 00553 /// with. 00554 Sema &getSema() const { return *SemaPtr; } 00555 00556 /// A class for iterating through a result set and possibly 00557 /// filtering out results. The results returned are possibly 00558 /// sugared. 00559 class Filter { 00560 LookupResult &Results; 00561 LookupResult::iterator I; 00562 bool Changed; 00563 bool CalledDone; 00564 00565 friend class LookupResult; 00566 Filter(LookupResult &Results) 00567 : Results(Results), I(Results.begin()), Changed(false), CalledDone(false) 00568 {} 00569 00570 public: 00571 ~Filter() { 00572 assert(CalledDone && 00573 "LookupResult::Filter destroyed without done() call"); 00574 } 00575 00576 bool hasNext() const { 00577 return I != Results.end(); 00578 } 00579 00580 NamedDecl *next() { 00581 assert(I != Results.end() && "next() called on empty filter"); 00582 return *I++; 00583 } 00584 00585 /// Restart the iteration. 00586 void restart() { 00587 I = Results.begin(); 00588 } 00589 00590 /// Erase the last element returned from this iterator. 00591 void erase() { 00592 Results.Decls.erase(--I); 00593 Changed = true; 00594 } 00595 00596 /// Replaces the current entry with the given one, preserving the 00597 /// access bits. 00598 void replace(NamedDecl *D) { 00599 Results.Decls.replace(I-1, D); 00600 Changed = true; 00601 } 00602 00603 /// Replaces the current entry with the given one. 00604 void replace(NamedDecl *D, AccessSpecifier AS) { 00605 Results.Decls.replace(I-1, D, AS); 00606 Changed = true; 00607 } 00608 00609 void done() { 00610 assert(!CalledDone && "done() called twice"); 00611 CalledDone = true; 00612 00613 if (Changed) 00614 Results.resolveKindAfterFilter(); 00615 } 00616 }; 00617 00618 /// Create a filter for this result set. 00619 Filter makeFilter() { 00620 return Filter(*this); 00621 } 00622 00623 void setFindLocalExtern(bool FindLocalExtern) { 00624 if (FindLocalExtern) 00625 IDNS |= Decl::IDNS_LocalExtern; 00626 else 00627 IDNS &= ~Decl::IDNS_LocalExtern; 00628 } 00629 00630 private: 00631 void diagnose() { 00632 if (isAmbiguous()) 00633 getSema().DiagnoseAmbiguousLookup(*this); 00634 else if (isClassLookup() && getSema().getLangOpts().AccessControl) 00635 getSema().CheckLookupAccess(*this); 00636 } 00637 00638 void setAmbiguous(AmbiguityKind AK) { 00639 ResultKind = Ambiguous; 00640 Ambiguity = AK; 00641 } 00642 00643 void addDeclsFromBasePaths(const CXXBasePaths &P); 00644 void configure(); 00645 00646 // Sanity checks. 00647 bool sanity() const; 00648 00649 bool sanityCheckUnresolved() const { 00650 for (iterator I = begin(), E = end(); I != E; ++I) 00651 if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl())) 00652 return true; 00653 return false; 00654 } 00655 00656 static void deletePaths(CXXBasePaths *); 00657 00658 // Results. 00659 LookupResultKind ResultKind; 00660 AmbiguityKind Ambiguity; // ill-defined unless ambiguous 00661 UnresolvedSet<8> Decls; 00662 CXXBasePaths *Paths; 00663 CXXRecordDecl *NamingClass; 00664 QualType BaseObjectType; 00665 00666 // Parameters. 00667 Sema *SemaPtr; 00668 DeclarationNameInfo NameInfo; 00669 SourceRange NameContextRange; 00670 Sema::LookupNameKind LookupKind; 00671 unsigned IDNS; // set by configure() 00672 00673 bool Redecl; 00674 00675 /// \brief True if tag declarations should be hidden if non-tags 00676 /// are present 00677 bool HideTags; 00678 00679 bool Diagnose; 00680 00681 /// \brief True if we should allow hidden declarations to be 'visible'. 00682 bool AllowHidden; 00683 00684 /// \brief True if the found declarations were shadowed by some other 00685 /// declaration that we skipped. This only happens when \c LookupKind 00686 /// is \c LookupRedeclarationWithLinkage. 00687 bool Shadowed; 00688 }; 00689 00690 /// \brief Consumes visible declarations found when searching for 00691 /// all visible names within a given scope or context. 00692 /// 00693 /// This abstract class is meant to be subclassed by clients of \c 00694 /// Sema::LookupVisibleDecls(), each of which should override the \c 00695 /// FoundDecl() function to process declarations as they are found. 00696 class VisibleDeclConsumer { 00697 public: 00698 /// \brief Destroys the visible declaration consumer. 00699 virtual ~VisibleDeclConsumer(); 00700 00701 /// \brief Determine whether hidden declarations (from unimported 00702 /// modules) should be given to this consumer. By default, they 00703 /// are not included. 00704 virtual bool includeHiddenDecls() const; 00705 00706 /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a 00707 /// declaration visible from the current scope or context. 00708 /// 00709 /// \param ND the declaration found. 00710 /// 00711 /// \param Hiding a declaration that hides the declaration \p ND, 00712 /// or NULL if no such declaration exists. 00713 /// 00714 /// \param Ctx the original context from which the lookup started. 00715 /// 00716 /// \param InBaseClass whether this declaration was found in base 00717 /// class of the context we searched. 00718 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, 00719 bool InBaseClass) = 0; 00720 }; 00721 00722 /// \brief A class for storing results from argument-dependent lookup. 00723 class ADLResult { 00724 private: 00725 /// A map from canonical decls to the 'most recent' decl. 00726 llvm::DenseMap<NamedDecl*, NamedDecl*> Decls; 00727 00728 public: 00729 /// Adds a new ADL candidate to this map. 00730 void insert(NamedDecl *D); 00731 00732 /// Removes any data associated with a given decl. 00733 void erase(NamedDecl *D) { 00734 Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); 00735 } 00736 00737 class iterator 00738 : public std::iterator<std::forward_iterator_tag, NamedDecl *> { 00739 typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator; 00740 inner_iterator iter; 00741 00742 friend class ADLResult; 00743 iterator(const inner_iterator &iter) : iter(iter) {} 00744 public: 00745 iterator() {} 00746 00747 iterator &operator++() { ++iter; return *this; } 00748 iterator operator++(int) { return iterator(iter++); } 00749 00750 value_type operator*() const { return iter->second; } 00751 00752 bool operator==(const iterator &other) const { return iter == other.iter; } 00753 bool operator!=(const iterator &other) const { return iter != other.iter; } 00754 }; 00755 00756 iterator begin() { return iterator(Decls.begin()); } 00757 iterator end() { return iterator(Decls.end()); } 00758 }; 00759 00760 } 00761 00762 #endif