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