]> granicus.if.org Git - clang/commitdiff
revert my previous patch, it is breaking something and I don't have time
authorChris Lattner <sabre@nondot.org>
Sun, 6 Dec 2009 20:58:07 +0000 (20:58 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 6 Dec 2009 20:58:07 +0000 (20:58 +0000)
to fix it ATM.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90717 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
include/clang/Parse/Action.h
include/clang/Parse/Parser.h
lib/Parse/ParseDeclCXX.cpp
lib/Parse/ParseExprCXX.cpp
lib/Sema/Sema.h
lib/Sema/SemaCXXScopeSpec.cpp
lib/Sema/TreeTransform.h
test/Parser/cxx-decl.cpp
test/SemaCXX/nested-name-spec.cpp

index bf188cf14f9111d3ad765a19b6ee6aaf926535d8..43107044720e6a986c2966534fe8a4a717957d7a 100644 (file)
@@ -166,8 +166,6 @@ def err_use_of_tag_name_without_tag : Error<
   "use of tagged type %0 without '%1' tag">;
 def err_expected_ident_in_using : Error<
   "expected an identifier in using directive">;
-def err_unexected_colon_in_nested_name_spec : Error<
-  "unexpected ':' in nested name specifier">;
 
 /// Objective-C parser diagnostics
 def err_objc_no_attributes_on_category : Error<
index 200bd8a6b21ef94fdde229204498825a500a2951..fc56cc68476eabb64491b2bcd28b009e311d3115 100644 (file)
@@ -334,20 +334,6 @@ public:
                                                   bool EnteringContext) {
     return 0;
   }
-  
-  /// IsInvalidUnlessNestedName - This method is used for error recovery
-  /// purposes to determine whether the specified identifier is only valid as
-  /// a nested name specifier, for example a namespace name.  It is
-  /// conservatively correct to always return false from this method.
-  ///
-  /// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
-  virtual bool IsInvalidUnlessNestedName(Scope *S,
-                                         const CXXScopeSpec &SS,
-                                         IdentifierInfo &II,
-                                         TypeTy *ObjectType,
-                                         bool EnteringContext) {
-    return false;
-  }
 
   /// ActOnCXXNestedNameSpecifier - Called during parsing of a
   /// nested-name-specifier that involves a template-id, e.g.,
index 3814cb9cc1a2269d6848f04fad35dfba54f5b20b..d906b09d9bb7c72b22583d9627cc934b6efbcffa 100644 (file)
@@ -887,8 +887,7 @@ private:
 
   bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
                                       TypeTy *ObjectType,
-                                      bool EnteringContext,
-                                      bool ColonIsSacred = false);
+                                      bool EnteringContext);
 
   //===--------------------------------------------------------------------===//
   // C++ 5.2p1: C++ Casts
index 238048f6153e2c9a12f2d4e95974920eff819ed1..d852127b1fb16a8a8fcf47d6ef3448969b3315c8 100644 (file)
@@ -132,7 +132,7 @@ Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
   
   CXXScopeSpec SS;
   // Parse (optional) nested-name-specifier.
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false, false);
+  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
 
   if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_namespace_name);
@@ -260,7 +260,7 @@ Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
   
   CXXScopeSpec SS;
   // Parse (optional) nested-name-specifier.
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false, false);
+  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
 
   IdentifierInfo *NamespcName = 0;
   SourceLocation IdentLoc = SourceLocation();
@@ -322,7 +322,7 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
     IsTypeName = false;
 
   // Parse nested-name-specifier.
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false, false);
+  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
 
   AttributeList *AttrList = 0;
 
@@ -601,7 +601,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
   // Parse the (optional) nested-name-specifier.
   CXXScopeSpec SS;
   if (getLang().CPlusPlus &&
-      ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true, true))
+      ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true))
     if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
       Diag(Tok, diag::err_expected_ident);
 
index ae2a47befd41c533ff09462c4bd2630e417c3148..4eb6cd5daa4681f449f9a4033b237a5d81e1ad70 100644 (file)
@@ -45,14 +45,10 @@ using namespace clang;
 /// \param EnteringContext whether we will be entering into the context of
 /// the nested-name-specifier after parsing it.
 ///
