Pass information in a record instead of stack. NFC
authorSerge Pavlov <sepavloff@gmail.com>
Mon, 8 Aug 2016 04:02:15 +0000 (04:02 +0000)
committerSerge Pavlov <sepavloff@gmail.com>
Mon, 8 Aug 2016 04:02:15 +0000 (04:02 +0000)
Functions of Sema that work with building of nested name specifiers have too
many parameters (BuildCXXNestedNameSpecifier already expects 10 arguments).
With this change the information about identifier and its context is packed
into a structure, which is then passes to the semantic functions.

llvm-svn: 277976

clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseExprCXX.cpp
clang/lib/Sema/SemaCXXScopeSpec.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/TreeTransform.h

index d50fb34..e51380f 100644 (file)
@@ -4954,16 +4954,41 @@ public:
                                        bool *CanCorrect = nullptr);
   NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
 
+  /// \brief Keeps information about an identifier in a nested-name-spec.
+  ///
+  struct NestedNameSpecInfo {
+    /// \brief The type of the object, if we're parsing nested-name-specifier in
+    /// a member access expression.
+    ParsedType ObjectType;
+
+    /// \brief The identifier preceding the '::'.
+    IdentifierInfo *Identifier;
+
+    /// \brief The location of the identifier.
+    SourceLocation IdentifierLoc;
+
+    /// \brief The location of the '::'.
+    SourceLocation CCLoc;
+
+    /// \brief Creates info object for the most typical case.
+    NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc,
+             SourceLocation ColonColonLoc, ParsedType ObjectType = ParsedType())
+      : ObjectType(ObjectType), Identifier(II), IdentifierLoc(IdLoc),
+        CCLoc(ColonColonLoc) {
+    }
+
+    NestedNameSpecInfo(IdentifierInfo *II, SourceLocation IdLoc,
+                       SourceLocation ColonColonLoc, QualType ObjectType)
+      : ObjectType(ParsedType::make(ObjectType)), Identifier(II),
+        IdentifierLoc(IdLoc), CCLoc(ColonColonLoc) {
+    }
+  };
+
   bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
-                                    SourceLocation IdLoc,
-                                    IdentifierInfo &II,
-                                    ParsedType ObjectType);
+                                    NestedNameSpecInfo &IdInfo);
 
   bool BuildCXXNestedNameSpecifier(Scope *S,
-                                   IdentifierInfo &Identifier,
-                                   SourceLocation IdentifierLoc,
-                                   SourceLocation CCLoc,
-                                   QualType ObjectType,
+                                   NestedNameSpecInfo &IdInfo,
                                    bool EnteringContext,
                                    CXXScopeSpec &SS,
                                    NamedDecl *ScopeLookupResult,
@@ -4974,14 +4999,8 @@ public:
   ///
   /// \param S The scope in which this nested-name-specifier occurs.
   ///
-  /// \param Identifier The identifier preceding the '::'.
-  ///
-  /// \param IdentifierLoc The location of the identifier.
-  ///
-  /// \param CCLoc The location of the '::'.
-  ///
-  /// \param ObjectType The type of the object, if we're parsing
-  /// nested-name-specifier in a member access expression.
+  /// \param IdInfo Parser information about an identifier in the
+  /// nested-name-spec.
   ///
   /// \param EnteringContext Whether we're entering the context nominated by
   /// this nested-name-specifier.
@@ -5000,10 +5019,7 @@ public:
   ///
   /// \returns true if an error occurred, false otherwise.
   bool ActOnCXXNestedNameSpecifier(Scope *S,
-                                   IdentifierInfo &Identifier,
-                                   SourceLocation IdentifierLoc,
-                                   SourceLocation CCLoc,
-                                   ParsedType ObjectType,
+                                   NestedNameSpecInfo &IdInfo,
                                    bool EnteringContext,
                                    CXXScopeSpec &SS,
                                    bool ErrorRecoveryLookup = false,
@@ -5016,10 +5032,7 @@ public:
                                            SourceLocation ColonColonLoc);
 
   bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
-                                 IdentifierInfo &Identifier,
-                                 SourceLocation IdentifierLoc,
-                                 SourceLocation ColonLoc,
-                                 ParsedType ObjectType,
+                                 NestedNameSpecInfo &IdInfo,
                                  bool EnteringContext);
 
   /// \brief The parser has parsed a nested-name-specifier
