Make our diagnostics about the obsolete GNU designated-initializer

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
This commit is contained in:
Douglas Gregor 2009-03-28 00:41:23 +00:00
Родитель f2390367a0
Коммит eeae8f0727
9 изменённых файлов: 32 добавлений и 23 удалений

Просмотреть файл

@ -1860,9 +1860,9 @@ class DesignatedInitExpr : public Expr {
/// expression. /// expression.
SourceLocation EqualOrColonLoc; SourceLocation EqualOrColonLoc;
/// Whether this designated initializer used the GNU deprecated ':' /// Whether this designated initializer used the GNU deprecated
/// syntax rather than the C99 '=' syntax. /// syntax rather than the C99 '=' syntax.
bool UsesColonSyntax : 1; bool GNUSyntax : 1;
/// The number of designators in this initializer expression. /// The number of designators in this initializer expression.
unsigned NumDesignators : 15; unsigned NumDesignators : 15;
@ -1873,10 +1873,10 @@ class DesignatedInitExpr : public Expr {
unsigned NumSubExprs : 16; unsigned NumSubExprs : 16;
DesignatedInitExpr(QualType Ty, unsigned NumDesignators, DesignatedInitExpr(QualType Ty, unsigned NumDesignators,
SourceLocation EqualOrColonLoc, bool UsesColonSyntax, SourceLocation EqualOrColonLoc, bool GNUSyntax,
unsigned NumSubExprs) unsigned NumSubExprs)
: Expr(DesignatedInitExprClass, Ty), : Expr(DesignatedInitExprClass, Ty),
EqualOrColonLoc(EqualOrColonLoc), UsesColonSyntax(UsesColonSyntax), EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax),
NumDesignators(NumDesignators), NumSubExprs(NumSubExprs) { } NumDesignators(NumDesignators), NumSubExprs(NumSubExprs) { }
public: public:
@ -2022,7 +2022,7 @@ public:
unsigned NumDesignators, unsigned NumDesignators,
Expr **IndexExprs, unsigned NumIndexExprs, Expr **IndexExprs, unsigned NumIndexExprs,
SourceLocation EqualOrColonLoc, SourceLocation EqualOrColonLoc,
bool UsesColonSyntax, Expr *Init); bool GNUSyntax, Expr *Init);
/// @brief Returns the number of designators in this initializer. /// @brief Returns the number of designators in this initializer.
unsigned size() const { return NumDesignators; } unsigned size() const { return NumDesignators; }
@ -2041,8 +2041,8 @@ public:
SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; } SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; }
/// @brief Determines whether this designated initializer used the /// @brief Determines whether this designated initializer used the
/// GNU 'fieldname:' syntax or the C99 '=' syntax. /// deprecated GNU syntax for designated initializers.
bool usesColonSyntax() const { return UsesColonSyntax; } bool usesGNUSyntax() const { return GNUSyntax; }
/// @brief Retrieve the initializer value. /// @brief Retrieve the initializer value.
Expr *getInit() const { Expr *getInit() const {

Просмотреть файл

@ -57,10 +57,10 @@ def ext_gnu_conditional_expr : Extension<
def ext_gnu_empty_initializer : Extension< def ext_gnu_empty_initializer : Extension<
"use of 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_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">; "use of GNU 'missing =' extension in designator">;
def err_expected_equal_designator : Error<"expected '=' or another 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">; "use of GNU old-style field designator extension">;
def ext_gnu_case_range : Extension<"use of GNU case range extension">; def ext_gnu_case_range : Extension<"use of GNU case range extension">;

Просмотреть файл

@ -703,15 +703,15 @@ public:
/// @param Loc The location of the '=' or ':' prior to the /// @param Loc The location of the '=' or ':' prior to the
/// initialization expression. /// initialization expression.
/// ///
/// @param UsedColonSyntax If true, then this designated initializer /// @param GNUSyntax If true, then this designated initializer used
/// used the deprecated GNU syntax @c fieldname:foo rather than the /// the deprecated GNU syntax @c fieldname:foo or @c [expr]foo rather
/// C99 syntax @c .fieldname=foo. /// than the C99 syntax @c .fieldname=foo or @c [expr]=foo.
/// ///
/// @param Init The value that the entity (or entities) described by /// @param Init The value that the entity (or entities) described by
/// the designation will be initialized with. /// the designation will be initialized with.
virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig, virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig,
SourceLocation Loc, SourceLocation Loc,
bool UsedColonSyntax, bool GNUSyntax,
OwningExprResult Init) { OwningExprResult Init) {
return ExprEmpty(); return ExprEmpty();
} }

Просмотреть файл

