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