diff -U 3 -dHrN include/clang/Basic/DiagnosticFrontendKinds.td include/clang/Basic/DiagnosticFrontendKinds.td
--- include/clang/Basic/DiagnosticFrontendKinds.td	2012-06-25 16:22:07.000000000 +0200
+++ include/clang/Basic/DiagnosticFrontendKinds.td	2012-06-25 16:01:13.000000000 +0200
@@ -63,6 +63,8 @@
     "unable to open file %0 for serializing diagnostics (%1)">,
     InGroup<DiagGroup<"serialized-diagnostics">>;
 
+def err_verify_missing_line : Error<
+    "missing or invalid line number following '@' in expected %0">;
 def err_verify_missing_start : Error<
     "cannot find start ('{{') of expected %0">;
 def err_verify_missing_end : Error<
diff -U 3 -dHrN include/clang/Frontend/VerifyDiagnosticConsumer.h include/clang/Frontend/VerifyDiagnosticConsumer.h
--- include/clang/Frontend/VerifyDiagnosticConsumer.h	2012-06-25 16:21:20.000000000 +0200
+++ include/clang/Frontend/VerifyDiagnosticConsumer.h	2012-06-25 16:23:24.000000000 +0200
@@ -43,6 +43,15 @@
 /// You can place as many diagnostics on one line as you wish. To make the code
 /// more readable, you can use slash-newline to separate out the diagnostics.
 ///
+/// Alternatively, it is possible to specify the line on which the diagnostic
+/// should appear by appending "@<line>" to "expected-<type>", for example:
+///
+///   #warning some text
+///   // expected-warning@10 {{some text}}
+///
+/// The line number may be absolute (as above), or relative to the current
+/// line by prefixing the number with either '+' or '-'.
+///
 /// The simple syntax above allows each specification to match exactly one
 /// error.  You can use the extended syntax to customize this. The extended
 /// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of
diff -U 3 -dHrN lib/Frontend/VerifyDiagnosticConsumer.cpp lib/Frontend/VerifyDiagnosticConsumer.cpp
--- lib/Frontend/VerifyDiagnosticConsumer.cpp	2012-06-25 16:21:20.000000000 +0200
+++ lib/Frontend/VerifyDiagnosticConsumer.cpp	2012-06-25 16:26:11.000000000 +0200
@@ -193,6 +193,8 @@
 static void ParseDirective(const char *CommentStart, unsigned CommentLen,
                            ExpectedData &ED, Preprocessor &PP,
                            SourceLocation Pos) {
+  SourceManager &SM = PP.getSourceManager();
+
   // A single comment may contain multiple directives.
   for (ParseHelper PH(CommentStart, CommentStart+CommentLen); !PH.Done();) {
     // search for token: expected
@@ -228,6 +230,45 @@
       KindStr = "regex";
     }
 
+    // next optional token: @
+    SourceLocation RealPos = Pos;
+    if (PH.Next("@")) {
+      PH.Advance();
+      unsigned Line = 0;
+      if (PH.Next("-")) { // previous to current line
+        PH.Advance();
+        bool Invalid = false;
+        unsigned CurrentLine = SM.getSpellingLineNumber(Pos, &Invalid);
+        if (Invalid || !PH.Next(Line) || Line >= CurrentLine ||
+              (RealPos = SM.translateLineCol(SM.getFileID(Pos),
+                                          CurrentLine - Line, 1)).isInvalid()) {
+          PP.Diag(Pos.getLocWithOffset(PH.C-PH.Begin),
+                  diag::err_verify_missing_line) << KindStr;
+          continue;
+        }
+      } else if (PH.Next("+")) { // subsequent to current line
+        PH.Advance();
+        bool Invalid = false;
+        unsigned CurrentLine = SM.getSpellingLineNumber(Pos, &Invalid);
+        if (Invalid || !PH.Next(Line) ||
+              (RealPos = SM.translateLineCol(SM.getFileID(Pos),
+                                          CurrentLine + Line, 1)).isInvalid()) {
+          PP.Diag(Pos.getLocWithOffset(PH.C-PH.Begin),
+                  diag::err_verify_missing_line) << KindStr;
+          continue;
+        }
+      } else { // absolute line number
+        if (!PH.Next(Line) || Line < 1 ||
+                (RealPos = SM.translateLineCol(SM.getFileID(Pos),
+                                               Line, 1)).isInvalid()) {
+          PP.Diag(Pos.getLocWithOffset(PH.C-PH.Begin),
+                  diag::err_verify_missing_line) << KindStr;
+          continue;
+        }
+      }
+      PH.Advance();
+    }
+
     // skip optional whitespace
     PH.SkipWhitespace();
 
@@ -276,7 +317,7 @@
       Text.assign(ContentBegin, ContentEnd);
 
     // construct new directive
-    Directive *D = Directive::Create(RegexKind, Pos, Text, Count);
+    Directive *D = Directive::Create(RegexKind, RealPos, Text, Count);
     std::string Error;
     if (D->isValid(Error))
       DL->push_back(D);
