зеркало из https://github.com/microsoft/clang-1.git
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77990 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
d1e1ef3b0a
Коммит
fec54013fc
|
@ -267,27 +267,44 @@ public:
|
|||
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; }
|
||||
|
||||
|
|
|
@ -923,8 +923,9 @@ private:
|
|||
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);
|
||||
|
|
|
@ -105,8 +105,12 @@ unsigned DeclSpec::getParsedSpecifiers() const {
|
|||
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 @@ const char *DeclSpec::getSpecifierName(TQ T) {
|
|||
}
|
||||
|
||||
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::SetStorageClassSpec(SCS S, SourceLocation Loc,
|
|||
}
|
||||
|
||||
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 @@ bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
|
|||
/// 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::SetTypeSpecError() {
|
|||
}
|
||||
|
||||
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 @@ bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
|
|||
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;
|
||||
|
|
|
@ -673,7 +673,8 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
|
|||
|
||||
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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
ConsumeToken(); // The C++ scope.
|
||||
|
||||
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
|
||||
TypeRep);
|
||||
DiagID, TypeRep);
|
||||
if (isInvalid)
|
||||
break;
|
||||
|
||||
|
@ -790,7 +793,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
goto DoneWithDeclSpec;
|
||||
|
||||
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
|
||||
TypeRep);
|
||||
DiagID, TypeRep);
|
||||
if (isInvalid)
|
||||
break;
|
||||
|
||||
|
@ -913,112 +916,138 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
|
||||
// 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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
|
||||
// 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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
/// [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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
|
|||
// 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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
|
|||
// 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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
|
|||
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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
|
|||
}
|
||||
|
||||
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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
|
|||
// 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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
|
|||
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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
|
|||
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 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
|||
|
||||
// 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 @@ bool Parser::isDeclarationSpecifier() {
|
|||
///
|
||||
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 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool AttributesAllowed) {
|
|||
// 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 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
|
|||
}
|
||||
|
||||
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 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -410,10 +410,11 @@ void Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
|
|||
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 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
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(),
|
||||
|
|
|
@ -610,6 +610,7 @@ Parser::OwningExprResult Parser::ParseCXXCondition() {
|
|||
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 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
|
|||
|
||||
// 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 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -522,8 +522,9 @@ Parser::ParseDeclarationOrFunctionDefinition(AccessSpecifier AS) {
|
|||
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 @@ Parser::DeclPtrTy Parser::ParseFunctionDefinition(Declarator &D,
|
|||
// 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());
|
||||
}
|
||||
|
||||
|
|
|
@ -1394,6 +1394,7 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
|
|||
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 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
|
|||
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 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
|
|||
|
||||
// Recover by removing the storage specifier.
|
||||
DS.SetStorageClassSpec(DeclSpec::SCS_unspecified, SourceLocation(),
|
||||
PrevSpec);
|
||||
PrevSpec, DiagID);
|
||||
}
|
||||
|
||||
// C++ [class.union]p2:
|
||||
|
@ -3434,8 +3436,9 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
|
|||
// 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 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
|
|||
// 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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче