Fix a layering oddity by passing Sema to DeclSpec::Finish instead of DiagnosticsEngine and Preprocessor. Everything the preprocessor was being used for can be acquired from Sema.

llvm-svn: 253158
This commit is contained in:
Craig Topper 2015-11-15 03:32:11 +00:00
parent e69b043088
commit 2512241b31
4 changed files with 48 additions and 58 deletions

View File

@ -41,14 +41,12 @@ namespace clang {
class CXXRecordDecl;
class TypeLoc;
class LangOptions;
class DiagnosticsEngine;
class IdentifierInfo;
class NamespaceAliasDecl;
class NamespaceDecl;
class NestedNameSpecifier;
class NestedNameSpecifierLoc;
class ObjCDeclSpec;
class Preprocessor;
class Sema;
class Declarator;
struct TemplateIdAnnotation;
@ -744,8 +742,7 @@ public:
/// 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(DiagnosticsEngine &D, Preprocessor &PP,
const PrintingPolicy &Policy);
void Finish(Sema &S, const PrintingPolicy &Policy);
const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
return writtenBS;

View File

@ -2671,7 +2671,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// If this is not a declaration specifier token, we're done reading decl
// specifiers. First verify that DeclSpec's are consistent.
DS.Finish(Diags, PP, Policy);
DS.Finish(Actions, Policy);
return;
case tok::l_square:
@ -4821,7 +4821,7 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs,
DoneWithTypeQuals:
// If this is not a type-qualifier token, we're done reading type
// qualifiers. First verify that DeclSpec's are consistent.
DS.Finish(Diags, PP, Actions.getASTContext().getPrintingPolicy());
DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());
if (EndLoc.isValid())
DS.SetRangeEnd(EndLoc);
return;

View File

@ -1821,7 +1821,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
ConsumeToken();
DS.Finish(Diags, PP, Policy);
DS.Finish(Actions, Policy);
return;
}
@ -1877,12 +1877,12 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
case tok::annot_decltype:
case tok::kw_decltype:
DS.SetRangeEnd(ParseDecltypeSpecifier(DS));
return DS.Finish(Diags, PP, Policy);
return DS.Finish(Actions, Policy);
// GNU typeof support.
case tok::kw_typeof:
ParseTypeofSpecifier(DS);
DS.Finish(Diags, PP, Policy);
DS.Finish(Actions, Policy);
return;
}
if (Tok.is(tok::annot_typename))
@ -1890,7 +1890,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
else
DS.SetRangeEnd(Tok.getLocation());
ConsumeToken();
DS.Finish(Diags, PP, Policy);
DS.Finish(Actions, Policy);
}
/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
@ -1906,7 +1906,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
///
bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
ParseSpecifierQualifierList(DS, AS_none, DSC_type_specifier);
DS.Finish(Diags, PP, Actions.getASTContext().getPrintingPolicy());
DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());
return false;
}

View File

