[PATCH] D16949: Fix for: Bug 5941 - improve diagnostic for * vs & confusion

2016-02-06 Thread Ryan Yee via cfe-commits
ryee88 created this revision.
ryee88 added reviewers: doug.gregor, jyasskin, nicholas, rsmith.
ryee88 added a subscriber: cfe-commits.

This is bug 5941: https://llvm.org/bugs/show_bug.cgi?id=5941

I copied the extra suggestions from the complete type case to the incomplete 
type case.

http://reviews.llvm.org/D16949

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaOverload.cpp

Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -9104,10 +9104,13 @@
   if (const PointerType *PTy = TempFromTy->getAs())
 TempFromTy = PTy->getPointeeType();
   if (TempFromTy->isIncompleteType()) {
+// Emit the generic diagnostic and, optionally, add the hints to it.
 S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
   << (unsigned) FnKind << FnDesc
   << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
-  << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+  << FromTy << ToTy << (unsigned) isObjectArgument << I+1
+  << (unsigned) (Cand->Fix.Kind);
+  
 MaybeEmitInheritedConstructorNote(S, Fn);
 return;
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3189,7 +3189,12 @@
 "function (the implicit move assignment operator)|"
 "constructor (inherited)}0%1 "
 "not viable: cannot convert argument of incomplete type "
-"%diff{$ to $|to parameter type}2,3">;
+"%diff{$ to $|to parameter type}2,3 for "
+"%select{%ordinal5 argument|object argument}4"
+"%select{|; dereference the argument with *|"
+"; take the address of the argument with &|"
+"; remove *|"
+"; remove &}6">;
 def note_ovl_candidate_bad_list_argument : Note<"candidate "
 "%select{function|function|constructor|"
 "function |function |constructor |"


Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -9104,10 +9104,13 @@
   if (const PointerType *PTy = TempFromTy->getAs())
 TempFromTy = PTy->getPointeeType();
   if (TempFromTy->isIncompleteType()) {
+// Emit the generic diagnostic and, optionally, add the hints to it.
 S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
   << (unsigned) FnKind << FnDesc
   << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
-  << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+  << FromTy << ToTy << (unsigned) isObjectArgument << I+1
+  << (unsigned) (Cand->Fix.Kind);
+  
 MaybeEmitInheritedConstructorNote(S, Fn);
 return;
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3189,7 +3189,12 @@
 "function (the implicit move assignment operator)|"
 "constructor (inherited)}0%1 "
 "not viable: cannot convert argument of incomplete type "
-"%diff{$ to $|to parameter type}2,3">;
+"%diff{$ to $|to parameter type}2,3 for "
+"%select{%ordinal5 argument|object argument}4"
+"%select{|; dereference the argument with *|"
+"; take the address of the argument with &|"
+"; remove *|"
+"; remove &}6">;
 def note_ovl_candidate_bad_list_argument : Note<"candidate "
 "%select{function|function|constructor|"
 "function |function |constructor |"
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-02-07 Thread Ryan Yee via cfe-commits
ryee88 created this revision.
ryee88 added reviewers: doug.gregor, gribozavr, francisco.lopes.
ryee88 added a subscriber: cfe-commits.

Bug 14644 - clang confuses scope operator for global namespace giving extra 
qualification on member

This is a fix for this bug: https://llvm.org/bugs/show_bug.cgi?id=14644

Essentially the diagnostic needs to distinguish between a "global-specifier 
with no nested-name-specifier" and nested-name-specifier (everything else) in 
order to provide a more helpful error message.

http://reviews.llvm.org/D16965

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp

Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -3789,6 +3789,17 @@
   if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() &&
   !IsExplicitInstantiation && !IsExplicitSpecialization &&
   !isa(Tag)) {
+
+// Per C++ standard [n3485] 3.4.4 Elaborated type specifiers, section 3:
+// "Cannot introduce an qualified".
+// A clang::NestedNameSpecifier can represent many kinds of specifiers.
+// A global-specifier with no nested-name-specifier requires a different
+// diagnostic from a nested-name specifier.
+unsigned diagId = ( SS.getScopeRep()->getKind() == 
NestedNameSpecifier::Global &&
+  !SS.getScopeRep()->getPrefix() )
+  ? diag::err_standalone_class_specifier
+  : diagId = diag::err_standalone_class_nested_name_specifier;
+
 // Per C++ [dcl.type.elab]p1, a class declaration cannot have a
 // nested-name-specifier unless it is an explicit instantiation
 // or an explicit specialization.
@@ -3797,8 +3808,9 @@
 // obvious intent of DR1819.
 //
 // Per C++ [dcl.enum]p1, an opaque-enum-declaration can't either.
-Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier)
-<< GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange();
+Diag(SS.getBeginLoc(), diagId)
+  << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange();
+
 return nullptr;
   }
 
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5241,6 +5241,9 @@
 def err_standalone_class_nested_name_specifier : Error<
   "forward declaration of %select{class|struct|interface|union|enum}0 cannot "
   "have a nested name specifier">;
+def err_standalone_class_specifier : Error<
+  "forward declaration of qualified 
%select{class|struct|interface|union|enum}0 "
+   "not allowed">;
 def err_typecheck_sclass_func : Error<"illegal storage class on function">;
 def err_static_block_func : Error<
   "function declared in block scope cannot have 'static' storage class">;


Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -3789,6 +3789,17 @@
   if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() &&
   !IsExplicitInstantiation && !IsExplicitSpecialization &&
   !isa(Tag)) {
+
+// Per C++ standard [n3485] 3.4.4 Elaborated type specifiers, section 3:
+// "Cannot introduce an qualified".
+// A clang::NestedNameSpecifier can represent many kinds of specifiers.
+// A global-specifier with no nested-name-specifier requires a different
+// diagnostic from a nested-name specifier.
+unsigned diagId = ( SS.getScopeRep()->getKind() == NestedNameSpecifier::Global &&
+  !SS.getScopeRep()->getPrefix() )
+  ? diag::err_standalone_class_specifier
+  : diagId = diag::err_standalone_class_nested_name_specifier;
+
 // Per C++ [dcl.type.elab]p1, a class declaration cannot have a
 // nested-name-specifier unless it is an explicit instantiation
 // or an explicit specialization.
@@ -3797,8 +3808,9 @@
 // obvious intent of DR1819.
 //
 // Per C++ [dcl.enum]p1, an opaque-enum-declaration can't either.
-Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier)
-<< GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange();
+Diag(SS.getBeginLoc(), diagId)
+  << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange();
+
 return nullptr;
   }
 
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5241,6 +5241,9 @@
 def err_standalone_class_nested_name_specifier : Error<
   "forward declaration of %select{class|struct|interface|union|enum}0 cannot "
   "have a nested name specifier">;
+def err_standalone_class_specifier : Error<
+  "forward declaration of qualified %select{class|struct|interface|union|enum}0 "
+	"not allowed">;
 def err_typecheck_sclass_func : Error<"illegal stora

Re: [PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-02-11 Thread Ryan Yee via cfe-commits
ryee88 added a comment.

Ping-- I think this review got missed.


http://reviews.llvm.org/D16965



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16949: Fix for: Bug 5941 - improve diagnostic for * vs & confusion

2016-02-11 Thread Ryan Yee via cfe-commits
ryee88 added a comment.

Ping-- can someone look at this review?


http://reviews.llvm.org/D16949



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-02-13 Thread Ryan Yee via cfe-commits
ryee88 updated this revision to Diff 47922.
ryee88 added a comment.

Added unit tests.


http://reviews.llvm.org/D16965

Files:
  test/Parser/forward-declaration.cpp

Index: test/Parser/forward-declaration.cpp
===
--- /dev/null
+++ test/Parser/forward-declaration.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+class Outer {class Inner;};
+
+class ::Outer; // expected-error {{forward declaration of qualified class not 
allowed}} expected-warning {{extra qualification on member 'Outer'}}
+
+class Outer;
+
+// specializations of qualified type introduction?
+class Outer::Inner; // expected-error {{forward declaration of class cannot 
have a nested name specifier}}
+class ::Outer::Inner; // expected-error {{forward declaration of class cannot 
have a nested name specifier}}


Index: test/Parser/forward-declaration.cpp
===
--- /dev/null
+++ test/Parser/forward-declaration.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+class Outer {class Inner;};
+
+class ::Outer; // expected-error {{forward declaration of qualified class not allowed}} expected-warning {{extra qualification on member 'Outer'}}
+
+class Outer;
+
+// specializations of qualified type introduction?
+class Outer::Inner; // expected-error {{forward declaration of class cannot have a nested name specifier}}
+class ::Outer::Inner; // expected-error {{forward declaration of class cannot have a nested name specifier}}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16949: Fix for: Bug 5941 - improve diagnostic for * vs & confusion

2016-02-13 Thread Ryan Yee via cfe-commits
ryee88 updated this revision to Diff 47924.
ryee88 added a comment.

Added unit test as per review comments.


http://reviews.llvm.org/D16949

Files:
  test/Parser/overloaded-pointer-vs-reference-hint.cpp

Index: test/Parser/overloaded-pointer-vs-reference-hint.cpp
===
--- /dev/null
+++ test/Parser/overloaded-pointer-vs-reference-hint.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+class A;
+
+void f0(A *a); // expected-note {{candidate function not viable: cannot 
convert argument of incomplete type 'A' to 'A *' for 1st argument; take the 
address of the argument with &}}
+void f1(A &a) {
+  f0(a); // expected-error {{no matching function for call to 'f0'}}
+}
+
+void f2(A &a); // expected-note {{candidate function not viable: cannot 
convert argument of incomplete type 'A *' to 'A &' for 1st argument; 
dereference the argument with *}}
+void f3(A *a) {
+  f2(a); // expected-error {{no matching function for call to 'f2'}}
+}
+
+


Index: test/Parser/overloaded-pointer-vs-reference-hint.cpp
===
--- /dev/null
+++ test/Parser/overloaded-pointer-vs-reference-hint.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+class A;
+
+void f0(A *a); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'A' to 'A *' for 1st argument; take the address of the argument with &}}
+void f1(A &a) {
+  f0(a); // expected-error {{no matching function for call to 'f0'}}
+}
+
+void f2(A &a); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'A *' to 'A &' for 1st argument; dereference the argument with *}}
+void f3(A *a) {
+  f2(a); // expected-error {{no matching function for call to 'f2'}}
+}
+
+
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16949: Fix for: Bug 5941 - improve diagnostic for * vs & confusion

2016-02-13 Thread Ryan Yee via cfe-commits
ryee88 updated this revision to Diff 47925.
ryee88 added a comment.

Sorry-- re-uploading the diff. Didn't notice I dropped the code changes.


http://reviews.llvm.org/D16949

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaOverload.cpp
  test/Parser/overloaded-pointer-vs-reference-hint.cpp