index f0b8102..35661d5 100644 (file)
@@ -427,13 +427,13 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
     //   namespace-name '::'
     //   nested-name-specifier identifier '::'
     Token Next = NextToken();
-    
+    Sema::NestedNameSpecInfo IdInfo(&II, Tok.getLocation(), Next.getLocation(),
+                                    ObjectType);
+
     // If we get foo:bar, this is almost certainly a typo for foo::bar.  Recover
     // and emit a fixit hint for it.
     if (Next.is(tok::colon) && !ColonIsSacred) {
-      if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, II, 
-                                            Tok.getLocation(), 
-                                            Next.getLocation(), ObjectType,
+      if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, IdInfo,
                                             EnteringContext) &&
           // If the token after the colon isn't an identifier, it's still an
           // error, but they probably meant something else strange so don't
@@ -459,8 +459,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
 
     if (Next.is(tok::coloncolon)) {
       if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) &&
-          !Actions.isNonTypeNestedNameSpecifier(
-              getCurScope(), SS, Tok.getLocation(), II, ObjectType)) {
+          !Actions.isNonTypeNestedNameSpecifier(getCurScope(), SS, IdInfo)) {
         *MayBePseudoDestructor = true;
         return false;
       }
@@ -496,8 +495,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
 
       bool IsCorrectedToColon = false;
       bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr;
-      if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), II, IdLoc, CCLoc,
-                                              ObjectType, EnteringContext, SS,
+      if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), IdInfo,
+                                              EnteringContext, SS,
                                               false, CorrectionFlagPtr)) {
         // Identifier is not recognized as a nested name, but we can have
         // mistyped '::' instead of ':'.
index 7ea9fbb..637a631 100644 (file)
@@ -380,12 +380,11 @@ NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
 }
 
 bool Sema::isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
-                                        SourceLocation IdLoc,
-                                        IdentifierInfo &II,
-                                        ParsedType ObjectTypePtr) {
-  QualType ObjectType = GetTypeFromParser(ObjectTypePtr);
-  LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
-  
+                                        NestedNameSpecInfo &IdInfo) {
+  QualType ObjectType = GetTypeFromParser(IdInfo.ObjectType);
+  LookupResult Found(*this, IdInfo.Identifier, IdInfo.IdentifierLoc,
+                     LookupNestedNameSpecifierName);
+
   // Determine where to perform name lookup
   DeclContext *LookupCtx = nullptr;
   bool isDependent = false;
@@ -448,11 +447,8 @@ class NestedNameSpecifierValidatorCCC : public CorrectionCandidateCallback {
 /// by ActOnCXXNestedNameSpecifier.
 ///
 /// \param S Scope in which the nested-name-specifier occurs.
-/// \param Identifier Identifier in the sequence "identifier" "::".
-/// \param IdentifierLoc Location of the \p Identifier.
-/// \param CCLoc Location of "::" following Identifier.
-/// \param ObjectType Type of postfix expression if the nested-name-specifier
-///        occurs in construct like: <tt>ptr->nns::f</tt>.
+/// \param IdInfo Parser information about an identifier in the
+///        nested-name-spec.
 /// \param EnteringContext If true, enter the context specified by the
 ///        nested-name-specifier.
 /// \param SS Optional nested name specifier preceding the identifier.
@@ -478,17 +474,15 @@ class NestedNameSpecifierValidatorCCC : public CorrectionCandidateCallback {
 /// dependent context, for example. Nor will it extend \p SS with the scope
 /// specifier.
 bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
-                                       IdentifierInfo &Identifier,
-                                       SourceLocation IdentifierLoc,
-                                       SourceLocation CCLoc,
-                                       QualType ObjectType,
+                                       NestedNameSpecInfo &IdInfo,
                                        bool EnteringContext,
                                        CXXScopeSpec &SS,
                                        NamedDecl *ScopeLookupResult,
                                        bool ErrorRecoveryLookup,
                                        bool *IsCorrectedToColon) {
-  LookupResult Found(*this, &Identifier, IdentifierLoc, 
+  LookupResult Found(*this, IdInfo.Identifier, IdInfo.IdentifierLoc,
                      LookupNestedNameSpecifierName);
+  QualType ObjectType = GetTypeFromParser(IdInfo.ObjectType);
 
   // Determine where to perform name lookup
   DeclContext *LookupCtx = nullptr;
@@ -573,7 +567,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
     // base object type or prior nested-name-specifier, so this
     // nested-name-specifier refers to an unknown specialization. Just build
     // a dependent nested-name-specifier.
-    SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
+    SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc, IdInfo.CCLoc);
     return false;
   }
 
@@ -592,18 +586,19 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
       // allowed, suggest replacement to ':'.
       if (IsCorrectedToColon) {
         *IsCorrectedToColon = true;
-        Diag(CCLoc, diag::err_nested_name_spec_is_not_class)
-            << &Identifier << getLangOpts().CPlusPlus
-            << FixItHint::CreateReplacement(CCLoc, ":");
+        Diag(IdInfo.CCLoc, diag::err_nested_name_spec_is_not_class)
+            << IdInfo.Identifier << getLangOpts().CPlusPlus
+            << FixItHint::CreateReplacement(IdInfo.CCLoc, ":");
         if (NamedDecl *ND = R.getAsSingle<NamedDecl>())
           Diag(ND->getLocation(), diag::note_declared_at);
         return true;
       }
       // Replacement '::' -> ':' is not allowed, just issue respective error.
       Diag(R.getNameLoc(), diag::err_expected_class_or_namespace)
-          << &Identifier << getLangOpts().CPlusPlus;
+          << IdInfo.Identifier << getLangOpts().CPlusPlus;
       if (NamedDecl *ND = R.getAsSingle<NamedDecl>())
-        Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
+        Diag(ND->getLocation(), diag::note_entity_declared_at)
+            << IdInfo.Identifier;
       return true;
     }
   }
