From 2d7346dc6e4ad6dea65ec6892afe974def223c0e Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 15 Nov 2015 03:32:11 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@253158 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/DeclSpec.h | 5 +- lib/Parse/ParseDecl.cpp | 4 +- lib/Parse/ParseExprCXX.cpp | 10 ++-- lib/Sema/DeclSpec.cpp | 87 ++++++++++++++++------------------- 4 files changed, 48 insertions(+), 58 deletions(-) diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 7bce0cdcfc..8f1543667e 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -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; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index d26f99560f..0c6e8bd453 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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; diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 229b76adde..477594b5a1 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -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; } diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index a503962876..9eb6f5f5d1 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -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; -- 2.40.0