[cfe-commits] r39227 - in /cfe/cfe/trunk: AST/SemaDecl.cpp Parse/DeclSpec.cpp Parse/ParseDecl.cpp Parse/Parser.cpp Sema/SemaDecl.cpp include/clang/Parse/DeclSpec.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:41:31 PDT 2007
Author: sabre
Date: Wed Jul 11 11:41:30 2007
New Revision: 39227
URL: http://llvm.org/viewvc/llvm-project?rev=39227&view=rev
Log:
capture sourcelocation info for type specifiers. This improves diagnostics
for things like 'short _Complex'.
Modified:
cfe/cfe/trunk/AST/SemaDecl.cpp
cfe/cfe/trunk/Parse/DeclSpec.cpp
cfe/cfe/trunk/Parse/ParseDecl.cpp
cfe/cfe/trunk/Parse/Parser.cpp
cfe/cfe/trunk/Sema/SemaDecl.cpp
cfe/cfe/trunk/include/clang/Parse/DeclSpec.h
Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39227&r1=39226&r2=39227&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:41:30 2007
@@ -137,7 +137,7 @@
// Set a Declarator for the implicit definition: int foo();
const char *Dummy;
DeclSpec DS;
- bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Dummy);
+ bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy);
assert(!Error && "Error setting up implicit decl!");
Declarator D(DS, Declarator::BlockContext);
D.AddTypeInfo(DeclaratorTypeInfo::getFunction(false, false, true, Loc));
Modified: cfe/cfe/trunk/Parse/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/DeclSpec.cpp?rev=39227&r1=39226&r2=39227&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/DeclSpec.cpp (original)
+++ cfe/cfe/trunk/Parse/DeclSpec.cpp Wed Jul 11 11:41:30 2007
@@ -141,34 +141,42 @@
/// These methods set the specified attribute of the DeclSpec, but return true
/// and ignore the request if invalid (e.g. "extern" then "auto" is
/// specified).
-bool DeclSpec::SetTypeSpecWidth(TSW W, const char *&PrevSpec) {
+bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
+ const char *&PrevSpec) {
if (TypeSpecWidth != TSW_unspecified &&
// Allow turning long -> long long.
(W != TSW_longlong || TypeSpecWidth != TSW_long))
return BadSpecifier(TypeSpecWidth, PrevSpec);
TypeSpecWidth = W;
+ TSWLoc = Loc;
return false;
}
-bool DeclSpec::SetTypeSpecComplex(TSC C, const char *&PrevSpec) {
+bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
+ const char *&PrevSpec) {
if (TypeSpecComplex != TSC_unspecified)
return BadSpecifier(TypeSpecComplex, PrevSpec);
TypeSpecComplex = C;
+ TSCLoc = Loc;
return false;
}
-bool DeclSpec::SetTypeSpecSign(TSS S, const char *&PrevSpec) {
+bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
+ const char *&PrevSpec) {
if (TypeSpecSign != TSS_unspecified)
return BadSpecifier(TypeSpecSign, PrevSpec);
TypeSpecSign = S;
+ TSSLoc = Loc;
return false;
}
-bool DeclSpec::SetTypeSpecType(TST T, const char *&PrevSpec, void *TypeRep) {
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+ const char *&PrevSpec, void *TypeRep) {
if (TypeSpecType != TST_unspecified)
return BadSpecifier(TypeSpecType, PrevSpec);
TypeSpecType = T;
TypenameRep = TypeRep;
+ TSTLoc = Loc;
return false;
}
@@ -200,8 +208,7 @@
/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
/// DeclSpec is guaranteed self-consistent, even if an error occurred.
-void DeclSpec::Finish(SourceLocation Loc, Diagnostic &D,
- const LangOptions &Lang) {
+void DeclSpec::Finish(Diagnostic &D, const LangOptions &Lang) {
// Check the type specifier components first.
// signed/unsigned are only valid with int/char.
@@ -209,7 +216,8 @@
if (TypeSpecType == TST_unspecified)
TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
else if (TypeSpecType != TST_int && TypeSpecType != TST_char) {
- D.Report(Loc, diag::err_invalid_sign_spec,getSpecifierName(TypeSpecType));
+ D.Report(TSSLoc, diag::err_invalid_sign_spec,
+ getSpecifierName(TypeSpecType));
// signed double -> double.
TypeSpecSign = TSS_unspecified;
}
@@ -223,8 +231,9 @@
if (TypeSpecType == TST_unspecified)
TypeSpecType = TST_int; // short -> short int, long long -> long long int.
else if (TypeSpecType != TST_int) {
- D.Report(Loc, TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec :
- diag::err_invalid_longlong_spec,
+ D.Report(TSWLoc,
+ TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
+ : diag::err_invalid_longlong_spec,
getSpecifierName(TypeSpecType));
TypeSpecType = TST_int;
}
@@ -233,7 +242,7 @@
if (TypeSpecType == TST_unspecified)
TypeSpecType = TST_int; // long -> long int.
else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
- D.Report(Loc, diag::err_invalid_long_spec,
+ D.Report(TSWLoc, diag::err_invalid_long_spec,
getSpecifierName(TypeSpecType));
TypeSpecType = TST_int;
}
@@ -244,13 +253,13 @@
// disallow their use. Need information about the backend.
if (TypeSpecComplex != TSC_unspecified) {
if (TypeSpecType == TST_unspecified) {
- D.Report(Loc, diag::ext_plain_complex);
+ D.Report(TSCLoc, diag::ext_plain_complex);
TypeSpecType = TST_double; // _Complex -> _Complex double.
} else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
// Note that this intentionally doesn't include _Complex _Bool.
- D.Report(Loc, diag::ext_integer_complex);
+ D.Report(TSTLoc, diag::ext_integer_complex);
} else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
- D.Report(Loc, diag::err_invalid_complex_spec,
+ D.Report(TSCLoc, diag::err_invalid_complex_spec,
getSpecifierName(TypeSpecType));
TypeSpecComplex = TSC_unspecified;
}
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39227&r1=39226&r2=39227&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:41:30 2007
@@ -247,8 +247,6 @@
/// [C99] 'inline'
///
void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
- // FIXME: Remove this.
- SourceLocation StartLoc = Tok.getLocation();
while (1) {
int isInvalid = false;
const char *PrevSpec = 0;
@@ -264,7 +262,7 @@
// It has to be available as a typedef too!
if (void *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(),
CurScope)) {
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, PrevSpec,
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
TypeRep);
}
break;
@@ -273,8 +271,7 @@
default:
// If this is not a declaration specifier token, we're done reading decl
// specifiers. First verify that DeclSpec's are consistent.
- // FIXME: Remove StartLoc.
- DS.Finish(StartLoc, Diags, getLang());
+ DS.Finish(Diags, getLang());
return;
// GNU attributes support.
@@ -308,52 +305,52 @@
// type-specifiers
case tok::kw_short:
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, PrevSpec);
+ isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
break;
case tok::kw_long:
if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, PrevSpec);
+ isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
else
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, PrevSpec);
+ isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec);
break;
case tok::kw_signed:
- isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, PrevSpec);
+ isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
break;
case tok::kw_unsigned:
- isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, PrevSpec);
+ isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
break;
case tok::kw__Complex:
- isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, PrevSpec);
+ isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec);
break;
case tok::kw__Imaginary:
- isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, PrevSpec);
+ isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec);
break;
case tok::kw_void:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
break;
case tok::kw_char:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
break;
case tok::kw_int:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
break;
case tok::kw_float:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
break;
case tok::kw_double:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
break;
case tok::kw__Bool:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
break;
case tok::kw__Decimal32:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec);
break;
case tok::kw__Decimal64:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec);
break;
case tok::kw__Decimal128:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec);
break;
case tok::kw_struct:
@@ -433,7 +430,7 @@
assert((Tok.getKind() == tok::kw_struct ||
Tok.getKind() == tok::kw_union) && "Not a struct/union specifier");
bool isUnion = Tok.getKind() == tok::kw_union;
- SourceLocation Start = ConsumeToken();
+ SourceLocation StartLoc = ConsumeToken();
// If attributes exist after tag, parse them.
if (Tok.getKind() == tok::kw___attribute)
@@ -530,8 +527,8 @@
const char *PrevSpec = 0;
if (DS.SetTypeSpecType(isUnion ? DeclSpec::TST_union : DeclSpec::TST_struct,
- PrevSpec))
- Diag(Start, diag::err_invalid_decl_spec_combination, PrevSpec);
+ StartLoc, PrevSpec))
+ Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
}
@@ -554,7 +551,7 @@
///
void Parser::ParseEnumSpecifier(DeclSpec &DS) {
assert(Tok.getKind() == tok::kw_enum && "Not an enum specifier");
- SourceLocation Start = ConsumeToken();
+ SourceLocation StartLoc = ConsumeToken();
if (Tok.getKind() == tok::kw___attribute)
ParseAttributes();
@@ -604,8 +601,8 @@
const char *PrevSpec = 0;
- if (DS.SetTypeSpecType(DeclSpec::TST_enum, PrevSpec))
- Diag(Start, diag::err_invalid_decl_spec_combination, PrevSpec);
+ if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec))
+ Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
}
@@ -714,7 +711,6 @@
/// [GNU] type-qualifier-list attributes
///
void Parser::ParseTypeQualifierListOpt(DeclSpec &DS) {
- SourceLocation StartLoc = Tok.getLocation();
while (1) {
int isInvalid = false;
const char *PrevSpec = 0;
@@ -724,7 +720,7 @@
default:
// If this is not a type-qualifier token, we're done reading type
// qualifiers. First verify that DeclSpec's are consistent.
- DS.Finish(StartLoc, Diags, getLang());
+ DS.Finish(Diags, getLang());
return;
case tok::kw_const:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
@@ -746,6 +742,7 @@
// If the specifier combination wasn't legal, issue a diagnostic.
if (isInvalid) {
+ // FIXME: emit a matching caret at the previous illegal spec combination.
assert(PrevSpec && "Method did not return previous specifier!");
if (isInvalid == 1) // Error.
Diag(Tok, diag::err_invalid_decl_spec_combination, PrevSpec);
Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=39227&r1=39226&r2=39227&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:41:30 2007
@@ -240,7 +240,7 @@
Dummy);
// TODO: add a 'TST_builtin' type?
- Error |= DS.SetTypeSpecType(DeclSpec::TST_int, Dummy);
+ Error |= DS.SetTypeSpecType(DeclSpec::TST_int, SourceLocation(), Dummy);
assert(!Error && "Error setting up __builtin_va_list!");
Declarator D(DS, Declarator::FileContext);
Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39227&r1=39226&r2=39227&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:41:30 2007
@@ -137,7 +137,7 @@
// Set a Declarator for the implicit definition: int foo();
const char *Dummy;
DeclSpec DS;
- bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Dummy);
+ bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy);
assert(!Error && "Error setting up implicit decl!");
Declarator D(DS, Declarator::BlockContext);
D.AddTypeInfo(DeclaratorTypeInfo::getFunction(false, false, true, Loc));
Modified: cfe/cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=39227&r1=39226&r2=39227&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jul 11 11:41:30 2007
@@ -121,6 +121,7 @@
// SourceLocation info. These are null if the item wasn't specified or if
// the setting was synthesized.
SourceLocation StorageClassSpecLoc, SCS_threadLoc;
+ SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc;
SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
SourceLocation FS_inlineLoc;
public:
@@ -159,6 +160,11 @@
TST getTypeSpecType() const { return TypeSpecType; }
void *getTypenameRep() const { return TypenameRep; }
+ SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
+ SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
+ SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
+ SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
+
// type-qualifiers
/// getTypeQualifiers - Return a set of TQs.
@@ -195,10 +201,11 @@
/// specified). The name of the previous specifier is returned in prevspec.
bool SetStorageClassSpec(SCS S, SourceLocation Loc, const char *&PrevSpec);
bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec);
- bool SetTypeSpecWidth(TSW W, const char *&PrevSpec);
- bool SetTypeSpecComplex(TSC C, const char *&PrevSpec);
- bool SetTypeSpecSign(TSS S, const char *&PrevSpec);
- bool SetTypeSpecType(TST T, const char *&PrevSpec, void *TypenameRep = 0);
+ bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec);
+ bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec);
+ bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec);
+ bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
+ void *TypenameRep = 0);
bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
const LangOptions &Lang);
@@ -208,7 +215,7 @@
/// Finish - This does final analysis of the declspec, issuing diagnostics for
/// things like "_Imaginary" (lacking an FP type). After calling this method,
/// DeclSpec is guaranteed self-consistent, even if an error occurred.
- void Finish(SourceLocation Loc, Diagnostic &D,const LangOptions &Lang);
+ void Finish(Diagnostic &D,const LangOptions &Lang);
};
More information about the cfe-commits
mailing list