@@ -638,7 +633,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
         Found.addDecl(ND);
       Found.setLookupName(Corrected.getCorrection());
     } else {
-      Found.setLookupName(&Identifier);
+      Found.setLookupName(IdInfo.Identifier);
     }
   }
 
@@ -648,7 +643,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
   bool AcceptSpec = isAcceptableNestedNameSpecifier(SD, &IsExtension);
   if (!AcceptSpec && IsExtension) {
     AcceptSpec = true;
-    Diag(IdentifierLoc, diag::ext_nested_name_spec_is_enum);
+    Diag(IdInfo.IdentifierLoc, diag::ext_nested_name_spec_is_enum);
   }
   if (AcceptSpec) {
     if (!ObjectType.isNull() && !ObjectTypeSearchedInScope &&
@@ -665,7 +660,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
       // Note that C++11 does *not* perform this redundant lookup.
       NamedDecl *OuterDecl;
       if (S) {
-        LookupResult FoundOuter(*this, &Identifier, IdentifierLoc, 
+        LookupResult FoundOuter(*this, IdInfo.Identifier, IdInfo.IdentifierLoc,
                                 LookupNestedNameSpecifierName);
         LookupName(FoundOuter, S);
         OuterDecl = FoundOuter.getAsSingle<NamedDecl>();
@@ -681,9 +676,9 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
         if (ErrorRecoveryLookup)
           return true;
 
-         Diag(IdentifierLoc, 
+         Diag(IdInfo.IdentifierLoc,
               diag::err_nested_name_member_ref_lookup_ambiguous)
-           << &Identifier;
+           << IdInfo.Identifier;
          Diag(SD->getLocation(), diag::note_ambig_member_ref_object_type)
            << ObjectType;
          Diag(OuterDecl->getLocation(), diag::note_ambig_member_ref_scope);
@@ -702,16 +697,15 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
       return false;
 
     // The use of a nested name specifier may trigger deprecation warnings.
-    DiagnoseUseOfDecl(SD, CCLoc);
+    DiagnoseUseOfDecl(SD, IdInfo.CCLoc);
 
-    
     if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD)) {
-      SS.Extend(Context, Namespace, IdentifierLoc, CCLoc);
+      SS.Extend(Context, Namespace, IdInfo.IdentifierLoc, IdInfo.CCLoc);
       return false;
     }
 
     if (NamespaceAliasDecl *Alias = dyn_cast<NamespaceAliasDecl>(SD)) {
-      SS.Extend(Context, Alias, IdentifierLoc, CCLoc);
+      SS.Extend(Context, Alias, IdInfo.IdentifierLoc, IdInfo.CCLoc);
       return false;
     }
 
@@ -721,41 +715,41 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
     if (isa<InjectedClassNameType>(T)) {
       InjectedClassNameTypeLoc InjectedTL
         = TLB.push<InjectedClassNameTypeLoc>(T);
-      InjectedTL.setNameLoc(IdentifierLoc);
+      InjectedTL.setNameLoc(IdInfo.IdentifierLoc);
     } else if (isa<RecordType>(T)) {
       RecordTypeLoc RecordTL = TLB.push<RecordTypeLoc>(T);
-      RecordTL.setNameLoc(IdentifierLoc);
+      RecordTL.setNameLoc(IdInfo.IdentifierLoc);
     } else if (isa<TypedefType>(T)) {
       TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(T);
-      TypedefTL.setNameLoc(IdentifierLoc);
+      TypedefTL.setNameLoc(IdInfo.IdentifierLoc);
     } else if (isa<EnumType>(T)) {
       EnumTypeLoc EnumTL = TLB.push<EnumTypeLoc>(T);
-      EnumTL.setNameLoc(IdentifierLoc);
+      EnumTL.setNameLoc(IdInfo.IdentifierLoc);
     } else if (isa<TemplateTypeParmType>(T)) {
       TemplateTypeParmTypeLoc TemplateTypeTL
         = TLB.push<TemplateTypeParmTypeLoc>(T);
-      TemplateTypeTL.setNameLoc(IdentifierLoc);
+      TemplateTypeTL.setNameLoc(IdInfo.IdentifierLoc);
     } else if (isa<UnresolvedUsingType>(T)) {
       UnresolvedUsingTypeLoc UnresolvedTL
         = TLB.push<UnresolvedUsingTypeLoc>(T);
-      UnresolvedTL.setNameLoc(IdentifierLoc);
+      UnresolvedTL.setNameLoc(IdInfo.IdentifierLoc);
     } else if (isa<SubstTemplateTypeParmType>(T)) {
       SubstTemplateTypeParmTypeLoc TL 
         = TLB.push<SubstTemplateTypeParmTypeLoc>(T);
-      TL.setNameLoc(IdentifierLoc);
+      TL.setNameLoc(IdInfo.IdentifierLoc);
     } else if (isa<SubstTemplateTypeParmPackType>(T)) {
       SubstTemplateTypeParmPackTypeLoc TL
         = TLB.push<SubstTemplateTypeParmPackTypeLoc>(T);
-      TL.setNameLoc(IdentifierLoc);
+      TL.setNameLoc(IdInfo.IdentifierLoc);
     } else {
       llvm_unreachable("Unhandled TypeDecl node in nested-name-specifier");
     }
 
     if (T->isEnumeralType())
-      Diag(IdentifierLoc, diag::warn_cxx98_compat_enum_nested_name_spec);
+      Diag(IdInfo.IdentifierLoc, diag::warn_cxx98_compat_enum_nested_name_spec);
 
     SS.Extend(Context, SourceLocation(), TLB.getTypeLocInContext(Context, T),
-              CCLoc);
+              IdInfo.CCLoc);
     return false;
   }
 
@@ -794,9 +788,11 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
     if (DC->isDependentContext() && DC->isFunctionOrMethod()) {
       CXXRecordDecl *ContainingClass = dyn_cast<CXXRecordDecl>(DC->getParent());
       if (ContainingClass && ContainingClass->hasAnyDependentBases()) {
-        Diag(IdentifierLoc, diag::ext_undeclared_unqual_id_with_dependent_base)
-            << &Identifier << ContainingClass;
-        SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
+        Diag(IdInfo.IdentifierLoc,
+             diag::ext_undeclared_unqual_id_with_dependent_base)
+            << IdInfo.Identifier << ContainingClass;
+        SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc,
+                  IdInfo.CCLoc);
         return false;
       }
     }
