[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