Index: test/Parser/overloaded-pointer-vs-reference-hint.cpp
===
--- /dev/null
+++ test/Parser/overloaded-pointer-vs-reference-hint.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+class A;
+
+void f0(A *a); // expected-note {{candidate function not viable: cannot 
convert argument of incomplete type 'A' to 'A *' for 1st argument; take the 
address of the argument with &}}
+void f1(A &a) {
+  f0(a); // expected-error {{no matching function for call to 'f0'}}
+}
+
+void f2(A &a); // expected-note {{candidate function not viable: cannot 
convert argument of incomplete type 'A *' to 'A &' for 1st argument; 
dereference the argument with *}}
+void f3(A *a) {
+  f2(a); // expected-error {{no matching function for call to 'f2'}}
+}
+
+
Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -9104,10 +9104,13 @@
   if (const PointerType *PTy = TempFromTy->getAs())
 TempFromTy = PTy->getPointeeType();
   if (TempFromTy->isIncompleteType()) {
+// Emit the generic diagnostic and, optionally, add the hints to it.
 S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
   << (unsigned) FnKind << FnDesc
   << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
-  << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+  << FromTy << ToTy << (unsigned) isObjectArgument << I+1
+  << (unsigned) (Cand->Fix.Kind);
+  
 MaybeEmitInheritedConstructorNote(S, Fn);
 return;
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3189,7 +3189,12 @@
 "function (the implicit move assignment operator)|"
 "constructor (inherited)}0%1 "
 "not viable: cannot convert argument of incomplete type "
-"%diff{$ to $|to parameter type}2,3">;
+"%diff{$ to $|to parameter type}2,3 for "
+"%select{%ordinal5 argument|object argument}4"
+"%select{|; dereference the argument with *|"
+"; take the address of the argument with &|"
+"; remove *|"
+"; remove &}6">;
 def note_ovl_candidate_bad_list_argument : Note<"candidate "
 "%select{function|function|constructor|"
 "function |function |constructor |"


Index: test/Parser/overloaded-pointer-vs-reference-hint.cpp
===
--- /dev/null
+++ test/Parser/overloaded-pointer-vs-reference-hint.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+class A;
+
+void f0(A *a); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'A' to 'A *' for 1st argument; take the address of the argument with &}}
+void f1(A &a) {
+  f0(a); // expected-error {{no matching function for call to 'f0'}}
+}
+
+void f2(A &a); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'A *' to 'A &' for 1st argument; dereference the argument with *}}
+void f3(A *a) {
+  f2(a); // expected-error {{no matching function for call to 'f2'}}
+}
+
+
Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -9104,10 +9104,13 @@
   if (const PointerType *PTy = TempFromTy->getAs())
 TempFromTy = PTy->getPointeeType();
   if (TempFromTy->isIncompleteType()) {
+// Emit the generic diagnostic and, optionally, add the hints to it.
 S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
   << (unsigned) FnKind << FnDesc
   << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
-  << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+  << FromTy << ToTy << (unsigned) isObjectArgument << I+1
+  << (unsigned) (Cand->Fix.Kind);
+  
 MaybeEmitInheritedConstructorNote(S, Fn);
 return;
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3189,7 +3189,12 @@
 "function (the implicit move assignment operator)|"
 "constructor (inherited)}0%1 "
 "not viable: cannot convert argument of incomplete type "
-"%diff{$ to $|to parameter type}2,3">;
+"%diff{$ to $|to parameter type}2,3 for "
+"%select{%ordinal5 argument|object argument}4"
+"%select{|; dereference the argument with *|"
+

Re: [PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-02-13 Thread Ryan Yee via cfe-commits
ryee88 updated this revision to Diff 47926.
ryee88 added a comment.

Messed up the diff. Uploading it again.


http://reviews.llvm.org/D16965

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/Parser/forward-declaration.cpp

Index: test/Parser/forward-declaration.cpp
===
--- /dev/null
+++ test/Parser/forward-declaration.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+class Outer {class Inner;};
+
+class ::Outer; // expected-error {{forward declaration of qualified class not 
allowed}} expected-warning {{extra qualification on member 'Outer'}}
+
+class Outer;
+
+// specializations of qualified type introduction?
+class Outer::Inner; // expected-error {{forward declaration of class cannot 
have a nested name specifier}}
+class ::Outer::Inner; // expected-error {{forward declaration of class cannot 
have a nested name specifier}}
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -3789,6 +3789,17 @@
   if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() &&
   !IsExplicitInstantiation && !IsExplicitSpecialization &&
   !isa(Tag)) {
+
+// Per C++ standard [n3485] 3.4.4 Elaborated type specifiers, section 3:
+// "Cannot introduce an qualified".
+// A clang::NestedNameSpecifier can represent many kinds of specifiers.
+// A global-specifier with no nested-name-specifier requires a different
+// diagnostic from a nested-name specifier.
+unsigned diagId = ( SS.getScopeRep()->getKind() == 
NestedNameSpecifier::Global &&
+  !SS.getScopeRep()->getPrefix() )
+  ? diag::err_standalone_class_specifier
+  : diagId = diag::err_standalone_class_nested_name_specifier;
+
 // Per C++ [dcl.type.elab]p1, a class declaration cannot have a
 // nested-name-specifier unless it is an explicit instantiation
 // or an explicit specialization.
@@ -3797,8 +3808,9 @@
 // obvious intent of DR1819.
 //
 // Per C++ [dcl.enum]p1, an opaque-enum-declaration can't either.
-Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier)
-<< GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange();
+Diag(SS.getBeginLoc(), diagId)
+  << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange();
+
 return nullptr;
   }

Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5236,6 +5236,9 @@
 def err_standalone_class_nested_name_specifier : Error<
   "forward declaration of %select{class|struct|interface|union|enum}0 cannot "
   "have a nested name specifier">;
+def err_standalone_class_specifier : Error<
+  "forward declaration of qualified 
%select{class|struct|interface|union|enum}0 "
+   "not allowed">;
 def err_typecheck_sclass_func : Error<"illegal storage class on function">;
 def err_static_block_func : Error<
   "function declared in block scope cannot have 'static' storage class">;


