forked from OSchip/llvm-project
Clean up VerifyDiagnosticsConsumer in preparation for upcoming enhancements.
Patch by Andy Gibbs! llvm-svn: 159977
This commit is contained in:
parent
50f5f46a93
commit
6dae761810
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include <climits>
|
||||
|
||||
namespace clang {
|
||||
|
||||
|
@ -68,13 +70,62 @@ class TextDiagnosticBuffer;
|
|||
///
|
||||
class VerifyDiagnosticConsumer: public DiagnosticConsumer {
|
||||
public:
|
||||
/// Directive - Abstract class representing a parsed verify directive.
|
||||
///
|
||||
class Directive {
|
||||
public:
|
||||
static Directive *create(bool RegexKind, const SourceLocation &Location,
|
||||
StringRef Text, unsigned Count);
|
||||
public:
|
||||
/// Constant representing one or more matches aka regex "+".
|
||||
static const unsigned OneOrMoreCount = UINT_MAX;
|
||||
|
||||
SourceLocation Location;
|
||||
const std::string Text;
|
||||
unsigned Count;
|
||||
|
||||
virtual ~Directive() { }
|
||||
|
||||
// Returns true if directive text is valid.
|
||||
// Otherwise returns false and populates E.
|
||||
virtual bool isValid(std::string &Error) = 0;
|
||||
|
||||
// Returns true on match.
|
||||
virtual bool match(StringRef S) = 0;
|
||||
|
||||
protected:
|
||||
Directive(const SourceLocation &Location, StringRef Text,
|
||||
unsigned Count)
|
||||
: Location(Location), Text(Text), Count(Count) { }
|
||||
|
||||
private:
|
||||
Directive(const Directive&); // DO NOT IMPLEMENT
|
||||
void operator=(const Directive&); // DO NOT IMPLEMENT
|
||||
};
|
||||
|
||||
typedef std::vector<Directive*> DirectiveList;
|
||||
|
||||
/// ExpectedData - owns directive objects and deletes on destructor.
|
||||
///
|
||||
struct ExpectedData {
|
||||
DirectiveList Errors;
|
||||
DirectiveList Warnings;
|
||||
DirectiveList Notes;
|
||||
|
||||
~ExpectedData() {
|
||||
llvm::DeleteContainerPointers(Errors);
|
||||
llvm::DeleteContainerPointers(Warnings);
|
||||
llvm::DeleteContainerPointers(Notes);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
DiagnosticsEngine &Diags;
|
||||
DiagnosticConsumer *PrimaryClient;
|
||||
bool OwnsPrimaryClient;
|
||||
OwningPtr<TextDiagnosticBuffer> Buffer;
|
||||
Preprocessor *CurrentPreprocessor;
|
||||
|
||||
private:
|
||||
ExpectedData ED;
|
||||
FileID FirstErrorFID; // FileID of first diagnostic
|
||||
void CheckDiagnostics();
|
||||
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/Regex.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <climits>
|
||||
|
||||
using namespace clang;
|
||||
typedef VerifyDiagnosticConsumer::Directive Directive;
|
||||
typedef VerifyDiagnosticConsumer::DirectiveList DirectiveList;
|
||||
typedef VerifyDiagnosticConsumer::ExpectedData ExpectedData;
|
||||
|
||||
VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &_Diags)
|
||||
: Diags(_Diags), PrimaryClient(Diags.getClient()),
|
||||
|
@ -77,44 +79,11 @@ typedef TextDiagnosticBuffer::const_iterator const_diag_iterator;
|
|||
|
||||
namespace {
|
||||
|
||||
/// Directive - Abstract class representing a parsed verify directive.
|
||||
///
|
||||
class Directive {
|
||||
public:
|
||||
static Directive* Create(bool RegexKind, const SourceLocation &Location,
|
||||
const std::string &Text, unsigned Count);
|
||||
public:
|
||||
/// Constant representing one or more matches aka regex "+".
|
||||
static const unsigned OneOrMoreCount = UINT_MAX;
|
||||
|
||||
SourceLocation Location;
|
||||
const std::string Text;
|
||||
unsigned Count;
|
||||
|
||||
virtual ~Directive() { }
|
||||
|
||||
// Returns true if directive text is valid.
|
||||
// Otherwise returns false and populates E.
|
||||
virtual bool isValid(std::string &Error) = 0;
|
||||
|
||||
// Returns true on match.
|
||||
virtual bool Match(const std::string &S) = 0;
|
||||
|
||||
protected:
|
||||
Directive(const SourceLocation &Location, const std::string &Text,
|
||||
unsigned Count)
|
||||
: Location(Location), Text(Text), Count(Count) { }
|
||||
|
||||
private:
|
||||
Directive(const Directive&); // DO NOT IMPLEMENT
|
||||
void operator=(const Directive&); // DO NOT IMPLEMENT
|
||||
};
|
||||
|
||||
/// StandardDirective - Directive with string matching.
|
||||
///
|
||||
class StandardDirective : public Directive {
|
||||
public:
|
||||
StandardDirective(const SourceLocation &Location, const std::string &Text,
|
||||
StandardDirective(const SourceLocation &Location, StringRef Text,
|
||||
unsigned Count)
|
||||
: Directive(Location, Text, Count) { }
|
||||
|
||||
|
@ -123,8 +92,8 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual bool Match(const std::string &S) {
|
||||
return S.find(Text) != std::string::npos;
|
||||
virtual bool match(StringRef S) {
|
||||
return S.find(Text) != StringRef::npos;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -132,7 +101,7 @@ public:
|
|||
///
|
||||
class RegexDirective : public Directive {
|
||||
public:
|
||||
RegexDirective(const SourceLocation &Location, const std::string &Text,
|
||||
RegexDirective(const SourceLocation &Location, StringRef Text,
|
||||
unsigned Count)
|
||||
: Directive(Location, Text, Count), Regex(Text) { }
|
||||
|
||||
|
@ -142,7 +111,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual bool Match(const std::string &S) {
|
||||
virtual bool match(StringRef S) {
|
||||
return Regex.match(S);
|
||||
}
|
||||
|
||||
|
@ -150,25 +119,6 @@ private:
|
|||
llvm::Regex Regex;
|
||||
};
|
||||
|
||||
typedef std::vector<Directive*> DirectiveList;
|
||||
|
||||
/// ExpectedData - owns directive objects and deletes on destructor.
|
||||
///
|
||||
struct ExpectedData {
|
||||
DirectiveList Errors;
|
||||
DirectiveList Warnings;
|
||||
DirectiveList Notes;
|
||||
|
||||
~ExpectedData() {
|
||||
DirectiveList* Lists[] = { &Errors, &Warnings, &Notes, 0 };
|
||||
for (DirectiveList **PL = Lists; *PL; ++PL) {
|
||||
DirectiveList * const L = *PL;
|
||||
for (DirectiveList::iterator I = L->begin(), E = L->end(); I != E; ++I)
|
||||
delete *I;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ParseHelper
|
||||
{
|
||||
public:
|
||||
|
@ -241,8 +191,8 @@ private:
|
|||
/// diagnostics. If so, then put them in the appropriate directive list.
|
||||
///
|
||||
static void ParseDirective(const char *CommentStart, unsigned CommentLen,
|
||||
ExpectedData &ED, Preprocessor &PP,
|
||||
SourceLocation Pos) {
|
||||
ExpectedData &ED, SourceManager &SM,
|
||||
SourceLocation Pos, DiagnosticsEngine &Diags) {
|
||||
// A single comment may contain multiple directives.
|
||||
for (ParseHelper PH(CommentStart, CommentStart+CommentLen); !PH.Done();) {
|
||||
// search for token: expected
|
||||
|
@ -295,8 +245,8 @@ static void ParseDirective(const char *CommentStart, unsigned CommentLen,
|
|||
|
||||
// next token: {{
|
||||
if (!PH.Next("{{")) {
|
||||
PP.Diag(Pos.getLocWithOffset(PH.C-PH.Begin),
|
||||
diag::err_verify_missing_start) << KindStr;
|
||||
Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
|
||||
diag::err_verify_missing_start) << KindStr;
|
||||
continue;
|
||||
}
|
||||
PH.Advance();
|
||||
|
@ -304,8 +254,8 @@ static void ParseDirective(const char *CommentStart, unsigned CommentLen,
|
|||
|
||||
// search for token: }}
|
||||
if (!PH.Search("}}")) {
|
||||
PP.Diag(Pos.getLocWithOffset(PH.C-PH.Begin),
|
||||
diag::err_verify_missing_end) << KindStr;
|
||||
Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
|
||||
diag::err_verify_missing_end) << KindStr;
|
||||
continue;
|
||||
}
|
||||
const char* const ContentEnd = PH.P; // mark content end
|
||||
|
@ -326,13 +276,13 @@ static void ParseDirective(const char *CommentStart, unsigned CommentLen,
|
|||
Text.assign(ContentBegin, ContentEnd);
|
||||
|
||||
// construct new directive
|
||||
Directive *D = Directive::Create(RegexKind, Pos, Text, Count);
|
||||
Directive *D = Directive::create(RegexKind, Pos, Text, Count);
|
||||
std::string Error;
|
||||
if (D->isValid(Error))
|
||||
DL->push_back(D);
|
||||
else {
|
||||
PP.Diag(Pos.getLocWithOffset(ContentBegin-PH.Begin),
|
||||
diag::err_verify_invalid_content)
|
||||
Diags.Report(Pos.getLocWithOffset(ContentBegin-PH.Begin),
|
||||
diag::err_verify_invalid_content)
|
||||
<< KindStr << Error;
|
||||
}
|
||||
}
|
||||
|
@ -363,7 +313,8 @@ static void FindExpectedDiags(Preprocessor &PP, ExpectedData &ED, FileID FID) {
|
|||
if (Comment.empty()) continue;
|
||||
|
||||
// Find all expected errors/warnings/notes.
|
||||
ParseDirective(&Comment[0], Comment.size(), ED, PP, Tok.getLocation());
|
||||
ParseDirective(&Comment[0], Comment.size(), ED, SM, Tok.getLocation(),
|
||||
PP.getDiagnostics());
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -439,7 +390,7 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
|
|||
continue;
|
||||
|
||||
const std::string &RightText = II->second;
|
||||
if (D.Match(RightText))
|
||||
if (D.match(RightText))
|
||||
break;
|
||||
}
|
||||
if (II == IE) {
|
||||
|
@ -495,8 +446,6 @@ static unsigned CheckResults(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
|
|||
}
|
||||
|
||||
void VerifyDiagnosticConsumer::CheckDiagnostics() {
|
||||
ExpectedData ED;
|
||||
|
||||
// Ensure any diagnostics go to the primary client.
|
||||
bool OwnsCurClient = Diags.ownsClient();
|
||||
DiagnosticConsumer *CurClient = Diags.takeClient();
|
||||
|
@ -549,8 +498,8 @@ VerifyDiagnosticConsumer::clone(DiagnosticsEngine &Diags) const {
|
|||
return new VerifyDiagnosticConsumer(Diags);
|
||||
}
|
||||
|
||||
Directive* Directive::Create(bool RegexKind, const SourceLocation &Location,
|
||||
const std::string &Text, unsigned Count) {
|
||||
Directive *Directive::create(bool RegexKind, const SourceLocation &Location,
|
||||
StringRef Text, unsigned Count) {
|
||||
if (RegexKind)
|
||||
return new RegexDirective(Location, Text, Count);
|
||||
return new StandardDirective(Location, Text, Count);
|
||||
|
|
Loading…
Reference in New Issue