[cfe-commits] r38811 - in /cfe/cfe/trunk: Parse/DeclSpec.cpp Parse/ParseDecl.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/DeclSpec.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:24:51 PDT 2007
Author: sabre
Date: Wed Jul 11 11:24:50 2007
New Revision: 38811
URL: http://llvm.org/viewvc/llvm-project?rev=38811&view=rev
Log:
Emit diagnostics for things like 'signed _Bool' and 'short float'
Modified:
cfe/cfe/trunk/Parse/DeclSpec.cpp
cfe/cfe/trunk/Parse/ParseDecl.cpp
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
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=38811&r1=38810&r2=38811&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/DeclSpec.cpp (original)
+++ cfe/cfe/trunk/Parse/DeclSpec.cpp Wed Jul 11 11:24:50 2007
@@ -13,6 +13,7 @@
#include "clang/Parse/Declarations.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
using namespace llvm;
using namespace clang;
@@ -67,19 +68,24 @@
return true;
}
-static bool BadSpecifier(DeclSpec::TST T, const char *&PrevSpec) {
+static const char *getSpecifierName(DeclSpec::TST T) {
switch (T) {
- case DeclSpec::TST_unspecified: PrevSpec = "unspecified"; break;
- case DeclSpec::TST_void: PrevSpec = "void"; break;
- case DeclSpec::TST_char: PrevSpec = "char"; break;
- case DeclSpec::TST_int: PrevSpec = "int"; break;
- case DeclSpec::TST_float: PrevSpec = "float"; break;
- case DeclSpec::TST_double: PrevSpec = "double"; break;
- case DeclSpec::TST_bool: PrevSpec = "_Bool"; break;
- case DeclSpec::TST_decimal32: PrevSpec = "_Decimal32"; break;
- case DeclSpec::TST_decimal64: PrevSpec = "_Decimal64"; break;
- case DeclSpec::TST_decimal128: PrevSpec = "_Decimal128"; break;
+ default: assert(0 && "Unknown typespec!");
+ case DeclSpec::TST_unspecified: return "unspecified";
+ case DeclSpec::TST_void: return "void";
+ case DeclSpec::TST_char: return "char";
+ case DeclSpec::TST_int: return "int";
+ case DeclSpec::TST_float: return "float";
+ case DeclSpec::TST_double: return "double";
+ case DeclSpec::TST_bool: return "_Bool";
+ case DeclSpec::TST_decimal32: return "_Decimal32";
+ case DeclSpec::TST_decimal64: return "_Decimal64";
+ case DeclSpec::TST_decimal128: return "_Decimal128";
}
+}
+
+static bool BadSpecifier(DeclSpec::TST T, const char *&PrevSpec) {
+ PrevSpec = getSpecifierName(T);
return true;
}
@@ -143,8 +149,38 @@
/// "_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.
-diag::kind DeclSpec::Finish(const LangOptions &Lang) {
- // FIXME: implement this.
+void DeclSpec::Finish(SourceLocation Loc, Diagnostic &D,
+ const LangOptions &Lang) {
+ // signed/unsigned are not valid with void,float,double,bool,decimal*.
+ if (TypeSpecSign != TSS_unspecified) {
+ if (TypeSpecType == TST_void || TypeSpecType == TST_float ||
+ TypeSpecType == TST_double || TypeSpecType == TST_bool ||
+ TypeSpecType == TST_decimal32 || TypeSpecType == TST_decimal64 ||
+ TypeSpecType == TST_decimal128) {
+ D.Report(Loc, diag::err_invalid_sign_spec,getSpecifierName(TypeSpecType));
+ TypeSpecSign = TSS_unspecified;
+ }
+ }
+
+ // Validate the width of the type.
+ switch (TypeSpecWidth) {
+ case TSW_unspecified: break;
+ case TSW_short: // short int
+ case TSW_longlong: // long long int
+ if (TypeSpecType != TST_unspecified && TypeSpecType != TST_int) {
+ D.Report(Loc, TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec :
+ diag::err_invalid_longlong_spec,
+ getSpecifierName(TypeSpecType));
+ TypeSpecType = TST_int;
+ }
+ break;
+ case TSW_long: // long double, long int
+ if (TypeSpecType != TST_unspecified && TypeSpecType != TST_int &&
+ TypeSpecType != TST_double) {
+ D.Report(Loc, diag::err_invalid_long_spec,
+ getSpecifierName(TypeSpecType));
+ TypeSpecType = TST_int;
+ }
+ }
- return diag::NUM_DIAGNOSTICS;
}
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=38811&r1=38810&r2=38811&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:24:50 2007
@@ -28,7 +28,7 @@
/// [C99] function-specifier declaration-specifiers [opt]
/// [GNU] attributes declaration-specifiers [opt] [TODO]
///
-/// storage-class-specifier: [C99 6.7.1]
+/// storage-class-specifier: [C99 6.7.1] [TODO]
/// 'typedef'
/// 'extern'
/// 'static'
@@ -73,9 +73,7 @@
default:
// If this is not a declaration specifier token, we're done reading decl
// specifiers. First verify that DeclSpec's are consistent.
- diag::kind Res = DS.Finish(getLang());
- if (Res != diag::NUM_DIAGNOSTICS)
- Diag(StartLoc, Res);
+ DS.Finish(StartLoc, Diags, getLang());
return;
// type-specifiers
case tok::kw_short:
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38811&r1=38810&r2=38811&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:24:50 2007
@@ -243,5 +243,13 @@
DIAG(err_invalid_decl_spec_combination, ERROR,
"cannot combine declaration specifier with previous '%s' specifier")
+DIAG(err_invalid_sign_spec, ERROR,
+ "'%s' cannot be signed or unsigned")
+DIAG(err_invalid_short_spec, ERROR,
+ "'short %s' is invalid")
+DIAG(err_invalid_long_spec, ERROR,
+ "'long %s' is invalid")
+DIAG(err_invalid_longlong_spec, ERROR,
+ "'long long %s' is invalid")
#undef DIAG
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=38811&r1=38810&r2=38811&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jul 11 11:24:50 2007
@@ -19,6 +19,7 @@
namespace llvm {
namespace clang {
class LangOptions;
+ class SourceLocation;
/// DeclSpec - This class captures information about "declaration specifiers",
/// which encompases storage-class-specifiers, type-specifiers, type-qualifiers,
@@ -121,11 +122,10 @@
bool SetTypeQual(TQ T, const char *&PrevSpec, const LangOptions &Lang);
- /// Finish - This does final analysis of the declspec, rejecting things like
- /// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
- /// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
+ /// 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.
- diag::kind Finish(const LangOptions &Lang);
+ void Finish(SourceLocation Loc, Diagnostic &D,const LangOptions &Lang);
};
} // end namespace clang
More information about the cfe-commits
mailing list