///
class Directive {
public:
- static std::unique_ptr<Directive> create(bool RegexKind,
- SourceLocation DirectiveLoc,
- SourceLocation DiagnosticLoc,
- bool MatchAnyLine, StringRef Text,
- unsigned Min, unsigned Max);
+ static std::unique_ptr<Directive>
+ create(bool RegexKind, SourceLocation DirectiveLoc,
+ SourceLocation DiagnosticLoc, bool MatchAnyFileAndLine,
+ bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max);
public:
/// Constant representing n or more matches.
const std::string Text;
unsigned Min, Max;
bool MatchAnyLine;
+ bool MatchAnyFileAndLine; // `MatchAnyFileAndLine` implies `MatchAnyLine`.
Directive(const Directive &) = delete;
Directive &operator=(const Directive &) = delete;
protected:
Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
- bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max)
- : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
- Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
+ bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text,
+ unsigned Min, unsigned Max)
+ : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc), Text(Text),
+ Min(Min), Max(Max), MatchAnyLine(MatchAnyLine || MatchAnyFileAndLine),
+ MatchAnyFileAndLine(MatchAnyFileAndLine) {
assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) &&
"DiagnosticLoc is invalid!");
class StandardDirective : public Directive {
public:
StandardDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
- bool MatchAnyLine, StringRef Text, unsigned Min,
- unsigned Max)
- : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max) {}
+ bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text,
+ unsigned Min, unsigned Max)
+ : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFileAndLine,
+ MatchAnyLine, Text, Min, Max) {}
bool isValid(std::string &Error) override {
// all strings are considered valid; even empty ones
class RegexDirective : public Directive {
public:
RegexDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
- bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max,
- StringRef RegexStr)
- : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max),
+ bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text,
+ unsigned Min, unsigned Max, StringRef RegexStr)
+ : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFileAndLine,
+ MatchAnyLine, Text, Min, Max),
Regex(RegexStr) {}
bool isValid(std::string &Error) override {
// Attach the specified directive to the line of code indicated by
// \p ExpectedLoc.
void attachDirective(DiagnosticsEngine &Diags, const UnattachedDirective &UD,
- SourceLocation ExpectedLoc, bool MatchAnyLine = false) {
+ SourceLocation ExpectedLoc,
+ bool MatchAnyFileAndLine = false,
+ bool MatchAnyLine = false) {
// Construct new directive.
- std::unique_ptr<Directive> D =
- Directive::create(UD.RegexKind, UD.DirectivePos, ExpectedLoc,
- MatchAnyLine, UD.Text, UD.Min, UD.Max);
+ std::unique_ptr<Directive> D = Directive::create(
+ UD.RegexKind, UD.DirectivePos, ExpectedLoc, MatchAnyFileAndLine,
+ MatchAnyLine, UD.Text, UD.Min, UD.Max);
std::string Error;
if (!D->isValid(Error)) {
// Next optional token: @
SourceLocation ExpectedLoc;
StringRef Marker;
+ bool MatchAnyFileAndLine = false;
bool MatchAnyLine = false;
if (!PH.Next("@")) {
ExpectedLoc = Pos;
StringRef Filename(PH.C, PH.P-PH.C);
PH.Advance();
- // Lookup file via Preprocessor, like a #include.
- const DirectoryLookup *CurDir;
- Optional<FileEntryRef> File =
- PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir,
- nullptr, nullptr, nullptr, nullptr, nullptr);
- if (!File) {
- Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
- diag::err_verify_missing_file) << Filename << KindStr;
- continue;
- }
-
- const FileEntry *FE = &File->getFileEntry();
- if (SM.translateFile(FE).isInvalid())
- SM.createFileID(FE, Pos, SrcMgr::C_User);
-
- if (PH.Next(Line) && Line > 0)
- ExpectedLoc = SM.translateFileLineCol(FE, Line, 1);
- else if (PH.Next("*")) {
+ if (Filename == "*") {
+ MatchAnyFileAndLine = true;
+ if (!PH.Next("*")) {
+ Diags.Report(Pos.getLocWithOffset(PH.C - PH.Begin),
+ diag::err_verify_missing_line)
+ << "'*'";
+ continue;
+ }
MatchAnyLine = true;
- ExpectedLoc = SM.translateFileLineCol(FE, 1, 1);
+ ExpectedLoc = SourceLocation();
+ } else {
+ // Lookup file via Preprocessor, like a #include.
+ const DirectoryLookup *CurDir;
+ Optional<FileEntryRef> File =
+ PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir,
+ nullptr, nullptr, nullptr, nullptr, nullptr);
+ if (!File) {
+ Diags.Report(Pos.getLocWithOffset(PH.C - PH.Begin),
+ diag::err_verify_missing_file)
+ << Filename << KindStr;
+ continue;
+ }
+
+ const FileEntry *FE = &File->getFileEntry();
+ if (SM.translateFile(FE).isInvalid())
+ SM.createFileID(FE, Pos, SrcMgr::C_User);
+
+ if (PH.Next(Line) && Line > 0)
+ ExpectedLoc = SM.translateFileLineCol(FE, Line, 1);
+ else if (PH.Next("*")) {
+ MatchAnyLine = true;
+ ExpectedLoc = SM.translateFileLineCol(FE, 1, 1);
+ }
}
} else if (PH.Next("*")) {
MatchAnyLine = true;
}
if (Marker.empty())
- attachDirective(Diags, D, ExpectedLoc, MatchAnyLine);
+ attachDirective(Diags, D, ExpectedLoc, MatchAnyFileAndLine, MatchAnyLine);
else
Markers.addDirective(Marker, D);
FoundDirective = true;
SmallString<256> Fmt;
llvm::raw_svector_ostream OS(Fmt);
for (const auto *D : DL) {
- if (D->DiagnosticLoc.isInvalid())
+ if (D->DiagnosticLoc.isInvalid() || D->MatchAnyFileAndLine)
OS << "\n File *";
else
OS << "\n File " << SourceMgr.getFilename(D->DiagnosticLoc);
continue;
}
- if (!D.DiagnosticLoc.isInvalid() &&
+ if (!D.DiagnosticLoc.isInvalid() && !D.MatchAnyFileAndLine &&
!IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first))
continue;
std::unique_ptr<Directive> Directive::create(bool RegexKind,
SourceLocation DirectiveLoc,
SourceLocation DiagnosticLoc,
+ bool MatchAnyFileAndLine,
bool MatchAnyLine, StringRef Text,
unsigned Min, unsigned Max) {
if (!RegexKind)
return std::make_unique<StandardDirective>(DirectiveLoc, DiagnosticLoc,
- MatchAnyLine, Text, Min, Max);
+ MatchAnyFileAndLine,
+ MatchAnyLine, Text, Min, Max);
// Parse the directive into a regular expression.
std::string RegexStr;
}
}
- return std::make_unique<RegexDirective>(
- DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max, RegexStr);
+ return std::make_unique<RegexDirective>(DirectiveLoc, DiagnosticLoc,
+ MatchAnyFileAndLine, MatchAnyLine,
+ Text, Min, Max, RegexStr);
}