@ -19,7 +19,6 @@
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/LocInfoType.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Sema.h"
@ -31,12 +30,6 @@
using namespace clang;
static DiagnosticBuilder Diag(DiagnosticsEngine &D, SourceLocation Loc,
unsigned DiagID) {
return D.Report(Loc, DiagID);
}
void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
assert(TemplateId && "NULL template-id annotation?");
Kind = IK_TemplateId;
@ -932,7 +925,7 @@ void DeclSpec::SaveWrittenBuiltinSpecs() {
/// "_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(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPolicy &Policy) {
void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
// Before possibly changing their values, save specs as written.
SaveWrittenBuiltinSpecs();
@ -955,8 +948,8 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
for (unsigned I = 0; I != NumLocs; ++I) {
if (ExtraLocs[I].isValid()) {
if (FirstLoc.isInvalid() ||
PP.getSourceManager().isBeforeInTranslationUnit(ExtraLocs[I],
FirstLoc))
S.getSourceManager().isBeforeInTranslationUnit(ExtraLocs[I],
FirstLoc))
FirstLoc = ExtraLocs[I];
Hints[I] = FixItHint::CreateRemoval(ExtraLocs[I]);
}
@ -966,7 +959,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
TypeSpecSign = TSS_unspecified;
TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false;
TypeQualifiers = 0;
Diag(D, TSTLoc, diag::err_decltype_auto_cannot_be_combined)
S.Diag(TSTLoc, diag::err_decltype_auto_cannot_be_combined)
<< Hints[0] << Hints[1] << Hints[2] << Hints[3]
<< Hints[4] << Hints[5] << Hints[6] << Hints[7];
}
@ -976,14 +969,14 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
if (TypeAltiVecBool) {
// Sign specifiers are not allowed with vector bool. (PIM 2.1)
if (TypeSpecSign != TSS_unspecified) {
Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec)
S.Diag(TSSLoc, diag::err_invalid_vector_bool_decl_spec)
<< getSpecifierName((TSS)TypeSpecSign);
}
// Only char/int are valid with vector bool. (PIM 2.1)
if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
(TypeSpecType != TST_int)) || TypeAltiVecPixel) {
Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec)
S.Diag(TSTLoc, diag::err_invalid_vector_bool_decl_spec)
<< (TypeAltiVecPixel ? "__pixel" :
getSpecifierName((TST)TypeSpecType, Policy));
}
@ -991,15 +984,15 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
// Only 'short' and 'long long' are valid with vector bool. (PIM 2.1)
if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short) &&
(TypeSpecWidth != TSW_longlong))
Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
S.Diag(TSWLoc, diag::err_invalid_vector_bool_decl_spec)
<< getSpecifierName((TSW)TypeSpecWidth);
// vector bool long long requires VSX support or ZVector.
if ((TypeSpecWidth == TSW_longlong) &&
(!PP.getTargetInfo().hasFeature("vsx")) &&
(!PP.getTargetInfo().hasFeature("power8-vector")) &&
!PP.getLangOpts().ZVector)
Diag(D, TSTLoc, diag::err_invalid_vector_long_long_decl_spec);
(!S.Context.getTargetInfo().hasFeature("vsx")) &&
(!S.Context.getTargetInfo().hasFeature("power8-vector")) &&
!S.getLangOpts().ZVector)
S.Diag(TSTLoc, diag::err_invalid_vector_long_long_decl_spec);
// Elements of vector bool are interpreted as unsigned. (PIM 2.1)
if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
@ -1009,20 +1002,20 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
// vector long double and vector long long double are never allowed.
// vector double is OK for Power7 and later, and ZVector.
if (TypeSpecWidth == TSW_long || TypeSpecWidth == TSW_longlong)
Diag(D, TSWLoc, diag::err_invalid_vector_long_double_decl_spec);
else if (!PP.getTargetInfo().hasFeature("vsx") &&
!PP.getLangOpts().ZVector)
Diag(D, TSTLoc, diag::err_invalid_vector_double_decl_spec);
S.Diag(TSWLoc, diag::err_invalid_vector_long_double_decl_spec);
else if (!S.Context.getTargetInfo().hasFeature("vsx") &&
!S.getLangOpts().ZVector)
S.Diag(TSTLoc, diag::err_invalid_vector_double_decl_spec);
} else if (TypeSpecType == TST_float) {
// vector float is unsupported for ZVector.
if (PP.getLangOpts().ZVector)
Diag(D, TSTLoc, diag::err_invalid_vector_float_decl_spec);
if (S.getLangOpts().ZVector)
S.Diag(TSTLoc, diag::err_invalid_vector_float_decl_spec);
} else if (TypeSpecWidth == TSW_long) {
// vector long is unsupported for ZVector and deprecated for AltiVec.
if (PP.getLangOpts().ZVector)
Diag(D, TSWLoc, diag::err_invalid_vector_long_decl_spec);
if (S.getLangOpts().ZVector)
S.Diag(TSWLoc, diag::err_invalid_vector_long_decl_spec);
else
Diag(D, TSWLoc, diag::warn_vector_long_decl_spec_combination)
S.Diag(TSWLoc, diag::warn_vector_long_decl_spec_combination)
<< getSpecifierName((TST)TypeSpecType, Policy);
}
@ -1041,7 +1034,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 &&
TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
Diag(D, TSSLoc, diag::err_invalid_sign_spec)
S.Diag(TSSLoc, diag::err_invalid_sign_spec)
<< getSpecifierName((TST)TypeSpecType, Policy);
// signed double -> double.
TypeSpecSign = TSS_unspecified;
@ -1056,7 +1049,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
if (TypeSpecType == TST_unspecified)
TypeSpecType = TST_int; // short -> short int, long long -> long long int.
else if (TypeSpecType != TST_int) {
Diag(D, TSWLoc, diag::err_invalid_width_spec) << (int)TypeSpecWidth
S.Diag(TSWLoc, diag::err_invalid_width_spec) << (int)TypeSpecWidth
<< getSpecifierName((TST)TypeSpecType, Policy);
TypeSpecType = TST_int;
TypeSpecOwned = false;
@ -1066,7 +1059,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
if (TypeSpecType == TST_unspecified)
TypeSpecType = TST_int; // long -> long int.
else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
Diag(D, TSWLoc, diag::err_invalid_width_spec) << (int)TypeSpecWidth
S.Diag(TSWLoc, diag::err_invalid_width_spec) << (int)TypeSpecWidth
<< getSpecifierName((TST)TypeSpecType, Policy);
TypeSpecType = TST_int;
TypeSpecOwned = false;
@ -1078,17 +1071,17 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
// disallow their use. Need information about the backend.
if (TypeSpecComplex != TSC_unspecified) {
if (TypeSpecType == TST_unspecified) {
Diag(D, TSCLoc, diag::ext_plain_complex)
S.Diag(TSCLoc, diag::ext_plain_complex)
<< FixItHint::CreateInsertion(
PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
S.getLocForEndOfToken(getTypeSpecComplexLoc()),
" double");
TypeSpecType = TST_double; // _Complex -> _Complex double.
} else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
// Note that this intentionally doesn't include _Complex _Bool.
if (!PP.getLangOpts().CPlusPlus)
Diag(D, TSTLoc, diag::ext_integer_complex);
if (!S.getLangOpts().CPlusPlus)
S.Diag(TSTLoc, diag::ext_integer_complex);
} else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
Diag(D, TSCLoc, diag::err_invalid_complex_spec)
S.Diag(TSCLoc, diag::err_invalid_complex_spec)
<< getSpecifierName((TST)TypeSpecType, Policy);
TypeSpecComplex = TSC_unspecified;
}
@ -1105,14 +1098,14 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
case SCS_static:
break;
default:
if (PP.getSourceManager().isBeforeInTranslationUnit(
if (S.getSourceManager().isBeforeInTranslationUnit(
getThreadStorageClassSpecLoc(), getStorageClassSpecLoc()))
Diag(D, getStorageClassSpecLoc(),
S.Diag(getStorageClassSpecLoc(),
diag::err_invalid_decl_spec_combination)
<< DeclSpec::getSpecifierName(getThreadStorageClassSpec())
<< SourceRange(getThreadStorageClassSpecLoc());
else
Diag(D, getThreadStorageClassSpecLoc(),
S.Diag(getThreadStorageClassSpecLoc(),
diag::err_invalid_decl_spec_combination)
<< DeclSpec::getSpecifierName(getStorageClassSpec())
<< SourceRange(getStorageClassSpecLoc());
@ -1126,7 +1119,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
// the type specifier is not optional, but we got 'auto' as a storage
// class specifier, then assume this is an attempt to use C++0x's 'auto'
// type specifier.
if (PP.getLangOpts().CPlusPlus &&
if (S.getLangOpts().CPlusPlus &&
TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
TypeSpecType = TST_auto;
StorageClassSpec = SCS_unspecified;
@ -1135,17 +1128,17 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
}
// Diagnose if we've recovered from an ill-formed 'auto' storage class
// specifier in a pre-C++11 dialect of C++.
if (!PP.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto)
Diag(D, TSTLoc, diag::ext_auto_type_specifier);
if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus11 &&
if (!S.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto)
S.Diag(TSTLoc, diag::ext_auto_type_specifier);
if (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11 &&
StorageClassSpec == SCS_auto)
Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class)
S.Diag(StorageClassSpecLoc, diag::warn_auto_storage_class)
<< FixItHint::CreateRemoval(StorageClassSpecLoc);
if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type)
S.Diag(TSTLoc, diag::warn_cxx98_compat_unicode_type)
<< (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
if (Constexpr_specified)
Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr);
S.Diag(ConstexprLoc, diag::warn_cxx98_compat_constexpr);
// C++ [class.friend]p6:
// No storage-class-specifier shall appear in the decl-specifier-seq
@ -1169,7 +1162,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
ThreadHint = FixItHint::CreateRemoval(SCLoc);
}
Diag(D, SCLoc, diag::err_friend_decl_spec)
S.Diag(SCLoc, diag::err_friend_decl_spec)
<< SpecName << StorageHint << ThreadHint;
ClearStorageClassSpecs();
@ -1195,7 +1188,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli
}
FixItHint Hint = FixItHint::CreateRemoval(SCLoc);
Diag(D, SCLoc, diag::err_friend_decl_spec)
S.Diag(SCLoc, diag::err_friend_decl_spec)
<< Keyword << Hint;
FS_virtual_specified = FS_explicit_specified = false;