@@ -804,28 +800,27 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
 
   if (!Found.empty()) {
     if (TypeDecl *TD = Found.getAsSingle<TypeDecl>())
-      Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
+      Diag(IdInfo.IdentifierLoc, diag::err_expected_class_or_namespace)
           << QualType(TD->getTypeForDecl(), 0) << getLangOpts().CPlusPlus;
     else {
-      Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
-          << &Identifier << getLangOpts().CPlusPlus;
+      Diag(IdInfo.IdentifierLoc, diag::err_expected_class_or_namespace)
+          << IdInfo.Identifier << getLangOpts().CPlusPlus;
       if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
-        Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
+        Diag(ND->getLocation(), diag::note_entity_declared_at)
+            << IdInfo.Identifier;
     }
   } else if (SS.isSet())
-    Diag(IdentifierLoc, diag::err_no_member) << &Identifier << LookupCtx
-                                             << SS.getRange();
+    Diag(IdInfo.IdentifierLoc, diag::err_no_member) << IdInfo.Identifier
+        << LookupCtx << SS.getRange();
   else
-    Diag(IdentifierLoc, diag::err_undeclared_var_use) << &Identifier;
+    Diag(IdInfo.IdentifierLoc, diag::err_undeclared_var_use)
+        << IdInfo.Identifier;
 
   return true;
 }
 
 bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