-/// \param ColonIsSacred - If this is true, then a colon is valid after the
-/// specifier, so we should not try to recover from colons aggressively.
-///
 /// \returns true if a scope specifier was parsed.
 bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
                                             Action::TypeTy *ObjectType,
-                                            bool EnteringContext,
-                                            bool ColonIsSacred) {
+                                            bool EnteringContext) {
   assert(getLang().CPlusPlus &&
          "Call sites of this function should be guarded by checking for C++");
 
@@ -218,29 +214,11 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
     //   namespace-name '::'
     //   nested-name-specifier identifier '::'
     Token Next = NextToken();
-    
-    // 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 &&
-        Actions.IsInvalidUnlessNestedName(CurScope, SS, II, ObjectType,
-                                          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
-        // recover like this.
-        PP.LookAhead(1).is(tok::identifier)) {
-      Diag(Next, diag::err_unexected_colon_in_nested_name_spec)
-        << CodeModificationHint::CreateReplacement(Next.getLocation(), "::");
-      
-      // Recover as if the user wrote '::'.
-      Next.setKind(tok::coloncolon);
-    }
-    
     if (Next.is(tok::coloncolon)) {
       // We have an identifier followed by a '::'. Lookup this name
       // as the name in a nested-name-specifier.
       SourceLocation IdLoc = ConsumeToken();
-      assert((Tok.is(tok::coloncolon) || Tok.is(tok::colon)) &&
-             "NextToken() not working properly!");
+      assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
       SourceLocation CCLoc = ConsumeToken();
 
       if (!HasScopeSpecifier) {
index cd1a725987f96dfa8d060303088e873296c66ef8..9606821f78a58997b3e44056938fa128df644ea6 100644 (file)
@@ -2000,8 +2000,7 @@ public:
                                           IdentifierInfo &II,
                                           QualType ObjectType,
                                           NamedDecl *ScopeLookupResult,
-                                          bool EnteringContext,
-                                          bool EmitNoDiagnostics);
+                                          bool EnteringContext);
 
   virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
                                                   const CXXScopeSpec &SS,
@@ -2011,12 +2010,6 @@ public:
                                                   TypeTy *ObjectType,
                                                   bool EnteringContext);
 
-  virtual bool IsInvalidUnlessNestedName(Scope *S,
-                                         const CXXScopeSpec &SS,
-                                         IdentifierInfo &II,
-                                         TypeTy *ObjectType,
-                                         bool EnteringContext);
-  
   /// ActOnCXXNestedNameSpecifier - Called during parsing of a
   /// nested-name-specifier that involves a template-id, e.g.,
   /// "foo::bar<int, float>::", and now we need to build a scope
index 4a8dd62b44e08d421189fe10ab718241dc19db14..14db77440fed0cd8fc353a56bf50f755baee461e 100644 (file)
@@ -330,9 +330,6 @@ NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
 /// that it contains an extra parameter \p ScopeLookupResult, which provides
 /// the result of name lookup within the scope of the nested-name-specifier
 /// that was computed at template definitino time.
-///
-/// If EmitNoDiagnostics is true, this should not emit diagnostics, it should
-/// just return null on failure.
 Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
                                                     const CXXScopeSpec &SS,
                                                     SourceLocation IdLoc,
@@ -340,8 +337,7 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
                                                     IdentifierInfo &II,
                                                     QualType ObjectType,
                                                   NamedDecl *ScopeLookupResult,