Index: test/Parser/forward-declaration.cpp
===
--- /dev/null
+++ test/Parser/forward-declaration.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+class Outer {class Inner;};
+
+class ::Outer; // expected-error {{forward declaration of qualified class not allowed}} expected-warning {{extra qualification on member 'Outer'}}
+
+class Outer;
+
+// specializations of qualified type introduction?
+class Outer::Inner; // expected-error {{forward declaration of class cannot have a nested name specifier}}
+class ::Outer::Inner; // expected-error {{forward declaration of class cannot have a nested name specifier}}
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -3789,6 +3789,17 @@
   if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() &&
   !IsExplicitInstantiation && !IsExplicitSpecialization &&
   !isa(Tag)) {
+
+// Per C++ standard [n3485] 3.4.4 Elaborated type specifiers, section 3:
+// "Cannot introduce an qualified".
+// A clang::NestedNameSpecifier can represent many kinds of specifiers.
+// A global-specifier with no nested-name-specifier requires a different
+// diagnostic from a nested-name specifier.
+unsigned diagId = ( SS.getScopeRep()->getKind() == NestedNameSpecifier::Global &&
+  !SS.getScopeRep()->getPrefix() )
+  ? diag::err_standalone_class_specifier
+  : diagId = diag::err_standalone_class_nested_name_specifier;
+
 // Per C++ [dcl.type.elab]p1, a class declaration cannot have a
 // nested-name-specifier unless it is an explicit instantiation
 // or an explicit specialization.
@@ -3797,8 +3808,

Re: [PATCH] D16949: Fix for: Bug 5941 - improve diagnostic for * vs & confusion

2016-02-16 Thread Ryan Yee via cfe-commits
ryee88 updated this revision to Diff 48149.
ryee88 added a comment.

Keeping the number of test files to a minimum makes sense.

Couldn't find an existing test for this diagnostic. I did find a 
cxx-reference.cpp that tests reference diagnostics so this seems like a 
reasonable location for this new test.


http://reviews.llvm.org/D16949

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaOverload.cpp
  test/Parser/cxx-reference.cpp

Index: test/Parser/cxx-reference.cpp
===
--- test/Parser/cxx-reference.cpp
+++ test/Parser/cxx-reference.cpp
@@ -24,3 +24,29 @@
 #if __cplusplus <= 199711L
 // expected-warning@-2 {{rvalue references are a C++11 extension}}
 #endif
+
+namespace PointerVsReferenceSuggestion{
+  class A;
+  
+  void f0(A *a); // expected-note {{candidate function not viable: cannot 
convert argument of incomplete type 'PointerVsReferenceSuggestion::A' to 
'PointerVsReferenceSuggestion::A *' for 1st argument; take the address of the 
argument with &}}
+  void f1(A &a) {
+f0(a); // expected-error {{no matching function for call to 'f0'}}
+  }
+  
+  void f2(A &a); // expected-note {{candidate function not viable: cannot 
convert argument of incomplete type 'PointerVsReferenceSuggestion::A *' to 
'PointerVsReferenceSuggestion::A &' for 1st argument; dereference the argument 
with *}}
+  void f3(A *a) {
+f2(a); // expected-error {{no matching function for call to 'f2'}}
+  }
+   
+  class B {};
+  
+  void f4(B *b); // expected-note {{candidate function not viable: no known 
conversion from 'PointerVsReferenceSuggestion::B' to 
'PointerVsReferenceSuggestion::B *' for 1st argument; take the address of the 
argument with &}}
+  void f5(B &b) {
+f4(b); // expected-error {{no matching function for call to 'f4'}}
+  }
+  
+  void f6(B &b); // expected-note {{candidate function not viable: no known 
conversion from 'PointerVsReferenceSuggestion::B *' to 
'PointerVsReferenceSuggestion::B &' for 1st argument; dereference the argument 
with *}}
+  void f7(B *b) {
+f6(b); // expected-error {{no matching function for call to 'f6'}}
+  }
+}
Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -9104,10 +9104,13 @@
   if (const PointerType *PTy = TempFromTy->getAs())
 TempFromTy = PTy->getPointeeType();
   if (TempFromTy->isIncompleteType()) {
+// Emit the generic diagnostic and, optionally, add the hints to it.
 S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
   << (unsigned) FnKind << FnDesc
   << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
-  << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+  << FromTy << ToTy << (unsigned) isObjectArgument << I+1
+  << (unsigned) (Cand->Fix.Kind);
+  
 MaybeEmitInheritedConstructorNote(S, Fn);
 return;
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3189,7 +3189,12 @@
 "function (the implicit move assignment operator)|"
 "constructor (inherited)}0%1 "
 "not viable: cannot convert argument of incomplete type "
-"%diff{$ to $|to parameter type}2,3">;
+"%diff{$ to $|to parameter type}2,3 for "
+"%select{%ordinal5 argument|object argument}4"
+"%select{|; dereference the argument with *|"
+"; take the address of the argument with &|"
+"; remove *|"
+"; remove &}6">;
 def note_ovl_candidate_bad_list_argument : Note<"candidate "
 "%select{function|function|constructor|"
 "function |function |constructor |"


Index: test/Parser/cxx-reference.cpp
===
--- test/Parser/cxx-reference.cpp
+++ test/Parser/cxx-reference.cpp
@@ -24,3 +24,29 @@
 #if __cplusplus <= 199711L
 // expected-warning@-2 {{rvalue references are a C++11 extension}}
 #endif
+
+namespace PointerVsReferenceSuggestion{
+  class A;
+  
+  void f0(A *a); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'PointerVsReferenceSuggestion::A' to 'PointerVsReferenceSuggestion::A *' for 1st argument; take the address of the argument with &}}
+  void f1(A &a) {
+f0(a); // expected-error {{no matching function for call to 'f0'}}
+  }
+  
+  void f2(A &a); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'PointerVsReferenceSuggestion::A *' to 'PointerVsReferenceSuggestion::A &' for 1st argument; dereference the argument with *}}
+  void f3(A *a) {
+f2(a); // expected-error {{no matching function for call to 'f2'}}
+  }
+	
+  class B {};
+  
+  void f4(B *b); // expected-note {{candidate function not viable: no known conversion from 'PointerVsReferenceSuggestion::B' to '

