Improve the diagnostics of the number-reading preprocessor directives.

The GNU line marker directive was sharing code with the #line directive, but some of the warnings/errors were reporting as #line directive diagnostics in both cases.

Previously:
#line 11foo1   ==> "#line directive requires a simple digit sequence"
# 11foo1       ==> "#line directive requires a simple digit sequence"

Now, we get:
#line 11foo1   ==> "#line directive requires a simple digit sequence"
# 11foo1       ==> "GNU line marker directive requires a simple digit sequence"

llvm-svn: 179139
This commit is contained in:
Michael Ilseman 2013-04-10 01:04:18 +00:00
parent e1368a107a
commit e910cc8e07
3 changed files with 10 additions and 7 deletions

View File

@ -476,9 +476,9 @@ def ext_pp_line_zero : Extension<
def err_pp_line_invalid_filename : Error< def err_pp_line_invalid_filename : Error<
"invalid filename for #line directive">; "invalid filename for #line directive">;
def warn_pp_line_decimal : Warning< def warn_pp_line_decimal : Warning<
"#line directive interprets number as decimal, not octal">; "%select{#line|GNU line marker}0 directive interprets number as decimal, not octal">;
def err_pp_line_digit_sequence : Error< def err_pp_line_digit_sequence : Error<
"#line directive requires a simple digit sequence">; "%select{#line|GNU line marker}0 directive requires a simple digit sequence">;
def err_pp_linemarker_requires_integer : Error< def err_pp_linemarker_requires_integer : Error<
"line marker directive requires a positive integer argument">; "line marker directive requires a positive integer argument">;
def err_pp_linemarker_invalid_filename : Error< def err_pp_linemarker_invalid_filename : Error<

View File

@ -793,7 +793,8 @@ void Preprocessor::HandleDirective(Token &Result) {
/// GetLineValue - Convert a numeric token into an unsigned value, emitting /// GetLineValue - Convert a numeric token into an unsigned value, emitting
/// Diagnostic DiagID if it is invalid, and returning the value in Val. /// Diagnostic DiagID if it is invalid, and returning the value in Val.
static bool GetLineValue(Token &DigitTok, unsigned &Val, static bool GetLineValue(Token &DigitTok, unsigned &Val,
unsigned DiagID, Preprocessor &PP) { unsigned DiagID, Preprocessor &PP,
bool IsGNULineDirective=false) {
if (DigitTok.isNot(tok::numeric_constant)) { if (DigitTok.isNot(tok::numeric_constant)) {
PP.Diag(DigitTok, DiagID); PP.Diag(DigitTok, DiagID);
@ -817,7 +818,7 @@ static bool GetLineValue(Token &DigitTok, unsigned &Val,
for (unsigned i = 0; i != ActualLength; ++i) { for (unsigned i = 0; i != ActualLength; ++i) {
if (!isDigit(DigitTokBegin[i])) { if (!isDigit(DigitTokBegin[i])) {
PP.Diag(PP.AdvanceToTokenCharacter(DigitTok.getLocation(), i), PP.Diag(PP.AdvanceToTokenCharacter(DigitTok.getLocation(), i),
diag::err_pp_line_digit_sequence); diag::err_pp_line_digit_sequence) << IsGNULineDirective;
PP.DiscardUntilEndOfDirective(); PP.DiscardUntilEndOfDirective();
return true; return true;
} }
@ -832,7 +833,8 @@ static bool GetLineValue(Token &DigitTok, unsigned &Val,
} }
if (DigitTokBegin[0] == '0' && Val) if (DigitTokBegin[0] == '0' && Val)
PP.Diag(DigitTok.getLocation(), diag::warn_pp_line_decimal); PP.Diag(DigitTok.getLocation(), diag::warn_pp_line_decimal)
<< IsGNULineDirective;
return false; return false;
} }
@ -998,7 +1000,7 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
// line # limit other than it fit in 32-bits. // line # limit other than it fit in 32-bits.
unsigned LineNo; unsigned LineNo;
if (GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer, if (GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
*this)) *this, true))
return; return;
Token StrTok; Token StrTok;

View File

@ -29,7 +29,7 @@
# 42 "foo" 3 1 // expected-error {{invalid flag line marker directive}} # 42 "foo" 3 1 // expected-error {{invalid flag line marker directive}}
# 42 "foo" 42 // expected-error {{invalid flag line marker directive}} # 42 "foo" 42 // expected-error {{invalid flag line marker directive}}
# 42 "foo" 1 2 // expected-error {{invalid flag line marker directive}} # 42 "foo" 1 2 // expected-error {{invalid flag line marker directive}}
# 42a33 // expected-error {{GNU line marker directive requires a simple digit sequence}}
// These are checked by the RUN line. // These are checked by the RUN line.
#line 92 "blonk.c" #line 92 "blonk.c"
@ -83,6 +83,7 @@ typedef int q; // original definition in system header, should not diagnose.
// Line markers are digit strings interpreted as decimal numbers, this is // Line markers are digit strings interpreted as decimal numbers, this is
// 10, not 8. // 10, not 8.
#line 010 // expected-warning {{#line directive interprets number as decimal, not octal}} #line 010 // expected-warning {{#line directive interprets number as decimal, not octal}}
# 010 // expected-warning {{GNU line marker directive interprets number as decimal, not octal}}
extern int array[__LINE__ == 10 ? 1:-1]; extern int array[__LINE__ == 10 ? 1:-1];
/* PR3917 */ /* PR3917 */