blob: cbba9b689153325cbd453044eb0a28662180991f [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
1239
eli.benderskyf890a862010-10-30 12:13:23 +02001240 def test_decl_named_inits(self):
1241 d1 = 'int a = {.k = 16};'
1242 self.assertEqual(self.get_decl_init(d1),
1243 [( [['ID', 'k']],
1244 ['Constant', 'int', '16'])])
1245
1246 d2 = 'int a = { [0].a = {1}, [1].a[0] = 2 };'
1247 self.assertEqual(self.get_decl_init(d2),
1248 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001249 ([['Constant', 'int', '0'], ['ID', 'a']],
1250 [['Constant', 'int', '1']]),
1251 ([['Constant', 'int', '1'], ['ID', 'a'], ['Constant', 'int', '0']],
eli.benderskyf890a862010-10-30 12:13:23 +02001252 ['Constant', 'int', '2'])])
1253
1254 d3 = 'int a = { .a = 1, .c = 3, 4, .b = 5};'
1255 self.assertEqual(self.get_decl_init(d3),
1256 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001257 ([['ID', 'a']], ['Constant', 'int', '1']),
1258 ([['ID', 'c']], ['Constant', 'int', '3']),
1259 ['Constant', 'int', '4'],
eli.benderskyf890a862010-10-30 12:13:23 +02001260 ([['ID', 'b']], ['Constant', 'int', '5'])])
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001261
1262 def test_function_definitions(self):
1263 def parse_fdef(str):
1264 return self.parse(str).ext[0]
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001265
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001266 def fdef_decl(fdef):
1267 return expand_decl(fdef.decl)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001268
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001269 f1 = parse_fdef('''
1270 int factorial(int p)
1271 {
1272 return 3;
1273 }
1274 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001275
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001276 self.assertEqual(fdef_decl(f1),
1277 ['Decl', 'factorial',
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001278 ['FuncDecl',
1279 [['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001280 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001281
eli.benderskyef29ff92010-10-29 16:25:43 +02001282 self.assertEqual(type(f1.body.block_items[0]), Return)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001283
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001284 f2 = parse_fdef('''
1285 char* zzz(int p, char* c)
1286 {
1287 int a;
1288 char b;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001289
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001290 a = b + 2;
1291 return 3;
1292 }
1293 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001294
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001295 self.assertEqual(fdef_decl(f2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001296 ['Decl', 'zzz',
1297 ['FuncDecl',
1298 [ ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]],
1299 ['Decl', 'c', ['PtrDecl',
1300 ['TypeDecl', ['IdentifierType', ['char']]]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001301 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001302
1303 self.assertEqual(list(map(type, f2.body.block_items)),
eli.benderskyef29ff92010-10-29 16:25:43 +02001304 [Decl, Decl, Assignment, Return])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001305
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001306 f3 = parse_fdef('''
1307 char* zzz(p, c)
1308 long p, *c;
1309 {
1310 int a;
1311 char b;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001312
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001313 a = b + 2;
1314 return 3;
1315 }
1316 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001317
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001318 self.assertEqual(fdef_decl(f3),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001319 ['Decl', 'zzz',
1320 ['FuncDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001321 [ ['ID', 'p'],
1322 ['ID', 'c']],
1323 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001324
1325 self.assertEqual(list(map(type, f3.body.block_items)),
eli.benderskyef29ff92010-10-29 16:25:43 +02001326 [Decl, Decl, Assignment, Return])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001327
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001328 self.assertEqual(expand_decl(f3.param_decls[0]),
1329 ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['long']]]])
1330 self.assertEqual(expand_decl(f3.param_decls[1]),
1331 ['Decl', 'c', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['long']]]]])
1332
Sye van der Veen51a46ec2013-06-10 12:56:15 -04001333 # function return values and parameters may not have type information
1334 f4 = parse_fdef('''
1335 que(p)
1336 {
1337 return 3;
1338 }
1339 ''')
1340
1341 self.assertEqual(fdef_decl(f4),
1342 ['Decl', 'que',
1343 ['FuncDecl',
1344 [['ID', 'p']],
1345 ['TypeDecl', ['IdentifierType', ['int']]]]])
1346
eli.bendersky71540662010-07-03 12:58:52 +02001347 def test_unified_string_literals(self):
1348 # simple string, for reference
1349 d1 = self.get_decl_init('char* s = "hello";')
1350 self.assertEqual(d1, ['Constant', 'string', '"hello"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001351
eli.bendersky71540662010-07-03 12:58:52 +02001352 d2 = self.get_decl_init('char* s = "hello" " world";')
1353 self.assertEqual(d2, ['Constant', 'string', '"hello world"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001354
eli.bendersky71540662010-07-03 12:58:52 +02001355 # the test case from issue 6
1356 d3 = self.parse(r'''
1357 int main() {
1358 fprintf(stderr,
1359 "Wrong Params?\n"
1360 "Usage:\n"
1361 "%s <binary_file_path>\n",
1362 argv[0]
1363 );
1364 }
1365 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001366
eli.bendersky71540662010-07-03 12:58:52 +02001367 self.assertEqual(
eli.benderskyef29ff92010-10-29 16:25:43 +02001368 d3.ext[0].body.block_items[0].args.exprs[1].value,
eli.bendersky71540662010-07-03 12:58:52 +02001369 r'"Wrong Params?\nUsage:\n%s <binary_file_path>\n"')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001370
eli.bendersky4a89f112010-07-05 06:02:03 +02001371 d4 = self.get_decl_init('char* s = "" "foobar";')
1372 self.assertEqual(d4, ['Constant', 'string', '"foobar"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001373
eli.bendersky4a89f112010-07-05 06:02:03 +02001374 d5 = self.get_decl_init(r'char* s = "foo\"" "bar";')
1375 self.assertEqual(d5, ['Constant', 'string', r'"foo\"bar"'])
eli.bendersky71540662010-07-03 12:58:52 +02001376
Eli Benderskyc9f1a382014-03-15 14:12:00 -07001377 def test_unified_wstring_literals(self):
1378 d1 = self.get_decl_init('char* s = L"hello" L"world";')
1379 self.assertEqual(d1, ['Constant', 'string', 'L"helloworld"'])
1380
1381 d2 = self.get_decl_init('char* s = L"hello " L"world" L" and I";')
1382 self.assertEqual(d2, ['Constant', 'string', 'L"hello world and I"'])
1383
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001384 def test_inline_specifier(self):
eli.bendersky79d5cf62010-10-29 13:33:52 +02001385 ps2 = self.parse('static inline void inlinefoo(void);')
1386 self.assertEqual(ps2.ext[0].funcspec, ['inline'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001387
eli.bendersky2e907fa2010-10-29 15:51:07 +02001388 # variable length array
1389 def test_vla(self):
1390 ps2 = self.parse(r'''
1391 int main() {
1392 int size;
1393 int var[size = 5];
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001394
eli.bendersky2e907fa2010-10-29 15:51:07 +02001395 int var2[*];
1396 }
1397 ''')
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001398 self.assertIsInstance(ps2.ext[0].body.block_items[1].type.dim, Assignment)
1399 self.assertIsInstance(ps2.ext[0].body.block_items[2].type.dim, ID)
eli.bendersky79d5cf62010-10-29 13:33:52 +02001400
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001401 def test_pragma(self):
1402 s1 = r'''
1403 #pragma bar
1404 void main() {
1405 #pragma foo
1406 for(;;) {}
Julian Hammer8a174062015-12-14 14:48:16 +01001407 #pragma
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001408 }
ldoreec233182017-11-22 14:52:53 +01001409 struct s {
1410 #pragma baz
1411 } s;
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001412 '''
1413 s1_ast = self.parse(s1)
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001414 self.assertIsInstance(s1_ast.ext[0], Pragma)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001415 self.assertEqual(s1_ast.ext[0].string, 'bar')
Julian Hammer8a174062015-12-14 14:48:16 +01001416 self.assertEqual(s1_ast.ext[0].coord.line, 2)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001417
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001418 self.assertIsInstance(s1_ast.ext[1].body.block_items[0], Pragma)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001419 self.assertEqual(s1_ast.ext[1].body.block_items[0].string, 'foo')
Julian Hammer8a174062015-12-14 14:48:16 +01001420 self.assertEqual(s1_ast.ext[1].body.block_items[0].coord.line, 4)
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001421
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001422 self.assertIsInstance(s1_ast.ext[1].body.block_items[2], Pragma)
Julian Hammer8a174062015-12-14 14:48:16 +01001423 self.assertEqual(s1_ast.ext[1].body.block_items[2].string, '')
1424 self.assertEqual(s1_ast.ext[1].body.block_items[2].coord.line, 6)
Eli Bendersky8ff80882018-07-25 05:36:22 -07001425
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001426 self.assertIsInstance(s1_ast.ext[2].type.type.decls[0], Pragma)
ldoreec233182017-11-22 14:52:53 +01001427 self.assertEqual(s1_ast.ext[2].type.type.decls[0].string, 'baz')
1428 self.assertEqual(s1_ast.ext[2].type.type.decls[0].coord.line, 9)
Julian Hammerdb9f2da2015-10-12 15:52:12 +02001429
dbluhm7af2fb92018-03-03 06:18:26 -07001430 def test_pragmacomp_or_statement(self):
1431 s1 = r'''
1432 void main() {
1433 int sum = 0;
1434 for (int i; i < 3; i++)
1435 #pragma omp critical
1436 sum += 1;
1437
1438 while(sum < 10)
1439 #pragma omp critical
1440 sum += 1;
1441
1442 mylabel:
1443 #pragma foo
1444 sum += 10;
1445
1446 if (sum > 10)
1447 #pragma bar
1448 sum = 10;
1449
1450 switch (sum)
1451 case 10:
1452 #pragma foo
1453 sum = 20;
1454 }
1455 '''
1456 s1_ast = self.parse(s1)
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001457 self.assertIsInstance(s1_ast.ext[0].body.block_items[1], For)
1458 self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt, Compound)
1459 self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt.block_items[0], Pragma)
1460 self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt.block_items[1], Assignment)
1461 self.assertIsInstance(s1_ast.ext[0].body.block_items[2], While)
1462 self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt, Compound)
1463 self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt.block_items[0], Pragma)
1464 self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt.block_items[1], Assignment)
1465 self.assertIsInstance(s1_ast.ext[0].body.block_items[3], Label)
1466 self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt, Compound)
1467 self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt.block_items[0], Pragma)
1468 self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt.block_items[1], Assignment)
1469 self.assertIsInstance(s1_ast.ext[0].body.block_items[4], If)
1470 self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue, Compound)
1471 self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue.block_items[0], Pragma)
1472 self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue.block_items[1], Assignment)
1473 self.assertIsInstance(s1_ast.ext[0].body.block_items[5], Switch)
1474 self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0], Compound)
1475 self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0].block_items[0], Pragma)
1476 self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0].block_items[1], Assignment)
dbluhm7af2fb92018-03-03 06:18:26 -07001477
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001478
eli.bendersky85d2e732011-05-20 19:47:26 +03001479class TestCParser_whole_code(TestCParser_base):
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001480 """ Testing of parsing whole chunks of code.
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001481
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001482 Since I don't want to rely on the structure of ASTs too
1483 much, most of these tests are implemented with visitors.
1484 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001485 # A simple helper visitor that lists the values of all the
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001486 # Constant nodes it sees.
1487 #
1488 class ConstantVisitor(NodeVisitor):
1489 def __init__(self):
1490 self.values = []
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001491
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001492 def visit_Constant(self, node):
1493 self.values.append(node.value)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001494
1495 # This visitor counts the amount of references to the ID
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001496 # with the name provided to it in the constructor.
1497 #
1498 class IDNameCounter(NodeVisitor):
1499 def __init__(self, name):
1500 self.name = name
1501 self.nrefs = 0
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001502
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001503 def visit_ID(self, node):
1504 if node.name == self.name:
1505 self.nrefs += 1
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001506
1507 # Counts the amount of nodes of a given class
1508 #
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001509 class NodeKlassCounter(NodeVisitor):
1510 def __init__(self, node_klass):
1511 self.klass = node_klass
1512 self.n = 0
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001513
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001514 def generic_visit(self, node):
1515 if node.__class__ == self.klass:
1516 self.n += 1
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001517
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001518 NodeVisitor.generic_visit(self, node)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001519
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001520 def assert_all_Constants(self, code, constants):
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001521 """ Asserts that the list of all Constant values (by
1522 'preorder' appearance) in the chunk of code is as
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001523 given.
1524 """
eli.benderskyed890492010-06-25 08:25:55 +03001525 if isinstance(code, str):
1526 parsed = self.parse(code)
1527 else:
1528 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001529
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001530 cv = self.ConstantVisitor()
1531 cv.visit(parsed)
1532 self.assertEqual(cv.values, constants)
1533
1534 def assert_num_ID_refs(self, code, name, num):
1535 """ Asserts the number of references to the ID with
1536 the given name.
1537 """
1538 if isinstance(code, str):
1539 parsed = self.parse(code)
1540 else:
1541 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001542
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001543 iv = self.IDNameCounter(name)
1544 iv.visit(parsed)
1545 self.assertEqual(iv.nrefs, num)
1546
1547 def assert_num_klass_nodes(self, code, klass, num):
1548 """ Asserts the amount of klass nodes in the code.
1549 """
1550 if isinstance(code, str):
1551 parsed = self.parse(code)
1552 else:
1553 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001554
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001555 cv = self.NodeKlassCounter(klass)
1556 cv.visit(parsed)
1557 self.assertEqual(cv.n, num)
1558
1559 def test_expressions(self):
1560 e1 = '''int k = (r + 10.0) >> 6 + 8 << (3 & 0x14);'''
1561 self.assert_all_Constants(e1, ['10.0', '6', '8', '3', '0x14'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001562
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001563 e2 = r'''char n = '\n', *prefix = "st_";'''
1564 self.assert_all_Constants(e2, [r"'\n'", '"st_"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001565
Eli Bendersky09e22a62013-07-02 06:00:36 -07001566 s1 = r'''int main() {
1567 int i = 5, j = 6, k = 1;
1568 if ((i=j && k == 1) || k > j)
1569 printf("Hello, world\n");
1570 return 0;
1571 }'''
1572 ps1 = self.parse(s1)
1573 self.assert_all_Constants(ps1,
1574 ['5', '6', '1', '1', '"Hello, world\\n"', '0'])
1575 self.assert_num_ID_refs(ps1, 'i', 1)
1576 self.assert_num_ID_refs(ps1, 'j', 2)
1577
1578
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001579 def test_statements(self):
1580 s1 = r'''
1581 void foo(){
1582 if (sp == 1)
1583 if (optind >= argc ||
1584 argv[optind][0] != '-' || argv[optind][1] == '\0')
1585 return -1;
1586 else if (strcmp(argv[optind], "--") == 0) {
1587 optind++;
1588 return -1;
1589 }
1590 }
1591 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001592
1593 self.assert_all_Constants(s1,
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001594 ['1', '0', r"'-'", '1', r"'\0'", '1', r'"--"', '0', '1'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001595
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001596 ps1 = self.parse(s1)
1597 self.assert_num_ID_refs(ps1, 'argv', 3)
1598 self.assert_num_ID_refs(ps1, 'optind', 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001599
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001600 self.assert_num_klass_nodes(ps1, If, 3)
1601 self.assert_num_klass_nodes(ps1, Return, 2)
1602 self.assert_num_klass_nodes(ps1, FuncCall, 1) # strcmp
1603 self.assert_num_klass_nodes(ps1, BinaryOp, 7)
1604
1605 # In the following code, Hash and Node were defined as
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001606 # int to pacify the parser that sees they're used as
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001607 # types
1608 #
1609 s2 = r'''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001610 typedef int Hash, Node;
1611
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001612 void HashDestroy(Hash* hash)
1613 {
1614 unsigned int i;
1615
1616 if (hash == NULL)
1617 return;
1618
1619 for (i = 0; i < hash->table_size; ++i)
1620 {
1621 Node* temp = hash->heads[i];
1622
1623 while (temp != NULL)
1624 {
1625 Node* temp2 = temp;
1626
1627 free(temp->entry->key);
1628 free(temp->entry->value);
1629 free(temp->entry);
1630
1631 temp = temp->next;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001632
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001633 free(temp2);
1634 }
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001635 }
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001636
1637 free(hash->heads);
1638 hash->heads = NULL;
1639
1640 free(hash);
1641 }
1642 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001643
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001644 ps2 = self.parse(s2)
1645 self.assert_num_klass_nodes(ps2, FuncCall, 6)
1646 self.assert_num_klass_nodes(ps2, FuncDef, 1)
1647 self.assert_num_klass_nodes(ps2, For, 1)
1648 self.assert_num_klass_nodes(ps2, While, 1)
1649 self.assert_num_klass_nodes(ps2, StructRef, 10)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001650
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001651 # declarations don't count
1652 self.assert_num_ID_refs(ps2, 'hash', 6)
1653 self.assert_num_ID_refs(ps2, 'i', 4)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001654
eli.benderskyed890492010-06-25 08:25:55 +03001655 s3 = r'''
1656 void x(void) {
1657 int a, b;
1658 if (a < b)
1659 do {
1660 a = 0;
1661 } while (0);
1662 else if (a == b) {
1663 a = 1;
1664 }
1665 }
1666 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001667
eli.benderskyed890492010-06-25 08:25:55 +03001668 ps3 = self.parse(s3)
1669 self.assert_num_klass_nodes(ps3, DoWhile, 1)
1670 self.assert_num_ID_refs(ps3, 'a', 4)
1671 self.assert_all_Constants(ps3, ['0', '0', '1'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001672
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001673 def test_empty_statements(self):
eli.bendersky91c0aa32011-10-16 05:50:43 +02001674 s1 = r'''
1675 void foo(void){
1676 ;
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001677 return;;
1678
1679 ;
eli.bendersky91c0aa32011-10-16 05:50:43 +02001680 }
1681 '''
1682 ps1 = self.parse(s1)
Eli Benderskyb77d6c02016-10-11 20:33:53 -07001683 self.assert_num_klass_nodes(ps1, EmptyStatement, 3)
eli.bendersky91c0aa32011-10-16 05:50:43 +02001684 self.assert_num_klass_nodes(ps1, Return, 1)
serpilliere471442f2017-03-10 15:02:00 +01001685 self.assert_coord(ps1.ext[0].body.block_items[0], 3)
1686 self.assert_coord(ps1.ext[0].body.block_items[1], 4)
1687 self.assert_coord(ps1.ext[0].body.block_items[2], 4)
1688 self.assert_coord(ps1.ext[0].body.block_items[3], 6)
eli.bendersky145890d2010-10-29 12:02:32 +02001689
Ben5cd3fd62012-02-03 06:02:40 +02001690 def test_switch_statement(self):
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001691 def assert_case_node(node, const_value):
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001692 self.assertIsInstance(node, Case)
1693 self.assertIsInstance(node.expr, Constant)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001694 self.assertEqual(node.expr.value, const_value)
1695
1696 def assert_default_node(node):
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001697 self.assertIsInstance(node, Default)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001698
Ben5cd3fd62012-02-03 06:02:40 +02001699 s1 = r'''
1700 int foo(void) {
1701 switch (myvar) {
1702 case 10:
1703 k = 10;
1704 p = k + 1;
1705 return 10;
1706 case 20:
1707 case 30:
1708 return 20;
1709 default:
1710 break;
1711 }
1712 return 0;
1713 }
1714 '''
1715 ps1 = self.parse(s1)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001716 switch = ps1.ext[0].body.block_items[0]
1717
1718 block = switch.stmt.block_items
1719 assert_case_node(block[0], '10')
1720 self.assertEqual(len(block[0].stmts), 3)
1721 assert_case_node(block[1], '20')
1722 self.assertEqual(len(block[1].stmts), 0)
1723 assert_case_node(block[2], '30')
1724 self.assertEqual(len(block[2].stmts), 1)
1725 assert_default_node(block[3])
1726
1727 s2 = r'''
1728 int foo(void) {
1729 switch (myvar) {
1730 default:
1731 joe = moe;
1732 return 10;
1733 case 10:
1734 case 20:
1735 case 30:
1736 case 40:
1737 break;
1738 }
1739 return 0;
1740 }
1741 '''
1742 ps2 = self.parse(s2)
1743 switch = ps2.ext[0].body.block_items[0]
1744
1745 block = switch.stmt.block_items
1746 assert_default_node(block[0])
1747 self.assertEqual(len(block[0].stmts), 2)
1748 assert_case_node(block[1], '10')
1749 self.assertEqual(len(block[1].stmts), 0)
1750 assert_case_node(block[2], '20')
1751 self.assertEqual(len(block[1].stmts), 0)
1752 assert_case_node(block[3], '30')
1753 self.assertEqual(len(block[1].stmts), 0)
1754 assert_case_node(block[4], '40')
1755 self.assertEqual(len(block[4].stmts), 1)
Ben5cd3fd62012-02-03 06:02:40 +02001756
eli.bendersky145890d2010-10-29 12:02:32 +02001757 def test_for_statement(self):
1758 s2 = r'''
1759 void x(void)
1760 {
1761 int i;
1762 for (i = 0; i < 5; ++i) {
1763 x = 50;
1764 }
1765 }
1766 '''
1767 ps2 = self.parse(s2)
1768 self.assert_num_klass_nodes(ps2, For, 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001769 # here there are 3 refs to 'i' since the declaration doesn't count as
eli.bendersky145890d2010-10-29 12:02:32 +02001770 # a ref in the visitor
1771 #
1772 self.assert_num_ID_refs(ps2, 'i', 3)
Eli Bendersky4476d092012-12-25 14:07:57 -08001773
eli.bendersky145890d2010-10-29 12:02:32 +02001774 s3 = r'''
1775 void x(void)
1776 {
1777 for (int i = 0; i < 5; ++i) {
1778 x = 50;
1779 }
1780 }
1781 '''
1782 ps3 = self.parse(s3)
eli.bendersky145890d2010-10-29 12:02:32 +02001783 self.assert_num_klass_nodes(ps3, For, 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001784 # here there are 2 refs to 'i' since the declaration doesn't count as
eli.bendersky145890d2010-10-29 12:02:32 +02001785 # a ref in the visitor
1786 #
1787 self.assert_num_ID_refs(ps3, 'i', 2)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001788
Eli Bendersky4476d092012-12-25 14:07:57 -08001789 s4 = r'''
1790 void x(void) {
1791 for (int i = 0;;)
1792 i;
1793 }
1794 '''
1795 ps4 = self.parse(s4)
1796 self.assert_num_ID_refs(ps4, 'i', 1)
1797
Eli Benderskyd0973782012-01-19 08:09:33 +02001798 def _open_c_file(self, name):
1799 """ Find a c file by name, taking into account the current dir can be
1800 in a couple of typical places
1801 """
Stefano Riveraebaf5922013-08-08 09:45:26 +02001802 testdir = os.path.dirname(__file__)
1803 name = os.path.join(testdir, 'c_files', name)
1804 assert os.path.exists(name)
Jon Dufresne13224c12018-06-26 13:48:31 -07001805 return io.open(name)
Eli Benderskyd0973782012-01-19 08:09:33 +02001806
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001807 def test_whole_file(self):
1808 # See how pycparser handles a whole, real C file.
1809 #
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001810 with self._open_c_file('memmgr_with_h.c') as f:
1811 code = f.read()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001812 p = self.parse(code)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001813
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001814 self.assert_num_klass_nodes(p, FuncDef, 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001815
1816 # each FuncDef also has a FuncDecl. 4 declarations
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001817 # + 5 definitions, overall 9
1818 self.assert_num_klass_nodes(p, FuncDecl, 9)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001819
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001820 self.assert_num_klass_nodes(p, Typedef, 4)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001821
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001822 self.assertEqual(p.ext[4].coord.line, 88)
1823 self.assertEqual(p.ext[4].coord.file, "./memmgr.h")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001824
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001825 self.assertEqual(p.ext[6].coord.line, 10)
1826 self.assertEqual(p.ext[6].coord.file, "memmgr.c")
1827
1828 def test_whole_file_with_stdio(self):
1829 # Parse a whole file with stdio.h included by cpp
1830 #
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001831 with self._open_c_file('cppd_with_stdio_h.c') as f:
1832 code = f.read()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001833 p = self.parse(code)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001834
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001835 self.assertIsInstance(p.ext[0], Typedef)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001836 self.assertEqual(p.ext[0].coord.line, 213)
Ville Skyttä2129f5f2017-03-05 04:52:22 +02001837 self.assertEqual(p.ext[0].coord.file, r"D:\eli\cpp_stuff\libc_include/stddef.h")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001838
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001839 self.assertIsInstance(p.ext[-1], FuncDef)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001840 self.assertEqual(p.ext[-1].coord.line, 15)
1841 self.assertEqual(p.ext[-1].coord.file, "example_c_file.c")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001842
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001843 self.assertIsInstance(p.ext[-8], Typedef)
1844 self.assertIsInstance(p.ext[-8].type, TypeDecl)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001845 self.assertEqual(p.ext[-8].name, 'cookie_io_functions_t')
eli.bendersky85d2e732011-05-20 19:47:26 +03001846
1847
1848class TestCParser_typenames(TestCParser_base):
1849 """ Test issues related to the typedef-name problem.
1850 """
1851 def test_innerscope_typedef(self):
1852 # should fail since TT is not a type in bar
1853 s1 = r'''
1854 void foo() {
1855 typedef char TT;
1856 TT x;
1857 }
1858 void bar() {
1859 TT y;
1860 }
1861 '''
1862 self.assertRaises(ParseError, self.parse, s1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001863
eli.bendersky85d2e732011-05-20 19:47:26 +03001864 # should succeed since TT is not a type in bar
1865 s2 = r'''
1866 void foo() {
1867 typedef char TT;
1868 TT x;
1869 }
1870 void bar() {
1871 unsigned TT;
1872 }
1873 '''
Jon Dufresnee8afcc92018-06-26 13:49:06 -07001874 self.assertIsInstance(self.parse(s2), FileAST)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001875
Nate Bogdanowicz14b8a7e2017-02-22 08:54:05 -05001876 def test_ambiguous_parameters(self):
1877 # From ISO/IEC 9899:TC2, 6.7.5.3.11:
1878 # "If, in a parameter declaration, an identifier can be treated either
1879 # as a typedef name or as a parameter name, it shall be taken as a
1880 # typedef name."
1881
1882 # foo takes an int named aa
1883 # bar takes a function taking a TT
1884 s1 = r'''
1885 typedef char TT;
1886 int foo(int (aa));
1887 int bar(int (TT));
1888 '''
1889 s1_ast = self.parse(s1)
1890 self.assertEqual(expand_decl(s1_ast.ext[1].type.args.params[0]),
1891 ['Decl', 'aa', ['TypeDecl', ['IdentifierType', ['int']]]])
1892 self.assertEqual(expand_decl(s1_ast.ext[2].type.args.params[0]),
1893 ['Typename', ['FuncDecl',
1894 [['Typename', ['TypeDecl', ['IdentifierType', ['TT']]]]],
1895 ['TypeDecl', ['IdentifierType', ['int']]]]])
1896
1897 # foo takes a function taking a char
1898 # bar takes a function taking a function taking a char
1899 s2 = r'''
1900 typedef char TT;
1901 int foo(int (aa (char)));
1902 int bar(int (TT (char)));
1903 '''
1904 s2_ast = self.parse(s2)
1905 self.assertEqual(expand_decl(s2_ast.ext[1].type.args.params[0]),
1906 ['Decl', 'aa', ['FuncDecl',
1907 [['Typename', ['TypeDecl', ['IdentifierType', ['char']]]]],
1908 ['TypeDecl', ['IdentifierType', ['int']]]]])
1909 self.assertEqual(expand_decl(s2_ast.ext[2].type.args.params[0]),
1910 ['Typename', ['FuncDecl',
1911 [['Typename', ['FuncDecl',
1912 [['Typename', ['TypeDecl', ['IdentifierType', ['char']]]]],
1913 ['TypeDecl', ['IdentifierType', ['TT']]]]]],
1914 ['TypeDecl', ['IdentifierType', ['int']]]]])
1915
1916
1917 # foo takes an int array named aa
1918 # bar takes a function taking a TT array
1919 s3 = r'''
1920 typedef char TT;
1921 int foo(int (aa[]));
1922 int bar(int (TT[]));
1923 '''
1924 s3_ast = self.parse(s3)
1925 self.assertEqual(expand_decl(s3_ast.ext[1].type.args.params[0]),
1926 ['Decl', 'aa', ['ArrayDecl', '', [], ['TypeDecl', ['IdentifierType', ['int']]]]])
1927 self.assertEqual(expand_decl(s3_ast.ext[2].type.args.params[0]),
1928 ['Typename', ['FuncDecl',
1929 [['Typename', ['ArrayDecl', '', [], ['TypeDecl', ['IdentifierType', ['TT']]]]]],
1930 ['TypeDecl', ['IdentifierType', ['int']]]]])
1931
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001932 def test_innerscope_reuse_typedef_name(self):
1933 # identifiers can be reused in inner scopes; the original should be
1934 # restored at the end of the block
1935 s1 = r'''
1936 typedef char TT;
1937 void foo(void) {
1938 unsigned TT;
1939 TT = 10;
1940 }
1941 TT x = 5;
1942 '''
1943 s1_ast = self.parse(s1)
1944 self.assertEqual(expand_decl(s1_ast.ext[1].body.block_items[0]),
1945 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
Eli Bendersky3877c4c2013-07-13 06:54:04 -07001946 self.assertEqual(expand_decl(s1_ast.ext[2]),
1947 ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['TT']]]])
eli.bendersky85d2e732011-05-20 19:47:26 +03001948
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001949 # this should be recognized even with an initializer
1950 s2 = r'''
1951 typedef char TT;
1952 void foo(void) {
1953 unsigned TT = 10;
1954 }
1955 '''
1956 s2_ast = self.parse(s2)
1957 self.assertEqual(expand_decl(s2_ast.ext[1].body.block_items[0]),
1958 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1959
1960 # before the second local variable, TT is a type; after, it's a
1961 # variable
1962 s3 = r'''
1963 typedef char TT;
1964 void foo(void) {
1965 TT tt = sizeof(TT);
1966 unsigned TT = 10;
1967 }
1968 '''
1969 s3_ast = self.parse(s3)
1970 self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[0]),
1971 ['Decl', 'tt', ['TypeDecl', ['IdentifierType', ['TT']]]])
1972 self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[1]),
1973 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1974
1975 # a variable and its type can even share the same name
1976 s4 = r'''
1977 typedef char TT;
1978 void foo(void) {
1979 TT TT = sizeof(TT);
1980 unsigned uu = TT * 2;
1981 }
1982 '''
1983 s4_ast = self.parse(s4)
1984 self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[0]),
1985 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['TT']]]])
1986 self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[1]),
1987 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1988
1989 # ensure an error is raised if a type, redeclared as a variable, is
1990 # used as a type
1991 s5 = r'''
1992 typedef char TT;
1993 void foo(void) {
1994 unsigned TT = 10;
1995 TT erroneous = 20;
1996 }
1997 '''
1998 self.assertRaises(ParseError, self.parse, s5)
1999
Nate Bogdanowicz14b8a7e2017-02-22 08:54:05 -05002000 # reusing a type name should work with multiple declarators
2001 s6 = r'''
2002 typedef char TT;
2003 void foo(void) {
2004 unsigned TT, uu;
2005 }
2006 '''
2007 s6_ast = self.parse(s6)
2008 items = s6_ast.ext[1].body.block_items
2009 self.assertEqual(expand_decl(items[0]),
2010 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
2011 self.assertEqual(expand_decl(items[1]),
2012 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
2013
2014 # reusing a type name should work after a pointer
2015 s7 = r'''
2016 typedef char TT;
2017 void foo(void) {
2018 unsigned * TT;
2019 }
2020 '''
2021 s7_ast = self.parse(s7)
2022 items = s7_ast.ext[1].body.block_items
2023 self.assertEqual(expand_decl(items[0]),
2024 ['Decl', 'TT', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['unsigned']]]]])
2025
2026 # redefine a name in the middle of a multi-declarator declaration
2027 s8 = r'''
2028 typedef char TT;
2029 void foo(void) {
2030 int tt = sizeof(TT), TT, uu = sizeof(TT);
2031 int uu = sizeof(tt);
2032 }
2033 '''
2034 s8_ast = self.parse(s8)
2035 items = s8_ast.ext[1].body.block_items
2036 self.assertEqual(expand_decl(items[0]),
2037 ['Decl', 'tt', ['TypeDecl', ['IdentifierType', ['int']]]])
2038 self.assertEqual(expand_decl(items[1]),
2039 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['int']]]])
2040 self.assertEqual(expand_decl(items[2]),
2041 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['int']]]])
2042
2043 # Don't test this until we have support for it
2044 # self.assertEqual(expand_init(items[0].init),
2045 # ['UnaryOp', 'sizeof', ['Typename', ['TypeDecl', ['IdentifierType', ['TT']]]]])
2046 # self.assertEqual(expand_init(items[2].init),
2047 # ['UnaryOp', 'sizeof', ['ID', 'TT']])
2048
Sye van der Veen9ec6c422013-07-11 09:10:38 -04002049 def test_parameter_reuse_typedef_name(self):
2050 # identifiers can be reused as parameter names; parameter name scope
2051 # begins and ends with the function body; it's important that TT is
Eli Bendersky4d969b32013-07-13 06:07:07 -07002052 # used immediately before the LBRACE or after the RBRACE, to test
2053 # a corner case
Sye van der Veen9ec6c422013-07-11 09:10:38 -04002054 s1 = r'''
2055 typedef char TT;
2056 void foo(unsigned TT, TT bar) {
2057 TT = 10;
2058 }
2059 TT x = 5;
2060 '''
2061 s1_ast = self.parse(s1)
2062 self.assertEqual(expand_decl(s1_ast.ext[1].decl),
2063 ['Decl', 'foo',
2064 ['FuncDecl',
2065 [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
2066 ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
2067 ['TypeDecl', ['IdentifierType', ['void']]]]])
2068
2069 # the scope of a parameter name in a function declaration ends at the
2070 # end of the declaration...so it is effectively never used; it's
2071 # important that TT is used immediately after the declaration, to
2072 # test a corner case
2073 s2 = r'''
2074 typedef char TT;
2075 void foo(unsigned TT, TT bar);
2076 TT x = 5;
2077 '''
2078 s2_ast = self.parse(s2)
2079 self.assertEqual(expand_decl(s2_ast.ext[1]),
2080 ['Decl', 'foo',
2081 ['FuncDecl',
2082 [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
2083 ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
2084 ['TypeDecl', ['IdentifierType', ['void']]]]])
2085
2086 # ensure an error is raised if a type, redeclared as a parameter, is
2087 # used as a type
2088 s3 = r'''
2089 typedef char TT;
2090 void foo(unsigned TT, TT bar) {
2091 TT erroneous = 20;
2092 }
2093 '''
2094 self.assertRaises(ParseError, self.parse, s3)
2095
2096 def test_nested_function_decls(self):
2097 # parameter names of nested function declarations must not escape into
2098 # the top-level function _definition's_ scope; the following must
2099 # succeed because TT is still a typedef inside foo's body
2100 s1 = r'''
2101 typedef char TT;
2102 void foo(unsigned bar(int TT)) {
2103 TT x = 10;
2104 }
2105 '''
Jon Dufresnee8afcc92018-06-26 13:49:06 -07002106 self.assertIsInstance(self.parse(s1), FileAST)
Sye van der Veen9ec6c422013-07-11 09:10:38 -04002107
2108 def test_samescope_reuse_name(self):
2109 # a typedef name cannot be reused as an object name in the same scope
2110 s1 = r'''
2111 typedef char TT;
2112 char TT = 5;
2113 '''
2114 self.assertRaises(ParseError, self.parse, s1)
2115
2116 # ...and vice-versa
2117 s2 = r'''
2118 char TT = 5;
2119 typedef char TT;
2120 '''
2121 self.assertRaises(ParseError, self.parse, s2)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03002122
Julian Hammerdb9f2da2015-10-12 15:52:12 +02002123
Eli Bendersky3921e8e2010-05-21 09:05:39 +03002124if __name__ == '__main__':
2125 #~ suite = unittest.TestLoader().loadTestsFromNames(
2126 #~ ['test_c_parser.TestCParser_fundamentals.test_typedef'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08002127
Eli Bendersky3921e8e2010-05-21 09:05:39 +03002128 #~ unittest.TextTestRunner(verbosity=2).run(suite)
2129 unittest.main()