blob: 67048a1ec7d3672565e087a9d8cdfaf434f70e87 [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 ''
50 return ['ArrayDecl', dimval, nested]
51 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 Bendersky3921e8e2010-05-21 09:05:39 +0300213 def test_simple_decls(self):
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800214 self.assertEqual(self.get_decl('int a;'),
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300215 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
216
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800217 self.assertEqual(self.get_decl('unsigned int a;'),
Eli Bendersky68497c22012-01-19 06:04:58 +0200218 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['unsigned', 'int']]]])
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300219
eli.benderskyaffe0322011-09-24 06:16:55 +0300220 self.assertEqual(self.get_decl('_Bool a;'),
221 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['_Bool']]]])
222
Eli Benderskyf4d73462012-01-19 05:56:27 +0200223 self.assertEqual(self.get_decl('float _Complex fcc;'),
Eli Bendersky68497c22012-01-19 06:04:58 +0200224 ['Decl', 'fcc', ['TypeDecl', ['IdentifierType', ['float', '_Complex']]]])
Eli Benderskyf4d73462012-01-19 05:56:27 +0200225
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800226 self.assertEqual(self.get_decl('char* string;'),
227 ['Decl', 'string',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300228 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]])
229
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800230 self.assertEqual(self.get_decl('long ar[15];'),
231 ['Decl', 'ar',
232 ['ArrayDecl', '15',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300233 ['TypeDecl', ['IdentifierType', ['long']]]]])
eli.bendersky98f45372010-10-30 09:46:29 +0200234
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800235 self.assertEqual(self.get_decl('long long ar[15];'),
236 ['Decl', 'ar',
237 ['ArrayDecl', '15',
eli.benderskyf890a862010-10-30 12:13:23 +0200238 ['TypeDecl', ['IdentifierType', ['long', 'long']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800239
240 self.assertEqual(self.get_decl('unsigned ar[];'),
241 ['Decl', 'ar',
242 ['ArrayDecl', '',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300243 ['TypeDecl', ['IdentifierType', ['unsigned']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800244
245 self.assertEqual(self.get_decl('int strlen(char* s);'),
246 ['Decl', 'strlen',
247 ['FuncDecl',
248 [['Decl', 's',
249 ['PtrDecl',
250 ['TypeDecl', ['IdentifierType', ['char']]]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300251 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800252
253 self.assertEqual(self.get_decl('int strcmp(char* s1, char* s2);'),
254 ['Decl', 'strcmp',
255 ['FuncDecl',
256 [ ['Decl', 's1',
257 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
258 ['Decl', 's2',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300259 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800260 ],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300261 ['TypeDecl', ['IdentifierType', ['int']]]]])
262
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400263 # function return values and parameters may not have type information
Eli Bendersky09e22a62013-07-02 06:00:36 -0700264 self.assertEqual(self.get_decl('extern foobar(foo, bar);'),
265 ['Decl', 'foobar',
266 ['FuncDecl',
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400267 [ ['ID', 'foo'],
268 ['ID', 'bar']
Eli Bendersky09e22a62013-07-02 06:00:36 -0700269 ],
Sye van der Veen51a46ec2013-06-10 12:56:15 -0400270 ['TypeDecl', ['IdentifierType', ['int']]]]])
271
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300272 def test_nested_decls(self): # the fun begins
273 self.assertEqual(self.get_decl('char** ar2D;'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800274 ['Decl', 'ar2D',
275 ['PtrDecl', ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300276 ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800277
278 self.assertEqual(self.get_decl('int (*a)[1][2];'),
279 ['Decl', 'a',
280 ['PtrDecl',
281 ['ArrayDecl', '1',
282 ['ArrayDecl', '2',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300283 ['TypeDecl', ['IdentifierType', ['int']]]]]]])
284
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800285 self.assertEqual(self.get_decl('int *a[1][2];'),
286 ['Decl', 'a',
287 ['ArrayDecl', '1',
288 ['ArrayDecl', '2',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300289 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['int']]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800290
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300291 self.assertEqual(self.get_decl('char ***ar3D[40];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800292 ['Decl', 'ar3D',
293 ['ArrayDecl', '40',
294 ['PtrDecl', ['PtrDecl', ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300295 ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800296
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300297 self.assertEqual(self.get_decl('char (***ar3D)[40];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800298 ['Decl', 'ar3D',
299 ['PtrDecl', ['PtrDecl', ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300300 ['ArrayDecl', '40', ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800301
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300302 self.assertEqual(self.get_decl('int (*x[4])(char, int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800303 ['Decl', 'x',
304 ['ArrayDecl', '4',
305 ['PtrDecl',
306 ['FuncDecl',
307 [ ['Typename', ['TypeDecl', ['IdentifierType', ['char']]]],
308 ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300309 ['TypeDecl', ['IdentifierType', ['int']]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800310
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300311 self.assertEqual(self.get_decl('char *(*(**foo [][8])())[];'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800312 ['Decl', 'foo',
313 ['ArrayDecl', '',
314 ['ArrayDecl', '8',
315 ['PtrDecl', ['PtrDecl',
316 ['FuncDecl',
317 [],
318 ['PtrDecl',
319 ['ArrayDecl', '',
320 ['PtrDecl',
321 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300322 ['IdentifierType', ['char']]]]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800323
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300324 # explore named and unnamed function pointer parameters,
325 # with and without qualifiers
326 #
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800327
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300328 # unnamed w/o quals
329 self.assertEqual(self.get_decl('int (*k)(int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800330 ['Decl', 'k',
331 ['PtrDecl',
332 ['FuncDecl',
333 [['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300334 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800335
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300336 # unnamed w/ quals
337 self.assertEqual(self.get_decl('int (*k)(const int);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800338 ['Decl', 'k',
339 ['PtrDecl',
340 ['FuncDecl',
341 [['Typename', ['const'], ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300342 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800343
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300344 # named w/o quals
345 self.assertEqual(self.get_decl('int (*k)(int q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800346 ['Decl', 'k',
347 ['PtrDecl',
348 ['FuncDecl',
349 [['Decl', 'q', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300350 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800351
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300352 # named w/ quals
353 self.assertEqual(self.get_decl('int (*k)(const volatile int q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800354 ['Decl', 'k',
355 ['PtrDecl',
356 ['FuncDecl',
357 [['Decl', ['const', 'volatile'], 'q',
358 ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300359 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800360
eli.bendersky79d5cf62010-10-29 13:33:52 +0200361 # restrict qualifier
362 self.assertEqual(self.get_decl('int (*k)(restrict int* q);'),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800363 ['Decl', 'k',
364 ['PtrDecl',
365 ['FuncDecl',
366 [['Decl', ['restrict'], 'q',
eli.bendersky79d5cf62010-10-29 13:33:52 +0200367 ['PtrDecl',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800368 ['TypeDecl', ['IdentifierType', ['int']]]]]],
eli.bendersky79d5cf62010-10-29 13:33:52 +0200369 ['TypeDecl', ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800370
Eli Benderskye7c55cf2014-01-25 06:15:43 -0800371 def test_func_decls_with_array_dim_qualifiers(self):
372 self.assertEqual(self.get_decl('int zz(int p[static 10]);'),
373 ['Decl', 'zz',
374 ['FuncDecl',
375 [['Decl', 'p', ['ArrayDecl', '10',
376 ['TypeDecl', ['IdentifierType', ['int']]]]]],
377 ['TypeDecl', ['IdentifierType', ['int']]]]])
378
379 self.assertEqual(self.get_decl('int zz(int p[const 10]);'),
380 ['Decl', 'zz',
381 ['FuncDecl',
382 [['Decl', 'p', ['ArrayDecl', '10',
383 ['TypeDecl', ['IdentifierType', ['int']]]]]],
384 ['TypeDecl', ['IdentifierType', ['int']]]]])
385
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300386 def test_qualifiers_storage_specifiers(self):
387 def assert_qs(txt, index, quals, storage):
388 d = self.parse(txt).ext[index]
389 self.assertEqual(d.quals, quals)
390 self.assertEqual(d.storage, storage)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800391
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300392 assert_qs("extern int p;", 0, [], ['extern'])
393 assert_qs("const long p = 6;", 0, ['const'], [])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800394
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300395 d1 = "static const int p, q, r;"
396 for i in range(3):
397 assert_qs(d1, i, ['const'], ['static'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800398
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300399 d2 = "static char * const p;"
400 assert_qs(d2, 0, [], ['static'])
401 pdecl = self.parse(d2).ext[0].type
Eli Benderskya1da7fd2012-07-06 15:48:57 +0300402 self.assertTrue(isinstance(pdecl, PtrDecl))
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300403 self.assertEqual(pdecl.quals, ['const'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800404
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300405 def test_sizeof(self):
406 e = """
407 void foo()
408 {
409 int a = sizeof k;
410 int b = sizeof(int);
eli.benderskyc51e1d32011-02-04 08:52:33 +0200411 int c = sizeof(int**);;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800412
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300413 char* p = "just to make sure this parses w/o error...";
414 int d = sizeof(int());
415 }
416 """
417 compound = self.parse(e).ext[0].body
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800418
eli.benderskyef29ff92010-10-29 16:25:43 +0200419 s1 = compound.block_items[0].init
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300420 self.assertTrue(isinstance(s1, UnaryOp))
421 self.assertEqual(s1.op, 'sizeof')
422 self.assertTrue(isinstance(s1.expr, ID))
423 self.assertEqual(s1.expr.name, 'k')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800424
eli.benderskyef29ff92010-10-29 16:25:43 +0200425 s2 = compound.block_items[1].init
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300426 self.assertEqual(expand_decl(s2.expr),
427 ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800428
eli.benderskyef29ff92010-10-29 16:25:43 +0200429 s3 = compound.block_items[2].init
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300430 self.assertEqual(expand_decl(s3.expr),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800431 ['Typename',
432 ['PtrDecl',
433 ['PtrDecl',
434 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300435 ['IdentifierType', ['int']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800436
eli.bendersky9f481562010-10-30 15:50:47 +0200437 # The C99 compound literal feature
438 #
eli.benderskyf890a862010-10-30 12:13:23 +0200439 def test_compound_literals(self):
eli.bendersky9f481562010-10-30 15:50:47 +0200440 ps1 = self.parse(r'''
eli.benderskyf890a862010-10-30 12:13:23 +0200441 void foo() {
eli.bendersky9f481562010-10-30 15:50:47 +0200442 p = (long long){k};
443 tc = (struct jk){.a = {1, 2}, .b[0] = t};
444 }''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800445
eli.bendersky9f481562010-10-30 15:50:47 +0200446 compound = ps1.ext[0].body.block_items[0].rvalue
447 self.assertEqual(expand_decl(compound.type),
448 ['Typename', ['TypeDecl', ['IdentifierType', ['long', 'long']]]])
449 self.assertEqual(expand_init(compound.init),
450 [['ID', 'k']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800451
452 compound = ps1.ext[0].body.block_items[1].rvalue
eli.bendersky9f481562010-10-30 15:50:47 +0200453 self.assertEqual(expand_decl(compound.type),
454 ['Typename', ['TypeDecl', ['Struct', 'jk', []]]])
455 self.assertEqual(expand_init(compound.init),
456 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800457 ([['ID', 'a']], [['Constant', 'int', '1'], ['Constant', 'int', '2']]),
eli.bendersky9f481562010-10-30 15:50:47 +0200458 ([['ID', 'b'], ['Constant', 'int', '0']], ['ID', 't'])])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800459
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300460 def test_enums(self):
461 e1 = "enum mycolor op;"
462 e1_type = self.parse(e1).ext[0].type.type
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800463
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300464 self.assertTrue(isinstance(e1_type, Enum))
465 self.assertEqual(e1_type.name, 'mycolor')
466 self.assertEqual(e1_type.values, None)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800467
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300468 e2 = "enum mysize {large=20, small, medium} shoes;"
469 e2_type = self.parse(e2).ext[0].type.type
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800470
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300471 self.assertTrue(isinstance(e2_type, Enum))
472 self.assertEqual(e2_type.name, 'mysize')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800473
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300474 e2_elist = e2_type.values
475 self.assertTrue(isinstance(e2_elist, EnumeratorList))
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800476
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300477 for e2_eval in e2_elist.enumerators:
478 self.assertTrue(isinstance(e2_eval, Enumerator))
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800479
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300480 self.assertEqual(e2_elist.enumerators[0].name, 'large')
481 self.assertEqual(e2_elist.enumerators[0].value.value, '20')
482 self.assertEqual(e2_elist.enumerators[2].name, 'medium')
483 self.assertEqual(e2_elist.enumerators[2].value, None)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800484
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300485 # enum with trailing comma (C99 feature)
486 e3 = """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800487 enum
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300488 {
489 red,
490 blue,
491 green,
492 } color;
493 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800494
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300495 e3_type = self.parse(e3).ext[0].type.type
496 self.assertTrue(isinstance(e3_type, Enum))
497 e3_elist = e3_type.values
498 self.assertTrue(isinstance(e3_elist, EnumeratorList))
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800499
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300500 for e3_eval in e3_elist.enumerators:
501 self.assertTrue(isinstance(e3_eval, Enumerator))
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800502
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300503 self.assertEqual(e3_elist.enumerators[0].name, 'red')
504 self.assertEqual(e3_elist.enumerators[0].value, None)
505 self.assertEqual(e3_elist.enumerators[1].name, 'blue')
506 self.assertEqual(e3_elist.enumerators[2].name, 'green')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800507
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300508 def test_typedef(self):
509 # without typedef, error
510 s1 = """
511 node k;
512 """
513 self.assertRaises(ParseError, self.parse, s1)
514
515 # now with typedef, works
516 s2 = """
517 typedef void* node;
518 node k;
519 """
520 ps2 = self.parse(s2)
521 self.assertEqual(expand_decl(ps2.ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800522 ['Typedef', 'node',
523 ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300524 ['TypeDecl', ['IdentifierType', ['void']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800525
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300526 self.assertEqual(expand_decl(ps2.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800527 ['Decl', 'k',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300528 ['TypeDecl', ['IdentifierType', ['node']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800529
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300530 s3 = """
531 typedef int T;
532 typedef T *pT;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800533
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300534 pT aa, bb;
535 """
536 ps3 = self.parse(s3)
537 self.assertEqual(expand_decl(ps3.ext[3]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800538 ['Decl', 'bb',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300539 ['TypeDecl', ['IdentifierType', ['pT']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800540
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300541 s4 = '''
542 typedef char* __builtin_va_list;
543 typedef __builtin_va_list __gnuc_va_list;
544 '''
545 ps4 = self.parse(s4)
546 self.assertEqual(expand_decl(ps4.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800547 ['Typedef', '__gnuc_va_list',
548 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300549 ['IdentifierType', ['__builtin_va_list']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800550
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300551 s5 = '''typedef struct tagHash Hash;'''
552 ps5 = self.parse(s5)
553 self.assertEqual(expand_decl(ps5.ext[0]),
554 ['Typedef', 'Hash', ['TypeDecl', ['Struct', 'tagHash', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800555
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300556 def test_struct_union(self):
557 s1 = """
558 struct {
559 int id;
560 char* name;
561 } joe;
562 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800563
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300564 self.assertEqual(expand_decl(self.parse(s1).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800565 ['Decl', 'joe',
566 ['TypeDecl', ['Struct', None,
567 [ ['Decl', 'id',
568 ['TypeDecl',
569 ['IdentifierType', ['int']]]],
570 ['Decl', 'name',
571 ['PtrDecl',
572 ['TypeDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300573 ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800574
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300575 s2 = """
576 struct node p;
577 """
578 self.assertEqual(expand_decl(self.parse(s2).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800579 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300580 ['TypeDecl', ['Struct', 'node', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800581
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300582 s21 = """
583 union pri ra;
584 """
585 self.assertEqual(expand_decl(self.parse(s21).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800586 ['Decl', 'ra',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300587 ['TypeDecl', ['Union', 'pri', []]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800588
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300589 s3 = """
590 struct node* p;
591 """
592 self.assertEqual(expand_decl(self.parse(s3).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800593 ['Decl', 'p',
594 ['PtrDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300595 ['TypeDecl', ['Struct', 'node', []]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800596
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300597 s4 = """
598 struct node;
599 """
600 self.assertEqual(expand_decl(self.parse(s4).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800601 ['Decl', None,
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300602 ['Struct', 'node', []]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800603
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300604 s5 = """
605 union
606 {
607 struct
608 {
609 int type;
610 } n;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800611
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300612 struct
613 {
614 int type;
615 int intnode;
616 } ni;
617 } u;
618 """
619 self.assertEqual(expand_decl(self.parse(s5).ext[0]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800620 ['Decl', 'u',
621 ['TypeDecl',
622 ['Union', None,
623 [['Decl', 'n',
624 ['TypeDecl',
625 ['Struct', None,
626 [['Decl', 'type',
627 ['TypeDecl', ['IdentifierType', ['int']]]]]]]],
628 ['Decl', 'ni',
629 ['TypeDecl',
630 ['Struct', None,
631 [['Decl', 'type',
632 ['TypeDecl', ['IdentifierType', ['int']]]],
633 ['Decl', 'intnode',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300634 ['TypeDecl', ['IdentifierType', ['int']]]]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800635
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300636 s6 = """
637 typedef struct foo_tag
638 {
639 void* data;
640 } foo, *pfoo;
641 """
642 s6_ast = self.parse(s6)
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800643
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300644 self.assertEqual(expand_decl(s6_ast.ext[0]),
645 ['Typedef', 'foo',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800646 ['TypeDecl',
647 ['Struct', 'foo_tag',
648 [['Decl', 'data',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300649 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['void']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800650
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300651 self.assertEqual(expand_decl(s6_ast.ext[1]),
652 ['Typedef', 'pfoo',
653 ['PtrDecl',
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800654 ['TypeDecl',
655 ['Struct', 'foo_tag',
656 [['Decl', 'data',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300657 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['void']]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800658
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300659 s7 = r"""
660 struct _on_exit_args {
661 void * _fnargs[32];
662 void * _dso_handle[32];
663
664 long _fntypes;
665 #line 77 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
666
667 long _is_cxa;
668 };
669 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800670
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300671 s7_ast = self.parse(s7, filename='test.c')
672 self.assert_coord(s7_ast.ext[0].type.decls[2], 6, 'test.c')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800673 self.assert_coord(s7_ast.ext[0].type.decls[3], 78,
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300674 r'D:\eli\cpp_stuff\libc_include/sys/reent.h')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800675
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300676 s8 = """
677 typedef enum tagReturnCode {SUCCESS, FAIL} ReturnCode;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800678
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300679 typedef struct tagEntry
680 {
681 char* key;
682 char* value;
683 } Entry;
684
685
686 typedef struct tagNode
687 {
688 Entry* entry;
689
690 struct tagNode* next;
691 } Node;
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800692
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300693 typedef struct tagHash
694 {
695 unsigned int table_size;
696
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800697 Node** heads;
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300698
699 } Hash;
700 """
701 s8_ast = self.parse(s8)
702 self.assertEqual(expand_decl(s8_ast.ext[3]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800703 ['Typedef', 'Hash',
704 ['TypeDecl', ['Struct', 'tagHash',
705 [['Decl', 'table_size',
706 ['TypeDecl', ['IdentifierType', ['unsigned', 'int']]]],
707 ['Decl', 'heads',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300708 ['PtrDecl', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['Node']]]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800709
eli.bendersky697ecc52011-02-10 07:05:13 +0200710 def test_anonymous_struct_union(self):
711 s1 = """
712 union
713 {
714 union
715 {
716 int i;
717 long l;
718 };
719
720 struct
721 {
722 int type;
723 int intnode;
724 };
725 } u;
726 """
727
728 self.assertEqual(expand_decl(self.parse(s1).ext[0]),
729 ['Decl', 'u',
730 ['TypeDecl',
731 ['Union', None,
732 [['Decl', None,
733 ['Union', None,
734 [['Decl', 'i',
735 ['TypeDecl',
736 ['IdentifierType', ['int']]]],
737 ['Decl', 'l',
738 ['TypeDecl',
739 ['IdentifierType', ['long']]]]]]],
740 ['Decl', None,
741 ['Struct', None,
742 [['Decl', 'type',
743 ['TypeDecl',
744 ['IdentifierType', ['int']]]],
745 ['Decl', 'intnode',
746 ['TypeDecl',
747 ['IdentifierType', ['int']]]]]]]]]]])
748
749 s2 = """
750 struct
751 {
752 int i;
753 union
754 {
755 int id;
756 char* name;
757 };
758 float f;
759 } joe;
760 """
761
762 self.assertEqual(expand_decl(self.parse(s2).ext[0]),
763 ['Decl', 'joe',
764 ['TypeDecl',
765 ['Struct', None,
766 [['Decl', 'i',
767 ['TypeDecl',
768 ['IdentifierType', ['int']]]],
769 ['Decl', None,
770 ['Union', None,
771 [['Decl', 'id',
772 ['TypeDecl',
773 ['IdentifierType', ['int']]]],
774 ['Decl', 'name',
775 ['PtrDecl',
776 ['TypeDecl',
777 ['IdentifierType', ['char']]]]]]]],
778 ['Decl', 'f',
779 ['TypeDecl',
780 ['IdentifierType', ['float']]]]]]]])
781
782 # ISO/IEC 9899:201x Commitee Draft 2010-11-16, N1539
783 # section 6.7.2.1, par. 19, example 1
784 s3 = """
785 struct v {
786 union {
787 struct { int i, j; };
788 struct { long k, l; } w;
789 };
790 int m;
791 } v1;
792 """
793
794 self.assertEqual(expand_decl(self.parse(s3).ext[0]),
795 ['Decl', 'v1',
796 ['TypeDecl',
797 ['Struct', 'v',
798 [['Decl', None,
799 ['Union', None,
800 [['Decl', None,
801 ['Struct', None,
802 [['Decl', 'i',
803 ['TypeDecl',
804 ['IdentifierType', ['int']]]],
805 ['Decl', 'j',
806 ['TypeDecl',
807 ['IdentifierType', ['int']]]]]]],
808 ['Decl', 'w',
809 ['TypeDecl',
810 ['Struct', None,
811 [['Decl', 'k',
812 ['TypeDecl',
813 ['IdentifierType', ['long']]]],
814 ['Decl', 'l',
815 ['TypeDecl',
816 ['IdentifierType', ['long']]]]]]]]]]],
817 ['Decl', 'm',
818 ['TypeDecl',
819 ['IdentifierType', ['int']]]]]]]])
820
eli.benderskydce29a02011-02-10 07:55:00 +0200821 s4 = """
822 struct v {
823 int i;
824 float;
825 } v2;"""
eli.bendersky6b011792011-06-22 17:50:56 +0300826 # just make sure this doesn't raise ParseError
827 self.parse(s4)
eli.benderskydce29a02011-02-10 07:55:00 +0200828
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400829 def test_struct_members_namespace(self):
Eli Bendersky4d969b32013-07-13 06:07:07 -0700830 """ Tests that structure/union member names reside in a separate
831 namespace and can be named after existing types.
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400832 """
833 s1 = """
834 typedef int Name;
835 typedef Name NameArray[10];
836
837 struct {
838 Name Name;
839 Name NameArray[3];
840 } sye;
841
842 void main(void)
843 {
844 sye.Name = 1;
845 }
846 """
847
848 s1_ast = self.parse(s1)
849 self.assertEqual(expand_decl(s1_ast.ext[2]),
850 ['Decl', 'sye',
851 ['TypeDecl', ['Struct', None,
852 [ ['Decl', 'Name',
853 ['TypeDecl',
854 ['IdentifierType', ['Name']]]],
855 ['Decl', 'NameArray',
856 ['ArrayDecl', '3',
857 ['TypeDecl', ['IdentifierType', ['Name']]]]]]]]])
858 self.assertEqual(s1_ast.ext[3].body.block_items[0].lvalue.field.name, 'Name')
859
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200860 def test_struct_bitfields(self):
eli.bendersky38ed9a92010-10-09 09:29:59 +0200861 # a struct with two bitfields, one unnamed
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200862 s1 = """
863 struct {
864 int k:6;
865 int :2;
866 } joe;
867 """
868
869 parsed_struct = self.parse(s1).ext[0]
870
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800871 # We can see here the name of the decl for the unnamed bitfield is
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200872 # None, but expand_decl doesn't show bitfield widths
873 # ...
874 self.assertEqual(expand_decl(parsed_struct),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800875 ['Decl', 'joe',
876 ['TypeDecl', ['Struct', None,
877 [ ['Decl', 'k',
878 ['TypeDecl',
879 ['IdentifierType', ['int']]]],
880 ['Decl', None,
881 ['TypeDecl',
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200882 ['IdentifierType', ['int']]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800883
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200884 # ...
885 # so we test them manually
886 self.assertEqual(parsed_struct.type.type.decls[0].bitsize.value, '6')
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800887 self.assertEqual(parsed_struct.type.type.decls[1].bitsize.value, '2')
888
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300889 def test_tags_namespace(self):
890 """ Tests that the tags of structs/unions/enums reside in a separate namespace and
891 can be named after existing types.
892 """
893 s1 = """
894 typedef int tagEntry;
895
896 struct tagEntry
897 {
898 char* key;
899 char* value;
900 } Entry;
901 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800902
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300903 s1_ast = self.parse(s1)
904 self.assertEqual(expand_decl(s1_ast.ext[1]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800905 ['Decl', 'Entry',
906 ['TypeDecl', ['Struct', 'tagEntry',
907 [['Decl', 'key',
908 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
909 ['Decl', 'value',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300910 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800911
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300912 s2 = """
913 struct tagEntry;
914
915 typedef struct tagEntry tagEntry;
916
917 struct tagEntry
918 {
919 char* key;
920 char* value;
921 } Entry;
922 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800923
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300924 s2_ast = self.parse(s2)
925 self.assertEqual(expand_decl(s2_ast.ext[2]),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800926 ['Decl', 'Entry',
927 ['TypeDecl', ['Struct', 'tagEntry',
928 [['Decl', 'key',
929 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
930 ['Decl', 'value',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300931 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800932
933 s3 = """
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300934 typedef int mytag;
935
936 enum mytag {ABC, CDE};
937 enum mytag joe;
938 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800939
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300940 s3_type = self.parse(s3).ext[1].type
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800941
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300942 self.assertTrue(isinstance(s3_type, Enum))
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800943 self.assertEqual(s3_type.name, 'mytag')
944
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300945 def test_multi_decls(self):
946 d1 = 'int a, b;'
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800947
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300948 self.assertEqual(self.get_decl(d1, 0),
949 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
950 self.assertEqual(self.get_decl(d1, 1),
951 ['Decl', 'b', ['TypeDecl', ['IdentifierType', ['int']]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800952
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300953 d2 = 'char* p, notp, ar[4];'
954 self.assertEqual(self.get_decl(d2, 0),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800955 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300956 ['PtrDecl',
957 ['TypeDecl', ['IdentifierType', ['char']]]]])
958 self.assertEqual(self.get_decl(d2, 1),
959 ['Decl', 'notp', ['TypeDecl', ['IdentifierType', ['char']]]])
960 self.assertEqual(self.get_decl(d2, 2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800961 ['Decl', 'ar',
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300962 ['ArrayDecl', '4',
963 ['TypeDecl', ['IdentifierType', ['char']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800964
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300965 def test_invalid_multiple_types_error(self):
966 bad = [
967 'int enum {ab, cd} fubr;',
968 'enum kid char brbr;']
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800969
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300970 for b in bad:
Eli Bendersky86f2eee2013-01-18 06:04:01 -0800971 self.assertRaises(ParseError, self.parse, b)
Eli Bendersky9dadc3f2012-07-06 15:53:53 +0300972
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400973 def test_duplicate_typedef(self):
974 """ Tests that redeclarations of existing types are parsed correctly.
975 This is non-standard, but allowed by many compilers.
976 """
977 d1 = '''
Eli Bendersky9dadc3f2012-07-06 15:53:53 +0300978 typedef int numbertype;
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400979 typedef int numbertype;
Eli Bendersky9dadc3f2012-07-06 15:53:53 +0300980 '''
Sye van der Veen9ec6c422013-07-11 09:10:38 -0400981
982 self.assertEqual(self.get_decl(d1, 0),
983 ['Typedef', 'numbertype',
984 ['TypeDecl', ['IdentifierType', ['int']]]])
985 self.assertEqual(self.get_decl(d1, 1),
986 ['Typedef', 'numbertype',
987 ['TypeDecl', ['IdentifierType', ['int']]]])
988
989 d2 = '''
990 typedef int (*funcptr)(int x);
991 typedef int (*funcptr)(int x);
992 '''
993 self.assertEqual(self.get_decl(d2, 0),
994 ['Typedef', 'funcptr',
995 ['PtrDecl', ['FuncDecl',
996 [['Decl', 'x', ['TypeDecl', ['IdentifierType', ['int']]]]],
997 ['TypeDecl', ['IdentifierType', ['int']]]]]])
998 self.assertEqual(self.get_decl(d2, 1),
999 ['Typedef', 'funcptr',
1000 ['PtrDecl', ['FuncDecl',
1001 [['Decl', 'x', ['TypeDecl', ['IdentifierType', ['int']]]]],
1002 ['TypeDecl', ['IdentifierType', ['int']]]]]])
1003
1004 d3 = '''
1005 typedef int numberarray[5];
1006 typedef int numberarray[5];
1007 '''
1008 self.assertEqual(self.get_decl(d3, 0),
1009 ['Typedef', 'numberarray',
1010 ['ArrayDecl', '5',
1011 ['TypeDecl', ['IdentifierType', ['int']]]]])
1012 self.assertEqual(self.get_decl(d3, 1),
1013 ['Typedef', 'numberarray',
1014 ['ArrayDecl', '5',
1015 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001016
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001017 def test_decl_inits(self):
1018 d1 = 'int a = 16;'
eli.benderskyf890a862010-10-30 12:13:23 +02001019 #~ self.parse(d1).show()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001020 self.assertEqual(self.get_decl(d1),
1021 ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
1022 self.assertEqual(self.get_decl_init(d1),
1023 ['Constant', 'int', '16'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001024
Eli Bendersky3b1b08d2012-06-15 12:37:54 +03001025 d1_1 = 'float f = 0xEF.56p1;'
1026 self.assertEqual(self.get_decl_init(d1_1),
1027 ['Constant', 'float', '0xEF.56p1'])
1028
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001029 d2 = 'long ar[] = {7, 8, 9};'
eli.benderskyf890a862010-10-30 12:13:23 +02001030 #~ self.parse(d2).show()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001031 self.assertEqual(self.get_decl(d2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001032 ['Decl', 'ar',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001033 ['ArrayDecl', '',
1034 ['TypeDecl', ['IdentifierType', ['long']]]]])
1035 self.assertEqual(self.get_decl_init(d2),
1036 [ ['Constant', 'int', '7'],
1037 ['Constant', 'int', '8'],
eli.benderskyf890a862010-10-30 12:13:23 +02001038 ['Constant', 'int', '9']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001039
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001040 d3 = 'char p = j;'
1041 self.assertEqual(self.get_decl(d3),
1042 ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['char']]]])
1043 self.assertEqual(self.get_decl_init(d3),
1044 ['ID', 'j'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001045
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001046 d4 = "char x = 'c', *p = {0, 1, 2, {4, 5}, 6};"
1047 self.assertEqual(self.get_decl(d4, 0),
1048 ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['char']]]])
1049 self.assertEqual(self.get_decl_init(d4, 0),
1050 ['Constant', 'char', "'c'"])
1051 self.assertEqual(self.get_decl(d4, 1),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001052 ['Decl', 'p',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001053 ['PtrDecl',
1054 ['TypeDecl', ['IdentifierType', ['char']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001055
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001056 self.assertEqual(self.get_decl_init(d4, 1),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001057 [ ['Constant', 'int', '0'],
1058 ['Constant', 'int', '1'],
1059 ['Constant', 'int', '2'],
1060 [['Constant', 'int', '4'],
1061 ['Constant', 'int', '5']],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001062 ['Constant', 'int', '6']])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001063
eli.benderskyf890a862010-10-30 12:13:23 +02001064 def test_decl_named_inits(self):
1065 d1 = 'int a = {.k = 16};'
1066 self.assertEqual(self.get_decl_init(d1),
1067 [( [['ID', 'k']],
1068 ['Constant', 'int', '16'])])
1069
1070 d2 = 'int a = { [0].a = {1}, [1].a[0] = 2 };'
1071 self.assertEqual(self.get_decl_init(d2),
1072 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001073 ([['Constant', 'int', '0'], ['ID', 'a']],
1074 [['Constant', 'int', '1']]),
1075 ([['Constant', 'int', '1'], ['ID', 'a'], ['Constant', 'int', '0']],
eli.benderskyf890a862010-10-30 12:13:23 +02001076 ['Constant', 'int', '2'])])
1077
1078 d3 = 'int a = { .a = 1, .c = 3, 4, .b = 5};'
1079 self.assertEqual(self.get_decl_init(d3),
1080 [
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001081 ([['ID', 'a']], ['Constant', 'int', '1']),
1082 ([['ID', 'c']], ['Constant', 'int', '3']),
1083 ['Constant', 'int', '4'],
eli.benderskyf890a862010-10-30 12:13:23 +02001084 ([['ID', 'b']], ['Constant', 'int', '5'])])
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001085
1086 def test_function_definitions(self):
1087 def parse_fdef(str):
1088 return self.parse(str).ext[0]
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001089
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001090 def fdef_decl(fdef):
1091 return expand_decl(fdef.decl)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001092
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001093 f1 = parse_fdef('''
1094 int factorial(int p)
1095 {
1096 return 3;
1097 }
1098 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001099
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001100 self.assertEqual(fdef_decl(f1),
1101 ['Decl', 'factorial',
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001102 ['FuncDecl',
1103 [['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001104 ['TypeDecl', ['IdentifierType', ['int']]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001105
eli.benderskyef29ff92010-10-29 16:25:43 +02001106 self.assertEqual(type(f1.body.block_items[0]), Return)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001107
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001108 f2 = parse_fdef('''
1109 char* zzz(int p, char* c)
1110 {
1111 int a;
1112 char b;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001113
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001114 a = b + 2;
1115 return 3;
1116 }
1117 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001118
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001119 self.assertEqual(fdef_decl(f2),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001120 ['Decl', 'zzz',
1121 ['FuncDecl',
1122 [ ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]],
1123 ['Decl', 'c', ['PtrDecl',
1124 ['TypeDecl', ['IdentifierType', ['char']]]]]],
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001125 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001126
1127 self.assertEqual(list(map(type, f2.body.block_items)),
eli.benderskyef29ff92010-10-29 16:25:43 +02001128 [Decl, Decl, Assignment, Return])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001129
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001130 f3 = parse_fdef('''
1131 char* zzz(p, c)
1132 long p, *c;
1133 {
1134 int a;
1135 char b;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001136
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001137 a = b + 2;
1138 return 3;
1139 }
1140 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001141
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001142 self.assertEqual(fdef_decl(f3),
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001143 ['Decl', 'zzz',
1144 ['FuncDecl',
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001145 [ ['ID', 'p'],
1146 ['ID', 'c']],
1147 ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001148
1149 self.assertEqual(list(map(type, f3.body.block_items)),
eli.benderskyef29ff92010-10-29 16:25:43 +02001150 [Decl, Decl, Assignment, Return])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001151
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001152 self.assertEqual(expand_decl(f3.param_decls[0]),
1153 ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['long']]]])
1154 self.assertEqual(expand_decl(f3.param_decls[1]),
1155 ['Decl', 'c', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['long']]]]])
1156
Sye van der Veen51a46ec2013-06-10 12:56:15 -04001157 # function return values and parameters may not have type information
1158 f4 = parse_fdef('''
1159 que(p)
1160 {
1161 return 3;
1162 }
1163 ''')
1164
1165 self.assertEqual(fdef_decl(f4),
1166 ['Decl', 'que',
1167 ['FuncDecl',
1168 [['ID', 'p']],
1169 ['TypeDecl', ['IdentifierType', ['int']]]]])
1170
eli.bendersky71540662010-07-03 12:58:52 +02001171 def test_unified_string_literals(self):
1172 # simple string, for reference
1173 d1 = self.get_decl_init('char* s = "hello";')
1174 self.assertEqual(d1, ['Constant', 'string', '"hello"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001175
eli.bendersky71540662010-07-03 12:58:52 +02001176 d2 = self.get_decl_init('char* s = "hello" " world";')
1177 self.assertEqual(d2, ['Constant', 'string', '"hello world"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001178
eli.bendersky71540662010-07-03 12:58:52 +02001179 # the test case from issue 6
1180 d3 = self.parse(r'''
1181 int main() {
1182 fprintf(stderr,
1183 "Wrong Params?\n"
1184 "Usage:\n"
1185 "%s <binary_file_path>\n",
1186 argv[0]
1187 );
1188 }
1189 ''')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001190
eli.bendersky71540662010-07-03 12:58:52 +02001191 self.assertEqual(
eli.benderskyef29ff92010-10-29 16:25:43 +02001192 d3.ext[0].body.block_items[0].args.exprs[1].value,
eli.bendersky71540662010-07-03 12:58:52 +02001193 r'"Wrong Params?\nUsage:\n%s <binary_file_path>\n"')
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001194
eli.bendersky4a89f112010-07-05 06:02:03 +02001195 d4 = self.get_decl_init('char* s = "" "foobar";')
1196 self.assertEqual(d4, ['Constant', 'string', '"foobar"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001197
eli.bendersky4a89f112010-07-05 06:02:03 +02001198 d5 = self.get_decl_init(r'char* s = "foo\"" "bar";')
1199 self.assertEqual(d5, ['Constant', 'string', r'"foo\"bar"'])
eli.bendersky71540662010-07-03 12:58:52 +02001200
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001201 def test_inline_specifier(self):
eli.bendersky79d5cf62010-10-29 13:33:52 +02001202 ps2 = self.parse('static inline void inlinefoo(void);')
1203 self.assertEqual(ps2.ext[0].funcspec, ['inline'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001204
eli.bendersky2e907fa2010-10-29 15:51:07 +02001205 # variable length array
1206 def test_vla(self):
1207 ps2 = self.parse(r'''
1208 int main() {
1209 int size;
1210 int var[size = 5];
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001211
eli.bendersky2e907fa2010-10-29 15:51:07 +02001212 int var2[*];
1213 }
1214 ''')
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001215 self.assertTrue(isinstance(ps2.ext[0].body.block_items[1].type.dim, Assignment))
1216 self.assertTrue(isinstance(ps2.ext[0].body.block_items[2].type.dim, ID))
eli.bendersky79d5cf62010-10-29 13:33:52 +02001217
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001218
eli.bendersky85d2e732011-05-20 19:47:26 +03001219class TestCParser_whole_code(TestCParser_base):
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001220 """ Testing of parsing whole chunks of code.
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001221
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001222 Since I don't want to rely on the structure of ASTs too
1223 much, most of these tests are implemented with visitors.
1224 """
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001225 # A simple helper visitor that lists the values of all the
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001226 # Constant nodes it sees.
1227 #
1228 class ConstantVisitor(NodeVisitor):
1229 def __init__(self):
1230 self.values = []
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001231
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001232 def visit_Constant(self, node):
1233 self.values.append(node.value)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001234
1235 # This visitor counts the amount of references to the ID
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001236 # with the name provided to it in the constructor.
1237 #
1238 class IDNameCounter(NodeVisitor):
1239 def __init__(self, name):
1240 self.name = name
1241 self.nrefs = 0
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001242
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001243 def visit_ID(self, node):
1244 if node.name == self.name:
1245 self.nrefs += 1
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001246
1247 # Counts the amount of nodes of a given class
1248 #
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001249 class NodeKlassCounter(NodeVisitor):
1250 def __init__(self, node_klass):
1251 self.klass = node_klass
1252 self.n = 0
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001253
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001254 def generic_visit(self, node):
1255 if node.__class__ == self.klass:
1256 self.n += 1
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001257
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001258 NodeVisitor.generic_visit(self, node)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001259
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001260 def assert_all_Constants(self, code, constants):
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001261 """ Asserts that the list of all Constant values (by
1262 'preorder' appearance) in the chunk of code is as
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001263 given.
1264 """
eli.benderskyed890492010-06-25 08:25:55 +03001265 if isinstance(code, str):
1266 parsed = self.parse(code)
1267 else:
1268 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001269
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001270 cv = self.ConstantVisitor()
1271 cv.visit(parsed)
1272 self.assertEqual(cv.values, constants)
1273
1274 def assert_num_ID_refs(self, code, name, num):
1275 """ Asserts the number of references to the ID with
1276 the given name.
1277 """
1278 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 iv = self.IDNameCounter(name)
1284 iv.visit(parsed)
1285 self.assertEqual(iv.nrefs, num)
1286
1287 def assert_num_klass_nodes(self, code, klass, num):
1288 """ Asserts the amount of klass nodes in the code.
1289 """
1290 if isinstance(code, str):
1291 parsed = self.parse(code)
1292 else:
1293 parsed = code
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001294
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001295 cv = self.NodeKlassCounter(klass)
1296 cv.visit(parsed)
1297 self.assertEqual(cv.n, num)
1298
1299 def test_expressions(self):
1300 e1 = '''int k = (r + 10.0) >> 6 + 8 << (3 & 0x14);'''
1301 self.assert_all_Constants(e1, ['10.0', '6', '8', '3', '0x14'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001302
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001303 e2 = r'''char n = '\n', *prefix = "st_";'''
1304 self.assert_all_Constants(e2, [r"'\n'", '"st_"'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001305
Eli Bendersky09e22a62013-07-02 06:00:36 -07001306 s1 = r'''int main() {
1307 int i = 5, j = 6, k = 1;
1308 if ((i=j && k == 1) || k > j)
1309 printf("Hello, world\n");
1310 return 0;
1311 }'''
1312 ps1 = self.parse(s1)
1313 self.assert_all_Constants(ps1,
1314 ['5', '6', '1', '1', '"Hello, world\\n"', '0'])
1315 self.assert_num_ID_refs(ps1, 'i', 1)
1316 self.assert_num_ID_refs(ps1, 'j', 2)
1317
1318
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001319 def test_statements(self):
1320 s1 = r'''
1321 void foo(){
1322 if (sp == 1)
1323 if (optind >= argc ||
1324 argv[optind][0] != '-' || argv[optind][1] == '\0')
1325 return -1;
1326 else if (strcmp(argv[optind], "--") == 0) {
1327 optind++;
1328 return -1;
1329 }
1330 }
1331 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001332
1333 self.assert_all_Constants(s1,
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001334 ['1', '0', r"'-'", '1', r"'\0'", '1', r'"--"', '0', '1'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001335
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001336 ps1 = self.parse(s1)
1337 self.assert_num_ID_refs(ps1, 'argv', 3)
1338 self.assert_num_ID_refs(ps1, 'optind', 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001339
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001340 self.assert_num_klass_nodes(ps1, If, 3)
1341 self.assert_num_klass_nodes(ps1, Return, 2)
1342 self.assert_num_klass_nodes(ps1, FuncCall, 1) # strcmp
1343 self.assert_num_klass_nodes(ps1, BinaryOp, 7)
1344
1345 # In the following code, Hash and Node were defined as
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001346 # int to pacify the parser that sees they're used as
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001347 # types
1348 #
1349 s2 = r'''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001350 typedef int Hash, Node;
1351
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001352 void HashDestroy(Hash* hash)
1353 {
1354 unsigned int i;
1355
1356 if (hash == NULL)
1357 return;
1358
1359 for (i = 0; i < hash->table_size; ++i)
1360 {
1361 Node* temp = hash->heads[i];
1362
1363 while (temp != NULL)
1364 {
1365 Node* temp2 = temp;
1366
1367 free(temp->entry->key);
1368 free(temp->entry->value);
1369 free(temp->entry);
1370
1371 temp = temp->next;
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001372
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001373 free(temp2);
1374 }
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001375 }
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001376
1377 free(hash->heads);
1378 hash->heads = NULL;
1379
1380 free(hash);
1381 }
1382 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001383
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001384 ps2 = self.parse(s2)
1385 self.assert_num_klass_nodes(ps2, FuncCall, 6)
1386 self.assert_num_klass_nodes(ps2, FuncDef, 1)
1387 self.assert_num_klass_nodes(ps2, For, 1)
1388 self.assert_num_klass_nodes(ps2, While, 1)
1389 self.assert_num_klass_nodes(ps2, StructRef, 10)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001390
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001391 # declarations don't count
1392 self.assert_num_ID_refs(ps2, 'hash', 6)
1393 self.assert_num_ID_refs(ps2, 'i', 4)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001394
eli.benderskyed890492010-06-25 08:25:55 +03001395 s3 = r'''
1396 void x(void) {
1397 int a, b;
1398 if (a < b)
1399 do {
1400 a = 0;
1401 } while (0);
1402 else if (a == b) {
1403 a = 1;
1404 }
1405 }
1406 '''
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001407
eli.benderskyed890492010-06-25 08:25:55 +03001408 ps3 = self.parse(s3)
1409 self.assert_num_klass_nodes(ps3, DoWhile, 1)
1410 self.assert_num_ID_refs(ps3, 'a', 4)
1411 self.assert_all_Constants(ps3, ['0', '0', '1'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001412
eli.bendersky91c0aa32011-10-16 05:50:43 +02001413 def test_empty_statement(self):
1414 s1 = r'''
1415 void foo(void){
1416 ;
1417 return;
1418 }
1419 '''
1420 ps1 = self.parse(s1)
1421 self.assert_num_klass_nodes(ps1, EmptyStatement, 1)
1422 self.assert_num_klass_nodes(ps1, Return, 1)
eli.bendersky145890d2010-10-29 12:02:32 +02001423
Ben5cd3fd62012-02-03 06:02:40 +02001424 def test_switch_statement(self):
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001425 def assert_case_node(node, const_value):
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001426 self.assertTrue(isinstance(node, Case))
1427 self.assertTrue(isinstance(node.expr, Constant))
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001428 self.assertEqual(node.expr.value, const_value)
1429
1430 def assert_default_node(node):
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001431 self.assertTrue(isinstance(node, Default))
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001432
Ben5cd3fd62012-02-03 06:02:40 +02001433 s1 = r'''
1434 int foo(void) {
1435 switch (myvar) {
1436 case 10:
1437 k = 10;
1438 p = k + 1;
1439 return 10;
1440 case 20:
1441 case 30:
1442 return 20;
1443 default:
1444 break;
1445 }
1446 return 0;
1447 }
1448 '''
1449 ps1 = self.parse(s1)
Eli Bendersky12f0c9d2012-02-03 11:22:25 +02001450 switch = ps1.ext[0].body.block_items[0]
1451
1452 block = switch.stmt.block_items
1453 assert_case_node(block[0], '10')
1454 self.assertEqual(len(block[0].stmts), 3)
1455 assert_case_node(block[1], '20')
1456 self.assertEqual(len(block[1].stmts), 0)
1457 assert_case_node(block[2], '30')
1458 self.assertEqual(len(block[2].stmts), 1)
1459 assert_default_node(block[3])
1460
1461 s2 = r'''
1462 int foo(void) {
1463 switch (myvar) {
1464 default:
1465 joe = moe;
1466 return 10;
1467 case 10:
1468 case 20:
1469 case 30:
1470 case 40:
1471 break;
1472 }
1473 return 0;
1474 }
1475 '''
1476 ps2 = self.parse(s2)
1477 switch = ps2.ext[0].body.block_items[0]
1478
1479 block = switch.stmt.block_items
1480 assert_default_node(block[0])
1481 self.assertEqual(len(block[0].stmts), 2)
1482 assert_case_node(block[1], '10')
1483 self.assertEqual(len(block[1].stmts), 0)
1484 assert_case_node(block[2], '20')
1485 self.assertEqual(len(block[1].stmts), 0)
1486 assert_case_node(block[3], '30')
1487 self.assertEqual(len(block[1].stmts), 0)
1488 assert_case_node(block[4], '40')
1489 self.assertEqual(len(block[4].stmts), 1)
Ben5cd3fd62012-02-03 06:02:40 +02001490
eli.bendersky145890d2010-10-29 12:02:32 +02001491 def test_for_statement(self):
1492 s2 = r'''
1493 void x(void)
1494 {
1495 int i;
1496 for (i = 0; i < 5; ++i) {
1497 x = 50;
1498 }
1499 }
1500 '''
1501 ps2 = self.parse(s2)
1502 self.assert_num_klass_nodes(ps2, For, 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001503 # here there are 3 refs to 'i' since the declaration doesn't count as
eli.bendersky145890d2010-10-29 12:02:32 +02001504 # a ref in the visitor
1505 #
1506 self.assert_num_ID_refs(ps2, 'i', 3)
Eli Bendersky4476d092012-12-25 14:07:57 -08001507
eli.bendersky145890d2010-10-29 12:02:32 +02001508 s3 = r'''
1509 void x(void)
1510 {
1511 for (int i = 0; i < 5; ++i) {
1512 x = 50;
1513 }
1514 }
1515 '''
1516 ps3 = self.parse(s3)
eli.bendersky145890d2010-10-29 12:02:32 +02001517 self.assert_num_klass_nodes(ps3, For, 1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001518 # here there are 2 refs to 'i' since the declaration doesn't count as
eli.bendersky145890d2010-10-29 12:02:32 +02001519 # a ref in the visitor
1520 #
1521 self.assert_num_ID_refs(ps3, 'i', 2)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001522
Eli Bendersky4476d092012-12-25 14:07:57 -08001523 s4 = r'''
1524 void x(void) {
1525 for (int i = 0;;)
1526 i;
1527 }
1528 '''
1529 ps4 = self.parse(s4)
1530 self.assert_num_ID_refs(ps4, 'i', 1)
1531
Eli Benderskyd0973782012-01-19 08:09:33 +02001532 def _open_c_file(self, name):
1533 """ Find a c file by name, taking into account the current dir can be
1534 in a couple of typical places
1535 """
Stefano Riveraebaf5922013-08-08 09:45:26 +02001536 testdir = os.path.dirname(__file__)
1537 name = os.path.join(testdir, 'c_files', name)
1538 assert os.path.exists(name)
1539 return open(name, 'rU')
Eli Benderskyd0973782012-01-19 08:09:33 +02001540
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001541 def test_whole_file(self):
1542 # See how pycparser handles a whole, real C file.
1543 #
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001544 with self._open_c_file('memmgr_with_h.c') as f:
1545 code = f.read()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001546 p = self.parse(code)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001547
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001548 self.assert_num_klass_nodes(p, FuncDef, 5)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001549
1550 # each FuncDef also has a FuncDecl. 4 declarations
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001551 # + 5 definitions, overall 9
1552 self.assert_num_klass_nodes(p, FuncDecl, 9)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001553
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001554 self.assert_num_klass_nodes(p, Typedef, 4)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001555
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001556 self.assertEqual(p.ext[4].coord.line, 88)
1557 self.assertEqual(p.ext[4].coord.file, "./memmgr.h")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001558
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001559 self.assertEqual(p.ext[6].coord.line, 10)
1560 self.assertEqual(p.ext[6].coord.file, "memmgr.c")
1561
1562 def test_whole_file_with_stdio(self):
1563 # Parse a whole file with stdio.h included by cpp
1564 #
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001565 with self._open_c_file('cppd_with_stdio_h.c') as f:
1566 code = f.read()
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001567 p = self.parse(code)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001568
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001569 self.assertTrue(isinstance(p.ext[0], Typedef))
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001570 self.assertEqual(p.ext[0].coord.line, 213)
1571 self.assertEqual(p.ext[0].coord.file, "D:\eli\cpp_stuff\libc_include/stddef.h")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001572
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001573 self.assertTrue(isinstance(p.ext[-1], FuncDef))
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001574 self.assertEqual(p.ext[-1].coord.line, 15)
1575 self.assertEqual(p.ext[-1].coord.file, "example_c_file.c")
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001576
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001577 self.assertTrue(isinstance(p.ext[-8], Typedef))
1578 self.assertTrue(isinstance(p.ext[-8].type, TypeDecl))
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001579 self.assertEqual(p.ext[-8].name, 'cookie_io_functions_t')
eli.bendersky85d2e732011-05-20 19:47:26 +03001580
1581
1582class TestCParser_typenames(TestCParser_base):
1583 """ Test issues related to the typedef-name problem.
1584 """
1585 def test_innerscope_typedef(self):
1586 # should fail since TT is not a type in bar
1587 s1 = r'''
1588 void foo() {
1589 typedef char TT;
1590 TT x;
1591 }
1592 void bar() {
1593 TT y;
1594 }
1595 '''
1596 self.assertRaises(ParseError, self.parse, s1)
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001597
eli.bendersky85d2e732011-05-20 19:47:26 +03001598 # should succeed since TT is not a type in bar
1599 s2 = r'''
1600 void foo() {
1601 typedef char TT;
1602 TT x;
1603 }
1604 void bar() {
1605 unsigned TT;
1606 }
1607 '''
Eli Benderskya1da7fd2012-07-06 15:48:57 +03001608 self.assertTrue(isinstance(self.parse(s2), FileAST))
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001609
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001610 def test_innerscope_reuse_typedef_name(self):
1611 # identifiers can be reused in inner scopes; the original should be
1612 # restored at the end of the block
1613 s1 = r'''
1614 typedef char TT;
1615 void foo(void) {
1616 unsigned TT;
1617 TT = 10;
1618 }
1619 TT x = 5;
1620 '''
1621 s1_ast = self.parse(s1)
1622 self.assertEqual(expand_decl(s1_ast.ext[1].body.block_items[0]),
1623 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
Eli Bendersky3877c4c2013-07-13 06:54:04 -07001624 self.assertEqual(expand_decl(s1_ast.ext[2]),
1625 ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['TT']]]])
eli.bendersky85d2e732011-05-20 19:47:26 +03001626
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001627 # this should be recognized even with an initializer
1628 s2 = r'''
1629 typedef char TT;
1630 void foo(void) {
1631 unsigned TT = 10;
1632 }
1633 '''
1634 s2_ast = self.parse(s2)
1635 self.assertEqual(expand_decl(s2_ast.ext[1].body.block_items[0]),
1636 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1637
1638 # before the second local variable, TT is a type; after, it's a
1639 # variable
1640 s3 = r'''
1641 typedef char TT;
1642 void foo(void) {
1643 TT tt = sizeof(TT);
1644 unsigned TT = 10;
1645 }
1646 '''
1647 s3_ast = self.parse(s3)
1648 self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[0]),
1649 ['Decl', 'tt', ['TypeDecl', ['IdentifierType', ['TT']]]])
1650 self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[1]),
1651 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1652
1653 # a variable and its type can even share the same name
1654 s4 = r'''
1655 typedef char TT;
1656 void foo(void) {
1657 TT TT = sizeof(TT);
1658 unsigned uu = TT * 2;
1659 }
1660 '''
1661 s4_ast = self.parse(s4)
1662 self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[0]),
1663 ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['TT']]]])
1664 self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[1]),
1665 ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
1666
1667 # ensure an error is raised if a type, redeclared as a variable, is
1668 # used as a type
1669 s5 = r'''
1670 typedef char TT;
1671 void foo(void) {
1672 unsigned TT = 10;
1673 TT erroneous = 20;
1674 }
1675 '''
1676 self.assertRaises(ParseError, self.parse, s5)
1677
1678 def test_parameter_reuse_typedef_name(self):
1679 # identifiers can be reused as parameter names; parameter name scope
1680 # begins and ends with the function body; it's important that TT is
Eli Bendersky4d969b32013-07-13 06:07:07 -07001681 # used immediately before the LBRACE or after the RBRACE, to test
1682 # a corner case
Sye van der Veen9ec6c422013-07-11 09:10:38 -04001683 s1 = r'''
1684 typedef char TT;
1685 void foo(unsigned TT, TT bar) {
1686 TT = 10;
1687 }
1688 TT x = 5;
1689 '''
1690 s1_ast = self.parse(s1)
1691 self.assertEqual(expand_decl(s1_ast.ext[1].decl),
1692 ['Decl', 'foo',
1693 ['FuncDecl',
1694 [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
1695 ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
1696 ['TypeDecl', ['IdentifierType', ['void']]]]])
1697
1698 # the scope of a parameter name in a function declaration ends at the
1699 # end of the declaration...so it is effectively never used; it's
1700 # important that TT is used immediately after the declaration, to
1701 # test a corner case
1702 s2 = r'''
1703 typedef char TT;
1704 void foo(unsigned TT, TT bar);
1705 TT x = 5;
1706 '''
1707 s2_ast = self.parse(s2)
1708 self.assertEqual(expand_decl(s2_ast.ext[1]),
1709 ['Decl', 'foo',
1710 ['FuncDecl',
1711 [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
1712 ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
1713 ['TypeDecl', ['IdentifierType', ['void']]]]])
1714
1715 # ensure an error is raised if a type, redeclared as a parameter, is
1716 # used as a type
1717 s3 = r'''
1718 typedef char TT;
1719 void foo(unsigned TT, TT bar) {
1720 TT erroneous = 20;
1721 }
1722 '''
1723 self.assertRaises(ParseError, self.parse, s3)
1724
1725 def test_nested_function_decls(self):
1726 # parameter names of nested function declarations must not escape into
1727 # the top-level function _definition's_ scope; the following must
1728 # succeed because TT is still a typedef inside foo's body
1729 s1 = r'''
1730 typedef char TT;
1731 void foo(unsigned bar(int TT)) {
1732 TT x = 10;
1733 }
1734 '''
1735 self.assertTrue(isinstance(self.parse(s1), FileAST))
1736
1737 def test_samescope_reuse_name(self):
1738 # a typedef name cannot be reused as an object name in the same scope
1739 s1 = r'''
1740 typedef char TT;
1741 char TT = 5;
1742 '''
1743 self.assertRaises(ParseError, self.parse, s1)
1744
1745 # ...and vice-versa
1746 s2 = r'''
1747 char TT = 5;
1748 typedef char TT;
1749 '''
1750 self.assertRaises(ParseError, self.parse, s2)
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001751
1752if __name__ == '__main__':
1753 #~ suite = unittest.TestLoader().loadTestsFromNames(
1754 #~ ['test_c_parser.TestCParser_fundamentals.test_typedef'])
Eli Bendersky86f2eee2013-01-18 06:04:01 -08001755
Eli Bendersky3921e8e2010-05-21 09:05:39 +03001756 #~ unittest.TextTestRunner(verbosity=2).run(suite)
1757 unittest.main()