zcov: / lib/Sema/SemaCXXScopeSpec.cpp


Files: 1 Branches Taken: 80.1% 197 / 246
Generated: 2010-02-10 01:31 Branches Executed: 97.6% 240 / 246
Line Coverage: 92.8% 206 / 222


Programs: 2 Runs 3018


       1                 : //===--- SemaCXXScopeSpec.cpp - Semantic Analysis for C++ scope specifiers-===//
       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 implements C++ semantic analysis for scope specifiers.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "Sema.h"
      15                 : #include "Lookup.h"
      16                 : #include "clang/AST/ASTContext.h"
      17                 : #include "clang/AST/DeclTemplate.h"
      18                 : #include "clang/AST/ExprCXX.h"
      19                 : #include "clang/AST/NestedNameSpecifier.h"
      20                 : #include "clang/Basic/PartialDiagnostic.h"
      21                 : #include "clang/Parse/DeclSpec.h"
      22                 : #include "llvm/ADT/STLExtras.h"
      23                 : #include "llvm/Support/raw_ostream.h"
      24                 : using namespace clang;
      25                 : 
      26                 : /// \brief Find the current instantiation that associated with the given type.
      27                 : static CXXRecordDecl *
      28                 : getCurrentInstantiationOf(ASTContext &Context, DeclContext *CurContext, 
      29              982:                           QualType T) {
                        0: branch 1 not taken
                      982: branch 2 taken
      30              982:   if (T.isNull())
      31                0:     return 0;
      32                 :   
      33              982:   T = Context.getCanonicalType(T).getUnqualifiedType();
      34                 :   
                     1441: branch 1 taken
                        0: branch 2 not taken
      35             1441:   for (DeclContext *Ctx = CurContext; Ctx; Ctx = Ctx->getLookupParent()) {
      36                 :     // If we've hit a namespace or the global scope, then the
      37                 :     // nested-name-specifier can't refer to the current instantiation.
                      681: branch 1 taken
                      760: branch 2 taken
      38             1441:     if (Ctx->isFileContext())
      39              681:       return 0;
      40                 :     
      41                 :     // Skip non-class contexts.
      42              760:     CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx);
                      610: branch 0 taken
                      150: branch 1 taken
      43              760:     if (!Record)
      44              150:       continue;
      45                 :     
      46                 :     // If this record type is not dependent,
                        7: branch 1 taken
                      603: branch 2 taken
      47              610:     if (!Record->isDependentType())
      48                7:       return 0;
      49                 :     
      50                 :     // C++ [temp.dep.type]p1:
      51                 :     //
      52                 :     //   In the definition of a class template, a nested class of a
      53                 :     //   class template, a member of a class template, or a member of a
      54                 :     //   nested class of a class template, a name refers to the current
      55                 :     //   instantiation if it is
      56                 :     //     -- the injected-class-name (9) of the class template or
      57                 :     //        nested class,
      58                 :     //     -- in the definition of a primary class template, the name
      59                 :     //        of the class template followed by the template argument
      60                 :     //        list of the primary template (as described below)
      61                 :     //        enclosed in <>,
      62                 :     //     -- in the definition of a nested class of a class template,
      63                 :     //        the name of the nested class referenced as a member of
      64                 :     //        the current instantiation, or
      65                 :     //     -- in the definition of a partial specialization, the name
      66                 :     //        of the class template followed by the template argument
      67                 :     //        list of the partial specialization enclosed in <>. If
      68                 :     //        the nth template parameter is a parameter pack, the nth
      69                 :     //        template argument is a pack expansion (14.6.3) whose
      70                 :     //        pattern is the name of the parameter pack.
      71                 :     //        (FIXME: parameter packs)
      72                 :     //
      73                 :     // All of these options come down to having the
      74                 :     // nested-name-specifier type that is equivalent to the
      75                 :     // injected-class-name of one of the types that is currently in
      76                 :     // our context.
                      118: branch 4 taken
                      485: branch 5 taken
      77              603:     if (Context.getCanonicalType(Context.getTypeDeclType(Record)) == T)
      78              118:       return Record;
      79                 :     
                      420: branch 1 taken
                       65: branch 2 taken
      80              485:     if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
      81                 :       QualType InjectedClassName
      82              420:         = Template->getInjectedClassNameType(Context);
                      176: branch 3 taken
                      244: branch 4 taken
      83              420:       if (T == Context.getCanonicalType(InjectedClassName))
      84              176:         return Template->getTemplatedDecl();
      85                 :     }
      86                 :     // FIXME: check for class template partial specializations
      87                 :   }  
      88                 :   
      89                0:   return 0;
      90                 : }
      91                 : 
      92                 : /// \brief Compute the DeclContext that is associated with the given type.
      93                 : ///
      94                 : /// \param T the type for which we are attempting to find a DeclContext.
      95                 : ///
      96                 : /// \returns the declaration context represented by the type T,
      97                 : /// or NULL if the declaration context cannot be computed (e.g., because it is
      98                 : /// dependent and not the current instantiation).
      99              119: DeclContext *Sema::computeDeclContext(QualType T) {
                       91: branch 2 taken
                       28: branch 3 taken
     100              119:   if (const TagType *Tag = T->getAs<TagType>())
                       91: branch 1 taken
                        0: branch 2 not taken
     101               91:     return Tag->getDecl();
     102                 : 
                       10: branch 1 taken
                       18: branch 2 taken
     103               28:   return ::getCurrentInstantiationOf(Context, CurContext, T);
     104                 : }
     105                 : 
     106                 : /// \brief Compute the DeclContext that is associated with the given
     107                 : /// scope specifier.
     108                 : ///
     109                 : /// \param SS the C++ scope specifier as it appears in the source
     110                 : ///
     111                 : /// \param EnteringContext when true, we will be entering the context of
     112                 : /// this scope specifier, so we can retrieve the declaration context of a
     113                 : /// class template or class template partial specialization even if it is
     114                 : /// not the current instantiation.
     115                 : ///
     116                 : /// \returns the declaration context represented by the scope specifier @p SS,
     117                 : /// or NULL if the declaration context cannot be computed (e.g., because it is
     118                 : /// dependent and not the current instantiation).
     119                 : DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
     120             9364:                                       bool EnteringContext) {
                     9361: branch 1 taken
                        3: branch 2 taken
                        0: branch 4 not taken
                     9361: branch 5 taken
                        3: branch 6 taken
                     9361: branch 7 taken
     121             9364:   if (!SS.isSet() || SS.isInvalid())
     122                3:     return 0;
     123                 : 
     124                 :   NestedNameSpecifier *NNS
     125             9361:     = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
                      849: branch 1 taken
                     8512: branch 2 taken
     126             9361:   if (NNS->isDependent()) {
     127                 :     // If this nested-name-specifier refers to the current
     128                 :     // instantiation, return its DeclContext.
                      220: branch 1 taken
                      629: branch 2 taken
     129              849:     if (CXXRecordDecl *Record = getCurrentInstantiationOf(NNS))
                      220: branch 0 taken
                        0: branch 1 not taken
     130              220:       return Record;
     131                 : 
                      378: branch 0 taken
                      251: branch 1 taken
     132              629:     if (EnteringContext) {
                      358: branch 0 taken
                       20: branch 1 taken
     133              378:       if (const TemplateSpecializationType *SpecType
     134              378:             = dyn_cast_or_null<TemplateSpecializationType>(NNS->getAsType())) {
     135                 :         // We are entering the context of the nested name specifier, so try to
     136                 :         // match the nested name specifier to either a primary class template
     137                 :         // or a class template partial specialization.
                      358: branch 0 taken
                        0: branch 1 not taken
     138              358:         if (ClassTemplateDecl *ClassTemplate
     139                 :               = dyn_cast_or_null<ClassTemplateDecl>(
     140              358:                             SpecType->getTemplateName().getAsTemplateDecl())) {
     141                 :           QualType ContextType
     142              358:             = Context.getCanonicalType(QualType(SpecType, 0));
     143                 : 
     144                 :           // If the type of the nested name specifier is the same as the
     145                 :           // injected class name of the named class template, we're entering
     146                 :           // into that class template definition.
     147              358:           QualType Injected = ClassTemplate->getInjectedClassNameType(Context);
                      337: branch 1 taken
                       21: branch 2 taken
     148              358:           if (Context.hasSameType(Injected, ContextType))
                      337: branch 1 taken
                        0: branch 2 not taken
     149              337:             return ClassTemplate->getTemplatedDecl();
     150                 : 
     151                 :           // If the type of the nested name specifier is the same as the
     152                 :           // type of one of the class template's class template partial
     153                 :           // specializations, we're entering into the definition of that
     154                 :           // class template partial specialization.
                       15: branch 0 taken
                        6: branch 1 taken
     155               21:           if (ClassTemplatePartialSpecializationDecl *PartialSpec
     156               21:                 = ClassTemplate->findPartialSpecialization(ContextType))
                       15: branch 0 taken
                        0: branch 1 not taken
     157               15:             return PartialSpec;
     158                 :         }
                       11: branch 0 taken
                        9: branch 1 taken
     159               20:       } else if (const RecordType *RecordT
     160               20:                    = dyn_cast_or_null<RecordType>(NNS->getAsType())) {
     161                 :         // The nested name specifier refers to a member of a class template.
                       11: branch 1 taken
                        0: branch 2 not taken
     162               11:         return RecordT->getDecl();
     163                 :       }
     164                 :     }
     165                 : 
     166              266:     return 0;
     167                 :   }
     168                 : 
                        0: branch 1 not taken
                     1543: branch 2 taken
                     6760: branch 3 taken
                      209: branch 4 taken
                        0: branch 5 not taken
     169             8512:   switch (NNS->getKind()) {
     170                 :   case NestedNameSpecifier::Identifier:
     171                0:     assert(false && "Dependent nested-name-specifier has no DeclContext");
     172                 :     break;
     173                 : 
     174                 :   case NestedNameSpecifier::Namespace:
                     1543: branch 1 taken
                        0: branch 2 not taken
     175             1543:     return NNS->getAsNamespace();
     176                 : 
     177                 :   case NestedNameSpecifier::TypeSpec:
     178                 :   case NestedNameSpecifier::TypeSpecWithTemplate: {
     179             6760:     const TagType *Tag = NNS->getAsType()->getAs<TagType>();
                        0: branch 0 not taken
                     6760: branch 1 taken
     180             6760:     assert(Tag && "Non-tag type in nested-name-specifier");
                     6760: branch 1 taken
                        0: branch 2 not taken
     181             6760:     return Tag->getDecl();
     182                 :   } break;
     183                 : 
     184                 :   case NestedNameSpecifier::Global:
                      209: branch 1 taken
                        0: branch 2 not taken
     185              209:     return Context.getTranslationUnitDecl();
     186                 :   }
     187                 : 
     188                 :   // Required to silence a GCC warning.
     189                0:   return 0;
     190                 : }
     191                 : 
     192             1320: bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) {
                     1317: branch 1 taken
                        3: branch 2 taken
                        0: branch 4 not taken
                     1317: branch 5 taken
                        3: branch 6 taken
                     1317: branch 7 taken
     193             1320:   if (!SS.isSet() || SS.isInvalid())
     194                3:     return false;
     195                 : 
     196                 :   NestedNameSpecifier *NNS
     197             1317:     = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
     198             1317:   return NNS->isDependent();
     199                 : }
     200                 : 
     201                 : // \brief Determine whether this C++ scope specifier refers to an
     202                 : // unknown specialization, i.e., a dependent type that is not the
     203                 : // current instantiation.
     204                0: bool Sema::isUnknownSpecialization(const CXXScopeSpec &SS) {
                        0: branch 1 not taken
                        0: branch 2 not taken
     205                0:   if (!isDependentScopeSpecifier(SS))
     206                0:     return false;
     207                 : 
     208                 :   NestedNameSpecifier *NNS
     209                0:     = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
     210                0:   return getCurrentInstantiationOf(NNS) == 0;
     211                 : }
     212                 : 
     213                 : /// \brief If the given nested name specifier refers to the current
     214                 : /// instantiation, return the declaration that corresponds to that
     215                 : /// current instantiation (C++0x [temp.dep.type]p1).
     216                 : ///
     217                 : /// \param NNS a dependent nested name specifier.
     218              992: CXXRecordDecl *Sema::getCurrentInstantiationOf(NestedNameSpecifier *NNS) {
                      992: branch 1 taken
                        0: branch 2 not taken
     219              992:   assert(getLangOptions().CPlusPlus && "Only callable in C++");
                      992: branch 1 taken
                        0: branch 2 not taken
     220              992:   assert(NNS->isDependent() && "Only dependent nested-name-specifier allowed");
     221                 : 
                       38: branch 1 taken
                      954: branch 2 taken
     222              992:   if (!NNS->getAsType())
     223               38:     return 0;
     224                 : 
     225              954:   QualType T = QualType(NNS->getAsType(), 0);
     226              954:   return ::getCurrentInstantiationOf(Context, CurContext, T);
     227                 : }
     228                 : 
     229                 : /// \brief Require that the context specified by SS be complete.
     230                 : ///
     231                 : /// If SS refers to a type, this routine checks whether the type is
     232                 : /// complete enough (or can be made complete enough) for name lookup
     233                 : /// into the DeclContext. A type that is not yet completed can be
     234                 : /// considered "complete enough" if it is a class/struct/union/enum
     235                 : /// that is currently being defined. Or, if we have a type that names
     236                 : /// a class template specialization that is not a complete type, we
     237                 : /// will attempt to instantiate that class template.
     238             3535: bool Sema::RequireCompleteDeclContext(const CXXScopeSpec &SS) {
                     3474: branch 1 taken
                       61: branch 2 taken
                        0: branch 4 not taken
                     3474: branch 5 taken
                       61: branch 6 taken
                     3474: branch 7 taken
     239             3535:   if (!SS.isSet() || SS.isInvalid())
     240               61:     return false;
     241                 : 
     242             3474:   DeclContext *DC = computeDeclContext(SS, true);
                     2727: branch 1 taken
                      747: branch 2 taken
     243             3474:   if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
     244                 :     // If this is a dependent type, then we consider it complete.
                       41: branch 1 taken
                     2686: branch 2 taken
     245             2727:     if (Tag->isDependentContext())
     246               41:       return false;
     247                 : 
     248                 :     // If we're currently defining this type, then lookup into the
     249                 :     // type is okay: don't complain that it isn't complete yet.
     250             2686:     const TagType *TagT = Context.getTypeDeclType(Tag)->getAs<TagType>();
                        6: branch 1 taken
                     2680: branch 2 taken
     251             2686:     if (TagT->isBeingDefined())
     252                6:       return false;
     253                 : 
     254                 :     // The type must be complete.
     255                 :     return RequireCompleteType(SS.getRange().getBegin(),
     256                 :                                Context.getTypeDeclType(Tag),
     257                 :                                PDiag(diag::err_incomplete_nested_name_spec)
     258             2680:                                  << SS.getRange());
     259                 :   }
     260                 : 
     261              747:   return false;
     262                 : }
     263                 : 
     264                 : /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
     265                 : /// global scope ('::').
     266                 : Sema::CXXScopeTy *Sema::ActOnCXXGlobalScopeSpecifier(Scope *S,
     267               85:                                                      SourceLocation CCLoc) {
     268               85:   return NestedNameSpecifier::GlobalSpecifier(Context);
     269                 : }
     270                 : 
     271                 : /// \brief Determines whether the given declaration is an valid acceptable
     272                 : /// result for name lookup of a nested-name-specifier.
     273             1714: bool Sema::isAcceptableNestedNameSpecifier(NamedDecl *SD) {
                       27: branch 0 taken
                     1687: branch 1 taken
     274             1714:   if (!SD)
     275               27:     return false;
     276                 : 
     277                 :   // Namespace and namespace aliases are fine.
                     1117: branch 1 taken
                      570: branch 2 taken
                        4: branch 4 taken
                     1113: branch 5 taken
                      574: branch 6 taken
                     1113: branch 7 taken
     278             1687:   if (isa<NamespaceDecl>(SD) || isa<NamespaceAliasDecl>(SD))
     279              574:     return true;
     280                 : 
                        5: branch 1 taken
                     1108: branch 2 taken
     281             1113:   if (!isa<TypeDecl>(SD))
     282                5:     return false;
     283                 : 
     284                 :   // Determine whether we have a class (or, in C++0x, an enum) or
     285                 :   // a typedef thereof. If so, build the nested-name-specifier.
     286             1108:   QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD));
                      139: branch 2 taken
                      969: branch 3 taken
     287             1108:   if (T->isDependentType())
     288              139:     return true;
                       28: branch 1 taken
                      941: branch 2 taken
     289              969:   else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
                        2: branch 3 taken
                       26: branch 4 taken
                        0: branch 6 not taken
                        2: branch 7 taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                       26: branch 13 taken
                        2: branch 14 taken
     290               28:     if (TD->getUnderlyingType()->isRecordType() ||
     291                 :         (Context.getLangOptions().CPlusPlus0x &&
     292                 :          TD->getUnderlyingType()->isEnumeralType()))
     293               26:       return true;
                        3: branch 1 taken
                      938: branch 2 taken
                        0: branch 4 not taken
                        3: branch 5 taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                      938: branch 9 taken
                        3: branch 10 taken
     294              941:   } else if (isa<RecordDecl>(SD) ||
     295                 :              (Context.getLangOptions().CPlusPlus0x && isa<EnumDecl>(SD)))
     296              938:     return true;
     297                 : 
     298                5:   return false;
     299                 : }
     300                 : 
     301                 : /// \brief If the given nested-name-specifier begins with a bare identifier
     302                 : /// (e.g., Base::), perform name lookup for that identifier as a
     303                 : /// nested-name-specifier within the given scope, and return the result of that
     304                 : /// name lookup.
     305               60: NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
                       60: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                       60: branch 3 taken
     306               60:   if (!S || !NNS)
     307                0:     return 0;
     308                 : 
                       13: branch 1 taken
                       60: branch 2 taken
     309              133:   while (NNS->getPrefix())
     310               13:     NNS = NNS->getPrefix();
     311                 : 
                       46: branch 1 taken
                       14: branch 2 taken
     312               60:   if (NNS->getKind() != NestedNameSpecifier::Identifier)
     313               46:     return 0;
     314                 : 
     315                 :   LookupResult Found(*this, NNS->getAsIdentifier(), SourceLocation(),
     316               14:                      LookupNestedNameSpecifierName);
     317               14:   LookupName(Found, S);
                       14: branch 1 taken
                        0: branch 2 not taken
     318               14:   assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet");
     319                 : 
                        5: branch 1 taken
                        9: branch 2 taken
     320               14:   if (!Found.isSingleResult())
     321                5:     return 0;
     322                 : 
     323                9:   NamedDecl *Result = Found.getFoundDecl();
                        8: branch 1 taken
                        1: branch 2 taken
     324                9:   if (isAcceptableNestedNameSpecifier(Result))
     325                8:     return Result;
     326                 : 
     327                1:   return 0;
     328                 : }
     329                 : 
     330                 : /// \brief Build a new nested-name-specifier for "identifier::", as described
     331                 : /// by ActOnCXXNestedNameSpecifier.
     332                 : ///
     333                 : /// This routine differs only slightly from ActOnCXXNestedNameSpecifier, in
     334                 : /// that it contains an extra parameter \p ScopeLookupResult, which provides
     335                 : /// the result of name lookup within the scope of the nested-name-specifier
     336                 : /// that was computed at template definition time.
     337                 : ///
     338                 : /// If ErrorRecoveryLookup is true, then this call is used to improve error
     339                 : /// recovery.  This means that it should not emit diagnostics, it should
     340                 : /// just return null on failure.  It also means it should only return a valid
     341                 : /// scope if it *knows* that the result is correct.  It should not return in a
     342                 : /// dependent context, for example.
     343                 : Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
     344                 :                                                     const CXXScopeSpec &SS,
     345                 :                                                     SourceLocation IdLoc,
     346                 :                                                     SourceLocation CCLoc,
     347                 :                                                     IdentifierInfo &II,
     348                 :                                                     QualType ObjectType,
     349                 :                                                   NamedDecl *ScopeLookupResult,
     350                 :                                                     bool EnteringContext,
     351             1660:                                                     bool ErrorRecoveryLookup) {
     352                 :   NestedNameSpecifier *Prefix
     353             1660:     = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
     354                 : 
     355             1660:   LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
     356                 : 
     357                 :   // Determine where to perform name lookup
     358             1660:   DeclContext *LookupCtx = 0;
     359             1660:   bool isDependent = false;
                       76: branch 1 taken
                     1584: branch 2 taken
     360             1660:   if (!ObjectType.isNull()) {
     361                 :     // This nested-name-specifier occurs in a member access expression, e.g.,
     362                 :     // x->B::f, and we are looking into the type of the object.
                       76: branch 1 taken
                        0: branch 2 not taken
     363               76:     assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist");
     364               76:     LookupCtx = computeDeclContext(ObjectType);
     365               76:     isDependent = ObjectType->isDependentType();
                      199: branch 1 taken
                     1385: branch 2 taken
     366             1584:   } else if (SS.isSet()) {
     367                 :     // This nested-name-specifier occurs after another nested-name-specifier,
     368                 :     // so long into the context associated with the prior nested-name-specifier.
     369              199:     LookupCtx = computeDeclContext(SS, EnteringContext);
     370              199:     isDependent = isDependentScopeSpecifier(SS);
     371              199:     Found.setContextRange(SS.getRange());
     372                 :   }
     373                 : 
     374                 : 
     375             1660:   bool ObjectTypeSearchedInScope = false;
                      243: branch 0 taken
                     1417: branch 1 taken
     376             1660:   if (LookupCtx) {
     377                 :     // Perform "qualified" name lookup into the declaration context we
     378                 :     // computed, which is either the type of the base of a member access
     379                 :     // expression or the declaration context associated with a prior
     380                 :     // nested-name-specifier.
     381                 : 
     382                 :     // The declaration context must be complete.
                      226: branch 1 taken
                       17: branch 2 taken
                        0: branch 4 not taken
                      226: branch 5 taken
                        0: branch 6 not taken
                      243: branch 7 taken
     383              243:     if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
     384                0:       return 0;
     385                 : 
     386              243:     LookupQualifiedName(Found, LookupCtx);
     387                 : 
                       61: branch 1 taken
                      182: branch 2 taken
                       20: branch 4 taken
                       41: branch 5 taken
                       20: branch 6 taken
                      223: branch 7 taken
     388              243:     if (!ObjectType.isNull() && Found.empty()) {
     389                 :       // C++ [basic.lookup.classref]p4:
     390                 :       //   If the id-expression in a class member access is a qualified-id of
     391                 :       //   the form
     392                 :       //
     393                 :       //        class-name-or-namespace-name::...
     394                 :       //
     395                 :       //   the class-name-or-namespace-name following the . or -> operator is
     396                 :       //   looked up both in the context of the entire postfix-expression and in
     397                 :       //   the scope of the class of the object expression. If the name is found
     398                 :       //   only in the scope of the class of the object expression, the name
     399                 :       //   shall refer to a class-name. If the name is found only in the
     400                 :       //   context of the entire postfix-expression, the name shall refer to a
     401                 :       //   class-name or namespace-name. [...]
     402                 :       //
     403                 :       // Qualified name lookup into a class will not find a namespace-name,
     404                 :       // so we do not need to diagnoste that case specifically. However,
     405                 :       // this qualified name lookup may find nothing. In that case, perform
     406                 :       // unqualified name lookup in the given scope (if available) or
     407                 :       // reconstruct the result from when name lookup was performed at template
     408                 :       // definition time.
                       11: branch 0 taken
                        9: branch 1 taken
     409               20:       if (S)
     410               11:         LookupName(Found, S);
                        8: branch 0 taken
                        1: branch 1 taken
     411                9:       else if (ScopeLookupResult)
     412                8:         Found.addDecl(ScopeLookupResult);
     413                 : 
     414               20:       ObjectTypeSearchedInScope = true;
     415                 :     }
                       32: branch 0 taken
                     1385: branch 1 taken
     416             1417:   } else if (isDependent) {
     417                 :     // Don't speculate if we're just trying to improve error recovery.
                        0: branch 0 not taken
                       32: branch 1 taken
     418               32:     if (ErrorRecoveryLookup)
     419                0:       return 0;
     420                 :     
     421                 :     // We were not able to compute the declaration context for a dependent
     422                 :     // base object type or prior nested-name-specifier, so this
     423                 :     // nested-name-specifier refers to an unknown specialization. Just build
     424                 :     // a dependent nested-name-specifier.
                       15: branch 0 taken
                       17: branch 1 taken
     425               32:     if (!Prefix)
     426               15:       return NestedNameSpecifier::Create(Context, &II);
     427                 : 
     428               17:     return NestedNameSpecifier::Create(Context, Prefix, &II);
     429                 :   } else {
     430                 :     // Perform unqualified name lookup in the current scope.
     431             1385:     LookupName(Found, S);
     432                 :   }
     433                 : 
     434                 :   // FIXME: Deal with ambiguities cleanly.
     435                 : 
                       20: branch 1 taken
                     1608: branch 2 taken
                       16: branch 3 taken
                        4: branch 4 taken
                       16: branch 5 taken
                     1612: branch 6 taken
     436             1628:   if (Found.empty() && !ErrorRecoveryLookup) {
     437                 :     // We haven't found anything, and we're not recovering from a
     438                 :     // different kind of error, so look for typos.
     439               16:     DeclarationName Name = Found.getLookupName();
                        4: branch 1 taken
                       12: branch 2 taken
                        4: branch 4 taken
                        0: branch 5 not taken
                        4: branch 8 taken
                        0: branch 9 not taken
                        4: branch 10 taken
                       12: branch 11 taken
     440               16:     if (CorrectTypo(Found, S, &SS, LookupCtx, EnteringContext) &&
     441                 :         Found.isSingleResult() &&
     442                 :         isAcceptableNestedNameSpecifier(Found.getAsSingle<NamedDecl>())) {
                        2: branch 0 taken
                        2: branch 1 taken
     443                4:       if (LookupCtx)
     444                 :         Diag(Found.getNameLoc(), diag::err_no_member_suggest)
     445                 :           << Name << LookupCtx << Found.getLookupName() << SS.getRange()
     446                 :           << CodeModificationHint::CreateReplacement(Found.getNameLoc(),
     447                2:                                            Found.getLookupName().getAsString());
     448                 :       else
     449                 :         Diag(Found.getNameLoc(), diag::err_undeclared_var_use_suggest)
     450                 :           << Name << Found.getLookupName()
     451                 :           << CodeModificationHint::CreateReplacement(Found.getNameLoc(),
     452                2:                                            Found.getLookupName().getAsString());
     453                 :       
                        4: branch 1 taken
                        0: branch 2 not taken
     454                4:       if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
     455                 :         Diag(ND->getLocation(), diag::note_previous_decl)
     456                4:           << ND->getDeclName();
     457                 :     } else
     458               12:       Found.clear();
     459                 :   }
     460                 : 
     461             1628:   NamedDecl *SD = Found.getAsSingle<NamedDecl>();
                     1608: branch 1 taken
                       20: branch 2 taken
     462             1628:   if (isAcceptableNestedNameSpecifier(SD)) {
                       58: branch 1 taken
                     1550: branch 2 taken
                       41: branch 3 taken
                       17: branch 4 taken
                       41: branch 5 taken
                     1567: branch 6 taken
     463             1608:     if (!ObjectType.isNull() && !ObjectTypeSearchedInScope) {
     464                 :       // C++ [basic.lookup.classref]p4:
     465                 :       //   [...] If the name is found in both contexts, the
     466                 :       //   class-name-or-namespace-name shall refer to the same entity.
     467                 :       //
     468                 :       // We already found the name in the scope of the object. Now, look
     469                 :       // into the current scope (the scope of the postfix-expression) to
     470                 :       // see if we can find the same name there. As above, if there is no
     471                 :       // scope, reconstruct the result from the template instantiation itself.
     472                 :       NamedDecl *OuterDecl;
                       33: branch 0 taken
                        8: branch 1 taken
     473               41:       if (S) {
     474               33:         LookupResult FoundOuter(*this, &II, IdLoc, LookupNestedNameSpecifierName);
     475               33:         LookupName(FoundOuter, S);
     476               33:         OuterDecl = FoundOuter.getAsSingle<NamedDecl>();
     477                 :       } else
     478                8:         OuterDecl = ScopeLookupResult;
     479                 : 
                       30: branch 1 taken
                       11: branch 2 taken
                        5: branch 5 taken
                       25: branch 6 taken
                        5: branch 8 taken
                        0: branch 9 not taken
                        5: branch 11 taken
                        0: branch 12 not taken
                        2: branch 18 taken
                        3: branch 19 taken
                        2: branch 20 taken
                       39: branch 21 taken
     480               41:       if (isAcceptableNestedNameSpecifier(OuterDecl) &&
     481                 :           OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() &&
     482                 :           (!isa<TypeDecl>(OuterDecl) || !isa<TypeDecl>(SD) ||
     483                 :            !Context.hasSameType(
     484                 :                             Context.getTypeDeclType(cast<TypeDecl>(OuterDecl)),
     485                 :                                Context.getTypeDeclType(cast<TypeDecl>(SD))))) {
                        0: branch 0 not taken
                        2: branch 1 taken
     486                2:              if (ErrorRecoveryLookup)
     487                0:                return 0;
     488                 :              
     489                 :              Diag(IdLoc, diag::err_nested_name_member_ref_lookup_ambiguous)
     490                2:                << &II;
     491                 :              Diag(SD->getLocation(), diag::note_ambig_member_ref_object_type)
     492                2:                << ObjectType;
     493                2:              Diag(OuterDecl->getLocation(), diag::note_ambig_member_ref_scope);
     494                 : 
     495                 :              // Fall through so that we'll pick the name we found in the object
     496                 :              // type, since that's probably what the user wanted anyway.
     497                 :            }
     498                 :     }
     499                 : 
                      549: branch 1 taken
                     1059: branch 2 taken
     500             1608:     if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD))
     501              549:       return NestedNameSpecifier::Create(Context, Prefix, Namespace);
     502                 : 
     503                 :     // FIXME: It would be nice to maintain the namespace alias name, then
     504                 :     // see through that alias when resolving the nested-name-specifier down to
     505                 :     // a declaration context.
                        3: branch 1 taken
                     1056: branch 2 taken
     506             1059:     if (NamespaceAliasDecl *Alias = dyn_cast<NamespaceAliasDecl>(SD))
     507                 :       return NestedNameSpecifier::Create(Context, Prefix,
     508                 : 
     509                3:                                          Alias->getNamespace());
     510                 : 
     511             1056:     QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD));
     512                 :     return NestedNameSpecifier::Create(Context, Prefix, false,
     513             1056:                                        T.getTypePtr());
     514                 :   }
     515                 : 
     516                 :   // Otherwise, we have an error case.  If we don't want diagnostics, just
     517                 :   // return an error now.
                        4: branch 0 taken
                       16: branch 1 taken
     518               20:   if (ErrorRecoveryLookup)
     519                4:     return 0;
     520                 : 
     521                 :   // If we didn't find anything during our lookup, try again with
     522                 :   // ordinary name lookup, which can help us produce better error
     523                 :   // messages.
                       12: branch 1 taken
                        4: branch 2 taken
     524               16:   if (Found.empty()) {
     525               12:     Found.clear(LookupOrdinaryName);
     526               12:     LookupName(Found, S);
     527                 :   }
     528                 : 
     529                 :   unsigned DiagID;
                        5: branch 1 taken
                       11: branch 2 taken
     530               16:   if (!Found.empty())
     531                5:     DiagID = diag::err_expected_class_or_namespace;
                        5: branch 1 taken
                        6: branch 2 taken
     532               11:   else if (SS.isSet()) {
     533                5:     Diag(IdLoc, diag::err_no_member) << &II << LookupCtx << SS.getRange();
     534                5:     return 0;
     535                 :   } else
     536                6:     DiagID = diag::err_undeclared_var_use;
     537                 : 
                        0: branch 1 not taken
                       11: branch 2 taken
     538               11:   if (SS.isSet())
     539                0:     Diag(IdLoc, DiagID) << &II << SS.getRange();
     540                 :   else
     541               11:     Diag(IdLoc, DiagID) << &II;
     542                 : 
     543               11:   return 0;
     544                 : }
     545                 : 
     546                 : /// ActOnCXXNestedNameSpecifier - Called during parsing of a
     547                 : /// nested-name-specifier. e.g. for "foo::bar::" we parsed "foo::" and now
     548                 : /// we want to resolve "bar::". 'SS' is empty or the previously parsed
     549                 : /// nested-name part ("foo::"), 'IdLoc' is the source location of 'bar',
     550                 : /// 'CCLoc' is the location of '::' and 'II' is the identifier for 'bar'.
     551                 : /// Returns a CXXScopeTy* object representing the C++ scope.
     552                 : Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
     553                 :                                                     const CXXScopeSpec &SS,
     554                 :                                                     SourceLocation IdLoc,
     555                 :                                                     SourceLocation CCLoc,
     556                 :                                                     IdentifierInfo &II,
     557                 :                                                     TypeTy *ObjectTypePtr,
     558             1620:                                                     bool EnteringContext) {
     559                 :   return BuildCXXNestedNameSpecifier(S, SS, IdLoc, CCLoc, II,
     560                 :                                      QualType::getFromOpaquePtr(ObjectTypePtr),
     561                 :                                      /*ScopeLookupResult=*/0, EnteringContext,
     562             1620:                                      false);
     563                 : }
     564                 : 
     565                 : /// IsInvalidUnlessNestedName - This method is used for error recovery
     566                 : /// purposes to determine whether the specified identifier is only valid as
     567                 : /// a nested name specifier, for example a namespace name.  It is
     568                 : /// conservatively correct to always return false from this method.
     569                 : ///
     570                 : /// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
     571                 : bool Sema::IsInvalidUnlessNestedName(Scope *S, const CXXScopeSpec &SS,
     572                 :                                      IdentifierInfo &II, TypeTy *ObjectType,
     573                8:                                      bool EnteringContext) {
     574                 :   return BuildCXXNestedNameSpecifier(S, SS, SourceLocation(), SourceLocation(),
     575                 :                                      II, QualType::getFromOpaquePtr(ObjectType),
     576                 :                                      /*ScopeLookupResult=*/0, EnteringContext,
     577                8:                                      true);
     578                 : }
     579                 : 
     580                 : Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
     581                 :                                                     const CXXScopeSpec &SS,
     582                 :                                                     TypeTy *Ty,
     583                 :                                                     SourceRange TypeRange,
     584              795:                                                     SourceLocation CCLoc) {
     585                 :   NestedNameSpecifier *Prefix
     586              795:     = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
     587              795:   QualType T = GetTypeFromParser(Ty);
     588                 :   return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
     589              795:                                      T.getTypePtr());
     590                 : }
     591                 : 
     592              500: bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
                      500: branch 1 taken
                        0: branch 2 not taken
     593              500:   assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
     594                 : 
     595                 :   NestedNameSpecifier *Qualifier =
     596              500:     static_cast<NestedNameSpecifier*>(SS.getScopeRep());
     597                 : 
     598                 :   // There are only two places a well-formed program may qualify a
     599                 :   // declarator: first, when defining a namespace or class member
     600                 :   // out-of-line, and second, when naming an explicitly-qualified
     601                 :   // friend function.  The latter case is governed by
     602                 :   // C++03 [basic.lookup.unqual]p10:
     603                 :   //   In a friend declaration naming a member function, a name used
     604                 :   //   in the function declarator and not part of a template-argument
     605                 :   //   in a template-id is first looked up in the scope of the member
     606                 :   //   function's class. If it is not found, or if the name is part of
     607                 :   //   a template-argument in a template-id, the look up is as
     608                 :   //   described for unqualified names in the definition of the class
     609                 :   //   granting friendship.
     610                 :   // i.e. we don't push a scope unless it's a class member.
     611                 : 
                       27: branch 1 taken
                      473: branch 2 taken
                        0: branch 3 not taken
     612              500:   switch (Qualifier->getKind()) {
     613                 :   case NestedNameSpecifier::Global:
     614                 :   case NestedNameSpecifier::Namespace:
     615                 :     // These are always namespace scopes.  We never want to enter a
     616                 :     // namespace scope from anything but a file context.
     617               27:     return CurContext->getLookupContext()->isFileContext();
     618                 : 
     619                 :   case NestedNameSpecifier::Identifier:
     620                 :   case NestedNameSpecifier::TypeSpec:
     621                 :   case NestedNameSpecifier::TypeSpecWithTemplate:
     622                 :     // These are never namespace scopes.
     623              473:     return true;
     624                 :   }
     625                 : 
     626                 :   // Silence bogus warning.
     627                0:   return false;
     628                 : }
     629                 : 
     630                 : /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
     631                 : /// scope or nested-name-specifier) is parsed, part of a declarator-id.
     632                 : /// After this method is called, according to [C++ 3.4.3p3], names should be
     633                 : /// looked up in the declarator-id's scope, until the declarator is parsed and
     634                 : /// ActOnCXXExitDeclaratorScope is called.
     635                 : /// The 'SS' should be a non-empty valid CXXScopeSpec.
     636              496: bool Sema::ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
                      496: branch 1 taken
                        0: branch 2 not taken
     637              496:   assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
     638                 : 
                        0: branch 1 not taken
                      496: branch 2 taken
     639              496:   if (SS.isInvalid()) return true;
     640                 : 
     641              496:   DeclContext *DC = computeDeclContext(SS, true);
                        3: branch 0 taken
                      493: branch 1 taken
     642              496:   if (!DC) return true;
     643                 : 
     644                 :   // Before we enter a declarator's context, we need to make sure that
     645                 :   // it is a complete declaration context.
                      378: branch 1 taken
                      115: branch 2 taken
                        4: branch 4 taken
                      374: branch 5 taken
                        4: branch 6 taken
                      489: branch 7 taken
     646              493:   if (!DC->isDependentContext() && RequireCompleteDeclContext(SS))
     647                4:     return true;
     648                 :     
     649              489:   EnterDeclaratorContext(S, DC);
     650              489:   return false;
     651                 : }
     652                 : 
     653                 : /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
     654                 : /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
     655                 : /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well.
     656                 : /// Used to indicate that names should revert to being looked up in the
     657                 : /// defining scope.
     658              489: void Sema::ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
                      489: branch 1 taken
                        0: branch 2 not taken
     659              489:   assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
                      489: branch 1 taken
                        0: branch 2 not taken
     660              489:   if (SS.isInvalid())
     661                0:     return;
     662                 :   assert(!SS.isInvalid() && computeDeclContext(SS, true) &&
                      489: branch 1 taken
                        0: branch 2 not taken
                      489: branch 4 taken
                        0: branch 5 not taken
     663              489:          "exiting declarator scope we never really entered");
     664              489:   ExitDeclaratorContext(S);
     665                 : }

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