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"
167eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose#include "llvm/ADT/PointerIntPair.h"
174313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose#include "llvm/ADT/STLExtras.h"
184313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose#include <climits>
19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <memory>
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
376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines///   expected-{error,warning,remark,note}
38266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \endcode
3960909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// to tag if it's an expected error, remark or warning, and place the expected
416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// text between {{ and }} markers. The full text doesn't have to be included,
426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// only 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///
64b42f200777a66b98989160bf3987ce431540a584Andy Gibbs/// If the diagnostic is generated in a separate file, for example in a shared
65b42f200777a66b98989160bf3987ce431540a584Andy Gibbs/// header file, it may be beneficial to be able to declare the file in which
66b42f200777a66b98989160bf3987ce431540a584Andy Gibbs/// the diagnostic will appear, rather than placing the expected-* directive in
67b42f200777a66b98989160bf3987ce431540a584Andy Gibbs/// the actual file itself.  This can be done using the following syntax:
68b42f200777a66b98989160bf3987ce431540a584Andy Gibbs///
69b42f200777a66b98989160bf3987ce431540a584Andy Gibbs/// \code
70b42f200777a66b98989160bf3987ce431540a584Andy Gibbs///   // expected-error@path/include.h:15 {{error message}}
71b42f200777a66b98989160bf3987ce431540a584Andy Gibbs/// \endcode
72b42f200777a66b98989160bf3987ce431540a584Andy Gibbs///
73b42f200777a66b98989160bf3987ce431540a584Andy Gibbs/// The path can be absolute or relative and the same search paths will be used
74ef8225444452a1486bd721f3285301fe84643b00Stephen Hines/// as for #include directives.  The line number in an external file may be
75ef8225444452a1486bd721f3285301fe84643b00Stephen Hines/// substituted with '*' meaning that any line number will match (useful where
76ef8225444452a1486bd721f3285301fe84643b00Stephen Hines/// the included file is, for example, a system header where the actual line
77ef8225444452a1486bd721f3285301fe84643b00Stephen Hines/// number may change and is not critical).
78b42f200777a66b98989160bf3987ce431540a584Andy Gibbs///
7981f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// The simple syntax above allows each specification to match exactly one
8081f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar/// error.  You can use the extended syntax to customize this. The extended
81a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of
82a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// "error", "warning" or "note", and \<n> is a positive integer. This allows
83a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// the diagnostic to appear as many times as specified. Example:
8481f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///
85a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// \code
8681f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///   void f(); // expected-note 2 {{previous declaration is here}}
87a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett/// \endcode
8881f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar///
893b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// Where the diagnostic is expected to occur a minimum number of times, this
903b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// can be specified by appending a '+' to the number. Example:
913b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
923b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \code
933b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///   void f(); // expected-note 0+ {{previous declaration is here}}
943b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///   void g(); // expected-note 1+ {{previous declaration is here}}
953b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \endcode
963b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
973b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// In the first example, the diagnostic becomes optional, i.e. it will be
983b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// swallowed if it occurs, but will not generate an error if it does not
993b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// occur.  In the second example, the diagnostic must occur at least once.
1003b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// As a short-hand, "one or more" can be specified simply by '+'. Example:
1013b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
1023b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \code
1033b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///   void g(); // expected-note + {{previous declaration is here}}
1043b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \endcode
1053b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
1063b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// A range can also be specified by "<n>-<m>".  Example:
1073b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
1083b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \code
1093b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///   void f(); // expected-note 0-1 {{previous declaration is here}}
1103b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// \endcode
1113b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
1123b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose/// In this example, the diagnostic may appear only once, if at all.
1133b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose///
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Regex matching mode may be selected by appending '-re' to type and
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// including regexes wrapped in double curly braces in the directive, such as:
11660909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
117266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \code
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines///   expected-error-re {{format specifies type 'wchar_t **' (aka '{{.+}}')}}
119266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \endcode
12060909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
12160909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner/// Examples matching error: "variable has incomplete type 'struct s'"
12260909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
123266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \code
12460909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///   // expected-error {{variable has incomplete type 'struct s'}}
12560909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///   // expected-error {{variable has incomplete type}}
12660909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines///   // expected-error-re {{variable has type 'struct {{.}}'}}
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines///   // expected-error-re {{variable has type 'struct {{.*}}'}}
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines///   // expected-error-re {{variable has type 'struct {{(.*)}}'}}
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines///   // expected-error-re {{variable has type 'struct{{[[:space:]](.*)}}'}}
131266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \endcode
132266dba3661928d26f043560b169bea87578aa917Andy Gibbs///
133266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// VerifyDiagnosticConsumer expects at least one expected-* directive to
134266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// be found inside the source code.  If no diagnostics are expected the
135266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// following directive can be used to indicate this:
136266dba3661928d26f043560b169bea87578aa917Andy Gibbs///
137266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \code
138266dba3661928d26f043560b169bea87578aa917Andy Gibbs///   // expected-no-diagnostics
139266dba3661928d26f043560b169bea87578aa917Andy Gibbs/// \endcode
14060909e1242f19aa8b1b87110aaa8e394f329ae96Chris Lattner///
14178541c433049322b27b4f437973076ba29cff709Jordan Roseclass VerifyDiagnosticConsumer: public DiagnosticConsumer,
14278541c433049322b27b4f437973076ba29cff709Jordan Rose                                public CommentHandler {
14381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbarpublic:
1444313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  /// Directive - Abstract class representing a parsed verify directive.
1454313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  ///
1464313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  class Directive {
1474313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  public:
148aa48fe80a1b2000809900a437f0819d929793002Jordan Rose    static Directive *create(bool RegexKind, SourceLocation DirectiveLoc,
149ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                             SourceLocation DiagnosticLoc, bool MatchAnyLine,
1503b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose                             StringRef Text, unsigned Min, unsigned Max);
1514313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  public:
1523b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    /// Constant representing n or more matches.
1533b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    static const unsigned MaxCount = UINT_MAX;
1544313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
155aa48fe80a1b2000809900a437f0819d929793002Jordan Rose    SourceLocation DirectiveLoc;
156aa48fe80a1b2000809900a437f0819d929793002Jordan Rose    SourceLocation DiagnosticLoc;
1574313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    const std::string Text;
1583b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    unsigned Min, Max;
159ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    bool MatchAnyLine;
1604313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1614313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    virtual ~Directive() { }
1624313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1634313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    // Returns true if directive text is valid.
1644313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    // Otherwise returns false and populates E.
1654313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    virtual bool isValid(std::string &Error) = 0;
1664313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1674313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    // Returns true on match.
1684313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    virtual bool match(StringRef S) = 0;
1694313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1704313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  protected:
171aa48fe80a1b2000809900a437f0819d929793002Jordan Rose    Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
172ef8225444452a1486bd721f3285301fe84643b00Stephen Hines              bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max)
173aa48fe80a1b2000809900a437f0819d929793002Jordan Rose      : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
174ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
1753b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
1763b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!");
1773b81b7d604e851498243ee732dee3babc1cf20d4Jordan Rose    }
1784313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1794313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  private:
180f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko    Directive(const Directive &) LLVM_DELETED_FUNCTION;
181f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko    void operator=(const Directive &) LLVM_DELETED_FUNCTION;
1824313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  };
1834313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1844313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  typedef std::vector<Directive*> DirectiveList;
1854313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1864313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  /// ExpectedData - owns directive objects and deletes on destructor.
1874313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  ///
1884313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  struct ExpectedData {
1894313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    DirectiveList Errors;
1904313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    DirectiveList Warnings;
1916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DirectiveList Remarks;
1924313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    DirectiveList Notes;
1934313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
1946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    void Reset() {
1954313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose      llvm::DeleteContainerPointers(Errors);
1964313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose      llvm::DeleteContainerPointers(Warnings);
1976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      llvm::DeleteContainerPointers(Remarks);
1984313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose      llvm::DeleteContainerPointers(Notes);
1994313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose    }
2006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
2016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ~ExpectedData() { Reset(); }
2024313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  };
2034313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose
204266dba3661928d26f043560b169bea87578aa917Andy Gibbs  enum DirectiveStatus {
205266dba3661928d26f043560b169bea87578aa917Andy Gibbs    HasNoDirectives,
206266dba3661928d26f043560b169bea87578aa917Andy Gibbs    HasNoDirectivesReported,
207266dba3661928d26f043560b169bea87578aa917Andy Gibbs    HasExpectedNoDiagnostics,
208266dba3661928d26f043560b169bea87578aa917Andy Gibbs    HasOtherExpectedDirectives
209266dba3661928d26f043560b169bea87578aa917Andy Gibbs  };
210266dba3661928d26f043560b169bea87578aa917Andy Gibbs
2117c304f56eecbd03db7d222a05dfcd593750d50d3Jordan Roseprivate:
212d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &Diags;
21378ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie  DiagnosticConsumer *PrimaryClient;
21478243658c533168d51fd076fba328437932ba6f1Douglas Gregor  bool OwnsPrimaryClient;
215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<TextDiagnosticBuffer> Buffer;
21678541c433049322b27b4f437973076ba29cff709Jordan Rose  const Preprocessor *CurrentPreprocessor;
2177eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  const LangOptions *LangOpts;
2187eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  SourceManager *SrcManager;
2197c304f56eecbd03db7d222a05dfcd593750d50d3Jordan Rose  unsigned ActiveSourceFiles;
220266dba3661928d26f043560b169bea87578aa917Andy Gibbs  DirectiveStatus Status;
2214313c013c658f6c97e6460e7780c26faa6b78d9aJordan Rose  ExpectedData ED;
2227eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
22381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar  void CheckDiagnostics();
2247eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  void setSourceManager(SourceManager &SM) {
2257eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!");
2267eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    SrcManager = &SM;
2277eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  }
2287eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // These facilities are used for validation in debug builds.
2307eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  class UnparsedFileStatus {
2317eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    llvm::PointerIntPair<const FileEntry *, 1, bool> Data;
2327eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  public:
2337eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    UnparsedFileStatus(const FileEntry *File, bool FoundDirectives)
2347eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose      : Data(File, FoundDirectives) {}
2357eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    const FileEntry *getFile() const { return Data.getPointer(); }
2367eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    bool foundDirectives() const { return Data.getInt(); }
2377eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  };
2387eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap;
2397eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap;
2407eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  ParsedFilesMap ParsedFiles;
2417eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  UnparsedFilesMap UnparsedFiles;
24281f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
24381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbarpublic:
244a6366f5c7e92466ebad0042afa55c2e5952ebe61James Dennett  /// Create a new verifying diagnostic client, which will issue errors to
24578243658c533168d51fd076fba328437932ba6f1Douglas Gregor  /// the currently-attached diagnostic client when a diagnostic does not match
24678243658c533168d51fd076fba328437932ba6f1Douglas Gregor  /// what is expected (as indicated in the source file).
247621bc69624599da62abd9bc9e5edd8a63ac99fe6David Blaikie  VerifyDiagnosticConsumer(DiagnosticsEngine &Diags);
248621bc69624599da62abd9bc9e5edd8a63ac99fe6David Blaikie  ~VerifyDiagnosticConsumer();
24981f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void BeginSourceFile(const LangOptions &LangOpts,
251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       const Preprocessor *PP) override;
25281f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void EndSourceFile() override;
254221c7211c507482a91e97ede1bf6cf65a456ff67Daniel Dunbar
2557eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  enum ParsedStatus {
2567eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    /// File has been processed via HandleComment.
2577eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    IsParsed,
2587eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2597eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    /// File has diagnostics and may have directives.
2607eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    IsUnparsed,
2617eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2627eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    /// File has diagnostics but guaranteed no directives.
2637eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose    IsUnparsedNoDirectives
2647eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  };
2657eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose
2667eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  /// \brief Update lists of parsed and unparsed files.
2677eaaa186d1e9797f424136f565403f7a8b6672faJordan Rose  void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS);
2687c304f56eecbd03db7d222a05dfcd593750d50d3Jordan Rose
269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool HandleComment(Preprocessor &PP, SourceRange Comment) override;
27078541c433049322b27b4f437973076ba29cff709Jordan Rose
271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        const Diagnostic &Info) override;
27381f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar};
27481f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
27581f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar} // end namspace clang
27681f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar
27781f5a1e699b2eefa4a5e50b5dfc06df600748f59Daniel Dunbar#endif
278