]> granicus.if.org Git - clang/commitdiff
__decltype is a GNU extension, not a C++11 extension.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 24 Feb 2012 18:10:23 +0000 (18:10 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 24 Feb 2012 18:10:23 +0000 (18:10 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151377 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Parse/ParseDeclCXX.cpp
lib/Sema/DeclSpec.cpp
test/SemaCXX/cxx98-compat.cpp
test/SemaCXX/decltype-98.cpp

index 3fd7e90083a385f6b0a62332db34f6cb0f1df61f..b3f2067ff68c98aba318ef08c1425bc318d689b3 100644 (file)
@@ -254,6 +254,12 @@ def err_missing_comma_before_ellipsis : Error<
   "C requires a comma prior to the ellipsis in a variadic function type">;
 def err_unexpected_typedef_ident : Error<
   "unexpected type name %0: expected identifier">;
+def ext_gnu_decltype : Extension<
+  "'__decltype' type specifier is a GNU extension">,
+  InGroup<GNU>, DefaultIgnore;
+def warn_cxx98_compat_decltype : Warning<
+  "'decltype' type specifier is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_unexpected_scope_on_base_decltype : Error<
   "unexpected namespace scope prior to decltype">;
 def err_expected_class_name : Error<"expected class name">;
index bfece366f14ff853f4164cb29661351d959ed11f..b961e0961a3b3d9475460d25a0cc87131b025e82 100644 (file)
@@ -1176,9 +1176,6 @@ def warn_cxx98_compat_temp_copy : Warning<
   InGroup<CXX98CompatBindToTemporaryCopy>, DefaultIgnore;
 
 // C++11 decltype
-def warn_cxx98_compat_decltype : Warning<
-  "'decltype' type specifier is incompatible with C++98">,
-  InGroup<CXX98Compat>, DefaultIgnore;
 def err_decltype_in_declarator : Error<
     "'decltype' cannot be used to name a declaration">;
     
index c2bf54db2cdfec31c9b2a194032c81621aa9279d..5468700bc92544209a363a92abde1410b70a1def 100644 (file)
@@ -653,6 +653,9 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
       return EndLoc;
     }
   } else {
+    Diag(Tok, Tok.getIdentifierInfo()->isStr("decltype")
+           ? diag::warn_cxx98_compat_decltype : diag::ext_gnu_decltype);
+
     ConsumeToken();
 
     BalancedDelimiterTracker T(*this, tok::l_paren);
index 11818f6fa24894440ec7cad5e86ff6a13afc61bd..72a51bc474c087111005c382690455a0f77592fe 100644 (file)
@@ -898,8 +898,6 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
   if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
     Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type)
       << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
-  if (TypeSpecType == TST_decltype)
-    Diag(D, TSTLoc, diag::warn_cxx98_compat_decltype);
   if (Constexpr_specified)
     Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr);
 
index b7abe266f2de9eb72f4ead6fb09e562a72a93fe2..879c72211d18761ec7abcc869da5169a1543c920 100644 (file)
@@ -99,6 +99,7 @@ char16_t c16 = 0; // expected-warning {{'char16_t' type specifier is incompatibl
 char32_t c32 = 0; // expected-warning {{'char32_t' type specifier is incompatible with C++98}}
 constexpr int const_expr = 0; // expected-warning {{'constexpr' specifier is incompatible with C++98}}
 decltype(const_expr) decl_type = 0; // expected-warning {{'decltype' type specifier is incompatible with C++98}}
+__decltype(const_expr) decl_type2 = 0; // ok
 void no_except() noexcept; // expected-warning {{noexcept specifications are incompatible with C++98}}
 bool no_except_expr = noexcept(1 + 1); // expected-warning {{noexcept expressions are incompatible with C++98}}
 void *null = nullptr; // expected-warning {{'nullptr' is incompatible with C++98}}
index db52565e6c74628ffefd94428bbfcb09fe246143..44d5896c53eaf98fc8fc4fd0b40f4379b4ecb351 100644 (file)
@@ -1,3 +1,3 @@
-// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s -Wgnu
 extern int x;
-__decltype(1) x = 3;
+__decltype(1) x = 3; // expected-warning {{is a GNU extension}}