зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
f2390367a0
Коммит
eeae8f0727
|
@ -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'}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче