221
|
1 // RUN: llvm-tblgen %s | FileCheck %s
|
|
2 // RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s
|
|
3 // RUN: not llvm-tblgen -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s
|
|
4 // RUN: not llvm-tblgen -DERROR3 %s 2>&1 | FileCheck --check-prefix=ERROR3 %s
|
|
5 // RUN: not llvm-tblgen -DERROR4 %s 2>&1 | FileCheck --check-prefix=ERROR4 %s
|
|
6 // RUN: not llvm-tblgen -DERROR5 %s 2>&1 | FileCheck --check-prefix=ERROR5 %s
|
|
7 // RUN: not llvm-tblgen -DERROR6 %s 2>&1 | FileCheck --check-prefix=ERROR6 %s
|
|
8 // RUN: not llvm-tblgen -DERROR7 %s 2>&1 | FileCheck --check-prefix=ERROR7 %s
|
252
|
9 // RUN: not llvm-tblgen -DERROR8 %s 2>&1 | FileCheck --check-prefix=ERROR8 %s
|
|
10 // RUN: not llvm-tblgen -DERROR9 %s 2>&1 | FileCheck --check-prefix=ERROR9 %s
|
|
11 // RUN: not llvm-tblgen -DERROR10 %s 2>&1 | FileCheck --check-prefix=ERROR10 %s
|
221
|
12
|
252
|
13 // This file tests that all required arguments are specified and template
|
|
14 // arguments are type-checked and cast if necessary.
|
221
|
15
|
|
16 // Class template arguments.
|
|
17
|
|
18 class Class1<string nm> {
|
|
19 string Name = nm;
|
|
20 }
|
|
21
|
|
22 // CHECK: def Rec1
|
|
23 // CHECK: string Name = "Alice"
|
|
24 // CHECK: string NameName = "AliceAlice"
|
|
25
|
|
26 def Rec1 : Class1<"Alice"> {
|
|
27 string NameName = Name # Name;
|
|
28 }
|
|
29
|
|
30 #ifdef ERROR1
|
252
|
31 // ERROR1: Value specified for template argument 'Class1:nm' is of type int
|
221
|
32
|
|
33 def Rec2 : Class1<42> {
|
|
34 }
|
|
35 #endif
|
|
36
|
|
37 class Class2<bits<8> cd> {
|
|
38 int Code = cd;
|
|
39 }
|
|
40
|
|
41 // CHECK: def Rec3
|
|
42 // CHECK: int Code = 42
|
|
43 // CHECK: list<int> CodeList = [42]
|
|
44
|
|
45 def Rec3 : Class2<0b00101010> {
|
|
46 list<int> CodeList = [Code];
|
|
47 }
|
|
48
|
|
49 // CHECK: def Rec4
|
|
50 // CHECK: int Code = 42
|
|
51 // CHECK: list<int> CodeList = [42]
|
|
52
|
|
53 def Rec4 : Class2<42> {
|
|
54 list<int> CodeList = [Code];
|
|
55 }
|
|
56
|
|
57 #ifdef ERROR2
|
252
|
58 // ERROR2: Value specified for template argument 'Class2:cd' is of type string
|
221
|
59
|
|
60 def Rec5 : Class2<"oops"> {
|
|
61 list<int> CodeList = [Code];
|
|
62 }
|
|
63 #endif
|
|
64
|
|
65 // Anonymous class instantiation template arguments.
|
|
66
|
|
67 // CHECK: def Rec6
|
|
68 // CHECK: string Name = "Ted"
|
|
69
|
|
70 def Rec6 {
|
|
71 string Name = Class1<"Ted">.Name;
|
|
72 }
|
|
73
|
|
74 #ifdef ERROR3
|
252
|
75 // ERROR3: Value specified for template argument 'Class1:nm' is of type int
|
221
|
76
|
|
77 def Rec7 {
|
|
78 string Name = Class1<42>.Name;
|
|
79 }
|
|
80 #endif
|
|
81
|
|
82 // CHECK: def Rec8
|
|
83 // CHECK: list<int> CodeList = [42]
|
|
84
|
|
85 def Rec8 {
|
|
86 list<int> CodeList = [Class2<42>.Code];
|
|
87 }
|
|
88
|
|
89 #ifdef ERROR4
|
252
|
90 // ERROR4: Value specified for template argument 'Class2:cd' is of type string
|
221
|
91
|
|
92 def Rec9 {
|
|
93 list<int> CodeList = [Class2<"huh?">.Code];
|
|
94 }
|
|
95 #endif
|
|
96
|
|
97 // Multiclass template arguments.
|
|
98
|
|
99 multiclass MC1<string nm> {
|
|
100 def _1 {
|
|
101 string Name = nm;
|
|
102 }
|
|
103 def _2 {
|
|
104 string NameNmae = nm # nm;
|
|
105 }
|
|
106 }
|
|
107
|
|
108 // CHECK: def RecMC1_1
|
|
109 // CHECK: string Name = "Carol"
|
|
110 // CHECK: def RecMC1_2
|
|
111 // CHECK: string NameNmae = "CarolCarol"
|
|
112
|
|
113 defm RecMC1 : MC1<"Carol">;
|
|
114
|
|
115 #ifdef ERROR5
|
252
|
116 // ERROR5: Value specified for template argument 'MC1::nm' is of type int
|
221
|
117
|
|
118 defm RecMC2 : MC1<42>;
|
|
119 #endif
|
|
120
|
|
121 multiclass MC2<bits<8> cd> {
|
|
122 def _1 {
|
|
123 bits<8> Code = cd;
|
|
124 }
|
|
125 def _2 {
|
|
126 int Code = cd;
|
|
127 }
|
|
128 def _3 {
|
|
129 list<int> CodeList = [cd];
|
|
130 }
|
|
131 }
|
|
132
|
|
133 // CHECK: def RecMC3_1
|
|
134 // CHECK: bits<8> Code = { 0, 0, 1, 0, 1, 0, 1, 0 }
|
|
135 // CHECK: def RecMC3_2
|
|
136 // CHECK: int Code = 42
|
|
137 // CHECK: def RecMC3_3
|
|
138 // CHECK: list<int> CodeList = [42]
|
|
139
|
|
140 defm RecMC3 : MC2<42>;
|
|
141
|
|
142 #ifdef ERROR6
|
252
|
143 // ERROR6: Value specified for template argument 'MC2::cd' is of type string
|
221
|
144
|
|
145 defm RecMC4 : MC2<"Bob">;
|
|
146 #endif
|
|
147
|
|
148 #ifdef ERROR7
|
|
149 multiclass TwoArgs<bits<8> a, string b> {
|
|
150 def _1 { bits<8> A = a; }
|
|
151 def _2 { string B = b; }
|
|
152 }
|
|
153 defm Good : TwoArgs<1, "one">;
|
|
154 defm MissingComma : TwoArgs<2 "two">;
|
|
155 // ERROR7: [[#@LINE-1]]:31: error: Expected comma before next argument
|
|
156 #endif
|
252
|
157
|
|
158 #ifdef ERROR8
|
|
159 def error8: Class1;
|
|
160 // ERROR8: value not specified for template argument 'Class1:nm'
|
|
161 // ERROR8: 18:21: note: declared in 'Class1'
|
|
162 #endif
|
|
163
|
|
164 #ifdef ERROR9
|
|
165 defm error9: MC1;
|
|
166 // ERROR9: value not specified for template argument 'MC1::nm'
|
|
167 // ERROR9: 99:23: note: declared in 'MC1'
|
|
168 #endif
|
|
169
|
|
170 #ifdef ERROR10
|
|
171 def error10 {
|
|
172 int value = Class2<>.Code;
|
|
173 }
|
|
174 // ERROR10: value not specified for template argument 'Class2:cd'
|
|
175 // ERROR10: 37:22: note: declared in 'Class2'
|
|
176 #endif
|