[cfe-commits] r39224 - in /cfe/cfe/trunk: Parse/DeclSpec.cpp Parse/ParseDecl.cpp Parse/Parser.cpp include/clang/Parse/DeclSpec.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:41:28 PDT 2007
Author: sabre
Date: Wed Jul 11 11:41:28 2007
New Revision: 39224
URL: http://llvm.org/viewvc/llvm-project?rev=39224&view=rev
Log:
record accurate sourceloc info for storage class specs, so we can report
things like:
t.c:4:10: error: invalid storage class specifier in function declarator
int foo2(auto int Aaslfkasdflkj, register B);
^
instead of:
t.c:4:19: error: invalid storage class specifier in function declarator
int foo2(auto int Aaslfkasdflkj, register B);
^
Modified:
cfe/cfe/trunk/Parse/DeclSpec.cpp
cfe/cfe/trunk/Parse/ParseDecl.cpp
cfe/cfe/trunk/Parse/Parser.cpp
cfe/cfe/trunk/include/clang/Parse/DeclSpec.h
Modified: cfe/cfe/trunk/Parse/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/DeclSpec.cpp?rev=39224&r1=39223&r2=39224&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/DeclSpec.cpp (original)
+++ cfe/cfe/trunk/Parse/DeclSpec.cpp Wed Jul 11 11:41:28 2007
@@ -25,7 +25,7 @@
SCS_thread_specified)
Res |= PQ_StorageClassSpecifier;
- if (TypeQualifiers != TQ_unspecified)
+ if (TypeQualifiers != TQ_unspecified)
Res |= PQ_TypeQualifier;
if (hasTypeSpecifier())
@@ -117,19 +117,23 @@
return true;
}
-bool DeclSpec::SetStorageClassSpec(SCS S, const char *&PrevSpec) {
+bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc,
+ const char *&PrevSpec) {
if (StorageClassSpec != SCS_unspecified)
return BadSpecifier(StorageClassSpec, PrevSpec);
StorageClassSpec = S;
+ StorageClassSpecLoc = Loc;
return false;
}
-bool DeclSpec::SetStorageClassSpecThread(const char *&PrevSpec) {
+bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
+ const char *&PrevSpec) {
if (SCS_thread_specified) {
PrevSpec = "__thread";
return true;
}
SCS_thread_specified = true;
+ SCS_threadLoc = Loc;
return false;
}
@@ -250,7 +254,7 @@
StorageClassSpec = SCS_extern; // '__thread int' -> 'extern __thread int'
} else if (StorageClassSpec != SCS_extern &&
StorageClassSpec != SCS_static) {
- D.Report(Loc, diag::err_invalid_thread_spec,
+ D.Report(getStorageClassSpecLoc(), diag::err_invalid_thread_spec,
getSpecifierName(StorageClassSpec));
SCS_thread_specified = false;
}
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39224&r1=39223&r2=39224&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:41:28 2007
@@ -244,10 +244,13 @@
/// [C99] 'inline'
///
void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
+ // FIXME: Remove this.
SourceLocation StartLoc = Tok.getLocation();
while (1) {
int isInvalid = false;
const char *PrevSpec = 0;
+ SourceLocation Loc = Tok.getLocation();
+
switch (Tok.getKind()) {
// typedef-name
case tok::identifier:
@@ -267,6 +270,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());
return;
@@ -277,26 +281,26 @@
// storage-class-specifier
case tok::kw_typedef:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec);
break;
case tok::kw_extern:
if (DS.isThreadSpecified())
Diag(Tok, diag::ext_thread_before, "extern");
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec);
break;
case tok::kw_static:
if (DS.isThreadSpecified())
Diag(Tok, diag::ext_thread_before, "static");
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec);
break;
case tok::kw_auto:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec);
break;
case tok::kw_register:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec);
break;
case tok::kw___thread:
- isInvalid = DS.SetStorageClassSpecThread(PrevSpec)*2;
+ isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec)*2;
break;
// type-specifiers
@@ -989,12 +993,16 @@
case DeclSpec::SCS_auto:
// NOTE: we could trivially allow 'int foo(auto int X)' if we wanted.
default:
- // FIXME: Get better loc info from declspecs!
- Diag(DeclaratorInfo.getIdentifierLoc(),
+ Diag(DS.getStorageClassSpecLoc(),
diag::err_invalid_storage_class_in_func_decl);
DS.ClearStorageClassSpecs();
break;
}
+ if (DS.isThreadSpecified()) {
+ Diag(DS.getThreadSpecLoc(),
+ diag::err_invalid_storage_class_in_func_decl);
+ DS.ClearStorageClassSpecs();
+ }
// Inform the actions module about the parameter declarator, so it gets
// added to the current scope.
Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=39224&r1=39223&r2=39224&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:41:28 2007
@@ -236,7 +236,8 @@
//__builtin_va_list
DeclSpec DS;
- bool Error = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Dummy);
+ bool Error = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, SourceLocation(),
+ Dummy);
// TODO: add a 'TST_builtin' type?
Error |= DS.SetTypeSpecType(DeclSpec::TST_int, Dummy);
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=39224&r1=39223&r2=39224&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jul 11 11:41:28 2007
@@ -117,6 +117,11 @@
// attributes.
// FIXME: implement declspec attributes.
+
+ // SourceLocation info. These are null if the item wasn't specified or if
+ // the setting was synthesized.
+ SourceLocation StorageClassSpecLoc, SCS_threadLoc;
+
public:
DeclSpec()
@@ -135,9 +140,15 @@
SCS getStorageClassSpec() const { return StorageClassSpec; }
bool isThreadSpecified() const { return SCS_thread_specified; }
+ SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; }
+ SourceLocation getThreadSpecLoc() const { return SCS_threadLoc; }
+
+
void ClearStorageClassSpecs() {
StorageClassSpec = DeclSpec::SCS_unspecified;
SCS_thread_specified = false;
+ StorageClassSpecLoc = SourceLocation();
+ SCS_threadLoc = SourceLocation();
}
// type-specifier
@@ -175,8 +186,8 @@
/// 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). The name of the previous specifier is returned in prevspec.
- bool SetStorageClassSpec(SCS S, const char *&PrevSpec);
- bool SetStorageClassSpecThread(const char *&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);
More information about the cfe-commits
mailing list