]> granicus.if.org Git - clang/commitdiff
Make our diagnostics about the obsolete GNU designated-initializer
authorDouglas Gregor <dgregor@apple.com>
Sat, 28 Mar 2009 00:41:23 +0000 (00:41 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 28 Mar 2009 00:41:23 +0000 (00:41 +0000)
syntax into extension warnings, and provide code-modification hints
showing how to fix the problem.

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

include/clang/AST/Expr.h
include/clang/Basic/DiagnosticParseKinds.td
include/clang/Parse/Action.h
lib/AST/ASTContext.cpp
lib/AST/Expr.cpp
lib/Parse/ParseInit.cpp
lib/Sema/Sema.h
lib/Sema/SemaInit.cpp
test/Sema/designated-initializers.c

index 9ce86ef12d559544f23bfa244182c7c0aaaf751f..f652f1d26e973e44ecc71fa9a588b556f465f47f 100644 (file)
@@ -1860,9 +1860,9 @@ class DesignatedInitExpr : public Expr {
   /// expression.
   SourceLocation EqualOrColonLoc;
 
-  /// Whether this designated initializer used the GNU deprecated ':'
+  /// Whether this designated initializer used the GNU deprecated
   /// syntax rather than the C99 '=' syntax.
-  bool UsesColonSyntax : 1;
+  bool GNUSyntax : 1;
 
   /// The number of designators in this initializer expression.
   unsigned NumDesignators : 15;
@@ -1873,10 +1873,10 @@ class DesignatedInitExpr : public Expr {
   unsigned NumSubExprs : 16;
 
   DesignatedInitExpr(QualType Ty, unsigned NumDesignators, 
-                     SourceLocation EqualOrColonLoc, bool UsesColonSyntax,
+                     SourceLocation EqualOrColonLoc, bool GNUSyntax,
                      unsigned NumSubExprs)
     : Expr(DesignatedInitExprClass, Ty), 
-      EqualOrColonLoc(EqualOrColonLoc), UsesColonSyntax(UsesColonSyntax), 
+      EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax), 
       NumDesignators(NumDesignators), NumSubExprs(NumSubExprs) { }
 
 public:
@@ -2022,7 +2022,7 @@ public:
                                     unsigned NumDesignators,
                                     Expr **IndexExprs, unsigned NumIndexExprs,
                                     SourceLocation EqualOrColonLoc,
-                                    bool UsesColonSyntax, Expr *Init);
+                                    bool GNUSyntax, Expr *Init);
 
   /// @brief Returns the number of designators in this initializer.
   unsigned size() const { return NumDesignators; }
@@ -2041,8 +2041,8 @@ public:
   SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; }
 
   /// @brief Determines whether this designated initializer used the
-  /// GNU 'fieldname:' syntax or the C99 '=' syntax.
-  bool usesColonSyntax() const { return UsesColonSyntax; }
+  /// deprecated GNU syntax for designated initializers.
+  bool usesGNUSyntax() const { return GNUSyntax; }
 
   /// @brief Retrieve the initializer value.
   Expr *getInit() const { 
index 4f1b1abe489c41441ef1be4bd2d02d98dbb6f68d..7b264d34613477270b14e49370e285754e970753 100644 (file)
@@ -57,10 +57,10 @@ def ext_gnu_conditional_expr : Extension<
 def ext_gnu_empty_initializer : Extension<
   "use of GNU empty initializer extension">;
 def ext_gnu_array_range : Extension<"use of GNU array range extension">;
-def ext_gnu_missing_equal_designator : Extension<
+def ext_gnu_missing_equal_designator : ExtWarn<
   "use of GNU 'missing =' extension in designator">;
 def err_expected_equal_designator : Error<"expected '=' or another designator">;
-def ext_gnu_old_style_field_designator : Extension<
+def ext_gnu_old_style_field_designator : ExtWarn<
   "use of GNU old-style field designator extension">;
 def ext_gnu_case_range : Extension<"use of GNU case range extension">;
 
index b602934cc31ed0790f023f5f9b522e27d0000332..f284ca0a75441216d18358ff967c620254ea8ad4 100644 (file)
@@ -703,15 +703,15 @@ public:
   /// @param Loc The location of the '=' or ':' prior to the
   /// initialization expression.
   ///
-  /// @param UsedColonSyntax If true, then this designated initializer
-  /// used the deprecated GNU syntax @c fieldname:foo rather than the
-  /// C99 syntax @c .fieldname=foo.
+  /// @param GNUSyntax If true, then this designated initializer used
+  /// the deprecated GNU syntax @c fieldname:foo or @c [expr]foo rather
+  /// than the C99 syntax @c .fieldname=foo or @c [expr]=foo.
   ///
   /// @param Init The value that the entity (or entities) described by
   /// the designation will be initialized with.
   virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig,
                                                       SourceLocation Loc,
-                                                      bool UsedColonSyntax,
+                                                      bool GNUSyntax,
                                                       OwningExprResult Init) {
     return ExprEmpty();
   }
