1212795Sdim//===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===// 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim// 8212795Sdim//===----------------------------------------------------------------------===// 9212795Sdim// 10212795Sdim// This file defines the LookupResult class, which is integral to 11212795Sdim// Sema's name-lookup subsystem. 12212795Sdim// 13212795Sdim//===----------------------------------------------------------------------===// 14212795Sdim 15212795Sdim#ifndef LLVM_CLANG_SEMA_LOOKUP_H 16212795Sdim#define LLVM_CLANG_SEMA_LOOKUP_H 17212795Sdim 18249423Sdim#include "clang/AST/DeclCXX.h" 19212795Sdim#include "clang/Sema/Sema.h" 20212795Sdim 21212795Sdimnamespace clang { 22212795Sdim 23212795Sdim/// @brief Represents the results of name lookup. 24212795Sdim/// 25212795Sdim/// An instance of the LookupResult class captures the results of a 26212795Sdim/// single name lookup, which can return no result (nothing found), 27212795Sdim/// a single declaration, a set of overloaded functions, or an 28212795Sdim/// ambiguity. Use the getKind() method to determine which of these 29212795Sdim/// results occurred for a given lookup. 30212795Sdimclass LookupResult { 31212795Sdimpublic: 32212795Sdim enum LookupResultKind { 33212795Sdim /// @brief No entity found met the criteria. 34212795Sdim NotFound = 0, 35212795Sdim 36212795Sdim /// @brief No entity found met the criteria within the current 37212795Sdim /// instantiation,, but there were dependent base classes of the 38212795Sdim /// current instantiation that could not be searched. 39212795Sdim NotFoundInCurrentInstantiation, 40212795Sdim 41212795Sdim /// @brief Name lookup found a single declaration that met the 42212795Sdim /// criteria. getFoundDecl() will return this declaration. 43212795Sdim Found, 44212795Sdim 45212795Sdim /// @brief Name lookup found a set of overloaded functions that 46212795Sdim /// met the criteria. 47212795Sdim FoundOverloaded, 48212795Sdim 49212795Sdim /// @brief Name lookup found an unresolvable value declaration 50212795Sdim /// and cannot yet complete. This only happens in C++ dependent 51212795Sdim /// contexts with dependent using declarations. 52212795Sdim FoundUnresolvedValue, 53212795Sdim 54212795Sdim /// @brief Name lookup results in an ambiguity; use 55212795Sdim /// getAmbiguityKind to figure out what kind of ambiguity 56212795Sdim /// we have. 57212795Sdim Ambiguous 58212795Sdim }; 59212795Sdim 60212795Sdim enum AmbiguityKind { 61212795Sdim /// Name lookup results in an ambiguity because multiple 62212795Sdim /// entities that meet the lookup criteria were found in 63212795Sdim /// subobjects of different types. For example: 64212795Sdim /// @code 65212795Sdim /// struct A { void f(int); } 66212795Sdim /// struct B { void f(double); } 67212795Sdim /// struct C : A, B { }; 68212795Sdim /// void test(C c) { 69212795Sdim /// c.f(0); // error: A::f and B::f come from subobjects of different 70212795Sdim /// // types. overload resolution is not performed. 71212795Sdim /// } 72212795Sdim /// @endcode 73212795Sdim AmbiguousBaseSubobjectTypes, 74212795Sdim 75212795Sdim /// Name lookup results in an ambiguity because multiple 76212795Sdim /// nonstatic entities that meet the lookup criteria were found 77212795Sdim /// in different subobjects of the same type. For example: 78212795Sdim /// @code 79212795Sdim /// struct A { int x; }; 80212795Sdim /// struct B : A { }; 81212795Sdim /// struct C : A { }; 82212795Sdim /// struct D : B, C { }; 83212795Sdim /// int test(D d) { 84212795Sdim /// return d.x; // error: 'x' is found in two A subobjects (of B and C) 85212795Sdim /// } 86212795Sdim /// @endcode 87212795Sdim AmbiguousBaseSubobjects, 88212795Sdim 89212795Sdim /// Name lookup results in an ambiguity because multiple definitions 90212795Sdim /// of entity that meet the lookup criteria were found in different 91212795Sdim /// declaration contexts. 92212795Sdim /// @code 93212795Sdim /// namespace A { 94212795Sdim /// int i; 95212795Sdim /// namespace B { int i; } 96212795Sdim /// int test() { 97212795Sdim /// using namespace B; 98212795Sdim /// return i; // error 'i' is found in namespace A and A::B 99212795Sdim /// } 100212795Sdim /// } 101212795Sdim /// @endcode 102212795Sdim AmbiguousReference, 103212795Sdim 104212795Sdim /// Name lookup results in an ambiguity because an entity with a 105212795Sdim /// tag name was hidden by an entity with an ordinary name from 106212795Sdim /// a different context. 107212795Sdim /// @code 108212795Sdim /// namespace A { struct Foo {}; } 109212795Sdim /// namespace B { void Foo(); } 110212795Sdim /// namespace C { 111212795Sdim /// using namespace A; 112212795Sdim /// using namespace B; 113212795Sdim /// } 114212795Sdim /// void test() { 115212795Sdim /// C::Foo(); // error: tag 'A::Foo' is hidden by an object in a 116212795Sdim /// // different namespace 117212795Sdim /// } 118212795Sdim /// @endcode 119212795Sdim AmbiguousTagHiding 120212795Sdim }; 121212795Sdim 122212795Sdim /// A little identifier for flagging temporary lookup results. 123212795Sdim enum TemporaryToken { 124212795Sdim Temporary 125212795Sdim }; 126212795Sdim 127212795Sdim typedef UnresolvedSetImpl::iterator iterator; 128212795Sdim 129212795Sdim LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo, 130212795Sdim Sema::LookupNameKind LookupKind, 131212795Sdim Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration) 132212795Sdim : ResultKind(NotFound), 133276479Sdim Paths(nullptr), 134276479Sdim NamingClass(nullptr), 135280031Sdim SemaPtr(&SemaRef), 136212795Sdim NameInfo(NameInfo), 137212795Sdim LookupKind(LookupKind), 138212795Sdim IDNS(0), 139212795Sdim Redecl(Redecl != Sema::NotForRedeclaration), 140212795Sdim HideTags(true), 141249423Sdim Diagnose(Redecl == Sema::NotForRedeclaration), 142296417Sdim AllowHidden(false), 143261991Sdim Shadowed(false) 144212795Sdim { 145212795Sdim configure(); 146212795Sdim } 147212795Sdim 148212795Sdim // TODO: consider whether this constructor should be restricted to take 149212795Sdim // as input a const IndentifierInfo* (instead of Name), 150212795Sdim // forcing other cases towards the constructor taking a DNInfo. 151212795Sdim LookupResult(Sema &SemaRef, DeclarationName Name, 152212795Sdim SourceLocation NameLoc, Sema::LookupNameKind LookupKind, 153212795Sdim Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration) 154212795Sdim : ResultKind(NotFound), 155276479Sdim Paths(nullptr), 156276479Sdim NamingClass(nullptr), 157280031Sdim SemaPtr(&SemaRef), 158212795Sdim NameInfo(Name, NameLoc), 159212795Sdim LookupKind(LookupKind), 160212795Sdim IDNS(0), 161212795Sdim Redecl(Redecl != Sema::NotForRedeclaration), 162212795Sdim HideTags(true), 163249423Sdim Diagnose(Redecl == Sema::NotForRedeclaration), 164296417Sdim AllowHidden(false), 165261991Sdim Shadowed(false) 166212795Sdim { 167212795Sdim configure(); 168212795Sdim } 169212795Sdim 170212795Sdim /// Creates a temporary lookup result, initializing its core data 171212795Sdim /// using the information from another result. Diagnostics are always 172212795Sdim /// disabled. 173212795Sdim LookupResult(TemporaryToken _, const LookupResult &Other) 174212795Sdim : ResultKind(NotFound), 175276479Sdim Paths(nullptr), 176276479Sdim NamingClass(nullptr), 177280031Sdim SemaPtr(Other.SemaPtr), 178212795Sdim NameInfo(Other.NameInfo), 179212795Sdim LookupKind(Other.LookupKind), 180212795Sdim IDNS(Other.IDNS), 181212795Sdim Redecl(Other.Redecl), 182212795Sdim HideTags(Other.HideTags), 183249423Sdim Diagnose(false), 184261991Sdim AllowHidden(Other.AllowHidden), 185261991Sdim Shadowed(false) 186212795Sdim {} 187212795Sdim 188212795Sdim ~LookupResult() { 189212795Sdim if (Diagnose) diagnose(); 190212795Sdim if (Paths) deletePaths(Paths); 191212795Sdim } 192212795Sdim 193212795Sdim /// Gets the name info to look up. 194212795Sdim const DeclarationNameInfo &getLookupNameInfo() const { 195212795Sdim return NameInfo; 196212795Sdim } 197212795Sdim 198212795Sdim /// \brief Sets the name info to look up. 199212795Sdim void setLookupNameInfo(const DeclarationNameInfo &NameInfo) { 200212795Sdim this->NameInfo = NameInfo; 201212795Sdim } 202212795Sdim 203212795Sdim /// Gets the name to look up. 204212795Sdim DeclarationName getLookupName() const { 205212795Sdim return NameInfo.getName(); 206212795Sdim } 207212795Sdim 208212795Sdim /// \brief Sets the name to look up. 209212795Sdim void setLookupName(DeclarationName Name) { 210212795Sdim NameInfo.setName(Name); 211212795Sdim } 212212795Sdim 213212795Sdim /// Gets the kind of lookup to perform. 214212795Sdim Sema::LookupNameKind getLookupKind() const { 215212795Sdim return LookupKind; 216212795Sdim } 217212795Sdim 218212795Sdim /// True if this lookup is just looking for an existing declaration. 219212795Sdim bool isForRedeclaration() const { 220212795Sdim return Redecl; 221212795Sdim } 222212795Sdim 223249423Sdim /// \brief Specify whether hidden declarations are visible, e.g., 224249423Sdim /// for recovery reasons. 225249423Sdim void setAllowHidden(bool AH) { 226249423Sdim AllowHidden = AH; 227249423Sdim } 228249423Sdim 229234353Sdim /// \brief Determine whether this lookup is permitted to see hidden 230234353Sdim /// declarations, such as those in modules that have not yet been imported. 231296417Sdim bool isHiddenDeclarationVisible(NamedDecl *ND) const { 232296417Sdim return AllowHidden || 233296417Sdim (isForRedeclaration() && ND->isExternallyVisible()); 234234353Sdim } 235296417Sdim 236212795Sdim /// Sets whether tag declarations should be hidden by non-tag 237212795Sdim /// declarations during resolution. The default is true. 238212795Sdim void setHideTags(bool Hide) { 239212795Sdim HideTags = Hide; 240212795Sdim } 241212795Sdim 242212795Sdim bool isAmbiguous() const { 243212795Sdim return getResultKind() == Ambiguous; 244212795Sdim } 245212795Sdim 246212795Sdim /// Determines if this names a single result which is not an 247212795Sdim /// unresolved value using decl. If so, it is safe to call 248212795Sdim /// getFoundDecl(). 249212795Sdim bool isSingleResult() const { 250212795Sdim return getResultKind() == Found; 251212795Sdim } 252212795Sdim 253212795Sdim /// Determines if the results are overloaded. 254212795Sdim bool isOverloadedResult() const { 255212795Sdim return getResultKind() == FoundOverloaded; 256212795Sdim } 257212795Sdim 258212795Sdim bool isUnresolvableResult() const { 259212795Sdim return getResultKind() == FoundUnresolvedValue; 260212795Sdim } 261212795Sdim 262212795Sdim LookupResultKind getResultKind() const { 263276479Sdim assert(sanity()); 264212795Sdim return ResultKind; 265212795Sdim } 266212795Sdim 267212795Sdim AmbiguityKind getAmbiguityKind() const { 268212795Sdim assert(isAmbiguous()); 269212795Sdim return Ambiguity; 270212795Sdim } 271212795Sdim 272212795Sdim const UnresolvedSetImpl &asUnresolvedSet() const { 273212795Sdim return Decls; 274212795Sdim } 275212795Sdim 276212795Sdim iterator begin() const { return iterator(Decls.begin()); } 277212795Sdim iterator end() const { return iterator(Decls.end()); } 278212795Sdim 279212795Sdim /// \brief Return true if no decls were found 280212795Sdim bool empty() const { return Decls.empty(); } 281212795Sdim 282212795Sdim /// \brief Return the base paths structure that's associated with 283212795Sdim /// these results, or null if none is. 284212795Sdim CXXBasePaths *getBasePaths() const { 285212795Sdim return Paths; 286212795Sdim } 287212795Sdim 288234353Sdim /// \brief Determine whether the given declaration is visible to the 289234353Sdim /// program. 290261991Sdim static bool isVisible(Sema &SemaRef, NamedDecl *D) { 291234353Sdim // If this declaration is not hidden, it's visible. 292234353Sdim if (!D->isHidden()) 293234353Sdim return true; 294261991Sdim 295261991Sdim // During template instantiation, we can refer to hidden declarations, if 296261991Sdim // they were visible in any module along the path of instantiation. 297261991Sdim return isVisibleSlow(SemaRef, D); 298212795Sdim } 299261991Sdim 300234353Sdim /// \brief Retrieve the accepted (re)declaration of the given declaration, 301234353Sdim /// if there is one. 302234353Sdim NamedDecl *getAcceptableDecl(NamedDecl *D) const { 303234353Sdim if (!D->isInIdentifierNamespace(IDNS)) 304276479Sdim return nullptr; 305261991Sdim 306296417Sdim if (isVisible(getSema(), D) || isHiddenDeclarationVisible(D)) 307234353Sdim return D; 308261991Sdim 309234353Sdim return getAcceptableDeclSlow(D); 310234353Sdim } 311261991Sdim 312234353Sdimprivate: 313261991Sdim static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D); 314234353Sdim NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const; 315261991Sdim 316234353Sdimpublic: 317212795Sdim /// \brief Returns the identifier namespace mask for this lookup. 318212795Sdim unsigned getIdentifierNamespace() const { 319212795Sdim return IDNS; 320212795Sdim } 321212795Sdim 322212795Sdim /// \brief Returns whether these results arose from performing a 323212795Sdim /// lookup into a class. 324212795Sdim bool isClassLookup() const { 325276479Sdim return NamingClass != nullptr; 326212795Sdim } 327212795Sdim 328212795Sdim /// \brief Returns the 'naming class' for this lookup, i.e. the 329212795Sdim /// class which was looked into to find these results. 330212795Sdim /// 331212795Sdim /// C++0x [class.access.base]p5: 332212795Sdim /// The access to a member is affected by the class in which the 333212795Sdim /// member is named. This naming class is the class in which the 334212795Sdim /// member name was looked up and found. [Note: this class can be 335212795Sdim /// explicit, e.g., when a qualified-id is used, or implicit, 336212795Sdim /// e.g., when a class member access operator (5.2.5) is used 337212795Sdim /// (including cases where an implicit "this->" is added). If both 338212795Sdim /// a class member access operator and a qualified-id are used to 339212795Sdim /// name the member (as in p->T::m), the class naming the member 340212795Sdim /// is the class named by the nested-name-specifier of the 341212795Sdim /// qualified-id (that is, T). -- end note ] 342212795Sdim /// 343212795Sdim /// This is set by the lookup routines when they find results in a class. 344212795Sdim CXXRecordDecl *getNamingClass() const { 345212795Sdim return NamingClass; 346212795Sdim } 347212795Sdim 348212795Sdim /// \brief Sets the 'naming class' for this lookup. 349212795Sdim void setNamingClass(CXXRecordDecl *Record) { 350212795Sdim NamingClass = Record; 351212795Sdim } 352212795Sdim 353212795Sdim /// \brief Returns the base object type associated with this lookup; 354212795Sdim /// important for [class.protected]. Most lookups do not have an 355212795Sdim /// associated base object. 356212795Sdim QualType getBaseObjectType() const { 357212795Sdim return BaseObjectType; 358212795Sdim } 359212795Sdim 360212795Sdim /// \brief Sets the base object type for this lookup. 361212795Sdim void setBaseObjectType(QualType T) { 362212795Sdim BaseObjectType = T; 363212795Sdim } 364212795Sdim 365212795Sdim /// \brief Add a declaration to these results with its natural access. 366212795Sdim /// Does not test the acceptance criteria. 367212795Sdim void addDecl(NamedDecl *D) { 368212795Sdim addDecl(D, D->getAccess()); 369212795Sdim } 370212795Sdim 371212795Sdim /// \brief Add a declaration to these results with the given access. 372212795Sdim /// Does not test the acceptance criteria. 373212795Sdim void addDecl(NamedDecl *D, AccessSpecifier AS) { 374212795Sdim Decls.addDecl(D, AS); 375212795Sdim ResultKind = Found; 376212795Sdim } 377212795Sdim 378212795Sdim /// \brief Add all the declarations from another set of lookup 379212795Sdim /// results. 380212795Sdim void addAllDecls(const LookupResult &Other) { 381212795Sdim Decls.append(Other.Decls.begin(), Other.Decls.end()); 382212795Sdim ResultKind = Found; 383212795Sdim } 384212795Sdim 385212795Sdim /// \brief Determine whether no result was found because we could not 386212795Sdim /// search into dependent base classes of the current instantiation. 387212795Sdim bool wasNotFoundInCurrentInstantiation() const { 388212795Sdim return ResultKind == NotFoundInCurrentInstantiation; 389212795Sdim } 390212795Sdim 391212795Sdim /// \brief Note that while no result was found in the current instantiation, 392212795Sdim /// there were dependent base classes that could not be searched. 393212795Sdim void setNotFoundInCurrentInstantiation() { 394212795Sdim assert(ResultKind == NotFound && Decls.empty()); 395212795Sdim ResultKind = NotFoundInCurrentInstantiation; 396212795Sdim } 397261991Sdim 398261991Sdim /// \brief Determine whether the lookup result was shadowed by some other 399261991Sdim /// declaration that lookup ignored. 400261991Sdim bool isShadowed() const { return Shadowed; } 401261991Sdim 402261991Sdim /// \brief Note that we found and ignored a declaration while performing 403261991Sdim /// lookup. 404261991Sdim void setShadowed() { Shadowed = true; } 405261991Sdim 406212795Sdim /// \brief Resolves the result kind of the lookup, possibly hiding 407212795Sdim /// decls. 408212795Sdim /// 409212795Sdim /// This should be called in any environment where lookup might 410212795Sdim /// generate multiple lookup results. 411212795Sdim void resolveKind(); 412212795Sdim 413212795Sdim /// \brief Re-resolves the result kind of the lookup after a set of 414212795Sdim /// removals has been performed. 415212795Sdim void resolveKindAfterFilter() { 416212795Sdim if (Decls.empty()) { 417212795Sdim if (ResultKind != NotFoundInCurrentInstantiation) 418212795Sdim ResultKind = NotFound; 419218893Sdim 420218893Sdim if (Paths) { 421218893Sdim deletePaths(Paths); 422276479Sdim Paths = nullptr; 423218893Sdim } 424212795Sdim } else { 425280031Sdim AmbiguityKind SavedAK; 426280031Sdim bool WasAmbiguous = false; 427280031Sdim if (ResultKind == Ambiguous) { 428280031Sdim SavedAK = Ambiguity; 429280031Sdim WasAmbiguous = true; 430280031Sdim } 431212795Sdim ResultKind = Found; 432212795Sdim resolveKind(); 433212795Sdim 434212795Sdim // If we didn't make the lookup unambiguous, restore the old 435212795Sdim // ambiguity kind. 436212795Sdim if (ResultKind == Ambiguous) { 437280031Sdim (void)WasAmbiguous; 438280031Sdim assert(WasAmbiguous); 439212795Sdim Ambiguity = SavedAK; 440212795Sdim } else if (Paths) { 441212795Sdim deletePaths(Paths); 442276479Sdim Paths = nullptr; 443212795Sdim } 444212795Sdim } 445212795Sdim } 446212795Sdim 447212795Sdim template <class DeclClass> 448212795Sdim DeclClass *getAsSingle() const { 449276479Sdim if (getResultKind() != Found) return nullptr; 450212795Sdim return dyn_cast<DeclClass>(getFoundDecl()); 451212795Sdim } 452212795Sdim 453212795Sdim /// \brief Fetch the unique decl found by this lookup. Asserts 454212795Sdim /// that one was found. 455212795Sdim /// 456212795Sdim /// This is intended for users who have examined the result kind 457212795Sdim /// and are certain that there is only one result. 458212795Sdim NamedDecl *getFoundDecl() const { 459212795Sdim assert(getResultKind() == Found 460212795Sdim && "getFoundDecl called on non-unique result"); 461212795Sdim return (*begin())->getUnderlyingDecl(); 462212795Sdim } 463212795Sdim 464212795Sdim /// Fetches a representative decl. Useful for lazy diagnostics. 465212795Sdim NamedDecl *getRepresentativeDecl() const { 466212795Sdim assert(!Decls.empty() && "cannot get representative of empty set"); 467212795Sdim return *begin(); 468212795Sdim } 469212795Sdim 470212795Sdim /// \brief Asks if the result is a single tag decl. 471212795Sdim bool isSingleTagDecl() const { 472212795Sdim return getResultKind() == Found && isa<TagDecl>(getFoundDecl()); 473212795Sdim } 474212795Sdim 475212795Sdim /// \brief Make these results show that the name was found in 476212795Sdim /// base classes of different types. 477212795Sdim /// 478212795Sdim /// The given paths object is copied and invalidated. 479212795Sdim void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P); 480212795Sdim 481212795Sdim /// \brief Make these results show that the name was found in 482212795Sdim /// distinct base classes of the same type. 483212795Sdim /// 484212795Sdim /// The given paths object is copied and invalidated. 485212795Sdim void setAmbiguousBaseSubobjects(CXXBasePaths &P); 486212795Sdim 487212795Sdim /// \brief Make these results show that the name was found in 488212795Sdim /// different contexts and a tag decl was hidden by an ordinary 489212795Sdim /// decl in a different context. 490212795Sdim void setAmbiguousQualifiedTagHiding() { 491212795Sdim setAmbiguous(AmbiguousTagHiding); 492212795Sdim } 493212795Sdim 494212795Sdim /// \brief Clears out any current state. 495212795Sdim void clear() { 496212795Sdim ResultKind = NotFound; 497212795Sdim Decls.clear(); 498212795Sdim if (Paths) deletePaths(Paths); 499276479Sdim Paths = nullptr; 500276479Sdim NamingClass = nullptr; 501261991Sdim Shadowed = false; 502212795Sdim } 503212795Sdim 504212795Sdim /// \brief Clears out any current state and re-initializes for a 505212795Sdim /// different kind of lookup. 506212795Sdim void clear(Sema::LookupNameKind Kind) { 507212795Sdim clear(); 508212795Sdim LookupKind = Kind; 509212795Sdim configure(); 510212795Sdim } 511212795Sdim 512212795Sdim /// \brief Change this lookup's redeclaration kind. 513212795Sdim void setRedeclarationKind(Sema::RedeclarationKind RK) { 514212795Sdim Redecl = RK; 515212795Sdim configure(); 516212795Sdim } 517212795Sdim 518296417Sdim void dump(); 519226633Sdim void print(raw_ostream &); 520212795Sdim 521212795Sdim /// Suppress the diagnostics that would normally fire because of this 522212795Sdim /// lookup. This happens during (e.g.) redeclaration lookups. 523212795Sdim void suppressDiagnostics() { 524212795Sdim Diagnose = false; 525212795Sdim } 526212795Sdim 527212795Sdim /// Determines whether this lookup is suppressing diagnostics. 528212795Sdim bool isSuppressingDiagnostics() const { 529212795Sdim return !Diagnose; 530212795Sdim } 531212795Sdim 532212795Sdim /// Sets a 'context' source range. 533212795Sdim void setContextRange(SourceRange SR) { 534212795Sdim NameContextRange = SR; 535212795Sdim } 536212795Sdim 537212795Sdim /// Gets the source range of the context of this name; for C++ 538212795Sdim /// qualified lookups, this is the source range of the scope 539212795Sdim /// specifier. 540212795Sdim SourceRange getContextRange() const { 541212795Sdim return NameContextRange; 542212795Sdim } 543212795Sdim 544212795Sdim /// Gets the location of the identifier. This isn't always defined: 545212795Sdim /// sometimes we're doing lookups on synthesized names. 546212795Sdim SourceLocation getNameLoc() const { 547212795Sdim return NameInfo.getLoc(); 548212795Sdim } 549212795Sdim 550212795Sdim /// \brief Get the Sema object that this lookup result is searching 551212795Sdim /// with. 552280031Sdim Sema &getSema() const { return *SemaPtr; } 553212795Sdim 554212795Sdim /// A class for iterating through a result set and possibly 555212795Sdim /// filtering out results. The results returned are possibly 556212795Sdim /// sugared. 557212795Sdim class Filter { 558212795Sdim LookupResult &Results; 559212795Sdim LookupResult::iterator I; 560212795Sdim bool Changed; 561212795Sdim bool CalledDone; 562212795Sdim 563212795Sdim friend class LookupResult; 564212795Sdim Filter(LookupResult &Results) 565218893Sdim : Results(Results), I(Results.begin()), Changed(false), CalledDone(false) 566212795Sdim {} 567212795Sdim 568212795Sdim public: 569296417Sdim Filter(Filter &&F) 570296417Sdim : Results(F.Results), I(F.I), Changed(F.Changed), 571296417Sdim CalledDone(F.CalledDone) { 572296417Sdim F.CalledDone = true; 573296417Sdim } 574212795Sdim ~Filter() { 575212795Sdim assert(CalledDone && 576212795Sdim "LookupResult::Filter destroyed without done() call"); 577212795Sdim } 578212795Sdim 579212795Sdim bool hasNext() const { 580212795Sdim return I != Results.end(); 581212795Sdim } 582212795Sdim 583212795Sdim NamedDecl *next() { 584212795Sdim assert(I != Results.end() && "next() called on empty filter"); 585212795Sdim return *I++; 586212795Sdim } 587212795Sdim 588234353Sdim /// Restart the iteration. 589234353Sdim void restart() { 590234353Sdim I = Results.begin(); 591234353Sdim } 592234353Sdim 593212795Sdim /// Erase the last element returned from this iterator. 594212795Sdim void erase() { 595212795Sdim Results.Decls.erase(--I); 596212795Sdim Changed = true; 597212795Sdim } 598212795Sdim 599212795Sdim /// Replaces the current entry with the given one, preserving the 600212795Sdim /// access bits. 601212795Sdim void replace(NamedDecl *D) { 602212795Sdim Results.Decls.replace(I-1, D); 603212795Sdim Changed = true; 604212795Sdim } 605212795Sdim 606212795Sdim /// Replaces the current entry with the given one. 607212795Sdim void replace(NamedDecl *D, AccessSpecifier AS) { 608212795Sdim Results.Decls.replace(I-1, D, AS); 609212795Sdim Changed = true; 610212795Sdim } 611212795Sdim 612212795Sdim void done() { 613212795Sdim assert(!CalledDone && "done() called twice"); 614212795Sdim CalledDone = true; 615212795Sdim 616212795Sdim if (Changed) 617212795Sdim Results.resolveKindAfterFilter(); 618212795Sdim } 619212795Sdim }; 620212795Sdim 621212795Sdim /// Create a filter for this result set. 622212795Sdim Filter makeFilter() { 623212795Sdim return Filter(*this); 624212795Sdim } 625212795Sdim 626261991Sdim void setFindLocalExtern(bool FindLocalExtern) { 627261991Sdim if (FindLocalExtern) 628261991Sdim IDNS |= Decl::IDNS_LocalExtern; 629261991Sdim else 630261991Sdim IDNS &= ~Decl::IDNS_LocalExtern; 631261991Sdim } 632261991Sdim 633212795Sdimprivate: 634212795Sdim void diagnose() { 635212795Sdim if (isAmbiguous()) 636280031Sdim getSema().DiagnoseAmbiguousLookup(*this); 637280031Sdim else if (isClassLookup() && getSema().getLangOpts().AccessControl) 638280031Sdim getSema().CheckLookupAccess(*this); 639212795Sdim } 640212795Sdim 641212795Sdim void setAmbiguous(AmbiguityKind AK) { 642212795Sdim ResultKind = Ambiguous; 643212795Sdim Ambiguity = AK; 644212795Sdim } 645212795Sdim 646212795Sdim void addDeclsFromBasePaths(const CXXBasePaths &P); 647212795Sdim void configure(); 648212795Sdim 649212795Sdim // Sanity checks. 650276479Sdim bool sanity() const; 651212795Sdim 652212795Sdim bool sanityCheckUnresolved() const { 653212795Sdim for (iterator I = begin(), E = end(); I != E; ++I) 654249423Sdim if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl())) 655212795Sdim return true; 656212795Sdim return false; 657212795Sdim } 658212795Sdim 659212795Sdim static void deletePaths(CXXBasePaths *); 660212795Sdim 661212795Sdim // Results. 662212795Sdim LookupResultKind ResultKind; 663212795Sdim AmbiguityKind Ambiguity; // ill-defined unless ambiguous 664212795Sdim UnresolvedSet<8> Decls; 665212795Sdim CXXBasePaths *Paths; 666212795Sdim CXXRecordDecl *NamingClass; 667212795Sdim QualType BaseObjectType; 668212795Sdim 669212795Sdim // Parameters. 670280031Sdim Sema *SemaPtr; 671212795Sdim DeclarationNameInfo NameInfo; 672212795Sdim SourceRange NameContextRange; 673212795Sdim Sema::LookupNameKind LookupKind; 674212795Sdim unsigned IDNS; // set by configure() 675212795Sdim 676212795Sdim bool Redecl; 677212795Sdim 678212795Sdim /// \brief True if tag declarations should be hidden if non-tags 679212795Sdim /// are present 680212795Sdim bool HideTags; 681212795Sdim 682212795Sdim bool Diagnose; 683249423Sdim 684249423Sdim /// \brief True if we should allow hidden declarations to be 'visible'. 685249423Sdim bool AllowHidden; 686261991Sdim 687261991Sdim /// \brief True if the found declarations were shadowed by some other 688261991Sdim /// declaration that we skipped. This only happens when \c LookupKind 689261991Sdim /// is \c LookupRedeclarationWithLinkage. 690261991Sdim bool Shadowed; 691212795Sdim}; 692212795Sdim 693261991Sdim/// \brief Consumes visible declarations found when searching for 694261991Sdim/// all visible names within a given scope or context. 695261991Sdim/// 696261991Sdim/// This abstract class is meant to be subclassed by clients of \c 697261991Sdim/// Sema::LookupVisibleDecls(), each of which should override the \c 698261991Sdim/// FoundDecl() function to process declarations as they are found. 699261991Sdimclass VisibleDeclConsumer { 700261991Sdimpublic: 701261991Sdim /// \brief Destroys the visible declaration consumer. 702261991Sdim virtual ~VisibleDeclConsumer(); 703261991Sdim 704261991Sdim /// \brief Determine whether hidden declarations (from unimported 705261991Sdim /// modules) should be given to this consumer. By default, they 706261991Sdim /// are not included. 707261991Sdim virtual bool includeHiddenDecls() const; 708261991Sdim 709261991Sdim /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a 710261991Sdim /// declaration visible from the current scope or context. 711212795Sdim /// 712261991Sdim /// \param ND the declaration found. 713261991Sdim /// 714261991Sdim /// \param Hiding a declaration that hides the declaration \p ND, 715261991Sdim /// or NULL if no such declaration exists. 716261991Sdim /// 717261991Sdim /// \param Ctx the original context from which the lookup started. 718261991Sdim /// 719261991Sdim /// \param InBaseClass whether this declaration was found in base 720261991Sdim /// class of the context we searched. 721261991Sdim virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, 722261991Sdim bool InBaseClass) = 0; 723261991Sdim}; 724212795Sdim 725212795Sdim/// \brief A class for storing results from argument-dependent lookup. 726212795Sdimclass ADLResult { 727212795Sdimprivate: 728212795Sdim /// A map from canonical decls to the 'most recent' decl. 729212795Sdim llvm::DenseMap<NamedDecl*, NamedDecl*> Decls; 730212795Sdim 731212795Sdimpublic: 732212795Sdim /// Adds a new ADL candidate to this map. 733212795Sdim void insert(NamedDecl *D); 734212795Sdim 735212795Sdim /// Removes any data associated with a given decl. 736212795Sdim void erase(NamedDecl *D) { 737212795Sdim Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); 738212795Sdim } 739212795Sdim 740261991Sdim class iterator 741288943Sdim : public llvm::iterator_adaptor_base< 742288943Sdim iterator, llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator, 743288943Sdim std::forward_iterator_tag, NamedDecl *> { 744288943Sdim friend class ADLResult; 745212795Sdim 746288943Sdim iterator(llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator Iter) 747288943Sdim : iterator_adaptor_base(std::move(Iter)) {} 748288943Sdim 749212795Sdim public: 750212795Sdim iterator() {} 751212795Sdim 752288943Sdim value_type operator*() const { return I->second; } 753212795Sdim }; 754212795Sdim 755212795Sdim iterator begin() { return iterator(Decls.begin()); } 756212795Sdim iterator end() { return iterator(Decls.end()); } 757212795Sdim}; 758212795Sdim 759212795Sdim} 760212795Sdim 761212795Sdim#endif 762