Re: [PATCH] D16949: Fix for: Bug 5941 - improve diagnostic for * vs & confusion

2016-02-25 Thread Ryan Yee via cfe-commits
ryee88 added a comment.

any comments?


http://reviews.llvm.org/D16949



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-04-29 Thread Ryan Yee via cfe-commits
ryee88 updated this revision to Diff 55707.
ryee88 added a comment.

Removed unnecessary code changes. This patch contains a unit test to detect a 
regression of this global name specifier issue.


http://reviews.llvm.org/D16965

Files:
  test/Parser/cxx-class.cpp

Index: test/Parser/cxx-class.cpp
===
--- test/Parser/cxx-class.cpp
+++ test/Parser/cxx-class.cpp
@@ -120,17 +120,36 @@
 // expected-error{{unknown type name 'UnknownType'}}
 }
 
-namespace nns_decl {
-  struct A {
-struct B;
+namespace NestedNameSpecifiers {
+  struct OuterStruct {
+struct InnerStruct;
   };
-  namespace N {
-union C;
+  namespace UnionOuterNamespace {
+union UnionInner;
   }
-  struct A::B; // expected-error {{forward declaration of struct cannot have a 
nested name specifier}}
-  union N::C; // expected-error {{forward declaration of union cannot have a 
nested name specifier}}
+   class OuterClass{
+   class InnerClass;
+   };
+
+  struct OuterStruct::InnerStruct; // expected-error {{forward declaration of 
struct cannot have a nested name specifier}}
+  struct ::NestedNameSpecifiers::OuterStruct::InnerStruct; // expected-error 
{{forward declaration of struct cannot have a nested name specifier}}
+
+  union UnionOuterNamespace::UnionInner; // expected-error {{forward 
declaration of union cannot have a nested name specifier}}
+  union ::NestedNameSpecifiers::UnionOuterNamespace::UnionInner; // 
expected-error {{forward declaration of union cannot have a nested name 
specifier}}
+
+  class OuterClass::InnerClass; // expected-error {{forward declaration of 
class cannot have a nested name specifier}}
+  class ::NestedNameSpecifiers::OuterClass::InnerClass; // expected-error 
{{forward declaration of class cannot have a nested name specifier}}
 }
 
+// Testing the global "nested" name qualifier
+class GlobalSpecifierOuterClass {class InnerClass;};
+class ::GlobalSpecifierOuterClass; // expected-error {{forward declaration of 
class cannot have a nested name specifier}} expected-warning {{extra 
qualification on member 'GlobalSpecifierOuterClass'}}
+class GlobalSpecifierOuterClass;
+// specializations of qualified type introduction?
+class GlobalSpecifierOuterClass::InnerClass; // expected-error {{forward 
declaration of class cannot have a nested name specifier}}
+class ::GlobalSpecifierOuterClass::InnerClass; // expected-error {{forward 
declaration of class cannot have a nested name specifier}}
+
+
 // PR13775: Don't assert here.
 namespace PR13775 {
   class bar


Index: test/Parser/cxx-class.cpp
===
--- test/Parser/cxx-class.cpp
+++ test/Parser/cxx-class.cpp
@@ -120,17 +120,36 @@
 // expected-error{{unknown type name 'UnknownType'}}
 }
 
