1621bc69624599da62abd9bc9e5edd8a63ac99fe6David Blaikie//===- VerifyDiagnosticConsumer.h - Verifying Diagnostic Client -*- C++ -*-===//
281f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar//
381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar//                     The LLVM Compiler Infrastructure
481f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar//
581f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar// This file is distributed under the University of Illinois Open Source
681f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar// License. See LICENSE.TXT for details.
781f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar//
881f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar//===----------------------------------------------------------------------===//
981f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
1081f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar#ifndef LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
1181f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
1281f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
1381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar#include "clang/Basic/Diagnostic.h"
1478541c433049322b27b4f437973076ba29cff709Jordan Rose#include "clang/Lex/Preprocessor.h"
157eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose#include "llvm/ADT/DenseMap.h"
1681f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar#include "llvm/ADT/OwningPtr.h"
177eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose#include "llvm/ADT/PointerIntPair.h"
184313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose#include "llvm/ADT/STLExtras.h"
194313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose#include <climits>
2081f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
2181f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbarnamespace clang {
2281f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
23d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikieclass DiagnosticsEngine;
2481f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbarclass TextDiagnosticBuffer;
2578541c433049322b27b4f437973076ba29cff709Jordan Roseclass FileEntry;
2681f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
27621bc69624599da62abd9bc9e5edd8a63ac99fe6David Blaikie/// VerifyDiagnosticConsumer - Create a diagnostic client which will use
28621bc69624599da62abd9bc9e5edd8a63ac99fe6David Blaikie/// markers in the input source to check that all the emitted diagnostics match
29621bc69624599da62abd9bc9e5edd8a63ac99fe6David Blaikie/// those expected.
3081f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///
3181f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// USING THE DIAGNOSTIC CHECKER:
3281f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///
3381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// Indicating that a line expects an error or a warning is simple. Put a
3460909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner/// comment on the line that has the diagnostic, use:
3560909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
36266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \code
37266dba3661928d26f043560b169bea87578aa917Andy Gibbs///   expected-{error,warning,note}
38266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \endcode
3960909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
4081f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// to tag if it's an expected error or warning, and place the expected text
4181f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// between {{ and }} markers. The full text doesn't have to be included, only
4281f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// enough to ensure that the correct diagnostic was emitted.
4381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///
4481f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// Here's an example:
4581f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///
46a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// \code
4781f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///   int A = B; // expected-error {{use of undeclared identifier 'B'}}
48a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// \endcode
4981f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///
5081f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// You can place as many diagnostics on one line as you wish. To make the code
5181f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// more readable, you can use slash-newline to separate out the diagnostics.
5281f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///
53aa48fe80a1b2000809900a437f0819d929793002Jordan Rose/// Alternatively, it is possible to specify the line on which the diagnostic
54aa48fe80a1b2000809900a437f0819d929793002Jordan Rose/// should appear by appending "@<line>" to "expected-<type>", for example:
55aa48fe80a1b2000809900a437f0819d929793002Jordan Rose///
563b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \code
57aa48fe80a1b2000809900a437f0819d929793002Jordan Rose///   #warning some text
58aa48fe80a1b2000809900a437f0819d929793002Jordan Rose///   // expected-warning@10 {{some text}}
593b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \endcode
60aa48fe80a1b2000809900a437f0819d929793002Jordan Rose///
61aa48fe80a1b2000809900a437f0819d929793002Jordan Rose/// The line number may be absolute (as above), or relative to the current
62aa48fe80a1b2000809900a437f0819d929793002Jordan Rose/// line by prefixing the number with either '+' or '-'.
63aa48fe80a1b2000809900a437f0819d929793002Jordan Rose///
6481f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// The simple syntax above allows each specification to match exactly one
6581f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// error.  You can use the extended syntax to customize this. The extended
66a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of
67a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// "error", "warning" or "note", and \<n> is a positive integer. This allows
68a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// the diagnostic to appear as many times as specified. Example:
6981f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///
70a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// \code
7181f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///   void f(); // expected-note 2 {{previous declaration is here}}
72a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// \endcode
7381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///
743b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// Where the diagnostic is expected to occur a minimum number of times, this
753b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// can be specified by appending a '+' to the number. Example:
763b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
773b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \code
783b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///   void f(); // expected-note 0+ {{previous declaration is here}}
793b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///   void g(); // expected-note 1+ {{previous declaration is here}}
803b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \endcode
813b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
823b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// In the first example, the diagnostic becomes optional, i.e. it will be
833b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// swallowed if it occurs, but will not generate an error if it does not
843b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// occur.  In the second example, the diagnostic must occur at least once.
853b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// As a short-hand, "one or more" can be specified simply by '+'. Example:
863b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
873b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \code
883b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///   void g(); // expected-note + {{previous declaration is here}}
893b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \endcode
903b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
913b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// A range can also be specified by "<n>-<m>".  Example:
923b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
933b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \code
943b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///   void f(); // expected-note 0-1 {{previous declaration is here}}
953b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \endcode
963b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
973b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// In this example, the diagnostic may appear only once, if at all.
983b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
99266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// Regex matching mode may be selected by appending '-re' to type, such as:
10060909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
101266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \code
10260909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///   expected-error-re
103266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \endcode
10460909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
10560909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner/// Examples matching error: "variable has incomplete type 'struct s'"
10660909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
107266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \code
10860909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///   // expected-error {{variable has incomplete type 'struct s'}}
10960909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///   // expected-error {{variable has incomplete type}}
11060909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
11160909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///   // expected-error-re {{variable has has type 'struct .'}}
11260909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///   // expected-error-re {{variable has has type 'struct .*'}}
11360909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///   // expected-error-re {{variable has has type 'struct (.*)'}}
11460909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///   // expected-error-re {{variable has has type 'struct[[:space:]](.*)'}}
115266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \endcode
116266dba3661928d26f043560b169bea87578aa917Andy Gibbs///
117266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// VerifyDiagnosticConsumer expects at least one expected-* directive to
118266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// be found inside the source code.  If no diagnostics are expected the
119266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// following directive can be used to indicate this:
120266dba3661928d26f043560b169bea87578aa917Andy Gibbs///
121266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \code
122266dba3661928d26f043560b169bea87578aa917Andy Gibbs///   // expected-no-diagnostics
123266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \endcode
12460909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
12578541c433049322b27b4f437973076ba29cff709Jordan Roseclass VerifyDiagnosticConsumer: public DiagnosticConsumer,
12678541c433049322b27b4f437973076ba29cff709Jordan Rose                                public CommentHandler {
12781f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbarpublic:
1284313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  /// Directive - Abstract class representing a parsed verify directive.
1294313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  ///
1304313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  class Directive {
1314313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  public:
132aa48fe80a1b2000809900a437f0819d929793002Jordan Rose    static Directive *create(bool RegexKind, SourceLocation DirectiveLoc,
133aa48fe80a1b2000809900a437f0819d929793002Jordan Rose                             SourceLocation DiagnosticLoc,
1343b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose                             StringRef Text, unsigned Min, unsigned Max);
1354313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  public:
1363b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    /// Constant representing n or more matches.
1373b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    static const unsigned MaxCount = UINT_MAX;
1384313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
139aa48fe80a1b2000809900a437f0819d929793002Jordan Rose    SourceLocation DirectiveLoc;
140aa48fe80a1b2000809900a437f0819d929793002Jordan Rose    SourceLocation DiagnosticLoc;
1414313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    const std::string Text;
1423b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    unsigned Min, Max;
1434313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1444313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    virtual ~Directive() { }
1454313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1464313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    // Returns true if directive text is valid.
1474313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    // Otherwise returns false and populates E.
1484313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    virtual bool isValid(std::string &Error) = 0;
1494313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1504313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    // Returns true on match.
1514313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    virtual bool match(StringRef S) = 0;
1524313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1534313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  protected:
154aa48fe80a1b2000809900a437f0819d929793002Jordan Rose    Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
1553b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose              StringRef Text, unsigned Min, unsigned Max)
156aa48fe80a1b2000809900a437f0819d929793002Jordan Rose      : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
1573b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose        Text(Text), Min(Min), Max(Max) {
1583b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
1593b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!");
1603b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    }
1614313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1624313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  private:
163f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko    Directive(const Directive &) LLVM_DELETED_FUNCTION;
164f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko    void operator=(const Directive &) LLVM_DELETED_FUNCTION;
1654313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  };
1664313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1674313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  typedef std::vector<Directive*> DirectiveList;
1684313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1694313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  /// ExpectedData - owns directive objects and deletes on destructor.
1704313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  ///
1714313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  struct ExpectedData {
1724313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    DirectiveList Errors;
1734313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    DirectiveList Warnings;
1744313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    DirectiveList Notes;
1754313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1764313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    ~ExpectedData() {
1774313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose      llvm::DeleteContainerPointers(Errors);
1784313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose      llvm::DeleteContainerPointers(Warnings);
1794313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose      llvm::DeleteContainerPointers(Notes);
1804313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    }
1814313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  };
1824313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
183266dba3661928d26f043560b169bea87578aa917Andy Gibbs  enum DirectiveStatus {
184266dba3661928d26f043560b169bea87578aa917Andy Gibbs    HasNoDirectives,
185266dba3661928d26f043560b169bea87578aa917Andy Gibbs    HasNoDirectivesReported,
186266dba3661928d26f043560b169bea87578aa917Andy Gibbs    HasExpectedNoDiagnostics,
187266dba3661928d26f043560b169bea87578aa917Andy Gibbs    HasOtherExpectedDirectives
188266dba3661928d26f043560b169bea87578aa917Andy Gibbs  };
189266dba3661928d26f043560b169bea87578aa917Andy Gibbs
1907c304f56eecbd03db7d222a05dfcd593750d50d3Jordan Roseprivate:
191d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &Diags;
19278ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie  DiagnosticConsumer *PrimaryClient;
19378243658c533168d51fd076fba328437932ba6f1Douglas Gregor  bool OwnsPrimaryClient;
1946f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<TextDiagnosticBuffer> Buffer;
19578541c433049322b27b4f437973076ba29cff709Jordan Rose  const Preprocessor *CurrentPreprocessor;
1967eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  const LangOptions *LangOpts;
1977eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  SourceManager *SrcManager;
1987c304f56eecbd03db7d222a05dfcd593750d50d3Jordan Rose  unsigned ActiveSourceFiles;
199266dba3661928d26f043560b169bea87578aa917Andy Gibbs  DirectiveStatus Status;
2004313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  ExpectedData ED;
2017eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
20281f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar  void CheckDiagnostics();
2037eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  void setSourceManager(SourceManager &SM) {
2047eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!");
2057eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    SrcManager = &SM;
2067eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  }
2077eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2087eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose#ifndef NDEBUG
2097eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  class UnparsedFileStatus {
2107eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    llvm::PointerIntPair<const FileEntry *, 1, bool> Data;
2117eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2127eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  public:
2137eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    UnparsedFileStatus(const FileEntry *File, bool FoundDirectives)
2147eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose      : Data(File, FoundDirectives) {}
2157eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2167eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    const FileEntry *getFile() const { return Data.getPointer(); }
2177eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    bool foundDirectives() const { return Data.getInt(); }
2187eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  };
2197eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2207eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap;
2217eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap;
2227eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2237eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  ParsedFilesMap ParsedFiles;
2247eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  UnparsedFilesMap UnparsedFiles;
2257eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose#endif
22681f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
22781f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbarpublic:
228a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett  /// Create a new verifying diagnostic client, which will issue errors to
22978243658c533168d51fd076fba328437932ba6f1Douglas Gregor  /// the currently-attached diagnostic client when a diagnostic does not match
23078243658c533168d51fd076fba328437932ba6f1Douglas Gregor  /// what is expected (as indicated in the source file).
231621bc69624599da62abd9bc9e5edd8a63ac99fe6David Blaikie  VerifyDiagnosticConsumer(DiagnosticsEngine &Diags);
232621bc69624599da62abd9bc9e5edd8a63ac99fe6David Blaikie  ~VerifyDiagnosticConsumer();
23381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
23481f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar  virtual void BeginSourceFile(const LangOptions &LangOpts,
23581f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar                               const Preprocessor *PP);
23681f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
23781f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar  virtual void EndSourceFile();
238221c7211c507482a91e97ede1bf6cf65a456ff67Daniel Dunbar
2397eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  enum ParsedStatus {
2407eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    /// File has been processed via HandleComment.
2417eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    IsParsed,
2427eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2437eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    /// File has diagnostics and may have directives.
2447eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    IsUnparsed,
2457eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2467eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    /// File has diagnostics but guaranteed no directives.
2477eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    IsUnparsedNoDirectives
2487eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  };
2497eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2507eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  /// \brief Update lists of parsed and unparsed files.
2517eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS);
2527c304f56eecbd03db7d222a05dfcd593750d50d3Jordan Rose
25378541c433049322b27b4f437973076ba29cff709Jordan Rose  virtual bool HandleComment(Preprocessor &PP, SourceRange Comment);
25478541c433049322b27b4f437973076ba29cff709Jordan Rose
255d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
25640847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie                                const Diagnostic &Info);
257aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor
258aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor  virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const;
25981f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar};
26081f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
26181f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar} // end namspace clang
26281f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
26381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar#endif
264