-                                       IdentifierInfo &Identifier,
-                                       SourceLocation IdentifierLoc,
-                                       SourceLocation CCLoc,
-                                       ParsedType ObjectType,
+                                       NestedNameSpecInfo &IdInfo,
                                        bool EnteringContext,
                                        CXXScopeSpec &SS,
                                        bool ErrorRecoveryLookup,
@@ -833,9 +828,8 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
   if (SS.isInvalid())
     return true;
 
-  return BuildCXXNestedNameSpecifier(S, Identifier, IdentifierLoc, CCLoc,
-                                     GetTypeFromParser(ObjectType),
-                                     EnteringContext, SS, 
+  return BuildCXXNestedNameSpecifier(S, IdInfo,
+                                     EnteringContext, SS,
                                      /*ScopeLookupResult=*/nullptr, false,
                                      IsCorrectedToColon);
 }
@@ -870,17 +864,12 @@ bool Sema::ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS,
 ///
 /// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
 bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
-                                     IdentifierInfo &Identifier, 
-                                     SourceLocation IdentifierLoc,
-                                     SourceLocation ColonLoc,
-                                     ParsedType ObjectType,
+                                     NestedNameSpecInfo &IdInfo,
                                      bool EnteringContext) {
   if (SS.isInvalid())
     return false;
 
-  return !BuildCXXNestedNameSpecifier(S, Identifier, IdentifierLoc, ColonLoc,
-                                      GetTypeFromParser(ObjectType),
-                                      EnteringContext, SS, 
+  return !BuildCXXNestedNameSpecifier(S, IdInfo, EnteringContext, SS,
                                       /*ScopeLookupResult=*/nullptr, true);
 }
 
index ea7a31d..a18ef0c 100644 (file)
@@ -781,8 +781,8 @@ Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name,
   ObjCMethodDecl *CurMethod = getCurMethodDecl();
 
   if (NextToken.is(tok::coloncolon)) {
-    BuildCXXNestedNameSpecifier(S, *Name, NameLoc, NextToken.getLocation(),
-                                QualType(), false, SS, nullptr, false);
+    NestedNameSpecInfo IdInfo(Name, NameLoc, NextToken.getLocation());
+    BuildCXXNestedNameSpecifier(S, IdInfo, false, SS, nullptr, false);
   }
 
   LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
index f68cdca..8ea0b01 100644 (file)
@@ -3438,15 +3438,13 @@ TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
     NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
 
     switch (QNNS->getKind()) {
-    case NestedNameSpecifier::Identifier:
-      if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr,
-                                              *QNNS->getAsIdentifier(),
-                                              Q.getLocalBeginLoc(),
-                                              Q.getLocalEndLoc(),
-                                              ObjectType, false, SS,
-                                              FirstQualifierInScope, false))
+    case NestedNameSpecifier::Identifier: {
+      Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
+                          Q.getLocalBeginLoc(), Q.getLocalEndLoc(), ObjectType);
+      if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
+                                              SS, FirstQualifierInScope, false))
         return NestedNameSpecifierLoc();
-
+    }
       break;
 
     case NestedNameSpecifier::Namespace: {