-namespace nns_decl {
-  struct A {
-struct B;
+namespace NestedNameSpecifiers {
+  struct OuterStruct {
+struct InnerStruct;
   };
-  namespace N {
-union C;
+  namespace UnionOuterNamespace {
+union UnionInner;
   }
-  struct A::B; // expected-error {{forward declaration of struct cannot have a nested name specifier}}
-  union N::C; // expected-error {{forward declaration of union cannot have a nested name specifier}}
+	class OuterClass{
+		class InnerClass;
+	};
+
+  struct OuterStruct::InnerStruct; // expected-error {{forward declaration of struct cannot have a nested name specifier}}
+  struct ::NestedNameSpecifiers::OuterStruct::InnerStruct; // expected-error {{forward declaration of struct cannot have a nested name specifier}}
+
+  union UnionOuterNamespace::UnionInner; // expected-error {{forward declaration of union cannot have a nested name specifier}}
+  union ::NestedNameSpecifiers::UnionOuterNamespace::UnionInner; // expected-error {{forward declaration of union cannot have a nested name specifier}}
+
+  class OuterClass::InnerClass; // expected-error {{forward declaration of class cannot have a nested name specifier}}
+  class ::NestedNameSpecifiers::OuterClass::InnerClass; // expected-error {{forward declaration of class cannot have a nested name specifier}}
 }
 
+// Testing the global "nested" name qualifier
+class GlobalSpecifierOuterClass {class InnerClass;};
+class ::GlobalSpecifierOuterClass; // expected-error {{forward declaration of class cannot have a nested name specifier}} expected-warning {{extra qualification on member 'GlobalSpecifierOuterClass'}}
+class GlobalSpecifierOuterClass;
+// specializations of qualified type introduction?
+class GlobalSpecifierOuterClass::InnerClass; // expected-error {{forward declaration of class cannot have a nested name specifier}}
+class ::GlobalSpecifierOuterClass::InnerClass; // expected-error {{forward declaration of class cannot have a nested name specifier}}
+
+
 // PR13775: Don't assert here.
 namespace PR13775 {
   class bar
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm

Re: [PATCH] D16949: Fix for: Bug 5941 - improve diagnostic for * vs & confusion

2016-02-26 Thread Ryan Yee via cfe-commits
ryee88 updated this revision to Diff 49280.
ryee88 added a comment.

Moved test to a file that checks for similar diagnostics.


http://reviews.llvm.org/D16949

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaOverload.cpp
  test/SemaCXX/overload-call.cpp

Index: test/SemaCXX/overload-call.cpp
===
--- test/SemaCXX/overload-call.cpp
+++ test/SemaCXX/overload-call.cpp
@@ -639,3 +639,29 @@
 g(y); // expected-error {{ambiguous}}
   }
 }
+
+namespace PointerVsReferenceSuggestion{
+  class A;
+  
+  void f0(A *a); // expected-note {{candidate function not viable: cannot 
convert argument of incomplete type 'PointerVsReferenceSuggestion::A' to 
'PointerVsReferenceSuggestion::A *' for 1st argument; take the address of the 
argument with &}}
+  void f1(A &a) {
+f0(a); // expected-error {{no matching function for call to 'f0'}}
+  }
+  
+  void f2(A &a); // expected-note {{candidate function not viable: cannot 
convert argument of incomplete type 'PointerVsReferenceSuggestion::A *' to 
'PointerVsReferenceSuggestion::A &' for 1st argument; dereference the argument 
with *}}
+  void f3(A *a) {
+f2(a); // expected-error {{no matching function for call to 'f2'}}
+  }
+  
+  class B {};
+  
+  void f4(B *b); // expected-note {{candidate function not viable: no known 
conversion from 'PointerVsReferenceSuggestion::B' to 
'PointerVsReferenceSuggestion::B *' for 1st argument; take the address of the 
argument with &}}
+  void f5(B &b) {
+f4(b); // expected-error {{no matching function for call to 'f4'}}
+  }
+  
+  void f6(B &b); // expected-note {{candidate function not viable: no known 
conversion from 'PointerVsReferenceSuggestion::B *' to 
'PointerVsReferenceSuggestion::B &' for 1st argument; dereference the argument 
with *}}
+  void f7(B *b) {
+f6(b); // expected-error {{no matching function for call to 'f6'}}
+  }
+}
Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -9104,10 +9104,13 @@
   if (const PointerType *PTy = TempFromTy->getAs())
 TempFromTy = PTy->getPointeeType();
   if (TempFromTy->isIncompleteType()) {
+// Emit the generic diagnostic and, optionally, add the hints to it.
 S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
   << (unsigned) FnKind << FnDesc
   << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
-  << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+  << FromTy << ToTy << (unsigned) isObjectArgument << I+1
+  << (unsigned) (Cand->Fix.Kind);
+  
 MaybeEmitInheritedConstructorNote(S, Fn);
 return;
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3189,7 +3189,12 @@
 "function (the implicit move assignment operator)|"
 "constructor (inherited)}0%1 "
 "not viable: cannot convert argument of incomplete type "
-"%diff{$ to $|to parameter type}2,3">;
+"%diff{$ to $|to parameter type}2,3 for "
+"%select{%ordinal5 argument|object argument}4"
+"%select{|; dereference the argument with *|"
+"; take the address of the argument with &|"
+"; remove *|"
+"; remove &}6">;
 def note_ovl_candidate_bad_list_argument : Note<"candidate "
 "%select{function|function|constructor|"
 "function |function |constructor |"


Index: test/SemaCXX/overload-call.cpp
===
--- test/SemaCXX/overload-call.cpp
+++ test/SemaCXX/overload-call.cpp
@@ -639,3 +639,29 @@
 g(y); // expected-error {{ambiguous}}
   }
 }
+
+namespace PointerVsReferenceSuggestion{
+  class A;
+  
+  void f0(A *a); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'PointerVsReferenceSuggestion::A' to 'PointerVsReferenceSuggestion::A *' for 1st argument; take the address of the argument with &}}
+  void f1(A &a) {
+f0(a); // expected-error {{no matching function for call to 'f0'}}
+  }
+  
+  void f2(A &a); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'PointerVsReferenceSuggestion::A *' to 'PointerVsReferenceSuggestion::A &' for 1st argument; dereference the argument with *}}
+  void f3(A *a) {
+f2(a); // expected-error {{no matching function for call to 'f2'}}
+  }
+  
+  class B {};
+  
+  void f4(B *b); // expected-note {{candidate function not viable: no known conversion from 'PointerVsReferenceSuggestion::B' to 'PointerVsReferenceSuggestion::B *' for 1st argument; take the address of the argument with &}}
+  void f5(B &b) {
+f4(b); // expected-error {{no matching function for call to 'f4'}}
+  }
+  
+  void f6(B &b); // expected-note {{candidate function not viable: no known convers

Re: [PATCH] D16949: Fix for: Bug 5941 - improve diagnostic for * vs & confusion

2016-03-01 Thread Ryan Yee via cfe-commits
ryee88 added a comment.

Yeah you’re right about this one being the original variant. I missed it when I 
was reading through the tests in this file.

I’ve reworked it to reflect the new variants.


http://reviews.llvm.org/D16949



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16949: Fix for: Bug 5941 - improve diagnostic for * vs & confusion

2016-03-01 Thread Ryan Yee via cfe-commits
ryee88 updated this revision to Diff 49577.

http://reviews.llvm.org/D16949

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaOverload.cpp
  test/SemaCXX/overload-call.cpp

Index: test/SemaCXX/overload-call.cpp
===
--- test/SemaCXX/overload-call.cpp
+++ test/SemaCXX/overload-call.cpp
@@ -375,16 +375,24 @@
 }
 
 // PR 6117
