[cfe-commits] r159979 - in /cfe/trunk: include/clang/Basic/DiagnosticFrontendKinds.td include/clang/Frontend/VerifyDiagnosticConsumer.h lib/Frontend/VerifyDiagnosticConsumer.cpp
Jordan Rose
jordan_rose at apple.com
Mon Jul 9 19:57:26 PDT 2012
Author: jrose
Date: Mon Jul 9 21:57:26 2012
New Revision: 159979
URL: http://llvm.org/viewvc/llvm-project?rev=159979&view=rev
Log:
Allow -verify directives to specify a min and max count, not just "+".
void f(); // expected-note 0+ {{previous declaration is here}}
void g(); // expected-note 0-1 {{previous declaration is here}}
The old "+" syntax is still an alias for "1+", and single numbers still work.
Patch by Andy Gibbs!
Modified:
cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h
cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td?rev=159979&r1=159978&r2=159979&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td Mon Jul 9 21:57:26 2012
@@ -65,6 +65,8 @@
def err_verify_missing_line : Error<
"missing or invalid line number following '@' in expected %0">;
+def err_verify_invalid_range : Error<
+ "invalid range following '-' in expected %0">;
def err_verify_missing_start : Error<
"cannot find start ('{{') of expected %0">;
def err_verify_missing_end : Error<
Modified: cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h?rev=159979&r1=159978&r2=159979&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h (original)
+++ cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h Mon Jul 9 21:57:26 2012
@@ -47,8 +47,10 @@
/// Alternatively, it is possible to specify the line on which the diagnostic
/// should appear by appending "@<line>" to "expected-<type>", for example:
///
+/// \code
/// #warning some text
/// // expected-warning at 10 {{some text}}
+/// \endcode
///
/// The line number may be absolute (as above), or relative to the current
/// line by prefixing the number with either '+' or '-'.
@@ -63,6 +65,31 @@
/// void f(); // expected-note 2 {{previous declaration is here}}
/// \endcode
///
+/// Where the diagnostic is expected to occur a minimum number of times, this
+/// can be specified by appending a '+' to the number. Example:
+///
+/// \code
+/// void f(); // expected-note 0+ {{previous declaration is here}}
+/// void g(); // expected-note 1+ {{previous declaration is here}}
+/// \endcode
+///
+/// In the first example, the diagnostic becomes optional, i.e. it will be
+/// swallowed if it occurs, but will not generate an error if it does not
+/// occur. In the second example, the diagnostic must occur at least once.
+/// As a short-hand, "one or more" can be specified simply by '+'. Example:
+///
+/// \code
+/// void g(); // expected-note + {{previous declaration is here}}
+/// \endcode
+///
+/// A range can also be specified by "<n>-<m>". Example:
+///
+/// \code
+/// void f(); // expected-note 0-1 {{previous declaration is here}}
+/// \endcode
+///
+/// In this example, the diagnostic may appear only once, if at all.
+///
/// Regex matching mode may be selected by appending '-re' to type. Example:
///
/// expected-error-re
@@ -85,15 +112,15 @@
public:
static Directive *create(bool RegexKind, SourceLocation DirectiveLoc,
SourceLocation DiagnosticLoc,
- StringRef Text, unsigned Count);
+ StringRef Text, unsigned Min, unsigned Max);
public:
- /// Constant representing one or more matches aka regex "+".
- static const unsigned OneOrMoreCount = UINT_MAX;
+ /// Constant representing n or more matches.
+ static const unsigned MaxCount = UINT_MAX;
SourceLocation DirectiveLoc;
SourceLocation DiagnosticLoc;
const std::string Text;
- unsigned Count;
+ unsigned Min, Max;
virtual ~Directive() { }
@@ -106,9 +133,12 @@
protected:
Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
- StringRef Text, unsigned Count)
+ StringRef Text, unsigned Min, unsigned Max)
: DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
- Text(Text), Count(Count) { }
+ Text(Text), Min(Min), Max(Max) {
+ assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
+ assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!");
+ }
private:
Directive(const Directive&); // DO NOT IMPLEMENT
Modified: cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp?rev=159979&r1=159978&r2=159979&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp (original)
+++ cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp Mon Jul 9 21:57:26 2012
@@ -84,8 +84,8 @@
class StandardDirective : public Directive {
public:
StandardDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
- StringRef Text, unsigned Count)
- : Directive(DirectiveLoc, DiagnosticLoc, Text, Count) { }
+ StringRef Text, unsigned Min, unsigned Max)
+ : Directive(DirectiveLoc, DiagnosticLoc, Text, Min, Max) { }
virtual bool isValid(std::string &Error) {
// all strings are considered valid; even empty ones
@@ -102,8 +102,8 @@
class RegexDirective : public Directive {
public:
RegexDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
- StringRef Text, unsigned Count)
- : Directive(DirectiveLoc, DiagnosticLoc, Text, Count), Regex(Text) { }
+ StringRef Text, unsigned Min, unsigned Max)
+ : Directive(DirectiveLoc, DiagnosticLoc, Text, Min, Max), Regex(Text) { }
virtual bool isValid(std::string &Error) {
if (Regex.isValid(Error))
@@ -264,11 +264,29 @@
PH.SkipWhitespace();
// Next optional token: positive integer or a '+'.
- unsigned Count = 1;
- if (PH.Next(Count))
+ unsigned Min = 1;
+ unsigned Max = 1;
+ if (PH.Next(Min)) {
PH.Advance();
- else if (PH.Next("+")) {
- Count = Directive::OneOrMoreCount;
+ // A positive integer can be followed by a '+' meaning min
+ // or more, or by a '-' meaning a range from min to max.
+ if (PH.Next("+")) {
+ Max = Directive::MaxCount;
+ PH.Advance();
+ } else if (PH.Next("-")) {
+ PH.Advance();
+ if (!PH.Next(Max) || Max < Min) {
+ Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
+ diag::err_verify_invalid_range) << KindStr;
+ continue;
+ }
+ PH.Advance();
+ } else {
+ Max = Min;
+ }
+ } else if (PH.Next("+")) {
+ // '+' on its own means "1 or more".
+ Max = Directive::MaxCount;
PH.Advance();
}
@@ -308,7 +326,8 @@
Text.assign(ContentBegin, ContentEnd);
// Construct new directive.
- Directive *D = Directive::create(RegexKind, Pos, ExpectedLoc, Text, Count);
+ Directive *D = Directive::create(RegexKind, Pos, ExpectedLoc, Text,
+ Min, Max);
std::string Error;
if (D->isValid(Error))
DL->push_back(D);
@@ -411,9 +430,8 @@
for (DirectiveList::iterator I = Left.begin(), E = Left.end(); I != E; ++I) {
Directive& D = **I;
unsigned LineNo1 = SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
- bool FoundOnce = false;
- for (unsigned i = 0; i < D.Count; ++i) {
+ for (unsigned i = 0; i < D.Max; ++i) {
DiagList::iterator II, IE;
for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
unsigned LineNo2 = SourceMgr.getPresumedLineNumber(II->first);
@@ -425,18 +443,12 @@
break;
}
if (II == IE) {
- if (D.Count == D.OneOrMoreCount) {
- if (!FoundOnce)
- LeftOnly.push_back(*I);
- // We are only interested in at least one match, so exit the loop.
- break;
- }
// Not found.
+ if (i >= D.Min) break;
LeftOnly.push_back(*I);
} else {
// Found. The same cannot be found twice.
Right.erase(II);
- FoundOnce = true;
}
}
}
@@ -527,8 +539,8 @@
Directive *Directive::create(bool RegexKind, SourceLocation DirectiveLoc,
SourceLocation DiagnosticLoc, StringRef Text,
- unsigned Count) {
+ unsigned Min, unsigned Max) {
if (RegexKind)
- return new RegexDirective(DirectiveLoc, DiagnosticLoc, Text, Count);
- return new StandardDirective(DirectiveLoc, DiagnosticLoc, Text, Count);
+ return new RegexDirective(DirectiveLoc, DiagnosticLoc, Text, Min, Max);
+ return new StandardDirective(DirectiveLoc, DiagnosticLoc, Text, Min, Max);
}
More information about the cfe-commits
mailing list