-                                                    bool EnteringContext,
-                                                    bool EmitNoDiagnostics) {
+                                                    bool EnteringContext) {
   NestedNameSpecifier *Prefix
     = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
 
@@ -446,17 +442,14 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
            !Context.hasSameType(
                             Context.getTypeDeclType(cast<TypeDecl>(OuterDecl)),
                                Context.getTypeDeclType(cast<TypeDecl>(SD))))) {
-             if (EmitNoDiagnostics)
-               return 0;
-             
              Diag(IdLoc, diag::err_nested_name_member_ref_lookup_ambiguous)
                << &II;
              Diag(SD->getLocation(), diag::note_ambig_member_ref_object_type)
                << ObjectType;
              Diag(OuterDecl->getLocation(), diag::note_ambig_member_ref_scope);
 
-             // Fall through so that we'll pick the name we found in the object
-             // type, since that's probably what the user wanted anyway.
+             // Fall through so that we'll pick the name we found in the object type,
+             // since that's probably what the user wanted anyway.
            }
     }
 
@@ -476,11 +469,6 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
                                        T.getTypePtr());
   }
 
-  // Otherwise, we have an error case.  If we don't want diagnostics, just
-  // return an error now.
-  if (EmitNoDiagnostics)
-    return 0;
-
   // If we didn't find anything during our lookup, try again with
   // ordinary name lookup, which can help us produce better error
   // messages.
@@ -521,23 +509,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
                                                     bool EnteringContext) {
   return BuildCXXNestedNameSpecifier(S, SS, IdLoc, CCLoc, II,
                                      QualType::getFromOpaquePtr(ObjectTypePtr),
-                                     /*ScopeLookupResult=*/0, EnteringContext,
-                                     false);
-}
-
-/// IsInvalidUnlessNestedName - This method is used for error recovery
-/// purposes to determine whether the specified identifier is only valid as
-/// a nested name specifier, for example a namespace name.  It is
-/// conservatively correct to always return false from this method.
-///
-/// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
-bool Sema::IsInvalidUnlessNestedName(Scope *S, const CXXScopeSpec &SS,
-                                     IdentifierInfo &II, TypeTy *ObjectType,
-                                     bool EnteringContext) {
-  return BuildCXXNestedNameSpecifier(S, SS, SourceLocation(), SourceLocation(),
-                                     II, QualType::getFromOpaquePtr(ObjectType),
-                                     /*ScopeLookupResult=*/0, EnteringContext,
-                                     true);
+                                     /*ScopeLookupResult=*/0, EnteringContext);
 }
 
 Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
index 8c251e70403e202d654f54fc696cae30e11e8c91..b029a379671528daeb05410c8d6ca6cb6b32a0f0 100644 (file)
@@ -5407,7 +5407,7 @@ TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
                                                         Range.getEnd(), II,
                                                         ObjectType,
                                                         FirstQualifierInScope,
-                                                        false, false));
+                                                        false));
 }
 
 template<typename Derived>
index 8c5ab6a55d57c29180d323fe820541c9d2bf1cf6..3fa284282ad6f7bbf42b340d7d34496936af8d6f 100644 (file)
@@ -1,24 +1,3 @@
 // RUN: clang-cc -verify -fsyntax-only %s
 
 int x(*g); // expected-error {{use of undeclared identifier 'g'}}
-
-
-// PR4451 - We should recover well from the typo of '::' as ':' in a2.
-namespace y {
-  struct a { };  
-}
-
-y::a a1;
-y:a a2;  // expected-error {{unexpected ':' in nested name specifier}}
-y::a a3 = a2;
-
-// Some valid colons:
-void foo() {
-y:  // label
-  y::a s;
-  
-  int a = 4;
-  a = a ? a : a+1;
-}
-
-struct b : y::a {};
\ No newline at end of file
index 6a51261e26fcf9cabbf0f3c511804a1e9efa5af7..83c72417d590bd88498347aad7a063751eb2bf8b 100644 (file)
@@ -186,10 +186,12 @@ class foo {
 };
 
 
-// PR4452 / PR4451
-foo<somens:a> a2;  // expected-error {{unexpected ':' in nested name specifier}}
+// PR4452
+// FIXME: This error recovery sucks.
+foo<somens:a> a2;  // expected-error {{unexpected namespace name 'somens': expected expression}} \
+expected-error {{C++ requires a type specifier for all declarations}}
 
-somens::a a3 = a2; // expected-error {{cannot initialize 'a3' with an lvalue of type 'foo<somens::a>'}}
+somens::a a3 = a2;