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