29 #include "llvm/ADT/STLExtras.h" 30 #include "llvm/ADT/SmallPtrSet.h" 31 #include "llvm/ADT/SmallString.h" 32 #include "llvm/ADT/StringRef.h" 33 #include "llvm/ADT/Twine.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Support/Regex.h" 36 #include "llvm/Support/raw_ostream.h" 47 using namespace clang;
63 : Verify(Verify),
SM(
SM) {}
89 class StandardDirective :
public Directive {
92 bool MatchAnyFileAndLine,
bool MatchAnyLine, StringRef
Text,
93 unsigned Min,
unsigned Max)
94 :
Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFileAndLine,
95 MatchAnyLine,
Text, Min, Max) {}
97 bool isValid(std::string &
Error)
override {
102 bool match(StringRef S)
override {
103 return S.find(
Text) != StringRef::npos;
108 class RegexDirective :
public Directive {
111 bool MatchAnyFileAndLine,
bool MatchAnyLine, StringRef
Text,
112 unsigned Min,
unsigned Max, StringRef RegexStr)
113 :
Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFileAndLine,
114 MatchAnyLine,
Text, Min, Max),
117 bool isValid(std::string &
Error)
override {
121 bool match(StringRef S)
override {
122 return Regex.match(S);
132 ParseHelper(StringRef S)
136 bool Next(StringRef S) {
141 return memcmp(
P, S.data(), S.size()) == 0;
146 bool Next(
unsigned &N) {
150 for (; PEnd < End && *PEnd >=
'0' && *PEnd <=
'9'; ++PEnd) {
164 if (
P ==
End || *
P !=
'#')
183 bool Search(StringRef S,
bool EnsureStartOfWord =
false,
184 bool FinishDirectiveToken =
false) {
187 P = std::search(
C,
End, S.begin(), S.end());
199 if (EnsureStartOfWord
203 || (
P > (
Begin + 1) && (
P[-1] ==
'/' ||
P[-1] ==
'*')
206 if (FinishDirectiveToken) {
208 || *PEnd ==
'-' || *PEnd ==
'_'))
215 assert(
isLetter(*
P) &&
"-verify prefix must start with a letter");
216 while (
isDigit(PEnd[-1]) || PEnd[-1] ==
'-')
226 bool SearchClosingBrace(StringRef OpenBrace, StringRef CloseBrace) {
230 StringRef S(
P,
End -
P);
231 if (S.startswith(OpenBrace)) {
233 P += OpenBrace.size();
234 }
else if (S.startswith(CloseBrace)) {
237 PEnd =
P + CloseBrace.size();
240 P += CloseBrace.size();
257 StringRef Match() {
return StringRef(
P, PEnd -
P); }
260 void SkipWhitespace() {
271 const char *
const Begin;
274 const char *
const End;
284 const char *PEnd =
nullptr;
288 struct UnattachedDirective {
290 bool RegexKind =
false;
293 unsigned Min = 1, Max = 1;
300 bool MatchAnyFileAndLine =
false,
301 bool MatchAnyLine =
false) {
304 UD.RegexKind, UD.DirectivePos, ExpectedLoc, MatchAnyFileAndLine,
305 MatchAnyLine, UD.Text, UD.Min, UD.Max);
308 if (!D->isValid(
Error)) {
309 Diags.
Report(UD.ContentBegin, diag::err_verify_invalid_content)
310 << (UD.RegexKind ?
"regex" :
"string") <<
Error;
313 UD.DL->push_back(std::move(D));
336 llvm::StringMap<Marker> Markers;
340 llvm::StringMap<llvm::SmallVector<UnattachedDirective, 2>> DeferredDirectives;
347 auto InsertResult = Markers.insert(
350 Marker &M = InsertResult.first->second;
351 if (!InsertResult.second) {
356 auto Deferred = DeferredDirectives.find(MarkerName);
357 if (Deferred != DeferredDirectives.end()) {
358 for (
auto &UD : Deferred->second) {
359 if (M.UseLoc.isInvalid())
360 M.UseLoc = UD.DirectivePos;
361 attachDirective(Diags, UD, Pos);
363 DeferredDirectives.erase(Deferred);
369 void addDirective(StringRef MarkerName,
const UnattachedDirective &UD) {
370 auto MarkerIt = Markers.find(MarkerName);
371 if (MarkerIt != Markers.end()) {
372 Marker &M = MarkerIt->second;
373 if (M.UseLoc.isInvalid())
374 M.UseLoc = UD.DirectivePos;
375 return attachDirective(Diags, UD, M.DefLoc);
377 DeferredDirectives[MarkerName].push_back(UD);
383 for (
auto &MarkerInfo : Markers) {
384 StringRef Name = MarkerInfo.first();
385 Marker &M = MarkerInfo.second;
386 if (M.RedefLoc.isValid() && M.UseLoc.isValid()) {
387 Diags.
Report(M.UseLoc, diag::err_verify_ambiguous_marker) << Name;
388 Diags.
Report(M.DefLoc, diag::note_verify_ambiguous_marker) << Name;
389 Diags.
Report(M.RedefLoc, diag::note_verify_ambiguous_marker) << Name;
393 for (
auto &DeferredPair : DeferredDirectives) {
394 Diags.
Report(DeferredPair.second.front().DirectivePos,
395 diag::err_verify_no_such_marker)
396 << DeferredPair.first();
412 for (ParseHelper PH(S); !PH.Done();) {
413 if (!PH.Search(
"#",
true))
416 if (!PH.NextMarker()) {
426 bool FoundDirective =
false;
427 for (ParseHelper PH(S); !PH.Done();) {
432 if (!(Prefixes.size() == 1 ? PH.Search(*Prefixes.begin(),
true,
true)
433 : PH.Search(
"",
true,
true)))
436 StringRef DToken = PH.Match();
440 UnattachedDirective D;
441 const char *KindStr =
"string";
450 if (DToken.endswith(
"-re")) {
453 DToken = DToken.substr(0, DToken.size()-3);
459 if (DToken.endswith(DType=
"-error"))
460 D.DL = ED ? &ED->
Errors :
nullptr;
461 else if (DToken.endswith(DType=
"-warning"))
462 D.DL = ED ? &ED->
Warnings :
nullptr;
463 else if (DToken.endswith(DType=
"-remark"))
464 D.DL = ED ? &ED->
Remarks :
nullptr;
465 else if (DToken.endswith(DType=
"-note"))
466 D.DL = ED ? &ED->
Notes :
nullptr;
467 else if (DToken.endswith(DType=
"-no-diagnostics")) {
474 DToken = DToken.substr(0, DToken.size()-DType.size());
479 if (!std::binary_search(Prefixes.begin(), Prefixes.end(), DToken))
484 Diags.
Report(Pos, diag::err_verify_invalid_no_diags)
491 Diags.
Report(Pos, diag::err_verify_invalid_no_diags)
505 bool MatchAnyFileAndLine =
false;
506 bool MatchAnyLine =
false;
512 bool FoundPlus = PH.Next(
"+");
513 if (FoundPlus || PH.Next(
"-")) {
516 bool Invalid =
false;
517 unsigned ExpectedLine =
SM.getSpellingLineNumber(Pos, &Invalid);
518 if (!Invalid && PH.Next(
Line) && (FoundPlus ||
Line < ExpectedLine)) {
519 if (FoundPlus) ExpectedLine +=
Line;
520 else ExpectedLine -=
Line;
521 ExpectedLoc =
SM.translateLineCol(
SM.getFileID(Pos), ExpectedLine, 1);
523 }
else if (PH.Next(
Line)) {
526 ExpectedLoc =
SM.translateLineCol(
SM.getFileID(Pos),
Line, 1);
527 }
else if (PH.NextMarker()) {
529 }
else if (PP && PH.Search(
":")) {
531 StringRef
Filename(PH.C, PH.P-PH.C);
535 MatchAnyFileAndLine =
true;
538 diag::err_verify_missing_line)
549 nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
552 diag::err_verify_missing_file)
562 ExpectedLoc =
SM.translateLineCol(FID,
Line, 1);
563 else if (PH.Next(
"*")) {
565 ExpectedLoc =
SM.translateLineCol(FID, 1, 1);
568 }
else if (PH.Next(
"*")) {
573 if (ExpectedLoc.
isInvalid() && !MatchAnyLine && Marker.empty()) {
575 diag::err_verify_missing_line) << KindStr;
585 if (PH.Next(D.Min)) {
592 }
else if (PH.Next(
"-")) {
594 if (!PH.Next(D.Max) || D.Max < D.Min) {
596 diag::err_verify_invalid_range) << KindStr;
603 }
else if (PH.Next(
"+")) {
613 if (!PH.Next(
"{{")) {
615 diag::err_verify_missing_start) << KindStr;
619 const char*
const ContentBegin = PH.C;
621 if (!PH.SearchClosingBrace(
"{{",
"}}")) {
623 diag::err_verify_missing_end) << KindStr;
626 const char*
const ContentEnd = PH.P;
629 D.DirectivePos = Pos;
633 StringRef NewlineStr =
"\\n";
634 StringRef Content(ContentBegin, ContentEnd-ContentBegin);
637 while ((FPos = Content.find(NewlineStr, CPos)) != StringRef::npos) {
638 D.Text += Content.substr(CPos, FPos-CPos);
640 CPos = FPos + NewlineStr.size();
643 D.Text.assign(ContentBegin, ContentEnd);
646 if (D.RegexKind && D.Text.find(
"{{") == StringRef::npos) {
647 Diags.
Report(D.ContentBegin, diag::err_verify_missing_regex) << D.Text;
652 attachDirective(Diags, D, ExpectedLoc, MatchAnyFileAndLine, MatchAnyLine);
655 FoundDirective =
true;
658 return FoundDirective;
662 : Diags(Diags_), PrimaryClient(Diags.getClient()),
663 PrimaryClientOwner(Diags.takeClient()),
665 Status(HasNoDirectives) {
671 assert(!ActiveSourceFiles &&
"Incomplete parsing of source files!");
672 assert(!CurrentPreprocessor &&
"CurrentPreprocessor should be invalid!");
673 SrcManager =
nullptr;
676 "The VerifyDiagnosticConsumer takes over ownership of the client!");
684 if (++ActiveSourceFiles == 1) {
686 CurrentPreprocessor = PP;
687 this->LangOpts = &LangOpts;
689 const_cast<Preprocessor *>(PP)->addCommentHandler(
this);
692 const_cast<Preprocessor *>(PP)->addPPCallbacks(
693 std::make_unique<VerifyFileTracker>(*
this, *SrcManager));
698 assert((!PP || CurrentPreprocessor == PP) &&
"Preprocessor changed!");
703 assert(ActiveSourceFiles &&
"No active source files!");
707 if (--ActiveSourceFiles == 0) {
708 if (CurrentPreprocessor)
709 const_cast<Preprocessor *>(CurrentPreprocessor)->
710 removeCommentHandler(
this);
717 CurrentPreprocessor =
nullptr;
744 if (FE && CurrentPreprocessor && SrcManager->
isLoadedFileID(FID)) {
759 Buffer->HandleDiagnostic(DiagLevel, Info);
769 if (SrcManager && &
SM != SrcManager)
774 const char *CommentRaw =
SM.getCharacterData(CommentBegin);
775 StringRef
C(CommentRaw,
SM.getCharacterData(Comment.
getEnd()) - CommentRaw);
781 size_t loc =
C.find(
'\\');
782 if (loc == StringRef::npos) {
788 C2.reserve(
C.size());
790 for (
size_t last = 0;; loc =
C.find(
'\\', last)) {
791 if (loc == StringRef::npos || loc ==
C.size()) {
792 C2 +=
C.substr(last);
795 C2 +=
C.substr(last, loc-last);
798 if (
C[last] ==
'\n' ||
C[last] ==
'\r') {
803 if (
C[last] ==
'\n' ||
C[last] ==
'\r')
804 if (
C[last] !=
C[last-1])
830 llvm::MemoryBufferRef FromFile =
SM.getBufferOrFake(FID);
831 Lexer RawLex(FID, FromFile,
SM, LangOpts);
837 Tok.setKind(tok::comment);
842 if (!
Tok.
is(tok::comment))
continue;
845 if (Comment.empty())
continue;
865 if (diag_begin == diag_end)
return 0;
868 llvm::raw_svector_ostream OS(Fmt);
870 if (I->first.isInvalid() || !SourceMgr)
871 OS <<
"\n (frontend)";
876 OS <<
" File " <<
File->getName();
879 OS <<
": " << I->second;
883 <<
Kind <<
true << OS.str();
891 std::vector<Directive *> &DL,
const char *
Kind) {
896 llvm::raw_svector_ostream OS(Fmt);
897 for (
const auto *D : DL) {
898 if (D->DiagnosticLoc.isInvalid() || D->MatchAnyFileAndLine)
901 OS <<
"\n File " << SourceMgr.
getFilename(D->DiagnosticLoc);
906 if (D->DirectiveLoc != D->DiagnosticLoc)
907 OS <<
" (directive at " 910 OS <<
": " << D->Text;
914 <<
Kind <<
false << OS.str();
922 DiagnosticLoc =
SM.getImmediateMacroCallerLoc(DiagnosticLoc);
924 if (
SM.isWrittenInSameFile(DirectiveLoc, DiagnosticLoc))
927 const FileEntry *DiagFile =
SM.getFileEntryForID(
SM.getFileID(DiagnosticLoc));
928 if (!DiagFile &&
SM.isWrittenInMainFile(DirectiveLoc))
931 return (DiagFile ==
SM.getFileEntryForID(
SM.getFileID(DirectiveLoc)));
941 bool IgnoreUnexpected) {
942 std::vector<Directive *> LeftOnly;
945 for (
auto &Owner : Left) {
949 for (
unsigned i = 0; i < D.
Max; ++i) {
950 DiagList::iterator II, IE;
951 for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
954 if (LineNo1 != LineNo2)
962 const std::string &RightText = II->second;
963 if (D.
match(RightText))
968 if (i >= D.
Min)
break;
969 LeftOnly.push_back(&D);
978 if (!IgnoreUnexpected)
994 unsigned NumProblems = 0;
1026 setSourceManager(
SM);
1036 UnparsedFiles.erase(FID);
1037 ParsedFiles.insert(std::make_pair(FID, FE));
1038 }
else if (!ParsedFiles.count(FID) && !UnparsedFiles.count(FID)) {
1042 bool FoundDirectives;
1044 FoundDirectives =
false;
1049 UnparsedFiles.insert(std::make_pair(FID,
1050 UnparsedFileStatus(FE, FoundDirectives)));
1055 void VerifyDiagnosticConsumer::CheckDiagnostics() {
1058 std::unique_ptr<DiagnosticConsumer> Owner = Diags.
takeClient();
1068 if (!UnparsedFiles.empty()) {
1071 for (
const auto &I : ParsedFiles)
1073 ParsedFileCache.insert(FE);
1076 for (
const auto &I : UnparsedFiles) {
1077 const UnparsedFileStatus &Status = I.second;
1081 if (FE && ParsedFileCache.count(FE))
1085 if (Status.foundDirectives()) {
1086 llvm::report_fatal_error(Twine(
"-verify directives found after rather" 1087 " than during normal parsing of ",
1088 StringRef(FE ? FE->
getName() :
"(unknown)")));
1093 UnparsedFiles.clear();
1113 Buffer->err_end(),
"error");
1116 Buffer->warn_end(),
"warn");
1119 Buffer->remark_end(),
"remark");
1122 Buffer->note_end(),
"note");
1125 Diags.
setClient(CurClient, Owner.release() !=
nullptr);
1135 bool MatchAnyFileAndLine,
1136 bool MatchAnyLine, StringRef
Text,
1137 unsigned Min,
unsigned Max) {
1139 return std::make_unique<StandardDirective>(DirectiveLoc, DiagnosticLoc,
1140 MatchAnyFileAndLine,
1141 MatchAnyLine,
Text, Min, Max);
1144 std::string RegexStr;
1146 while (!S.empty()) {
1147 if (S.startswith(
"{{")) {
1148 S = S.drop_front(2);
1149 size_t RegexMatchLength = S.find(
"}}");
1150 assert(RegexMatchLength != StringRef::npos);
1153 RegexStr.append(S.data(), RegexMatchLength);
1155 S = S.drop_front(RegexMatchLength + 2);
1157 size_t VerbatimMatchLength = S.find(
"{{");
1158 if (VerbatimMatchLength == StringRef::npos)
1159 VerbatimMatchLength = S.size();
1161 RegexStr += llvm::Regex::escape(S.substr(0, VerbatimMatchLength));
1162 S = S.drop_front(VerbatimMatchLength);
1166 return std::make_unique<RegexDirective>(DirectiveLoc, DiagnosticLoc,
1167 MatchAnyFileAndLine, MatchAnyLine,
1168 Text, Min, Max, RegexStr);
static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)
getSpelling - This method is used to get the spelling of a token into a preallocated buffer,...
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
DiagnosticConsumer * getClient()
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
std::vector< std::unique_ptr< Directive > > DirectiveList
VerifyDiagnosticConsumer - Create a diagnostic client which will use markers in the input source to c...
Defines the clang::FileManager interface and associated types.
SourceManager & getSourceManager() const
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
unsigned NumErrors
Number of errors reported.
Defines the SourceManager interface.
void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS)
Update lists of parsed and unparsed files.
const_iterator remark_end() const
static unsigned CheckResults(DiagnosticsEngine &Diags, SourceManager &SourceMgr, const TextDiagnosticBuffer &Buffer, ExpectedData &ED)
CheckResults - This compares the expected results to those that were actually reported.
VerifyDiagnosticConsumer(DiagnosticsEngine &Diags)
Create a new verifying diagnostic client, which will issue errors to the currently-attached diagnosti...
bool isLoadedFileID(FileID FID) const
Returns true if FID came from a PCH/Module.
File has been processed via HandleComment.
const DiagnosticBuilder & setForceEmit() const
Forces the diagnostic to be emitted.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
std::unique_ptr< DiagnosticConsumer > takeClient()
Return the current diagnostic client along with ownership of that client.
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
virtual void EndSourceFile()
Callback to inform the diagnostic client that processing of a source file has ended.
SourceLocation DiagnosticLoc
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool hasSourceManager() const
This interface provides a way to observe the actions of the preprocessor as it does its thing.
void EndSourceFile() override
Callback to inform the diagnostic client that processing of a source file has ended.
static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, Preprocessor *PP, SourceLocation Pos, VerifyDiagnosticConsumer::DirectiveStatus &Status, VerifyDiagnosticConsumer::MarkerTracker &Markers)
ParseDirective - Go through the comment and see if it indicates expected diagnostics.
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
ExpectedData - owns directive objects and deletes on destructor.
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
Token - This structure provides full information about a lexed token.
const_iterator err_end() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const_iterator note_begin() const
const_iterator note_end() const
TextDiagnosticBuffer::DiagList DiagList
LLVM_READONLY bool isWhitespace(unsigned char c)
Return true if this character is horizontal or vertical ASCII whitespace: ' ', '\t',...
HeaderSearch & getHeaderSearchInfo() const
const SourceLocation & getLocation() const
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID.
Concrete class used by the front-end to report problems and issues.
void addMarker(StringRef MarkerName, SourceLocation Pos)
Defines the Diagnostic-related interfaces.
const_iterator err_begin() const
static unsigned PrintExpected(DiagnosticsEngine &Diags, SourceManager &SourceMgr, std::vector< Directive * > &DL, const char *Kind)
Takes a list of diagnostics that were expected to have been generated but were not and produces a dia...
DiagList::const_iterator const_iterator
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
StringRef getFilename(SourceLocation SpellingLoc) const
Return the filename of the file containing a SourceLocation.
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override
Handle this diagnostic, reporting it to the user or capturing it to a log as needed.
File has diagnostics but guaranteed no directives.
std::vector< std::pair< SourceLocation, std::string > > DiagList
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
const AnnotatedLine * Line
Defines the clang::Preprocessor interface.
static unsigned PrintUnexpected(DiagnosticsEngine &Diags, SourceManager *SourceMgr, const_diag_iterator diag_begin, const_diag_iterator diag_end, const char *Kind)
Takes a list of diagnostics that have been generated but not matched by an expected-* directive and p...
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
MarkerTracker(DiagnosticsEngine &Diags)
SourceLocation getEnd() const
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
DirectoryLookup - This class represents one entry in the search list that specifies the search order ...
bool HandleComment(Preprocessor &PP, SourceRange Comment) override
HandleComment - Hook into the preprocessor and extract comments containing expected errors and warnin...
SourceManager & getSourceManager() const
static bool IsFromSameFile(SourceManager &SM, SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc)
Determine whether two source locations come from the same file.
Encodes a location in the source.
StringRef getName() const
Cached information about one file (either on disk or in the virtual file system).
void addDirective(StringRef MarkerName, const UnattachedDirective &UD)
SourceManager & getSourceManager() const
virtual bool match(StringRef S)=0
File has diagnostics and may have directives.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
virtual bool isValid(std::string &Error)=0
const_iterator warn_end() const
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
static bool findDirectives(SourceManager &SM, FileID FID, const LangOptions &LangOpts)
Lex the specified source file to determine whether it contains any expected-* directives.
Optional< FileEntryRef > LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const FileEntry *FromFile, const DirectoryLookup *&CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false)
Given a "foo" or <foo> reference, look up the indicated file.
std::vector< std::string > VerifyPrefixes
The prefixes for comment directives sought by -verify ("expected" by default).
VerifyDiagnosticConsumer::DirectiveList DirectiveList
DiagnosticOptions & getDiagnosticOptions() const
Retrieve the diagnostic options.
VerifyDiagnosticConsumer::ExpectedData ExpectedData
~VerifyDiagnosticConsumer() override
TextDiagnosticBuffer::const_iterator const_diag_iterator
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
static std::unique_ptr< Directive > create(bool RegexKind, SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc, bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max)
Defines the PPCallbacks interface.
Defines the clang::TokenKind enum and support functions.
const_iterator warn_begin() const
Defines the clang::SourceLocation class and associated facilities.
static const unsigned MaxCount
Constant representing n or more matches.
DiagnosticsEngine & getDiagnostics() const
Level
The level of the diagnostic, after it has been through mapping.
const_iterator remark_begin() const
bool hasSourceManager() const
static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr, const char *Label, DirectiveList &Left, const_diag_iterator d2_begin, const_diag_iterator d2_end, bool IgnoreUnexpected)
CheckLists - Compare expected to seen diagnostic lists and return the the difference between them.
void SetCommentRetentionState(bool Mode)
SetCommentRetentionMode - Change the comment retention mode of the lexer to the specified mode.
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine) ...
DiagnosticLevelMask
A bitmask representing the diagnostic levels used by VerifyDiagnosticConsumer.
A trivial tuple used to represent a source range.
Directive - Abstract class representing a parsed verify directive.
virtual void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP=nullptr)
Callback to inform the diagnostic client that processing of a source file is beginning.
SourceLocation getBegin() const
VerifyDiagnosticConsumer::Directive Directive
This class handles loading and caching of source files into memory.
void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP) override
Callback to inform the diagnostic client that processing of a source file is beginning.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool ownsClient() const
Determine whether this DiagnosticsEngine object own its client.