-namespace test3 {
-  struct Base {};
+namespace IncompleteConversion {
+  struct Complete {};
   struct Incomplete;
 
-  void foo(Base *); // expected-note 2 {{cannot convert argument of incomplete 
type}}
-  void foo(Base &); // expected-note 2 {{cannot convert argument of incomplete 
type}}
-
-  void test(Incomplete *P) {
-foo(P); // expected-error {{no matching function for call to 'foo'}}
-foo(*P); // expected-error {{no matching function for call to 'foo'}}
+  void completeFunction(Complete *); // expected-note 2 {{cannot convert 
argument of incomplete type}}
+  void completeFunction(Complete &); // expected-note 2 {{cannot convert 
argument of incomplete type}}
+  
+  void testTypeConversion(Incomplete *P) {
+completeFunction(P); // expected-error {{no matching function for call to 
'completeFunction'}}
+completeFunction(*P); // expected-error {{no matching function for call to 
'completeFunction'}}
+  }
+  
+  void incompletePointerFunction(Incomplete *); // expected-note {{candidate 
function not viable: cannot convert argument of incomplete type 
'IncompleteConversion::Incomplete' to 'IncompleteConversion::Incomplete *' for 
1st argument; take the address of the argument with &}}
+  void incompleteReferenceFunction(Incomplete &); // expected-note {{candidate 
function not viable: cannot convert argument of incomplete type 
'IncompleteConversion::Incomplete *' to 'IncompleteConversion::Incomplete &' 
for 1st argument; dereference the argument with *}}
+  
+  void testPointerReferenceConversion(Incomplete &reference, Incomplete 
*pointer) {
+incompletePointerFunction(reference); // expected-error {{no matching 
function for call to 'incompletePointerFunction'}}
+incompleteReferenceFunction(pointer); // expected-error {{no matching 
function for call to 'incompleteReferenceFunction'}}
   }
 }
 
Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -9104,10 +9104,13 @@
   if (const PointerType *PTy = TempFromTy->getAs())
 TempFromTy = PTy->getPointeeType();
   if (TempFromTy->isIncompleteType()) {
+// Emit the generic diagnostic and, optionally, add the hints to it.
 S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
   << (unsigned) FnKind << FnDesc
   << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
-  << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+  << FromTy << ToTy << (unsigned) isObjectArgument << I+1
+  << (unsigned) (Cand->Fix.Kind);
+  
 MaybeEmitInheritedConstructorNote(S, Fn);
 return;
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3189,7 +3189,12 @@
 "function (the implicit move assignment operator)|"
 "constructor (inherited)}0%1 "
 "not viable: cannot convert argument of incomplete type "
-"%diff{$ to $|to parameter type}2,3">;
+"%diff{$ to $|to parameter type}2,3 for "
+"%select{%ordinal5 argument|object argument}4"
+"%select{|; dereference the argument with *|"
+"; take the address of the argument with &|"
+"; remove *|"
+"; remove &}6">;
 def note_ovl_candidate_bad_list_argument : Note<"candidate "
 "%select{function|function|constructor|"
 "function |function |constructor |"


Index: test/SemaCXX/overload-call.cpp
===
--- test/SemaCXX/overload-call.cpp
+++ test/SemaCXX/overload-call.cpp
@@ -375,16 +375,24 @@
 }
 
 // PR 6117
-namespace test3 {
-  struct Base {};
+namespace IncompleteConversion {
+  struct Complete {};
   struct Incomplete;
 
-  void foo(Base *); // expected-note 2 {{cannot convert argument of incomplete type}}
-  void foo(Base &); // expected-note 2 {{cannot convert argument of incomplete type}}
-
-  void test(Incomplete *P) {
-foo(P); // expected-error {{no matching function for call to 'foo'}}
-foo(*P); // expected-error {{no matching function for call to 'foo'}}
+  void completeFunction(Complete *); // expected-note 2 {{cannot convert argument of incomplete type}}
+  void completeFunction(Complete &); // expected-note 2 {{cannot convert argument of incomplete type}}
+  
+  void testTypeConversion(Incomplete *P) {
+completeFunction(P); // expected-error {{no matching function for call to 'completeFunction'}}
+completeFunction(*P); // expected-error {{no

Re: [PATCH] D16949: Fix for: Bug 5941 - improve diagnostic for * vs & confusion

2016-03-03 Thread Ryan Yee via cfe-commits
ryee88 added a comment.

Thanks! I don’t have commit permissions; can you submit for me?


http://reviews.llvm.org/D16949



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-03-04 Thread Ryan Yee via cfe-commits
ryee88 updated this revision to Diff 49866.

http://reviews.llvm.org/D16965

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/Parser/cxx-class.cpp

Index: test/Parser/cxx-class.cpp
===
--- test/Parser/cxx-class.cpp
+++ test/Parser/cxx-class.cpp
@@ -98,17 +98,36 @@
 // expected-error{{unknown type name 'UnknownType'}}
 }
 
-namespace nns_decl {
-  struct A {
-struct B;
+namespace NestedNameSpecifiers {
+  struct OuterStruct {
+struct InnerStruct;
   };
-  namespace N {
-union C;
+  namespace UnionOuterNamespace {
+union UnionInner;
   }
-  struct A::B; // expected-error {{forward declaration of struct cannot have a 
nested name specifier}}
-  union N::C; // expected-error {{forward declaration of union cannot have a 
nested name specifier}}
+   class OuterClass{
+   class InnerClass;
+   };
+
+  struct OuterStruct::InnerStruct; // expected-error {{forward declaration of 
struct cannot have a nested name specifier}}
+  struct ::NestedNameSpecifiers::OuterStruct::InnerStruct; // expected-error 
{{forward declaration of struct cannot have a nested name specifier}}
+
+  union UnionOuterNamespace::UnionInner; // expected-error {{forward 
declaration of union cannot have a nested name specifier}}
+  union ::NestedNameSpecifiers::UnionOuterNamespace::UnionInner; // 
expected-error {{forward declaration of union cannot have a nested name 
specifier}}
+
+  class OuterClass::InnerClass; // expected-error {{forward declaration of 
class cannot have a nested name specifier}}
+  class ::NestedNameSpecifiers::OuterClass::InnerClass; // expected-error 
{{forward declaration of class cannot have a nested name specifier}}
 }
 
