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), 133212795Sdim Paths(0), 134212795Sdim NamingClass(0), 135212795Sdim SemaRef(SemaRef), 136212795Sdim NameInfo(NameInfo), 137212795Sdim LookupKind(LookupKind), 138212795Sdim IDNS(0), 139212795Sdim Redecl(Redecl != Sema::NotForRedeclaration), 140212795Sdim HideTags(true), 141249423Sdim Diagnose(Redecl == Sema::NotForRedeclaration), 142263508Sdim AllowHidden(Redecl == Sema::ForRedeclaration), 143263508Sdim 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), 155212795Sdim Paths(0), 156212795Sdim NamingClass(0), 157212795Sdim SemaRef(SemaRef), 158212795Sdim NameInfo(Name, NameLoc), 159212795Sdim LookupKind(LookupKind), 160212795Sdim IDNS(0), 161212795Sdim Redecl(Redecl != Sema::NotForRedeclaration), 162212795Sdim HideTags(true), 163249423Sdim Diagnose(Redecl == Sema::NotForRedeclaration), 164263508Sdim AllowHidden(Redecl == Sema::ForRedeclaration), 165263508Sdim 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), 175212795Sdim Paths(0), 176212795Sdim NamingClass(0), 177212795Sdim SemaRef(Other.SemaRef), 178212795Sdim NameInfo(Other.NameInfo), 179212795Sdim LookupKind(Other.LookupKind), 180212795Sdim IDNS(Other.IDNS), 181212795Sdim Redecl(Other.Redecl), 182212795Sdim HideTags(Other.HideTags), 183249423Sdim Diagnose(false), 184263508Sdim AllowHidden(Other.AllowHidden), 185263508Sdim 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. 231234353Sdim bool isHiddenDeclarationVisible() const { 232249423Sdim return AllowHidden || LookupKind == Sema::LookupTagName; 233234353Sdim } 234234353Sdim 235212795Sdim /// Sets whether tag declarations should be hidden by non-tag 236212795Sdim /// declarations during resolution. The default is true. 237212795Sdim void setHideTags(bool Hide) { 238212795Sdim HideTags = Hide; 239212795Sdim } 240212795Sdim 241212795Sdim bool isAmbiguous() const { 242212795Sdim return getResultKind() == Ambiguous; 243212795Sdim } 244212795Sdim 245212795Sdim /// Determines if this names a single result which is not an 246212795Sdim /// unresolved value using decl. If so, it is safe to call 247212795Sdim /// getFoundDecl(). 248212795Sdim bool isSingleResult() const { 249212795Sdim return getResultKind() == Found; 250212795Sdim } 251212795Sdim 252212795Sdim /// Determines if the results are overloaded. 253212795Sdim bool isOverloadedResult() const { 254212795Sdim return getResultKind() == FoundOverloaded; 255212795Sdim } 256212795Sdim 257212795Sdim bool isUnresolvableResult() const { 258212795Sdim return getResultKind() == FoundUnresolvedValue; 259212795Sdim } 260212795Sdim 261212795Sdim LookupResultKind getResultKind() const { 262212795Sdim sanity(); 263212795Sdim return ResultKind; 264212795Sdim } 265212795Sdim 266212795Sdim AmbiguityKind getAmbiguityKind() const { 267212795Sdim assert(isAmbiguous()); 268212795Sdim return Ambiguity; 269212795Sdim } 270212795Sdim 271212795Sdim const UnresolvedSetImpl &asUnresolvedSet() const { 272212795Sdim return Decls; 273212795Sdim } 274212795Sdim 275212795Sdim iterator begin() const { return iterator(Decls.begin()); } 276212795Sdim iterator end() const { return iterator(Decls.end()); } 277212795Sdim 278212795Sdim /// \brief Return true if no decls were found 279212795Sdim bool empty() const { return Decls.empty(); } 280212795Sdim 281212795Sdim /// \brief Return the base paths structure that's associated with 282212795Sdim /// these results, or null if none is. 283212795Sdim CXXBasePaths *getBasePaths() const { 284212795Sdim return Paths; 285212795Sdim } 286212795Sdim 287234353Sdim /// \brief Determine whether the given declaration is visible to the 288234353Sdim /// program. 289263508Sdim static bool isVisible(Sema &SemaRef, NamedDecl *D) { 290234353Sdim // If this declaration is not hidden, it's visible. 291234353Sdim if (!D->isHidden()) 292234353Sdim return true; 293263508Sdim 294263508Sdim if (SemaRef.ActiveTemplateInstantiations.empty()) 295263508Sdim return false; 296263508Sdim 297263508Sdim // During template instantiation, we can refer to hidden declarations, if 298263508Sdim // they were visible in any module along the path of instantiation. 299263508Sdim return isVisibleSlow(SemaRef, D); 300212795Sdim } 301263508Sdim 302234353Sdim /// \brief Retrieve the accepted (re)declaration of the given declaration, 303234353Sdim /// if there is one. 304234353Sdim NamedDecl *getAcceptableDecl(NamedDecl *D) const { 305234353Sdim if (!D->isInIdentifierNamespace(IDNS)) 306234353Sdim return 0; 307263508Sdim 308263508Sdim if (isHiddenDeclarationVisible() || isVisible(SemaRef, D)) 309234353Sdim return D; 310263508Sdim 311234353Sdim return getAcceptableDeclSlow(D); 312234353Sdim } 313263508Sdim 314234353Sdimprivate: 315263508Sdim static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D); 316234353Sdim NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const; 317263508Sdim 318234353Sdimpublic: 319212795Sdim /// \brief Returns the identifier namespace mask for this lookup. 320212795Sdim unsigned getIdentifierNamespace() const { 321212795Sdim return IDNS; 322212795Sdim } 323212795Sdim 324212795Sdim /// \brief Returns whether these results arose from performing a 325212795Sdim /// lookup into a class. 326212795Sdim bool isClassLookup() const { 327212795Sdim return NamingClass != 0; 328212795Sdim } 329212795Sdim 330212795Sdim /// \brief Returns the 'naming class' for this lookup, i.e. the 331212795Sdim /// class which was looked into to find these results. 332212795Sdim /// 333212795Sdim /// C++0x [class.access.base]p5: 334212795Sdim /// The access to a member is affected by the class in which the 335212795Sdim /// member is named. This naming class is the class in which the 336212795Sdim /// member name was looked up and found. [Note: this class can be 337212795Sdim /// explicit, e.g., when a qualified-id is used, or implicit, 338212795Sdim /// e.g., when a class member access operator (5.2.5) is used 339212795Sdim /// (including cases where an implicit "this->" is added). If both 340212795Sdim /// a class member access operator and a qualified-id are used to 341212795Sdim /// name the member (as in p->T::m), the class naming the member 342212795Sdim /// is the class named by the nested-name-specifier of the 343212795Sdim /// qualified-id (that is, T). -- end note ] 344212795Sdim /// 345212795Sdim /// This is set by the lookup routines when they find results in a class. 346212795Sdim CXXRecordDecl *getNamingClass() const { 347212795Sdim return NamingClass; 348212795Sdim } 349212795Sdim 350212795Sdim /// \brief Sets the 'naming class' for this lookup. 351212795Sdim void setNamingClass(CXXRecordDecl *Record) { 352212795Sdim NamingClass = Record; 353212795Sdim } 354212795Sdim 355212795Sdim /// \brief Returns the base object type associated with this lookup; 356212795Sdim /// important for [class.protected]. Most lookups do not have an 357212795Sdim /// associated base object. 358212795Sdim QualType getBaseObjectType() const { 359212795Sdim return BaseObjectType; 360212795Sdim } 361212795Sdim 362212795Sdim /// \brief Sets the base object type for this lookup. 363212795Sdim void setBaseObjectType(QualType T) { 364212795Sdim BaseObjectType = T; 365212795Sdim } 366212795Sdim 367212795Sdim /// \brief Add a declaration to these results with its natural access. 368212795Sdim /// Does not test the acceptance criteria. 369212795Sdim void addDecl(NamedDecl *D) { 370212795Sdim addDecl(D, D->getAccess()); 371212795Sdim } 372212795Sdim 373212795Sdim /// \brief Add a declaration to these results with the given access. 374212795Sdim /// Does not test the acceptance criteria. 375212795Sdim void addDecl(NamedDecl *D, AccessSpecifier AS) { 376212795Sdim Decls.addDecl(D, AS); 377212795Sdim ResultKind = Found; 378212795Sdim } 379212795Sdim 380212795Sdim /// \brief Add all the declarations from another set of lookup 381212795Sdim /// results. 382212795Sdim void addAllDecls(const LookupResult &Other) { 383212795Sdim Decls.append(Other.Decls.begin(), Other.Decls.end()); 384212795Sdim ResultKind = Found; 385212795Sdim } 386212795Sdim 387212795Sdim /// \brief Determine whether no result was found because we could not 388212795Sdim /// search into dependent base classes of the current instantiation. 389212795Sdim bool wasNotFoundInCurrentInstantiation() const { 390212795Sdim return ResultKind == NotFoundInCurrentInstantiation; 391212795Sdim } 392212795Sdim 393212795Sdim /// \brief Note that while no result was found in the current instantiation, 394212795Sdim /// there were dependent base classes that could not be searched. 395212795Sdim void setNotFoundInCurrentInstantiation() { 396212795Sdim assert(ResultKind == NotFound && Decls.empty()); 397212795Sdim ResultKind = NotFoundInCurrentInstantiation; 398212795Sdim } 399263508Sdim 400263508Sdim /// \brief Determine whether the lookup result was shadowed by some other 401263508Sdim /// declaration that lookup ignored. 402263508Sdim bool isShadowed() const { return Shadowed; } 403263508Sdim 404263508Sdim /// \brief Note that we found and ignored a declaration while performing 405263508Sdim /// lookup. 406263508Sdim void setShadowed() { Shadowed = true; } 407263508Sdim 408212795Sdim /// \brief Resolves the result kind of the lookup, possibly hiding 409212795Sdim /// decls. 410212795Sdim /// 411212795Sdim /// This should be called in any environment where lookup might 412212795Sdim /// generate multiple lookup results. 413212795Sdim void resolveKind(); 414212795Sdim 415212795Sdim /// \brief Re-resolves the result kind of the lookup after a set of 416212795Sdim /// removals has been performed. 417212795Sdim void resolveKindAfterFilter() { 418212795Sdim if (Decls.empty()) { 419212795Sdim if (ResultKind != NotFoundInCurrentInstantiation) 420212795Sdim ResultKind = NotFound; 421218893Sdim 422218893Sdim if (Paths) { 423218893Sdim deletePaths(Paths); 424218893Sdim Paths = 0; 425218893Sdim } 426212795Sdim } else { 427212795Sdim AmbiguityKind SavedAK = Ambiguity; 428212795Sdim ResultKind = Found; 429212795Sdim resolveKind(); 430212795Sdim 431212795Sdim // If we didn't make the lookup unambiguous, restore the old 432212795Sdim // ambiguity kind. 433212795Sdim if (ResultKind == Ambiguous) { 434212795Sdim Ambiguity = SavedAK; 435212795Sdim } else if (Paths) { 436212795Sdim deletePaths(Paths); 437212795Sdim Paths = 0; 438212795Sdim } 439212795Sdim } 440212795Sdim } 441212795Sdim 442212795Sdim template <class DeclClass> 443212795Sdim DeclClass *getAsSingle() const { 444212795Sdim if (getResultKind() != Found) return 0; 445212795Sdim return dyn_cast<DeclClass>(getFoundDecl()); 446212795Sdim } 447212795Sdim 448212795Sdim /// \brief Fetch the unique decl found by this lookup. Asserts 449212795Sdim /// that one was found. 450212795Sdim /// 451212795Sdim /// This is intended for users who have examined the result kind 452212795Sdim /// and are certain that there is only one result. 453212795Sdim NamedDecl *getFoundDecl() const { 454212795Sdim assert(getResultKind() == Found 455212795Sdim && "getFoundDecl called on non-unique result"); 456212795Sdim return (*begin())->getUnderlyingDecl(); 457212795Sdim } 458212795Sdim 459212795Sdim /// Fetches a representative decl. Useful for lazy diagnostics. 460212795Sdim NamedDecl *getRepresentativeDecl() const { 461212795Sdim assert(!Decls.empty() && "cannot get representative of empty set"); 462212795Sdim return *begin(); 463212795Sdim } 464212795Sdim 465212795Sdim /// \brief Asks if the result is a single tag decl. 466212795Sdim bool isSingleTagDecl() const { 467212795Sdim return getResultKind() == Found && isa<TagDecl>(getFoundDecl()); 468212795Sdim } 469212795Sdim 470212795Sdim /// \brief Make these results show that the name was found in 471212795Sdim /// base classes of different types. 472212795Sdim /// 473212795Sdim /// The given paths object is copied and invalidated. 474212795Sdim void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P); 475212795Sdim 476212795Sdim /// \brief Make these results show that the name was found in 477212795Sdim /// distinct base classes of the same type. 478212795Sdim /// 479212795Sdim /// The given paths object is copied and invalidated. 480212795Sdim void setAmbiguousBaseSubobjects(CXXBasePaths &P); 481212795Sdim 482212795Sdim /// \brief Make these results show that the name was found in 483212795Sdim /// different contexts and a tag decl was hidden by an ordinary 484212795Sdim /// decl in a different context. 485212795Sdim void setAmbiguousQualifiedTagHiding() { 486212795Sdim setAmbiguous(AmbiguousTagHiding); 487212795Sdim } 488212795Sdim 489212795Sdim /// \brief Clears out any current state. 490212795Sdim void clear() { 491212795Sdim ResultKind = NotFound; 492212795Sdim Decls.clear(); 493212795Sdim if (Paths) deletePaths(Paths); 494212795Sdim Paths = NULL; 495221345Sdim NamingClass = 0; 496263508Sdim Shadowed = false; 497212795Sdim } 498212795Sdim 499212795Sdim /// \brief Clears out any current state and re-initializes for a 500212795Sdim /// different kind of lookup. 501212795Sdim void clear(Sema::LookupNameKind Kind) { 502212795Sdim clear(); 503212795Sdim LookupKind = Kind; 504212795Sdim configure(); 505212795Sdim } 506212795Sdim 507212795Sdim /// \brief Change this lookup's redeclaration kind. 508212795Sdim void setRedeclarationKind(Sema::RedeclarationKind RK) { 509212795Sdim Redecl = RK; 510249423Sdim AllowHidden = (RK == Sema::ForRedeclaration); 511212795Sdim configure(); 512212795Sdim } 513212795Sdim 514226633Sdim void print(raw_ostream &); 515212795Sdim 516212795Sdim /// Suppress the diagnostics that would normally fire because of this 517212795Sdim /// lookup. This happens during (e.g.) redeclaration lookups. 518212795Sdim void suppressDiagnostics() { 519212795Sdim Diagnose = false; 520212795Sdim } 521212795Sdim 522212795Sdim /// Determines whether this lookup is suppressing diagnostics. 523212795Sdim bool isSuppressingDiagnostics() const { 524212795Sdim return !Diagnose; 525212795Sdim } 526212795Sdim 527212795Sdim /// Sets a 'context' source range. 528212795Sdim void setContextRange(SourceRange SR) { 529212795Sdim NameContextRange = SR; 530212795Sdim } 531212795Sdim 532212795Sdim /// Gets the source range of the context of this name; for C++ 533212795Sdim /// qualified lookups, this is the source range of the scope 534212795Sdim /// specifier. 535212795Sdim SourceRange getContextRange() const { 536212795Sdim return NameContextRange; 537212795Sdim } 538212795Sdim 539212795Sdim /// Gets the location of the identifier. This isn't always defined: 540212795Sdim /// sometimes we're doing lookups on synthesized names. 541212795Sdim SourceLocation getNameLoc() const { 542212795Sdim return NameInfo.getLoc(); 543212795Sdim } 544212795Sdim 545212795Sdim /// \brief Get the Sema object that this lookup result is searching 546212795Sdim /// with. 547212795Sdim Sema &getSema() const { return SemaRef; } 548212795Sdim 549212795Sdim /// A class for iterating through a result set and possibly 550212795Sdim /// filtering out results. The results returned are possibly 551212795Sdim /// sugared. 552212795Sdim class Filter { 553212795Sdim LookupResult &Results; 554212795Sdim LookupResult::iterator I; 555212795Sdim bool Changed; 556212795Sdim bool CalledDone; 557212795Sdim 558212795Sdim friend class LookupResult; 559212795Sdim Filter(LookupResult &Results) 560218893Sdim : Results(Results), I(Results.begin()), Changed(false), CalledDone(false) 561212795Sdim {} 562212795Sdim 563212795Sdim public: 564212795Sdim ~Filter() { 565212795Sdim assert(CalledDone && 566212795Sdim "LookupResult::Filter destroyed without done() call"); 567212795Sdim } 568212795Sdim 569212795Sdim bool hasNext() const { 570212795Sdim return I != Results.end(); 571212795Sdim } 572212795Sdim 573212795Sdim NamedDecl *next() { 574212795Sdim assert(I != Results.end() && "next() called on empty filter"); 575212795Sdim return *I++; 576212795Sdim } 577212795Sdim 578234353Sdim /// Restart the iteration. 579234353Sdim void restart() { 580234353Sdim I = Results.begin(); 581234353Sdim } 582234353Sdim 583212795Sdim /// Erase the last element returned from this iterator. 584212795Sdim void erase() { 585212795Sdim Results.Decls.erase(--I); 586212795Sdim Changed = true; 587212795Sdim } 588212795Sdim 589212795Sdim /// Replaces the current entry with the given one, preserving the 590212795Sdim /// access bits. 591212795Sdim void replace(NamedDecl *D) { 592212795Sdim Results.Decls.replace(I-1, D); 593212795Sdim Changed = true; 594212795Sdim } 595212795Sdim 596212795Sdim /// Replaces the current entry with the given one. 597212795Sdim void replace(NamedDecl *D, AccessSpecifier AS) { 598212795Sdim Results.Decls.replace(I-1, D, AS); 599212795Sdim Changed = true; 600212795Sdim } 601212795Sdim 602212795Sdim void done() { 603212795Sdim assert(!CalledDone && "done() called twice"); 604212795Sdim CalledDone = true; 605212795Sdim 606212795Sdim if (Changed) 607212795Sdim Results.resolveKindAfterFilter(); 608212795Sdim } 609212795Sdim }; 610212795Sdim 611212795Sdim /// Create a filter for this result set. 612212795Sdim Filter makeFilter() { 613212795Sdim return Filter(*this); 614212795Sdim } 615212795Sdim 616263508Sdim void setFindLocalExtern(bool FindLocalExtern) { 617263508Sdim if (FindLocalExtern) 618263508Sdim IDNS |= Decl::IDNS_LocalExtern; 619263508Sdim else 620263508Sdim IDNS &= ~Decl::IDNS_LocalExtern; 621263508Sdim } 622263508Sdim 623212795Sdimprivate: 624212795Sdim void diagnose() { 625212795Sdim if (isAmbiguous()) 626212795Sdim SemaRef.DiagnoseAmbiguousLookup(*this); 627234353Sdim else if (isClassLookup() && SemaRef.getLangOpts().AccessControl) 628212795Sdim SemaRef.CheckLookupAccess(*this); 629212795Sdim } 630212795Sdim 631212795Sdim void setAmbiguous(AmbiguityKind AK) { 632212795Sdim ResultKind = Ambiguous; 633212795Sdim Ambiguity = AK; 634212795Sdim } 635212795Sdim 636212795Sdim void addDeclsFromBasePaths(const CXXBasePaths &P); 637212795Sdim void configure(); 638212795Sdim 639212795Sdim // Sanity checks. 640234353Sdim void sanityImpl() const; 641212795Sdim 642234353Sdim void sanity() const { 643234353Sdim#ifndef NDEBUG 644234353Sdim sanityImpl(); 645234353Sdim#endif 646234353Sdim } 647234353Sdim 648212795Sdim bool sanityCheckUnresolved() const { 649212795Sdim for (iterator I = begin(), E = end(); I != E; ++I) 650249423Sdim if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl())) 651212795Sdim return true; 652212795Sdim return false; 653212795Sdim } 654212795Sdim 655212795Sdim static void deletePaths(CXXBasePaths *); 656212795Sdim 657212795Sdim // Results. 658212795Sdim LookupResultKind ResultKind; 659212795Sdim AmbiguityKind Ambiguity; // ill-defined unless ambiguous 660212795Sdim UnresolvedSet<8> Decls; 661212795Sdim CXXBasePaths *Paths; 662212795Sdim CXXRecordDecl *NamingClass; 663212795Sdim QualType BaseObjectType; 664212795Sdim 665212795Sdim // Parameters. 666212795Sdim Sema &SemaRef; 667212795Sdim DeclarationNameInfo NameInfo; 668212795Sdim SourceRange NameContextRange; 669212795Sdim Sema::LookupNameKind LookupKind; 670212795Sdim unsigned IDNS; // set by configure() 671212795Sdim 672212795Sdim bool Redecl; 673212795Sdim 674212795Sdim /// \brief True if tag declarations should be hidden if non-tags 675212795Sdim /// are present 676212795Sdim bool HideTags; 677212795Sdim 678212795Sdim bool Diagnose; 679249423Sdim 680249423Sdim /// \brief True if we should allow hidden declarations to be 'visible'. 681249423Sdim bool AllowHidden; 682263508Sdim 683263508Sdim /// \brief True if the found declarations were shadowed by some other 684263508Sdim /// declaration that we skipped. This only happens when \c LookupKind 685263508Sdim /// is \c LookupRedeclarationWithLinkage. 686263508Sdim bool Shadowed; 687212795Sdim}; 688212795Sdim 689263508Sdim/// \brief Consumes visible declarations found when searching for 690263508Sdim/// all visible names within a given scope or context. 691263508Sdim/// 692263508Sdim/// This abstract class is meant to be subclassed by clients of \c 693263508Sdim/// Sema::LookupVisibleDecls(), each of which should override the \c 694263508Sdim/// FoundDecl() function to process declarations as they are found. 695263508Sdimclass VisibleDeclConsumer { 696263508Sdimpublic: 697263508Sdim /// \brief Destroys the visible declaration consumer. 698263508Sdim virtual ~VisibleDeclConsumer(); 699263508Sdim 700263508Sdim /// \brief Determine whether hidden declarations (from unimported 701263508Sdim /// modules) should be given to this consumer. By default, they 702263508Sdim /// are not included. 703263508Sdim virtual bool includeHiddenDecls() const; 704263508Sdim 705263508Sdim /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a 706263508Sdim /// declaration visible from the current scope or context. 707212795Sdim /// 708263508Sdim /// \param ND the declaration found. 709263508Sdim /// 710263508Sdim /// \param Hiding a declaration that hides the declaration \p ND, 711263508Sdim /// or NULL if no such declaration exists. 712263508Sdim /// 713263508Sdim /// \param Ctx the original context from which the lookup started. 714263508Sdim /// 715263508Sdim /// \param InBaseClass whether this declaration was found in base 716263508Sdim /// class of the context we searched. 717263508Sdim virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, 718263508Sdim bool InBaseClass) = 0; 719263508Sdim}; 720212795Sdim 721212795Sdim/// \brief A class for storing results from argument-dependent lookup. 722212795Sdimclass ADLResult { 723212795Sdimprivate: 724212795Sdim /// A map from canonical decls to the 'most recent' decl. 725212795Sdim llvm::DenseMap<NamedDecl*, NamedDecl*> Decls; 726212795Sdim 727212795Sdimpublic: 728212795Sdim /// Adds a new ADL candidate to this map. 729212795Sdim void insert(NamedDecl *D); 730212795Sdim 731212795Sdim /// Removes any data associated with a given decl. 732212795Sdim void erase(NamedDecl *D) { 733212795Sdim Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); 734212795Sdim } 735212795Sdim 736263508Sdim class iterator 737263508Sdim : public std::iterator<std::forward_iterator_tag, NamedDecl *> { 738212795Sdim typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator; 739212795Sdim inner_iterator iter; 740212795Sdim 741212795Sdim friend class ADLResult; 742212795Sdim iterator(const inner_iterator &iter) : iter(iter) {} 743212795Sdim public: 744212795Sdim iterator() {} 745212795Sdim 746212795Sdim iterator &operator++() { ++iter; return *this; } 747212795Sdim iterator operator++(int) { return iterator(iter++); } 748212795Sdim 749263508Sdim value_type operator*() const { return iter->second; } 750212795Sdim 751212795Sdim bool operator==(const iterator &other) const { return iter == other.iter; } 752212795Sdim bool operator!=(const iterator &other) const { return iter != other.iter; } 753212795Sdim }; 754212795Sdim 755212795Sdim iterator begin() { return iterator(Decls.begin()); } 756212795Sdim iterator end() { return iterator(Decls.end()); } 757212795Sdim}; 758212795Sdim 759212795Sdim} 760212795Sdim 761212795Sdim#endif 762