[cfe-commits] r142056 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseStmt.cpp lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp test/SemaCXX/cxx98-compat-pedantic.cpp test/SemaCXX/cxx98-compat.cpp

Richard Smith richard-llvm at metafoo.co.uk
Fri Oct 14 22:09:34 PDT 2011


Author: rsmith
Date: Sat Oct 15 00:09:34 2011
New Revision: 142056

URL: http://llvm.org/viewvc/llvm-project?rev=142056&view=rev
Log:
Implement -Wc++98-compat warnings for the parser.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp
    cfe/trunk/test/SemaCXX/cxx98-compat.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sat Oct 15 00:09:34 2011
@@ -23,6 +23,9 @@
 def ext_empty_source_file : Extension<"ISO C forbids an empty source file">;
 def ext_top_level_semi : Extension<
   "extra ';' outside of a function">;
+def warn_cxx98_compat_top_level_semi : Warning<
+  "extra ';' outside of a function is incompatible with C++98">,
+  InGroup<CXX98CompatPedantic>, DefaultIgnore;
 def ext_extra_struct_semi : Extension<
   "extra ';' inside a %0">;
 def ext_extra_ivar_semi : Extension<
@@ -55,6 +58,9 @@
 def ext_enumerator_list_comma : Extension<
   "commas at the end of enumerator lists are a %select{C99|C++11}0-specific "
   "feature">;
+def warn_cxx98_compat_enumerator_list_comma : Warning<
+  "commas at the end of enumerator lists are incompatible with C++98">,
+  InGroup<CXX98CompatPedantic>, DefaultIgnore;
 def err_enumerator_list_missing_comma : Error<
   "missing ',' between enumerators">;
 def err_enumerator_unnamed_no_def : Error<
@@ -62,6 +68,9 @@
 def ext_ms_enum_fixed_underlying_type : Extension<
   "enumeration types with a fixed underlying type are a Microsoft extension">, 
   InGroup<Microsoft>;
+def warn_cxx98_compat_enum_fixed_underlying_type : Warning<
+  "enumeration types with a fixed underlying type are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 
 def ext_c1x_generic_selection : Extension<
   "generic selections are a C1X-specific feature">, InGroup<C1X>;
@@ -188,15 +197,30 @@
   "%0 declared as a reference to a reference">;
 def ext_rvalue_reference : ExtWarn<
   "rvalue references are a C++11 extension">, InGroup<CXX11>;
+def warn_cxx98_compat_rvalue_reference : Warning<
+  "rvalue references are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def ext_ref_qualifier : ExtWarn<
   "reference qualifiers on functions are a C++11 extension">, InGroup<CXX11>;
+def warn_cxx98_compat_ref_qualifier : Warning<
+  "reference qualifiers on functions are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def ext_inline_namespace : ExtWarn<
   "inline namespaces are a C++11 feature">, InGroup<CXX11>;
+def warn_cxx98_compat_inline_namespace : Warning<
+  "inline namespaces are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_generalized_initializer_lists : Error<
   "generalized initializer lists are a C++11 extension unsupported in Clang">;
 def ext_generalized_initializer_lists : ExtWarn<
   "generalized initializer lists are a C++11 extension unsupported in Clang">,
   InGroup<CXX11>;
+def warn_cxx98_compat_generalized_initializer_lists : Warning<
+  "generalized initializer lists are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
+def warn_cxx98_compat_trailing_return_type : Warning<
+  "trailing return types are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def ext_auto_type_specifier : ExtWarn<
   "'auto' type specifier is a C++11 extension">, InGroup<CXX11>;
 def warn_auto_storage_class : Warning<
@@ -207,6 +231,9 @@
   "be supported in future releases">;
 def ext_for_range : ExtWarn<
   "range-based for loop is a C++11 extension">, InGroup<CXX11>;
+def warn_cxx98_compat_for_range : Warning<
+  "range-based for loop is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_argument_required_after_attribute : Error<
   "argument required after attribute">;
 def err_missing_param : Error<"expected parameter declarator">;
@@ -363,6 +390,9 @@
 // C++ operator overloading
 def err_operator_string_not_empty : Error<
   "string literal after 'operator' must be '\"\"'">;