@ -89,7 +89,6 @@ ASTContext::~ASTContext() {
GlobalNestedNameSpecifier->Destroy(*this); GlobalNestedNameSpecifier->Destroy(*this);
TUDecl->Destroy(*this); TUDecl->Destroy(*this);
} }
void ASTContext::PrintStats() const { void ASTContext::PrintStats() const {

Просмотреть файл

@ -1534,7 +1534,7 @@ SourceRange DesignatedInitExpr::getSourceRange() const {
Designator &First = Designator &First =
*const_cast<DesignatedInitExpr*>(this)->designators_begin(); *const_cast<DesignatedInitExpr*>(this)->designators_begin();
if (First.isFieldDesignator()) { if (First.isFieldDesignator()) {
if (UsesColonSyntax) if (GNUSyntax)
StartLoc = SourceLocation::getFromRawEncoding(First.Field.FieldLoc); StartLoc = SourceLocation::getFromRawEncoding(First.Field.FieldLoc);
else else
StartLoc = SourceLocation::getFromRawEncoding(First.Field.DotLoc); StartLoc = SourceLocation::getFromRawEncoding(First.Field.DotLoc);

Просмотреть файл

@ -64,14 +64,22 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
// Handle it as a field designator. Otherwise, this must be the start of a // Handle it as a field designator. Otherwise, this must be the start of a
// normal expression. // normal expression.
if (Tok.is(tok::identifier)) { if (Tok.is(tok::identifier)) {
Diag(Tok, diag::ext_gnu_old_style_field_designator);
const IdentifierInfo *FieldName = Tok.getIdentifierInfo(); const IdentifierInfo *FieldName = Tok.getIdentifierInfo();
std::string NewSyntax(".");
NewSyntax += FieldName->getName();
NewSyntax += " = ";
SourceLocation NameLoc = ConsumeToken(); // Eat the identifier. SourceLocation NameLoc = ConsumeToken(); // Eat the identifier.
assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!"); assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!");
SourceLocation ColonLoc = ConsumeToken(); SourceLocation ColonLoc = ConsumeToken();
Diag(Tok, diag::ext_gnu_old_style_field_designator)
<< CodeModificationHint::CreateReplacement(SourceRange(NameLoc,
ColonLoc),
NewSyntax);
Designation D; Designation D;
D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc)); D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
return Actions.ActOnDesignatedInitializer(D, ColonLoc, true, return Actions.ActOnDesignatedInitializer(D, ColonLoc, true,
@ -209,8 +217,9 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
if (Desig.getNumDesignators() == 1 && if (Desig.getNumDesignators() == 1 &&
(Desig.getDesignator(0).isArrayDesignator() || (Desig.getDesignator(0).isArrayDesignator() ||
Desig.getDesignator(0).isArrayRangeDesignator())) { Desig.getDesignator(0).isArrayRangeDesignator())) {
Diag(Tok, diag::ext_gnu_missing_equal_designator); Diag(Tok, diag::ext_gnu_missing_equal_designator)
return Actions.ActOnDesignatedInitializer(Desig, SourceLocation(), << CodeModificationHint::CreateInsertion(Tok.getLocation(), "=");
return Actions.ActOnDesignatedInitializer(Desig, Tok.getLocation(),
true, ParseInitializer()); true, ParseInitializer());
} }

Просмотреть файл

@ -1285,7 +1285,7 @@ public:
virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig, virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig,
SourceLocation Loc, SourceLocation Loc,
bool UsedColonSyntax, bool GNUSyntax,
OwningExprResult Init); OwningExprResult Init);
virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,

Просмотреть файл

@ -1548,7 +1548,7 @@ CheckArrayDesignatorExpr(Sema &Self, Expr *Index, llvm::APSInt &Value) {
Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig, Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
SourceLocation Loc, SourceLocation Loc,
bool UsedColonSyntax, bool GNUSyntax,
OwningExprResult Init) { OwningExprResult Init) {
typedef DesignatedInitExpr::Designator ASTDesignator; typedef DesignatedInitExpr::Designator ASTDesignator;
@ -1622,7 +1622,7 @@ Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
DesignatedInitExpr *DIE DesignatedInitExpr *DIE
= DesignatedInitExpr::Create(Context, &Designators[0], Designators.size(), = DesignatedInitExpr::Create(Context, &Designators[0], Designators.size(),
&InitExpressions[0], InitExpressions.size(), &InitExpressions[0], InitExpressions.size(),
Loc, UsedColonSyntax, Loc, GNUSyntax,
static_cast<Expr *>(Init.release())); static_cast<Expr *>(Init.release()));
return Owned(DIE); return Owned(DIE);
} }

Просмотреть файл

@ -18,6 +18,7 @@ int iarray2[10] = {
}; };
int iarray3[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)}} [5 ... 12] = 2 // expected-error{{array designator index (12) exceeds array bounds (10)}}
}; };
@ -28,7 +29,7 @@ struct point {
struct point p1 = { struct point p1 = {
.y = 1.0, .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'}} .a = 4.0, // expected-error{{field designator 'a' does not refer to any field in type 'struct point'}}
}; };