diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-03-28 00:41:23 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-03-28 00:41:23 +0000 |
| commit | 5c7c9cb6786d03108ae41af9ddb4d5a67f5d3086 (patch) | |
| tree | 3cc512b609fb6f6c1feeb6799345e62cd3322fb2 | |
| parent | a94d139a1f1bd3d930d0af649e2276ab1822ea3a (diff) | |
| download | bcm5719-llvm-5c7c9cb6786d03108ae41af9ddb4d5a67f5d3086.tar.gz bcm5719-llvm-5c7c9cb6786d03108ae41af9ddb4d5a67f5d3086.zip | |
Make our diagnostics about the obsolete GNU designated-initializer
syntax into extension warnings, and provide code-modification hints
showing how to fix the problem.
llvm-svn: 67885
| -rw-r--r-- | clang/include/clang/AST/Expr.h | 14 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticParseKinds.td | 4 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Action.h | 8 | ||||
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseInit.cpp | 17 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 4 | ||||
| -rw-r--r-- | clang/test/Sema/designated-initializers.c | 3 |
9 files changed, 32 insertions, 23 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 9ce86ef12d5..f652f1d26e9 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -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 { diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 4f1b1abe489..7b264d34613 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -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">; diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index b602934cc31..f284ca0a754 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -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(); } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 2fc6a7d5273..da6e049732e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -89,7 +89,6 @@ ASTContext::~ASTContext() { GlobalNestedNameSpecifier->Destroy(*this); TUDecl->Destroy(*this); - } void ASTContext::PrintStats() const { diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 92310902e28..08ab5440b16 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -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); diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 3a42e50a9ca..7837a0c7fd5 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -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()); } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 8dee4f19a21..76740e8dd99 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -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, diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 600dc343517..fbf3ae2a785 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -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); } diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c index cfbe80224bf..f4170c267de 100644 --- a/clang/test/Sema/designated-initializers.c +++ b/clang/test/Sema/designated-initializers.c @@ -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'}} }; |