+def warn_cxx98_compat_literal_operator : Warning<
+  "literal operators are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 
 // Classes.
 def err_anon_type_definition : Error<
@@ -405,6 +435,9 @@
 def warn_cxx0x_right_shift_in_template_arg : Warning<
   "use of right-shift operator ('>>') in template argument will require "
   "parentheses in C++11">;
+def warn_cxx98_compat_two_right_angle_brackets : Warning<
+  "consecutive right angle brackets are incompatible with C++98 (use '> >')">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_multiple_template_declarators : Error<
     "%select{|a template declaration|an explicit template specialization|"
     "an explicit template instantiation}0 can "
@@ -466,14 +499,23 @@
 
 def warn_deleted_function_accepted_as_extension: ExtWarn<
   "deleted function definition accepted as a C++11 extension">, InGroup<CXX11>;
+def warn_cxx98_compat_deleted_function : Warning<
+  "deleted function definitions are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def warn_defaulted_function_accepted_as_extension: ExtWarn<
   "defaulted function definition accepted as a C++11 extension">,
   InGroup<CXX11>;
+def warn_cxx98_compat_defaulted_function : Warning<
+  "defaulted function definitions are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 
 // C++11 in-class member initialization
 def ext_nonstatic_member_init : ExtWarn<
   "in-class initialization of non-static data member accepted as a C++11 extension">,
   InGroup<CXX11>;
+def warn_cxx98_compat_nonstatic_member_init : Warning<
+  "in-class initialization of non-static data members is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_bitfield_member_init: Error<
   "bitfield member cannot have an in-class initializer">;
 def err_incomplete_array_member_init: Error<
@@ -482,6 +524,9 @@
 // C++11 alias-declaration
 def ext_alias_declaration : ExtWarn<
   "alias declarations accepted as a C++11 extension">, InGroup<CXX11>;
+def warn_cxx98_compat_alias_declaration : Warning<
+  "alias declarations are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_alias_declaration_not_identifier : Error<
   "name defined in alias declaration must be an identifier">;
 def err_alias_declaration_specialization : Error<
@@ -490,6 +535,9 @@
 // C++11 override control
 def ext_override_control_keyword : ExtWarn<
   "'%0' keyword accepted as a C++11 extension">, InGroup<CXX11>;
+def warn_cxx98_compat_override_control_keyword : Warning<
+  "'%0' keyword is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 
 def err_duplicate_virt_specifier : Error<
   "class member already marked '%0'">;
@@ -498,6 +546,9 @@
 
 def err_scoped_enum_missing_identifier : Error<
   "scoped enumeration requires a name">;
+def warn_cxx98_compat_scoped_enum : Warning<
+  "scoped enumerations are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 
 def err_expected_parameter_pack : Error<
   "expected the name of a parameter pack">;
@@ -514,6 +565,9 @@
 def err_expected_capture : Error<
   "expected variable name or 'this' in lambda capture list">;
 def err_expected_lambda_body : Error<"expected body of lambda expression">;
+def warn_cxx98_compat_lambda : Warning<
+  "lambda expressions are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 
 // Availability attribute
 def err_expected_version : Error<

Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Sat Oct 15 00:09:34 2011
@@ -67,15 +67,17 @@
     bool Delete = false;
     SourceLocation KWLoc;
     if (Tok.is(tok::kw_delete)) {
-      if (!getLang().CPlusPlus0x)
-        Diag(Tok, diag::warn_deleted_function_accepted_as_extension);
+      Diag(Tok, getLang().CPlusPlus0x ?
+           diag::warn_cxx98_compat_deleted_function :
+           diag::warn_deleted_function_accepted_as_extension);
 
       KWLoc = ConsumeToken();
       Actions.SetDeclDeleted(FnD, KWLoc);
       Delete = true;
     } else if (Tok.is(tok::kw_default)) {
-      if (!getLang().CPlusPlus0x)
-        Diag(Tok, diag::warn_defaulted_function_accepted_as_extension);
+      Diag(Tok, getLang().CPlusPlus0x ?
+           diag::warn_cxx98_compat_defaulted_function :
+           diag::warn_defaulted_function_accepted_as_extension);
 
       KWLoc = ConsumeToken();
       Actions.SetDeclDefaulted(FnD, KWLoc);

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Sat Oct 15 00:09:34 2011
@@ -1276,6 +1276,8 @@
     }
   } else if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
     // Parse C++0x braced-init-list.
