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/STLExtras.h" 30 #include "llvm/Support/Casting.h" 31 #include <cassert> 32 #include <optional> 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(checkDebugAssumptions()); 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. 349 static bool isVisible(Sema &SemaRef, NamedDecl *D); 350 351 static bool isReachable(Sema &SemaRef, NamedDecl *D); 352 isAcceptable(Sema & SemaRef,NamedDecl * D,Sema::AcceptableKind Kind)353 static bool isAcceptable(Sema &SemaRef, NamedDecl *D, 354 Sema::AcceptableKind Kind) { 355 return Kind == Sema::AcceptableKind::Visible ? isVisible(SemaRef, D) 356 : isReachable(SemaRef, D); 357 } 358 359 /// Determine whether this lookup is permitted to see the declaration. 360 /// Note that a reachable but not visible declaration inhabiting a namespace 361 /// is not allowed to be seen during name lookup. 362 /// 363 /// For example: 364 /// ``` 365 /// // m.cppm 366 /// export module m; 367 /// struct reachable { int v; } 368 /// export auto func() { return reachable{43}; } 369 /// // Use.cpp 370 /// import m; 371 /// auto Use() { 372 /// // Not valid. We couldn't see reachable here. 373 /// // So isAvailableForLookup would return false when we look 374 /// up 'reachable' here. 375 /// // return reachable(43).v; 376 /// // Valid. The field name 'v' is allowed during name lookup. 377 /// // So isAvailableForLookup would return true when we look up 'v' here. 378 /// return func().v; 379 /// } 380 /// ``` 381 static bool isAvailableForLookup(Sema &SemaRef, NamedDecl *ND); 382 383 /// Retrieve the accepted (re)declaration of the given declaration, 384 /// if there is one. getAcceptableDecl(NamedDecl * D)385 NamedDecl *getAcceptableDecl(NamedDecl *D) const { 386 if (!D->isInIdentifierNamespace(IDNS)) 387 return nullptr; 388 389 if (isAvailableForLookup(getSema(), D) || isHiddenDeclarationVisible(D)) 390 return D; 391 392 return getAcceptableDeclSlow(D); 393 } 394 395 private: 396 static bool isAcceptableSlow(Sema &SemaRef, NamedDecl *D, 397 Sema::AcceptableKind Kind); 398 static bool isReachableSlow(Sema &SemaRef, NamedDecl *D); 399 NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const; 400 401 public: 402 /// Returns the identifier namespace mask for this lookup. getIdentifierNamespace()403 unsigned getIdentifierNamespace() const { 404 return IDNS; 405 } 406 407 /// Returns whether these results arose from performing a 408 /// lookup into a class. isClassLookup()409 bool isClassLookup() const { 410 return NamingClass != nullptr; 411 } 412 413 /// Returns the 'naming class' for this lookup, i.e. the 414 /// class which was looked into to find these results. 415 /// 416 /// C++0x [class.access.base]p5: 417 /// The access to a member is affected by the class in which the 418 /// member is named. This naming class is the class in which the 419 /// member name was looked up and found. [Note: this class can be 420 /// explicit, e.g., when a qualified-id is used, or implicit, 421 /// e.g., when a class member access operator (5.2.5) is used 422 /// (including cases where an implicit "this->" is added). If both 423 /// a class member access operator and a qualified-id are used to 424 /// name the member (as in p->T::m), the class naming the member 425 /// is the class named by the nested-name-specifier of the 426 /// qualified-id (that is, T). -- end note ] 427 /// 428 /// This is set by the lookup routines when they find results in a class. getNamingClass()429 CXXRecordDecl *getNamingClass() const { 430 return NamingClass; 431 } 432 433 /// Sets the 'naming class' for this lookup. setNamingClass(CXXRecordDecl * Record)434 void setNamingClass(CXXRecordDecl *Record) { 435 NamingClass = Record; 436 } 437 438 /// Returns the base object type associated with this lookup; 439 /// important for [class.protected]. Most lookups do not have an 440 /// associated base object. getBaseObjectType()441 QualType getBaseObjectType() const { 442 return BaseObjectType; 443 } 444 445 /// Sets the base object type for this lookup. setBaseObjectType(QualType T)446 void setBaseObjectType(QualType T) { 447 BaseObjectType = T; 448 } 449 450 /// Add a declaration to these results with its natural access. 451 /// Does not test the acceptance criteria. addDecl(NamedDecl * D)452 void addDecl(NamedDecl *D) { 453 addDecl(D, D->getAccess()); 454 } 455 456 /// Add a declaration to these results with the given access. 457 /// Does not test the acceptance criteria. addDecl(NamedDecl * D,AccessSpecifier AS)458 void addDecl(NamedDecl *D, AccessSpecifier AS) { 459 Decls.addDecl(D, AS); 460 ResultKind = Found; 461 } 462 463 /// Add all the declarations from another set of lookup 464 /// results. addAllDecls(const LookupResult & Other)465 void addAllDecls(const LookupResult &Other) { 466 Decls.append(Other.Decls.begin(), Other.Decls.end()); 467 ResultKind = Found; 468 } 469 470 /// Determine whether no result was found because we could not 471 /// search into dependent base classes of the current instantiation. wasNotFoundInCurrentInstantiation()472 bool wasNotFoundInCurrentInstantiation() const { 473 return ResultKind == NotFoundInCurrentInstantiation; 474 } 475 476 /// Note that while no result was found in the current instantiation, 477 /// there were dependent base classes that could not be searched. setNotFoundInCurrentInstantiation()478 void setNotFoundInCurrentInstantiation() { 479 assert(ResultKind == NotFound && Decls.empty()); 480 ResultKind = NotFoundInCurrentInstantiation; 481 } 482 483 /// Determine whether the lookup result was shadowed by some other 484 /// declaration that lookup ignored. isShadowed()485 bool isShadowed() const { return Shadowed; } 486 487 /// Note that we found and ignored a declaration while performing 488 /// lookup. setShadowed()489 void setShadowed() { Shadowed = true; } 490 491 /// Resolves the result kind of the lookup, possibly hiding 492 /// decls. 493 /// 494 /// This should be called in any environment where lookup might 495 /// generate multiple lookup results. 496 void resolveKind(); 497 498 /// Re-resolves the result kind of the lookup after a set of 499 /// removals has been performed. resolveKindAfterFilter()500 void resolveKindAfterFilter() { 501 if (Decls.empty()) { 502 if (ResultKind != NotFoundInCurrentInstantiation) 503 ResultKind = NotFound; 504 505 if (Paths) { 506 deletePaths(Paths); 507 Paths = nullptr; 508 } 509 } else { 510 std::optional<AmbiguityKind> SavedAK; 511 bool WasAmbiguous = false; 512 if (ResultKind == Ambiguous) { 513 SavedAK = Ambiguity; 514 WasAmbiguous = true; 515 } 516 ResultKind = Found; 517 resolveKind(); 518 519 // If we didn't make the lookup unambiguous, restore the old 520 // ambiguity kind. 521 if (ResultKind == Ambiguous) { 522 (void)WasAmbiguous; 523 assert(WasAmbiguous); 524 Ambiguity = *SavedAK; 525 } else if (Paths) { 526 deletePaths(Paths); 527 Paths = nullptr; 528 } 529 } 530 } 531 532 template <class DeclClass> getAsSingle()533 DeclClass *getAsSingle() const { 534 if (getResultKind() != Found) return nullptr; 535 return dyn_cast<DeclClass>(getFoundDecl()); 536 } 537 538 /// Fetch the unique decl found by this lookup. Asserts 539 /// that one was found. 540 /// 541 /// This is intended for users who have examined the result kind 542 /// and are certain that there is only one result. getFoundDecl()543 NamedDecl *getFoundDecl() const { 544 assert(getResultKind() == Found 545 && "getFoundDecl called on non-unique result"); 546 return (*begin())->getUnderlyingDecl(); 547 } 548 549 /// Fetches a representative decl. Useful for lazy diagnostics. getRepresentativeDecl()550 NamedDecl *getRepresentativeDecl() const { 551 assert(!Decls.empty() && "cannot get representative of empty set"); 552 return *begin(); 553 } 554 555 /// Asks if the result is a single tag decl. isSingleTagDecl()556 bool isSingleTagDecl() const { 557 return getResultKind() == Found && isa<TagDecl>(getFoundDecl()); 558 } 559 560 /// Make these results show that the name was found in 561 /// base classes of different types. 562 /// 563 /// The given paths object is copied and invalidated. 564 void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P); 565 566 /// Make these results show that the name was found in 567 /// distinct base classes of the same type. 568 /// 569 /// The given paths object is copied and invalidated. 570 void setAmbiguousBaseSubobjects(CXXBasePaths &P); 571 572 /// Make these results show that the name was found in 573 /// different contexts and a tag decl was hidden by an ordinary 574 /// decl in a different context. setAmbiguousQualifiedTagHiding()575 void setAmbiguousQualifiedTagHiding() { 576 setAmbiguous(AmbiguousTagHiding); 577 } 578 579 /// Clears out any current state. clear()580 LLVM_ATTRIBUTE_REINITIALIZES void clear() { 581 ResultKind = NotFound; 582 Decls.clear(); 583 if (Paths) deletePaths(Paths); 584 Paths = nullptr; 585 NamingClass = nullptr; 586 Shadowed = false; 587 } 588 589 /// Clears out any current state and re-initializes for a 590 /// different kind of lookup. clear(Sema::LookupNameKind Kind)591 void clear(Sema::LookupNameKind Kind) { 592 clear(); 593 LookupKind = Kind; 594 configure(); 595 } 596 597 /// Change this lookup's redeclaration kind. setRedeclarationKind(Sema::RedeclarationKind RK)598 void setRedeclarationKind(Sema::RedeclarationKind RK) { 599 Redecl = (RK != Sema::NotForRedeclaration); 600 ExternalRedecl = (RK == Sema::ForExternalRedeclaration); 601 configure(); 602 } 603 604 void dump(); 605 void print(raw_ostream &); 606 607 /// Suppress the diagnostics that would normally fire because of this 608 /// lookup. This happens during (e.g.) redeclaration lookups. suppressDiagnostics()609 void suppressDiagnostics() { 610 Diagnose = false; 611 } 612 613 /// Determines whether this lookup is suppressing diagnostics. isSuppressingDiagnostics()614 bool isSuppressingDiagnostics() const { 615 return !Diagnose; 616 } 617 618 /// Sets a 'context' source range. setContextRange(SourceRange SR)619 void setContextRange(SourceRange SR) { 620 NameContextRange = SR; 621 } 622 623 /// Gets the source range of the context of this name; for C++ 624 /// qualified lookups, this is the source range of the scope 625 /// specifier. getContextRange()626 SourceRange getContextRange() const { 627 return NameContextRange; 628 } 629 630 /// Gets the location of the identifier. This isn't always defined: 631 /// sometimes we're doing lookups on synthesized names. getNameLoc()632 SourceLocation getNameLoc() const { 633 return NameInfo.getLoc(); 634 } 635 636 /// Get the Sema object that this lookup result is searching 637 /// with. getSema()638 Sema &getSema() const { return *SemaPtr; } 639 640 /// A class for iterating through a result set and possibly 641 /// filtering out results. The results returned are possibly 642 /// sugared. 643 class Filter { 644 friend class LookupResult; 645 646 LookupResult &Results; 647 LookupResult::iterator I; 648 bool Changed = false; 649 bool CalledDone = false; 650 Filter(LookupResult & Results)651 Filter(LookupResult &Results) : Results(Results), I(Results.begin()) {} 652 653 public: Filter(Filter && F)654 Filter(Filter &&F) 655 : Results(F.Results), I(F.I), Changed(F.Changed), 656 CalledDone(F.CalledDone) { 657 F.CalledDone = true; 658 } 659 ~Filter()660 ~Filter() { 661 assert(CalledDone && 662 "LookupResult::Filter destroyed without done() call"); 663 } 664 hasNext()665 bool hasNext() const { 666 return I != Results.end(); 667 } 668 next()669 NamedDecl *next() { 670 assert(I != Results.end() && "next() called on empty filter"); 671 return *I++; 672 } 673 674 /// Restart the iteration. restart()675 void restart() { 676 I = Results.begin(); 677 } 678 679 /// Erase the last element returned from this iterator. erase()680 void erase() { 681 Results.Decls.erase(--I); 682 Changed = true; 683 } 684 685 /// Replaces the current entry with the given one, preserving the 686 /// access bits. replace(NamedDecl * D)687 void replace(NamedDecl *D) { 688 Results.Decls.replace(I-1, D); 689 Changed = true; 690 } 691 692 /// Replaces the current entry with the given one. replace(NamedDecl * D,AccessSpecifier AS)693 void replace(NamedDecl *D, AccessSpecifier AS) { 694 Results.Decls.replace(I-1, D, AS); 695 Changed = true; 696 } 697 done()698 void done() { 699 assert(!CalledDone && "done() called twice"); 700 CalledDone = true; 701 702 if (Changed) 703 Results.resolveKindAfterFilter(); 704 } 705 }; 706 707 /// Create a filter for this result set. makeFilter()708 Filter makeFilter() { 709 return Filter(*this); 710 } 711 setFindLocalExtern(bool FindLocalExtern)712 void setFindLocalExtern(bool FindLocalExtern) { 713 if (FindLocalExtern) 714 IDNS |= Decl::IDNS_LocalExtern; 715 else 716 IDNS &= ~Decl::IDNS_LocalExtern; 717 } 718 719 private: diagnose()720 void diagnose() { 721 if (isAmbiguous()) 722 getSema().DiagnoseAmbiguousLookup(*this); 723 else if (isClassLookup() && getSema().getLangOpts().AccessControl) 724 getSema().CheckLookupAccess(*this); 725 } 726 setAmbiguous(AmbiguityKind AK)727 void setAmbiguous(AmbiguityKind AK) { 728 ResultKind = Ambiguous; 729 Ambiguity = AK; 730 } 731 732 void addDeclsFromBasePaths(const CXXBasePaths &P); 733 void configure(); 734 735 bool checkDebugAssumptions() const; 736 checkUnresolved()737 bool checkUnresolved() const { 738 for (iterator I = begin(), E = end(); I != E; ++I) 739 if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl())) 740 return true; 741 return false; 742 } 743 744 static void deletePaths(CXXBasePaths *); 745 746 // Results. 747 LookupResultKind ResultKind = NotFound; 748 // ill-defined unless ambiguous. Still need to be initialized it will be 749 // copied/moved. 750 AmbiguityKind Ambiguity = {}; 751 UnresolvedSet<8> Decls; 752 CXXBasePaths *Paths = nullptr; 753 CXXRecordDecl *NamingClass = nullptr; 754 QualType BaseObjectType; 755 756 // Parameters. 757 Sema *SemaPtr; 758 DeclarationNameInfo NameInfo; 759 SourceRange NameContextRange; 760 Sema::LookupNameKind LookupKind; 761 unsigned IDNS = 0; // set by configure() 762 763 bool Redecl; 764 bool ExternalRedecl; 765 766 /// True if tag declarations should be hidden if non-tags 767 /// are present 768 bool HideTags = true; 769 770 bool Diagnose = false; 771 772 /// True if we should allow hidden declarations to be 'visible'. 773 bool AllowHidden = false; 774 775 /// True if the found declarations were shadowed by some other 776 /// declaration that we skipped. This only happens when \c LookupKind 777 /// is \c LookupRedeclarationWithLinkage. 778 bool Shadowed = false; 779 780 /// True if we're looking up a template-name. 781 bool TemplateNameLookup = false; 782 }; 783 784 /// Consumes visible declarations found when searching for 785 /// all visible names within a given scope or context. 786 /// 787 /// This abstract class is meant to be subclassed by clients of \c 788 /// Sema::LookupVisibleDecls(), each of which should override the \c 789 /// FoundDecl() function to process declarations as they are found. 790 class VisibleDeclConsumer { 791 public: 792 /// Destroys the visible declaration consumer. 793 virtual ~VisibleDeclConsumer(); 794 795 /// Determine whether hidden declarations (from unimported 796 /// modules) should be given to this consumer. By default, they 797 /// are not included. 798 virtual bool includeHiddenDecls() const; 799 800 /// Invoked each time \p Sema::LookupVisibleDecls() finds a 801 /// declaration visible from the current scope or context. 802 /// 803 /// \param ND the declaration found. 804 /// 805 /// \param Hiding a declaration that hides the declaration \p ND, 806 /// or NULL if no such declaration exists. 807 /// 808 /// \param Ctx the original context from which the lookup started. 809 /// 810 /// \param InBaseClass whether this declaration was found in base 811 /// class of the context we searched. 812 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, 813 bool InBaseClass) = 0; 814 815 /// Callback to inform the client that Sema entered into a new context 816 /// to find a visible declaration. 817 // 818 /// \param Ctx the context which Sema entered. EnteredContext(DeclContext * Ctx)819 virtual void EnteredContext(DeclContext *Ctx) {} 820 }; 821 822 /// A class for storing results from argument-dependent lookup. 823 class ADLResult { 824 private: 825 /// A map from canonical decls to the 'most recent' decl. 826 llvm::MapVector<NamedDecl*, NamedDecl*> Decls; 827 828 struct select_second { operatorselect_second829 NamedDecl *operator()(std::pair<NamedDecl*, NamedDecl*> P) const { 830 return P.second; 831 } 832 }; 833 834 public: 835 /// Adds a new ADL candidate to this map. 836 void insert(NamedDecl *D); 837 838 /// Removes any data associated with a given decl. erase(NamedDecl * D)839 void erase(NamedDecl *D) { 840 Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); 841 } 842 843 using iterator = 844 llvm::mapped_iterator<decltype(Decls)::iterator, select_second>; 845 begin()846 iterator begin() { return iterator(Decls.begin(), select_second()); } end()847 iterator end() { return iterator(Decls.end(), select_second()); } 848 }; 849 850 } // namespace clang 851 852 #endif // LLVM_CLANG_SEMA_LOOKUP_H 853