diff options
Diffstat (limited to 'include/clang/Frontend/VerifyDiagnosticConsumer.h')
-rw-r--r-- | include/clang/Frontend/VerifyDiagnosticConsumer.h | 278 |
1 files changed, 0 insertions, 278 deletions
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h deleted file mode 100644 index 475f07f..0000000 --- a/include/clang/Frontend/VerifyDiagnosticConsumer.h +++ /dev/null @@ -1,278 +0,0 @@ -//===- VerifyDiagnosticConsumer.h - Verifying Diagnostic Client -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H -#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H - -#include "clang/Basic/Diagnostic.h" -#include "clang/Lex/Preprocessor.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/STLExtras.h" -#include <climits> -#include <memory> - -namespace clang { - -class DiagnosticsEngine; -class TextDiagnosticBuffer; -class FileEntry; - -/// VerifyDiagnosticConsumer - Create a diagnostic client which will use -/// markers in the input source to check that all the emitted diagnostics match -/// those expected. -/// -/// USING THE DIAGNOSTIC CHECKER: -/// -/// Indicating that a line expects an error or a warning is simple. Put a -/// comment on the line that has the diagnostic, use: -/// -/// \code -/// expected-{error,warning,remark,note} -/// \endcode -/// -/// to tag if it's an expected error, remark or warning, and place the expected -/// text between {{ and }} markers. The full text doesn't have to be included, -/// only enough to ensure that the correct diagnostic was emitted. -/// -/// Here's an example: -/// -/// \code -/// int A = B; // expected-error {{use of undeclared identifier 'B'}} -/// \endcode -/// -/// You can place as many diagnostics on one line as you wish. To make the code -/// more readable, you can use slash-newline to separate out the diagnostics. -/// -/// Alternatively, it is possible to specify the line on which the diagnostic -/// should appear by appending "@<line>" to "expected-<type>", for example: -/// -/// \code -/// #warning some text -/// // expected-warning@10 {{some text}} -/// \endcode -/// -/// The line number may be absolute (as above), or relative to the current -/// line by prefixing the number with either '+' or '-'. -/// -/// If the diagnostic is generated in a separate file, for example in a shared -/// header file, it may be beneficial to be able to declare the file in which -/// the diagnostic will appear, rather than placing the expected-* directive in -/// the actual file itself. This can be done using the following syntax: -/// -/// \code -/// // expected-error@path/include.h:15 {{error message}} -/// \endcode -/// -/// The path can be absolute or relative and the same search paths will be used -/// as for #include directives. The line number in an external file may be -/// substituted with '*' meaning that any line number will match (useful where -/// the included file is, for example, a system header where the actual line -/// number may change and is not critical). -/// -/// The simple syntax above allows each specification to match exactly one -/// error. You can use the extended syntax to customize this. The extended -/// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of -/// "error", "warning" or "note", and \<n> is a positive integer. This allows -/// the diagnostic to appear as many times as specified. Example: -/// -/// \code -/// void f(); // expected-note 2 {{previous declaration is here}} -/// \endcode -/// -/// Where the diagnostic is expected to occur a minimum number of times, this -/// can be specified by appending a '+' to the number. Example: -/// -/// \code -/// void f(); // expected-note 0+ {{previous declaration is here}} -/// void g(); // expected-note 1+ {{previous declaration is here}} -/// \endcode -/// -/// In the first example, the diagnostic becomes optional, i.e. it will be -/// swallowed if it occurs, but will not generate an error if it does not -/// occur. In the second example, the diagnostic must occur at least once. -/// As a short-hand, "one or more" can be specified simply by '+'. Example: -/// -/// \code -/// void g(); // expected-note + {{previous declaration is here}} -/// \endcode -/// -/// A range can also be specified by "<n>-<m>". Example: -/// -/// \code -/// void f(); // expected-note 0-1 {{previous declaration is here}} -/// \endcode -/// -/// In this example, the diagnostic may appear only once, if at all. -/// -/// Regex matching mode may be selected by appending '-re' to type and -/// including regexes wrapped in double curly braces in the directive, such as: -/// -/// \code -/// expected-error-re {{format specifies type 'wchar_t **' (aka '{{.+}}')}} -/// \endcode -/// -/// Examples matching error: "variable has incomplete type 'struct s'" -/// -/// \code -/// // expected-error {{variable has incomplete type 'struct s'}} -/// // expected-error {{variable has incomplete type}} -/// -/// // expected-error-re {{variable has type 'struct {{.}}'}} -/// // expected-error-re {{variable has type 'struct {{.*}}'}} -/// // expected-error-re {{variable has type 'struct {{(.*)}}'}} -/// // expected-error-re {{variable has type 'struct{{[[:space:]](.*)}}'}} -/// \endcode -/// -/// VerifyDiagnosticConsumer expects at least one expected-* directive to -/// be found inside the source code. If no diagnostics are expected the -/// following directive can be used to indicate this: -/// -/// \code -/// // expected-no-diagnostics -/// \endcode -/// -class VerifyDiagnosticConsumer: public DiagnosticConsumer, - public CommentHandler { -public: - /// Directive - Abstract class representing a parsed verify directive. - /// - class Directive { - public: - static std::unique_ptr<Directive> create(bool RegexKind, - SourceLocation DirectiveLoc, - SourceLocation DiagnosticLoc, - bool MatchAnyLine, StringRef Text, - unsigned Min, unsigned Max); - - public: - /// Constant representing n or more matches. - static const unsigned MaxCount = UINT_MAX; - - SourceLocation DirectiveLoc; - SourceLocation DiagnosticLoc; - const std::string Text; - unsigned Min, Max; - bool MatchAnyLine; - - virtual ~Directive() { } - - // Returns true if directive text is valid. - // Otherwise returns false and populates E. - virtual bool isValid(std::string &Error) = 0; - - // Returns true on match. - virtual bool match(StringRef S) = 0; - - protected: - Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc, - bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max) - : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc), - Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) { - assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!"); - assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!"); - } - - private: - Directive(const Directive &) = delete; - void operator=(const Directive &) = delete; - }; - - typedef std::vector<std::unique_ptr<Directive>> DirectiveList; - - /// ExpectedData - owns directive objects and deletes on destructor. - /// - struct ExpectedData { - DirectiveList Errors; - DirectiveList Warnings; - DirectiveList Remarks; - DirectiveList Notes; - - void Reset() { - Errors.clear(); - Warnings.clear(); - Remarks.clear(); - Notes.clear(); - } - }; - - enum DirectiveStatus { - HasNoDirectives, - HasNoDirectivesReported, - HasExpectedNoDiagnostics, - HasOtherExpectedDirectives - }; - -private: - DiagnosticsEngine &Diags; - DiagnosticConsumer *PrimaryClient; - std::unique_ptr<DiagnosticConsumer> PrimaryClientOwner; - std::unique_ptr<TextDiagnosticBuffer> Buffer; - const Preprocessor *CurrentPreprocessor; - const LangOptions *LangOpts; - SourceManager *SrcManager; - unsigned ActiveSourceFiles; - DirectiveStatus Status; - ExpectedData ED; - - void CheckDiagnostics(); - void setSourceManager(SourceManager &SM) { - assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!"); - SrcManager = &SM; - } - - // These facilities are used for validation in debug builds. - class UnparsedFileStatus { - llvm::PointerIntPair<const FileEntry *, 1, bool> Data; - public: - UnparsedFileStatus(const FileEntry *File, bool FoundDirectives) - : Data(File, FoundDirectives) {} - const FileEntry *getFile() const { return Data.getPointer(); } - bool foundDirectives() const { return Data.getInt(); } - }; - typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap; - typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap; - ParsedFilesMap ParsedFiles; - UnparsedFilesMap UnparsedFiles; - -public: - /// Create a new verifying diagnostic client, which will issue errors to - /// the currently-attached diagnostic client when a diagnostic does not match - /// what is expected (as indicated in the source file). - VerifyDiagnosticConsumer(DiagnosticsEngine &Diags); - ~VerifyDiagnosticConsumer() override; - - void BeginSourceFile(const LangOptions &LangOpts, - const Preprocessor *PP) override; - - void EndSourceFile() override; - - enum ParsedStatus { - /// File has been processed via HandleComment. - IsParsed, - - /// File has diagnostics and may have directives. - IsUnparsed, - - /// File has diagnostics but guaranteed no directives. - IsUnparsedNoDirectives - }; - - /// \brief Update lists of parsed and unparsed files. - void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS); - - bool HandleComment(Preprocessor &PP, SourceRange Comment) override; - - void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, - const Diagnostic &Info) override; -}; - -} // end namspace clang - -#endif |