+    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+
     if (D.getCXXScopeSpec().isSet()) {
       EnterScope(0);
       Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
@@ -2778,6 +2780,7 @@
 
   if (getLang().CPlusPlus0x &&
       (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) {
+    Diag(Tok, diag::warn_cxx98_compat_scoped_enum);
     IsScopedEnum = true;
     IsScopedUsingClassTag = Tok.is(tok::kw_class);
     ConsumeToken();
@@ -2894,6 +2897,8 @@
       if (!getLang().CPlusPlus0x && !getLang().ObjC2)
         Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type)
           << Range;
+      if (getLang().CPlusPlus0x)
+        Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
     }
   }
 
@@ -3054,11 +3059,15 @@
       break;
     SourceLocation CommaLoc = ConsumeToken();
 
-    if (Tok.isNot(tok::identifier) &&
-        !(getLang().C99 || getLang().CPlusPlus0x))
-      Diag(CommaLoc, diag::ext_enumerator_list_comma)
-        << getLang().CPlusPlus
-        << FixItHint::CreateRemoval(CommaLoc);
+    if (Tok.isNot(tok::identifier)) {
+      if (!getLang().C99 && !getLang().CPlusPlus0x)
+        Diag(CommaLoc, diag::ext_enumerator_list_comma)
+          << getLang().CPlusPlus
+          << FixItHint::CreateRemoval(CommaLoc);
+      else if (getLang().CPlusPlus0x)
+        Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
+          << FixItHint::CreateRemoval(CommaLoc);
+    }
   }
 
   // Eat the }.
@@ -3682,8 +3691,10 @@
 
     // Complain about rvalue references in C++03, but then go on and build
     // the declarator.
-    if (Kind == tok::ampamp && !getLang().CPlusPlus0x)
-      Diag(Loc, diag::ext_rvalue_reference);
+    if (Kind == tok::ampamp)
+      Diag(Loc, getLang().CPlusPlus0x ?
+           diag::warn_cxx98_compat_rvalue_reference :
+           diag::ext_rvalue_reference);
 
     // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
     // cv-qualifiers are introduced through the use of a typedef or of a
@@ -4080,8 +4091,9 @@
 
       // Parse ref-qualifier[opt].
       if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
-        if (!getLang().CPlusPlus0x)
-          Diag(Tok, diag::ext_ref_qualifier);
+        Diag(Tok, getLang().CPlusPlus0x ?
+             diag::warn_cxx98_compat_ref_qualifier :
+             diag::ext_ref_qualifier);
         
         RefQualifierIsLValueRef = Tok.is(tok::amp);
         RefQualifierLoc = ConsumeToken();
@@ -4098,6 +4110,7 @@
 
       // Parse trailing-return-type[opt].
       if (getLang().CPlusPlus0x && Tok.is(tok::arrow)) {
+        Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
         SourceRange Range;
         TrailingReturnType = ParseTrailingReturnType(Range).get();
         if (Range.getEnd().isValid())

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Sat Oct 15 00:09:34 2011
@@ -148,8 +148,9 @@
   }
 
   // If we're still good, complain about inline namespaces in non-C++0x now.
-  if (!getLang().CPlusPlus0x && InlineLoc.isValid())
-    Diag(InlineLoc, diag::ext_inline_namespace);
+  if (InlineLoc.isValid())
+    Diag(InlineLoc, getLang().CPlusPlus0x ?
+         diag::warn_cxx98_compat_inline_namespace : diag::ext_inline_namespace);
 
   // Enter a scope for the namespace.
   ParseScope NamespaceScope(this, Scope::DeclScope);
@@ -481,8 +482,9 @@
     // Where can GNU attributes appear?
     ConsumeToken();
 
-    if (!getLang().CPlusPlus0x)
-      Diag(Tok.getLocation(), diag::ext_alias_declaration);
+    Diag(Tok.getLocation(), getLang().CPlusPlus0x ?
+         diag::warn_cxx98_compat_alias_declaration :
+         diag::ext_alias_declaration);
 
     // Type alias templates cannot be specialized.
     int SpecKind = -1;
@@ -1516,9 +1518,10 @@
         << PrevSpec
         << FixItHint::CreateRemoval(Tok.getLocation());
 
-    if (!getLang().CPlusPlus0x)
-      Diag(Tok.getLocation(), diag::ext_override_control_keyword)
-        << VirtSpecifiers::getSpecifierName(Specifier);
+    Diag(Tok.getLocation(), getLang().CPlusPlus0x ?
+         diag::warn_cxx98_compat_override_control_keyword :
+         diag::ext_override_control_keyword)
+      << VirtSpecifiers::getSpecifierName(Specifier);
     ConsumeToken();
   }
 }
@@ -1884,9 +1887,10 @@
     // Handle the initializer.
     if (HasDeferredInitializer) {
       // The initializer was deferred; parse it and cache the tokens.
-      if (!getLang().CPlusPlus0x)
-        Diag(Tok, diag::ext_nonstatic_member_init);
-      
+      Diag(Tok, getLang().CPlusPlus0x ?
+           diag::warn_cxx98_compat_nonstatic_member_init :
+           diag::ext_nonstatic_member_init);
+
       if (DeclaratorInfo.isArrayOfUnknownBound()) {
         // C++0x [dcl.array]p3: An array bound may also be omitted when the
         // declarator is followed by an initializer. 
@@ -2075,8 +2079,9 @@
     assert(isCXX0XFinalKeyword() && "not a class definition");
     FinalLoc = ConsumeToken();
 
-    if (!getLang().CPlusPlus0x)
-      Diag(FinalLoc, diag::ext_override_control_keyword) << "final";
+    Diag(FinalLoc, getLang().CPlusPlus0x ?
+         diag::warn_cxx98_compat_override_control_keyword :
+         diag::ext_override_control_keyword) << "final";
   }
 
   if (Tok.is(tok::colon)) {
@@ -2318,6 +2323,8 @@
 
   // Parse the '('.
   if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+
     ExprResult InitList = ParseBraceInitializer();
     if (InitList.isInvalid())
       return true;

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Sat Oct 15 00:09:34 2011
@@ -949,6 +949,9 @@
       return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
                          << DS.getSourceRange());
 
+    if (Tok.is(tok::l_brace))
+      Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+
     Res = ParseCXXTypeConstructExpression(DS);
     break;
   }
@@ -1207,9 +1210,10 @@
       T.consumeOpen();
       Loc = T.getOpenLocation();
       ExprResult Idx;
-      if (getLang().CPlusPlus0x && Tok.is(tok::l_brace))
+      if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+        Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
         Idx = ParseBraceInitializer();
-      else
+      } else
         Idx = ParseExpression();
 
       SourceLocation RLoc = Tok.getLocation();
@@ -2157,9 +2161,10 @@
     }
 
     ExprResult Expr;
-    if (getLang().CPlusPlus0x && Tok.is(tok::l_brace))
+    if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+      Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
       Expr = ParseBraceInitializer();
