From: Douglas Gregor Date: Wed, 24 Oct 2012 15:17:15 +0000 (+0000) Subject: Serialize DiagnosticOptions to the AST file. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f3d8224af99ad0d9107601c0c31b74693371cc1;p=clang Serialize DiagnosticOptions to the AST file. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166572 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticOptions.def b/include/clang/Basic/DiagnosticOptions.def index 600ed0357d..14b8abfffa 100644 --- a/include/clang/Basic/DiagnosticOptions.def +++ b/include/clang/Basic/DiagnosticOptions.def @@ -11,7 +11,9 @@ // must define the DIAGOPT macro to make use of this information. // Optionally, the user may also define ENUM_DIAGOPT (for options // that have enumeration type and VALUE_DIAGOPT (for options that -// describe a value rather than a flag). +// describe a value rather than a flag). The SEMANTIC_* variants of these macros +// indicate options that affect the processing of the program, rather than +// simply the output. // //===----------------------------------------------------------------------===// #ifndef DIAGOPT @@ -28,7 +30,21 @@ DIAGOPT(Name, Bits, Default) DIAGOPT(Name, Bits, Default) #endif -DIAGOPT(IgnoreWarnings, 1, 0) /// -w +#ifndef SEMANTIC_DIAGOPT +# define SEMANTIC_DIAGOPT(Name, Bits, Default) DIAGOPT(Name, Bits, Default) +#endif + +#ifndef SEMANTIC_VALUE_DIAGOPT +# define SEMANTIC_VALUE_DIAGOPT(Name, Bits, Default) \ + VALUE_DIAGOPT(Name, Bits, Default) +#endif + +#ifndef SEMANTIC_ENUM_DIAGOPT +# define SEMANTIC_ENUM_DIAGOPT(Name, Type, Bits, Default) \ + ENUM_DIAGOPT(Name, Type, Bits, Default) +#endif + +SEMANTIC_DIAGOPT(IgnoreWarnings, 1, 0) /// -w DIAGOPT(NoRewriteMacros, 1, 0) /// -Wno-rewrite-macros DIAGOPT(Pedantic, 1, 0) /// -pedantic DIAGOPT(PedanticErrors, 1, 0) /// -pedantic-errors @@ -50,12 +66,27 @@ DIAGOPT(ShowColors, 1, 0) /// Show diagnostics with ANSI color sequences. ENUM_DIAGOPT(ShowOverloads, OverloadsShown, 1, Ovl_All) /// Overload candidates to show. DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected - /// diagnostics, indicated by markers in the - /// input source file. + /// diagnostics, indicated by markers in the + /// input source file. DIAGOPT(ElideType, 1, 0) /// Elide identical types in template diffing DIAGOPT(ShowTemplateTree, 1, 0) /// Print a template tree when diffing +VALUE_DIAGOPT(ErrorLimit, 32, 0) /// Limit # errors emitted. +/// Limit depth of macro expansion backtrace. +VALUE_DIAGOPT(MacroBacktraceLimit, 32, DefaultMacroBacktraceLimit) +/// Limit depth of instantiation backtrace. +VALUE_DIAGOPT(TemplateBacktraceLimit, 32, DefaultTemplateBacktraceLimit) +/// Limit depth of constexpr backtrace. +VALUE_DIAGOPT(ConstexprBacktraceLimit, 32, DefaultConstexprBacktraceLimit) + +VALUE_DIAGOPT(TabStop, 32, DefaultTabStop) /// The distance between tab stops. +/// Column limit for formatting message diagnostics, or 0 if unused. +VALUE_DIAGOPT(MessageLength, 32, 0) + #undef DIAGOPT #undef ENUM_DIAGOPT #undef VALUE_DIAGOPT +#undef SEMANTIC_DIAGOPT +#undef SEMANTIC_ENUM_DIAGOPT +#undef SEMANTIC_ diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h index 775d87b502..b75cb0c24d 100644 --- a/include/clang/Basic/DiagnosticOptions.h +++ b/include/clang/Basic/DiagnosticOptions.h @@ -30,6 +30,12 @@ class DiagnosticOptions : public llvm::RefCountedBase{ public: enum TextDiagnosticFormat { Clang, Msvc, Vi }; + // Default values. + enum { DefaultTabStop = 8, MaxTabStop = 100, + DefaultMacroBacktraceLimit = 6, + DefaultTemplateBacktraceLimit = 10, + DefaultConstexprBacktraceLimit = 10 }; + // Define simple diagnostic options (with no accessors). #define DIAGOPT(Name, Bits, Default) unsigned Name : Bits; #define ENUM_DIAGOPT(Name, Type, Bits, Default) @@ -43,21 +49,6 @@ protected: #include "clang/Basic/DiagnosticOptions.def" public: - unsigned ErrorLimit; /// Limit # errors emitted. - unsigned MacroBacktraceLimit; /// Limit depth of macro expansion backtrace. - unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace. - unsigned ConstexprBacktraceLimit; /// Limit depth of constexpr backtrace. - - /// The distance between tab stops. - unsigned TabStop; - enum { DefaultTabStop = 8, MaxTabStop = 100, - DefaultMacroBacktraceLimit = 6, - DefaultTemplateBacktraceLimit = 10, - DefaultConstexprBacktraceLimit = 10 }; - - /// Column limit for formatting message diagnostics, or 0 if unused. - unsigned MessageLength; - /// If non-empty, a file to log extended build information to, for development /// testing and analysis. std::string DumpBuildInformation; @@ -84,16 +75,11 @@ public: #define DIAGOPT(Name, Bits, Default) Name = Default; #define ENUM_DIAGOPT(Name, Type, Bits, Default) set##Name(Default); #include "clang/Basic/DiagnosticOptions.def" - - MessageLength = 0; - TabStop = DefaultTabStop; - ErrorLimit = 0; - TemplateBacktraceLimit = DefaultTemplateBacktraceLimit; - MacroBacktraceLimit = DefaultMacroBacktraceLimit; - ConstexprBacktraceLimit = DefaultConstexprBacktraceLimit; } }; +typedef DiagnosticOptions::TextDiagnosticFormat TextDiagnosticFormat; + } // end namespace clang #endif diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 1cf118638c..6e3bd149de 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -261,7 +261,10 @@ namespace clang { /// \brief Offsets into the input-files block where input files /// reside. - INPUT_FILE_OFFSETS = 7 + INPUT_FILE_OFFSETS = 7, + + /// \brief Record code for the diagnostic options table. + DIAGNOSTIC_OPTIONS = 8 }; /// \brief Record types that occur within the input-files block diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index e9920efaa8..ffebcb9712 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -63,6 +63,7 @@ class ASTUnit; // FIXME: Layering violation and egregious hack. class Attr; class Decl; class DeclContext; +class DiagnosticOptions; class NestedNameSpecifier; class CXXBaseSpecifier; class CXXConstructorDecl; @@ -120,6 +121,15 @@ public: return false; } + /// \brief Receives the diagnostic options. + /// + /// \returns true to indicate the diagnostic options are invalid, or false + /// otherwise. + virtual bool ReadDiagnosticOptions(const DiagnosticOptions &DiagOpts, + bool Complain) { + return false; + } + /// \brief Receives the contents of the predefines buffer. /// /// \param Buffers Information about the predefines buffers. @@ -913,6 +923,8 @@ private: ASTReaderListener &Listener); static bool ParseTargetOptions(const RecordData &Record, bool Complain, ASTReaderListener &Listener); + static bool ParseDiagnosticOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); struct RecordLocation { RecordLocation(ModuleFile *M, uint64_t O) diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 613f8b9dc8..2b76d60467 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2007,6 +2007,14 @@ ASTReader::ReadControlBlock(ModuleFile &F, break; } + case DIAGNOSTIC_OPTIONS: { + bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0; + if (Listener && &F == *ModuleMgr.begin() && + ParseDiagnosticOptions(Record, Complain, *Listener) && + !DisableValidation) + return ConfigurationMismatch; + break; + } case ORIGINAL_FILE: F.OriginalSourceFileID = FileID::get(Record[0]); F.ActualOriginalSourceFileName.assign(BlobStart, BlobLen); @@ -3466,6 +3474,11 @@ bool ASTReader::isAcceptableASTFile(StringRef Filename, return false; break; + case DIAGNOSTIC_OPTIONS: + if (ParseDiagnosticOptions(Record, false, Validator)) + return false; + break; + default: // No other validation to perform. break; @@ -3806,6 +3819,22 @@ bool ASTReader::ParseTargetOptions(const RecordData &Record, return Listener.ReadTargetOptions(TargetOpts, Complain); } +bool ASTReader::ParseDiagnosticOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener) { + DiagnosticOptions DiagOpts; + unsigned Idx = 0; +#define DIAGOPT(Name, Bits, Default) DiagOpts.Name = Record[Idx++]; +#define ENUM_DIAGOPT(Name, Type, Bits, Default) \ + DiagOpts.set##Name(static_cast(Record[Idx++])); +#include "clang/Basic/DiagnosticOptions.def" + + for (unsigned N = Record[Idx++]; N; --N) { + DiagOpts.Warnings.push_back(ReadString(Record, Idx)); + } + + return Listener.ReadDiagnosticOptions(DiagOpts, Complain); +} + std::pair ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) { GlobalPreprocessedEntityMapType::iterator diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 801615280f..650d1aa3c5 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -776,6 +776,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(ORIGINAL_FILE); RECORD(ORIGINAL_PCH_DIR); RECORD(INPUT_FILE_OFFSETS); + RECORD(DIAGNOSTIC_OPTIONS); BLOCK(INPUT_FILES_BLOCK); RECORD(INPUT_FILE); @@ -1068,6 +1069,21 @@ void ASTWriter::WriteControlBlock(ASTContext &Context, StringRef isysroot, } Stream.EmitRecord(TARGET_OPTIONS, Record); + // Diagnostic options. + Record.clear(); + const DiagnosticOptions &DiagOpts + = Context.getDiagnostics().getDiagnosticOptions(); +#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name); +#define ENUM_DIAGOPT(Name, Type, Bits, Default) \ + Record.push_back(static_cast(DiagOpts.get##Name())); +#include "clang/Basic/DiagnosticOptions.def" + Record.push_back(DiagOpts.Warnings.size()); + for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I) + AddString(DiagOpts.Warnings[I], Record); + // Note: we don't serialize the log or serialization file names, because they + // are generally transient files and will almost always be overridden. + Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record); + // Original file name and file ID SourceManager &SM = Context.getSourceManager(); if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {