diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -2836,7 +2836,7 @@ return false; if (!consume(tgtok::l_brace)) - return TokError("Expected ';' or '{' to start body"); + return TokError("Expected '{' to start body or ';' for declaration only"); // An object body introduces a new scope for local variables. TGLocalVarScope *BodyScope = PushLocalScope(); @@ -2849,6 +2849,14 @@ // Eat the '}'. Lex.Lex(); + + // If we have a semicolon, print a gentle error. + SMLoc SemiLoc = Lex.getLoc(); + if (consume(tgtok::semi)) { + PrintError(SemiLoc, "A class or def body should not end with a semicolon"); + PrintNote("Semicolon ignored; remove to eliminate this error"); + } + return false; } @@ -3432,6 +3440,13 @@ } Lex.Lex(); // eat the '}'. + // If we have a semicolon, print a gentle error. + SMLoc SemiLoc = Lex.getLoc(); + if (consume(tgtok::semi)) { + PrintError(SemiLoc, "A multiclass body should not end with a semicolon"); + PrintNote("Semicolon ignored; remove to eliminate this error"); + } + PopLocalScope(MulticlassScope); } @@ -3623,7 +3638,7 @@ if (Lex.getCode() == tgtok::Eof) return false; - return TokError("Unexpected input at top level"); + return TokError("Unexpected token at top level"); } // Check an assertion: Obtain the condition value and be sure it is true. diff --git a/llvm/test/TableGen/spurious-semi.td b/llvm/test/TableGen/spurious-semi.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/spurious-semi.td @@ -0,0 +1,39 @@ +// RUN: llvm-tblgen %s | FileCheck %s +// RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s + +// This file tests the error message that is printed when a body is +// terminated with a semicolon in addition to the close brace. + +// CHECK: class Class0 +// CHECK: def Rec0 + +class Class0 { +} + +def Rec0 { +} + +multiclass MC0 { + def R; +} + +#ifdef ERROR1 + +// ERROR1: error: A class or def body should not end with a semicolon +// ERROR1: Semicolon ignored +// ERROR1: error: A class or def body should not end with a semicolon +// ERROR1: Semicolon ignored +// ERROR1: error: A multiclass body should not end with a semicolon +// ERROR1: Semicolon ignored + +class Class1 { +}; + +def Rec1 { +}; + +multiclass MC1 { + def R; +}; + +#endif