[cfe-commits] r77990 - in /cfe/trunk: include/clang/Parse/DeclSpec.h include/clang/Parse/Parser.h lib/Parse/DeclSpec.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/Parser.cpp lib/Sema/SemaDecl.cpp
John McCall
rjmccall at apple.com
Mon Aug 3 13:12:21 PDT 2009
Author: rjmccall
Date: Mon Aug 3 15:12:06 2009
New Revision: 77990
URL: http://llvm.org/viewvc/llvm-project?rev=77990&view=rev
Log:
Refactor methods on DeclSpec to take a diagnostic& parameter, and reflect this
elsewhere. Very slightly decouples DeclSpec users from knowing the exact
diagnostics to report, and makes it easier to provide different diagnostics in
some places.
Modified:
cfe/trunk/include/clang/Parse/DeclSpec.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/DeclSpec.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=77990&r1=77989&r2=77990&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Mon Aug 3 15:12:06 2009
@@ -267,27 +267,44 @@
void SetRangeStart(SourceLocation Loc) { Range.setBegin(Loc); }
void SetRangeEnd(SourceLocation Loc) { Range.setEnd(Loc); }
- /// 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, SourceLocation Loc, const char *&PrevSpec);
- bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec);
- 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);
+ /// These methods set the specified attribute of the DeclSpec and
+ /// return false if there was no error. If an error occurs (for
+ /// example, if we tried to set "auto" on a spec with "extern"
+ /// already set), they return true and set PrevSpec and DiagID
+ /// such that
+ /// Diag(Loc, DiagID) << PrevSpec;
+ /// will yield a useful result.
+ ///
+ /// TODO: use a more general approach that still allows these
+ /// diagnostics to be ignored when desired.
+ bool SetStorageClassSpec(SCS S, SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+ bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+ bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+ bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+ bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
- void *Rep = 0, bool Owned = false);
+ unsigned &DiagID, void *Rep = 0, bool Owned = false);
bool SetTypeSpecError();
void UpdateTypeRep(void *Rep) { TypeRep = Rep; }
bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
- const LangOptions &Lang);
+ unsigned &DiagID, const LangOptions &Lang);
- bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec);
- bool SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec);
- bool SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec);
+ bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+ bool SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+ bool SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
- bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec);
+ bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID);
+
bool isFriendSpecified() const { return Friend_specified; }
SourceLocation getFriendSpecLoc() const { return FriendLoc; }
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=77990&r1=77989&r2=77990&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Aug 3 15:12:06 2009
@@ -923,8 +923,9 @@
void ParseDeclarationSpecifiers(DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
AccessSpecifier AS = AS_none);
- bool ParseOptionalTypeSpecifier(DeclSpec &DS, int &isInvalid,
+ bool ParseOptionalTypeSpecifier(DeclSpec &DS, bool &isInvalid,
const char *&PrevSpec,
+ unsigned &DiagID,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
void ParseSpecifierQualifierList(DeclSpec &DS);
Modified: cfe/trunk/lib/Parse/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/DeclSpec.cpp?rev=77990&r1=77989&r2=77990&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Parse/DeclSpec.cpp Mon Aug 3 15:12:06 2009
@@ -105,8 +105,12 @@
return Res;
}
-template <class T> static bool BadSpecifier(T TPrev, const char *&PrevSpec) {
+template <class T> static bool BadSpecifier(T TNew, T TPrev,
+ const char *&PrevSpec,
+ unsigned &DiagID) {
PrevSpec = DeclSpec::getSpecifierName(TPrev);
+ DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
+ : diag::err_invalid_decl_spec_combination);
return true;
}
@@ -193,9 +197,10 @@
}
bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc,
- const char *&PrevSpec) {
+ const char *&PrevSpec,
+ unsigned &DiagID) {
if (StorageClassSpec != SCS_unspecified)
- return BadSpecifier((SCS)StorageClassSpec, PrevSpec);
+ return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID);
StorageClassSpec = S;
StorageClassSpecLoc = Loc;
assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield");
@@ -203,9 +208,11 @@
}
bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
- const char *&PrevSpec) {
+ const char *&PrevSpec,
+ unsigned &DiagID) {
if (SCS_thread_specified) {
PrevSpec = "__thread";
+ DiagID = diag::ext_duplicate_declspec;
return true;
}
SCS_thread_specified = true;
@@ -218,39 +225,46 @@
/// and ignore the request if invalid (e.g. "extern" then "auto" is
/// specified).
bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
- const char *&PrevSpec) {
+ const char *&PrevSpec,
+ unsigned &DiagID) {
if (TypeSpecWidth != TSW_unspecified &&
// Allow turning long -> long long.
(W != TSW_longlong || TypeSpecWidth != TSW_long))
- return BadSpecifier((TSW)TypeSpecWidth, PrevSpec);
+ return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
TypeSpecWidth = W;
TSWLoc = Loc;
return false;
}
bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
- const char *&PrevSpec) {
+ const char *&PrevSpec,
+ unsigned &DiagID) {
if (TypeSpecComplex != TSC_unspecified)
- return BadSpecifier((TSC)TypeSpecComplex, PrevSpec);
+ return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
TypeSpecComplex = C;
TSCLoc = Loc;
return false;
}
bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
- const char *&PrevSpec) {
+ const char *&PrevSpec,
+ unsigned &DiagID) {
if (TypeSpecSign != TSS_unspecified)
- return BadSpecifier((TSS)TypeSpecSign, PrevSpec);
+ return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
TypeSpecSign = S;
TSSLoc = Loc;
return false;
}
bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
- const char *&PrevSpec, void *Rep,
- bool Owned) {
- if (TypeSpecType != TST_unspecified)
- return BadSpecifier((TST)TypeSpecType, PrevSpec);
+ const char *&PrevSpec,
+ unsigned &DiagID,
+ void *Rep, bool Owned) {
+ if (TypeSpecType != TST_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_decl_spec_combination;
+ return true;
+ }
TypeSpecType = T;
TypeRep = Rep;
TSTLoc = Loc;
@@ -266,10 +280,10 @@
}
bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
- const LangOptions &Lang) {
+ unsigned &DiagID, const LangOptions &Lang) {
// Duplicates turn into warnings pre-C99.
if ((TypeQualifiers & T) && !Lang.C99)
- return BadSpecifier(T, PrevSpec);
+ return BadSpecifier(T, T, PrevSpec, DiagID);
TypeQualifiers |= T;
switch (T) {
@@ -281,33 +295,38 @@
return false;
}
-bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec){
+bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID) {
// 'inline inline' is ok.
FS_inline_specified = true;
FS_inlineLoc = Loc;
return false;
}
-bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec){
+bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID) {
// 'virtual virtual' is ok.
FS_virtual_specified = true;
FS_virtualLoc = Loc;
return false;
}
-bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec){
+bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID) {
// 'explicit explicit' is ok.
FS_explicit_specified = true;
FS_explicitLoc = Loc;
return false;
}
-bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec) {
+bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID) {
if (Friend_specified) {
PrevSpec = "friend";
+ DiagID = diag::ext_duplicate_declspec;
return true;
}
-
+
Friend_specified = true;
FriendLoc = Loc;
return false;
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=77990&r1=77989&r2=77990&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Aug 3 15:12:06 2009
@@ -673,7 +673,8 @@
Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
const char *PrevSpec;
- DS.SetTypeSpecType(DeclSpec::TST_error, Loc, PrevSpec);
+ unsigned DiagID;
+ DS.SetTypeSpecType(DeclSpec::TST_error, Loc, PrevSpec, DiagID);
DS.SetRangeEnd(Tok.getLocation());
ConsumeToken();
@@ -710,8 +711,10 @@
AccessSpecifier AS) {
DS.SetRangeStart(Tok.getLocation());
while (1) {
- int isInvalid = false;
+ bool isInvalid = false;
const char *PrevSpec = 0;
+ unsigned DiagID = 0;
+
SourceLocation Loc = Tok.getLocation();
switch (Tok.getKind()) {
@@ -777,7 +780,7 @@
ConsumeToken(); // The C++ scope.
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
- TypeRep);
+ DiagID, TypeRep);
if (isInvalid)
break;
@@ -790,7 +793,7 @@
case tok::annot_typename: {
if (Tok.getAnnotationValue())
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
- Tok.getAnnotationValue());
+ DiagID, Tok.getAnnotationValue());
else
DS.SetTypeSpecError();
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
@@ -846,7 +849,7 @@
goto DoneWithDeclSpec;
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
- TypeRep);
+ DiagID, TypeRep);
if (isInvalid)
break;
@@ -913,112 +916,138 @@
// storage-class-specifier
case tok::kw_typedef:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_extern:
if (DS.isThreadSpecified())
Diag(Tok, diag::ext_thread_before) << "extern";
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw___private_extern__:
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_private_extern, Loc,
- PrevSpec);
+ PrevSpec, DiagID);
break;
case tok::kw_static:
if (DS.isThreadSpecified())
Diag(Tok, diag::ext_thread_before) << "static";
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_auto:
if (getLang().CPlusPlus0x)
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
+ DiagID);
else
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_register:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_mutable:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_mutable, Loc, PrevSpec);
+ isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_mutable, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw___thread:
- isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec)*2;
+ isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID);
break;
// function-specifier
case tok::kw_inline:
- isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec);
+ isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
break;
case tok::kw_virtual:
- isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec);
+ isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec, DiagID);
break;
case tok::kw_explicit:
- isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec);
+ isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID);
break;
// friend
case tok::kw_friend:
- isInvalid = DS.SetFriendSpec(Loc, PrevSpec);
+ isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
break;
-
+
// type-specifier
case tok::kw_short:
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_long:
if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
+ DiagID);
else
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_signed:
- isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_unsigned:
- isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw__Complex:
- isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw__Imaginary:
- isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_void:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_char:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_int:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_float:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_double:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_wchar_t:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_char16_t:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_char32_t:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_bool:
case tok::kw__Bool:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw__Decimal32:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw__Decimal64:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw__Decimal128:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
+ DiagID);
break;
// class-specifier:
@@ -1039,15 +1068,16 @@
// cv-qualifier:
case tok::kw_const:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec,getLang())*2;
+ isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
+ getLang());
break;
case tok::kw_volatile:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
- getLang())*2;
+ isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
+ getLang());
break;
case tok::kw_restrict:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
- getLang())*2;
+ isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
+ getLang());
break;
// C++ typename-specifier:
@@ -1087,12 +1117,10 @@
continue;
}
}
- // If the specifier combination wasn't legal, issue a diagnostic.
+ // If the specifier wasn't legal, issue a diagnostic.
if (isInvalid) {
assert(PrevSpec && "Method did not return previous specifier!");
- // Pick between error or extwarn.
- unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
- : diag::ext_duplicate_declspec;
+ assert(DiagID);
Diag(Tok, DiagID) << PrevSpec;
}
DS.SetRangeEnd(Tok.getLocation());
@@ -1143,8 +1171,9 @@
/// [OBJC] class-name objc-protocol-refs[opt] [TODO]
/// [OBJC] typedef-name objc-protocol-refs[opt] [TODO]
/// [C++0x] 'decltype' ( expression )
-bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
+bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
const char *&PrevSpec,
+ unsigned &DiagID,
const ParsedTemplateInfo &TemplateInfo) {
SourceLocation Loc = Tok.getLocation();
@@ -1154,7 +1183,8 @@
// Annotate typenames and C++ scope specifiers. If we get one, just
// recurse to handle whatever we get.
if (TryAnnotateTypeOrScopeToken())
- return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, TemplateInfo);
+ return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
+ TemplateInfo);
// Otherwise, not a type specifier.
return false;
case tok::coloncolon: // ::foo::bar
@@ -1165,7 +1195,8 @@
// Annotate typenames and C++ scope specifiers. If we get one, just
// recurse to handle whatever we get.
if (TryAnnotateTypeOrScopeToken())
- return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, TemplateInfo);
+ return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
+ TemplateInfo);
// Otherwise, not a type specifier.
return false;
@@ -1173,7 +1204,7 @@
case tok::annot_typename: {
if (Tok.getAnnotationValue())
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
- Tok.getAnnotationValue());
+ DiagID, Tok.getAnnotationValue());
else
DS.SetTypeSpecError();
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
@@ -1196,62 +1227,70 @@
}
case tok::kw_short:
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID);
break;
case tok::kw_long:
if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
+ DiagID);
else
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_signed:
- isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
break;
case tok::kw_unsigned:
- isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw__Complex:
- isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw__Imaginary:
- isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw_void:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID);
break;
case tok::kw_char:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID);
break;
case tok::kw_int:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
break;
case tok::kw_float:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID);
break;
case tok::kw_double:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID);
break;
case tok::kw_wchar_t:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID);
break;
case tok::kw_char16_t:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID);
break;
case tok::kw_char32_t:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID);
break;
case tok::kw_bool:
case tok::kw__Bool:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID);
break;
case tok::kw__Decimal32:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw__Decimal64:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
+ DiagID);
break;
case tok::kw__Decimal128:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
+ DiagID);
break;
// class-specifier:
@@ -1273,15 +1312,15 @@
// cv-qualifier:
case tok::kw_const:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
- getLang())*2;
+ DiagID, getLang());
break;
case tok::kw_volatile:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
- getLang())*2;
+ DiagID, getLang());
break;
case tok::kw_restrict:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
- getLang())*2;
+ DiagID, getLang());
break;
// GNU typeof support.
@@ -1299,7 +1338,7 @@
if (!getLang().CPlusPlus0x)
return false;
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec);
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, DiagID);
break;
case tok::kw___ptr64:
case tok::kw___w64:
@@ -1318,8 +1357,6 @@
if (isInvalid) {
assert(PrevSpec && "Method did not return previous specifier!");
// Pick between error or extwarn.
- unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
- : diag::ext_duplicate_declspec;
Diag(Tok, DiagID) << PrevSpec;
}
DS.SetRangeEnd(Tok.getLocation());
@@ -1595,9 +1632,10 @@
// TODO: semantic analysis on the declspec for enums.
const char *PrevSpec = 0;
- if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec,
+ unsigned DiagID;
+ if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec, DiagID,
TagDecl.getAs<void>(), Owned))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+ Diag(StartLoc, DiagID) << PrevSpec;
}
/// ParseEnumBody - Parse a {} enclosed enumerator-list.
@@ -1883,22 +1921,23 @@
///
void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool AttributesAllowed) {
while (1) {
- int isInvalid = false;
+ bool isInvalid = false;
const char *PrevSpec = 0;
+ unsigned DiagID = 0;
SourceLocation Loc = Tok.getLocation();
switch (Tok.getKind()) {
case tok::kw_const:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
- getLang())*2;
+ isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
+ getLang());
break;
case tok::kw_volatile:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
- getLang())*2;
+ isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
+ getLang());
break;
case tok::kw_restrict:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
- getLang())*2;
+ isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
+ getLang());
break;
case tok::kw___w64:
case tok::kw___ptr64:
@@ -1927,9 +1966,6 @@
// If the specifier combination wasn't legal, issue a diagnostic.
if (isInvalid) {
assert(PrevSpec && "Method did not return previous specifier!");
- // Pick between error or extwarn.
- unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
- : diag::ext_duplicate_declspec;
Diag(Tok, DiagID) << PrevSpec;
}
ConsumeToken();
@@ -2831,10 +2867,11 @@
}
const char *PrevSpec = 0;
+ unsigned DiagID;
// Check for duplicate type specifiers (e.g. "int typeof(int)").
if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
- CastTy))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+ DiagID, CastTy))
+ Diag(StartLoc, DiagID) << PrevSpec;
return;
}
@@ -2845,8 +2882,9 @@
}
const char *PrevSpec = 0;
+ unsigned DiagID;
// Check for duplicate type specifiers (e.g. "int typeof(int)").
if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
- Operand.release()))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+ DiagID, Operand.release()))
+ Diag(StartLoc, DiagID) << PrevSpec;
}
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=77990&r1=77989&r2=77990&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Aug 3 15:12:06 2009
@@ -410,10 +410,11 @@
return;
const char *PrevSpec = 0;
+ unsigned DiagID;
// Check for duplicate type specifiers (e.g. "int decltype(a)").
if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
- Result.release()))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+ DiagID, Result.release()))
+ Diag(StartLoc, DiagID) << PrevSpec;
}
/// ParseClassName - Parse a C++ class-name, which names a class. Note
@@ -716,15 +717,16 @@
Diag(Tok, diag::err_expected_lbrace);
}
- const char *PrevSpec = 0;
if (TagOrTempResult.isInvalid()) {
DS.SetTypeSpecError();
return;
}
- if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec,
+ const char *PrevSpec = 0;
+ unsigned DiagID;
+ if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, DiagID,
TagOrTempResult.get().getAs<void>(), Owned))
- Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+ Diag(StartLoc, DiagID) << PrevSpec;
if (DS.isFriendSpecified())
Actions.ActOnFriendDecl(CurScope, DS.getFriendSpecLoc(),
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=77990&r1=77989&r2=77990&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Aug 3 15:12:06 2009
@@ -610,6 +610,7 @@
void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
DS.SetRangeStart(Tok.getLocation());
const char *PrevSpec;
+ unsigned DiagID;
SourceLocation Loc = Tok.getLocation();
switch (Tok.getKind()) {
@@ -622,50 +623,50 @@
// type-name
case tok::annot_typename: {
- DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
+ DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
Tok.getAnnotationValue());
break;
}
// builtin types
case tok::kw_short:
- DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
+ DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID);
break;
case tok::kw_long:
- DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
+ DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID);
break;
case tok::kw_signed:
- DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
+ DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
break;
case tok::kw_unsigned:
- DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
+ DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID);
break;
case tok::kw_void:
- DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
+ DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID);
break;
case tok::kw_char:
- DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
+ DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID);
break;
case tok::kw_int:
- DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
+ DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
break;
case tok::kw_float:
- DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
+ DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID);
break;
case tok::kw_double:
- DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
+ DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID);
break;
case tok::kw_wchar_t:
- DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
+ DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID);
break;
case tok::kw_char16_t:
- DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec);
+ DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID);
break;
case tok::kw_char32_t:
- DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec);
+ DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID);
break;
case tok::kw_bool:
- DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
+ DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID);
break;
// GNU typeof support.
@@ -696,15 +697,16 @@
bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
DS.SetRangeStart(Tok.getLocation());
const char *PrevSpec = 0;
- int isInvalid = 0;
+ unsigned DiagID;
+ bool isInvalid = 0;
// Parse one or more of the type specifiers.
- if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) {
+ if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) {
Diag(Tok, diag::err_operator_missing_type_specifier);
return true;
}
- while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) ;
+ while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) ;
return false;
}
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=77990&r1=77989&r2=77990&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon Aug 3 15:12:06 2009
@@ -522,8 +522,9 @@
return DeclGroupPtrTy();
}
const char *PrevSpec = 0;
- if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec))
- Diag(AtLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+ unsigned DiagID;
+ if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID))
+ Diag(AtLoc, DiagID) << PrevSpec;
DeclPtrTy TheDecl;
if (Tok.isObjCAtKeyword(tok::objc_protocol))
@@ -619,9 +620,10 @@
// declaration-specifiers are completely optional in the grammar.
if (getLang().ImplicitInt && D.getDeclSpec().isEmpty()) {
const char *PrevSpec;
+ unsigned DiagID;
D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int,
D.getIdentifierLoc(),
- PrevSpec);
+ PrevSpec, DiagID);
D.SetRangeBegin(D.getDeclSpec().getSourceRange().getBegin());
}
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=77990&r1=77989&r2=77990&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Aug 3 15:12:06 2009
@@ -1394,6 +1394,7 @@
bool Invalid = false;
if (getLangOptions().CPlusPlus) {
const char* PrevSpec = 0;
+ unsigned DiagID;
// C++ [class.union]p3:
// Anonymous unions declared in a named namespace or in the
// global namespace shall be declared static.
@@ -1405,7 +1406,8 @@
Invalid = true;
// Recover by adding 'static'.
- DS.SetStorageClassSpec(DeclSpec::SCS_static, SourceLocation(), PrevSpec);
+ DS.SetStorageClassSpec(DeclSpec::SCS_static, SourceLocation(),
+ PrevSpec, DiagID);
}
// C++ [class.union]p3:
// A storage class is not allowed in a declaration of an
@@ -1418,7 +1420,7 @@
// Recover by removing the storage specifier.
DS.SetStorageClassSpec(DeclSpec::SCS_unspecified, SourceLocation(),
- PrevSpec);
+ PrevSpec, DiagID);
}
// C++ [class.union]p2:
@@ -3434,8 +3436,9 @@
// type.
DeclSpec DS;
const char* PrevSpec; // unused
+ unsigned DiagID; // unused
DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc,
- PrevSpec);
+ PrevSpec, DiagID);
Declarator ParamD(DS, Declarator::KNRTypeListContext);
ParamD.SetIdentifier(FTI.ArgInfo[i].Ident, FTI.ArgInfo[i].IdentLoc);
FTI.ArgInfo[i].Param = ActOnParamDeclarator(S, ParamD);
@@ -3688,7 +3691,8 @@
// Set a Declarator for the implicit definition: int foo();
const char *Dummy;
DeclSpec DS;
- bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy);
+ unsigned DiagID;
+ bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID);
Error = Error; // Silence warning.
assert(!Error && "Error setting up implicit decl!");
Declarator D(DS, Declarator::BlockContext);
More information about the cfe-commits
mailing list