[PATCH] D16965: Fix for Bug 14644 - clang confuses scope operator for global namespace giving extra qualification on member
Ryan Yee via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 4 17:56:23 PST 2016
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<ClassTemplatePartialSpecializationDecl>(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">;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D16965.49866.patch
Type: text/x-patch
Size: 4562 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160305/fc427d50/attachment.bin>
More information about the cfe-commits
mailing list