blob: d617ddd230badc67441fb3ac82dea012fcf9023c [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
Eli Bendersky3921e8e2010-05-21 09:05:39 +03006import unittest
7
Eli Bendersky3877c4c2013-07-13 06:54:04 -07008sys.path[0:0] = ['.', '..']
Eli Bendersky3921e8e2010-05-21 09:05:39 +03009
10from pycparser import c_parser
11from pycparser.c_ast import *
12from pycparser.c_parser import CParser, Coord, ParseError
13
Eli Bendersky3921e8e2010-05-21 09:05:39 +030014_c_parser = c_parser.CParser(
15 lex_optimize=False,
Eli Bendersky86f2eee2013-01-18 06:04:01 -080016 yacc_debug=True,
Eli Bendersky3921e8e2010-05-21 09:05:39 +030017 yacc_optimize=False,
18 yacctab='yacctab')
19
20
21def expand_decl(decl):
22 """ Converts the declaration into a nested list.
23 """
24 typ = type(decl)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080025
Eli Bendersky3921e8e2010-05-21 09:05:39 +030026 if typ == TypeDecl:
27 return ['TypeDecl', expand_decl(decl.type)]
28 elif typ == IdentifierType:
29 return ['IdentifierType', decl.names]
30 elif typ == ID:
31 return ['ID', decl.name]
32 elif typ in [Struct, Union]:
33 decls = [expand_decl(d) for d in decl.decls or []]
34 return [typ.__name__, decl.name, decls]
Eli Bendersky86f2eee2013-01-18 06:04:01 -080035 else:
Eli Bendersky3921e8e2010-05-21 09:05:39 +030036 nested = expand_decl(decl.type)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080037
Eli Bendersky3921e8e2010-05-21 09:05:39 +030038 if typ == Decl:
39 if decl.quals:
40 return ['Decl', decl.quals, decl.name, nested]
41 else:
42 return ['Decl', decl.name, nested]
43 elif typ == Typename: # for function parameters
44 if decl.quals:
45 return ['Typename', decl.quals, nested]
46 else:
47 return ['Typename', nested]
48 elif typ == ArrayDecl:
49 dimval = decl.dim.value if decl.dim else ''
Eli Bendersky8aad3182014-01-25 06:30:53 -080050 return ['ArrayDecl', dimval, decl.dim_quals, nested]
Eli Bendersky3921e8e2010-05-21 09:05:39 +030051 elif typ == PtrDecl:
52 return ['PtrDecl', nested]
53 elif typ == Typedef:
54 return ['Typedef', decl.name, nested]
55 elif typ == FuncDecl:
56 if decl.args:
57 params = [expand_decl(param) for param in decl.args.params]
58 else:
59 params = []
60 return ['FuncDecl', params, nested]
Eli Bendersky86f2eee2013-01-18 06:04:01 -080061
Eli Bendersky3921e8e2010-05-21 09:05:39 +030062
63def expand_init(init):
64 """ Converts an initialization into a nested list
65 """
66 typ = type(init)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080067
eli.benderskyf890a862010-10-30 12:13:23 +020068 if typ == NamedInitializer:
69 des = [expand_init(dp) for dp in init.name]
70 return (des, expand_init(init.expr))
Eli Bendersky293ea912012-12-25 14:52:48 -080071 elif typ in (InitList, ExprList):
eli.benderskyf890a862010-10-30 12:13:23 +020072 return [expand_init(expr) for expr in init.exprs]
73 elif typ == Constant:
Eli Bendersky3921e8e2010-05-21 09:05:39 +030074 return ['Constant', init.type, init.value]
75 elif typ == ID:
76 return ['ID', init.name]
Eli Bendersky3921e8e2010-05-21 09:05:39 +030077
78
eli.bendersky85d2e732011-05-20 19:47:26 +030079class TestCParser_base(unittest.TestCase):
Eli Bendersky3921e8e2010-05-21 09:05:39 +030080 def parse(self, txt, filename=''):
81 return self.cparser.parse(txt, filename)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080082
Eli Bendersky3921e8e2010-05-21 09:05:39 +030083 def setUp(self):
84 self.cparser = _c_parser
Eli Bendersky86f2eee2013-01-18 06:04:01 -080085
eli.bendersky85d2e732011-05-20 19:47:26 +030086
87class TestCParser_fundamentals(TestCParser_base):
Eli Bendersky3921e8e2010-05-21 09:05:39 +030088 def get_decl(self, txt, index=0):
89 """ Given a source and an index returns the expanded
90 declaration at that index.
Eli Bendersky86f2eee2013-01-18 06:04:01 -080091
92 FileAST holds a list of 'external declarations'.
Eli Bendersky3921e8e2010-05-21 09:05:39 +030093 index is the offset of the desired declaration in that
94 list.
95 """
96 t = self.parse(txt).ext[index]
97 return expand_decl(t)
Eli Bendersky86f2eee2013-01-18 06:04:01 -080098
Eli Bendersky3921e8e2010-05-21 09:05:39 +030099 def get_decl_init(self, txt, index=0):
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800100 """ Returns the expanded initializer of the declaration
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300101 at index.
102 """
103 t = self.parse(txt).ext[index]
104 return expand_init(t.init)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800105
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300106 def test_FileAST(self):
107 t = self.parse('int a; char c;')
Eli Benderskya1da7fd2012-07-06 15:48:57 +0300108 self.assertTrue(isinstance(t, FileAST))
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300109 self.assertEqual(len(t.ext), 2)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800110
eli.bendersky43cf0b22011-10-19 05:56:15 +0200111 # empty file
112 t2 = self.parse('')
Eli Benderskya1da7fd2012-07-06 15:48:57 +0300113 self.assertTrue(isinstance(t2, FileAST))
eli.bendersky43cf0b22011-10-19 05:56:15 +0200114 self.assertEqual(len(t2.ext), 0)
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300115
eli.bendersky38165b72011-02-04 08:13:39 +0200116 def test_empty_toplevel_decl(self):
117 code = 'int foo;;'
118 t = self.parse(code)
Eli Benderskya1da7fd2012-07-06 15:48:57 +0300119 self.assertTrue(isinstance(t, FileAST))
eli.bendersky38165b72011-02-04 08:13:39 +0200120 self.assertEqual(len(t.ext), 1)
121 self.assertEqual(self.get_decl(code),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800122 ['Decl', 'foo',
eli.bendersky38165b72011-02-04 08:13:39 +0200123 ['TypeDecl', ['IdentifierType', ['int']]]])
124
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300125 def assert_coord(self, node, line, file=None):
126 self.assertEqual(node.coord.line, line)
127 if file:
128 self.assertEqual(node.coord.file, file)
129
130 def test_coords(self):
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800131 """ Tests the "coordinates" of parsed elements - file
eli.bendersky38165b72011-02-04 08:13:39 +0200132 name and line numbers, with modification insterted by
133 #line directives.
134 """
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300135 self.assert_coord(self.parse('int a;').ext[0], 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800136
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300137 t1 = """
138 int a;
139 int b;\n\n
140 int c;
141 """
142 f1 = self.parse(t1, filename='test.c')
143 self.assert_coord(f1.ext[0], 2, 'test.c')
144 self.assert_coord(f1.ext[1], 3, 'test.c')
145 self.assert_coord(f1.ext[2], 6, 'test.c')
146
147 t1_1 = '''
148 int main() {
149 k = p;
150 printf("%d", b);
151 return 0;
152 }'''
153 f1_1 = self.parse(t1_1, filename='test.c')
eli.benderskyef29ff92010-10-29 16:25:43 +0200154 self.assert_coord(f1_1.ext[0].body.block_items[0], 3, 'test.c')
155 self.assert_coord(f1_1.ext[0].body.block_items[1], 4, 'test.c')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800156
eli.benderskyfc96e5e2011-03-04 09:51:23 +0200157 t1_2 = '''
158 int main () {
159 int p = (int) k;
160 }'''
161 f1_2 = self.parse(t1_2, filename='test.c')
162 # make sure that the Cast has a coord (issue 23)
163 self.assert_coord(f1_2.ext[0].body.block_items[0].init, 3, 'test.c')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800164
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300165 t2 = """
166 #line 99
167 int c;
168 """
169 self.assert_coord(self.parse(t2).ext[0], 99)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800170
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300171 t3 = """
172 int dsf;
173 char p;
174 #line 3000 "in.h"
175 char d;
176 """
177 f3 = self.parse(t3, filename='test.c')
178 self.assert_coord(f3.ext[0], 2, 'test.c')
179 self.assert_coord(f3.ext[1], 3, 'test.c')
180 self.assert_coord(f3.ext[2], 3000, 'in.h')
181
182 t4 = """
183 #line 20 "restore.h"
184 int maydler(char);
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800185
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300186 #line 30 "includes/daween.ph"
187 long j, k;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800188
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300189 #line 50000
190 char* ro;
191 """
192 f4 = self.parse(t4, filename='myb.c')
193 self.assert_coord(f4.ext[0], 20, 'restore.h')
194 self.assert_coord(f4.ext[1], 30, 'includes/daween.ph')
195 self.assert_coord(f4.ext[2], 30, 'includes/daween.ph')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800196 self.assert_coord(f4.ext[3], 50000, 'includes/daween.ph')
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300197
198 t5 = """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800199 int
200 #line 99
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300201 c;
202 """
203 self.assert_coord(self.parse(t5).ext[0], 99)
204
Eli Bendersky203b9672012-06-15 10:11:24 +0300205 # coord for ellipsis
206 t6 = """
207 int foo(int j,
208 ...) {
209 }"""
210 f6 = self.parse(t6, filename='z.c')
211 self.assert_coord(self.parse(t6).ext[0].decl.type.args.params[1], 3)
212
Eli Bendersky8e5d3a92014-03-15 14:06:00 -0700213 def test_forloop_coord(self):
214 t = '''\
215 void foo() {
216 for(int z=0; z<4;
217 z++){}
218 }
219 '''
220 s = self.parse(t, filename='f.c')
221 forloop = s.ext[0].body.block_items[0]
222 self.assert_coord(forloop.init, 2, 'f.c')
223 self.assert_coord(forloop.cond, 2, 'f.c')
224 self.assert_coord(forloop.next, 3, 'f.c')
225
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300226 def test_simple_decls(self):
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800227 self.assertEqual(self.get_decl('int a;'),
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300228 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
229
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800230 self.assertEqual(self.get_decl('unsigned int a;'),
Eli Bendersky68497c22012-01-19 06:04:58 +0200231 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['unsigned', 'int']]]])
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300232
eli.benderskyaffe0322011-09-24 06:16:55 +0300233 self.assertEqual(self.get_decl('_Bool a;'),
234 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['_Bool']]]])
235
Eli Benderskyf4d73462012-01-19 05:56:27 +0200236 self.assertEqual(self.get_decl('float _Complex fcc;'),
Eli Bendersky68497c22012-01-19 06:04:58 +0200237 ['Decl', 'fcc', ['TypeDecl', ['IdentifierType', ['float', '_Complex']]]])
Eli Benderskyf4d73462012-01-19 05:56:27 +0200238
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800239 self.assertEqual(self.get_decl('char* string;'),
240 ['Decl', 'string',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300241 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]])
242
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800243 self.assertEqual(self.get_decl('long ar[15];'),
244 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800245 ['ArrayDecl', '15', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300246 ['TypeDecl', ['IdentifierType', ['long']]]]])
eli.bendersky98f45372010-10-30 09:46:29 +0200247
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800248 self.assertEqual(self.get_decl('long long ar[15];'),
249 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800250 ['ArrayDecl', '15', [],
eli.benderskyf890a862010-10-30 12:13:23 +0200251 ['TypeDecl', ['IdentifierType', ['long', 'long']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800252
253 self.assertEqual(self.get_decl('unsigned ar[];'),
254 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800255 ['ArrayDecl', '', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300256 ['TypeDecl', ['IdentifierType', ['unsigned']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800257
258 self.assertEqual(self.get_decl('int strlen(char* s);'),
259 ['Decl', 'strlen',
260 ['FuncDecl',
261 [['Decl', 's',
262 ['PtrDecl',
263 ['TypeDecl', ['IdentifierType', ['char']]]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300264 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800265
266 self.assertEqual(self.get_decl('int strcmp(char* s1, char* s2);'),
267 ['Decl', 'strcmp',
268 ['FuncDecl',
269 [ ['Decl', 's1',
270 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
271 ['Decl', 's2',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300272 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800273 ],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300274 ['TypeDecl', ['IdentifierType', ['int']]]]])
275
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400276 # function return values and parameters may not have type information
Eli Bendersky09e22a62013-07-02 06:00:36 -0700277 self.assertEqual(self.get_decl('extern foobar(foo, bar);'),
278 ['Decl', 'foobar',
279 ['FuncDecl',
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400280 [ ['ID', 'foo'],
281 ['ID', 'bar']
Eli Bendersky09e22a62013-07-02 06:00:36 -0700282 ],
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400283 ['TypeDecl', ['IdentifierType', ['int']]]]])
284
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300285 def test_nested_decls(self): # the fun begins
286 self.assertEqual(self.get_decl('char** ar2D;'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800287 ['Decl', 'ar2D',
288 ['PtrDecl', ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300289 ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800290
291 self.assertEqual(self.get_decl('int (*a)[1][2];'),
292 ['Decl', 'a',
293 ['PtrDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800294 ['ArrayDecl', '1', [],
295 ['ArrayDecl', '2', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300296 ['TypeDecl', ['IdentifierType', ['int']]]]]]])
297
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800298 self.assertEqual(self.get_decl('int *a[1][2];'),
299 ['Decl', 'a',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800300 ['ArrayDecl', '1', [],
301 ['ArrayDecl', '2', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300302 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['int']]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800303
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300304 self.assertEqual(self.get_decl('char ***ar3D[40];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800305 ['Decl', 'ar3D',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800306 ['ArrayDecl', '40', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800307 ['PtrDecl', ['PtrDecl', ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300308 ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800309
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300310 self.assertEqual(self.get_decl('char (***ar3D)[40];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800311 ['Decl', 'ar3D',
312 ['PtrDecl', ['PtrDecl', ['PtrDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800313 ['ArrayDecl', '40', [], ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800314
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300315 self.assertEqual(self.get_decl('int (*x[4])(char, int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800316 ['Decl', 'x',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800317 ['ArrayDecl', '4', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800318 ['PtrDecl',
319 ['FuncDecl',
320 [ ['Typename', ['TypeDecl', ['IdentifierType', ['char']]]],
321 ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300322 ['TypeDecl', ['IdentifierType', ['int']]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800323
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300324 self.assertEqual(self.get_decl('char *(*(**foo [][8])())[];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800325 ['Decl', 'foo',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800326 ['ArrayDecl', '', [],
327 ['ArrayDecl', '8', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800328 ['PtrDecl', ['PtrDecl',
329 ['FuncDecl',
330 [],
331 ['PtrDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800332 ['ArrayDecl', '', [],
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800333 ['PtrDecl',
334 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300335 ['IdentifierType', ['char']]]]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800336
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300337 # explore named and unnamed function pointer parameters,
338 # with and without qualifiers
339 #
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800340
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300341 # unnamed w/o quals
342 self.assertEqual(self.get_decl('int (*k)(int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800343 ['Decl', 'k',
344 ['PtrDecl',
345 ['FuncDecl',
346 [['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300347 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800348
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300349 # unnamed w/ quals
350 self.assertEqual(self.get_decl('int (*k)(const int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800351 ['Decl', 'k',
352 ['PtrDecl',
353 ['FuncDecl',
354 [['Typename', ['const'], ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300355 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800356
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300357 # named w/o quals
358 self.assertEqual(self.get_decl('int (*k)(int q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800359 ['Decl', 'k',
360 ['PtrDecl',
361 ['FuncDecl',
362 [['Decl', 'q', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300363 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800364
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300365 # named w/ quals
366 self.assertEqual(self.get_decl('int (*k)(const volatile int q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800367 ['Decl', 'k',
368 ['PtrDecl',
369 ['FuncDecl',
370 [['Decl', ['const', 'volatile'], 'q',
371 ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300372 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800373
eli.bendersky79d5cf62010-10-29 13:33:52 +0200374 # restrict qualifier
375 self.assertEqual(self.get_decl('int (*k)(restrict int* q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800376 ['Decl', 'k',
377 ['PtrDecl',
378 ['FuncDecl',
379 [['Decl', ['restrict'], 'q',
eli.bendersky79d5cf62010-10-29 13:33:52 +0200380 ['PtrDecl',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800381 ['TypeDecl', ['IdentifierType', ['int']]]]]],
eli.bendersky79d5cf62010-10-29 13:33:52 +0200382 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800383
Eli Benderskye7c55cf2014-01-25 06:15:43 -0800384 def test_func_decls_with_array_dim_qualifiers(self):
385 self.assertEqual(self.get_decl('int zz(int p[static 10]);'),
386 ['Decl', 'zz',
387 ['FuncDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800388 [['Decl', 'p', ['ArrayDecl', '10', ['static'],
Eli Benderskye7c55cf2014-01-25 06:15:43 -0800389 ['TypeDecl', ['IdentifierType', ['int']]]]]],
390 ['TypeDecl', ['IdentifierType', ['int']]]]])
391
392 self.assertEqual(self.get_decl('int zz(int p[const 10]);'),
393 ['Decl', 'zz',
394 ['FuncDecl',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800395 [['Decl', 'p', ['ArrayDecl', '10', ['const'],
Eli Benderskye7c55cf2014-01-25 06:15:43 -0800396 ['TypeDecl', ['IdentifierType', ['int']]]]]],
397 ['TypeDecl', ['IdentifierType', ['int']]]]])
398
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300399 def test_qualifiers_storage_specifiers(self):
400 def assert_qs(txt, index, quals, storage):
401 d = self.parse(txt).ext[index]
402 self.assertEqual(d.quals, quals)
403 self.assertEqual(d.storage, storage)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800404
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300405 assert_qs("extern int p;", 0, [], ['extern'])
406 assert_qs("const long p = 6;", 0, ['const'], [])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800407
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300408 d1 = "static const int p, q, r;"
409 for i in range(3):
410 assert_qs(d1, i, ['const'], ['static'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800411
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300412 d2 = "static char * const p;"
413 assert_qs(d2, 0, [], ['static'])
414 pdecl = self.parse(d2).ext[0].type
Eli Benderskya1da7fd2012-07-06 15:48:57 +0300415 self.assertTrue(isinstance(pdecl, PtrDecl))
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300416 self.assertEqual(pdecl.quals, ['const'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800417
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300418 def test_sizeof(self):
419 e = """
420 void foo()
421 {
422 int a = sizeof k;
423 int b = sizeof(int);
eli.benderskyc51e1d32011-02-04 08:52:33 +0200424 int c = sizeof(int**);;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800425
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300426 char* p = "just to make sure this parses w/o error...";
427 int d = sizeof(int());
428 }
429 """
430 compound = self.parse(e).ext[0].body
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800431
eli.benderskyef29ff92010-10-29 16:25:43 +0200432 s1 = compound.block_items[0].init
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300433 self.assertTrue(isinstance(s1, UnaryOp))
434 self.assertEqual(s1.op, 'sizeof')
435 self.assertTrue(isinstance(s1.expr, ID))
436 self.assertEqual(s1.expr.name, 'k')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800437
eli.benderskyef29ff92010-10-29 16:25:43 +0200438 s2 = compound.block_items[1].init
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300439 self.assertEqual(expand_decl(s2.expr),
440 ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800441
eli.benderskyef29ff92010-10-29 16:25:43 +0200442 s3 = compound.block_items[2].init
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300443 self.assertEqual(expand_decl(s3.expr),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800444 ['Typename',
445 ['PtrDecl',
446 ['PtrDecl',
447 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300448 ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800449
eli.bendersky9f481562010-10-30 15:50:47 +0200450 # The C99 compound literal feature
451 #
eli.benderskyf890a862010-10-30 12:13:23 +0200452 def test_compound_literals(self):
eli.bendersky9f481562010-10-30 15:50:47 +0200453 ps1 = self.parse(r'''
eli.benderskyf890a862010-10-30 12:13:23 +0200454 void foo() {
eli.bendersky9f481562010-10-30 15:50:47 +0200455 p = (long long){k};
456 tc = (struct jk){.a = {1, 2}, .b[0] = t};
457 }''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800458
eli.bendersky9f481562010-10-30 15:50:47 +0200459 compound = ps1.ext[0].body.block_items[0].rvalue
460 self.assertEqual(expand_decl(compound.type),
461 ['Typename', ['TypeDecl', ['IdentifierType', ['long', 'long']]]])
462 self.assertEqual(expand_init(compound.init),
463 [['ID', 'k']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800464
465 compound = ps1.ext[0].body.block_items[1].rvalue
eli.bendersky9f481562010-10-30 15:50:47 +0200466 self.assertEqual(expand_decl(compound.type),
467 ['Typename', ['TypeDecl', ['Struct', 'jk', []]]])
468 self.assertEqual(expand_init(compound.init),
469 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800470 ([['ID', 'a']], [['Constant', 'int', '1'], ['Constant', 'int', '2']]),
eli.bendersky9f481562010-10-30 15:50:47 +0200471 ([['ID', 'b'], ['Constant', 'int', '0']], ['ID', 't'])])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800472
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300473 def test_enums(self):
474 e1 = "enum mycolor op;"
475 e1_type = self.parse(e1).ext[0].type.type
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800476
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300477 self.assertTrue(isinstance(e1_type, Enum))
478 self.assertEqual(e1_type.name, 'mycolor')
479 self.assertEqual(e1_type.values, None)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800480
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300481 e2 = "enum mysize {large=20, small, medium} shoes;"
482 e2_type = self.parse(e2).ext[0].type.type
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800483
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300484 self.assertTrue(isinstance(e2_type, Enum))
485 self.assertEqual(e2_type.name, 'mysize')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800486
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300487 e2_elist = e2_type.values
488 self.assertTrue(isinstance(e2_elist, EnumeratorList))
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800489
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300490 for e2_eval in e2_elist.enumerators:
491 self.assertTrue(isinstance(e2_eval, Enumerator))
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800492
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300493 self.assertEqual(e2_elist.enumerators[0].name, 'large')
494 self.assertEqual(e2_elist.enumerators[0].value.value, '20')
495 self.assertEqual(e2_elist.enumerators[2].name, 'medium')
496 self.assertEqual(e2_elist.enumerators[2].value, None)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800497
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300498 # enum with trailing comma (C99 feature)
499 e3 = """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800500 enum
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300501 {
502 red,
503 blue,
504 green,
505 } color;
506 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800507
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300508 e3_type = self.parse(e3).ext[0].type.type
509 self.assertTrue(isinstance(e3_type, Enum))
510 e3_elist = e3_type.values
511 self.assertTrue(isinstance(e3_elist, EnumeratorList))
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800512
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300513 for e3_eval in e3_elist.enumerators:
514 self.assertTrue(isinstance(e3_eval, Enumerator))
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800515
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300516 self.assertEqual(e3_elist.enumerators[0].name, 'red')
517 self.assertEqual(e3_elist.enumerators[0].value, None)
518 self.assertEqual(e3_elist.enumerators[1].name, 'blue')
519 self.assertEqual(e3_elist.enumerators[2].name, 'green')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800520
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300521 def test_typedef(self):
522 # without typedef, error
523 s1 = """
524 node k;
525 """
526 self.assertRaises(ParseError, self.parse, s1)
527
528 # now with typedef, works
529 s2 = """
530 typedef void* node;
531 node k;
532 """
533 ps2 = self.parse(s2)
534 self.assertEqual(expand_decl(ps2.ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800535 ['Typedef', 'node',
536 ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300537 ['TypeDecl', ['IdentifierType', ['void']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800538
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300539 self.assertEqual(expand_decl(ps2.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800540 ['Decl', 'k',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300541 ['TypeDecl', ['IdentifierType', ['node']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800542
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300543 s3 = """
544 typedef int T;
545 typedef T *pT;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800546
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300547 pT aa, bb;
548 """
549 ps3 = self.parse(s3)
550 self.assertEqual(expand_decl(ps3.ext[3]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800551 ['Decl', 'bb',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300552 ['TypeDecl', ['IdentifierType', ['pT']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800553
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300554 s4 = '''
555 typedef char* __builtin_va_list;
556 typedef __builtin_va_list __gnuc_va_list;
557 '''
558 ps4 = self.parse(s4)
559 self.assertEqual(expand_decl(ps4.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800560 ['Typedef', '__gnuc_va_list',
561 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300562 ['IdentifierType', ['__builtin_va_list']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800563
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300564 s5 = '''typedef struct tagHash Hash;'''
565 ps5 = self.parse(s5)
566 self.assertEqual(expand_decl(ps5.ext[0]),
567 ['Typedef', 'Hash', ['TypeDecl', ['Struct', 'tagHash', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800568
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300569 def test_struct_union(self):
570 s1 = """
571 struct {
572 int id;
573 char* name;
574 } joe;
575 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800576
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300577 self.assertEqual(expand_decl(self.parse(s1).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800578 ['Decl', 'joe',
579 ['TypeDecl', ['Struct', None,
580 [ ['Decl', 'id',
581 ['TypeDecl',
582 ['IdentifierType', ['int']]]],
583 ['Decl', 'name',
584 ['PtrDecl',
585 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300586 ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800587
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300588 s2 = """
589 struct node p;
590 """
591 self.assertEqual(expand_decl(self.parse(s2).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800592 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300593 ['TypeDecl', ['Struct', 'node', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800594
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300595 s21 = """
596 union pri ra;
597 """
598 self.assertEqual(expand_decl(self.parse(s21).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800599 ['Decl', 'ra',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300600 ['TypeDecl', ['Union', 'pri', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800601
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300602 s3 = """
603 struct node* p;
604 """
605 self.assertEqual(expand_decl(self.parse(s3).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800606 ['Decl', 'p',
607 ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300608 ['TypeDecl', ['Struct', 'node', []]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800609
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300610 s4 = """
611 struct node;
612 """
613 self.assertEqual(expand_decl(self.parse(s4).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800614 ['Decl', None,
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300615 ['Struct', 'node', []]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800616
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300617 s5 = """
618 union
619 {
620 struct
621 {
622 int type;
623 } n;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800624
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300625 struct
626 {
627 int type;
628 int intnode;
629 } ni;
630 } u;
631 """
632 self.assertEqual(expand_decl(self.parse(s5).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800633 ['Decl', 'u',
634 ['TypeDecl',
635 ['Union', None,
636 [['Decl', 'n',
637 ['TypeDecl',
638 ['Struct', None,
639 [['Decl', 'type',
640 ['TypeDecl', ['IdentifierType', ['int']]]]]]]],
641 ['Decl', 'ni',
642 ['TypeDecl',
643 ['Struct', None,
644 [['Decl', 'type',
645 ['TypeDecl', ['IdentifierType', ['int']]]],
646 ['Decl', 'intnode',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300647 ['TypeDecl', ['IdentifierType', ['int']]]]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800648
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300649 s6 = """
650 typedef struct foo_tag
651 {
652 void* data;
653 } foo, *pfoo;
654 """
655 s6_ast = self.parse(s6)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800656
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300657 self.assertEqual(expand_decl(s6_ast.ext[0]),
658 ['Typedef', 'foo',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800659 ['TypeDecl',
660 ['Struct', 'foo_tag',
661 [['Decl', 'data',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300662 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['void']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800663
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300664 self.assertEqual(expand_decl(s6_ast.ext[1]),
665 ['Typedef', 'pfoo',
666 ['PtrDecl',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800667 ['TypeDecl',
668 ['Struct', 'foo_tag',
669 [['Decl', 'data',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300670 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['void']]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800671
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300672 s7 = r"""
673 struct _on_exit_args {
674 void * _fnargs[32];
675 void * _dso_handle[32];
676
677 long _fntypes;
678 #line 77 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
679
680 long _is_cxa;
681 };
682 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800683
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300684 s7_ast = self.parse(s7, filename='test.c')
685 self.assert_coord(s7_ast.ext[0].type.decls[2], 6, 'test.c')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800686 self.assert_coord(s7_ast.ext[0].type.decls[3], 78,
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300687 r'D:\eli\cpp_stuff\libc_include/sys/reent.h')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800688
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300689 s8 = """
690 typedef enum tagReturnCode {SUCCESS, FAIL} ReturnCode;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800691
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300692 typedef struct tagEntry
693 {
694 char* key;
695 char* value;
696 } Entry;
697
698
699 typedef struct tagNode
700 {
701 Entry* entry;
702
703 struct tagNode* next;
704 } Node;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800705
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300706 typedef struct tagHash
707 {
708 unsigned int table_size;
709
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800710 Node** heads;
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300711
712 } Hash;
713 """
714 s8_ast = self.parse(s8)
715 self.assertEqual(expand_decl(s8_ast.ext[3]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800716 ['Typedef', 'Hash',
717 ['TypeDecl', ['Struct', 'tagHash',
718 [['Decl', 'table_size',
719 ['TypeDecl', ['IdentifierType', ['unsigned', 'int']]]],
720 ['Decl', 'heads',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300721 ['PtrDecl', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['Node']]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800722
eli.bendersky697ecc52011-02-10 07:05:13 +0200723 def test_anonymous_struct_union(self):
724 s1 = """
725 union
726 {
727 union
728 {
729 int i;
730 long l;
731 };
732
733 struct
734 {
735 int type;
736 int intnode;
737 };
738 } u;
739 """
740
741 self.assertEqual(expand_decl(self.parse(s1).ext[0]),
742 ['Decl', 'u',
743 ['TypeDecl',
744 ['Union', None,
745 [['Decl', None,
746 ['Union', None,
747 [['Decl', 'i',
748 ['TypeDecl',
749 ['IdentifierType', ['int']]]],
750 ['Decl', 'l',
751 ['TypeDecl',
752 ['IdentifierType', ['long']]]]]]],
753 ['Decl', None,
754 ['Struct', None,
755 [['Decl', 'type',
756 ['TypeDecl',
757 ['IdentifierType', ['int']]]],
758 ['Decl', 'intnode',
759 ['TypeDecl',
760 ['IdentifierType', ['int']]]]]]]]]]])
761
762 s2 = """
763 struct
764 {
765 int i;
766 union
767 {
768 int id;
769 char* name;
770 };
771 float f;
772 } joe;
773 """
774
775 self.assertEqual(expand_decl(self.parse(s2).ext[0]),
776 ['Decl', 'joe',
777 ['TypeDecl',
778 ['Struct', None,
779 [['Decl', 'i',
780 ['TypeDecl',
781 ['IdentifierType', ['int']]]],
782 ['Decl', None,
783 ['Union', None,
784 [['Decl', 'id',
785 ['TypeDecl',
786 ['IdentifierType', ['int']]]],
787 ['Decl', 'name',
788 ['PtrDecl',
789 ['TypeDecl',
790 ['IdentifierType', ['char']]]]]]]],
791 ['Decl', 'f',
792 ['TypeDecl',
793 ['IdentifierType', ['float']]]]]]]])
794
795 # ISO/IEC 9899:201x Commitee Draft 2010-11-16, N1539
796 # section 6.7.2.1, par. 19, example 1
797 s3 = """
798 struct v {
799 union {
800 struct { int i, j; };
801 struct { long k, l; } w;
802 };
803 int m;
804 } v1;
805 """
806
807 self.assertEqual(expand_decl(self.parse(s3).ext[0]),
808 ['Decl', 'v1',
809 ['TypeDecl',
810 ['Struct', 'v',
811 [['Decl', None,
812 ['Union', None,
813 [['Decl', None,
814 ['Struct', None,
815 [['Decl', 'i',
816 ['TypeDecl',
817 ['IdentifierType', ['int']]]],
818 ['Decl', 'j',
819 ['TypeDecl',
820 ['IdentifierType', ['int']]]]]]],
821 ['Decl', 'w',
822 ['TypeDecl',
823 ['Struct', None,
824 [['Decl', 'k',
825 ['TypeDecl',
826 ['IdentifierType', ['long']]]],
827 ['Decl', 'l',
828 ['TypeDecl',
829 ['IdentifierType', ['long']]]]]]]]]]],
830 ['Decl', 'm',
831 ['TypeDecl',
832 ['IdentifierType', ['int']]]]]]]])
833
eli.benderskydce29a02011-02-10 07:55:00 +0200834 s4 = """
835 struct v {
836 int i;
837 float;
838 } v2;"""
eli.bendersky6b011792011-06-22 17:50:56 +0300839 # just make sure this doesn't raise ParseError
840 self.parse(s4)
eli.benderskydce29a02011-02-10 07:55:00 +0200841
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400842 def test_struct_members_namespace(self):
Eli Bendersky4d969b32013-07-13 06:07:07 -0700843 """ Tests that structure/union member names reside in a separate
844 namespace and can be named after existing types.
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400845 """
846 s1 = """
847 typedef int Name;
848 typedef Name NameArray[10];
849
850 struct {
851 Name Name;
852 Name NameArray[3];
853 } sye;
854
855 void main(void)
856 {
857 sye.Name = 1;
858 }
859 """
860
861 s1_ast = self.parse(s1)
862 self.assertEqual(expand_decl(s1_ast.ext[2]),
863 ['Decl', 'sye',
864 ['TypeDecl', ['Struct', None,
865 [ ['Decl', 'Name',
866 ['TypeDecl',
867 ['IdentifierType', ['Name']]]],
868 ['Decl', 'NameArray',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800869 ['ArrayDecl', '3', [],
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400870 ['TypeDecl', ['IdentifierType', ['Name']]]]]]]]])
871 self.assertEqual(s1_ast.ext[3].body.block_items[0].lvalue.field.name, 'Name')
872
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200873 def test_struct_bitfields(self):
eli.bendersky38ed9a92010-10-09 09:29:59 +0200874 # a struct with two bitfields, one unnamed
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200875 s1 = """
876 struct {
877 int k:6;
878 int :2;
879 } joe;
880 """
881
882 parsed_struct = self.parse(s1).ext[0]
883
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800884 # We can see here the name of the decl for the unnamed bitfield is
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200885 # None, but expand_decl doesn't show bitfield widths
886 # ...
887 self.assertEqual(expand_decl(parsed_struct),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800888 ['Decl', 'joe',
889 ['TypeDecl', ['Struct', None,
890 [ ['Decl', 'k',
891 ['TypeDecl',
892 ['IdentifierType', ['int']]]],
893 ['Decl', None,
894 ['TypeDecl',
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200895 ['IdentifierType', ['int']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800896
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200897 # ...
898 # so we test them manually
899 self.assertEqual(parsed_struct.type.type.decls[0].bitsize.value, '6')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800900 self.assertEqual(parsed_struct.type.type.decls[1].bitsize.value, '2')
901
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300902 def test_tags_namespace(self):
903 """ Tests that the tags of structs/unions/enums reside in a separate namespace and
904 can be named after existing types.
905 """
906 s1 = """
907 typedef int tagEntry;
908
909 struct tagEntry
910 {
911 char* key;
912 char* value;
913 } Entry;
914 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800915
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300916 s1_ast = self.parse(s1)
917 self.assertEqual(expand_decl(s1_ast.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800918 ['Decl', 'Entry',
919 ['TypeDecl', ['Struct', 'tagEntry',
920 [['Decl', 'key',
921 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
922 ['Decl', 'value',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300923 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800924
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300925 s2 = """
926 struct tagEntry;
927
928 typedef struct tagEntry tagEntry;
929
930 struct tagEntry
931 {
932 char* key;
933 char* value;
934 } Entry;
935 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800936
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300937 s2_ast = self.parse(s2)
938 self.assertEqual(expand_decl(s2_ast.ext[2]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800939 ['Decl', 'Entry',
940 ['TypeDecl', ['Struct', 'tagEntry',
941 [['Decl', 'key',
942 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
943 ['Decl', 'value',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300944 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800945
946 s3 = """
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300947 typedef int mytag;
948
949 enum mytag {ABC, CDE};
950 enum mytag joe;
951 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800952
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300953 s3_type = self.parse(s3).ext[1].type
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800954
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300955 self.assertTrue(isinstance(s3_type, Enum))
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800956 self.assertEqual(s3_type.name, 'mytag')
957
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300958 def test_multi_decls(self):
959 d1 = 'int a, b;'
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800960
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300961 self.assertEqual(self.get_decl(d1, 0),
962 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
963 self.assertEqual(self.get_decl(d1, 1),
964 ['Decl', 'b', ['TypeDecl', ['IdentifierType', ['int']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800965
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300966 d2 = 'char* p, notp, ar[4];'
967 self.assertEqual(self.get_decl(d2, 0),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800968 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300969 ['PtrDecl',
970 ['TypeDecl', ['IdentifierType', ['char']]]]])
971 self.assertEqual(self.get_decl(d2, 1),
972 ['Decl', 'notp', ['TypeDecl', ['IdentifierType', ['char']]]])
973 self.assertEqual(self.get_decl(d2, 2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800974 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -0800975 ['ArrayDecl', '4', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300976 ['TypeDecl', ['IdentifierType', ['char']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800977
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300978 def test_invalid_multiple_types_error(self):
979 bad = [
980 'int enum {ab, cd} fubr;',
981 'enum kid char brbr;']
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800982
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300983 for b in bad:
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800984 self.assertRaises(ParseError, self.parse, b)
Eli Bendersky9dadc3f2012-07-06 15:53:53 +0300985
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400986 def test_duplicate_typedef(self):
987 """ Tests that redeclarations of existing types are parsed correctly.
988 This is non-standard, but allowed by many compilers.
989 """
990 d1 = '''
Eli Bendersky9dadc3f2012-07-06 15:53:53 +0300991 typedef int numbertype;
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400992 typedef int numbertype;
Eli Bendersky9dadc3f2012-07-06 15:53:53 +0300993 '''
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400994
995 self.assertEqual(self.get_decl(d1, 0),
996 ['Typedef', 'numbertype',
997 ['TypeDecl', ['IdentifierType', ['int']]]])
998 self.assertEqual(self.get_decl(d1, 1),
999 ['Typedef', 'numbertype',
1000 ['TypeDecl', ['IdentifierType', ['int']]]])
1001
1002 d2 = '''
1003 typedef int (*funcptr)(int x);
1004 typedef int (*funcptr)(int x);
1005 '''
1006 self.assertEqual(self.get_decl(d2, 0),
1007 ['Typedef', 'funcptr',
1008 ['PtrDecl', ['FuncDecl',
1009 [['Decl', 'x', ['TypeDecl', ['IdentifierType', ['int']]]]],
1010 ['TypeDecl', ['IdentifierType', ['int']]]]]])
1011 self.assertEqual(self.get_decl(d2, 1),
1012 ['Typedef', 'funcptr',
1013 ['PtrDecl', ['FuncDecl',
1014 [['Decl', 'x', ['TypeDecl', ['IdentifierType', ['int']]]]],
1015 ['TypeDecl', ['IdentifierType', ['int']]]]]])
1016
1017 d3 = '''
1018 typedef int numberarray[5];
1019 typedef int numberarray[5];
1020 '''
1021 self.assertEqual(self.get_decl(d3, 0),
1022 ['Typedef', 'numberarray',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001023 ['ArrayDecl', '5', [],
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001024 ['TypeDecl', ['IdentifierType', ['int']]]]])
1025 self.assertEqual(self.get_decl(d3, 1),
1026 ['Typedef', 'numberarray',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001027 ['ArrayDecl', '5', [],
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001028 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001029
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001030 def test_decl_inits(self):
1031 d1 = 'int a = 16;'
eli.benderskyf890a862010-10-30 12:13:23 +02001032 #~ self.parse(d1).show()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001033 self.assertEqual(self.get_decl(d1),
1034 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
1035 self.assertEqual(self.get_decl_init(d1),
1036 ['Constant', 'int', '16'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001037
Eli Bendersky3b1b08d2012-06-15 12:37:54 +03001038 d1_1 = 'float f = 0xEF.56p1;'
1039 self.assertEqual(self.get_decl_init(d1_1),
1040 ['Constant', 'float', '0xEF.56p1'])
1041
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001042 d2 = 'long ar[] = {7, 8, 9};'
eli.benderskyf890a862010-10-30 12:13:23 +02001043 #~ self.parse(d2).show()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001044 self.assertEqual(self.get_decl(d2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001045 ['Decl', 'ar',
Eli Bendersky8aad3182014-01-25 06:30:53 -08001046 ['ArrayDecl', '', [],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001047 ['TypeDecl', ['IdentifierType', ['long']]]]])
1048 self.assertEqual(self.get_decl_init(d2),
1049 [ ['Constant', 'int', '7'],
1050 ['Constant', 'int', '8'],
eli.benderskyf890a862010-10-30 12:13:23 +02001051 ['Constant', 'int', '9']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001052
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001053 d3 = 'char p = j;'
1054 self.assertEqual(self.get_decl(d3),
1055 ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['char']]]])
1056 self.assertEqual(self.get_decl_init(d3),
1057 ['ID', 'j'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001058
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001059 d4 = "char x = 'c', *p = {0, 1, 2, {4, 5}, 6};"
1060 self.assertEqual(self.get_decl(d4, 0),
1061 ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['char']]]])
1062 self.assertEqual(self.get_decl_init(d4, 0),
1063 ['Constant', 'char', "'c'"])
1064 self.assertEqual(self.get_decl(d4, 1),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001065 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001066 ['PtrDecl',
1067 ['TypeDecl', ['IdentifierType', ['char']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001068
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001069 self.assertEqual(self.get_decl_init(d4, 1),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001070 [ ['Constant', 'int', '0'],
1071 ['Constant', 'int', '1'],
1072 ['Constant', 'int', '2'],
1073 [['Constant', 'int', '4'],
1074 ['Constant', 'int', '5']],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001075 ['Constant', 'int', '6']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001076
eli.benderskyf890a862010-10-30 12:13:23 +02001077 def test_decl_named_inits(self):
1078 d1 = 'int a = {.k = 16};'
1079 self.assertEqual(self.get_decl_init(d1),
1080 [( [['ID', 'k']],
1081 ['Constant', 'int', '16'])])
1082
1083 d2 = 'int a = { [0].a = {1}, [1].a[0] = 2 };'
1084 self.assertEqual(self.get_decl_init(d2),
1085 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001086 ([['Constant', 'int', '0'], ['ID', 'a']],
1087 [['Constant', 'int', '1']]),
1088 ([['Constant', 'int', '1'], ['ID', 'a'], ['Constant', 'int', '0']],
eli.benderskyf890a862010-10-30 12:13:23 +02001089 ['Constant', 'int', '2'])])
1090
1091 d3 = 'int a = { .a = 1, .c = 3, 4, .b = 5};'
1092 self.assertEqual(self.get_decl_init(d3),
1093 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001094 ([['ID', 'a']], ['Constant', 'int', '1']),
1095 ([['ID', 'c']], ['Constant', 'int', '3']),
1096 ['Constant', 'int', '4'],
eli.benderskyf890a862010-10-30 12:13:23 +02001097 ([['ID', 'b']], ['Constant', 'int', '5'])])
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001098
1099 def test_function_definitions(self):
1100 def parse_fdef(str):
1101 return self.parse(str).ext[0]
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001102
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001103 def fdef_decl(fdef):
1104 return expand_decl(fdef.decl)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001105
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001106 f1 = parse_fdef('''
1107 int factorial(int p)
1108 {
1109 return 3;
1110 }
1111 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001112
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001113 self.assertEqual(fdef_decl(f1),
1114 ['Decl', 'factorial',
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001115 ['FuncDecl',
1116 [['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001117 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001118
eli.benderskyef29ff92010-10-29 16:25:43 +02001119 self.assertEqual(type(f1.body.block_items[0]), Return)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001120
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001121 f2 = parse_fdef('''
1122 char* zzz(int p, char* c)
1123 {
1124 int a;
1125 char b;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001126
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001127 a = b + 2;
1128 return 3;
1129 }
1130 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001131
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001132 self.assertEqual(fdef_decl(f2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001133 ['Decl', 'zzz',
1134 ['FuncDecl',
1135 [ ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]],
1136 ['Decl', 'c', ['PtrDecl',
1137 ['TypeDecl', ['IdentifierType', ['char']]]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001138 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001139
1140 self.assertEqual(list(map(type, f2.body.block_items)),
eli.benderskyef29ff92010-10-29 16:25:43 +02001141 [Decl, Decl, Assignment, Return])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001142
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001143 f3 = parse_fdef('''
1144 char* zzz(p, c)
1145 long p, *c;
1146 {
1147 int a;
1148 char b;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001149
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001150 a = b + 2;
1151 return 3;
1152 }
1153 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001154
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001155 self.assertEqual(fdef_decl(f3),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001156 ['Decl', 'zzz',
1157 ['FuncDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001158 [ ['ID', 'p'],
1159 ['ID', 'c']],
1160 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001161
1162 self.assertEqual(list(map(type, f3.body.block_items)),
eli.benderskyef29ff92010-10-29 16:25:43 +02001163 [Decl, Decl, Assignment, Return])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001164
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001165 self.assertEqual(expand_decl(f3.param_decls[0]),
1166 ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['long']]]])
1167 self.assertEqual(expand_decl(f3.param_decls[1]),
1168 ['Decl', 'c', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['long']]]]])
1169
Sye van der Veen51a46ec2013-06-10 12:56:15 -04001170 # function return values and parameters may not have type information
1171 f4 = parse_fdef('''
1172 que(p)
1173 {
1174 return 3;
1175 }
1176 ''')
1177
1178 self.assertEqual(fdef_decl(f4),
1179 ['Decl', 'que',
1180 ['FuncDecl',
1181 [['ID', 'p']],
1182 ['TypeDecl', ['IdentifierType', ['int']]]]])
1183
eli.bendersky71540662010-07-03 12:58:52 +02001184 def test_unified_string_literals(self):
1185 # simple string, for reference
1186 d1 = self.get_decl_init('char* s = "hello";')
1187 self.assertEqual(d1, ['Constant', 'string', '"hello"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001188
eli.bendersky71540662010-07-03 12:58:52 +02001189 d2 = self.get_decl_init('char* s = "hello" " world";')
1190 self.assertEqual(d2, ['Constant', 'string', '"hello world"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001191
eli.bendersky71540662010-07-03 12:58:52 +02001192 # the test case from issue 6
1193 d3 = self.parse(r'''
1194 int main() {
1195 fprintf(stderr,
1196 "Wrong Params?\n"
1197 "Usage:\n"
1198 "%s <binary_file_path>\n",
1199 argv[0]
1200 );
1201 }
1202 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001203
eli.bendersky71540662010-07-03 12:58:52 +02001204 self.assertEqual(
eli.benderskyef29ff92010-10-29 16:25:43 +02001205 d3.ext[0].body.block_items[0].args.exprs[1].value,
eli.bendersky71540662010-07-03 12:58:52 +02001206 r'"Wrong Params?\nUsage:\n%s <binary_file_path>\n"')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001207
eli.bendersky4a89f112010-07-05 06:02:03 +02001208 d4 = self.get_decl_init('char* s = "" "foobar";')
1209 self.assertEqual(d4, ['Constant', 'string', '"foobar"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001210
eli.bendersky4a89f112010-07-05 06:02:03 +02001211 d5 = self.get_decl_init(r'char* s = "foo\"" "bar";')
1212 self.assertEqual(d5, ['Constant', 'string', r'"foo\"bar"'])
eli.bendersky71540662010-07-03 12:58:52 +02001213
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001214 def test_inline_specifier(self):
eli.bendersky79d5cf62010-10-29 13:33:52 +02001215 ps2 = self.parse('static inline void inlinefoo(void);')
1216 self.assertEqual(ps2.ext[0].funcspec, ['inline'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001217
eli.bendersky2e907fa2010-10-29 15:51:07 +02001218 # variable length array
1219 def test_vla(self):
1220 ps2 = self.parse(r'''
1221 int main() {
1222 int size;
1223 int var[size = 5];
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001224
eli.bendersky2e907fa2010-10-29 15:51:07 +02001225 int var2[*];
1226 }
1227 ''')
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001228 self.assertTrue(isinstance(ps2.ext[0].body.block_items[1].type.dim, Assignment))
1229 self.assertTrue(isinstance(ps2.ext[0].body.block_items[2].type.dim, ID))
eli.bendersky79d5cf62010-10-29 13:33:52 +02001230
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001231
eli.bendersky85d2e732011-05-20 19:47:26 +03001232class TestCParser_whole_code(TestCParser_base):
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001233 """ Testing of parsing whole chunks of code.
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001234
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001235 Since I don't want to rely on the structure of ASTs too
1236 much, most of these tests are implemented with visitors.
1237 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001238 # A simple helper visitor that lists the values of all the
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001239 # Constant nodes it sees.
1240 #
1241 class ConstantVisitor(NodeVisitor):
1242 def __init__(self):
1243 self.values = []
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001244
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001245 def visit_Constant(self, node):
1246 self.values.append(node.value)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001247
1248 # This visitor counts the amount of references to the ID
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001249 # with the name provided to it in the constructor.
1250 #
1251 class IDNameCounter(NodeVisitor):
1252 def __init__(self, name):
1253 self.name = name
1254 self.nrefs = 0
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001255
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001256 def visit_ID(self, node):
1257 if node.name == self.name:
1258 self.nrefs += 1
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001259
1260 # Counts the amount of nodes of a given class
1261 #
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001262 class NodeKlassCounter(NodeVisitor):
1263 def __init__(self, node_klass):
1264 self.klass = node_klass
1265 self.n = 0
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001266
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001267 def generic_visit(self, node):
1268 if node.__class__ == self.klass:
1269 self.n += 1
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001270
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001271 NodeVisitor.generic_visit(self, node)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001272
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001273 def assert_all_Constants(self, code, constants):
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001274 """ Asserts that the list of all Constant values (by
1275 'preorder' appearance) in the chunk of code is as
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001276 given.
1277 """
eli.benderskyed890492010-06-25 08:25:55 +03001278 if isinstance(code, str):
1279 parsed = self.parse(code)
1280 else:
1281 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001282
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001283 cv = self.ConstantVisitor()
1284 cv.visit(parsed)
1285 self.assertEqual(cv.values, constants)
1286
1287 def assert_num_ID_refs(self, code, name, num):
1288 """ Asserts the number of references to the ID with
1289 the given name.
1290 """
1291 if isinstance(code, str):
1292 parsed = self.parse(code)
1293 else:
1294 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001295
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001296 iv = self.IDNameCounter(name)
1297 iv.visit(parsed)
1298 self.assertEqual(iv.nrefs, num)
1299
1300 def assert_num_klass_nodes(self, code, klass, num):
1301 """ Asserts the amount of klass nodes in the code.
1302 """
1303 if isinstance(code, str):
1304 parsed = self.parse(code)
1305 else:
1306 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001307
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001308 cv = self.NodeKlassCounter(klass)
1309 cv.visit(parsed)
1310 self.assertEqual(cv.n, num)
1311
1312 def test_expressions(self):
1313 e1 = '''int k = (r + 10.0) >> 6 + 8 << (3 & 0x14);'''
1314 self.assert_all_Constants(e1, ['10.0', '6', '8', '3', '0x14'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001315
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001316 e2 = r'''char n = '\n', *prefix = "st_";'''
1317 self.assert_all_Constants(e2, [r"'\n'", '"st_"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001318
Eli Bendersky09e22a62013-07-02 06:00:36 -07001319 s1 = r'''int main() {
1320 int i = 5, j = 6, k = 1;
1321 if ((i=j && k == 1) || k > j)
1322 printf("Hello, world\n");
1323 return 0;
1324 }'''
1325 ps1 = self.parse(s1)
1326 self.assert_all_Constants(ps1,
1327 ['5', '6', '1', '1', '"Hello, world\\n"', '0'])
1328 self.assert_num_ID_refs(ps1, 'i', 1)
1329 self.assert_num_ID_refs(ps1, 'j', 2)
1330
1331
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001332 def test_statements(self):
1333 s1 = r'''
1334 void foo(){
1335 if (sp == 1)
1336 if (optind >= argc ||
1337 argv[optind][0] != '-' || argv[optind][1] == '\0')
1338 return -1;
1339 else if (strcmp(argv[optind], "--") == 0) {
1340 optind++;
1341 return -1;
1342 }
1343 }
1344 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001345
1346 self.assert_all_Constants(s1,
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001347 ['1', '0', r"'-'", '1', r"'\0'", '1', r'"--"', '0', '1'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001348
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001349 ps1 = self.parse(s1)
1350 self.assert_num_ID_refs(ps1, 'argv', 3)
1351 self.assert_num_ID_refs(ps1, 'optind', 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001352
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001353 self.assert_num_klass_nodes(ps1, If, 3)
1354 self.assert_num_klass_nodes(ps1, Return, 2)
1355 self.assert_num_klass_nodes(ps1, FuncCall, 1) # strcmp
1356 self.assert_num_klass_nodes(ps1, BinaryOp, 7)
1357
1358 # In the following code, Hash and Node were defined as
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001359 # int to pacify the parser that sees they're used as
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001360 # types
1361 #
1362 s2 = r'''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001363 typedef int Hash, Node;
1364
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001365 void HashDestroy(Hash* hash)
1366 {
1367 unsigned int i;
1368
1369 if (hash == NULL)
1370 return;
1371
1372 for (i = 0; i < hash->table_size; ++i)
1373 {
1374 Node* temp = hash->heads[i];
1375
1376 while (temp != NULL)
1377 {
1378 Node* temp2 = temp;
1379
1380 free(temp->entry->key);
1381 free(temp->entry->value);
1382 free(temp->entry);
1383
1384 temp = temp->next;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001385
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001386 free(temp2);
1387 }
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001388 }
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001389
1390 free(hash->heads);
1391 hash->heads = NULL;
1392
1393 free(hash);
1394 }
1395 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001396
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001397 ps2 = self.parse(s2)
1398 self.assert_num_klass_nodes(ps2, FuncCall, 6)
1399 self.assert_num_klass_nodes(ps2, FuncDef, 1)
1400 self.assert_num_klass_nodes(ps2, For, 1)
1401 self.assert_num_klass_nodes(ps2, While, 1)
1402 self.assert_num_klass_nodes(ps2, StructRef, 10)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001403
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001404 # declarations don't count
1405 self.assert_num_ID_refs(ps2, 'hash', 6)
1406 self.assert_num_ID_refs(ps2, 'i', 4)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001407
eli.benderskyed890492010-06-25 08:25:55 +03001408 s3 = r'''
1409 void x(void) {
1410 int a, b;
1411 if (a < b)
1412 do {
1413 a = 0;
1414 } while (0);
1415 else if (a == b) {
1416 a = 1;
1417 }
1418 }
1419 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001420
eli.benderskyed890492010-06-25 08:25:55 +03001421 ps3 = self.parse(s3)
1422 self.assert_num_klass_nodes(ps3, DoWhile, 1)
1423 self.assert_num_ID_refs(ps3, 'a', 4)
1424 self.assert_all_Constants(ps3, ['0', '0', '1'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001425
eli.bendersky91c0aa32011-10-16 05:50:43 +02001426 def test_empty_statement(self):
1427 s1 = r'''
1428 void foo(void){
1429 ;
1430 return;
1431 }
1432 '''
1433 ps1 = self.parse(s1)
1434 self.assert_num_klass_nodes(ps1, EmptyStatement, 1)
1435 self.assert_num_klass_nodes(ps1, Return, 1)
eli.bendersky145890d2010-10-29 12:02:32 +02001436
Ben5cd3fd62012-02-03 06:02:40 +02001437 def test_switch_statement(self):
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001438 def assert_case_node(node, const_value):
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001439 self.assertTrue(isinstance(node, Case))
1440 self.assertTrue(isinstance(node.expr, Constant))
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001441 self.assertEqual(node.expr.value, const_value)
1442
1443 def assert_default_node(node):
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001444 self.assertTrue(isinstance(node, Default))
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001445
Ben5cd3fd62012-02-03 06:02:40 +02001446 s1 = r'''
1447 int foo(void) {
1448 switch (myvar) {
1449 case 10:
1450 k = 10;
1451 p = k + 1;
1452 return 10;
1453 case 20:
1454 case 30:
1455 return 20;
1456 default:
1457 break;
1458 }
1459 return 0;
1460 }
1461 '''
1462 ps1 = self.parse(s1)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001463 switch = ps1.ext[0].body.block_items[0]
1464
1465 block = switch.stmt.block_items
1466 assert_case_node(block[0], '10')
1467 self.assertEqual(len(block[0].stmts), 3)
1468 assert_case_node(block[1], '20')
1469 self.assertEqual(len(block[1].stmts), 0)
1470 assert_case_node(block[2], '30')
1471 self.assertEqual(len(block[2].stmts), 1)
1472 assert_default_node(block[3])
1473
1474 s2 = r'''
1475 int foo(void) {
1476 switch (myvar) {
1477 default:
1478 joe = moe;
1479 return 10;
1480 case 10:
1481 case 20:
1482 case 30:
1483 case 40:
1484 break;
1485 }
1486 return 0;
1487 }
1488 '''
1489 ps2 = self.parse(s2)
1490 switch = ps2.ext[0].body.block_items[0]
1491
1492 block = switch.stmt.block_items
1493 assert_default_node(block[0])
1494 self.assertEqual(len(block[0].stmts), 2)
1495 assert_case_node(block[1], '10')
1496 self.assertEqual(len(block[1].stmts), 0)
1497 assert_case_node(block[2], '20')
1498 self.assertEqual(len(block[1].stmts), 0)
1499 assert_case_node(block[3], '30')
1500 self.assertEqual(len(block[1].stmts), 0)
1501 assert_case_node(block[4], '40')
1502 self.assertEqual(len(block[4].stmts), 1)
Ben5cd3fd62012-02-03 06:02:40 +02001503
eli.bendersky145890d2010-10-29 12:02:32 +02001504 def test_for_statement(self):
1505 s2 = r'''
1506 void x(void)
1507 {
1508 int i;
1509 for (i = 0; i < 5; ++i) {
1510 x = 50;
1511 }
1512 }
1513 '''
1514 ps2 = self.parse(s2)
1515 self.assert_num_klass_nodes(ps2, For, 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001516 # here there are 3 refs to 'i' since the declaration doesn't count as
eli.bendersky145890d2010-10-29 12:02:32 +02001517 # a ref in the visitor
1518 #
1519 self.assert_num_ID_refs(ps2, 'i', 3)
Eli Bendersky4476d092012-12-25 14:07:57 -08001520
eli.bendersky145890d2010-10-29 12:02:32 +02001521 s3 = r'''
1522 void x(void)
1523 {
1524 for (int i = 0; i < 5; ++i) {
1525 x = 50;
1526 }
1527 }
1528 '''
1529 ps3 = self.parse(s3)
eli.bendersky145890d2010-10-29 12:02:32 +02001530 self.assert_num_klass_nodes(ps3, For, 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001531 # here there are 2 refs to 'i' since the declaration doesn't count as
eli.bendersky145890d2010-10-29 12:02:32 +02001532 # a ref in the visitor
1533 #
1534 self.assert_num_ID_refs(ps3, 'i', 2)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001535
Eli Bendersky4476d092012-12-25 14:07:57 -08001536 s4 = r'''
1537 void x(void) {
1538 for (int i = 0;;)
1539 i;
1540 }
1541 '''
1542 ps4 = self.parse(s4)
1543 self.assert_num_ID_refs(ps4, 'i', 1)
1544
Eli Benderskyd0973782012-01-19 08:09:33 +02001545 def _open_c_file(self, name):
1546 """ Find a c file by name, taking into account the current dir can be
1547 in a couple of typical places
1548 """
Stefano Riveraebaf5922013-08-08 09:45:26 +02001549 testdir = os.path.dirname(__file__)
1550 name = os.path.join(testdir, 'c_files', name)
1551 assert os.path.exists(name)
1552 return open(name, 'rU')
Eli Benderskyd0973782012-01-19 08:09:33 +02001553
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001554 def test_whole_file(self):
1555 # See how pycparser handles a whole, real C file.
1556 #
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001557 with self._open_c_file('memmgr_with_h.c') as f:
1558 code = f.read()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001559 p = self.parse(code)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001560
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001561 self.assert_num_klass_nodes(p, FuncDef, 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001562
1563 # each FuncDef also has a FuncDecl. 4 declarations
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001564 # + 5 definitions, overall 9
1565 self.assert_num_klass_nodes(p, FuncDecl, 9)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001566
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001567 self.assert_num_klass_nodes(p, Typedef, 4)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001568
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001569 self.assertEqual(p.ext[4].coord.line, 88)
1570 self.assertEqual(p.ext[4].coord.file, "./memmgr.h")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001571
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001572 self.assertEqual(p.ext[6].coord.line, 10)
1573 self.assertEqual(p.ext[6].coord.file, "memmgr.c")
1574
1575 def test_whole_file_with_stdio(self):
1576 # Parse a whole file with stdio.h included by cpp
1577 #
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001578 with self._open_c_file('cppd_with_stdio_h.c') as f:
1579 code = f.read()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001580 p = self.parse(code)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001581
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001582 self.assertTrue(isinstance(p.ext[0], Typedef))
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001583 self.assertEqual(p.ext[0].coord.line, 213)
1584 self.assertEqual(p.ext[0].coord.file, "D:\eli\cpp_stuff\libc_include/stddef.h")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001585
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001586 self.assertTrue(isinstance(p.ext[-1], FuncDef))
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001587 self.assertEqual(p.ext[-1].coord.line, 15)
1588 self.assertEqual(p.ext[-1].coord.file, "example_c_file.c")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001589
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001590 self.assertTrue(isinstance(p.ext[-8], Typedef))
1591 self.assertTrue(isinstance(p.ext[-8].type, TypeDecl))
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001592 self.assertEqual(p.ext[-8].name, 'cookie_io_functions_t')
eli.bendersky85d2e732011-05-20 19:47:26 +03001593
1594
1595class TestCParser_typenames(TestCParser_base):
1596 """ Test issues related to the typedef-name problem.
1597 """
1598 def test_innerscope_typedef(self):
1599 # should fail since TT is not a type in bar
1600 s1 = r'''
1601 void foo() {
1602 typedef char TT;
1603 TT x;
1604 }
1605 void bar() {
1606 TT y;
1607 }
1608 '''
1609 self.assertRaises(ParseError, self.parse, s1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001610
eli.bendersky85d2e732011-05-20 19:47:26 +03001611 # should succeed since TT is not a type in bar
1612 s2 = r'''
1613 void foo() {
1614 typedef char TT;
1615 TT x;
1616 }
1617 void bar() {
1618 unsigned TT;
1619 }
1620 '''
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001621 self.assertTrue(isinstance(self.parse(s2), FileAST))
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001622
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001623 def test_innerscope_reuse_typedef_name(self):
1624 # identifiers can be reused in inner scopes; the original should be
1625 # restored at the end of the block
1626 s1 = r'''
1627 typedef char TT;
1628 void foo(void) {
1629 unsigned TT;
1630 TT = 10;
1631 }
1632 TT x = 5;
1633 '''
1634 s1_ast = self.parse(s1)
1635 self.assertEqual(expand_decl(s1_ast.ext[1].body.block_items[0]),
1636 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
Eli Bendersky3877c4c2013-07-13 06:54:04 -07001637 self.assertEqual(expand_decl(s1_ast.ext[2]),
1638 ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['TT']]]])
eli.bendersky85d2e732011-05-20 19:47:26 +03001639
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001640 # this should be recognized even with an initializer
1641 s2 = r'''
1642 typedef char TT;
1643 void foo(void) {
1644 unsigned TT = 10;
1645 }
1646 '''
1647 s2_ast = self.parse(s2)
1648 self.assertEqual(expand_decl(s2_ast.ext[1].body.block_items[0]),
1649 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1650
1651 # before the second local variable, TT is a type; after, it's a
1652 # variable
1653 s3 = r'''
1654 typedef char TT;
1655 void foo(void) {
1656 TT tt = sizeof(TT);
1657 unsigned TT = 10;
1658 }
1659 '''
1660 s3_ast = self.parse(s3)
1661 self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[0]),
1662 ['Decl', 'tt', ['TypeDecl', ['IdentifierType', ['TT']]]])
1663 self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[1]),
1664 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1665
1666 # a variable and its type can even share the same name
1667 s4 = r'''
1668 typedef char TT;
1669 void foo(void) {
1670 TT TT = sizeof(TT);
1671 unsigned uu = TT * 2;
1672 }
1673 '''
1674 s4_ast = self.parse(s4)
1675 self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[0]),
1676 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['TT']]]])
1677 self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[1]),
1678 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1679
1680 # ensure an error is raised if a type, redeclared as a variable, is
1681 # used as a type
1682 s5 = r'''
1683 typedef char TT;
1684 void foo(void) {
1685 unsigned TT = 10;
1686 TT erroneous = 20;
1687 }
1688 '''
1689 self.assertRaises(ParseError, self.parse, s5)
1690
1691 def test_parameter_reuse_typedef_name(self):
1692 # identifiers can be reused as parameter names; parameter name scope
1693 # begins and ends with the function body; it's important that TT is
Eli Bendersky4d969b32013-07-13 06:07:07 -07001694 # used immediately before the LBRACE or after the RBRACE, to test
1695 # a corner case
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001696 s1 = r'''
1697 typedef char TT;
1698 void foo(unsigned TT, TT bar) {
1699 TT = 10;
1700 }
1701 TT x = 5;
1702 '''
1703 s1_ast = self.parse(s1)
1704 self.assertEqual(expand_decl(s1_ast.ext[1].decl),
1705 ['Decl', 'foo',
1706 ['FuncDecl',
1707 [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
1708 ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
1709 ['TypeDecl', ['IdentifierType', ['void']]]]])
1710
1711 # the scope of a parameter name in a function declaration ends at the
1712 # end of the declaration...so it is effectively never used; it's
1713 # important that TT is used immediately after the declaration, to
1714 # test a corner case
1715 s2 = r'''
1716 typedef char TT;
1717 void foo(unsigned TT, TT bar);
1718 TT x = 5;
1719 '''
1720 s2_ast = self.parse(s2)
1721 self.assertEqual(expand_decl(s2_ast.ext[1]),
1722 ['Decl', 'foo',
1723 ['FuncDecl',
1724 [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
1725 ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
1726 ['TypeDecl', ['IdentifierType', ['void']]]]])
1727
1728 # ensure an error is raised if a type, redeclared as a parameter, is
1729 # used as a type
1730 s3 = r'''
1731 typedef char TT;
1732 void foo(unsigned TT, TT bar) {
1733 TT erroneous = 20;
1734 }
1735 '''
1736 self.assertRaises(ParseError, self.parse, s3)
1737
1738 def test_nested_function_decls(self):
1739 # parameter names of nested function declarations must not escape into
1740 # the top-level function _definition's_ scope; the following must
1741 # succeed because TT is still a typedef inside foo's body
1742 s1 = r'''
1743 typedef char TT;
1744 void foo(unsigned bar(int TT)) {
1745 TT x = 10;
1746 }
1747 '''
1748 self.assertTrue(isinstance(self.parse(s1), FileAST))
1749
1750 def test_samescope_reuse_name(self):
1751 # a typedef name cannot be reused as an object name in the same scope
1752 s1 = r'''
1753 typedef char TT;
1754 char TT = 5;
1755 '''
1756 self.assertRaises(ParseError, self.parse, s1)
1757
1758 # ...and vice-versa
1759 s2 = r'''
1760 char TT = 5;
1761 typedef char TT;
1762 '''
1763 self.assertRaises(ParseError, self.parse, s2)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001764
1765if __name__ == '__main__':
1766 #~ suite = unittest.TestLoader().loadTestsFromNames(
1767 #~ ['test_c_parser.TestCParser_fundamentals.test_typedef'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001768
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001769 #~ unittest.TextTestRunner(verbosity=2).run(suite)
1770 unittest.main()