adlint 3.0.4 → 3.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +374 -13
- data/INSTALL +1 -3
- data/MANIFEST +12 -0
- data/NEWS +30 -4
- data/README +0 -4
- data/TODO +2 -1
- data/etc/mesg.d/c_builtin/en_US/messages.yml +2 -2
- data/etc/mesg.d/c_builtin/ja_JP/messages.yml +2 -2
- data/etc/mesg.d/core/en_US/messages.yml +5 -1
- data/etc/mesg.d/core/ja_JP/messages.yml +5 -1
- data/features/code_check/W0422.feature +128 -0
- data/features/code_check/W0491.feature +57 -0
- data/features/code_check/W0492.feature +80 -0
- data/features/code_check/W0542.feature +20 -0
- data/features/code_check/W0580.feature +25 -0
- data/features/code_check/W0610.feature +36 -0
- data/features/code_check/W0642.feature +67 -0
- data/features/code_check/W0786.feature +39 -0
- data/features/code_check/W0830.feature +27 -0
- data/features/code_check/W1047.feature +72 -0
- data/features/code_check/W9003.feature +22 -0
- data/features/code_extraction/TODO +1 -0
- data/features/metric_measurement/TODO +1 -0
- data/lib/adlint/analyzer.rb +2 -2
- data/lib/adlint/cc1/ctrlexpr.rb +27 -6
- data/lib/adlint/cc1/domain.rb +72 -12
- data/lib/adlint/cc1/enum.rb +4 -0
- data/lib/adlint/cc1/expr.rb +31 -29
- data/lib/adlint/cc1/interp.rb +45 -56
- data/lib/adlint/cc1/lexer.rb +26 -5
- data/lib/adlint/cc1/mediator.rb +35 -6
- data/lib/adlint/cc1/object.rb +62 -19
- data/lib/adlint/cc1/parser.rb +948 -904
- data/lib/adlint/cc1/parser.y +59 -29
- data/lib/adlint/cc1/phase.rb +6 -8
- data/lib/adlint/cc1/syntax.rb +70 -17
- data/lib/adlint/cc1/util.rb +4 -4
- data/lib/adlint/code.rb +16 -6
- data/lib/adlint/cpp/eval.rb +31 -25
- data/lib/adlint/cpp/lexer.rb +11 -5
- data/lib/adlint/cpp/macro.rb +34 -7
- data/lib/adlint/cpp/phase.rb +8 -8
- data/lib/adlint/error.rb +6 -0
- data/lib/adlint/exam/c_builtin/cc1_check.rb +557 -594
- data/lib/adlint/exam/c_builtin/cc1_check_shima.rb +72 -72
- data/lib/adlint/exam/c_builtin/cc1_code.rb +72 -52
- data/lib/adlint/exam/c_builtin/cc1_metric.rb +131 -131
- data/lib/adlint/exam/c_builtin/cpp_check.rb +48 -48
- data/lib/adlint/exam/c_builtin/cpp_check_shima.rb +2 -2
- data/lib/adlint/exam/c_builtin/cpp_code.rb +21 -21
- data/lib/adlint/exam/c_builtin/ld_check.rb +88 -87
- data/lib/adlint/exam/c_builtin/ld_metric.rb +4 -5
- data/lib/adlint/exam/c_builtin.rb +6 -6
- data/lib/adlint/ld/object.rb +269 -186
- data/lib/adlint/ld/phase.rb +19 -19
- data/lib/adlint/ld/typedef.rb +7 -7
- data/lib/adlint/ld/util.rb +25 -17
- data/lib/adlint/location.rb +6 -1
- data/lib/adlint/memo.rb +66 -13
- data/lib/adlint/prelude.rb +2 -2
- data/lib/adlint/report.rb +13 -14
- data/lib/adlint/util.rb +1 -1
- data/lib/adlint/version.rb +2 -2
- data/share/doc/Makefile +6 -2
- data/share/doc/c99gram.dot +502 -0
- data/share/doc/c99gram.pdf +0 -0
- data/share/doc/developers_guide_ja.html +4 -3
- data/share/doc/developers_guide_ja.texi +2 -1
- data/share/doc/users_guide_en.html +9 -9
- data/share/doc/users_guide_en.texi +7 -7
- data/share/doc/users_guide_ja.html +9 -9
- data/share/doc/users_guide_ja.texi +7 -7
- metadata +14 -2
data/lib/adlint/ld/object.rb
CHANGED
@@ -104,7 +104,7 @@ module Ld #:nodoc:
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
class
|
107
|
+
class VariableMap
|
108
108
|
def initialize
|
109
109
|
@def_index = Hash.new { |hash, key| hash[key] = Set.new }
|
110
110
|
@dcl_index = Hash.new { |hash, key| hash[key] = Set.new }
|
@@ -142,10 +142,10 @@ module Ld #:nodoc:
|
|
142
142
|
|
143
143
|
class VariableMapper
|
144
144
|
def initialize
|
145
|
-
@
|
145
|
+
@map = VariableMap.new
|
146
146
|
end
|
147
147
|
|
148
|
-
attr_reader :
|
148
|
+
attr_reader :map
|
149
149
|
|
150
150
|
def execute(met_fpath)
|
151
151
|
sma_wd = Pathname.pwd
|
@@ -156,103 +156,18 @@ module Ld #:nodoc:
|
|
156
156
|
sma_wd = Pathname.new(rec.exec_working_directory)
|
157
157
|
when rec.variable_definition?
|
158
158
|
if rec.variable_linkage_type == "X"
|
159
|
-
@
|
159
|
+
@map.add_variable(Variable.new(rec))
|
160
160
|
end
|
161
161
|
when rec.global_variable_declaration?
|
162
|
-
@
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
class VariableReference
|
169
|
-
include LocationHolder
|
170
|
-
|
171
|
-
def initialize(fun, var, loc)
|
172
|
-
@function = fun
|
173
|
-
@variable = var
|
174
|
-
@location = loc
|
175
|
-
end
|
176
|
-
|
177
|
-
attr_reader :function
|
178
|
-
attr_reader :variable
|
179
|
-
attr_reader :location
|
180
|
-
|
181
|
-
def eql?(rhs)
|
182
|
-
to_a == rhs.to_a
|
183
|
-
end
|
184
|
-
|
185
|
-
alias :== :eql?
|
186
|
-
|
187
|
-
def hash
|
188
|
-
to_a.hash
|
189
|
-
end
|
190
|
-
|
191
|
-
def to_a
|
192
|
-
[@function, @variable, @location]
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
class VariableReferenceGraph
|
197
|
-
def initialize(funcall_graph)
|
198
|
-
@funcall_graph = funcall_graph
|
199
|
-
@ref_index = Hash.new { |hash, key| hash[key] = Set.new }
|
200
|
-
@var_index = Hash.new { |hash, key| hash[key] = Set.new }
|
201
|
-
end
|
202
|
-
|
203
|
-
def add(var_ref)
|
204
|
-
@ref_index[var_ref.function].add(var_ref)
|
205
|
-
@var_index[var_ref.variable].add(var_ref)
|
206
|
-
end
|
207
|
-
|
208
|
-
def all_referrers_of(var)
|
209
|
-
direct_referrers_of(var) + indirect_referrers_of(var)
|
210
|
-
end
|
211
|
-
|
212
|
-
def direct_referrers_of(var)
|
213
|
-
@var_index[var].map { |var_ref| var_ref.function }.to_set
|
214
|
-
end
|
215
|
-
|
216
|
-
def indirect_referrers_of(var)
|
217
|
-
direct_referrers = direct_referrers_of(var)
|
218
|
-
direct_referrers.reduce(Set.new) do |result, fun|
|
219
|
-
result + @funcall_graph.all_callers_of(fun)
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
class VariableReferenceGraphBuilder
|
225
|
-
def initialize(var_mapping, fun_mapping, funcall_graph)
|
226
|
-
@variable_mapping = var_mapping
|
227
|
-
@function_mapping = fun_mapping
|
228
|
-
@result = VariableReferenceGraph.new(funcall_graph)
|
229
|
-
end
|
230
|
-
|
231
|
-
attr_reader :result
|
232
|
-
|
233
|
-
def execute(met_fpath)
|
234
|
-
sma_wd = Pathname.pwd
|
235
|
-
CSV.foreach(met_fpath) do |csv_row|
|
236
|
-
rec = MetricRecord.of(csv_row, sma_wd)
|
237
|
-
case
|
238
|
-
when rec.version?
|
239
|
-
sma_wd = Pathname.new(rec.exec_working_directory)
|
240
|
-
when rec.variable_xref?
|
241
|
-
fun = @function_mapping.lookup_functions(
|
242
|
-
rec.accessor_function.name).first
|
243
|
-
var = @variable_mapping.lookup_variables(rec.accessee_variable).first
|
244
|
-
|
245
|
-
if fun && var
|
246
|
-
@result.add(VariableReference.new(fun, var, rec.location))
|
247
|
-
end
|
162
|
+
@map.add_variable_declaration(VariableDeclaration.new(rec))
|
248
163
|
end
|
249
164
|
end
|
250
165
|
end
|
251
166
|
end
|
252
167
|
|
253
168
|
class VariableTraversal
|
254
|
-
def initialize(
|
255
|
-
@
|
169
|
+
def initialize(var_map)
|
170
|
+
@map = var_map
|
256
171
|
end
|
257
172
|
|
258
173
|
extend Pluggable
|
@@ -261,11 +176,11 @@ module Ld #:nodoc:
|
|
261
176
|
def_plugin :on_definition
|
262
177
|
|
263
178
|
def execute
|
264
|
-
@
|
179
|
+
@map.all_variable_declarations.each do |var_dcl|
|
265
180
|
on_declaration.invoke(var_dcl)
|
266
181
|
end
|
267
182
|
|
268
|
-
@
|
183
|
+
@map.all_variables.each do |var_def|
|
269
184
|
on_definition.invoke(var_def)
|
270
185
|
end
|
271
186
|
end
|
@@ -347,7 +262,7 @@ module Ld #:nodoc:
|
|
347
262
|
end
|
348
263
|
end
|
349
264
|
|
350
|
-
class
|
265
|
+
class FunctionMap
|
351
266
|
def initialize
|
352
267
|
@def_index = Hash.new { |hash, key| hash[key] = Set.new }
|
353
268
|
@dcl_index = Hash.new { |hash, key| hash[key] = Set.new }
|
@@ -385,10 +300,10 @@ module Ld #:nodoc:
|
|
385
300
|
|
386
301
|
class FunctionMapper
|
387
302
|
def initialize
|
388
|
-
@
|
303
|
+
@map = FunctionMap.new
|
389
304
|
end
|
390
305
|
|
391
|
-
attr_reader :
|
306
|
+
attr_reader :map
|
392
307
|
|
393
308
|
def execute(met_fpath)
|
394
309
|
sma_wd = Pathname.pwd
|
@@ -398,22 +313,234 @@ module Ld #:nodoc:
|
|
398
313
|
when rec.version?
|
399
314
|
sma_wd = Pathname.new(rec.exec_working_directory)
|
400
315
|
when rec.function_definition?
|
401
|
-
@
|
316
|
+
@map.add_function(Function.new(rec))
|
402
317
|
when rec.function_declaration?
|
403
|
-
@
|
318
|
+
@map.add_function_declaration(FunctionDeclaration.new(rec))
|
404
319
|
end
|
405
320
|
end
|
406
321
|
end
|
407
322
|
end
|
408
323
|
|
324
|
+
class FunctionTraversal
|
325
|
+
def initialize(fun_map)
|
326
|
+
@map = fun_map
|
327
|
+
end
|
328
|
+
|
329
|
+
extend Pluggable
|
330
|
+
|
331
|
+
def_plugin :on_declaration
|
332
|
+
def_plugin :on_definition
|
333
|
+
|
334
|
+
def execute
|
335
|
+
@map.all_function_declarations.each do |fun_dcl|
|
336
|
+
on_declaration.invoke(fun_dcl)
|
337
|
+
end
|
338
|
+
|
339
|
+
@map.all_functions.each do |fun_def|
|
340
|
+
on_definition.invoke(fun_def)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
class ObjectReferrer
|
346
|
+
class << self
|
347
|
+
def of_function(fun)
|
348
|
+
Function.new(fun)
|
349
|
+
end
|
350
|
+
|
351
|
+
def of_ctors_section(ref_loc)
|
352
|
+
CtorsSection.new(ref_loc)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def location
|
357
|
+
subclass_responsibility
|
358
|
+
end
|
359
|
+
|
360
|
+
def function
|
361
|
+
subclass_responsibility
|
362
|
+
end
|
363
|
+
|
364
|
+
def hash
|
365
|
+
subclass_responsibility
|
366
|
+
end
|
367
|
+
|
368
|
+
def eql?(rhs)
|
369
|
+
subclass_responsibility
|
370
|
+
end
|
371
|
+
|
372
|
+
class Function < ObjectReferrer
|
373
|
+
def initialize(fun)
|
374
|
+
@function = fun
|
375
|
+
end
|
376
|
+
|
377
|
+
attr_reader :function
|
378
|
+
|
379
|
+
def location
|
380
|
+
@function.location
|
381
|
+
end
|
382
|
+
|
383
|
+
def hash
|
384
|
+
@function.hash
|
385
|
+
end
|
386
|
+
|
387
|
+
def eql?(rhs)
|
388
|
+
case rhs
|
389
|
+
when Function
|
390
|
+
@function == rhs.function
|
391
|
+
else
|
392
|
+
false
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
private_constant :Function
|
397
|
+
|
398
|
+
class CtorsSection < ObjectReferrer
|
399
|
+
def initialize(ref_loc)
|
400
|
+
@location = ref_loc
|
401
|
+
end
|
402
|
+
|
403
|
+
attr_reader :location
|
404
|
+
|
405
|
+
def function
|
406
|
+
nil
|
407
|
+
end
|
408
|
+
|
409
|
+
def hash
|
410
|
+
@location.fpath.hash
|
411
|
+
end
|
412
|
+
|
413
|
+
def eql?(rhs)
|
414
|
+
case rhs
|
415
|
+
when CtorsSection
|
416
|
+
@location.fpath == rhs.location.fpath
|
417
|
+
else
|
418
|
+
false
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
private_constant :CtorsSection
|
423
|
+
end
|
424
|
+
|
425
|
+
class ObjectReference
|
426
|
+
include LocationHolder
|
427
|
+
|
428
|
+
def initialize(ref, obj, loc)
|
429
|
+
@referrer = ref
|
430
|
+
@object = obj
|
431
|
+
@location = loc
|
432
|
+
end
|
433
|
+
|
434
|
+
attr_reader :referrer
|
435
|
+
attr_reader :object
|
436
|
+
attr_reader :location
|
437
|
+
|
438
|
+
def eql?(rhs)
|
439
|
+
to_a == rhs.to_a
|
440
|
+
end
|
441
|
+
|
442
|
+
alias :== :eql?
|
443
|
+
|
444
|
+
def hash
|
445
|
+
to_a.hash
|
446
|
+
end
|
447
|
+
|
448
|
+
def to_a
|
449
|
+
[@referrer, @object, @location]
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
class ObjectXRefGraph
|
454
|
+
def initialize(funcall_graph)
|
455
|
+
@funcall_graph = funcall_graph
|
456
|
+
@obj_index = Hash.new { |hash, key| hash[key] = Set.new }
|
457
|
+
end
|
458
|
+
|
459
|
+
def add(obj_ref)
|
460
|
+
@obj_index[obj_ref.object].add(obj_ref)
|
461
|
+
end
|
462
|
+
|
463
|
+
def all_referrers_of(obj)
|
464
|
+
direct_referrers_of(obj) + indirect_referrers_of(obj)
|
465
|
+
end
|
466
|
+
|
467
|
+
def direct_referrers_of(obj)
|
468
|
+
@obj_index[obj].map { |obj_ref| obj_ref.referrer }.to_set
|
469
|
+
end
|
470
|
+
|
471
|
+
def indirect_referrers_of(obj)
|
472
|
+
direct_referrers_of(obj).reduce(Set.new) do |res, ref|
|
473
|
+
if fun = ref.function
|
474
|
+
res + @funcall_graph.all_callers_of(fun)
|
475
|
+
else
|
476
|
+
res
|
477
|
+
end
|
478
|
+
end
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
class ObjectXRefGraphBuilder
|
483
|
+
def initialize(var_map, fun_map, funcall_graph)
|
484
|
+
@var_map, @fun_map = var_map, fun_map
|
485
|
+
@graph = ObjectXRefGraph.new(funcall_graph)
|
486
|
+
end
|
487
|
+
|
488
|
+
attr_reader :graph
|
489
|
+
|
490
|
+
def execute(met_fpath)
|
491
|
+
sma_wd = Pathname.pwd
|
492
|
+
CSV.foreach(met_fpath) do |csv_row|
|
493
|
+
rec = MetricRecord.of(csv_row, sma_wd)
|
494
|
+
case
|
495
|
+
when rec.version?
|
496
|
+
sma_wd = Pathname.new(rec.exec_working_directory)
|
497
|
+
when rec.variable_xref?
|
498
|
+
var = @var_map.lookup_variables(rec.accessee_variable).first
|
499
|
+
fun_id = rec.accessor_function
|
500
|
+
if fun_id.named?
|
501
|
+
fun = @fun_map.lookup_functions(fun_id.name).first
|
502
|
+
ref = ObjectReferrer.of_function(fun)
|
503
|
+
else
|
504
|
+
ref = ObjectReferrer.of_ctors_section(rec.location)
|
505
|
+
end
|
506
|
+
@graph.add(ObjectReference.new(ref, var, rec.location)) if var
|
507
|
+
when rec.function_xref?
|
508
|
+
ref, fun = lookup_referrer_and_function_by_xref(rec)
|
509
|
+
@graph.add(ObjectReference.new(ref, fun, rec.location)) if ref && fun
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
private
|
515
|
+
def lookup_referrer_and_function_by_xref(fun_xref)
|
516
|
+
caller_id = fun_xref.accessor_function
|
517
|
+
if caller_id.named?
|
518
|
+
caller_fun = @fun_map.lookup_functions(caller_id.name).find { |fun|
|
519
|
+
fun.location.fpath == fun_xref.location.fpath
|
520
|
+
}
|
521
|
+
return nil, nil unless caller_fun
|
522
|
+
ref = ObjectReferrer.of_function(caller_fun)
|
523
|
+
else
|
524
|
+
ref = ObjectReferrer.of_ctors_section(fun_xref.location)
|
525
|
+
end
|
526
|
+
|
527
|
+
callee_funs = @fun_map.lookup_functions(fun_xref.accessee_function.name)
|
528
|
+
callee_fun = callee_funs.find { |fun|
|
529
|
+
fun.location.fpath == ref.location.fpath
|
530
|
+
} || callee_funs.first
|
531
|
+
|
532
|
+
return ref, callee_fun
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
409
536
|
class FunctionCall
|
410
|
-
def initialize(
|
411
|
-
@
|
412
|
-
@
|
537
|
+
def initialize(caller_ref, callee_fun)
|
538
|
+
@caller = caller_ref
|
539
|
+
@callee = callee_fun
|
413
540
|
end
|
414
541
|
|
415
|
-
attr_reader :
|
416
|
-
attr_reader :
|
542
|
+
attr_reader :caller
|
543
|
+
attr_reader :callee
|
417
544
|
|
418
545
|
def eql?(rhs)
|
419
546
|
to_a == rhs.to_a
|
@@ -426,64 +553,63 @@ module Ld #:nodoc:
|
|
426
553
|
end
|
427
554
|
|
428
555
|
def to_a
|
429
|
-
[@
|
556
|
+
[@caller, @callee]
|
430
557
|
end
|
431
558
|
end
|
432
559
|
|
433
560
|
class FunctionCallGraph
|
434
561
|
def initialize
|
435
|
-
@caller_index = Hash.new { |hash, key| hash[key] = Set.new }
|
436
562
|
@callee_index = Hash.new { |hash, key| hash[key] = Set.new }
|
437
563
|
end
|
438
564
|
|
439
565
|
def add(funcall)
|
440
|
-
@
|
441
|
-
@callee_index[funcall.callee_function].add(funcall)
|
566
|
+
@callee_index[funcall.callee].add(funcall)
|
442
567
|
end
|
443
568
|
|
444
|
-
def all_callers_of(
|
445
|
-
direct_callers_of(
|
569
|
+
def all_callers_of(fun)
|
570
|
+
direct_callers_of(fun) + indirect_callers_of(fun)
|
446
571
|
end
|
447
572
|
memoize :all_callers_of
|
448
573
|
|
449
|
-
def direct_callers_of(
|
450
|
-
@callee_index[
|
451
|
-
funcall.caller_function
|
452
|
-
}.to_set
|
574
|
+
def direct_callers_of(fun)
|
575
|
+
@callee_index[fun].map { |funcall| funcall.caller }.to_set
|
453
576
|
end
|
454
577
|
memoize :direct_callers_of
|
455
578
|
|
456
|
-
def indirect_callers_of(
|
457
|
-
|
458
|
-
|
459
|
-
|
579
|
+
def indirect_callers_of(fun)
|
580
|
+
direct_callers_of(fun).reduce(Set.new) do |res, ref|
|
581
|
+
if fun = ref.function
|
582
|
+
res + collect_callers_of(fun, res)
|
583
|
+
else
|
584
|
+
res
|
585
|
+
end
|
460
586
|
end
|
461
587
|
end
|
462
588
|
memoize :indirect_callers_of
|
463
589
|
|
464
590
|
private
|
465
|
-
def collect_callers_of(
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
591
|
+
def collect_callers_of(fun, exclusions)
|
592
|
+
direct_callers_of(fun).reduce(Set.new) do |res, ref|
|
593
|
+
case
|
594
|
+
when exclusions.include?(ref)
|
595
|
+
res.add(ref)
|
596
|
+
when caller_fun = ref.function
|
597
|
+
res.add(ref) + collect_callers_of(caller_fun, exclusions + res)
|
471
598
|
else
|
472
|
-
|
473
|
-
collect_callers_of(fun, exclusion_list + all_callers)
|
599
|
+
res.add(ref)
|
474
600
|
end
|
475
601
|
end
|
476
602
|
end
|
477
|
-
memoize :collect_callers_of, 0
|
603
|
+
memoize :collect_callers_of, key_indices: [0]
|
478
604
|
end
|
479
605
|
|
480
606
|
class FunctionCallGraphBuilder
|
481
|
-
def initialize(
|
482
|
-
@
|
483
|
-
@
|
607
|
+
def initialize(fun_map)
|
608
|
+
@fun_map = fun_map
|
609
|
+
@graph = FunctionCallGraph.new
|
484
610
|
end
|
485
611
|
|
486
|
-
attr_reader :
|
612
|
+
attr_reader :graph
|
487
613
|
|
488
614
|
def execute(met_fpath)
|
489
615
|
sma_wd = Pathname.pwd
|
@@ -493,80 +619,37 @@ module Ld #:nodoc:
|
|
493
619
|
when rec.version?
|
494
620
|
sma_wd = Pathname.new(rec.exec_working_directory)
|
495
621
|
when rec.function_call?
|
496
|
-
|
497
|
-
if
|
498
|
-
@
|
499
|
-
end
|
500
|
-
when rec.function_xref?
|
501
|
-
caller_fun, callee_fun = lookup_functions_by_xref(rec)
|
502
|
-
if caller_fun && callee_fun
|
503
|
-
@result.add(FunctionCall.new(caller_fun, callee_fun))
|
622
|
+
caller_ref, callee_fun = lookup_functions_by_call(rec)
|
623
|
+
if caller_ref && callee_fun
|
624
|
+
@graph.add(FunctionCall.new(caller_ref, callee_fun))
|
504
625
|
end
|
505
626
|
end
|
506
627
|
end
|
507
628
|
end
|
508
629
|
|
630
|
+
private
|
509
631
|
def lookup_functions_by_call(funcall_rec)
|
510
|
-
caller_fun = @
|
632
|
+
caller_fun = @fun_map.lookup_functions(
|
511
633
|
funcall_rec.caller_function.name).find { |fun|
|
512
634
|
fun.location.fpath == funcall_rec.location.fpath
|
513
635
|
}
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
callee_fun = callee_funs.first
|
520
|
-
callee_funs.each do |fun|
|
521
|
-
if fun.location.fpath == caller_fun.location.fpath
|
522
|
-
callee_fun = fun
|
523
|
-
break
|
524
|
-
end
|
636
|
+
if caller_fun
|
637
|
+
caller_ref = ObjectReferrer.of_function(caller_fun)
|
638
|
+
else
|
639
|
+
return nil, nil
|
525
640
|
end
|
526
641
|
|
527
|
-
|
528
|
-
end
|
529
|
-
|
530
|
-
def lookup_functions_by_xref(fun_xref_rec)
|
531
|
-
caller_fun = @function_mapping.lookup_functions(
|
532
|
-
fun_xref_rec.accessor_function.name).find { |fun|
|
533
|
-
fun.location.fpath == fun_xref_rec.location.fpath
|
534
|
-
}
|
535
|
-
return nil, nil unless caller_fun
|
536
|
-
|
537
|
-
callee_funs = @function_mapping.lookup_functions(
|
538
|
-
fun_xref_rec.accessee_function.name)
|
642
|
+
callee_funs = @fun_map.lookup_functions(funcall_rec.callee_function.name)
|
539
643
|
|
540
644
|
callee_fun = callee_funs.first
|
541
645
|
callee_funs.each do |fun|
|
542
|
-
if fun.location.fpath ==
|
646
|
+
if fun.location.fpath == caller_ref.location.fpath
|
543
647
|
callee_fun = fun
|
544
648
|
break
|
545
649
|
end
|
546
650
|
end
|
547
651
|
|
548
|
-
return
|
549
|
-
end
|
550
|
-
end
|
551
|
-
|
552
|
-
class FunctionTraversal
|
553
|
-
def initialize(fun_mapping)
|
554
|
-
@function_mapping = fun_mapping
|
555
|
-
end
|
556
|
-
|
557
|
-
extend Pluggable
|
558
|
-
|
559
|
-
def_plugin :on_declaration
|
560
|
-
def_plugin :on_definition
|
561
|
-
|
562
|
-
def execute
|
563
|
-
@function_mapping.all_function_declarations.each do |fun_dcl|
|
564
|
-
on_declaration.invoke(fun_dcl)
|
565
|
-
end
|
566
|
-
|
567
|
-
@function_mapping.all_functions.each do |fun_def|
|
568
|
-
on_definition.invoke(fun_def)
|
569
|
-
end
|
652
|
+
return caller_ref, callee_fun
|
570
653
|
end
|
571
654
|
end
|
572
655
|
|
data/lib/adlint/ld/phase.rb
CHANGED
@@ -57,7 +57,7 @@ module Ld #:nodoc:
|
|
57
57
|
mapper.execute(fpath)
|
58
58
|
monitor.progress += 1.0 / phase_ctxt[:metric_fpaths].size
|
59
59
|
end
|
60
|
-
phase_ctxt[:
|
60
|
+
phase_ctxt[:ld_typedef_map] = mapper.map
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -73,7 +73,7 @@ module Ld #:nodoc:
|
|
73
73
|
mapper.execute(fpath)
|
74
74
|
monitor.progress += 1.0 / phase_ctxt[:metric_fpaths].size
|
75
75
|
end
|
76
|
-
phase_ctxt[:
|
76
|
+
phase_ctxt[:ld_function_map] = mapper.map
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -89,43 +89,43 @@ module Ld #:nodoc:
|
|
89
89
|
mapper.execute(fpath)
|
90
90
|
monitor.progress += 1.0 / phase_ctxt[:metric_fpaths].size
|
91
91
|
end
|
92
|
-
phase_ctxt[:
|
92
|
+
phase_ctxt[:ld_variable_map] = mapper.map
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
class
|
96
|
+
class BuildCallGraphPhase < LdPhase
|
97
97
|
def initialize(phase_ctxt)
|
98
|
-
super(phase_ctxt, "
|
98
|
+
super(phase_ctxt, "ld1")
|
99
99
|
end
|
100
100
|
|
101
101
|
private
|
102
102
|
def do_execute(phase_ctxt, monitor)
|
103
|
-
builder = FunctionCallGraphBuilder.new(phase_ctxt[:
|
103
|
+
builder = FunctionCallGraphBuilder.new(phase_ctxt[:ld_function_map])
|
104
104
|
phase_ctxt[:metric_fpaths].each do |fpath|
|
105
105
|
builder.execute(fpath)
|
106
106
|
monitor.progress += 1.0 / phase_ctxt[:metric_fpaths].size
|
107
107
|
end
|
108
|
-
phase_ctxt[:
|
108
|
+
phase_ctxt[:ld_call_graph] = builder.graph
|
109
109
|
ensure
|
110
110
|
DebugUtil.dump_function_call_graph(phase_ctxt)
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
class
|
114
|
+
class BuildXRefGraphPhase < LdPhase
|
115
115
|
def initialize(phase_ctxt)
|
116
|
-
super(phase_ctxt, "
|
116
|
+
super(phase_ctxt, "ld2")
|
117
117
|
end
|
118
118
|
|
119
119
|
private
|
120
120
|
def do_execute(phase_ctxt, monitor)
|
121
|
-
builder =
|
122
|
-
phase_ctxt[:
|
123
|
-
phase_ctxt[:
|
121
|
+
builder = ObjectXRefGraphBuilder.new(
|
122
|
+
phase_ctxt[:ld_variable_map], phase_ctxt[:ld_function_map],
|
123
|
+
phase_ctxt[:ld_call_graph])
|
124
124
|
phase_ctxt[:metric_fpaths].each do |fpath|
|
125
125
|
builder.execute(fpath)
|
126
126
|
monitor.progress += 1.0 / phase_ctxt[:metric_fpaths].size
|
127
127
|
end
|
128
|
-
phase_ctxt[:
|
128
|
+
phase_ctxt[:ld_xref_graph] = builder.graph
|
129
129
|
ensure
|
130
130
|
DebugUtil.dump_variable_reference_graph(phase_ctxt)
|
131
131
|
end
|
@@ -140,11 +140,11 @@ module Ld #:nodoc:
|
|
140
140
|
def do_execute(phase_ctxt, *)
|
141
141
|
collect_annotations
|
142
142
|
phase_ctxt[:ld_typedef_traversal] =
|
143
|
-
TypedefTraversal.new(phase_ctxt[:
|
143
|
+
TypedefTraversal.new(phase_ctxt[:ld_typedef_map])
|
144
144
|
phase_ctxt[:ld_function_traversal] =
|
145
|
-
FunctionTraversal.new(phase_ctxt[:
|
145
|
+
FunctionTraversal.new(phase_ctxt[:ld_function_map])
|
146
146
|
phase_ctxt[:ld_variable_traversal] =
|
147
|
-
VariableTraversal.new(phase_ctxt[:
|
147
|
+
VariableTraversal.new(phase_ctxt[:ld_variable_map])
|
148
148
|
end
|
149
149
|
|
150
150
|
def collect_annotations
|
@@ -160,9 +160,9 @@ module Ld #:nodoc:
|
|
160
160
|
end
|
161
161
|
|
162
162
|
def composing_fpaths
|
163
|
-
@phase_ctxt[:
|
164
|
-
|
165
|
-
|
163
|
+
@phase_ctxt[:ld_function_map].composing_fpaths +
|
164
|
+
@phase_ctxt[:ld_variable_map].composing_fpaths +
|
165
|
+
@phase_ctxt[:ld_typedef_map].composing_fpaths
|
166
166
|
end
|
167
167
|
|
168
168
|
def parse_annotation(comment, loc)
|