1// RUN: llvm-tblgen -dump-json %s | %python %S/JSON-check.py %s 2 3// CHECK: data['!tablegen_json_version'] == 1 4 5// CHECK: all(data[s]['!name'] == s for s in data if not s.startswith("!")) 6// CHECK: all('!locs' in data[s] for s in data if not s.startswith("!")) 7// CHECK: all(all(loc.startswith("JSON.td:") for loc in data[s]['!locs']) for s in data if not s.startswith("!")) 8 9class Base {} 10class Intermediate : Base {} 11class Derived : Intermediate {} 12 13def D : Intermediate {} 14// CHECK: data['D']['!locs'] == ['JSON.td:13'] 15// CHECK: 'D' in data['!instanceof']['Base'] 16// CHECK: 'D' in data['!instanceof']['Intermediate'] 17// CHECK: 'D' not in data['!instanceof']['Derived'] 18// CHECK: 'Base' in data['D']['!superclasses'] 19// CHECK: 'Intermediate' in data['D']['!superclasses'] 20// CHECK: 'Derived' not in data['D']['!superclasses'] 21 22def ExampleDagOp; 23 24def FieldKeywordTest { 25 int a; 26 field int b; 27 // CHECK: 'a' not in data['FieldKeywordTest']['!fields'] 28 // CHECK: 'b' in data['FieldKeywordTest']['!fields'] 29} 30 31class Variables { 32 int i; 33 string s; 34 bit b; 35 bits<8> bs; 36 code c; 37 list<int> li; 38 Base base; 39 dag d; 40} 41def VarNull : Variables { 42 // A variable not filled in at all has its value set to JSON 43 // 'null', which translates to Python None 44 // CHECK: data['VarNull']['i'] is None 45} 46def VarPrim : Variables { 47 // Test initializers that map to primitive JSON types 48 49 int i = 3; 50 // CHECK: data['VarPrim']['i'] == 3 51 52 // Integer literals should be emitted in the JSON at full 64-bit 53 // precision, for the benefit of JSON readers that preserve that 54 // much information. Python's is one such. 55 int enormous_pos = 9123456789123456789; 56 int enormous_neg = -9123456789123456789; 57 // CHECK: data['VarPrim']['enormous_pos'] == 9123456789123456789 58 // CHECK: data['VarPrim']['enormous_neg'] == -9123456789123456789 59 60 string s = "hello, world"; 61 // CHECK: data['VarPrim']['s'] == 'hello, world' 62 63 bit b = 0; 64 // CHECK: data['VarPrim']['b'] == 0 65 66 // bits<> arrays are stored in logical order (array[i] is the same 67 // bit identified in .td files as bs{i}), which means the _visual_ 68 // order of the list (in default rendering) is reversed. 69 bits<8> bs = { 0,0,0,1,0,1,1,1 }; 70 // CHECK: data['VarPrim']['bs'] == [ 1,1,1,0,1,0,0,0 ] 71 72 code c = [{ \" }]; 73 // CHECK: data['VarPrim']['c'] == r' \" ' 74 75 list<int> li = [ 1, 2, 3, 4 ]; 76 // CHECK: data['VarPrim']['li'] == [ 1, 2, 3, 4 ] 77} 78def VarObj : Variables { 79 // Test initializers that map to JSON objects containing a 'kind' 80 // discriminator 81 82 Base base = D; 83 // CHECK: data['VarObj']['base']['kind'] == 'def' 84 // CHECK: data['VarObj']['base']['def'] == 'D' 85 // CHECK: data['VarObj']['base']['printable'] == 'D' 86 87 dag d = (ExampleDagOp 22, "hello":$foo); 88 // CHECK: data['VarObj']['d']['kind'] == 'dag' 89 // CHECK: data['VarObj']['d']['operator']['kind'] == 'def' 90 // CHECK: data['VarObj']['d']['operator']['def'] == 'ExampleDagOp' 91 // CHECK: data['VarObj']['d']['operator']['printable'] == 'ExampleDagOp' 92 // CHECK: data['VarObj']['d']['args'] == [[22, None], ["hello", "foo"]] 93 // CHECK: data['VarObj']['d']['printable'] == '(ExampleDagOp 22, "hello":$foo)' 94 95 int undef_int; 96 field int ref_int = undef_int; 97 // CHECK: data['VarObj']['ref_int']['kind'] == 'var' 98 // CHECK: data['VarObj']['ref_int']['var'] == 'undef_int' 99 // CHECK: data['VarObj']['ref_int']['printable'] == 'undef_int' 100 101 bits<2> undef_bits; 102 bits<4> ref_bits; 103 let ref_bits{3...2} = 0b10; 104 let ref_bits{1...0} = undef_bits{1...0}; 105 // CHECK: data['VarObj']['ref_bits'][3] == 1 106 // CHECK: data['VarObj']['ref_bits'][2] == 0 107 // CHECK: data['VarObj']['ref_bits'][1]['kind'] == 'varbit' 108 // CHECK: data['VarObj']['ref_bits'][1]['var'] == 'undef_bits' 109 // CHECK: data['VarObj']['ref_bits'][1]['index'] == 1 110 // CHECK: data['VarObj']['ref_bits'][1]['printable'] == 'undef_bits{1}' 111 // CHECK: data['VarObj']['ref_bits'][0]['kind'] == 'varbit' 112 // CHECK: data['VarObj']['ref_bits'][0]['var'] == 'undef_bits' 113 // CHECK: data['VarObj']['ref_bits'][0]['index'] == 0 114 // CHECK: data['VarObj']['ref_bits'][0]['printable'] == 'undef_bits{0}' 115 116 field int complex_ref_int = !add(undef_int, 2); 117 // CHECK: data['VarObj']['complex_ref_int']['kind'] == 'complex' 118 // CHECK: data['VarObj']['complex_ref_int']['printable'] == '!add(undef_int, 2)' 119} 120 121// Test the !anonymous member. This is tricky because when a def is 122// anonymous, almost by definition, the test can't reliably predict 123// the name it will be stored under! So we have to search all the defs 124// in the JSON output looking for the one that has the test integer 125// field set to the right value. 126 127def Named { int AnonTestField = 1; } 128// CHECK: data['Named']['AnonTestField'] == 1 129// CHECK: data['Named']['!anonymous'] is False 130 131def { int AnonTestField = 2; } 132// CHECK: next(rec for rec in data.values() if isinstance(rec, dict) and rec.get('AnonTestField') == 2)['!anonymous'] is True 133 134multiclass AnonTestMulticlass<int base> { 135 def _plus_one { int AnonTestField = !add(base,1); } 136 def { int AnonTestField = !add(base,2); } 137} 138 139defm NamedDefm : AnonTestMulticlass<10>; 140// CHECK: data['NamedDefm_plus_one']['!anonymous'] is False 141// CHECK: data['NamedDefm_plus_one']['AnonTestField'] == 11 142// CHECK: next(rec for rec in data.values() if isinstance(rec, dict) and rec.get('AnonTestField') == 12)['!anonymous'] is True 143 144// D47431 clarifies that a named def inside a multiclass gives a 145// *non*-anonymous output record, even if the defm that instantiates 146// that multiclass is anonymous. 147defm : AnonTestMulticlass<20>; 148// CHECK: next(rec for rec in data.values() if isinstance(rec, dict) and rec.get('AnonTestField') == 21)['!anonymous'] is False 149// CHECK: next(rec for rec in data.values() if isinstance(rec, dict) and rec.get('AnonTestField') == 22)['!anonymous'] is True 150