Skip to content

Commit 196e6f9

Browse files
Paul C. Anagnostopoulosnhaehnle
authored andcommitted
Replace TableGen range piece punctuator with '...'
The TableGen range piece punctuator is currently '-' (e.g., {0-9}), which interacts oddly with the fact that an integer literal's sign is part of the literal. This patch replaces the '-' with the new punctuator '...'. The '-' punctuator is deprecated. Differential Revision: https://reviews.llvm.org/D85585 Change-Id: I3d53d14e23f878b142d8f84590dd465a0fb6c09c
1 parent 503deec commit 196e6f9

File tree

6 files changed

+110
-5
lines changed

6 files changed

+110
-5
lines changed

llvm/docs/ReleaseNotes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ Changes to the LLVM IR
6565
Changes to building LLVM
6666
------------------------
6767

68+
Changes to TableGen
69+
-------------------
70+
71+
* The syntax for specifying an integer range in a range list has changed.
72+
The old syntax used a hyphen in the range (e.g., ``{0-9}``). The new syntax
73+
uses the "`...`" range punctuator (e.g., ``{0...9}``). The hyphen syntax
74+
is deprecated. The "TableGen Language Reference" document has been updated.
75+
6876
Changes to the ARM Backend
6977
--------------------------
7078

llvm/docs/TableGen/ProgRef.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ to an entity of type ``bits<4>``.
321321
:| "." `TokIdentifier`
322322
RangeList: `RangePiece` ("," `RangePiece`)*
323323
RangePiece: `TokInteger`
324-
:| `TokInteger` ".." `TokInteger`
324+
:| `TokInteger` "..." `TokInteger`
325325
:| `TokInteger` "-" `TokInteger`
326326
:| `TokInteger` `TokInteger`
327327

llvm/lib/TableGen/TGLexer.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ tgtok::TokKind TGLexer::LexToken(bool FileOrLineStart) {
161161

162162
case ':': return tgtok::colon;
163163
case ';': return tgtok::semi;
164-
case '.': return tgtok::period;
165164
case ',': return tgtok::comma;
166165
case '<': return tgtok::less;
167166
case '>': return tgtok::greater;
@@ -181,6 +180,19 @@ tgtok::TokKind TGLexer::LexToken(bool FileOrLineStart) {
181180

182181
return tgtok::paste;
183182

183+
// The period is a separate case so we can recognize the "..."
184+
// range punctuator.
185+
case '.':
186+
if (peekNextChar(0) == '.') {
187+
++CurPtr; // Eat second dot.
188+
if (peekNextChar(0) == '.') {
189+
++CurPtr; // Eat third dot.
190+
return tgtok::dotdotdot;
191+
}
192+
return ReturnError(TokStart, "Invalid '..' punctuation");
193+
}
194+
return tgtok::dot;
195+
184196
case '\r':
185197
PrintFatalError("getNextChar() must never return '\r'");
186198
return tgtok::Error;

llvm/lib/TableGen/TGLexer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ namespace tgtok {
4040
l_paren, r_paren, // ( )
4141
less, greater, // < >
4242
colon, semi, // : ;
43-
comma, period, // , .
43+
comma, dot, // , .
4444
equal, question, // = ?
4545
paste, // #
46+
dotdotdot, // ...
4647

4748
// Keywords. ('ElseKW' is named to distinguish it from the existing 'Else'
4849
// that means the preprocessor #else.)

llvm/lib/TableGen/TGParser.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,10 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
671671

672672
/// ParseRangePiece - Parse a bit/value range.
673673
/// RangePiece ::= INTVAL
674+
/// RangePiece ::= INTVAL '...' INTVAL
674675
/// RangePiece ::= INTVAL '-' INTVAL
675-
/// RangePiece ::= INTVAL INTVAL
676+
/// RangePiece ::= INTVAL INTVAL
677+
// The last two forms are deprecated.
676678
bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
677679
TypedInit *FirstItem) {
678680
Init *CurVal = FirstItem;
@@ -693,6 +695,8 @@ bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
693695
default:
694696
Ranges.push_back(Start);
695697
return false;
698+
699+
case tgtok::dotdotdot:
696700
case tgtok::minus: {
697701
Lex.Lex(); // eat
698702

@@ -2167,7 +2171,7 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
21672171
}
21682172
break;
21692173
}
2170-
case tgtok::period: {
2174+
case tgtok::dot: {
21712175
if (Lex.Lex() != tgtok::Id) { // eat the .
21722176
TokError("expected field identifier after '.'");
21732177
return nullptr;

llvm/test/TableGen/range-lists.td

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// RUN: llvm-tblgen %s | FileCheck %s
2+
// XFAIL: vg_leak
3+
4+
// This file has tests for range lists and range pieces.
5+
6+
// These are tests for bits ranges.
7+
8+
def bit_range_hyphen {
9+
bits<16> field1;
10+
let field1{15, 14, 13, 12} = {1, 0, 1, 0};
11+
let field1{11-8} = {1, 0, 1, 1};
12+
let field1{+7-4} = {1, 1, 0, 0};
13+
let field1{+3-+0} = {1, 1, 0, 1};
14+
bit hyphen_field1_ok = !eq(field1, 0xABCD);
15+
}
16+
17+
def bit_range_dotdotdot {
18+
bits<16> field1;
19+
let field1{15, 14, 13, 12} = {1, 0, 1, 0};
20+
let field1{11...8} = {1, 0, 1, 1};
21+
let field1{+7...4} = {1, 1, 0, 0};
22+
let field1{+3...+0} = {1, 1, 0, 1};
23+
bit dotdotdot_field1_ok = !eq(field1, 0xABCD);
24+
}
25+
26+
if !eq(bit_range_hyphen.field1, bit_range_dotdotdot.field1) then
27+
def bit_range_ok {}
28+
else
29+
def bit_range_not_ok {}
30+
31+
// These are tests for lists.
32+
33+
def list_range_hyphen {
34+
list<string> field1 = ["foo", "bar", "baz", "snork", "quux", "quuux",
35+
"bazola", "ztesch", "bletch", "flarp"];
36+
list<string> subfielda = field1[0, 1, 2, 3];
37+
list<string> subfieldb = field1[4-5];
38+
list<string> subfieldc = field1[+6-7];
39+
list<string> subfieldd = field1[+8-+9];
40+
bit hyphen_subfields_ok = !and(!eq(subfieldb[0], "quux"),
41+
!eq(subfieldd[1], "flarp"));
42+
}
43+
44+
def list_range_dotdotdot {
45+
list<string> field1 = ["foo", "bar", "baz", "snork", "quux", "quuux",
46+
"bazola", "ztesch", "bletch", "flarp"];
47+
list<string> subfielda = field1[0, 1, 2, 3];
48+
list<string> subfieldb = field1[4...5];
49+
list<string> subfieldc = field1[+6...7];
50+
list<string> subfieldd = field1[+8...+9];
51+
bit dotdotdot_subfields_ok = !and(!eq(subfieldb[0], "quux"),
52+
!eq(subfieldd[1], "flarp"));
53+
}
54+
55+
if !eq(!head(list_range_hyphen.subfieldd),
56+
!head(list_range_dotdotdot.subfieldd)) then
57+
def list_range_ok {}
58+
else
59+
def list_range_not_ok {}
60+
61+
// This is a test of foreach.
62+
63+
foreach i = {0-3} in
64+
foreach j = {4...5} in
65+
def eachrec#i#j {
66+
int fi = i;
67+
int fj = j;
68+
}
69+
70+
//CHECK: bit dotdotdot_field1_ok = 1
71+
//CHECK: bit hyphen_field1_ok = 1
72+
//CHECK: def bit_range_ok {
73+
74+
//CHECK: def eachrec04 {
75+
//CHECK: def eachrec35 {
76+
77+
//CHECK: bit dotdotdot_subfields_ok = 1
78+
//CHECK: bit hyphen_subfields_ok = 1
79+
//CHECK: def list_range_ok {
80+

0 commit comments

Comments
 (0)