zcov: / lib/Sema/Lookup.h


Files: 1 Branches Taken: 75.0% 72 / 96
Generated: 2010-02-10 01:31 Branches Executed: 97.9% 94 / 96
Line Coverage: 99.4% 174 / 175


Programs: 30 Runs 45270


       1                 : //===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This file defines the LookupResult class, which is integral to
      11                 : // Sema's name-lookup subsystem.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : 
      15                 : #ifndef LLVM_CLANG_SEMA_LOOKUP_H
      16                 : #define LLVM_CLANG_SEMA_LOOKUP_H
      17                 : 
      18                 : #include "Sema.h"
      19                 : 
      20                 : namespace clang {
      21                 : 
      22                 : /// @brief Represents the results of name lookup.
      23                 : ///
      24                 : /// An instance of the LookupResult class captures the results of a
      25                 : /// single name lookup, which can return no result (nothing found),
      26                 : /// a single declaration, a set of overloaded functions, or an
      27                 : /// ambiguity. Use the getKind() method to determine which of these
      28                 : /// results occurred for a given lookup.
      29                 : class LookupResult {
      30                 : public:
      31                 :   enum LookupResultKind {
      32                 :     /// @brief No entity found met the criteria.
      33                 :     NotFound = 0,
      34                 : 
      35                 :     /// @brief No entity found met the criteria within the current 
      36                 :     /// instantiation,, but there were dependent base classes of the 
      37                 :     /// current instantiation that could not be searched.
      38                 :     NotFoundInCurrentInstantiation,
      39                 :     
      40                 :     /// @brief Name lookup found a single declaration that met the
      41                 :     /// criteria.  getFoundDecl() will return this declaration.
      42                 :     Found,
      43                 : 
      44                 :     /// @brief Name lookup found a set of overloaded functions that
      45                 :     /// met the criteria.
      46                 :     FoundOverloaded,
      47                 : 
      48                 :     /// @brief Name lookup found an unresolvable value declaration
      49                 :     /// and cannot yet complete.  This only happens in C++ dependent
      50                 :     /// contexts with dependent using declarations.
      51                 :     FoundUnresolvedValue,
      52                 : 
      53                 :     /// @brief Name lookup results in an ambiguity; use
      54                 :     /// getAmbiguityKind to figure out what kind of ambiguity
      55                 :     /// we have.
      56                 :     Ambiguous
      57                 :   };
      58                 : 
      59                 :   enum AmbiguityKind {
      60                 :     /// Name lookup results in an ambiguity because multiple
      61                 :     /// entities that meet the lookup criteria were found in
      62                 :     /// subobjects of different types. For example:
      63                 :     /// @code
      64                 :     /// struct A { void f(int); }
      65                 :     /// struct B { void f(double); }
      66                 :     /// struct C : A, B { };
      67                 :     /// void test(C c) {
      68                 :     ///   c.f(0); // error: A::f and B::f come from subobjects of different
      69                 :     ///           // types. overload resolution is not performed.
      70                 :     /// }
      71                 :     /// @endcode
      72                 :     AmbiguousBaseSubobjectTypes,
      73                 : 
      74                 :     /// Name lookup results in an ambiguity because multiple
      75                 :     /// nonstatic entities that meet the lookup criteria were found
      76                 :     /// in different subobjects of the same type. For example:
      77                 :     /// @code
      78                 :     /// struct A { int x; };
      79                 :     /// struct B : A { };
      80                 :     /// struct C : A { };
      81                 :     /// struct D : B, C { };
      82                 :     /// int test(D d) {
      83                 :     ///   return d.x; // error: 'x' is found in two A subobjects (of B and C)
      84                 :     /// }
      85                 :     /// @endcode
      86                 :     AmbiguousBaseSubobjects,
      87                 : 
      88                 :     /// Name lookup results in an ambiguity because multiple definitions
      89                 :     /// of entity that meet the lookup criteria were found in different
      90                 :     /// declaration contexts.
      91                 :     /// @code
      92                 :     /// namespace A {
      93                 :     ///   int i;
      94                 :     ///   namespace B { int i; }
      95                 :     ///   int test() {
      96                 :     ///     using namespace B;
      97                 :     ///     return i; // error 'i' is found in namespace A and A::B
      98                 :     ///    }
      99                 :     /// }
     100                 :     /// @endcode
     101                 :     AmbiguousReference,
     102                 : 
     103                 :     /// Name lookup results in an ambiguity because an entity with a
     104                 :     /// tag name was hidden by an entity with an ordinary name from
     105                 :     /// a different context.
     106                 :     /// @code
     107                 :     /// namespace A { struct Foo {}; }
     108                 :     /// namespace B { void Foo(); }
     109                 :     /// namespace C {
     110                 :     ///   using namespace A;
     111                 :     ///   using namespace B;
     112                 :     /// }
     113                 :     /// void test() {
     114                 :     ///   C::Foo(); // error: tag 'A::Foo' is hidden by an object in a
     115                 :     ///             // different namespace
     116                 :     /// }
     117                 :     /// @endcode
     118                 :     AmbiguousTagHiding
     119                 :   };
     120                 : 
     121                 :   /// A little identifier for flagging temporary lookup results.
     122                 :   enum TemporaryToken {
     123                 :     Temporary
     124                 :   };
     125                 : 
     126                 :   typedef UnresolvedSetImpl::iterator iterator;
     127                 :   typedef bool (*ResultFilter)(NamedDecl*, unsigned IDNS);
     128                 : 
     129                 :   LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
     130                 :                Sema::LookupNameKind LookupKind,
     131           140418:                Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
     132                 :     : ResultKind(NotFound),
     133                 :       Paths(0),
     134                 :       NamingClass(0),
     135                 :       SemaRef(SemaRef),
     136                 :       Name(Name),
     137                 :       NameLoc(NameLoc),
     138                 :       LookupKind(LookupKind),
     139                 :       IsAcceptableFn(0),
     140                 :       IDNS(0),
     141                 :       Redecl(Redecl != Sema::NotForRedeclaration),
     142                 :       HideTags(true),
     143           140418:       Diagnose(Redecl == Sema::NotForRedeclaration)
     144                 :   {
     145           140418:     configure();
     146           140418:   }
     147                 : 
     148                 :   /// Creates a temporary lookup result, initializing its core data
     149                 :   /// using the information from another result.  Diagnostics are always
     150                 :   /// disabled.
     151               61:   LookupResult(TemporaryToken _, const LookupResult &Other)
     152                 :     : ResultKind(NotFound),
     153                 :       Paths(0),
     154                 :       NamingClass(0),
     155                 :       SemaRef(Other.SemaRef),
     156                 :       Name(Other.Name),
     157                 :       NameLoc(Other.NameLoc),
     158                 :       LookupKind(Other.LookupKind),
     159                 :       IsAcceptableFn(Other.IsAcceptableFn),
     160                 :       IDNS(Other.IDNS),
     161                 :       Redecl(Other.Redecl),
     162                 :       HideTags(Other.HideTags),
     163               61:       Diagnose(false)
     164               61:   {}
     165                 : 
     166           140479:   ~LookupResult() {
                    78385: branch 0 taken
                    62094: branch 1 taken
     167           140479:     if (Diagnose) diagnose();
                       30: branch 0 taken
                   140449: branch 1 taken
     168           140479:     if (Paths) deletePaths(Paths);
     169           140479:   }
     170                 : 
     171                 :   /// Gets the name to look up.
     172           332992:   DeclarationName getLookupName() const {
     173           332992:     return Name;
     174                 :   }
     175                 : 
     176                 :   /// \brief Sets the name to look up.
     177               61:   void setLookupName(DeclarationName Name) {
     178               61:     this->Name = Name;
     179               61:   }
     180                 : 
     181                 :   /// Gets the kind of lookup to perform.
     182           136952:   Sema::LookupNameKind getLookupKind() const {
     183           136952:     return LookupKind;
     184                 :   }
     185                 : 
     186                 :   /// True if this lookup is just looking for an existing declaration.
     187           194765:   bool isForRedeclaration() const {
     188           194765:     return Redecl;
     189                 :   }
     190                 : 
     191                 :   /// Sets whether tag declarations should be hidden by non-tag
     192                 :   /// declarations during resolution.  The default is true.
     193              239:   void setHideTags(bool Hide) {
     194              239:     HideTags = Hide;
     195              239:   }
     196                 : 
     197           121162:   bool isAmbiguous() const {
     198           121162:     return getResultKind() == Ambiguous;
     199                 :   }
     200                 : 
     201                 :   /// Determines if this names a single result which is not an
     202                 :   /// unresolved value using decl.  If so, it is safe to call
     203                 :   /// getFoundDecl().
     204            86245:   bool isSingleResult() const {
     205            86245:     return getResultKind() == Found;
     206                 :   }
     207                 : 
     208                 :   /// Determines if the results are overloaded.
     209             3499:   bool isOverloadedResult() const {
     210             3499:     return getResultKind() == FoundOverloaded;
     211                 :   }
     212                 : 
     213             3076:   bool isUnresolvableResult() const {
     214             3076:     return getResultKind() == FoundUnresolvedValue;
     215                 :   }
     216                 : 
     217           514755:   LookupResultKind getResultKind() const {
     218           514755:     sanity();
     219           514755:     return ResultKind;
     220                 :   }
     221                 : 
     222               52:   AmbiguityKind getAmbiguityKind() const {
                        0: branch 1 not taken
                       52: branch 2 taken
     223               52:     assert(isAmbiguous());
     224               52:     return Ambiguity;
     225                 :   }
     226                 : 
     227                 :   const UnresolvedSetImpl &asUnresolvedSet() const {
     228                 :     return Decls;
     229                 :   }
     230                 : 
     231           220897:   iterator begin() const { return iterator(Decls.begin()); }
     232            59093:   iterator end() const { return iterator(Decls.end()); }
     233                 : 
     234                 :   /// \brief Return true if no decls were found
     235           189592:   bool empty() const { return Decls.empty(); }
     236                 : 
     237                 :   /// \brief Return the base paths structure that's associated with
     238                 :   /// these results, or null if none is.
     239               21:   CXXBasePaths *getBasePaths() const {
     240               21:     return Paths;
     241                 :   }
     242                 : 
     243                 :   /// \brief Tests whether the given declaration is acceptable.
     244            52717:   bool isAcceptableDecl(NamedDecl *D) const {
                        0: branch 0 not taken
                    52717: branch 1 taken
     245            52717:     assert(IsAcceptableFn);
     246            52717:     return IsAcceptableFn(D, IDNS);
     247                 :   }
     248                 : 
     249                 :   /// \brief Returns the identifier namespace mask for this lookup.
     250            78743:   unsigned getIdentifierNamespace() const {
     251            78743:     return IDNS;
     252                 :   }
     253                 : 
     254                 :   /// \brief Returns whether these results arose from performing a
     255                 :   /// lookup into a class.
     256            78352:   bool isClassLookup() const {
     257            78352:     return NamingClass != 0;
     258                 :   }
     259                 : 
     260                 :   /// \brief Returns the 'naming class' for this lookup, i.e. the
     261                 :   /// class which was looked into to find these results.
     262                 :   ///
     263                 :   /// C++0x [class.access.base]p5:
     264                 :   ///   The access to a member is affected by the class in which the
     265                 :   ///   member is named. This naming class is the class in which the
     266                 :   ///   member name was looked up and found. [Note: this class can be
     267                 :   ///   explicit, e.g., when a qualified-id is used, or implicit,
     268                 :   ///   e.g., when a class member access operator (5.2.5) is used
     269                 :   ///   (including cases where an implicit "this->" is added). If both
     270                 :   ///   a class member access operator and a qualified-id are used to
     271                 :   ///   name the member (as in p->T::m), the class naming the member
     272                 :   ///   is the class named by the nested-name-specifier of the
     273                 :   ///   qualified-id (that is, T). -- end note ]
     274                 :   ///
     275                 :   /// This is set by the lookup routines when they find results in a class.
     276             1820:   CXXRecordDecl *getNamingClass() const {
     277             1820:     return NamingClass;
     278                 :   }
     279                 : 
     280                 :   /// \brief Sets the 'naming class' for this lookup.
     281             4255:   void setNamingClass(CXXRecordDecl *Record) {
     282             4255:     NamingClass = Record;
     283             4255:   }
     284                 : 
     285                 :   /// \brief Add a declaration to these results with its natural access.
     286                 :   /// Does not test the acceptance criteria.
     287            94739:   void addDecl(NamedDecl *D) {
     288            94739:     addDecl(D, D->getAccess());
     289            94739:   }
     290                 : 
     291                 :   /// \brief Add a declaration to these results with the given access.
     292                 :   /// Does not test the acceptance criteria.
     293            95184:   void addDecl(NamedDecl *D, AccessSpecifier AS) {
     294            95184:     Decls.addDecl(D, AS);
     295            95184:     ResultKind = Found;
     296            95184:   }
     297                 : 
     298                 :   /// \brief Add all the declarations from another set of lookup
     299                 :   /// results.
     300               32:   void addAllDecls(const LookupResult &Other) {
     301               32:     Decls.append(Other.Decls.begin(), Other.Decls.end());
     302               32:     ResultKind = Found;
     303               32:   }
     304                 : 
     305                 :   /// \brief Determine whether no result was found because we could not
     306                 :   /// search into dependent base classes of the current instantiation.
     307                8:   bool wasNotFoundInCurrentInstantiation() const {
     308                8:     return ResultKind == NotFoundInCurrentInstantiation;
     309                 :   }
     310                 :   
     311                 :   /// \brief Note that while no result was found in the current instantiation,
     312                 :   /// there were dependent base classes that could not be searched.
     313                7:   void setNotFoundInCurrentInstantiation() {
                        7: branch 0 taken
                        0: branch 1 not taken
                        0: branch 3 not taken
                        7: branch 4 taken
     314                7:     assert(ResultKind == NotFound && Decls.empty());
     315                7:     ResultKind = NotFoundInCurrentInstantiation;
     316                7:   }
     317                 :   
     318                 :   /// \brief Resolves the result kind of the lookup, possibly hiding
     319                 :   /// decls.
     320                 :   ///
     321                 :   /// This should be called in any environment where lookup might
     322                 :   /// generate multiple lookup results.
     323                 :   void resolveKind();
     324                 : 
     325                 :   /// \brief Re-resolves the result kind of the lookup after a set of
     326                 :   /// removals has been performed.
     327              882:   void resolveKindAfterFilter() {
                      761: branch 1 taken
                      121: branch 2 taken
     328              882:     if (Decls.empty()) {
                      761: branch 0 taken
                        0: branch 1 not taken
     329              761:       if (ResultKind != NotFoundInCurrentInstantiation)
     330              761:         ResultKind = NotFound;
     331                 :     } else {
     332              121:       ResultKind = Found;
     333              121:       resolveKind();
     334                 :     }
     335              882:   }
     336                 : 
     337                 :   template <class DeclClass>
     338            94306:   DeclClass *getAsSingle() const {
                    25068: branch 1 taken
                    34226: branch 2 taken
                       28: branch 4 taken
                      101: branch 5 taken
                       56: branch 7 taken
                      770: branch 8 taken
                        0: branch 10 not taken
                        4: branch 11 taken
                        0: branch 13 not taken
                    27002: branch 14 taken
                        0: branch 16 not taken
                        0: branch 17 not taken
                      706: branch 19 taken
                     6345: branch 20 taken
     339            94306:     if (getResultKind() != Found) return 0;
     340            68448:     return dyn_cast<DeclClass>(getFoundDecl());
     341                 :   }
     342                 : 
     343                 :   /// \brief Fetch the unique decl found by this lookup.  Asserts
     344                 :   /// that one was found.
     345                 :   ///
     346                 :   /// This is intended for users who have examined the result kind
     347                 :   /// and are certain that there is only one result.
     348           140661:   NamedDecl *getFoundDecl() const {
     349                 :     assert(getResultKind() == Found
                   140661: branch 1 taken
                        0: branch 2 not taken
     350           140661:            && "getFoundDecl called on non-unique result");
     351           140661:     return (*begin())->getUnderlyingDecl();
     352                 :   }
     353                 : 
     354                 :   /// Fetches a representative decl.  Useful for lazy diagnostics.
     355               24:   NamedDecl *getRepresentativeDecl() const {
                       24: branch 1 taken
                        0: branch 2 not taken
     356               24:     assert(!Decls.empty() && "cannot get representative of empty set");
     357               24:     return *begin();
     358                 :   }
     359                 : 
     360                 :   /// \brief Asks if the result is a single tag decl.
     361            30697:   bool isSingleTagDecl() const {
                     1790: branch 1 taken
                    28907: branch 2 taken
                      130: branch 5 taken
                     1660: branch 6 taken
     362            30697:     return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
     363                 :   }
     364                 : 
     365                 :   /// \brief Make these results show that the name was found in
     366                 :   /// base classes of different types.
     367                 :   ///
     368                 :   /// The given paths object is copied and invalidated.
     369                 :   void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
     370                 : 
     371                 :   /// \brief Make these results show that the name was found in
     372                 :   /// distinct base classes of the same type.
     373                 :   ///
     374                 :   /// The given paths object is copied and invalidated.
     375                 :   void setAmbiguousBaseSubobjects(CXXBasePaths &P);
     376                 : 
     377                 :   /// \brief Make these results show that the name was found in
     378                 :   /// different contexts and a tag decl was hidden by an ordinary
     379                 :   /// decl in a different context.
     380                2:   void setAmbiguousQualifiedTagHiding() {
     381                2:     setAmbiguous(AmbiguousTagHiding);
     382                2:   }
     383                 : 
     384                 :   /// \brief Clears out any current state.
     385            15522:   void clear() {
     386            15522:     ResultKind = NotFound;
     387            15522:     Decls.clear();
                        0: branch 0 not taken
                    15522: branch 1 taken
     388            15522:     if (Paths) deletePaths(Paths);
     389            15522:     Paths = NULL;
     390            15522:   }
     391                 : 
     392                 :   /// \brief Clears out any current state and re-initializes for a
     393                 :   /// different kind of lookup.
     394            14434:   void clear(Sema::LookupNameKind Kind) {
     395            14434:     clear();
     396            14434:     LookupKind = Kind;
     397            14434:     configure();
     398            14434:   }
     399                 : 
     400                 :   void print(llvm::raw_ostream &);
     401                 : 
     402                 :   /// Suppress the diagnostics that would normally fire because of this
     403                 :   /// lookup.  This happens during (e.g.) redeclaration lookups.
     404            16009:   void suppressDiagnostics() {
     405            16009:     Diagnose = false;
     406            16009:   }
     407                 : 
     408                 :   /// Sets a 'context' source range.
     409              743:   void setContextRange(SourceRange SR) {
     410              743:     NameContextRange = SR;
     411              743:   }
     412                 : 
     413                 :   /// Gets the source range of the context of this name; for C++
     414                 :   /// qualified lookups, this is the source range of the scope
     415                 :   /// specifier.
     416               33:   SourceRange getContextRange() const {
     417               33:     return NameContextRange;
     418                 :   }
     419                 : 
     420                 :   /// Gets the location of the identifier.  This isn't always defined:
     421                 :   /// sometimes we're doing lookups on synthesized names.
     422            38394:   SourceLocation getNameLoc() const {
     423            38394:     return NameLoc;
     424                 :   }
     425                 : 
     426                 :   /// \brief Get the Sema object that this lookup result is searching
     427                 :   /// with.
     428               85:   Sema &getSema() const { return SemaRef; }
     429                 : 
     430                 :   /// A class for iterating through a result set and possibly
     431                 :   /// filtering out results.  The results returned are possibly
     432                 :   /// sugared.
     433                 :   class Filter {
     434                 :     LookupResult &Results;
     435                 :     LookupResult::iterator I;
     436                 :     bool Changed;
     437                 : #ifndef NDEBUG
     438                 :     bool CalledDone;
     439                 : #endif
     440                 :     
     441                 :     friend class LookupResult;
     442            33654:     Filter(LookupResult &Results)
     443                 :       : Results(Results), I(Results.begin()), Changed(false)
     444                 : #ifndef NDEBUG
     445            33654:       , CalledDone(false)
     446                 : #endif
     447            33654:     {}
     448                 : 
     449                 :   public:
     450                 : #ifndef NDEBUG
     451            33654:     ~Filter() {
     452                 :       assert(CalledDone &&
                        0: branch 0 not taken
                    33654: branch 1 taken
     453            33654:              "LookupResult::Filter destroyed without done() call");
     454            33654:     }
     455                 : #endif
     456                 : 
     457            40120:     bool hasNext() const {
     458            40120:       return I != Results.end();
     459                 :     }
     460                 : 
     461             6466:     NamedDecl *next() {
                     6466: branch 2 taken
                        0: branch 3 not taken
     462             6466:       assert(I != Results.end() && "next() called on empty filter");
     463             6466:       return *I++;
     464                 :     }
     465                 : 
     466                 :     /// Erase the last element returned from this iterator.
     467              818:     void erase() {
     468              818:       Results.Decls.erase(--I);
     469              818:       Changed = true;
     470              818:     }
     471                 : 
     472                 :     /// Replaces the current entry with the given one, preserving the
     473                 :     /// access bits.
     474              107:     void replace(NamedDecl *D) {
     475              107:       Results.Decls.replace(I-1, D);
     476              107:       Changed = true;
     477              107:     }
     478                 : 
     479                 :     /// Replaces the current entry with the given one.
     480                 :     void replace(NamedDecl *D, AccessSpecifier AS) {
     481                 :       Results.Decls.replace(I-1, D, AS);
     482                 :       Changed = true;
     483                 :     }
     484                 : 
     485            33654:     void done() {
     486                 : #ifndef NDEBUG
                        0: branch 0 not taken
                    33654: branch 1 taken
     487            33654:       assert(!CalledDone && "done() called twice");
     488            33654:       CalledDone = true;
     489                 : #endif
     490                 : 
                      882: branch 0 taken
                    32772: branch 1 taken
     491            33654:       if (Changed)
     492              882:         Results.resolveKindAfterFilter();
     493            33654:     }
     494                 :   };
     495                 : 
     496                 :   /// Create a filter for this result set.
     497            33654:   Filter makeFilter() {
     498            33654:     return Filter(*this);
     499                 :   }
     500                 : 
     501                 : private:
     502            78385:   void diagnose() {
                       33: branch 1 taken
                    78352: branch 2 taken
     503            78385:     if (isAmbiguous())
     504               33:       SemaRef.DiagnoseAmbiguousLookup(*this);
                     2563: branch 1 taken
                    75789: branch 2 taken
                      143: branch 4 taken
                     2420: branch 5 taken
                      143: branch 6 taken
                    78209: branch 7 taken
     505            78352:     else if (isClassLookup() && SemaRef.getLangOptions().AccessControl)
     506              143:       SemaRef.CheckAccess(*this);
     507            78385:   }
     508                 : 
     509               73:   void setAmbiguous(AmbiguityKind AK) {
     510               73:     ResultKind = Ambiguous;
     511               73:     Ambiguity = AK;
     512               73:   }
     513                 : 
     514                 :   void addDeclsFromBasePaths(const CXXBasePaths &P);
     515                 :   void configure();
     516                 : 
     517                 :   // Sanity checks.
     518           514755:   void sanity() const {
                   125023: branch 0 taken
                   389732: branch 1 taken
                        0: branch 3 not taken
                   125023: branch 4 taken
     519           514755:     assert(ResultKind != NotFound || Decls.size() == 0);
                   383176: branch 0 taken
                   131579: branch 1 taken
                        0: branch 3 not taken
                   383176: branch 4 taken
     520           514755:     assert(ResultKind != Found || Decls.size() == 1);
     521                 :     assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
     522                 :            (Decls.size() == 1 &&
                     6322: branch 0 taken
                   508433: branch 1 taken
                     2197: branch 3 taken
                     4125: branch 4 taken
                     2197: branch 6 taken
                        0: branch 7 not taken
                        0: branch 12 not taken
                     2197: branch 13 taken
     523           514755:             isa<FunctionTemplateDecl>((*begin())->getUnderlyingDecl())));
                       60: branch 0 taken
                   514695: branch 1 taken
                        0: branch 3 not taken
                       60: branch 4 taken
     524           514755:     assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
     525                 :     assert(ResultKind != Ambiguous || Decls.size() > 1 ||
                      163: branch 0 taken
                   514592: branch 1 taken
                       20: branch 3 taken
                      143: branch 4 taken
                       20: branch 6 taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                       20: branch 9 taken
     526           514755:            (Decls.size() == 1 && Ambiguity == AmbiguousBaseSubobjects));
     527                 :     assert((Paths != NULL) == (ResultKind == Ambiguous &&
     528                 :                                (Ambiguity == AmbiguousBaseSubobjectTypes ||
                      163: branch 0 taken
                   514592: branch 1 taken
                       90: branch 2 taken
                       73: branch 3 taken
                       32: branch 4 taken
                       58: branch 5 taken
                        0: branch 6 not taken
                   514755: branch 7 taken
     529           514755:                                 Ambiguity == AmbiguousBaseSubobjects)));
     530           514755:   }
     531                 : 
     532               60:   bool sanityCheckUnresolved() const {
                       69: branch 4 taken
                        0: branch 5 not taken
     533               69:     for (iterator I = begin(), E = end(); I != E; ++I)
                       60: branch 2 taken
                        9: branch 3 taken
     534               69:       if (isa<UnresolvedUsingValueDecl>(*I))
     535               60:         return true;
     536                0:     return false;
     537                 :   }
     538                 : 
     539                 :   static void deletePaths(CXXBasePaths *);
     540                 : 
     541                 :   // Results.
     542                 :   LookupResultKind ResultKind;
     543                 :   AmbiguityKind Ambiguity; // ill-defined unless ambiguous
     544                 :   UnresolvedSet<8> Decls;
     545                 :   CXXBasePaths *Paths;
     546                 :   CXXRecordDecl *NamingClass;
     547                 : 
     548                 :   // Parameters.
     549                 :   Sema &SemaRef;
     550                 :   DeclarationName Name;
     551                 :   SourceLocation NameLoc;
     552                 :   SourceRange NameContextRange;
     553                 :   Sema::LookupNameKind LookupKind;
     554                 :   ResultFilter IsAcceptableFn; // set by configure()
     555                 :   unsigned IDNS; // set by configure()
     556                 : 
     557                 :   bool Redecl;
     558                 : 
     559                 :   /// \brief True if tag declarations should be hidden if non-tags
     560                 :   ///   are present
     561                 :   bool HideTags;
     562                 : 
     563                 :   bool Diagnose;
     564                 : };
     565                 : 
     566                 :   /// \brief Consumes visible declarations found when searching for
     567                 :   /// all visible names within a given scope or context.
     568                 :   ///
     569                 :   /// This abstract class is meant to be subclassed by clients of \c
     570                 :   /// Sema::LookupVisibleDecls(), each of which should override the \c
     571                 :   /// FoundDecl() function to process declarations as they are found.
     572              223:   class VisibleDeclConsumer {
     573                 :   public:
     574                 :     /// \brief Destroys the visible declaration consumer.
     575                 :     virtual ~VisibleDeclConsumer();
     576                 : 
     577                 :     /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a
     578                 :     /// declaration visible from the current scope or context.
     579                 :     ///
     580                 :     /// \param ND the declaration found.
     581                 :     ///
     582                 :     /// \param Hiding a declaration that hides the declaration \p ND,
     583                 :     /// or NULL if no such declaration exists.
     584                 :     ///
     585                 :     /// \param InBaseClass whether this declaration was found in base
     586                 :     /// class of the context we searched.
     587                 :     virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, 
     588                 :                            bool InBaseClass) = 0;
     589                 :   };
     590                 : 
     591                 : /// \brief A class for storing results from argument-dependent lookup.
     592             3266: class ADLResult {
     593                 : private:
     594                 :   /// A map from canonical decls to the 'most recent' decl.
     595                 :   llvm::DenseMap<NamedDecl*, NamedDecl*> Decls;
     596                 : 
     597                 : public:
     598                 :   /// Adds a new ADL candidate to this map.
     599                 :   void insert(NamedDecl *D);
     600                 : 
     601                 :   /// Removes any data associated with a given decl.
     602             2043:   void erase(NamedDecl *D) {
     603             2043:     Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
     604             2043:   }
     605                 : 
     606                 :   class iterator {
     607                 :     typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator;
     608                 :     inner_iterator iter;
     609                 : 
     610                 :     friend class ADLResult;
     611             3266:     iterator(const inner_iterator &iter) : iter(iter) {}
     612                 :   public:
     613                 :     iterator() {}
     614                 : 
     615               69:     iterator &operator++() { ++iter; return *this; }
     616                 :     iterator operator++(int) { return iterator(iter++); }
     617                 : 
     618               73:     NamedDecl *operator*() const { return iter->second; }
     619                 : 
     620                 :     bool operator==(const iterator &other) const { return iter == other.iter; }
     621             1702:     bool operator!=(const iterator &other) const { return iter != other.iter; }
     622                 :   };
     623                 : 
     624             1633:   iterator begin() { return iterator(Decls.begin()); }
     625             1633:   iterator end() { return iterator(Decls.end()); }
     626                 : };
     627                 : 
     628                 : }
     629                 : 
     630                 : #endif

Generated: 2010-02-10 01:31 by zcov