blob: a48f1c63364486e0e750e1b06c899d2a81a173c1 [file] [log] [blame]
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001#!/usr/bin/env python
2
3import pprint
4import re
Eli Benderskyd0973782012-01-19 08:09:33 +02005import os, sys
Jon Dufresne13224c12018-06-26 13:48:31 -07006import io
Eli Bendersky3921e8e2010-05-21 09:05:39 +03007import unittest
8
Eli Bendersky3877c4c2013-07-13 06:54:04 -07009sys.path[0:0] = ['.', '..']
Eli Bendersky3921e8e2010-05-21 09:05:39 +030010
11from pycparser import c_parser
12from pycparser.c_ast import *
13from pycparser.c_parser import CParser, Coord, ParseError
14
Eli Bendersky3921e8e2010-05-21 09:05:39 +030015_c_parser = c_parser.CParser(
16 lex_optimize=False,
Eli Bendersky86f2eee2013-01-18 06:04:01 -080017 yacc_debug=True,
Eli Bendersky3921e8e2010-05-21 09:05:39 +030018 yacc_optimize=False,
19 yacctab='yacctab')
20
21
22def expand_decl(decl):
23 """ Converts the declaration into a nested list.
24 """
25 typ = type(decl)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080026
Eli Bendersky3921e8e2010-05-21 09:05:39 +030027 if typ == TypeDecl:
28 return ['TypeDecl', expand_decl(decl.type)]
29 elif typ == IdentifierType:
30 return ['IdentifierType', decl.names]
31 elif typ == ID:
32 return ['ID', decl.name]
33 elif typ in [Struct, Union]:
34 decls = [expand_decl(d) for d in decl.decls or []]
35 return [typ.__name__, decl.name, decls]
Eli Bendersky86f2eee2013-01-18 06:04:01 -080036 else:
Eli Bendersky3921e8e2010-05-21 09:05:39 +030037 nested = expand_decl(decl.type)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080038
Eli Bendersky3921e8e2010-05-21 09:05:39 +030039 if typ == Decl:
40 if decl.quals:
41 return ['Decl', decl.quals, decl.name, nested]
42 else:
43 return ['Decl', decl.name, nested]
44 elif typ == Typename: # for function parameters
45 if decl.quals:
46 return ['Typename', decl.quals, nested]
47 else:
48 return ['Typename', nested]
49 elif typ == ArrayDecl:
50 dimval = decl.dim.value if decl.dim else ''
Eli Bendersky8aad3182014-01-25 06:30:53 -080051 return ['ArrayDecl', dimval, decl.dim_quals, nested]
Eli Bendersky3921e8e2010-05-21 09:05:39 +030052 elif typ == PtrDecl:
Eli Benderskyb17da152015-04-21 14:35:18 -070053 if decl.quals:
54 return ['PtrDecl', decl.quals, nested]
55 else:
56 return ['PtrDecl', nested]
Eli Bendersky3921e8e2010-05-21 09:05:39 +030057 elif typ == Typedef:
58 return ['Typedef', decl.name, nested]
59 elif typ == FuncDecl:
60 if decl.args:
61 params = [expand_decl(param) for param in decl.args.params]
62 else:
63 params = []
64 return ['FuncDecl', params, nested]
Eli Bendersky86f2eee2013-01-18 06:04:01 -080065
Eli Bendersky3921e8e2010-05-21 09:05:39 +030066
67def expand_init(init):
68 """ Converts an initialization into a nested list
69 """
70 typ = type(init)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080071
eli.benderskyf890a862010-10-30 12:13:23 +020072 if typ == NamedInitializer:
73 des = [expand_init(dp) for dp in init.name]
74 return (des, expand_init(init.expr))
Eli Bendersky293ea912012-12-25 14:52:48 -080075 elif typ in (InitList, ExprList):
eli.benderskyf890a862010-10-30 12:13:23 +020076 return [expand_init(expr) for expr in init.exprs]
77 elif typ == Constant:
Eli Bendersky3921e8e2010-05-21 09:05:39 +030078 return ['Constant', init.type, init.value]
79 elif typ == ID:
80 return ['ID', init.name]
Nate Bogdanowicz14b8a7e2017-02-22 08:54:05 -050081 elif typ == UnaryOp:
82 return ['UnaryOp', init.op, expand_decl(init.expr)]
Eli Bendersky3921e8e2010-05-21 09:05:39 +030083
84
eli.bendersky85d2e732011-05-20 19:47:26 +030085class TestCParser_base(unittest.TestCase):
Eli Bendersky3921e8e2010-05-21 09:05:39 +030086 def parse(self, txt, filename=''):
87 return self.cparser.parse(txt, filename)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080088
Eli Bendersky3921e8e2010-05-21 09:05:39 +030089 def setUp(self):
90 self.cparser = _c_parser
Eli Bendersky86f2eee2013-01-18 06:04:01 -080091
serpilliere471442f2017-03-10 15:02:00 +010092 def assert_coord(self, node, line, column=None, file=None):
Eli Benderskyb77d6c02016-10-11 20:33:53 -070093 self.assertEqual(node.coord.line, line)
serpilliere471442f2017-03-10 15:02:00 +010094 if column is not None:
95 self.assertEqual(node.coord.column, column)
Eli Benderskyb77d6c02016-10-11 20:33:53 -070096 if file:
97 self.assertEqual(node.coord.file, file)
98
eli.bendersky85d2e732011-05-20 19:47:26 +030099
serpilliere471442f2017-03-10 15:02:00 +0100100
eli.bendersky85d2e732011-05-20 19:47:26 +0300101class TestCParser_fundamentals(TestCParser_base):
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300102 def get_decl(self, txt, index=0):
103 """ Given a source and an index returns the expanded
104 declaration at that index.
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800105
106 FileAST holds a list of 'external declarations'.
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300107 index is the offset of the desired declaration in that
108 list.
109 """
110 t = self.parse(txt).ext[index]
111 return expand_decl(t)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800112
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300113 def get_decl_init(self, txt, index=0):
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800114 """ Returns the expanded initializer of the declaration
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300115 at index.
116 """
117 t = self.parse(txt).ext[index]
118 return expand_init(t.init)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800119
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300120 def test_FileAST(self):
121 t = self.parse('int a; char c;')
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700122 self.assertIsInstance(t, FileAST)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300123 self.assertEqual(len(t.ext), 2)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800124
eli.bendersky43cf0b22011-10-19 05:56:15 +0200125 # empty file
126 t2 = self.parse('')
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700127 self.assertIsInstance(t2, FileAST)
eli.bendersky43cf0b22011-10-19 05:56:15 +0200128 self.assertEqual(len(t2.ext), 0)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300129
eli.bendersky38165b72011-02-04 08:13:39 +0200130 def test_empty_toplevel_decl(self):
131 code = 'int foo;;'
132 t = self.parse(code)
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700133 self.assertIsInstance(t, FileAST)
eli.bendersky38165b72011-02-04 08:13:39 +0200134 self.assertEqual(len(t.ext), 1)
135 self.assertEqual(self.get_decl(code),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800136 ['Decl', 'foo',
eli.bendersky38165b72011-02-04 08:13:39 +0200137 ['TypeDecl', ['IdentifierType', ['int']]]])
138
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300139 def test_coords(self):
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800140 """ Tests the "coordinates" of parsed elements - file
serpilliere471442f2017-03-10 15:02:00 +0100141 name, line and column numbers, with modification
142 insterted by #line directives.
eli.bendersky38165b72011-02-04 08:13:39 +0200143 """
serpilliere471442f2017-03-10 15:02:00 +0100144 self.assert_coord(self.parse('int a;').ext[0], 1, 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800145
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300146 t1 = """
147 int a;
148 int b;\n\n
149 int c;
150 """
151 f1 = self.parse(t1, filename='test.c')
serpilliere471442f2017-03-10 15:02:00 +0100152 self.assert_coord(f1.ext[0], 2, 13, 'test.c')
153 self.assert_coord(f1.ext[1], 3, 13, 'test.c')
154 self.assert_coord(f1.ext[2], 6, 13, 'test.c')
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300155
156 t1_1 = '''
157 int main() {
158 k = p;
159 printf("%d", b);
160 return 0;
161 }'''
162 f1_1 = self.parse(t1_1, filename='test.c')
serpilliere471442f2017-03-10 15:02:00 +0100163 self.assert_coord(f1_1.ext[0].body.block_items[0], 3, 13, 'test.c')
164 self.assert_coord(f1_1.ext[0].body.block_items[1], 4, 13, 'test.c')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800165
eli.benderskyfc96e5e2011-03-04 09:51:23 +0200166 t1_2 = '''
167 int main () {
168 int p = (int) k;
169 }'''
170 f1_2 = self.parse(t1_2, filename='test.c')
171 # make sure that the Cast has a coord (issue 23)
serpilliere471442f2017-03-10 15:02:00 +0100172 self.assert_coord(f1_2.ext[0].body.block_items[0].init, 3, 21, file='test.c')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800173
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300174 t2 = """
175 #line 99
176 int c;
177 """
serpilliere471442f2017-03-10 15:02:00 +0100178 self.assert_coord(self.parse(t2).ext[0], 99, 13)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800179
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300180 t3 = """
181 int dsf;
182 char p;
183 #line 3000 "in.h"
184 char d;
185 """
186 f3 = self.parse(t3, filename='test.c')
serpilliere471442f2017-03-10 15:02:00 +0100187 self.assert_coord(f3.ext[0], 2, 13, 'test.c')
188 self.assert_coord(f3.ext[1], 3, 14, 'test.c')
189 self.assert_coord(f3.ext[2], 3000, 14, 'in.h')
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300190
191 t4 = """
192 #line 20 "restore.h"
193 int maydler(char);
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800194
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300195 #line 30 "includes/daween.ph"
196 long j, k;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800197
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300198 #line 50000
199 char* ro;
200 """
201 f4 = self.parse(t4, filename='myb.c')
serpilliere471442f2017-03-10 15:02:00 +0100202 self.assert_coord(f4.ext[0], 20, 13, 'restore.h')
203 self.assert_coord(f4.ext[1], 30, 14, 'includes/daween.ph')
204 self.assert_coord(f4.ext[2], 30, 17, 'includes/daween.ph')
205 self.assert_coord(f4.ext[3], 50000, 13, 'includes/daween.ph')
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300206
207 t5 = """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800208 int
209 #line 99
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300210 c;
211 """
serpilliere471442f2017-03-10 15:02:00 +0100212 self.assert_coord(self.parse(t5).ext[0], 99, 9)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300213
Eli Bendersky203b9672012-06-15 10:11:24 +0300214 # coord for ellipsis
215 t6 = """
216 int foo(int j,
217 ...) {
218 }"""
219 f6 = self.parse(t6, filename='z.c')
serpilliere471442f2017-03-10 15:02:00 +0100220 self.assert_coord(self.parse(t6).ext[0].decl.type.args.params[1], 3, 17)
Eli Bendersky203b9672012-06-15 10:11:24 +0300221
Eli Bendersky8e5d3a92014-03-15 14:06:00 -0700222 def test_forloop_coord(self):
223 t = '''\
224 void foo() {
225 for(int z=0; z<4;
226 z++){}
227 }
228 '''
229 s = self.parse(t, filename='f.c')
230 forloop = s.ext[0].body.block_items[0]
serpilliere471442f2017-03-10 15:02:00 +0100231 self.assert_coord(forloop.init, 2, 13, 'f.c')
232 self.assert_coord(forloop.cond, 2, 26, 'f.c')
233 self.assert_coord(forloop.next, 3, 17, 'f.c')
Eli Bendersky8e5d3a92014-03-15 14:06:00 -0700234
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300235 def test_simple_decls(self):
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800236 self.assertEqual(self.get_decl('int a;'),
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300237 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
238
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800239 self.assertEqual(self.get_decl('unsigned int a;'),
Eli Bendersky68497c22012-01-19 06:04:58 +0200240 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['unsigned', 'int']]]])
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300241
eli.benderskyaffe0322011-09-24 06:16:55 +0300242 self.assertEqual(self.get_decl('_Bool a;'),
243 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['_Bool']]]])
244
Eli Benderskyf4d73462012-01-19 05:56:27 +0200245 self.assertEqual(self.get_decl('float _Complex fcc;'),
Eli Bendersky68497c22012-01-19 06:04:58 +0200246 ['Decl', 'fcc', ['TypeDecl', ['IdentifierType', ['float', '_Complex']]]])
Eli Benderskyf4d73462012-01-19 05:56:27 +0200247
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800248 self.assertEqual(self.get_decl('char* string;'),
249 ['Decl', 'string',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300250 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]])
251
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800252 self.assertEqual(self.get_decl('long ar[15];'),
253 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800254 ['ArrayDecl', '15', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300255 ['TypeDecl', ['IdentifierType', ['long']]]]])
eli.bendersky98f45372010-10-30 09:46:29 +0200256
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800257 self.assertEqual(self.get_decl('long long ar[15];'),
258 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800259 ['ArrayDecl', '15', [],
eli.benderskyf890a862010-10-30 12:13:23 +0200260 ['TypeDecl', ['IdentifierType', ['long', 'long']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800261
262 self.assertEqual(self.get_decl('unsigned ar[];'),
263 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800264 ['ArrayDecl', '', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300265 ['TypeDecl', ['IdentifierType', ['unsigned']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800266
267 self.assertEqual(self.get_decl('int strlen(char* s);'),
268 ['Decl', 'strlen',
269 ['FuncDecl',
270 [['Decl', 's',
271 ['PtrDecl',
272 ['TypeDecl', ['IdentifierType', ['char']]]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300273 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800274
275 self.assertEqual(self.get_decl('int strcmp(char* s1, char* s2);'),
276 ['Decl', 'strcmp',
277 ['FuncDecl',
278 [ ['Decl', 's1',
279 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
280 ['Decl', 's2',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300281 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800282 ],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300283 ['TypeDecl', ['IdentifierType', ['int']]]]])
284
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400285 # function return values and parameters may not have type information
Eli Bendersky09e22a62013-07-02 06:00:36 -0700286 self.assertEqual(self.get_decl('extern foobar(foo, bar);'),
287 ['Decl', 'foobar',
288 ['FuncDecl',
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400289 [ ['ID', 'foo'],
290 ['ID', 'bar']
Eli Bendersky09e22a62013-07-02 06:00:36 -0700291 ],
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400292 ['TypeDecl', ['IdentifierType', ['int']]]]])
293
Manuel Jacob0a15d7d2017-01-12 15:46:05 +0100294 def test_int128(self):
295 self.assertEqual(self.get_decl('__int128 a;'),
296 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['__int128']]]])
297
298
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300299 def test_nested_decls(self): # the fun begins
300 self.assertEqual(self.get_decl('char** ar2D;'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800301 ['Decl', 'ar2D',
302 ['PtrDecl', ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300303 ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800304
305 self.assertEqual(self.get_decl('int (*a)[1][2];'),
306 ['Decl', 'a',
307 ['PtrDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800308 ['ArrayDecl', '1', [],
309 ['ArrayDecl', '2', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300310 ['TypeDecl', ['IdentifierType', ['int']]]]]]])
311
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800312 self.assertEqual(self.get_decl('int *a[1][2];'),
313 ['Decl', 'a',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800314 ['ArrayDecl', '1', [],
315 ['ArrayDecl', '2', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300316 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['int']]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800317
Eli Benderskyb17da152015-04-21 14:35:18 -0700318 self.assertEqual(self.get_decl('char* const* p;'),
319 ['Decl', 'p',
320 ['PtrDecl', ['PtrDecl', ['const'],
321 ['TypeDecl', ['IdentifierType', ['char']]]]]])
322
323 self.assertEqual(self.get_decl('char* * const p;'),
324 ['Decl', 'p',
325 ['PtrDecl', ['const'], ['PtrDecl',
326 ['TypeDecl', ['IdentifierType', ['char']]]]]])
327
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300328 self.assertEqual(self.get_decl('char ***ar3D[40];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800329 ['Decl', 'ar3D',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800330 ['ArrayDecl', '40', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800331 ['PtrDecl', ['PtrDecl', ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300332 ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800333
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300334 self.assertEqual(self.get_decl('char (***ar3D)[40];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800335 ['Decl', 'ar3D',
336 ['PtrDecl', ['PtrDecl', ['PtrDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800337 ['ArrayDecl', '40', [], ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800338
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300339 self.assertEqual(self.get_decl('int (*x[4])(char, int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800340 ['Decl', 'x',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800341 ['ArrayDecl', '4', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800342 ['PtrDecl',
343 ['FuncDecl',
344 [ ['Typename', ['TypeDecl', ['IdentifierType', ['char']]]],
345 ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300346 ['TypeDecl', ['IdentifierType', ['int']]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800347
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300348 self.assertEqual(self.get_decl('char *(*(**foo [][8])())[];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800349 ['Decl', 'foo',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800350 ['ArrayDecl', '', [],
351 ['ArrayDecl', '8', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800352 ['PtrDecl', ['PtrDecl',
353 ['FuncDecl',
354 [],
355 ['PtrDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800356 ['ArrayDecl', '', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800357 ['PtrDecl',
358 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300359 ['IdentifierType', ['char']]]]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800360
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300361 # explore named and unnamed function pointer parameters,
362 # with and without qualifiers
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800363
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300364 # unnamed w/o quals
365 self.assertEqual(self.get_decl('int (*k)(int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800366 ['Decl', 'k',
367 ['PtrDecl',
368 ['FuncDecl',
369 [['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300370 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800371
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300372 # unnamed w/ quals
373 self.assertEqual(self.get_decl('int (*k)(const int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800374 ['Decl', 'k',
375 ['PtrDecl',
376 ['FuncDecl',
377 [['Typename', ['const'], ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300378 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800379
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300380 # named w/o quals
381 self.assertEqual(self.get_decl('int (*k)(int q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800382 ['Decl', 'k',
383 ['PtrDecl',
384 ['FuncDecl',
385 [['Decl', 'q', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300386 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800387
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300388 # named w/ quals
389 self.assertEqual(self.get_decl('int (*k)(const volatile int q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800390 ['Decl', 'k',
391 ['PtrDecl',
392 ['FuncDecl',
393 [['Decl', ['const', 'volatile'], 'q',
394 ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300395 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800396
Eli Benderskycecb6382018-06-15 05:36:02 -0700397 self.assertEqual(self.get_decl('int (*k)(const volatile int* q);'),
398 ['Decl', 'k',
399 ['PtrDecl',
400 ['FuncDecl',
401 [['Decl', ['const', 'volatile'], 'q',
402 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['int']]]]]],
403 ['TypeDecl', ['IdentifierType', ['int']]]]]])
404
eli.bendersky79d5cf62010-10-29 13:33:52 +0200405 # restrict qualifier
406 self.assertEqual(self.get_decl('int (*k)(restrict int* q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800407 ['Decl', 'k',
408 ['PtrDecl',
409 ['FuncDecl',
410 [['Decl', ['restrict'], 'q',
eli.bendersky79d5cf62010-10-29 13:33:52 +0200411 ['PtrDecl',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800412 ['TypeDecl', ['IdentifierType', ['int']]]]]],
eli.bendersky79d5cf62010-10-29 13:33:52 +0200413 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800414
Eli Benderskye7c55cf2014-01-25 06:15:43 -0800415 def test_func_decls_with_array_dim_qualifiers(self):
416 self.assertEqual(self.get_decl('int zz(int p[static 10]);'),
417 ['Decl', 'zz',
418 ['FuncDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800419 [['Decl', 'p', ['ArrayDecl', '10', ['static'],
Eli Benderskye7c55cf2014-01-25 06:15:43 -0800420 ['TypeDecl', ['IdentifierType', ['int']]]]]],
421 ['TypeDecl', ['IdentifierType', ['int']]]]])
422
423 self.assertEqual(self.get_decl('int zz(int p[const 10]);'),
424 ['Decl', 'zz',
425 ['FuncDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800426 [['Decl', 'p', ['ArrayDecl', '10', ['const'],
Eli Benderskye7c55cf2014-01-25 06:15:43 -0800427 ['TypeDecl', ['IdentifierType', ['int']]]]]],
428 ['TypeDecl', ['IdentifierType', ['int']]]]])
429
necase4a6afa02014-12-19 16:38:37 -0600430 self.assertEqual(self.get_decl('int zz(int p[restrict][5]);'),
431 ['Decl', 'zz',
432 ['FuncDecl',
433 [['Decl', 'p', ['ArrayDecl', '', ['restrict'],
434 ['ArrayDecl', '5', [],
435 ['TypeDecl', ['IdentifierType', ['int']]]]]]],
436 ['TypeDecl', ['IdentifierType', ['int']]]]])
437
438 self.assertEqual(self.get_decl('int zz(int p[const restrict static 10][5]);'),
439 ['Decl', 'zz',
440 ['FuncDecl',
441 [['Decl', 'p', ['ArrayDecl', '10', ['const', 'restrict', 'static'],
442 ['ArrayDecl', '5', [],
443 ['TypeDecl', ['IdentifierType', ['int']]]]]]],
444 ['TypeDecl', ['IdentifierType', ['int']]]]])
445
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300446 def test_qualifiers_storage_specifiers(self):
447 def assert_qs(txt, index, quals, storage):
448 d = self.parse(txt).ext[index]
449 self.assertEqual(d.quals, quals)
450 self.assertEqual(d.storage, storage)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800451
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300452 assert_qs("extern int p;", 0, [], ['extern'])
453 assert_qs("const long p = 6;", 0, ['const'], [])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800454
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300455 d1 = "static const int p, q, r;"
456 for i in range(3):
457 assert_qs(d1, i, ['const'], ['static'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800458
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300459 d2 = "static char * const p;"
460 assert_qs(d2, 0, [], ['static'])
461 pdecl = self.parse(d2).ext[0].type
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700462 self.assertIsInstance(pdecl, PtrDecl)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300463 self.assertEqual(pdecl.quals, ['const'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800464
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300465 def test_sizeof(self):
466 e = """
467 void foo()
468 {
469 int a = sizeof k;
470 int b = sizeof(int);
eli.benderskyc51e1d32011-02-04 08:52:33 +0200471 int c = sizeof(int**);;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800472
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300473 char* p = "just to make sure this parses w/o error...";
474 int d = sizeof(int());
475 }
476 """
477 compound = self.parse(e).ext[0].body
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800478
eli.benderskyef29ff92010-10-29 16:25:43 +0200479 s1 = compound.block_items[0].init
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700480 self.assertIsInstance(s1, UnaryOp)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300481 self.assertEqual(s1.op, 'sizeof')
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700482 self.assertIsInstance(s1.expr, ID)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300483 self.assertEqual(s1.expr.name, 'k')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800484
eli.benderskyef29ff92010-10-29 16:25:43 +0200485 s2 = compound.block_items[1].init
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300486 self.assertEqual(expand_decl(s2.expr),
487 ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800488
eli.benderskyef29ff92010-10-29 16:25:43 +0200489 s3 = compound.block_items[2].init
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300490 self.assertEqual(expand_decl(s3.expr),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800491 ['Typename',
492 ['PtrDecl',
493 ['PtrDecl',
494 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300495 ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800496
Eli Benderskye59395b2015-05-09 15:20:46 -0700497 def test_offsetof(self):
498 e = """
499 void foo() {
500 int a = offsetof(struct S, p);
501 a.b = offsetof(struct sockaddr, sp) + strlen(bar);
ksero749650a2016-09-09 07:31:09 +0200502 int a = offsetof(struct S, p.q.r);
503 int a = offsetof(struct S, p[5].q[4][5]);
Eli Benderskye59395b2015-05-09 15:20:46 -0700504 }
505 """
506 compound = self.parse(e).ext[0].body
507 s1 = compound.block_items[0].init
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700508 self.assertIsInstance(s1, FuncCall)
509 self.assertIsInstance(s1.name, ID)
Eli Benderskye59395b2015-05-09 15:20:46 -0700510 self.assertEqual(s1.name.name, 'offsetof')
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700511 self.assertIsInstance(s1.args.exprs[0], Typename)
512 self.assertIsInstance(s1.args.exprs[1], ID)
ksero749650a2016-09-09 07:31:09 +0200513 s3 = compound.block_items[2].init
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700514 self.assertIsInstance(s3.args.exprs[1], StructRef)
ksero749650a2016-09-09 07:31:09 +0200515 s4 = compound.block_items[3].init
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700516 self.assertIsInstance(s4.args.exprs[1], ArrayRef)
Eli Benderskye59395b2015-05-09 15:20:46 -0700517
Eli Benderskydbf9be22016-10-11 20:44:32 -0700518 def test_compound_statement(self):
519 e = """
520 void foo() {
521 }
522 """
523 compound = self.parse(e).ext[0].body
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700524 self.assertIsInstance(compound, Compound)
serpilliere471442f2017-03-10 15:02:00 +0100525 self.assert_coord(compound, 2)
Eli Benderskydbf9be22016-10-11 20:44:32 -0700526
eli.bendersky9f481562010-10-30 15:50:47 +0200527 # The C99 compound literal feature
528 #
eli.benderskyf890a862010-10-30 12:13:23 +0200529 def test_compound_literals(self):
eli.bendersky9f481562010-10-30 15:50:47 +0200530 ps1 = self.parse(r'''
eli.benderskyf890a862010-10-30 12:13:23 +0200531 void foo() {
eli.bendersky9f481562010-10-30 15:50:47 +0200532 p = (long long){k};
533 tc = (struct jk){.a = {1, 2}, .b[0] = t};
534 }''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800535
eli.bendersky9f481562010-10-30 15:50:47 +0200536 compound = ps1.ext[0].body.block_items[0].rvalue
537 self.assertEqual(expand_decl(compound.type),
538 ['Typename', ['TypeDecl', ['IdentifierType', ['long', 'long']]]])
539 self.assertEqual(expand_init(compound.init),
540 [['ID', 'k']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800541
542 compound = ps1.ext[0].body.block_items[1].rvalue
eli.bendersky9f481562010-10-30 15:50:47 +0200543 self.assertEqual(expand_decl(compound.type),
544 ['Typename', ['TypeDecl', ['Struct', 'jk', []]]])
545 self.assertEqual(expand_init(compound.init),
546 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800547 ([['ID', 'a']], [['Constant', 'int', '1'], ['Constant', 'int', '2']]),
eli.bendersky9f481562010-10-30 15:50:47 +0200548 ([['ID', 'b'], ['Constant', 'int', '0']], ['ID', 't'])])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800549
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300550 def test_enums(self):
551 e1 = "enum mycolor op;"
552 e1_type = self.parse(e1).ext[0].type.type
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800553
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700554 self.assertIsInstance(e1_type, Enum)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300555 self.assertEqual(e1_type.name, 'mycolor')
556 self.assertEqual(e1_type.values, None)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800557
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300558 e2 = "enum mysize {large=20, small, medium} shoes;"
559 e2_type = self.parse(e2).ext[0].type.type
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800560
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700561 self.assertIsInstance(e2_type, Enum)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300562 self.assertEqual(e2_type.name, 'mysize')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800563
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300564 e2_elist = e2_type.values
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700565 self.assertIsInstance(e2_elist, EnumeratorList)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800566
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300567 for e2_eval in e2_elist.enumerators:
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700568 self.assertIsInstance(e2_eval, Enumerator)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800569
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300570 self.assertEqual(e2_elist.enumerators[0].name, 'large')
571 self.assertEqual(e2_elist.enumerators[0].value.value, '20')
572 self.assertEqual(e2_elist.enumerators[2].name, 'medium')
573 self.assertEqual(e2_elist.enumerators[2].value, None)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800574
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300575 # enum with trailing comma (C99 feature)
576 e3 = """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800577 enum
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300578 {
579 red,
580 blue,
581 green,
582 } color;
583 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800584
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300585 e3_type = self.parse(e3).ext[0].type.type
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700586 self.assertIsInstance(e3_type, Enum)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300587 e3_elist = e3_type.values
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700588 self.assertIsInstance(e3_elist, EnumeratorList)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800589
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300590 for e3_eval in e3_elist.enumerators:
Jon Dufresnee8afcc92018-06-26 13:49:06 -0700591 self.assertIsInstance(e3_eval, Enumerator)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800592
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300593 self.assertEqual(e3_elist.enumerators[0].name, 'red')
594 self.assertEqual(e3_elist.enumerators[0].value, None)
595 self.assertEqual(e3_elist.enumerators[1].name, 'blue')
596 self.assertEqual(e3_elist.enumerators[2].name, 'green')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800597
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300598 def test_typedef(self):
599 # without typedef, error
600 s1 = """
601 node k;
602 """
603 self.assertRaises(ParseError, self.parse, s1)
604
605 # now with typedef, works
606 s2 = """
607 typedef void* node;
608 node k;
609 """
610 ps2 = self.parse(s2)
611 self.assertEqual(expand_decl(ps2.ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800612 ['Typedef', 'node',
613 ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300614 ['TypeDecl', ['IdentifierType', ['void']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800615
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300616 self.assertEqual(expand_decl(ps2.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800617 ['Decl', 'k',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300618 ['TypeDecl', ['IdentifierType', ['node']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800619
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300620 s3 = """
621 typedef int T;
622 typedef T *pT;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800623
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300624 pT aa, bb;
625 """
626 ps3 = self.parse(s3)
627 self.assertEqual(expand_decl(ps3.ext[3]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800628 ['Decl', 'bb',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300629 ['TypeDecl', ['IdentifierType', ['pT']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800630
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300631 s4 = '''
632 typedef char* __builtin_va_list;
633 typedef __builtin_va_list __gnuc_va_list;
634 '''
635 ps4 = self.parse(s4)
636 self.assertEqual(expand_decl(ps4.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800637 ['Typedef', '__gnuc_va_list',
638 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300639 ['IdentifierType', ['__builtin_va_list']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800640
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300641 s5 = '''typedef struct tagHash Hash;'''
642 ps5 = self.parse(s5)
643 self.assertEqual(expand_decl(ps5.ext[0]),
644 ['Typedef', 'Hash', ['TypeDecl', ['Struct', 'tagHash', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800645
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300646 def test_struct_union(self):
647 s1 = """
648 struct {
649 int id;
650 char* name;
651 } joe;
652 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800653
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300654 self.assertEqual(expand_decl(self.parse(s1).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800655 ['Decl', 'joe',
656 ['TypeDecl', ['Struct', None,
657 [ ['Decl', 'id',
658 ['TypeDecl',
659 ['IdentifierType', ['int']]]],
660 ['Decl', 'name',
661 ['PtrDecl',
662 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300663 ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800664
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300665 s2 = """
666 struct node p;
667 """
668 self.assertEqual(expand_decl(self.parse(s2).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800669 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300670 ['TypeDecl', ['Struct', 'node', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800671
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300672 s21 = """
673 union pri ra;
674 """
675 self.assertEqual(expand_decl(self.parse(s21).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800676 ['Decl', 'ra',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300677 ['TypeDecl', ['Union', 'pri', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800678
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300679 s3 = """
680 struct node* p;
681 """
682 self.assertEqual(expand_decl(self.parse(s3).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800683 ['Decl', 'p',
684 ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300685 ['TypeDecl', ['Struct', 'node', []]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800686
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300687 s4 = """
688 struct node;
689 """
690 self.assertEqual(expand_decl(self.parse(s4).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800691 ['Decl', None,
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300692 ['Struct', 'node', []]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800693
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300694 s5 = """
695 union
696 {
697 struct
698 {
699 int type;
700 } n;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800701
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300702 struct
703 {
704 int type;
705 int intnode;
706 } ni;
707 } u;
708 """
709 self.assertEqual(expand_decl(self.parse(s5).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800710 ['Decl', 'u',
711 ['TypeDecl',
712 ['Union', None,
713 [['Decl', 'n',
714 ['TypeDecl',
715 ['Struct', None,
716 [['Decl', 'type',
717 ['TypeDecl', ['IdentifierType', ['int']]]]]]]],
718 ['Decl', 'ni',
719 ['TypeDecl',
720 ['Struct', None,
721 [['Decl', 'type',
722 ['TypeDecl', ['IdentifierType', ['int']]]],
723 ['Decl', 'intnode',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300724 ['TypeDecl', ['IdentifierType', ['int']]]]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800725
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300726 s6 = """
727 typedef struct foo_tag
728 {
729 void* data;
730 } foo, *pfoo;
731 """
732 s6_ast = self.parse(s6)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800733
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300734 self.assertEqual(expand_decl(s6_ast.ext[0]),
735 ['Typedef', 'foo',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800736 ['TypeDecl',
737 ['Struct', 'foo_tag',
738 [['Decl', 'data',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300739 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['void']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800740
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300741 self.assertEqual(expand_decl(s6_ast.ext[1]),
742 ['Typedef', 'pfoo',
743 ['PtrDecl',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800744 ['TypeDecl',
745 ['Struct', 'foo_tag',
746 [['Decl', 'data',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300747 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['void']]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800748
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300749 s7 = r"""
750 struct _on_exit_args {
751 void * _fnargs[32];
752 void * _dso_handle[32];
753
754 long _fntypes;
755 #line 77 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
756
757 long _is_cxa;
758 };
759 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800760
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300761 s7_ast = self.parse(s7, filename='test.c')
serpilliere471442f2017-03-10 15:02:00 +0100762 self.assert_coord(s7_ast.ext[0].type.decls[2], 6, 22, 'test.c')
763 self.assert_coord(s7_ast.ext[0].type.decls[3], 78, 22,
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300764 r'D:\eli\cpp_stuff\libc_include/sys/reent.h')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800765
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300766 s8 = """
767 typedef enum tagReturnCode {SUCCESS, FAIL} ReturnCode;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800768
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300769 typedef struct tagEntry
770 {
771 char* key;
772 char* value;
773 } Entry;
774
775
776 typedef struct tagNode
777 {
778 Entry* entry;
779
780 struct tagNode* next;
781 } Node;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800782
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300783 typedef struct tagHash
784 {
785 unsigned int table_size;
786
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800787 Node** heads;
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300788
789 } Hash;
790 """
791 s8_ast = self.parse(s8)
792 self.assertEqual(expand_decl(s8_ast.ext[3]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800793 ['Typedef', 'Hash',
794 ['TypeDecl', ['Struct', 'tagHash',
795 [['Decl', 'table_size',
796 ['TypeDecl', ['IdentifierType', ['unsigned', 'int']]]],
797 ['Decl', 'heads',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300798 ['PtrDecl', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['Node']]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800799
Eli Bendersky95e3b762016-03-19 05:21:59 -0700800 def test_struct_with_extra_semis_inside(self):
801 s1 = """
802 struct {
803 int a;;
804 } foo;
805 """
806 s1_ast = self.parse(s1)
807 self.assertEqual(expand_decl(s1_ast.ext[0]),
808 ['Decl', 'foo',
809 ['TypeDecl', ['Struct', None,
810 [['Decl', 'a',
811 ['TypeDecl', ['IdentifierType', ['int']]]]]]]])
812
813 s2 = """
814 struct {
815 int a;;;;
816 float b, c;
817 ;;
818 char d;
819 } foo;
820 """
821 s2_ast = self.parse(s2)
822 self.assertEqual(expand_decl(s2_ast.ext[0]),
823 ['Decl', 'foo',
824 ['TypeDecl', ['Struct', None,
825 [['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]],
826 ['Decl', 'b', ['TypeDecl', ['IdentifierType', ['float']]]],
827 ['Decl', 'c', ['TypeDecl', ['IdentifierType', ['float']]]],
828 ['Decl', 'd',
829 ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
830
eli.bendersky697ecc52011-02-10 07:05:13 +0200831 def test_anonymous_struct_union(self):
832 s1 = """
833 union
834 {
835 union
836 {
837 int i;
838 long l;
839 };
840
841 struct
842 {
843 int type;
844 int intnode;
845 };
846 } u;
847 """
848
849 self.assertEqual(expand_decl(self.parse(s1).ext[0]),
850 ['Decl', 'u',
851 ['TypeDecl',
852 ['Union', None,
853 [['Decl', None,
854 ['Union', None,
855 [['Decl', 'i',
856 ['TypeDecl',
857 ['IdentifierType', ['int']]]],
858 ['Decl', 'l',
859 ['TypeDecl',
860 ['IdentifierType', ['long']]]]]]],
861 ['Decl', None,
862 ['Struct', None,
863 [['Decl', 'type',
864 ['TypeDecl',
865 ['IdentifierType', ['int']]]],
866 ['Decl', 'intnode',
867 ['TypeDecl',
868 ['IdentifierType', ['int']]]]]]]]]]])
869
870 s2 = """
871 struct
872 {
873 int i;
874 union
875 {
876 int id;
877 char* name;
878 };
879 float f;
880 } joe;
881 """
882
883 self.assertEqual(expand_decl(self.parse(s2).ext[0]),
884 ['Decl', 'joe',
885 ['TypeDecl',
886 ['Struct', None,
887 [['Decl', 'i',
888 ['TypeDecl',
889 ['IdentifierType', ['int']]]],
890 ['Decl', None,
891 ['Union', None,
892 [['Decl', 'id',
893 ['TypeDecl',
894 ['IdentifierType', ['int']]]],
895 ['Decl', 'name',
896 ['PtrDecl',
897 ['TypeDecl',
898 ['IdentifierType', ['char']]]]]]]],
899 ['Decl', 'f',
900 ['TypeDecl',
901 ['IdentifierType', ['float']]]]]]]])
902
903 # ISO/IEC 9899:201x Commitee Draft 2010-11-16, N1539
904 # section 6.7.2.1, par. 19, example 1
905 s3 = """
906 struct v {
907 union {
908 struct { int i, j; };
909 struct { long k, l; } w;
910 };
911 int m;
912 } v1;
913 """
914
915 self.assertEqual(expand_decl(self.parse(s3).ext[0]),
916 ['Decl', 'v1',
917 ['TypeDecl',
918 ['Struct', 'v',
919 [['Decl', None,
920 ['Union', None,
921 [['Decl', None,
922 ['Struct', None,
923 [['Decl', 'i',
924 ['TypeDecl',
925 ['IdentifierType', ['int']]]],
926 ['Decl', 'j',
927 ['TypeDecl',
928 ['IdentifierType', ['int']]]]]]],
929 ['Decl', 'w',
930 ['TypeDecl',
931 ['Struct', None,
932 [['Decl', 'k',
933 ['TypeDecl',
934 ['IdentifierType', ['long']]]],
935 ['Decl', 'l',
936 ['TypeDecl',
937 ['IdentifierType', ['long']]]]]]]]]]],
938 ['Decl', 'm',
939 ['TypeDecl',
940 ['IdentifierType', ['int']]]]]]]])
941
eli.benderskydce29a02011-02-10 07:55:00 +0200942 s4 = """
943 struct v {
944 int i;
945 float;
946 } v2;"""
eli.bendersky6b011792011-06-22 17:50:56 +0300947 # just make sure this doesn't raise ParseError
948 self.parse(s4)
eli.benderskydce29a02011-02-10 07:55:00 +0200949
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400950 def test_struct_members_namespace(self):
Eli Bendersky4d969b32013-07-13 06:07:07 -0700951 """ Tests that structure/union member names reside in a separate
952 namespace and can be named after existing types.
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400953 """
954 s1 = """
955 typedef int Name;
956 typedef Name NameArray[10];
957
958 struct {
959 Name Name;
960 Name NameArray[3];
961 } sye;
962
963 void main(void)
964 {
965 sye.Name = 1;
966 }
967 """
968
969 s1_ast = self.parse(s1)
970 self.assertEqual(expand_decl(s1_ast.ext[2]),
971 ['Decl', 'sye',
972 ['TypeDecl', ['Struct', None,
973 [ ['Decl', 'Name',
974 ['TypeDecl',
975 ['IdentifierType', ['Name']]]],
976 ['Decl', 'NameArray',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800977 ['ArrayDecl', '3', [],
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400978 ['TypeDecl', ['IdentifierType', ['Name']]]]]]]]])
979 self.assertEqual(s1_ast.ext[3].body.block_items[0].lvalue.field.name, 'Name')
980
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200981 def test_struct_bitfields(self):
eli.bendersky38ed9a92010-10-09 09:29:59 +0200982 # a struct with two bitfields, one unnamed
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200983 s1 = """
984 struct {
985 int k:6;
986 int :2;
987 } joe;
988 """
989
990 parsed_struct = self.parse(s1).ext[0]
991
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800992 # We can see here the name of the decl for the unnamed bitfield is
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200993 # None, but expand_decl doesn't show bitfield widths
994 # ...
995 self.assertEqual(expand_decl(parsed_struct),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800996 ['Decl', 'joe',
997 ['TypeDecl', ['Struct', None,
998 [ ['Decl', 'k',
999 ['TypeDecl',
1000 ['IdentifierType', ['int']]]],
1001 ['Decl', None,
1002 ['TypeDecl',
eli.bendersky0e0a71f2010-10-09 08:32:00 +02001003 ['IdentifierType', ['int']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001004
eli.bendersky0e0a71f2010-10-09 08:32:00 +02001005 # ...
1006 # so we test them manually
1007 self.assertEqual(parsed_struct.type.type.decls[0].bitsize.value, '6')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001008 self.assertEqual(parsed_struct.type.type.decls[1].bitsize.value, '2')
1009
ldore81a12ca2018-04-28 05:09:24 +02001010 def test_struct_empty(self):
1011 """
1012 Tests that parsing an empty struct works.
Eli Bendersky8ff80882018-07-25 05:36:22 -07001013
ldore81a12ca2018-04-28 05:09:24 +02001014 Empty structs do NOT follow C99 (See 6.2.5-20 of the C99 standard).
Eli Bendersky8ff80882018-07-25 05:36:22 -07001015 This is nevertheless supported by some compilers (clang, gcc),
1016 especially when using FORTIFY code.
ldore81a12ca2018-04-28 05:09:24 +02001017 Some compilers (visual) will fail to compile with an error.
1018 """
1019 # an empty struct. This is NOT C99 compliant
1020 s1 = """
1021 struct foo { };
1022 """
1023
1024 parsed_struct = self.parse(s1).ext[0]
ldore81a12ca2018-04-28 05:09:24 +02001025 self.assertEqual(expand_decl(parsed_struct),
Eli Bendersky92f65b62018-07-25 05:48:56 -07001026 ['Decl', None, ['Struct', 'foo', []]])
1027
1028 s2 = """struct { } foo;"""
1029 parsed_struct = self.parse(s2).ext[0]
1030 self.assertEqual(expand_decl(parsed_struct),
1031 ['Decl', 'foo', ['TypeDecl', ['Struct', None, []]]])
1032
1033 s3 = """union { } foo;"""
1034 parsed_struct = self.parse(s3).ext[0]
1035 self.assertEqual(expand_decl(parsed_struct),
1036 ['Decl', 'foo', ['TypeDecl', ['Union', None, []]]])
ldore81a12ca2018-04-28 05:09:24 +02001037
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001038 def test_tags_namespace(self):
1039 """ Tests that the tags of structs/unions/enums reside in a separate namespace and
1040 can be named after existing types.
1041 """
1042 s1 = """
1043 typedef int tagEntry;
1044
1045 struct tagEntry
1046 {
1047 char* key;
1048 char* value;
1049 } Entry;
1050 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001051
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001052 s1_ast = self.parse(s1)
1053 self.assertEqual(expand_decl(s1_ast.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001054 ['Decl', 'Entry',
1055 ['TypeDecl', ['Struct', 'tagEntry',
1056 [['Decl', 'key',
1057 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
1058 ['Decl', 'value',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001059 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001060
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001061 s2 = """
1062 struct tagEntry;
1063
1064 typedef struct tagEntry tagEntry;
1065
1066 struct tagEntry
1067 {
1068 char* key;
1069 char* value;
1070 } Entry;
1071 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001072
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001073 s2_ast = self.parse(s2)
1074 self.assertEqual(expand_decl(s2_ast.ext[2]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001075 ['Decl', 'Entry',
1076 ['TypeDecl', ['Struct', 'tagEntry',
1077 [['Decl', 'key',
1078 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
1079 ['Decl', 'value',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001080 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001081
1082 s3 = """
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001083 typedef int mytag;
1084
1085 enum mytag {ABC, CDE};
1086 enum mytag joe;
1087 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001088
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001089 s3_type = self.parse(s3).ext[1].type
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001090
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001091 self.assertIsInstance(s3_type, Enum)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001092 self.assertEqual(s3_type.name, 'mytag')
1093
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001094 def test_multi_decls(self):
1095 d1 = 'int a, b;'
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001096
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001097 self.assertEqual(self.get_decl(d1, 0),
1098 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
1099 self.assertEqual(self.get_decl(d1, 1),
1100 ['Decl', 'b', ['TypeDecl', ['IdentifierType', ['int']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001101
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001102 d2 = 'char* p, notp, ar[4];'
1103 self.assertEqual(self.get_decl(d2, 0),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001104 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001105 ['PtrDecl',
1106 ['TypeDecl', ['IdentifierType', ['char']]]]])
1107 self.assertEqual(self.get_decl(d2, 1),
1108 ['Decl', 'notp', ['TypeDecl', ['IdentifierType', ['char']]]])
1109 self.assertEqual(self.get_decl(d2, 2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001110 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001111 ['ArrayDecl', '4', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001112 ['TypeDecl', ['IdentifierType', ['char']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001113
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001114 def test_invalid_multiple_types_error(self):
1115 bad = [
1116 'int enum {ab, cd} fubr;',
1117 'enum kid char brbr;']
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001118
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001119 for b in bad:
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001120 self.assertRaises(ParseError, self.parse, b)
Eli Bendersky9dadc3f2012-07-06 15:53:53 +03001121
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001122 def test_duplicate_typedef(self):
1123 """ Tests that redeclarations of existing types are parsed correctly.
1124 This is non-standard, but allowed by many compilers.
1125 """
1126 d1 = '''
Eli Bendersky9dadc3f2012-07-06 15:53:53 +03001127 typedef int numbertype;
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001128 typedef int numbertype;
Eli Bendersky9dadc3f2012-07-06 15:53:53 +03001129 '''
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001130
1131 self.assertEqual(self.get_decl(d1, 0),
1132 ['Typedef', 'numbertype',
1133 ['TypeDecl', ['IdentifierType', ['int']]]])
1134 self.assertEqual(self.get_decl(d1, 1),
1135 ['Typedef', 'numbertype',
1136 ['TypeDecl', ['IdentifierType', ['int']]]])
1137
1138 d2 = '''
1139 typedef int (*funcptr)(int x);
1140 typedef int (*funcptr)(int x);
1141 '''
1142 self.assertEqual(self.get_decl(d2, 0),
1143 ['Typedef', 'funcptr',
1144 ['PtrDecl', ['FuncDecl',
1145 [['Decl', 'x', ['TypeDecl', ['IdentifierType', ['int']]]]],
1146 ['TypeDecl', ['IdentifierType', ['int']]]]]])
1147 self.assertEqual(self.get_decl(d2, 1),
1148 ['Typedef', 'funcptr',
1149 ['PtrDecl', ['FuncDecl',
1150 [['Decl', 'x', ['TypeDecl', ['IdentifierType', ['int']]]]],
1151 ['TypeDecl', ['IdentifierType', ['int']]]]]])
1152
1153 d3 = '''
1154 typedef int numberarray[5];
1155 typedef int numberarray[5];
1156 '''
1157 self.assertEqual(self.get_decl(d3, 0),
1158 ['Typedef', 'numberarray',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001159 ['ArrayDecl', '5', [],
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001160 ['TypeDecl', ['IdentifierType', ['int']]]]])
1161 self.assertEqual(self.get_decl(d3, 1),
1162 ['Typedef', 'numberarray',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001163 ['ArrayDecl', '5', [],
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001164 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001165
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001166 def test_decl_inits(self):
1167 d1 = 'int a = 16;'
eli.benderskyf890a862010-10-30 12:13:23 +02001168 #~ self.parse(d1).show()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001169 self.assertEqual(self.get_decl(d1),
1170 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
1171 self.assertEqual(self.get_decl_init(d1),
1172 ['Constant', 'int', '16'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001173
Eli Bendersky3b1b08d2012-06-15 12:37:54 +03001174 d1_1 = 'float f = 0xEF.56p1;'
1175 self.assertEqual(self.get_decl_init(d1_1),
1176 ['Constant', 'float', '0xEF.56p1'])
1177
Konstanty Bialkowski3bdbfdc2015-04-19 20:09:21 +10001178 d1_2 = 'int bitmask = 0b1001010;'
1179 self.assertEqual(self.get_decl_init(d1_2),
1180 ['Constant', 'int', '0b1001010'])
1181
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001182 d2 = 'long ar[] = {7, 8, 9};'
1183 self.assertEqual(self.get_decl(d2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001184 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001185 ['ArrayDecl', '', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001186 ['TypeDecl', ['IdentifierType', ['long']]]]])
1187 self.assertEqual(self.get_decl_init(d2),
1188 [ ['Constant', 'int', '7'],
1189 ['Constant', 'int', '8'],
eli.benderskyf890a862010-10-30 12:13:23 +02001190 ['Constant', 'int', '9']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001191
Eli Benderskyc830da82015-05-10 07:56:41 -07001192 d21 = 'long ar[4] = {};'
1193 self.assertEqual(self.get_decl_init(d21), [])
1194
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001195 d3 = 'char p = j;'
1196 self.assertEqual(self.get_decl(d3),
1197 ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['char']]]])
1198 self.assertEqual(self.get_decl_init(d3),
1199 ['ID', 'j'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001200
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001201 d4 = "char x = 'c', *p = {0, 1, 2, {4, 5}, 6};"
1202 self.assertEqual(self.get_decl(d4, 0),
1203 ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['char']]]])
1204 self.assertEqual(self.get_decl_init(d4, 0),
1205 ['Constant', 'char', "'c'"])
1206 self.assertEqual(self.get_decl(d4, 1),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001207 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001208 ['PtrDecl',
1209 ['TypeDecl', ['IdentifierType', ['char']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001210
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001211 self.assertEqual(self.get_decl_init(d4, 1),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001212 [ ['Constant', 'int', '0'],
1213 ['Constant', 'int', '1'],
1214 ['Constant', 'int', '2'],
1215 [['Constant', 'int', '4'],
1216 ['Constant', 'int', '5']],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001217 ['Constant', 'int', '6']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001218
Robbert Harmsa915c3d2018-08-31 15:00:14 +02001219 d5 = 'float d = 1.0;'
1220 self.assertEqual(self.get_decl_init(d5),
1221 ['Constant', 'double', '1.0'])
1222
1223 d51 = 'float ld = 1.0l;'
1224 self.assertEqual(self.get_decl_init(d51),
1225 ['Constant', 'long double', '1.0l'])
1226
1227 d52 = 'float ld = 1.0L;'
1228 self.assertEqual(self.get_decl_init(d52),
1229 ['Constant', 'long double', '1.0L'])
1230
1231 d53 = 'float ld = 1.0f;'
1232 self.assertEqual(self.get_decl_init(d53),
1233 ['Constant', 'float', '1.0f'])
1234
1235 d54 = 'float ld = 1.0F;'
1236 self.assertEqual(self.get_decl_init(d54),
1237 ['Constant', 'float', '1.0F'])
1238
Eli Bendersky40f0d912018-08-31 06:03:05 -07001239 d55 = 'float ld = 0xDE.38p0;'
1240 self.assertEqual(self.get_decl_init(d55),
1241 ['Constant', 'float', '0xDE.38p0'])
Robbert Harmsa915c3d2018-08-31 15:00:14 +02001242
eli.benderskyf890a862010-10-30 12:13:23 +02001243 def test_decl_named_inits(self):
1244 d1 = 'int a = {.k = 16};'
1245 self.assertEqual(self.get_decl_init(d1),
1246 [( [['ID', 'k']],
1247 ['Constant', 'int', '16'])])
1248
1249 d2 = 'int a = { [0].a = {1}, [1].a[0] = 2 };'
1250 self.assertEqual(self.get_decl_init(d2),
1251 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001252 ([['Constant', 'int', '0'], ['ID', 'a']],
1253 [['Constant', 'int', '1']]),
1254 ([['Constant', 'int', '1'], ['ID', 'a'], ['Constant', 'int', '0']],
eli.benderskyf890a862010-10-30 12:13:23 +02001255 ['Constant', 'int', '2'])])
1256
1257 d3 = 'int a = { .a = 1, .c = 3, 4, .b = 5};'
1258 self.assertEqual(self.get_decl_init(d3),
1259 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001260 ([['ID', 'a']], ['Constant', 'int', '1']),
1261 ([['ID', 'c']], ['Constant', 'int', '3']),
1262 ['Constant', 'int', '4'],
eli.benderskyf890a862010-10-30 12:13:23 +02001263 ([['ID', 'b']], ['Constant', 'int', '5'])])
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001264
1265 def test_function_definitions(self):
1266 def parse_fdef(str):
1267 return self.parse(str).ext[0]
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001268
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001269 def fdef_decl(fdef):
1270 return expand_decl(fdef.decl)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001271
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001272 f1 = parse_fdef('''
1273 int factorial(int p)
1274 {
1275 return 3;
1276 }
1277 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001278
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001279 self.assertEqual(fdef_decl(f1),
1280 ['Decl', 'factorial',
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001281 ['FuncDecl',
1282 [['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001283 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001284
eli.benderskyef29ff92010-10-29 16:25:43 +02001285 self.assertEqual(type(f1.body.block_items[0]), Return)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001286
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001287 f2 = parse_fdef('''
1288 char* zzz(int p, char* c)
1289 {
1290 int a;
1291 char b;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001292
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001293 a = b + 2;
1294 return 3;
1295 }
1296 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001297
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001298 self.assertEqual(fdef_decl(f2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001299 ['Decl', 'zzz',
1300 ['FuncDecl',
1301 [ ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]],
1302 ['Decl', 'c', ['PtrDecl',
1303 ['TypeDecl', ['IdentifierType', ['char']]]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001304 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001305
1306 self.assertEqual(list(map(type, f2.body.block_items)),
eli.benderskyef29ff92010-10-29 16:25:43 +02001307 [Decl, Decl, Assignment, Return])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001308
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001309 f3 = parse_fdef('''
1310 char* zzz(p, c)
1311 long p, *c;
1312 {
1313 int a;
1314 char b;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001315
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001316 a = b + 2;
1317 return 3;
1318 }
1319 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001320
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001321 self.assertEqual(fdef_decl(f3),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001322 ['Decl', 'zzz',
1323 ['FuncDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001324 [ ['ID', 'p'],
1325 ['ID', 'c']],
1326 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001327
1328 self.assertEqual(list(map(type, f3.body.block_items)),
eli.benderskyef29ff92010-10-29 16:25:43 +02001329 [Decl, Decl, Assignment, Return])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001330
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001331 self.assertEqual(expand_decl(f3.param_decls[0]),
1332 ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['long']]]])
1333 self.assertEqual(expand_decl(f3.param_decls[1]),
1334 ['Decl', 'c', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['long']]]]])
1335
Sye van der Veen51a46ec2013-06-10 12:56:15 -04001336 # function return values and parameters may not have type information
1337 f4 = parse_fdef('''
1338 que(p)
1339 {
1340 return 3;
1341 }
1342 ''')
1343
1344 self.assertEqual(fdef_decl(f4),
1345 ['Decl', 'que',
1346 ['FuncDecl',
1347 [['ID', 'p']],
1348 ['TypeDecl', ['IdentifierType', ['int']]]]])
1349
eli.bendersky71540662010-07-03 12:58:52 +02001350 def test_unified_string_literals(self):
1351 # simple string, for reference
1352 d1 = self.get_decl_init('char* s = "hello";')
1353 self.assertEqual(d1, ['Constant', 'string', '"hello"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001354
eli.bendersky71540662010-07-03 12:58:52 +02001355 d2 = self.get_decl_init('char* s = "hello" " world";')
1356 self.assertEqual(d2, ['Constant', 'string', '"hello world"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001357
eli.bendersky71540662010-07-03 12:58:52 +02001358 # the test case from issue 6
1359 d3 = self.parse(r'''
1360 int main() {
1361 fprintf(stderr,
1362 "Wrong Params?\n"
1363 "Usage:\n"
1364 "%s <binary_file_path>\n",
1365 argv[0]
1366 );
1367 }
1368 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001369
eli.bendersky71540662010-07-03 12:58:52 +02001370 self.assertEqual(
eli.benderskyef29ff92010-10-29 16:25:43 +02001371 d3.ext[0].body.block_items[0].args.exprs[1].value,
eli.bendersky71540662010-07-03 12:58:52 +02001372 r'"Wrong Params?\nUsage:\n%s <binary_file_path>\n"')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001373
eli.bendersky4a89f112010-07-05 06:02:03 +02001374 d4 = self.get_decl_init('char* s = "" "foobar";')
1375 self.assertEqual(d4, ['Constant', 'string', '"foobar"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001376
eli.bendersky4a89f112010-07-05 06:02:03 +02001377 d5 = self.get_decl_init(r'char* s = "foo\"" "bar";')
1378 self.assertEqual(d5, ['Constant', 'string', r'"foo\"bar"'])
eli.bendersky71540662010-07-03 12:58:52 +02001379
Eli Benderskyc9f1a382014-03-15 14:12:00 -07001380 def test_unified_wstring_literals(self):
1381 d1 = self.get_decl_init('char* s = L"hello" L"world";')
1382 self.assertEqual(d1, ['Constant', 'string', 'L"helloworld"'])
1383
1384 d2 = self.get_decl_init('char* s = L"hello " L"world" L" and I";')
1385 self.assertEqual(d2, ['Constant', 'string', 'L"hello world and I"'])
1386
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001387 def test_inline_specifier(self):
eli.bendersky79d5cf62010-10-29 13:33:52 +02001388 ps2 = self.parse('static inline void inlinefoo(void);')
1389 self.assertEqual(ps2.ext[0].funcspec, ['inline'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001390
eli.bendersky2e907fa2010-10-29 15:51:07 +02001391 # variable length array
1392 def test_vla(self):
1393 ps2 = self.parse(r'''
1394 int main() {
1395 int size;
1396 int var[size = 5];
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001397
eli.bendersky2e907fa2010-10-29 15:51:07 +02001398 int var2[*];
1399 }
1400 ''')
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001401 self.assertIsInstance(ps2.ext[0].body.block_items[1].type.dim, Assignment)
1402 self.assertIsInstance(ps2.ext[0].body.block_items[2].type.dim, ID)
eli.bendersky79d5cf62010-10-29 13:33:52 +02001403
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001404 def test_pragma(self):
1405 s1 = r'''
1406 #pragma bar
1407 void main() {
1408 #pragma foo
1409 for(;;) {}
Julian Hammer8a174062015-12-14 14:48:16 +01001410 #pragma
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001411 }
ldoreec233182017-11-22 14:52:53 +01001412 struct s {
1413 #pragma baz
1414 } s;
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001415 '''
1416 s1_ast = self.parse(s1)
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001417 self.assertIsInstance(s1_ast.ext[0], Pragma)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001418 self.assertEqual(s1_ast.ext[0].string, 'bar')
Julian Hammer8a174062015-12-14 14:48:16 +01001419 self.assertEqual(s1_ast.ext[0].coord.line, 2)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001420
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001421 self.assertIsInstance(s1_ast.ext[1].body.block_items[0], Pragma)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001422 self.assertEqual(s1_ast.ext[1].body.block_items[0].string, 'foo')
Julian Hammer8a174062015-12-14 14:48:16 +01001423 self.assertEqual(s1_ast.ext[1].body.block_items[0].coord.line, 4)
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001424
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001425 self.assertIsInstance(s1_ast.ext[1].body.block_items[2], Pragma)
Julian Hammer8a174062015-12-14 14:48:16 +01001426 self.assertEqual(s1_ast.ext[1].body.block_items[2].string, '')
1427 self.assertEqual(s1_ast.ext[1].body.block_items[2].coord.line, 6)
Eli Bendersky8ff80882018-07-25 05:36:22 -07001428
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001429 self.assertIsInstance(s1_ast.ext[2].type.type.decls[0], Pragma)
ldoreec233182017-11-22 14:52:53 +01001430 self.assertEqual(s1_ast.ext[2].type.type.decls[0].string, 'baz')
1431 self.assertEqual(s1_ast.ext[2].type.type.decls[0].coord.line, 9)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001432
dbluhm7af2fb92018-03-03 06:18:26 -07001433 def test_pragmacomp_or_statement(self):
1434 s1 = r'''
1435 void main() {
1436 int sum = 0;
1437 for (int i; i < 3; i++)
1438 #pragma omp critical
1439 sum += 1;
1440
1441 while(sum < 10)
1442 #pragma omp critical
1443 sum += 1;
1444
1445 mylabel:
1446 #pragma foo
1447 sum += 10;
1448
1449 if (sum > 10)
1450 #pragma bar
1451 sum = 10;
1452
1453 switch (sum)
1454 case 10:
1455 #pragma foo
1456 sum = 20;
1457 }
1458 '''
1459 s1_ast = self.parse(s1)
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001460 self.assertIsInstance(s1_ast.ext[0].body.block_items[1], For)
1461 self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt, Compound)
1462 self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt.block_items[0], Pragma)
1463 self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt.block_items[1], Assignment)
1464 self.assertIsInstance(s1_ast.ext[0].body.block_items[2], While)
1465 self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt, Compound)
1466 self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt.block_items[0], Pragma)
1467 self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt.block_items[1], Assignment)
1468 self.assertIsInstance(s1_ast.ext[0].body.block_items[3], Label)
1469 self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt, Compound)
1470 self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt.block_items[0], Pragma)
1471 self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt.block_items[1], Assignment)
1472 self.assertIsInstance(s1_ast.ext[0].body.block_items[4], If)
1473 self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue, Compound)
1474 self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue.block_items[0], Pragma)
1475 self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue.block_items[1], Assignment)
1476 self.assertIsInstance(s1_ast.ext[0].body.block_items[5], Switch)
1477 self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0], Compound)
1478 self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0].block_items[0], Pragma)
1479 self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0].block_items[1], Assignment)
dbluhm7af2fb92018-03-03 06:18:26 -07001480
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001481
eli.bendersky85d2e732011-05-20 19:47:26 +03001482class TestCParser_whole_code(TestCParser_base):
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001483 """ Testing of parsing whole chunks of code.
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001484
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001485 Since I don't want to rely on the structure of ASTs too
1486 much, most of these tests are implemented with visitors.
1487 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001488 # A simple helper visitor that lists the values of all the
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001489 # Constant nodes it sees.
1490 #
1491 class ConstantVisitor(NodeVisitor):
1492 def __init__(self):
1493 self.values = []
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001494
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001495 def visit_Constant(self, node):
1496 self.values.append(node.value)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001497
1498 # This visitor counts the amount of references to the ID
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001499 # with the name provided to it in the constructor.
1500 #
1501 class IDNameCounter(NodeVisitor):
1502 def __init__(self, name):
1503 self.name = name
1504 self.nrefs = 0
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001505
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001506 def visit_ID(self, node):
1507 if node.name == self.name:
1508 self.nrefs += 1
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001509
1510 # Counts the amount of nodes of a given class
1511 #
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001512 class NodeKlassCounter(NodeVisitor):
1513 def __init__(self, node_klass):
1514 self.klass = node_klass
1515 self.n = 0
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001516
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001517 def generic_visit(self, node):
1518 if node.__class__ == self.klass:
1519 self.n += 1
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001520
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001521 NodeVisitor.generic_visit(self, node)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001522
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001523 def assert_all_Constants(self, code, constants):
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001524 """ Asserts that the list of all Constant values (by
1525 'preorder' appearance) in the chunk of code is as
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001526 given.
1527 """
eli.benderskyed890492010-06-25 08:25:55 +03001528 if isinstance(code, str):
1529 parsed = self.parse(code)
1530 else:
1531 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001532
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001533 cv = self.ConstantVisitor()
1534 cv.visit(parsed)
1535 self.assertEqual(cv.values, constants)
1536
1537 def assert_num_ID_refs(self, code, name, num):
1538 """ Asserts the number of references to the ID with
1539 the given name.
1540 """
1541 if isinstance(code, str):
1542 parsed = self.parse(code)
1543 else:
1544 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001545
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001546 iv = self.IDNameCounter(name)
1547 iv.visit(parsed)
1548 self.assertEqual(iv.nrefs, num)
1549
1550 def assert_num_klass_nodes(self, code, klass, num):
1551 """ Asserts the amount of klass nodes in the code.
1552 """
1553 if isinstance(code, str):
1554 parsed = self.parse(code)
1555 else:
1556 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001557
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001558 cv = self.NodeKlassCounter(klass)
1559 cv.visit(parsed)
1560 self.assertEqual(cv.n, num)
1561
1562 def test_expressions(self):
1563 e1 = '''int k = (r + 10.0) >> 6 + 8 << (3 & 0x14);'''
1564 self.assert_all_Constants(e1, ['10.0', '6', '8', '3', '0x14'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001565
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001566 e2 = r'''char n = '\n', *prefix = "st_";'''
1567 self.assert_all_Constants(e2, [r"'\n'", '"st_"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001568
Eli Bendersky09e22a62013-07-02 06:00:36 -07001569 s1 = r'''int main() {
1570 int i = 5, j = 6, k = 1;
1571 if ((i=j && k == 1) || k > j)
1572 printf("Hello, world\n");
1573 return 0;
1574 }'''
1575 ps1 = self.parse(s1)
1576 self.assert_all_Constants(ps1,
1577 ['5', '6', '1', '1', '"Hello, world\\n"', '0'])
1578 self.assert_num_ID_refs(ps1, 'i', 1)
1579 self.assert_num_ID_refs(ps1, 'j', 2)
1580
1581
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001582 def test_statements(self):
1583 s1 = r'''
1584 void foo(){
1585 if (sp == 1)
1586 if (optind >= argc ||
1587 argv[optind][0] != '-' || argv[optind][1] == '\0')
1588 return -1;
1589 else if (strcmp(argv[optind], "--") == 0) {
1590 optind++;
1591 return -1;
1592 }
1593 }
1594 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001595
1596 self.assert_all_Constants(s1,
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001597 ['1', '0', r"'-'", '1', r"'\0'", '1', r'"--"', '0', '1'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001598
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001599 ps1 = self.parse(s1)
1600 self.assert_num_ID_refs(ps1, 'argv', 3)
1601 self.assert_num_ID_refs(ps1, 'optind', 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001602
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001603 self.assert_num_klass_nodes(ps1, If, 3)
1604 self.assert_num_klass_nodes(ps1, Return, 2)
1605 self.assert_num_klass_nodes(ps1, FuncCall, 1) # strcmp
1606 self.assert_num_klass_nodes(ps1, BinaryOp, 7)
1607
1608 # In the following code, Hash and Node were defined as
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001609 # int to pacify the parser that sees they're used as
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001610 # types
1611 #
1612 s2 = r'''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001613 typedef int Hash, Node;
1614
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001615 void HashDestroy(Hash* hash)
1616 {
1617 unsigned int i;
1618
1619 if (hash == NULL)
1620 return;
1621
1622 for (i = 0; i < hash->table_size; ++i)
1623 {
1624 Node* temp = hash->heads[i];
1625
1626 while (temp != NULL)
1627 {
1628 Node* temp2 = temp;
1629
1630 free(temp->entry->key);
1631 free(temp->entry->value);
1632 free(temp->entry);
1633
1634 temp = temp->next;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001635
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001636 free(temp2);
1637 }
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001638 }
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001639
1640 free(hash->heads);
1641 hash->heads = NULL;
1642
1643 free(hash);
1644 }
1645 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001646
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001647 ps2 = self.parse(s2)
1648 self.assert_num_klass_nodes(ps2, FuncCall, 6)
1649 self.assert_num_klass_nodes(ps2, FuncDef, 1)
1650 self.assert_num_klass_nodes(ps2, For, 1)
1651 self.assert_num_klass_nodes(ps2, While, 1)
1652 self.assert_num_klass_nodes(ps2, StructRef, 10)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001653
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001654 # declarations don't count
1655 self.assert_num_ID_refs(ps2, 'hash', 6)
1656 self.assert_num_ID_refs(ps2, 'i', 4)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001657
eli.benderskyed890492010-06-25 08:25:55 +03001658 s3 = r'''
1659 void x(void) {
1660 int a, b;
1661 if (a < b)
1662 do {
1663 a = 0;
1664 } while (0);
1665 else if (a == b) {
1666 a = 1;
1667 }
1668 }
1669 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001670
eli.benderskyed890492010-06-25 08:25:55 +03001671 ps3 = self.parse(s3)
1672 self.assert_num_klass_nodes(ps3, DoWhile, 1)
1673 self.assert_num_ID_refs(ps3, 'a', 4)
1674 self.assert_all_Constants(ps3, ['0', '0', '1'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001675
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001676 def test_empty_statements(self):
eli.bendersky91c0aa32011-10-16 05:50:43 +02001677 s1 = r'''
1678 void foo(void){
1679 ;
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001680 return;;
1681
1682 ;
eli.bendersky91c0aa32011-10-16 05:50:43 +02001683 }
1684 '''
1685 ps1 = self.parse(s1)
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001686 self.assert_num_klass_nodes(ps1, EmptyStatement, 3)
eli.bendersky91c0aa32011-10-16 05:50:43 +02001687 self.assert_num_klass_nodes(ps1, Return, 1)
serpilliere471442f2017-03-10 15:02:00 +01001688 self.assert_coord(ps1.ext[0].body.block_items[0], 3)
1689 self.assert_coord(ps1.ext[0].body.block_items[1], 4)
1690 self.assert_coord(ps1.ext[0].body.block_items[2], 4)
1691 self.assert_coord(ps1.ext[0].body.block_items[3], 6)
eli.bendersky145890d2010-10-29 12:02:32 +02001692
Ben5cd3fd62012-02-03 06:02:40 +02001693 def test_switch_statement(self):
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001694 def assert_case_node(node, const_value):
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001695 self.assertIsInstance(node, Case)
1696 self.assertIsInstance(node.expr, Constant)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001697 self.assertEqual(node.expr.value, const_value)
1698
1699 def assert_default_node(node):
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001700 self.assertIsInstance(node, Default)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001701
Ben5cd3fd62012-02-03 06:02:40 +02001702 s1 = r'''
1703 int foo(void) {
1704 switch (myvar) {
1705 case 10:
1706 k = 10;
1707 p = k + 1;
1708 return 10;
1709 case 20:
1710 case 30:
1711 return 20;
1712 default:
1713 break;
1714 }
1715 return 0;
1716 }
1717 '''
1718 ps1 = self.parse(s1)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001719 switch = ps1.ext[0].body.block_items[0]
1720
1721 block = switch.stmt.block_items
1722 assert_case_node(block[0], '10')
1723 self.assertEqual(len(block[0].stmts), 3)
1724 assert_case_node(block[1], '20')
1725 self.assertEqual(len(block[1].stmts), 0)
1726 assert_case_node(block[2], '30')
1727 self.assertEqual(len(block[2].stmts), 1)
1728 assert_default_node(block[3])
1729
1730 s2 = r'''
1731 int foo(void) {
1732 switch (myvar) {
1733 default:
1734 joe = moe;
1735 return 10;
1736 case 10:
1737 case 20:
1738 case 30:
1739 case 40:
1740 break;
1741 }
1742 return 0;
1743 }
1744 '''
1745 ps2 = self.parse(s2)
1746 switch = ps2.ext[0].body.block_items[0]
1747
1748 block = switch.stmt.block_items
1749 assert_default_node(block[0])
1750 self.assertEqual(len(block[0].stmts), 2)
1751 assert_case_node(block[1], '10')
1752 self.assertEqual(len(block[1].stmts), 0)
1753 assert_case_node(block[2], '20')
1754 self.assertEqual(len(block[1].stmts), 0)
1755 assert_case_node(block[3], '30')
1756 self.assertEqual(len(block[1].stmts), 0)
1757 assert_case_node(block[4], '40')
1758 self.assertEqual(len(block[4].stmts), 1)
Ben5cd3fd62012-02-03 06:02:40 +02001759
eli.bendersky145890d2010-10-29 12:02:32 +02001760 def test_for_statement(self):
1761 s2 = r'''
1762 void x(void)
1763 {
1764 int i;
1765 for (i = 0; i < 5; ++i) {
1766 x = 50;
1767 }
1768 }
1769 '''
1770 ps2 = self.parse(s2)
1771 self.assert_num_klass_nodes(ps2, For, 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001772 # here there are 3 refs to 'i' since the declaration doesn't count as
eli.bendersky145890d2010-10-29 12:02:32 +02001773 # a ref in the visitor
1774 #
1775 self.assert_num_ID_refs(ps2, 'i', 3)
Eli Bendersky4476d092012-12-25 14:07:57 -08001776
eli.bendersky145890d2010-10-29 12:02:32 +02001777 s3 = r'''
1778 void x(void)
1779 {
1780 for (int i = 0; i < 5; ++i) {
1781 x = 50;
1782 }
1783 }
1784 '''
1785 ps3 = self.parse(s3)
eli.bendersky145890d2010-10-29 12:02:32 +02001786 self.assert_num_klass_nodes(ps3, For, 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001787 # here there are 2 refs to 'i' since the declaration doesn't count as
eli.bendersky145890d2010-10-29 12:02:32 +02001788 # a ref in the visitor
1789 #
1790 self.assert_num_ID_refs(ps3, 'i', 2)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001791
Eli Bendersky4476d092012-12-25 14:07:57 -08001792 s4 = r'''
1793 void x(void) {
1794 for (int i = 0;;)
1795 i;
1796 }
1797 '''
1798 ps4 = self.parse(s4)
1799 self.assert_num_ID_refs(ps4, 'i', 1)
1800
Eli Benderskyd0973782012-01-19 08:09:33 +02001801 def _open_c_file(self, name):
1802 """ Find a c file by name, taking into account the current dir can be
1803 in a couple of typical places
1804 """
Stefano Riveraebaf5922013-08-08 09:45:26 +02001805 testdir = os.path.dirname(__file__)
1806 name = os.path.join(testdir, 'c_files', name)
1807 assert os.path.exists(name)
Jon Dufresne13224c12018-06-26 13:48:31 -07001808 return io.open(name)
Eli Benderskyd0973782012-01-19 08:09:33 +02001809
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001810 def test_whole_file(self):
1811 # See how pycparser handles a whole, real C file.
1812 #
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001813 with self._open_c_file('memmgr_with_h.c') as f:
1814 code = f.read()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001815 p = self.parse(code)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001816
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001817 self.assert_num_klass_nodes(p, FuncDef, 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001818
1819 # each FuncDef also has a FuncDecl. 4 declarations
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001820 # + 5 definitions, overall 9
1821 self.assert_num_klass_nodes(p, FuncDecl, 9)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001822
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001823 self.assert_num_klass_nodes(p, Typedef, 4)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001824
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001825 self.assertEqual(p.ext[4].coord.line, 88)
1826 self.assertEqual(p.ext[4].coord.file, "./memmgr.h")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001827
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001828 self.assertEqual(p.ext[6].coord.line, 10)
1829 self.assertEqual(p.ext[6].coord.file, "memmgr.c")
1830
1831 def test_whole_file_with_stdio(self):
1832 # Parse a whole file with stdio.h included by cpp
1833 #
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001834 with self._open_c_file('cppd_with_stdio_h.c') as f:
1835 code = f.read()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001836 p = self.parse(code)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001837
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001838 self.assertIsInstance(p.ext[0], Typedef)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001839 self.assertEqual(p.ext[0].coord.line, 213)
Ville Skyttä2129f5f2017-03-05 04:52:22 +02001840 self.assertEqual(p.ext[0].coord.file, r"D:\eli\cpp_stuff\libc_include/stddef.h")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001841
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001842 self.assertIsInstance(p.ext[-1], FuncDef)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001843 self.assertEqual(p.ext[-1].coord.line, 15)
1844 self.assertEqual(p.ext[-1].coord.file, "example_c_file.c")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001845
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001846 self.assertIsInstance(p.ext[-8], Typedef)
1847 self.assertIsInstance(p.ext[-8].type, TypeDecl)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001848 self.assertEqual(p.ext[-8].name, 'cookie_io_functions_t')
eli.bendersky85d2e732011-05-20 19:47:26 +03001849
1850
1851class TestCParser_typenames(TestCParser_base):
1852 """ Test issues related to the typedef-name problem.
1853 """
1854 def test_innerscope_typedef(self):
1855 # should fail since TT is not a type in bar
1856 s1 = r'''
1857 void foo() {
1858 typedef char TT;
1859 TT x;
1860 }
1861 void bar() {
1862 TT y;
1863 }
1864 '''
1865 self.assertRaises(ParseError, self.parse, s1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001866
eli.bendersky85d2e732011-05-20 19:47:26 +03001867 # should succeed since TT is not a type in bar
1868 s2 = r'''
1869 void foo() {
1870 typedef char TT;
1871 TT x;
1872 }
1873 void bar() {
1874 unsigned TT;
1875 }
1876 '''
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001877 self.assertIsInstance(self.parse(s2), FileAST)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001878
Nate Bogdanowicz14b8a7e2017-02-22 08:54:05 -05001879 def test_ambiguous_parameters(self):
1880 # From ISO/IEC 9899:TC2, 6.7.5.3.11:
1881 # "If, in a parameter declaration, an identifier can be treated either
1882 # as a typedef name or as a parameter name, it shall be taken as a
1883 # typedef name."
1884
1885 # foo takes an int named aa
1886 # bar takes a function taking a TT
1887 s1 = r'''
1888 typedef char TT;
1889 int foo(int (aa));
1890 int bar(int (TT));
1891 '''
1892 s1_ast = self.parse(s1)
1893 self.assertEqual(expand_decl(s1_ast.ext[1].type.args.params[0]),
1894 ['Decl', 'aa', ['TypeDecl', ['IdentifierType', ['int']]]])
1895 self.assertEqual(expand_decl(s1_ast.ext[2].type.args.params[0]),
1896 ['Typename', ['FuncDecl',
1897 [['Typename', ['TypeDecl', ['IdentifierType', ['TT']]]]],
1898 ['TypeDecl', ['IdentifierType', ['int']]]]])
1899
1900 # foo takes a function taking a char
1901 # bar takes a function taking a function taking a char
1902 s2 = r'''
1903 typedef char TT;
1904 int foo(int (aa (char)));
1905 int bar(int (TT (char)));
1906 '''
1907 s2_ast = self.parse(s2)
1908 self.assertEqual(expand_decl(s2_ast.ext[1].type.args.params[0]),
1909 ['Decl', 'aa', ['FuncDecl',
1910 [['Typename', ['TypeDecl', ['IdentifierType', ['char']]]]],
1911 ['TypeDecl', ['IdentifierType', ['int']]]]])
1912 self.assertEqual(expand_decl(s2_ast.ext[2].type.args.params[0]),
1913 ['Typename', ['FuncDecl',
1914 [['Typename', ['FuncDecl',
1915 [['Typename', ['TypeDecl', ['IdentifierType', ['char']]]]],
1916 ['TypeDecl', ['IdentifierType', ['TT']]]]]],
1917 ['TypeDecl', ['IdentifierType', ['int']]]]])
1918
1919
1920 # foo takes an int array named aa
1921 # bar takes a function taking a TT array
1922 s3 = r'''
1923 typedef char TT;
1924 int foo(int (aa[]));
1925 int bar(int (TT[]));
1926 '''
1927 s3_ast = self.parse(s3)
1928 self.assertEqual(expand_decl(s3_ast.ext[1].type.args.params[0]),
1929 ['Decl', 'aa', ['ArrayDecl', '', [], ['TypeDecl', ['IdentifierType', ['int']]]]])
1930 self.assertEqual(expand_decl(s3_ast.ext[2].type.args.params[0]),
1931 ['Typename', ['FuncDecl',
1932 [['Typename', ['ArrayDecl', '', [], ['TypeDecl', ['IdentifierType', ['TT']]]]]],
1933 ['TypeDecl', ['IdentifierType', ['int']]]]])
1934
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001935 def test_innerscope_reuse_typedef_name(self):
1936 # identifiers can be reused in inner scopes; the original should be
1937 # restored at the end of the block
1938 s1 = r'''
1939 typedef char TT;
1940 void foo(void) {
1941 unsigned TT;
1942 TT = 10;
1943 }
1944 TT x = 5;
1945 '''
1946 s1_ast = self.parse(s1)
1947 self.assertEqual(expand_decl(s1_ast.ext[1].body.block_items[0]),
1948 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
Eli Bendersky3877c4c2013-07-13 06:54:04 -07001949 self.assertEqual(expand_decl(s1_ast.ext[2]),
1950 ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['TT']]]])
eli.bendersky85d2e732011-05-20 19:47:26 +03001951
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001952 # this should be recognized even with an initializer
1953 s2 = r'''
1954 typedef char TT;
1955 void foo(void) {
1956 unsigned TT = 10;
1957 }
1958 '''
1959 s2_ast = self.parse(s2)
1960 self.assertEqual(expand_decl(s2_ast.ext[1].body.block_items[0]),
1961 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1962
1963 # before the second local variable, TT is a type; after, it's a
1964 # variable
1965 s3 = r'''
1966 typedef char TT;
1967 void foo(void) {
1968 TT tt = sizeof(TT);
1969 unsigned TT = 10;
1970 }
1971 '''
1972 s3_ast = self.parse(s3)
1973 self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[0]),
1974 ['Decl', 'tt', ['TypeDecl', ['IdentifierType', ['TT']]]])
1975 self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[1]),
1976 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1977
1978 # a variable and its type can even share the same name
1979 s4 = r'''
1980 typedef char TT;
1981 void foo(void) {
1982 TT TT = sizeof(TT);
1983 unsigned uu = TT * 2;
1984 }
1985 '''
1986 s4_ast = self.parse(s4)
1987 self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[0]),
1988 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['TT']]]])
1989 self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[1]),
1990 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1991
1992 # ensure an error is raised if a type, redeclared as a variable, is
1993 # used as a type
1994 s5 = r'''
1995 typedef char TT;
1996 void foo(void) {
1997 unsigned TT = 10;
1998 TT erroneous = 20;
1999 }
2000 '''
2001 self.assertRaises(ParseError, self.parse, s5)
2002
Nate Bogdanowicz14b8a7e2017-02-22 08:54:05 -05002003 # reusing a type name should work with multiple declarators
2004 s6 = r'''
2005 typedef char TT;
2006 void foo(void) {
2007 unsigned TT, uu;
2008 }
2009 '''
2010 s6_ast = self.parse(s6)
2011 items = s6_ast.ext[1].body.block_items
2012 self.assertEqual(expand_decl(items[0]),
2013 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
2014 self.assertEqual(expand_decl(items[1]),
2015 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
2016
2017 # reusing a type name should work after a pointer
2018 s7 = r'''
2019 typedef char TT;
2020 void foo(void) {
2021 unsigned * TT;
2022 }
2023 '''
2024 s7_ast = self.parse(s7)
2025 items = s7_ast.ext[1].body.block_items
2026 self.assertEqual(expand_decl(items[0]),
2027 ['Decl', 'TT', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['unsigned']]]]])
2028
2029 # redefine a name in the middle of a multi-declarator declaration
2030 s8 = r'''
2031 typedef char TT;
2032 void foo(void) {
2033 int tt = sizeof(TT), TT, uu = sizeof(TT);
2034 int uu = sizeof(tt);
2035 }
2036 '''
2037 s8_ast = self.parse(s8)
2038 items = s8_ast.ext[1].body.block_items
2039 self.assertEqual(expand_decl(items[0]),
2040 ['Decl', 'tt', ['TypeDecl', ['IdentifierType', ['int']]]])
2041 self.assertEqual(expand_decl(items[1]),
2042 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['int']]]])
2043 self.assertEqual(expand_decl(items[2]),
2044 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['int']]]])
2045
2046 # Don't test this until we have support for it
2047 # self.assertEqual(expand_init(items[0].init),
2048 # ['UnaryOp', 'sizeof', ['Typename', ['TypeDecl', ['IdentifierType', ['TT']]]]])
2049 # self.assertEqual(expand_init(items[2].init),
2050 # ['UnaryOp', 'sizeof', ['ID', 'TT']])
2051
Sye van der Veen9ec6c422013-07-11 09:10:38 -04002052 def test_parameter_reuse_typedef_name(self):
2053 # identifiers can be reused as parameter names; parameter name scope
2054 # begins and ends with the function body; it's important that TT is
Eli Bendersky4d969b32013-07-13 06:07:07 -07002055 # used immediately before the LBRACE or after the RBRACE, to test
2056 # a corner case
Sye van der Veen9ec6c422013-07-11 09:10:38 -04002057 s1 = r'''
2058 typedef char TT;
2059 void foo(unsigned TT, TT bar) {
2060 TT = 10;
2061 }
2062 TT x = 5;
2063 '''
2064 s1_ast = self.parse(s1)
2065 self.assertEqual(expand_decl(s1_ast.ext[1].decl),
2066 ['Decl', 'foo',
2067 ['FuncDecl',
2068 [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
2069 ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
2070 ['TypeDecl', ['IdentifierType', ['void']]]]])
2071
2072 # the scope of a parameter name in a function declaration ends at the
2073 # end of the declaration...so it is effectively never used; it's
2074 # important that TT is used immediately after the declaration, to
2075 # test a corner case
2076 s2 = r'''
2077 typedef char TT;
2078 void foo(unsigned TT, TT bar);
2079 TT x = 5;
2080 '''
2081 s2_ast = self.parse(s2)
2082 self.assertEqual(expand_decl(s2_ast.ext[1]),
2083 ['Decl', 'foo',
2084 ['FuncDecl',
2085 [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
2086 ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
2087 ['TypeDecl', ['IdentifierType', ['void']]]]])
2088
2089 # ensure an error is raised if a type, redeclared as a parameter, is
2090 # used as a type
2091 s3 = r'''
2092 typedef char TT;
2093 void foo(unsigned TT, TT bar) {
2094 TT erroneous = 20;
2095 }
2096 '''
2097 self.assertRaises(ParseError, self.parse, s3)
2098
2099 def test_nested_function_decls(self):
2100 # parameter names of nested function declarations must not escape into
2101 # the top-level function _definition's_ scope; the following must
2102 # succeed because TT is still a typedef inside foo's body
2103 s1 = r'''
2104 typedef char TT;
2105 void foo(unsigned bar(int TT)) {
2106 TT x = 10;
2107 }
2108 '''
Jon Dufresnee8afcc92018-06-26 13:49:06 -07002109 self.assertIsInstance(self.parse(s1), FileAST)
Sye van der Veen9ec6c422013-07-11 09:10:38 -04002110
2111 def test_samescope_reuse_name(self):
2112 # a typedef name cannot be reused as an object name in the same scope
2113 s1 = r'''
2114 typedef char TT;
2115 char TT = 5;
2116 '''
2117 self.assertRaises(ParseError, self.parse, s1)
2118
2119 # ...and vice-versa
2120 s2 = r'''
2121 char TT = 5;
2122 typedef char TT;
2123 '''
2124 self.assertRaises(ParseError, self.parse, s2)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03002125
Julian Hammerdb9f2da2015-10-12 15:52:12 +02002126
Eli Bendersky3921e8e2010-05-21 09:05:39 +03002127if __name__ == '__main__':
2128 #~ suite = unittest.TestLoader().loadTestsFromNames(
2129 #~ ['test_c_parser.TestCParser_fundamentals.test_typedef'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08002130
Eli Bendersky3921e8e2010-05-21 09:05:39 +03002131 #~ unittest.TextTestRunner(verbosity=2).run(suite)
2132 unittest.main()