index 2fc6a7d5273f6230a9a992e941c95d37963afd6c..da6e049732ea96b930768c5016f20c652c424b1f 100644 (file)
@@ -89,7 +89,6 @@ ASTContext::~ASTContext() {
     GlobalNestedNameSpecifier->Destroy(*this);
 
   TUDecl->Destroy(*this);
-
 }
 
 void ASTContext::PrintStats() const {
index 92310902e284abf52ed615e9cf10030bf065bfdf..08ab5440b16fa7212100464b86ee2575960e3bd8 100644 (file)
@@ -1534,7 +1534,7 @@ SourceRange DesignatedInitExpr::getSourceRange() const {
   Designator &First =
     *const_cast<DesignatedInitExpr*>(this)->designators_begin();
   if (First.isFieldDesignator()) {
-    if (UsesColonSyntax)
+    if (GNUSyntax)
       StartLoc = SourceLocation::getFromRawEncoding(First.Field.FieldLoc);
     else
       StartLoc = SourceLocation::getFromRawEncoding(First.Field.DotLoc);
index 3a42e50a9ca9a5cd66b76c51148bfea8f237452b..7837a0c7fd5f90dc733a0bda0fd3c3567c486338 100644 (file)
@@ -64,14 +64,22 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
   // Handle it as a field designator.  Otherwise, this must be the start of a
   // normal expression.
   if (Tok.is(tok::identifier)) {
-    Diag(Tok, diag::ext_gnu_old_style_field_designator);
-    
     const IdentifierInfo *FieldName = Tok.getIdentifierInfo();
+
+    std::string NewSyntax(".");
+    NewSyntax += FieldName->getName();
+    NewSyntax += " = ";
+
     SourceLocation NameLoc = ConsumeToken(); // Eat the identifier.
     
     assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!");
     SourceLocation ColonLoc = ConsumeToken();
 
+    Diag(Tok, diag::ext_gnu_old_style_field_designator)
+      << CodeModificationHint::CreateReplacement(SourceRange(NameLoc, 
+                                                             ColonLoc),
+                                                 NewSyntax);
+
     Designation D;
     D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
     return Actions.ActOnDesignatedInitializer(D, ColonLoc, true, 
@@ -209,8 +217,9 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
   if (Desig.getNumDesignators() == 1 && 
       (Desig.getDesignator(0).isArrayDesignator() ||
        Desig.getDesignator(0).isArrayRangeDesignator())) {
-    Diag(Tok, diag::ext_gnu_missing_equal_designator);
-    return Actions.ActOnDesignatedInitializer(Desig, SourceLocation(),
+    Diag(Tok, diag::ext_gnu_missing_equal_designator)
+      << CodeModificationHint::CreateInsertion(Tok.getLocation(), "=");
+    return Actions.ActOnDesignatedInitializer(Desig, Tok.getLocation(),
                                               true, ParseInitializer());
   }
 
index 8dee4f19a21a8f699a01fdbfe6be4735a373384b..76740e8dd99cb70d831bb841d230111359dcdb34 100644 (file)
@@ -1285,7 +1285,7 @@ public:
 
   virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig,
                                                       SourceLocation Loc,
-                                                      bool UsedColonSyntax,
+                                                      bool GNUSyntax,
                                                       OwningExprResult Init);
 
   virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
index 600dc34351761b0ee777f3645a80b59f9fbf7530..fbf3ae2a78525686ebafaf667a4396c1391439e0 100644 (file)
@@ -1548,7 +1548,7 @@ CheckArrayDesignatorExpr(Sema &Self, Expr *Index, llvm::APSInt &Value) {
 
 Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
                                                         SourceLocation Loc,
-                                                        bool UsedColonSyntax,
+                                                        bool GNUSyntax,
                                                         OwningExprResult Init) {
   typedef DesignatedInitExpr::Designator ASTDesignator;
 
@@ -1622,7 +1622,7 @@ Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
   DesignatedInitExpr *DIE
     = DesignatedInitExpr::Create(Context, &Designators[0], Designators.size(),
                                  &InitExpressions[0], InitExpressions.size(),
-                                 Loc, UsedColonSyntax, 
+                                 Loc, GNUSyntax, 
                                  static_cast<Expr *>(Init.release()));
   return Owned(DIE);
 }
index cfbe80224bf25a1aaf25c4368665e947f3234e92..f4170c267de36ac15cbd043a1f775d6e60bfc548 100644 (file)
@@ -18,6 +18,7 @@ int iarray2[10] = {
 };
 
 int iarray3[10] = {
+  [3] 2, // expected-warning{{use of GNU 'missing =' extension in designator}}
   [5 ... 12] = 2 // expected-error{{array designator index (12) exceeds array bounds (10)}}
 };
 
@@ -28,7 +29,7 @@ struct point {
 
 struct point p1 = { 
   .y = 1.0, 
-  x: 2.0,
+  x: 2.0, // expected-warning{{}}
   .a = 4.0, // expected-error{{field designator 'a' does not refer to any field in type 'struct point'}}
 };