[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