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 "clang/AST/Decl.h" 19 #include "clang/AST/DeclBase.h" 20 #include "clang/AST/DeclCXX.h" 21 #include "clang/AST/DeclarationName.h" 22 #include "clang/AST/Type.h" 23 #include "clang/AST/UnresolvedSet.h" 24 #include "clang/Basic/LLVM.h" 25 #include "clang/Basic/LangOptions.h" 26 #include "clang/Basic/SourceLocation.h" 27 #include "clang/Basic/Specifiers.h" 28 #include "clang/Sema/Sema.h" 29 #include "llvm/ADT/MapVector.h" 30 #include "llvm/ADT/Optional.h" 31 #include "llvm/ADT/STLExtras.h" 32 #include "llvm/Support/Casting.h" 33 #include <cassert> 34 #include <utility> 35 36 namespace clang { 37 38 class CXXBasePaths; 39 40 /// Represents the results of name lookup. 41 /// 42 /// An instance of the LookupResult class captures the results of a 43 /// single name lookup, which can return no result (nothing found), 44 /// a single declaration, a set of overloaded functions, or an 45 /// ambiguity. Use the getKind() method to determine which of these 46 /// results occurred for a given lookup. 47 class LookupResult { 48 public: 49 enum LookupResultKind { 50 /// No entity found met the criteria. 51 NotFound = 0, 52 53 /// No entity found met the criteria within the current 54 /// instantiation,, but there were dependent base classes of the 55 /// current instantiation that could not be searched. 56 NotFoundInCurrentInstantiation, 57 58 /// Name lookup found a single declaration that met the 59 /// criteria. getFoundDecl() will return this declaration. 60 Found, 61 62 /// Name lookup found a set of overloaded functions that 63 /// met the criteria. 64 FoundOverloaded, 65 66 /// Name lookup found an unresolvable value declaration 67 /// and cannot yet complete. This only happens in C++ dependent 68 /// contexts with dependent using declarations. 69 FoundUnresolvedValue, 70 71 /// Name lookup results in an ambiguity; use 72 /// getAmbiguityKind to figure out what kind of ambiguity 73 /// we have. 74 Ambiguous 75 }; 76 77 enum AmbiguityKind { 78 /// Name lookup results in an ambiguity because multiple 79 /// entities that meet the lookup criteria were found in 80 /// subobjects of different types. For example: 81 /// @code 82 /// struct A { void f(int); } 83 /// struct B { void f(double); } 84 /// struct C : A, B { }; 85 /// void test(C c) { 86 /// c.f(0); // error: A::f and B::f come from subobjects of different 87 /// // types. overload resolution is not performed. 88 /// } 89 /// @endcode 90 AmbiguousBaseSubobjectTypes, 91 92 /// Name lookup results in an ambiguity because multiple 93 /// nonstatic entities that meet the lookup criteria were found 94 /// in different subobjects of the same type. For example: 95 /// @code 96 /// struct A { int x; }; 97 /// struct B : A { }; 98 /// struct C : A { }; 99 /// struct D : B, C { }; 100 /// int test(D d) { 101 /// return d.x; // error: 'x' is found in two A subobjects (of B and C) 102 /// } 103 /// @endcode 104 AmbiguousBaseSubobjects, 105 106 /// Name lookup results in an ambiguity because multiple definitions 107 /// of entity that meet the lookup criteria were found in different 108 /// declaration contexts. 109 /// @code 110 /// namespace A { 111 /// int i; 112 /// namespace B { int i; } 113 /// int test() { 114 /// using namespace B; 115 /// return i; // error 'i' is found in namespace A and A::B 116 /// } 117 /// } 118 /// @endcode 119 AmbiguousReference, 120 121 /// Name lookup results in an ambiguity because an entity with a 122 /// tag name was hidden by an entity with an ordinary name from 123 /// a different context. 124 /// @code 125 /// namespace A { struct Foo {}; } 126 /// namespace B { void Foo(); } 127 /// namespace C { 128 /// using namespace A; 129 /// using namespace B; 130 /// } 131 /// void test() { 132 /// C::Foo(); // error: tag 'A::Foo' is hidden by an object in a 133 /// // different namespace 134 /// } 135 /// @endcode 136 AmbiguousTagHiding 137 }; 138 139 /// A little identifier for flagging temporary lookup results. 140 enum TemporaryToken { 141 Temporary 142 }; 143 144 using iterator = UnresolvedSetImpl::iterator; 145 146 LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo, 147 Sema::LookupNameKind LookupKind, 148 Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration) 149 : SemaPtr(&SemaRef), NameInfo(NameInfo), LookupKind(LookupKind), 150 Redecl(Redecl != Sema::NotForRedeclaration), 151 ExternalRedecl(Redecl == Sema::ForExternalRedeclaration), 152 Diagnose(Redecl == Sema::NotForRedeclaration) { 153 configure(); 154 } 155 156 // TODO: consider whether this constructor should be restricted to take 157 // as input a const IdentifierInfo* (instead of Name), 158 // forcing other cases towards the constructor taking a DNInfo. 159 LookupResult(Sema &SemaRef, DeclarationName Name, 160 SourceLocation NameLoc, Sema::LookupNameKind LookupKind, 161 Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration) 162 : SemaPtr(&SemaRef), NameInfo(Name, NameLoc), LookupKind(LookupKind), 163 Redecl(Redecl != Sema::NotForRedeclaration), 164 ExternalRedecl(Redecl == Sema::ForExternalRedeclaration), 165 Diagnose(Redecl == Sema::NotForRedeclaration) { 166 configure(); 167 } 168 169 /// Creates a temporary lookup result, initializing its core data 170 /// using the information from another result. Diagnostics are always 171 /// disabled. LookupResult(TemporaryToken _,const LookupResult & Other)172 LookupResult(TemporaryToken _, const LookupResult &Other) 173 : SemaPtr(Other.SemaPtr), NameInfo(Other.NameInfo), 174 LookupKind(Other.LookupKind), IDNS(Other.IDNS), Redecl(Other.Redecl), 175 ExternalRedecl(Other.ExternalRedecl), HideTags(Other.HideTags), 176 AllowHidden(Other.AllowHidden) {} 177 178 // FIXME: Remove these deleted methods once the default build includes 179 // -Wdeprecated. 180 LookupResult(const LookupResult &) = delete; 181 LookupResult &operator=(const LookupResult &) = delete; 182 LookupResult(LookupResult && Other)183 LookupResult(LookupResult &&Other) 184 : ResultKind(std::move(Other.ResultKind)), 185 Ambiguity(std::move(Other.Ambiguity)), Decls(std::move(Other.Decls)), 186 Paths(std::move(Other.Paths)), 187 NamingClass(std::move(Other.NamingClass)), 188 BaseObjectType(std::move(Other.BaseObjectType)), 189 SemaPtr(std::move(Other.SemaPtr)), NameInfo(std::move(Other.NameInfo)), 190 NameContextRange(std::move(Other.NameContextRange)), 191 LookupKind(std::move(Other.LookupKind)), IDNS(std::move(Other.IDNS)), 192 Redecl(std::move(Other.Redecl)), 193 ExternalRedecl(std::move(Other.ExternalRedecl)), 194 HideTags(std::move(Other.HideTags)), 195 Diagnose(std::move(Other.Diagnose)), 196 AllowHidden(std::move(Other.AllowHidden)), 197 Shadowed(std::move(Other.Shadowed)) { 198 Other.Paths = nullptr; 199 Other.Diagnose = false; 200 } 201 202 LookupResult &operator=(LookupResult &&Other) { 203 ResultKind = std::move(Other.ResultKind); 204 Ambiguity = std::move(Other.Ambiguity); 205 Decls = std::move(Other.Decls); 206 Paths = std::move(Other.Paths); 207 NamingClass = std::move(Other.NamingClass); 208 BaseObjectType = std::move(Other.BaseObjectType); 209 SemaPtr = std::move(Other.SemaPtr); 210 NameInfo = std::move(Other.NameInfo); 211 NameContextRange = std::move(Other.NameContextRange); 212 LookupKind = std::move(Other.LookupKind); 213 IDNS = std::move(Other.IDNS); 214 Redecl = std::move(Other.Redecl); 215 ExternalRedecl = std::move(Other.ExternalRedecl); 216 HideTags = std::move(Other.HideTags); 217 Diagnose = std::move(Other.Diagnose); 218 AllowHidden = std::move(Other.AllowHidden); 219 Shadowed = std::move(Other.Shadowed); 220 Other.Paths = nullptr; 221 Other.Diagnose = false; 222 return *this; 223 } 224 ~LookupResult()225 ~LookupResult() { 226 if (Diagnose) diagnose(); 227 if (Paths) deletePaths(Paths); 228 } 229 230 /// Gets the name info to look up. getLookupNameInfo()231 const DeclarationNameInfo &getLookupNameInfo() const { 232 return NameInfo; 233 } 234 235 /// Sets the name info to look up. setLookupNameInfo(const DeclarationNameInfo & NameInfo)236 void setLookupNameInfo(const DeclarationNameInfo &NameInfo) { 237 this->NameInfo = NameInfo; 238 } 239 240 /// Gets the name to look up. getLookupName()241 DeclarationName getLookupName() const { 242 return NameInfo.getName(); 243 } 244 245 /// Sets the name to look up. setLookupName(DeclarationName Name)246 void setLookupName(DeclarationName Name) { 247 NameInfo.setName(Name); 248 } 249 250 /// Gets the kind of lookup to perform. getLookupKind()251 Sema::LookupNameKind getLookupKind() const { 252 return LookupKind; 253 } 254 255 /// True if this lookup is just looking for an existing declaration. isForRedeclaration()256 bool isForRedeclaration() const { 257 return Redecl; 258 } 259 260 /// True if this lookup is just looking for an existing declaration to link 261 /// against a declaration with external linkage. isForExternalRedeclaration()262 bool isForExternalRedeclaration() const { 263 return ExternalRedecl; 264 } 265 redeclarationKind()266 Sema::RedeclarationKind redeclarationKind() const { 267 return ExternalRedecl ? Sema::ForExternalRedeclaration : 268 Redecl ? Sema::ForVisibleRedeclaration : Sema::NotForRedeclaration; 269 } 270 271 /// Specify whether hidden declarations are visible, e.g., 272 /// for recovery reasons. setAllowHidden(bool AH)273 void setAllowHidden(bool AH) { 274 AllowHidden = AH; 275 } 276 277 /// Determine whether this lookup is permitted to see hidden 278 /// declarations, such as those in modules that have not yet been imported. isHiddenDeclarationVisible(NamedDecl * ND)279 bool isHiddenDeclarationVisible(NamedDecl *ND) const { 280 return AllowHidden || 281 (isForExternalRedeclaration() && ND->isExternallyDeclarable()); 282 } 283 284 /// Sets whether tag declarations should be hidden by non-tag 285 /// declarations during resolution. The default is true. setHideTags(bool Hide)286 void setHideTags(bool Hide) { 287 HideTags = Hide; 288 } 289 isAmbiguous()290 bool isAmbiguous() const { 291 return getResultKind() == Ambiguous; 292 } 293 294 /// Determines if this names a single result which is not an 295 /// unresolved value using decl. If so, it is safe to call 296 /// getFoundDecl(). isSingleResult()297 bool isSingleResult() const { 298 return getResultKind() == Found; 299 } 300 301 /// Determines if the results are overloaded. isOverloadedResult()302 bool isOverloadedResult() const { 303 return getResultKind() == FoundOverloaded; 304 } 305 isUnresolvableResult()306 bool isUnresolvableResult() const { 307 return getResultKind() == FoundUnresolvedValue; 308 } 309 getResultKind()310 LookupResultKind getResultKind() const { 311 assert(sanity()); 312 return ResultKind; 313 } 314 getAmbiguityKind()315 AmbiguityKind getAmbiguityKind() const { 316 assert(isAmbiguous()); 317 return Ambiguity; 318 } 319 asUnresolvedSet()320 const UnresolvedSetImpl &asUnresolvedSet() const { 321 return Decls; 322 } 323 begin()324 iterator begin() const { return iterator(Decls.begin()); } end()325 iterator end() const { return iterator(Decls.end()); } 326 327 /// Return true if no decls were found empty()328 bool empty() const { return Decls.empty(); } 329 330 /// Return the base paths structure that's associated with 331 /// these results, or null if none is. getBasePaths()332 CXXBasePaths *getBasePaths() const { 333 return Paths; 334 } 335 336 /// Determine whether the given declaration is visible to the 337 /// program. isVisible(Sema & SemaRef,NamedDecl * D)338 static bool isVisible(Sema &SemaRef, NamedDecl *D) { 339 // If this declaration is not hidden, it's visible. 340 if (!D->isHidden()) 341 return true; 342 343 // During template instantiation, we can refer to hidden declarations, if 344 // they were visible in any module along the path of instantiation. 345 return isVisibleSlow(SemaRef, D); 346 } 347 348 /// Retrieve the accepted (re)declaration of the given declaration, 349 /// if there is one. getAcceptableDecl(NamedDecl * D)350 NamedDecl *getAcceptableDecl(NamedDecl *D) const { 351 if (!D->isInIdentifierNamespace(IDNS)) 352 return nullptr; 353 354 if (isVisible(getSema(), D) || isHiddenDeclarationVisible(D)) 355 return D; 356 357 return getAcceptableDeclSlow(D); 358 } 359 360 private: 361 static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D); 362 NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const; 363 364 public: 365 /// Returns the identifier namespace mask for this lookup. getIdentifierNamespace()366 unsigned getIdentifierNamespace() const { 367 return IDNS; 368 } 369 370 /// Returns whether these results arose from performing a 371 /// lookup into a class. isClassLookup()372 bool isClassLookup() const { 373 return NamingClass != nullptr; 374 } 375 376 /// Returns the 'naming class' for this lookup, i.e. the 377 /// class which was looked into to find these results. 378 /// 379 /// C++0x [class.access.base]p5: 380 /// The access to a member is affected by the class in which the 381 /// member is named. This naming class is the class in which the 382 /// member name was looked up and found. [Note: this class can be 383 /// explicit, e.g., when a qualified-id is used, or implicit, 384 /// e.g., when a class member access operator (5.2.5) is used 385 /// (including cases where an implicit "this->" is added). If both 386 /// a class member access operator and a qualified-id are used to 387 /// name the member (as in p->T::m), the class naming the member 388 /// is the class named by the nested-name-specifier of the 389 /// qualified-id (that is, T). -- end note ] 390 /// 391 /// This is set by the lookup routines when they find results in a class. getNamingClass()392 CXXRecordDecl *getNamingClass() const { 393 return NamingClass; 394 } 395 396 /// Sets the 'naming class' for this lookup. setNamingClass(CXXRecordDecl * Record)397 void setNamingClass(CXXRecordDecl *Record) { 398 NamingClass = Record; 399 } 400 401 /// Returns the base object type associated with this lookup; 402 /// important for [class.protected]. Most lookups do not have an 403 /// associated base object. getBaseObjectType()404 QualType getBaseObjectType() const { 405 return BaseObjectType; 406 } 407 408 /// Sets the base object type for this lookup. setBaseObjectType(QualType T)409 void setBaseObjectType(QualType T) { 410 BaseObjectType = T; 411 } 412 413 /// Add a declaration to these results with its natural access. 414 /// Does not test the acceptance criteria. addDecl(NamedDecl * D)415 void addDecl(NamedDecl *D) { 416 addDecl(D, D->getAccess()); 417 } 418 419 /// Add a declaration to these results with the given access. 420 /// Does not test the acceptance criteria. addDecl(NamedDecl * D,AccessSpecifier AS)421 void addDecl(NamedDecl *D, AccessSpecifier AS) { 422 Decls.addDecl(D, AS); 423 ResultKind = Found; 424 } 425 426 /// Add all the declarations from another set of lookup 427 /// results. addAllDecls(const LookupResult & Other)428 void addAllDecls(const LookupResult &Other) { 429 Decls.append(Other.Decls.begin(), Other.Decls.end()); 430 ResultKind = Found; 431 } 432 433 /// Determine whether no result was found because we could not 434 /// search into dependent base classes of the current instantiation. wasNotFoundInCurrentInstantiation()435 bool wasNotFoundInCurrentInstantiation() const { 436 return ResultKind == NotFoundInCurrentInstantiation; 437 } 438 439 /// Note that while no result was found in the current instantiation, 440 /// there were dependent base classes that could not be searched. setNotFoundInCurrentInstantiation()441 void setNotFoundInCurrentInstantiation() { 442 assert(ResultKind == NotFound && Decls.empty()); 443 ResultKind = NotFoundInCurrentInstantiation; 444 } 445 446 /// Determine whether the lookup result was shadowed by some other 447 /// declaration that lookup ignored. isShadowed()448 bool isShadowed() const { return Shadowed; } 449 450 /// Note that we found and ignored a declaration while performing 451 /// lookup. setShadowed()452 void setShadowed() { Shadowed = true; } 453 454 /// Resolves the result kind of the lookup, possibly hiding 455 /// decls. 456 /// 457 /// This should be called in any environment where lookup might 458 /// generate multiple lookup results. 459 void resolveKind(); 460 461 /// Re-resolves the result kind of the lookup after a set of 462 /// removals has been performed. resolveKindAfterFilter()463 void resolveKindAfterFilter() { 464 if (Decls.empty()) { 465 if (ResultKind != NotFoundInCurrentInstantiation) 466 ResultKind = NotFound; 467 468 if (Paths) { 469 deletePaths(Paths); 470 Paths = nullptr; 471 } 472 } else { 473 llvm::Optional<AmbiguityKind> SavedAK; 474 bool WasAmbiguous = false; 475 if (ResultKind == Ambiguous) { 476 SavedAK = Ambiguity; 477 WasAmbiguous = true; 478 } 479 ResultKind = Found; 480 resolveKind(); 481 482 // If we didn't make the lookup unambiguous, restore the old 483 // ambiguity kind. 484 if (ResultKind == Ambiguous) { 485 (void)WasAmbiguous; 486 assert(WasAmbiguous); 487 Ambiguity = SavedAK.getValue(); 488 } else if (Paths) { 489 deletePaths(Paths); 490 Paths = nullptr; 491 } 492 } 493 } 494 495 template <class DeclClass> getAsSingle()496 DeclClass *getAsSingle() const { 497 if (getResultKind() != Found) return nullptr; 498 return dyn_cast<DeclClass>(getFoundDecl()); 499 } 500 501 /// Fetch the unique decl found by this lookup. Asserts 502 /// that one was found. 503 /// 504 /// This is intended for users who have examined the result kind 505 /// and are certain that there is only one result. getFoundDecl()506 NamedDecl *getFoundDecl() const { 507 assert(getResultKind() == Found 508 && "getFoundDecl called on non-unique result"); 509 return (*begin())->getUnderlyingDecl(); 510 } 511 512 /// Fetches a representative decl. Useful for lazy diagnostics. getRepresentativeDecl()513 NamedDecl *getRepresentativeDecl() const { 514 assert(!Decls.empty() && "cannot get representative of empty set"); 515 return *begin(); 516 } 517 518 /// Asks if the result is a single tag decl. isSingleTagDecl()519 bool isSingleTagDecl() const { 520 return getResultKind() == Found && isa<TagDecl>(getFoundDecl()); 521 } 522 523 /// Make these results show that the name was found in 524 /// base classes of different types. 525 /// 526 /// The given paths object is copied and invalidated. 527 void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P); 528 529 /// Make these results show that the name was found in 530 /// distinct base classes of the same type. 531 /// 532 /// The given paths object is copied and invalidated. 533 void setAmbiguousBaseSubobjects(CXXBasePaths &P); 534 535 /// Make these results show that the name was found in 536 /// different contexts and a tag decl was hidden by an ordinary 537 /// decl in a different context. setAmbiguousQualifiedTagHiding()538 void setAmbiguousQualifiedTagHiding() { 539 setAmbiguous(AmbiguousTagHiding); 540 } 541 542 /// Clears out any current state. clear()543 LLVM_ATTRIBUTE_REINITIALIZES void clear() { 544 ResultKind = NotFound; 545 Decls.clear(); 546 if (Paths) deletePaths(Paths); 547 Paths = nullptr; 548 NamingClass = nullptr; 549 Shadowed = false; 550 } 551 552 /// Clears out any current state and re-initializes for a 553 /// different kind of lookup. clear(Sema::LookupNameKind Kind)554 void clear(Sema::LookupNameKind Kind) { 555 clear(); 556 LookupKind = Kind; 557 configure(); 558 } 559 560 /// Change this lookup's redeclaration kind. setRedeclarationKind(Sema::RedeclarationKind RK)561 void setRedeclarationKind(Sema::RedeclarationKind RK) { 562 Redecl = (RK != Sema::NotForRedeclaration); 563 ExternalRedecl = (RK == Sema::ForExternalRedeclaration); 564 configure(); 565 } 566 567 void dump(); 568 void print(raw_ostream &); 569 570 /// Suppress the diagnostics that would normally fire because of this 571 /// lookup. This happens during (e.g.) redeclaration lookups. suppressDiagnostics()572 void suppressDiagnostics() { 573 Diagnose = false; 574 } 575 576 /// Determines whether this lookup is suppressing diagnostics. isSuppressingDiagnostics()577 bool isSuppressingDiagnostics() const { 578 return !Diagnose; 579 } 580 581 /// Sets a 'context' source range. setContextRange(SourceRange SR)582 void setContextRange(SourceRange SR) { 583 NameContextRange = SR; 584 } 585 586 /// Gets the source range of the context of this name; for C++ 587 /// qualified lookups, this is the source range of the scope 588 /// specifier. getContextRange()589 SourceRange getContextRange() const { 590 return NameContextRange; 591 } 592 593 /// Gets the location of the identifier. This isn't always defined: 594 /// sometimes we're doing lookups on synthesized names. getNameLoc()595 SourceLocation getNameLoc() const { 596 return NameInfo.getLoc(); 597 } 598 599 /// Get the Sema object that this lookup result is searching 600 /// with. getSema()601 Sema &getSema() const { return *SemaPtr; } 602 603 /// A class for iterating through a result set and possibly 604 /// filtering out results. The results returned are possibly 605 /// sugared. 606 class Filter { 607 friend class LookupResult; 608 609 LookupResult &Results; 610 LookupResult::iterator I; 611 bool Changed = false; 612 bool CalledDone = false; 613 Filter(LookupResult & Results)614 Filter(LookupResult &Results) : Results(Results), I(Results.begin()) {} 615 616 public: Filter(Filter && F)617 Filter(Filter &&F) 618 : Results(F.Results), I(F.I), Changed(F.Changed), 619 CalledDone(F.CalledDone) { 620 F.CalledDone = true; 621 } 622 ~Filter()623 ~Filter() { 624 assert(CalledDone && 625 "LookupResult::Filter destroyed without done() call"); 626 } 627 hasNext()628 bool hasNext() const { 629 return I != Results.end(); 630 } 631 next()632 NamedDecl *next() { 633 assert(I != Results.end() && "next() called on empty filter"); 634 return *I++; 635 } 636 637 /// Restart the iteration. restart()638 void restart() { 639 I = Results.begin(); 640 } 641 642 /// Erase the last element returned from this iterator. erase()643 void erase() { 644 Results.Decls.erase(--I); 645 Changed = true; 646 } 647 648 /// Replaces the current entry with the given one, preserving the 649 /// access bits. replace(NamedDecl * D)650 void replace(NamedDecl *D) { 651 Results.Decls.replace(I-1, D); 652 Changed = true; 653 } 654 655 /// Replaces the current entry with the given one. replace(NamedDecl * D,AccessSpecifier AS)656 void replace(NamedDecl *D, AccessSpecifier AS) { 657 Results.Decls.replace(I-1, D, AS); 658 Changed = true; 659 } 660 done()661 void done() { 662 assert(!CalledDone && "done() called twice"); 663 CalledDone = true; 664 665 if (Changed) 666 Results.resolveKindAfterFilter(); 667 } 668 }; 669 670 /// Create a filter for this result set. makeFilter()671 Filter makeFilter() { 672 return Filter(*this); 673 } 674 setFindLocalExtern(bool FindLocalExtern)675 void setFindLocalExtern(bool FindLocalExtern) { 676 if (FindLocalExtern) 677 IDNS |= Decl::IDNS_LocalExtern; 678 else 679 IDNS &= ~Decl::IDNS_LocalExtern; 680 } 681 682 private: diagnose()683 void diagnose() { 684 if (isAmbiguous()) 685 getSema().DiagnoseAmbiguousLookup(*this); 686 else if (isClassLookup() && getSema().getLangOpts().AccessControl) 687 getSema().CheckLookupAccess(*this); 688 } 689 setAmbiguous(AmbiguityKind AK)690 void setAmbiguous(AmbiguityKind AK) { 691 ResultKind = Ambiguous; 692 Ambiguity = AK; 693 } 694 695 void addDeclsFromBasePaths(const CXXBasePaths &P); 696 void configure(); 697 698 // Sanity checks. 699 bool sanity() const; 700 sanityCheckUnresolved()701 bool sanityCheckUnresolved() const { 702 for (iterator I = begin(), E = end(); I != E; ++I) 703 if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl())) 704 return true; 705 return false; 706 } 707 708 static void deletePaths(CXXBasePaths *); 709 710 // Results. 711 LookupResultKind ResultKind = NotFound; 712 // ill-defined unless ambiguous. Still need to be initialized it will be 713 // copied/moved. 714 AmbiguityKind Ambiguity = {}; 715 UnresolvedSet<8> Decls; 716 CXXBasePaths *Paths = nullptr; 717 CXXRecordDecl *NamingClass = nullptr; 718 QualType BaseObjectType; 719 720 // Parameters. 721 Sema *SemaPtr; 722 DeclarationNameInfo NameInfo; 723 SourceRange NameContextRange; 724 Sema::LookupNameKind LookupKind; 725 unsigned IDNS = 0; // set by configure() 726 727 bool Redecl; 728 bool ExternalRedecl; 729 730 /// True if tag declarations should be hidden if non-tags 731 /// are present 732 bool HideTags = true; 733 734 bool Diagnose = false; 735 736 /// True if we should allow hidden declarations to be 'visible'. 737 bool AllowHidden = false; 738 739 /// True if the found declarations were shadowed by some other 740 /// declaration that we skipped. This only happens when \c LookupKind 741 /// is \c LookupRedeclarationWithLinkage. 742 bool Shadowed = false; 743 }; 744 745 /// Consumes visible declarations found when searching for 746 /// all visible names within a given scope or context. 747 /// 748 /// This abstract class is meant to be subclassed by clients of \c 749 /// Sema::LookupVisibleDecls(), each of which should override the \c 750 /// FoundDecl() function to process declarations as they are found. 751 class VisibleDeclConsumer { 752 public: 753 /// Destroys the visible declaration consumer. 754 virtual ~VisibleDeclConsumer(); 755 756 /// Determine whether hidden declarations (from unimported 757 /// modules) should be given to this consumer. By default, they 758 /// are not included. 759 virtual bool includeHiddenDecls() const; 760 761 /// Invoked each time \p Sema::LookupVisibleDecls() finds a 762 /// declaration visible from the current scope or context. 763 /// 764 /// \param ND the declaration found. 765 /// 766 /// \param Hiding a declaration that hides the declaration \p ND, 767 /// or NULL if no such declaration exists. 768 /// 769 /// \param Ctx the original context from which the lookup started. 770 /// 771 /// \param InBaseClass whether this declaration was found in base 772 /// class of the context we searched. 773 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, 774 bool InBaseClass) = 0; 775 776 /// Callback to inform the client that Sema entered into a new context 777 /// to find a visible declaration. 778 // 779 /// \param Ctx the context which Sema entered. EnteredContext(DeclContext * Ctx)780 virtual void EnteredContext(DeclContext *Ctx) {} 781 }; 782 783 /// A class for storing results from argument-dependent lookup. 784 class ADLResult { 785 private: 786 /// A map from canonical decls to the 'most recent' decl. 787 llvm::MapVector<NamedDecl*, NamedDecl*> Decls; 788 789 struct select_second { operatorselect_second790 NamedDecl *operator()(std::pair<NamedDecl*, NamedDecl*> P) const { 791 return P.second; 792 } 793 }; 794 795 public: 796 /// Adds a new ADL candidate to this map. 797 void insert(NamedDecl *D); 798 799 /// Removes any data associated with a given decl. erase(NamedDecl * D)800 void erase(NamedDecl *D) { 801 Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); 802 } 803 804 using iterator = 805 llvm::mapped_iterator<decltype(Decls)::iterator, select_second>; 806 begin()807 iterator begin() { return iterator(Decls.begin(), select_second()); } end()808 iterator end() { return iterator(Decls.end(), select_second()); } 809 }; 810 811 } // namespace clang 812 813 #endif // LLVM_CLANG_SEMA_LOOKUP_H 814