-    else
+    } else
       Expr = ParseAssignmentExpression();
 
     if (Tok.is(tok::ellipsis))

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sat Oct 15 00:09:34 2011
@@ -679,6 +679,8 @@
 /// expression.
 ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
                      LambdaIntroducer &Intro) {
+  Diag(Intro.Range.getBegin(), diag::warn_cxx98_compat_lambda);
+
   // Parse lambda-declarator[opt].
   DeclSpec DS(AttrFactory);
   Declarator D(DS, Declarator::PrototypeContext);
@@ -1743,6 +1745,7 @@
   //     operator "" identifier
 
   if (getLang().CPlusPlus0x && Tok.is(tok::string_literal)) {
+    Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator);
     if (Tok.getLength() != 2)
       Diag(Tok.getLocation(), diag::err_operator_string_not_empty);
     ConsumeStringToken();
@@ -2104,6 +2107,8 @@
       return ExprError();
     }
   } else if (Tok.is(tok::l_brace) && getLang().CPlusPlus0x) {
+    Diag(Tok.getLocation(),
+         diag::warn_cxx98_compat_generalized_initializer_lists);
     // FIXME: Have to communicate the init-list to ActOnCXXNew.
     ParseBraceInitializer();
   }

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Sat Oct 15 00:09:34 2011
@@ -1326,8 +1326,8 @@
     FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
 
     if (ForRangeInit.ParsedForRangeDecl()) {
-      if (!getLang().CPlusPlus0x)
-        Diag(ForRangeInit.ColonLoc, diag::ext_for_range);
+      Diag(ForRangeInit.ColonLoc, getLang().CPlusPlus0x ?
+           diag::warn_cxx98_compat_for_range : diag::ext_for_range);
 
       ForRange = true;
     } else if (Tok.is(tok::semi)) {  // for (int x = 4;
@@ -1569,8 +1569,10 @@
     // parse libstdc++ 4.5's headers.
     if (Tok.is(tok::l_brace) && getLang().CPlusPlus) {
       R = ParseInitializer();
-      if (R.isUsable() && !getLang().CPlusPlus0x)
-        Diag(R.get()->getLocStart(), diag::ext_generalized_initializer_lists)
+      if (R.isUsable())
+        Diag(R.get()->getLocStart(), getLang().CPlusPlus0x ?
+             diag::warn_cxx98_compat_generalized_initializer_lists :
+             diag::ext_generalized_initializer_lists)
           << R.get()->getSourceRange();
     } else
         R = ParseExpression();

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Sat Oct 15 00:09:34 2011
@@ -709,15 +709,15 @@
   RAngleLoc = Tok.getLocation();
 
   if (Tok.is(tok::greatergreater)) {
-    if (!getLang().CPlusPlus0x) {
-      const char *ReplaceStr = "> >";
-      if (NextToken().is(tok::greater) || NextToken().is(tok::greatergreater))
-        ReplaceStr = "> > ";
-
-      Diag(Tok.getLocation(), diag::err_two_right_angle_brackets_need_space)
-        << FixItHint::CreateReplacement(
-                                 SourceRange(Tok.getLocation()), ReplaceStr);
-    }
+    const char *ReplaceStr = "> >";
+    if (NextToken().is(tok::greater) || NextToken().is(tok::greatergreater))
+      ReplaceStr = "> > ";
+
+    Diag(Tok.getLocation(), getLang().CPlusPlus0x ?
+         diag::warn_cxx98_compat_two_right_angle_brackets :
+         diag::err_two_right_angle_brackets_need_space)
+      << FixItHint::CreateReplacement(SourceRange(Tok.getLocation()),
+                                      ReplaceStr);
 
     Tok.setKind(tok::greater);
     if (!ConsumeLastToken) {

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Sat Oct 15 00:09:34 2011
@@ -535,9 +535,9 @@
   Decl *SingleDecl = 0;
   switch (Tok.getKind()) {
   case tok::semi:
-    if (!getLang().CPlusPlus0x)
-      Diag(Tok, diag::ext_top_level_semi)
-        << FixItHint::CreateRemoval(Tok.getLocation());
+    Diag(Tok, getLang().CPlusPlus0x ?
+         diag::warn_cxx98_compat_top_level_semi : diag::ext_top_level_semi)
+      << FixItHint::CreateRemoval(Tok.getLocation());
 
     ConsumeToken();
     // TODO: Invoke action for top-level semicolon.
@@ -918,15 +918,17 @@
     bool Delete = false;
     SourceLocation KWLoc;
     if (Tok.is(tok::kw_delete)) {
-      if (!getLang().CPlusPlus0x)
-        Diag(Tok, diag::warn_deleted_function_accepted_as_extension);
+      Diag(Tok, getLang().CPlusPlus0x ?
+           diag::warn_cxx98_compat_deleted_function :
+           diag::warn_deleted_function_accepted_as_extension);
 
       KWLoc = ConsumeToken();
       Actions.SetDeclDeleted(Res, KWLoc);
       Delete = true;
     } else if (Tok.is(tok::kw_default)) {
-      if (!getLang().CPlusPlus0x)
-        Diag(Tok, diag::warn_defaulted_function_accepted_as_extension);
+      Diag(Tok, getLang().CPlusPlus0x ?
+           diag::warn_cxx98_compat_defaulted_function :
+           diag::warn_defaulted_function_accepted_as_extension);
 
       KWLoc = ConsumeToken();
       Actions.SetDeclDefaulted(Res, KWLoc);

Modified: cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp Sat Oct 15 00:09:34 2011
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -Werror %s
 // RUN: %clang_cc1 -fsyntax-only -std=c++98 -Werror %s
 
 // -Wc++98-compat-pedantic warns on C++11 features which we accept without a
@@ -9,3 +10,9 @@
 
 #define VA_MACRO(x, ...) x // expected-warning {{variadic macros are incompatible with C++98}}
 VA_MACRO(,x) // expected-warning {{empty macro argument list is incompatible with C++98}}
+
+; // expected-warning {{extra ';' outside of a function is incompatible with C++98}}
+
+enum Enum {
+  Enum_value, // expected-warning {{commas at the end of enumerator lists are incompatible with C++98}}
+};

Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=142056&r1=142055&r2=142056&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Sat Oct 15 00:09:34 2011
@@ -27,4 +27,63 @@
 }
 
 template<typename T> struct S {};
-S<::S<void> > s; // expected-warning {{'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98}}
+namespace TemplateParsing {
+  S<::S<void> > s; // expected-warning {{'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98}}
+  S< ::S<void>> t; // expected-warning {{consecutive right angle brackets are incompatible with C++98 (use '> >')}}
+}
+
+void Lambda() {
+  []{}; // expected-warning {{lambda expressions are incompatible with C++98}}
+}
+
+int InitList() {
+  (void)new int {}; // expected-warning {{generalized initializer lists are incompatible with C++98}}
+  (void)int{}; // expected-warning {{generalized initializer lists are incompatible with C++98}}
+  int x {}; // expected-warning {{generalized initializer lists are incompatible with C++98}}
+  return {}; // expected-warning {{generalized initializer lists are incompatible with C++98}}
+}
+
+int operator""_hello(const char *); // expected-warning {{literal operators are incompatible with C++98}}
+
+enum EnumFixed : int { // expected-warning {{enumeration types with a fixed underlying type are incompatible with C++98}}
+};
+
+enum class EnumScoped { // expected-warning {{scoped enumerations are incompatible with C++98}}
+};
+
+void Deleted() = delete; // expected-warning {{deleted function definitions are incompatible with C++98}}
+struct Defaulted {
+  Defaulted() = default; // expected-warning {{defaulted function definitions are incompatible with C++98}}
+};
+
+int &&RvalueReference = 0; // expected-warning {{rvalue references are incompatible with C++98}}
+struct RefQualifier {
+  void f() &; // expected-warning {{reference qualifiers on functions are incompatible with C++98}}
+};
+
+auto f() -> int; // expected-warning {{trailing return types are incompatible with C++98}}
+
+void RangeFor() {
+  int xs[] = {1, 2, 3};
+  for (int &a : xs) { // expected-warning {{range-based for loop is incompatible with C++98}}
+  }
+}
+
+struct InClassInit {
+  int n = 0; // expected-warning {{in-class initialization of non-static data members is incompatible with C++98}}
+};
+
+struct OverrideControlBase {
+  virtual void f();
+  virtual void g();
+};
+struct OverrideControl final : OverrideControlBase { // expected-warning {{'final' keyword is incompatible with C++98}}
+  virtual void f() override; // expected-warning {{'override' keyword is incompatible with C++98}}
+  virtual void g() final; // expected-warning {{'final' keyword is incompatible with C++98}}
+};
+
+using AliasDecl = int; // expected-warning {{alias declarations are incompatible with C++98}}
+template<typename T> using AliasTemplate = T; // expected-warning {{alias declarations are incompatible with C++98}}
+
+inline namespace N { // expected-warning {{inline namespaces are incompatible with C++98}}
+}





More information about the cfe-commits mailing list