adlint 1.4.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +413 -5
- data/MANIFEST +6 -0
- data/NEWS +43 -4
- data/etc/mesg.d/en_US/messages.yml +1 -1
- data/etc/mesg.d/ja_JP/messages.yml +1 -1
- data/lib/adlint/c.rb +1 -0
- data/lib/adlint/c/enum.rb +52 -0
- data/lib/adlint/c/expr.rb +43 -102
- data/lib/adlint/c/interp.rb +1 -1
- data/lib/adlint/c/mediator.rb +1 -0
- data/lib/adlint/c/message.rb +831 -49
- data/lib/adlint/c/message_shima.rb +236 -0
- data/lib/adlint/c/metric.rb +9 -0
- data/lib/adlint/c/object.rb +37 -32
- data/lib/adlint/c/parser.rb +7 -7
- data/lib/adlint/c/parser.y +7 -7
- data/lib/adlint/c/phase.rb +21 -0
- data/lib/adlint/c/syntax.rb +11 -4
- data/lib/adlint/c/type.rb +1 -1
- data/lib/adlint/cpp.rb +1 -0
- data/lib/adlint/cpp/asm.rb +73 -0
- data/lib/adlint/cpp/message.rb +13 -0
- data/lib/adlint/cpp/message_shima.rb +36 -0
- data/lib/adlint/cpp/phase.rb +3 -0
- data/lib/adlint/cpp/source.rb +9 -0
- data/lib/adlint/version.rb +3 -3
- data/share/demo/Makefile +4 -0
- data/share/demo/bad_conv/bad_conv.c +12 -0
- data/share/demo/bad_enum/bad_enum.c +48 -2
- data/share/demo/bad_label/bad_label.c +26 -0
- data/share/demo/bad_macro/bad_macro.c +3 -0
- data/share/demo/implicit_conv/implicit_conv.c +1 -0
- data/share/demo/inline_asm/inline_asm.c +18 -0
- data/share/demo/invalid_call/invalid_call.c +5 -0
- data/share/demo/multi_decl/multi_decl_1.c +30 -0
- data/share/demo/overflow/overflow.c +3 -3
- data/share/demo/redundant_select/redundant_select.c +25 -0
- data/share/demo/reserved_ident/reserved_ident.c +98 -0
- data/share/doc/developers_guide_ja.html +3 -3
- data/share/doc/developers_guide_ja.texi +1 -1
- data/share/doc/users_guide_en.html +234 -126
- data/share/doc/users_guide_en.texi +207 -98
- data/share/doc/users_guide_ja.html +247 -156
- data/share/doc/users_guide_ja.texi +221 -130
- data/share/sample/vim-7.3/adlint/xxd/adlint_traits.yml +1 -1
- metadata +8 -2
@@ -35,6 +35,53 @@ require "adlint/message"
|
|
35
35
|
module AdLint #:nodoc:
|
36
36
|
module C #:nodoc:
|
37
37
|
|
38
|
+
class W0573 < PassiveMessageDetection
|
39
|
+
def initialize(context)
|
40
|
+
super
|
41
|
+
interp = context[:c_interpreter]
|
42
|
+
interp.on_function_call_expr_evaled += method(:check)
|
43
|
+
@environ = interp.environment
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def check(function_call_expression, function, arg_variables,
|
48
|
+
result_variable)
|
49
|
+
if function.named? && function.name =~ /\A.*scanf\z/
|
50
|
+
format = create_format(function_call_expression,
|
51
|
+
format_str_index_of(function_call_expression),
|
52
|
+
arg_variables, @environ)
|
53
|
+
return unless format
|
54
|
+
|
55
|
+
format.conversion_specifiers.each_with_index do |cs, index|
|
56
|
+
if cs.scanset && cs.scanset.include?("-")
|
57
|
+
W(:W0573, format.location)
|
58
|
+
break
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def format_str_index_of(function_call_expression)
|
65
|
+
function_call_expression.argument_expressions.index do |arg_expr|
|
66
|
+
arg_expr.kind_of?(StringLiteralSpecifier)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_format(function_call_expression,
|
71
|
+
format_str_index, arg_variables, environment)
|
72
|
+
if format_str_index
|
73
|
+
format_str =
|
74
|
+
function_call_expression.argument_expressions[format_str_index]
|
75
|
+
if format_str && format_str.literal.value =~ /\AL?"(.*)"\z/i
|
76
|
+
location = format_str.location
|
77
|
+
trailing_args = arg_variables[(format_str_index + 1)..-1] || []
|
78
|
+
return ScanfFormat.new($1, location, trailing_args, environment)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
38
85
|
class W0606 < PassiveMessageDetection
|
39
86
|
def initialize(context)
|
40
87
|
super
|
@@ -55,6 +102,46 @@ module C #:nodoc:
|
|
55
102
|
end
|
56
103
|
end
|
57
104
|
|
105
|
+
class W0685 < W0573
|
106
|
+
def check(function_call_expression, function, arg_variables,
|
107
|
+
result_variable)
|
108
|
+
if function.named? && function.name =~ /\A.*scanf\z/
|
109
|
+
format = create_format(function_call_expression,
|
110
|
+
format_str_index_of(function_call_expression),
|
111
|
+
arg_variables, @environ)
|
112
|
+
return unless format
|
113
|
+
|
114
|
+
format.conversion_specifiers.each do |cs|
|
115
|
+
next unless cs.scanset
|
116
|
+
|
117
|
+
cs.scanset.scan(/(.)-(.)/).each do |lhs, rhs|
|
118
|
+
W(:W0685, format.location) if lhs.ord > rhs.ord
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class W0686 < W0573
|
126
|
+
def check(function_call_expression, function, arg_variables,
|
127
|
+
result_variable)
|
128
|
+
if function.named? && function.name =~ /\A.*scanf\z/
|
129
|
+
format = create_format(function_call_expression,
|
130
|
+
format_str_index_of(function_call_expression),
|
131
|
+
arg_variables, @environ)
|
132
|
+
return unless format
|
133
|
+
|
134
|
+
format.conversion_specifiers.each do |cs|
|
135
|
+
next unless cs.scanset
|
136
|
+
|
137
|
+
unless cs.valid_scanset?
|
138
|
+
W(:W0686, format.location)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
58
145
|
class W0698 < PassiveMessageDetection
|
59
146
|
def initialize(context)
|
60
147
|
super
|
@@ -114,6 +201,34 @@ module C #:nodoc:
|
|
114
201
|
end
|
115
202
|
end
|
116
203
|
|
204
|
+
class W0781 < PassiveMessageDetection
|
205
|
+
def initialize(context)
|
206
|
+
super
|
207
|
+
visitor = context[:c_visitor]
|
208
|
+
visitor.enter_switch_statement += method(:enter_switch_statement)
|
209
|
+
visitor.leave_switch_statement += method(:check)
|
210
|
+
visitor.enter_case_labeled_statement += method(:add_exec_path)
|
211
|
+
visitor.enter_default_labeled_statement += method(:add_exec_path)
|
212
|
+
@exec_path_nums = []
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
def enter_switch_statement(node)
|
217
|
+
@exec_path_nums.push(0)
|
218
|
+
end
|
219
|
+
|
220
|
+
def check(node)
|
221
|
+
if exec_path_num = @exec_path_nums.last and exec_path_num < 2
|
222
|
+
W(:W0781, node.location)
|
223
|
+
end
|
224
|
+
@exec_path_nums.pop
|
225
|
+
end
|
226
|
+
|
227
|
+
def add_exec_path(node)
|
228
|
+
@exec_path_nums[-1] += 1 if node.executed?
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
117
232
|
class W0801 < PassiveMessageDetection
|
118
233
|
def initialize(context)
|
119
234
|
super
|
@@ -128,6 +243,127 @@ module C #:nodoc:
|
|
128
243
|
end
|
129
244
|
end
|
130
245
|
|
246
|
+
class W0809 < PassiveMessageDetection
|
247
|
+
def initialize(context)
|
248
|
+
super
|
249
|
+
visitor = context[:c_visitor]
|
250
|
+
visitor.enter_function_declaration += method(:check_function_name)
|
251
|
+
visitor.enter_variable_declaration += method(:check_variable_name)
|
252
|
+
visitor.enter_variable_definition += method(:check_variable_name)
|
253
|
+
visitor.enter_parameter_definition += method(:check_variable_name)
|
254
|
+
visitor.enter_typedef_declaration += method(:check_typedef_name)
|
255
|
+
visitor.enter_struct_type_declaration += method(:check_tag_name)
|
256
|
+
visitor.enter_union_type_declaration += method(:check_tag_name)
|
257
|
+
visitor.enter_enum_type_declaration += method(:check_tag_name)
|
258
|
+
visitor.enter_enumerator += method(:check_enumerator_name)
|
259
|
+
visitor.enter_kandr_function_definition += method(:enter_function)
|
260
|
+
visitor.enter_ansi_function_definition += method(:enter_function)
|
261
|
+
visitor.leave_kandr_function_definition += method(:leave_function)
|
262
|
+
visitor.leave_ansi_function_definition += method(:leave_function)
|
263
|
+
@function_def_level = 0
|
264
|
+
end
|
265
|
+
|
266
|
+
private
|
267
|
+
def check_function_name(function_decl)
|
268
|
+
check_object_name(function_decl)
|
269
|
+
end
|
270
|
+
|
271
|
+
def check_variable_name(variable_decl_or_def)
|
272
|
+
check_object_name(variable_decl_or_def)
|
273
|
+
end
|
274
|
+
|
275
|
+
def check_typedef_name(typedef_decl)
|
276
|
+
if typedef_decl.identifier
|
277
|
+
case name = typedef_decl.identifier.value
|
278
|
+
when /\A__/, /\A_[A-Z]/, /\A_/
|
279
|
+
W(:W0809, typedef_decl.location, name)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def check_tag_name(type_decl)
|
285
|
+
if type_decl.identifier
|
286
|
+
case name = type_decl.identifier.value
|
287
|
+
when /\A__adlint/
|
288
|
+
# NOTE: To ignore AdLint internal tag names.
|
289
|
+
when /\A__/, /\A_[A-Z]/, /\A_/
|
290
|
+
W(:W0809, type_decl.location, name)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def check_enumerator_name(enumerator)
|
296
|
+
if enumerator.identifier
|
297
|
+
case name = enumerator.identifier.value
|
298
|
+
when /\A__/, /\A_[A-Z]/, /\A_/
|
299
|
+
W(:W0809, enumerator.location, name)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def enter_function(node)
|
305
|
+
check_object_name(node)
|
306
|
+
@function_def_level += 1
|
307
|
+
end
|
308
|
+
|
309
|
+
def leave_function(node)
|
310
|
+
@function_def_level -= 1
|
311
|
+
end
|
312
|
+
|
313
|
+
def check_object_name(decl_or_def)
|
314
|
+
if decl_or_def.identifier
|
315
|
+
case name = decl_or_def.identifier.value
|
316
|
+
when /\A__/, /\A_[A-Z]/
|
317
|
+
W(:W0809, decl_or_def.location, name)
|
318
|
+
when /\A_/
|
319
|
+
check_filelocal_object_name(name, decl_or_def)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def check_filelocal_object_name(name, decl_or_def)
|
325
|
+
if @function_def_level == 0
|
326
|
+
storage_class_specifier = decl_or_def.storage_class_specifier
|
327
|
+
if storage_class_specifier && storage_class_specifier.type == :STATIC
|
328
|
+
W(:W0809, decl_or_def.location, name)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
class W1030 < PassiveMessageDetection
|
335
|
+
def initialize(context)
|
336
|
+
super
|
337
|
+
visitor = context[:c_visitor]
|
338
|
+
visitor.enter_generic_labeled_statement += method(:check)
|
339
|
+
visitor.enter_ansi_function_definition += method(:enter_function)
|
340
|
+
visitor.leave_ansi_function_definition += method(:leave_function)
|
341
|
+
visitor.enter_kandr_function_definition += method(:enter_function)
|
342
|
+
visitor.leave_kandr_function_definition += method(:leave_function)
|
343
|
+
@labels = nil
|
344
|
+
end
|
345
|
+
|
346
|
+
private
|
347
|
+
def check(generic_labeled_statement)
|
348
|
+
return unless @labels
|
349
|
+
|
350
|
+
label = generic_labeled_statement.label
|
351
|
+
if @labels.include?(label.value)
|
352
|
+
W(:W1030, label.location, label.value)
|
353
|
+
else
|
354
|
+
@labels.add(label.value)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
def enter_function(node)
|
359
|
+
@labels = Set.new
|
360
|
+
end
|
361
|
+
|
362
|
+
def leave_function(node)
|
363
|
+
@labels = nil
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
131
367
|
class W1033 < PassiveMessageDetection
|
132
368
|
def initialize(context)
|
133
369
|
super
|
data/lib/adlint/c/metric.rb
CHANGED
@@ -291,6 +291,7 @@ module C #:nodoc:
|
|
291
291
|
interp.on_function_ended += method(:leave_function)
|
292
292
|
interp.on_variable_defined += method(:define_variable)
|
293
293
|
interp.on_parameter_defined += method(:define_variable)
|
294
|
+
interp.on_variable_referred += method(:refer_variable)
|
294
295
|
interp.on_variable_value_referred += method(:read_variable)
|
295
296
|
interp.on_variable_value_updated += method(:write_variable)
|
296
297
|
@current_function = nil
|
@@ -329,6 +330,14 @@ module C #:nodoc:
|
|
329
330
|
end
|
330
331
|
end
|
331
332
|
|
333
|
+
def refer_variable(expression, variable)
|
334
|
+
return unless @current_function
|
335
|
+
|
336
|
+
if variable.named? && @variables[variable.name]
|
337
|
+
@variables[variable.name] += 1
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
332
341
|
def read_variable(expression, variable)
|
333
342
|
return unless @current_function
|
334
343
|
|
data/lib/adlint/c/object.rb
CHANGED
@@ -661,14 +661,19 @@ module C #:nodoc:
|
|
661
661
|
interpreter.do_conversion(arg, param_type) ||
|
662
662
|
interpreter.temporary_variable(param_type)
|
663
663
|
else
|
664
|
-
|
664
|
+
converted = arg
|
665
665
|
end
|
666
666
|
else
|
667
667
|
converted = interpreter.do_default_argument_promotion(arg)
|
668
|
-
next if arg.type.same_as?(converted.type)
|
669
668
|
end
|
670
669
|
|
671
|
-
|
670
|
+
# NOTE: Value of the argument is referred when the assignment to the
|
671
|
+
# parameter is performed.
|
672
|
+
if arg.variable? && !arg.type.array?
|
673
|
+
interpreter.notify_variable_value_referred(expr, arg)
|
674
|
+
end
|
675
|
+
|
676
|
+
if converted && arg != converted
|
672
677
|
interpreter.notify_implicit_conv_performed(expr, arg, converted)
|
673
678
|
end
|
674
679
|
end
|
@@ -677,26 +682,40 @@ module C #:nodoc:
|
|
677
682
|
def return_values_via_pointer_arguments(interpreter, funcall_expr, args)
|
678
683
|
args.zip(type.parameter_types).each do |(arg, expr), param_type|
|
679
684
|
next if param_type && param_type.void?
|
680
|
-
next unless arg.variable? && arg.
|
685
|
+
next unless arg.variable? && (arg.type.pointer? || arg.type.array?)
|
681
686
|
|
682
687
|
param_type = param_type.unqualify if param_type
|
683
688
|
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
689
|
+
case
|
690
|
+
when param_type.nil? && (arg.type.pointer? || arg.type.array?),
|
691
|
+
param_type && param_type.pointer? && !param_type.base_type.const?,
|
692
|
+
param_type && param_type.array? && !param_type.base_type.const?
|
693
|
+
else
|
694
|
+
next
|
695
|
+
end
|
696
|
+
|
697
|
+
case
|
698
|
+
when arg.type.pointer?
|
699
|
+
pointee = interpreter.pointee_of(arg)
|
700
|
+
if pointee && pointee.designated_by_lvalue? && pointee.variable?
|
701
|
+
sink = pointee
|
702
|
+
else
|
703
|
+
next
|
698
704
|
end
|
705
|
+
when arg.type.array?
|
706
|
+
sink = arg
|
699
707
|
end
|
708
|
+
|
709
|
+
sink.assign!(sink.type.return_value)
|
710
|
+
interpreter.notify_variable_value_updated(expr, sink)
|
711
|
+
|
712
|
+
# NOTE: Returning a value via a pointer parameter can be considered as
|
713
|
+
# an evaluation of a statement-expression with a
|
714
|
+
# simple-assignment-expression.
|
715
|
+
# Control will reach to a sequence-point at the end of a full
|
716
|
+
# expression.
|
717
|
+
interpreter.notify_sequence_point_reached(
|
718
|
+
SequencePoint.new(funcall_expr, false))
|
700
719
|
end
|
701
720
|
end
|
702
721
|
end
|
@@ -1009,19 +1028,5 @@ module C #:nodoc:
|
|
1009
1028
|
end
|
1010
1029
|
end
|
1011
1030
|
|
1012
|
-
class EnumeratorTable
|
1013
|
-
def initialize
|
1014
|
-
@enumerators = {}
|
1015
|
-
end
|
1016
|
-
|
1017
|
-
def define(enumerator)
|
1018
|
-
@enumerators[enumerator.identifier.value] = enumerator
|
1019
|
-
end
|
1020
|
-
|
1021
|
-
def lookup(name_str)
|
1022
|
-
@enumerators[name_str]
|
1023
|
-
end
|
1024
|
-
end
|
1025
|
-
|
1026
1031
|
end
|
1027
1032
|
end
|
data/lib/adlint/c/parser.rb
CHANGED
@@ -70,7 +70,7 @@ def value_of(token)
|
|
70
70
|
token == "$" ? "EOF" : token.value
|
71
71
|
end
|
72
72
|
|
73
|
-
def
|
73
|
+
def create_unnamed_tag_name(base_token)
|
74
74
|
Token.new(:IDENTIFIER, "__adlint__unnamed_#{@unnamed_type_no += 1}",
|
75
75
|
base_token.location)
|
76
76
|
end
|
@@ -2342,7 +2342,7 @@ module_eval(<<'.,.,', 'parser.y', 904)
|
|
2342
2342
|
def _reduce_126(val, _values, result)
|
2343
2343
|
checkpoint(val[0].location)
|
2344
2344
|
|
2345
|
-
result = StructSpecifier.new(
|
2345
|
+
result = StructSpecifier.new(create_unnamed_tag_name(val[0]), val[2])
|
2346
2346
|
result.head_token = val[0]
|
2347
2347
|
result.tail_token = val[3]
|
2348
2348
|
|
@@ -2354,7 +2354,7 @@ module_eval(<<'.,.,', 'parser.y', 912)
|
|
2354
2354
|
def _reduce_127(val, _values, result)
|
2355
2355
|
checkpoint(val[0].location)
|
2356
2356
|
|
2357
|
-
result = StructSpecifier.new(
|
2357
|
+
result = StructSpecifier.new(create_unnamed_tag_name(val[0]), [])
|
2358
2358
|
result.head_token = val[0]
|
2359
2359
|
result.tail_token = val[2]
|
2360
2360
|
|
@@ -2366,7 +2366,7 @@ module_eval(<<'.,.,', 'parser.y', 920)
|
|
2366
2366
|
def _reduce_128(val, _values, result)
|
2367
2367
|
checkpoint(val[0].location)
|
2368
2368
|
|
2369
|
-
result = UnionSpecifier.new(
|
2369
|
+
result = UnionSpecifier.new(create_unnamed_tag_name(val[0]), val[2])
|
2370
2370
|
result.head_token = val[0]
|
2371
2371
|
result.tail_token = val[3]
|
2372
2372
|
|
@@ -2378,7 +2378,7 @@ module_eval(<<'.,.,', 'parser.y', 928)
|
|
2378
2378
|
def _reduce_129(val, _values, result)
|
2379
2379
|
checkpoint(val[0].location)
|
2380
2380
|
|
2381
|
-
result = UnionSpecifier.new(
|
2381
|
+
result = UnionSpecifier.new(create_unnamed_tag_name(val[0]), [])
|
2382
2382
|
result.head_token = val[0]
|
2383
2383
|
result.tail_token = val[2]
|
2384
2384
|
|
@@ -2578,7 +2578,7 @@ module_eval(<<'.,.,', 'parser.y', 1076)
|
|
2578
2578
|
def _reduce_146(val, _values, result)
|
2579
2579
|
checkpoint(val[0].location)
|
2580
2580
|
|
2581
|
-
result = EnumSpecifier.new(
|
2581
|
+
result = EnumSpecifier.new(create_unnamed_tag_name(val[0]), val[2])
|
2582
2582
|
result.head_token = val[0]
|
2583
2583
|
result.tail_token = val[3]
|
2584
2584
|
|
@@ -2602,7 +2602,7 @@ module_eval(<<'.,.,', 'parser.y', 1092)
|
|
2602
2602
|
def _reduce_148(val, _values, result)
|
2603
2603
|
checkpoint(val[0].location)
|
2604
2604
|
|
2605
|
-
result = EnumSpecifier.new(
|
2605
|
+
result = EnumSpecifier.new(create_unnamed_tag_name(val[0]), val[2])
|
2606
2606
|
result.head_token = val[0]
|
2607
2607
|
result.tail_token = val[4]
|
2608
2608
|
|
data/lib/adlint/c/parser.y
CHANGED
@@ -904,7 +904,7 @@ struct_or_union_specifier
|
|
904
904
|
{
|
905
905
|
checkpoint(val[0].location)
|
906
906
|
|
907
|
-
result = StructSpecifier.new(
|
907
|
+
result = StructSpecifier.new(create_unnamed_tag_name(val[0]), val[2])
|
908
908
|
result.head_token = val[0]
|
909
909
|
result.tail_token = val[3]
|
910
910
|
}
|
@@ -912,7 +912,7 @@ struct_or_union_specifier
|
|
912
912
|
{
|
913
913
|
checkpoint(val[0].location)
|
914
914
|
|
915
|
-
result = StructSpecifier.new(
|
915
|
+
result = StructSpecifier.new(create_unnamed_tag_name(val[0]), [])
|
916
916
|
result.head_token = val[0]
|
917
917
|
result.tail_token = val[2]
|
918
918
|
}
|
@@ -920,7 +920,7 @@ struct_or_union_specifier
|
|
920
920
|
{
|
921
921
|
checkpoint(val[0].location)
|
922
922
|
|
923
|
-
result = UnionSpecifier.new(
|
923
|
+
result = UnionSpecifier.new(create_unnamed_tag_name(val[0]), val[2])
|
924
924
|
result.head_token = val[0]
|
925
925
|
result.tail_token = val[3]
|
926
926
|
}
|
@@ -928,7 +928,7 @@ struct_or_union_specifier
|
|
928
928
|
{
|
929
929
|
checkpoint(val[0].location)
|
930
930
|
|
931
|
-
result = UnionSpecifier.new(
|
931
|
+
result = UnionSpecifier.new(create_unnamed_tag_name(val[0]), [])
|
932
932
|
result.head_token = val[0]
|
933
933
|
result.tail_token = val[2]
|
934
934
|
}
|
@@ -1076,7 +1076,7 @@ enum_specifier
|
|
1076
1076
|
{
|
1077
1077
|
checkpoint(val[0].location)
|
1078
1078
|
|
1079
|
-
result = EnumSpecifier.new(
|
1079
|
+
result = EnumSpecifier.new(create_unnamed_tag_name(val[0]), val[2])
|
1080
1080
|
result.head_token = val[0]
|
1081
1081
|
result.tail_token = val[3]
|
1082
1082
|
}
|
@@ -1092,7 +1092,7 @@ enum_specifier
|
|
1092
1092
|
{
|
1093
1093
|
checkpoint(val[0].location)
|
1094
1094
|
|
1095
|
-
result = EnumSpecifier.new(
|
1095
|
+
result = EnumSpecifier.new(create_unnamed_tag_name(val[0]), val[2])
|
1096
1096
|
result.head_token = val[0]
|
1097
1097
|
result.tail_token = val[4]
|
1098
1098
|
}
|
@@ -2078,7 +2078,7 @@ def value_of(token)
|
|
2078
2078
|
token == "$" ? "EOF" : token.value
|
2079
2079
|
end
|
2080
2080
|
|
2081
|
-
def
|
2081
|
+
def create_unnamed_tag_name(base_token)
|
2082
2082
|
Token.new(:IDENTIFIER, "__adlint__unnamed_#{@unnamed_type_no += 1}",
|
2083
2083
|
base_token.location)
|
2084
2084
|
end
|