+// Testing the global "nested" name qualifier
+class GlobalSpecifierOuterClass {class InnerClass;};
+class ::GlobalSpecifierOuterClass; // expected-error {{forward declaration of 
qualified class not allowed}} expected-warning {{extra qualification on member 
'GlobalSpecifierOuterClass'}}
+class GlobalSpecifierOuterClass;
+// specializations of qualified type introduction?
+class GlobalSpecifierOuterClass::InnerClass; // expected-error {{forward 
declaration of class cannot have a nested name specifier}}
+class ::GlobalSpecifierOuterClass::InnerClass; // expected-error {{forward 
declaration of class cannot have a nested name specifier}}
+
+
 // PR13775: Don't assert here.
 namespace PR13775 {
   class bar
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -3799,6 +3799,17 @@
   if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() &&
   !IsExplicitInstantiation && !IsExplicitSpecialization &&
   !isa(Tag)) {
+
+// Per C++ standard [n3485] 3.4.4 Elaborated type specifiers, section 3:
+// "Cannot introduce an qualified".
+// A clang::NestedNameSpecifier can represent many kinds of specifiers.
+// A global-specifier with no nested-name-specifier requires a different
+// diagnostic from a nested-name specifier.
+unsigned diagId = ( SS.getScopeRep()->getKind() == 
NestedNameSpecifier::Global &&
+  !SS.getScopeRep()->getPrefix() )
+  ? diag::err_standalone_class_specifier
+  : diagId = diag::err_standalone_class_nested_name_specifier;
+
 // Per C++ [dcl.type.elab]p1, a class declaration cannot have a
 // nested-name-specifier unless it is an explicit instantiation
 // or an explicit specialization.
@@ -3807,8 +3818,9 @@
 // obvious intent of DR1819.
 //
 // Per C++ [dcl.enum]p1, an opaque-enum-declaration can't either.
-Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier)
-<< GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange();
+Diag(SS.getBeginLoc(), diagId)
+  << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange();
+
 return nullptr;
   }
 
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5266,6 +5266,9 @@
 def err_standalone_class_nested_name_specifier : Error<
   "forward declaration of %select{class|struct|interface|union|enum}0 cannot "
   "have a nested name specifier">;
+def err_standalone_class_specifier : Error<
+  "forward declaration of qualified 
%select{class|struct|interface|union|enum}0 "
+   "not allowed">;
 def err_typecheck_sclass_func : Error<"illegal storage class on function">;
 def err_static_block_func : Error<
   "function declared in block scope cannot have 'static' storage class">;


Index: test/Parser/cxx-class.cpp
===
--- test/Parser/cxx-class.cpp
+++ test/Parser/cxx-class.cpp
@@ -98,17 +98,36 @@
 // expected-error{{unknown type name 'UnknownType'}}
 }
 
-na

Re: [PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-03-04 Thread Ryan Yee via cfe-commits
ryee88 added a subscriber: dblaikie.
ryee88 added a comment.

Anyone care to take a look?


http://reviews.llvm.org/D16965



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-03-15 Thread Ryan Yee via cfe-commits
ryee88 added a comment.

Anyone want to pick up this review?


http://reviews.llvm.org/D16965



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-03-19 Thread Ryan Yee via cfe-commits
ryee88 added inline comments.


Comment at: lib/Sema/SemaDecl.cpp:3803
@@ +3802,3 @@
+
+// Per C++ standard [n3485] 3.4.4 Elaborated type specifiers, section 3:
+// "Cannot introduce an qualified".

aaron.ballman wrote:
> Can drop the N-paper reference, and replace "3.4.4, section 3" with 
> [basic.lookup.elab]p3
I'm going to re-organize these comments and move the conditional because really 
all these comments apply too.


Comment at: lib/Sema/SemaDecl.cpp:3805
@@ +3804,3 @@
+// "Cannot introduce an qualified".
+// A clang::NestedNameSpecifier can represent many kinds of specifiers.
+// A global-specifier with no nested-name-specifier requires a different

aaron.ballman wrote:
> Can drop the clang::
ok


Comment at: lib/Sema/SemaDecl.cpp:3811
@@ +3810,3 @@
+  ? diag::err_standalone_class_specifier
+  : diagId = diag::err_standalone_class_nested_name_specifier;
+

aaron.ballman wrote:
> Should remove the diagId = from the else clause.
whoops. will do.


http://reviews.llvm.org/D16965



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-03-20 Thread Ryan Yee via cfe-commits
ryee88 added a comment.

In http://reviews.llvm.org/D16965#377864, @dblaikie wrote:

> Not sure I fully understand the issue with the existing diagnostic/change in 
> wording.
>
> '::' is a nested name specifier, even if it's a degenerate case, I think - so 
> the old wording doesn't seem wrong, as such (& the new text seems correct in 
> the other cases too - should we just switch to that in general rather than 
> having two cases?)


Yes that's the basically the issue raised in the bug report. The error wording 
for the degenerate nested name specifier is unclear. I'll tinker around with a 
generic wording.


http://reviews.llvm.org/D16965



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member

2016-03-21 Thread Ryan Yee via cfe-commits
ryee88 added a comment.

Yeah I don't think it's worth it to modify the general case wording to to 
explicitly call out the degenerate global nested-name-specifier. It'll cause 
more confusion for the general case.

At this point, do we just close the bug and keep the new unit tests?


http://reviews.llvm.org/D16965



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits