1// RUN: not llvm-tblgen %s 2>&1 | FileCheck %s
2
3// Test the assert statement at top level.
4
5// CHECK: assertion failed
6// CHECK-NOT: note: primary name is too short
7// CHECK: note: primary name is too long
8
9defvar Name = "Grace Brewster Murray Hopper";
10
11assert !ge(!size(Name), 20), "primary name is too short: " # Name;
12assert !le(!size(Name), 20), "primary name is too long: " # Name;
13
14// CHECK: assertion failed
15// CHECK: note: first name is incorrect
16
17def Rec01 {
18  string name = "Fred Smith";
19}
20
21assert !eq(!substr(Rec01.name, 0, 3), "Jane"),
22       !strconcat("first name is incorrect: ", Rec01.name);
23
24// CHECK: assertion failed
25// CHECK: note: record Rec02 is broken
26
27def Rec02 {
28  bit broken = true;
29}
30
31assert !not(Rec02.broken), "record Rec02 is broken";
32
33// CHECK: assertion failed
34// CHECK: note: cube of 9
35
36class Cube<int n> {
37  int result = !mul(n, n, n);
38}
39
40assert !eq(Cube<9>.result, 81), "cube of 9 should be 729";
41
42// CHECK: assertion failed
43// CHECK: note: foreach i cannot be 2
44// CHECK-NOT: note: foreach i cannot be 2
45
46foreach i = 1...3 in {
47  assert !ne(i, 2), "foreach i cannot be 2";
48  def bar_ # i;
49}
50
51// Test the assert statement in a record definition.
52
53// CHECK: assertion failed
54// CHECK-NOT: primary first name is not "Grace"
55// CHECK: primary first name is not "Grack"
56// CHECK: assertion failed
57// CHECK: foo field should be
58
59def Rec10 {
60  assert !eq(!substr(Name, 0, 5), "Grace"), "primary first name is not \"Grace\"";
61  assert !eq(!substr(Name, 0, 5), "Grack"), "primary first name is not \"Grack\"";
62  string foo = "Foo";
63  assert !eq(foo, "foo"), "foo field should be \"Foo\"";
64}
65
66// CHECK: assertion failed
67// CHECK: note: magic field is incorrect: 42
68
69def Rec11 {
70  int magic = 13;
71  assert !eq(magic, 13), "magic field is incorrect: " # magic;
72  let magic = 42;
73}
74
75// CHECK: assertion failed
76// CHECK: note: var field has wrong value
77
78def Rec12 {
79  defvar prefix = "foo_";
80  string var = prefix # "snork";
81  assert !eq(var, "foo_snorx"), "var field has wrong value: " # var;
82}
83
84// CHECK: assertion failed
85// CHECK: note: kind field has wrong value
86
87class Kind {
88  int kind = 7;
89}
90
91def Rec13 : Kind {
92  let kind = 8;
93  assert !eq(kind, 7), "kind field has wrong value: " # kind;
94}
95
96// CHECK: assertion failed
97// CHECK: note: double_result should be
98
99def Rec14 : Cube<3> {
100  int double_result = !mul(result, 2);
101  assert !eq(double_result, 53), "double_result should be 54";
102}
103
104// Test the assert statement in a class definition.
105
106class PersonName<string name> {
107  assert !le(!size(name), 32), "person name is too long: " # name;
108  string Name = name;
109}
110
111class Person<string name, int age> : PersonName<name> {
112  assert !and(!ge(age, 1), !le(age, 120)),
113         "person age is invalid: " # age;
114  int Age = age;
115}
116
117def Rec20 : Person<"Donald Knuth", 60>;
118
119// CHECK: assertion failed
120// CHECK: note: person name is too long
121
122def Rec21 : Person<"Donald Uh Oh This Name Is Too Long Knuth", 50>;
123
124// CHECK: assertion failed
125// CHECK: note: person age is invalid
126
127def Rec22 : Person<"Donald Knuth", 150>;
128
129// Test the assert statement in an anonymous class invocation.
130
131def Rec30 {
132  string Name = Person<"Margaret Heafield Hamilton", 25>.Name;
133  int Age = Person<"Margaret Heafield Hamilton", 25>.Age;
134}
135
136def Rec31 {
137  string Name = Person<"Margaret Heafield And More Middle Names Hamilton", 25>.Name;
138  int Age = Person<"Margaret Heafield Hamilton", 25>.Age;
139}
140
141def Rec32 {
142  string Name = Person<"Margaret Heafield Hamilton", 25>.Name;
143  int Age = Person<"Margaret Heafield Hamilton", 0>.Age;
144}
145
146// Test the assert statement in a multiclass.
147
148// CHECK: assertion failed
149// CHECK: note: MC1 id string is too long
150// CHECK: assertion failed
151// CHECK: note: MC1 seq is too high
152
153multiclass MC1<string id, int seq> {
154  assert !le(!size(id), 5), "MC1 id string is too long";
155  assert !le(seq, 999999), "MC1 seq is too high";
156
157  def _mc1 {
158    string ID = id;
159    int Seq = seq;
160  }
161}
162
163defm Rec40 : MC1<"ILISP", 999>;
164defm Rec41 : MC1<"ILISPX", 999>;
165defm Rec42 : MC1<"ILISP", 999999999>;
166
167// CHECK: assertion failed
168// CHECK: note: MC2 phrase must be secret: secrex code
169
170multiclass MC2<string phr> {
171  assert !eq(!substr(phr, 0, 6), "secret"), "MC2 phrase must be secret: " # phr;
172
173  def _mc2 {
174    string phrase = phr;
175  }
176}
177
178multiclass MC3<string phr> {
179  defm _mc3 : MC2<phr>;
180}
181
182defm Rec43 : MC3<"secrex code">;
183
184// CHECK: assertion failed
185// CHECK: note: MC2 phrase must be secret: xecret code
186
187multiclass MC4<string phr> : MC2<phr> {
188  def _def;
189}
190
191defm Rec44 : MC4<"xecret code">;
192
193// Test a defm in a multiclass that inherits from a class with asserts.
194
195// CHECK: assertion failed
196// CHECK: note: MC5 name must include a space: Ada_Lovelace
197// CHECK: assertion failed
198// CHECK: note: person age is invalid: 666
199
200multiclass MC5<string phr, string name, int age> {
201  assert !ne(!find(name, " "), -1), "MC5 name must include a space: " # name;
202
203  defm _mc5 : MC2<phr>, Person<name, age>;
204}
205
206defm Rec45 : MC5<"secret password", "Ada_Lovelace", 666>;
207