source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tecsgen/tecslib/core/types.rb@ 352

Last change on this file since 352 was 352, checked in by coas-nagasima, 6 years ago

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 43.0 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2015 by TOPPERS Project
7#--
8# 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
9# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
10# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
11# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13# スコード中に含まれていること.
14# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
16# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
17# の無保証規定を掲載すること.
18# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
19# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
20# と.
21# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22# 作権表示,この利用条件および下記の無保証規定を掲載すること.
23# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
24# 報告すること.
25# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
26# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
27# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
28# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
29# 免責すること.
30#
31# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
33# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
34# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
35# の責任を負わない.
36#
37# $Id$
38#++
39
40#= HasType: @type を内部に持つ型のためのモジュール
41# @b_cloned::Bool : true if @type is cloned
42#
43# このモジュールは DefinedType, PtrType, ArrayType に include される
44# 本当は typedef された時の Decl の要素のみ clone すればよいのだが、get_type, get_original_type で
45# 取り出されたとき、set_scs, set_qualifier されたときに無条件で clone する (無駄にメモリを使用する)
46# ただし、clone するのは一回のみである (二回 clone すると別の型を参照してしまう)
47#
48# initialize で clone しても、共有されているときに clone されない
49#
50module HasType
51 def initHasType
52 @b_cloned = false
53 end
54
55 #=== HasType# @type をクローンする
56 def clone_type
57# if @b_cloned == false then
58 @type = @type.clone
59 @b_cloned = true
60# end
61 end
62end
63
64class Type < Node
65# @b_const : bool
66# @b_volatile : bool
67
68 def initialize
69 super
70 end
71
72 def set_qualifier( qualifier )
73 case qualifier
74 when :CONST
75# if @b_const then
76# cdl_error( "T1001 const duplicate" )
77# end
78 @b_const = true
79 when :VOLATILE
80# if @b_volatile then
81# cdl_error( "T1002 volatile duplicate" )
82# end
83 @b_volatile = true
84 else
85 raise "Unknown qualifier #{qualifier}"
86 end
87 end
88
89 def is_const?
90 if @b_const then
91 return true
92 else
93 return false
94 end
95 end
96
97 def is_volatile?
98 if @b_volatile then
99 return true
100 else
101 return false
102 end
103 end
104
105 def is_void?
106 if self.kind_of? DefinedType then
107 return @type.is_void?
108 elsif self.kind_of? VoidType then
109 return true
110 else
111 return false
112 end
113 end
114
115 #=== size_is, count_is, string を設定
116 # 派生クラスでオーバーライドする(デフォルトではエラー)
117 def set_scs( size, count, string, max = nil, b_nullable = false )
118 str = ""
119 delim = ""
120 if size then
121 str = "size_is"
122 delim = ", "
123 end
124 if count then
125 str = "#{str}#{delim}count_is"
126 delim = ", "
127 end
128 if string then
129 str = "#{str}#{delim}string"
130 delim = ", "
131 end
132 if b_nullable then
133 str = "#{str}#{delim}nullable"
134 delim = ", "
135 end
136 cdl_error( "T1003 $1: unsuitable specifier for $2" , str, self.class )
137 end
138
139 def clear_max
140 raise "clear_max called: #{self.class}"
141 end
142
143 def get_type_str
144 str = ""
145 if @b_const then
146 str = "#{str}const "
147 end
148 if @b_volatile then
149 str = "#{str}volatile "
150 end
151 return str
152 end
153
154 #=== 型をチェック
155 # 正当な型定義かどうか、チェックする
156 def check
157 # 型に誤りがあれば、エラー文字列を返す
158 end
159
160 #=== struct の tag をチェック
161 # 正当な型定義かどうか、チェックする
162 #kind:: Decl の @kind を参照
163 def check_struct_tag kind
164 # tag が存在しなければエラーを出力する
165 # 配列型では、要素の型を再帰的にチェック
166 # ポインタ型では、指す先の tag チェックはしない
167 # 関数型ではパラメータリストのすべてについて行う
168 end
169
170 #=== 初期化可能かチェック
171 # attribute など初期化可能かチェックする(型に対し正当な初期化子が与えられているか)
172 #ident:: string 被代入変数命
173 #initialize:: Expression, Array of initializer or C_EXP
174 # 代入値、C_EXP が与えられるのは IntType の場合のみ
175 #kind:: symbol (:ATTRIBUTE, :VAR, :CONSTNAT )
176 #attribute:: NameList kind == :VAR のとき参照できる attribute
177 #
178 # locale を第一引数として取るのは、以下の理由による。
179 # このメソッドは、変数への代入が行われる「行」に対して呼び出されるが、
180 # Type クラスのインスタンスは、変数が定義された「行」を記憶している。
181 #
182 # STAGE: S
183 def check_init( locale, ident, initializer, kind, attribute = nil )
184 #
185 end
186
187 #=== const_val を指定の型にキャストする
188 # 派生クラスでオーバーライドしていないとエラー
189 def cast( const_val )
190 cdl_error( "T1004 cannot cast to $1" , self.class )
191 end
192
193 #=== 型が一致するかのチェック
194 # 型名の字面でチェック.
195 # typedef された型も字面で一致を見るため、元の型が同じでも型名が異なれば不一致となる
196 def equal? type2
197 return ( get_type_str == type2.get_type_str ) && ( get_type_str_post == type2.get_type_str_post )
198 end
199
200 #=== bit size を得る
201 # IntType, FloatType 以外は0
202 def get_bit_size
203 return 0
204 end
205
206 #=== 元の型を得る
207 # typedef された型の場合、その元の型を返す.
208 # それ以外は、自分自身を返す.
209 # (DefinedType では本メソッドがオーバーライドされる)
210 def get_original_type
211 return self
212 end
213
214 #=== 内部にポインタ型を持つ
215 # ポインタ型、またはポインタ型メンバを持つ構造体、または要素がポインタ型を持つ配列
216 def has_pointer?
217 false
218 end
219
220 #=== size_is, count_is, string 指定されたポインタを持つか
221 # size_is, count_is, string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれをを要素に持つ配列
222 def has_sized_pointer?
223 false
224 end
225
226 #=== 長さ指定のない string を持つ
227 # なさ指定のない string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれを要素に持つ配列
228 def has_unsized_string?
229 false
230 end
231
232 def show_tree indent
233 indent.times { print " " }
234 puts "const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
235 indent.times { print " " }
236 puts "has_pointer=#{has_pointer?} has_sized_pointer=#{has_sized_pointer?} has_unsized_string=#{has_unsized_string?}"
237 end
238end
239
240class DefinedType < Type
241# @type_name::string
242# @typedef::Typedef
243# @type:: kind_of Type
244
245 include HasType
246
247 def initialize( type_name )
248 super()
249 @type_name = type_name
250
251 # mikan type_name が path になっていないため暫定
252 @typedef = Namespace.find( [ type_name ] ) #1
253
254# if @type.class != Typedef then
255# raise NotTypedef
256 # end
257 if @typedef == nil then
258 cdl_error( "T1005 \'$1\' not defined" , type_name )
259 elsif @typedef.class != Typedef then
260 cdl_error( "T1006 \'$1\' not type name. expecting type name here" , type_name )
261 end
262 @type = @typedef.get_declarator.get_type
263 initHasType
264 end
265
266 def get_type
267 clone_type
268 return @type
269 end
270
271 def get_type_str
272 "#{super}#{@type_name}"
273 end
274
275 def get_type_str_post
276 ""
277 end
278
279 def get_size
280 return @type.get_size
281 end
282
283 def is_nullable?
284 return @type.is_nullable?
285 end
286
287 #=== qualifier(const, volatile) の設定
288 def set_qualifier( qualifier )
289 clone_type
290 @type.set_qualifier( qualifier )
291 super
292 end
293
294 def set_scs( size, count, string, max = nil, b_nullable = false )
295 clone_type
296 @type.set_scs( size, count, string, max, b_nullable )
297 end
298
299 def clear_max
300 @type.clear_max
301 end
302
303 def get_original_type
304 clone_type
305 return @type.get_original_type
306 end
307
308 def check # 意味的誤りがあれば、文字列を返す
309 nil # typedef の段階で意味チェックされている
310 end
311
312 def check_init( locale, ident, initializer, kind, attribute = nil )
313 get_type.check_init( locale, ident, initializer, kind, attribute )
314 end
315
316 #=== 内部にポインタ型を持つ
317 # ポインタ型、またはポインタ型メンバを持つ構造体、または要素がポインタ型を持つ配列
318 def has_pointer?
319 @type.has_pointer?
320 end
321
322 #=== size_is, count_is, string 指定されたポインタを持つか
323 # size_is, count_is, string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれをを要素に持つ配列
324 def has_sized_pointer?
325 @type.has_sized_pointer?
326 end
327
328 #=== 長さ指定のない string を持つ
329 # なさ指定のない string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれを要素に持つ配列
330 def has_unsized_string?
331 @type.has_unsized_string?
332 end
333
334 def show_tree( indent )
335 indent.times { print " " }
336 if @typedef == nil then
337 puts "DefinedType: #{@type_name} is missing, const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
338 else
339 puts "DefinedType: #{@type_name}, const=#{@b_const} volatile=#{@b_volatile}"
340 end
341 super( indent + 1 )
342 @typedef.show_tree( indent + 1 )
343 @type.show_tree( indent + 1 )
344 end
345end
346
347class VoidType < Type
348
349 def check # 意味的誤りがあれば、文字列を返す
350 nil
351 end
352
353 def check_init( locale, ident, initializer, kind, attribute = nil )
354 cdl_error2( locale, "T1007 $1: void type variable cannot have initializer" , ident )
355 end
356
357 def get_type_str
358 "#{super}void"
359 end
360
361 def get_type_str_post
362 ""
363 end
364
365 def show_tree( indent )
366 indent.times { print " " }
367 puts "VoidType #{locale_str}"
368 super( indent + 1 )
369 end
370end
371
372class BoolType < Type
373
374 def check # 意味的誤りがあれば、文字列を返す
375 nil
376 end
377
378 def get_type_str
379 "#{super}bool_t"
380 end
381
382 def get_type_str_post
383 ""
384 end
385
386 def show_tree( indent )
387 indent.times { print " " }
388 puts "BoolType #{locale_str}"
389 super( indent + 1 )
390 end
391end
392
393class IntType < Type
394# @bit_size:: -11: char, -1: char_t, -2: short, -3: int, -4: long, -5: long long
395# 8, 16, 32, 64, 128
396# @sign:: :SIGNED, :UNSIGNED, nil
397
398 def initialize( bit_size )
399 super()
400 @bit_size = bit_size
401 @sign = nil
402 end
403
404 def set_sign( sign, b_uint = false )
405 if @sign then
406 if @sign != sign then
407 cdl_error( "T1008 ambigous signed or unsigned" )
408 end
409 elsif b_uint == false && @bit_size > 0 then
410 if sign == :SIGNED then
411 cdl_warning( "W2001 signed int$1_t: obsolete. use int$2_t" , @bit_size, @bit_size )
412 else
413 cdl_warning( "W2002 unsinged int$1_t: obsolete. use uint$2_t" , @bit_size, @bit_size )
414 end
415 end
416
417 @sign = sign
418
419 if @sign != :SIGNED && @sign != :UNSIGNED then
420 raise "set_sign: unknown sign: #{@sign}"
421 end
422 end
423
424 def check # 意味的誤りがあれば、文字列を返す
425 nil
426 end
427
428 def check_init( locale, ident, initializer, kind, attribute = nil )
429 val = initializer # C_EXP, Array
430 if val.instance_of?( Expression ) then
431 val = val.eval_const2( nil, attribute )
432 # 評価の結果 C_EXP や Array となる可能性がある
433 end
434
435 if val.instance_of? Token then # StringVal 導入により、もはや Token は来ないはず
436 # val が Token の場合 == の右辺が String だとエラーを起こす (#198)
437 cdl_error2( locale, "T1009 $1: $2: not integer" , ident, val )
438 return
439 elsif val.is_a? C_EXP then
440 # #192 var が attribute を参照し、attribute の右辺が C_EXP の場合
441 # const の右辺が C_EXP の場合も
442 return
443 elsif val.kind_of? FloatVal then
444 cdl_error2( locale, "T1011 $1: need cast to assign float to integer" , ident )
445 return
446 elsif val.instance_of? Array then
447 cdl_error2( locale, "T1017 $1: unsuitable initializer for scalar type" , ident )
448 return
449 elsif val == nil then
450 cdl_error2( locale, "T1010 $1: initializer is not constant" , ident )
451 return
452 end
453
454 if ! val.kind_of? IntegerVal then
455 cdl_error2( locale, "T1012 $1: $2: not integer" , ident, val )
456 return
457 end
458
459 val = val.to_i
460 max = get_max
461 min = get_min
462 dbgPrint "sign=#{@sign} ident=#{ident} val=#{val} max=#{max} min=#{min}\n"
463
464 if max != nil then
465 if val > max then
466 if @sign == :SIGNED || @sign == nil then
467 cdl_error2( locale, "T1013 $1: too large (max=$2)" , ident, max )
468 else
469 cdl_error2( locale, "T1016 $1: too large (max=$2)" , ident, max )
470 end
471 end
472 end
473
474 if min != nil then
475 if val < min
476 if @sign == :SIGNED || @sign == nil then
477 cdl_error2( locale, "T1014 $1: too large negative value (min=$2)" , ident, min )
478 else
479 cdl_error2( locale, "T1015 $1: negative value for unsigned" , ident )
480 end
481 end
482 end
483 end
484
485 #=== IntType# 最大値、最小値をチェックしてクリップする
486 # キャスト演算を行う
487 #in_val:: IntegerVal, FloatVal: この型にキャストする値
488 #from_type:: Symbol: :IntType, :FloatType IntType の場合はビット数でクリップ、FloatType の場合は最大値でクリップ
489 def check_and_clip( in_val, from_type = :IntType )
490 bit_size = get_bit_size
491 if bit_size == -1 then
492 bit_size = 8
493 end
494 val = in_val.to_i
495 if get_max && val > get_max then
496 if from_type == :IntType then
497 rval = ((1 << bit_size)-1) & val # bit 数でクリップ
498 else
499 rval = get_max # 最大値でクリップ (FloatType)
500 end
501 cdl_warning( "W2003 $1: too large to cast to $2, clipped($3)" , in_val, get_type_str, rval )
502 elsif get_min && val < get_min then
503 if from_type == :IntType then
504 rval = ((1 << bit_size)-1) & val
505 else
506 rval = get_min
507 end
508 if @sign == :SIGNED || @sign == nil then
509 cdl_warning( "W2004 $1: too small to cast to $2, clipped($3)" , in_val, get_type_str, rval )
510 else # @sign == :UNSIGNED || @sign == nil (char の場合)
511 cdl_warning( "W2005 $1: negative value for unsigned: convert to $2" , in_val, rval )
512 end
513 else
514 rval = val
515 end
516 return rval
517 end
518
519 def get_min
520 if @sign == :SIGNED || @sign == nil then
521 if @bit_size == -1 then
522 bit_sz = 8 # char_t は、有符号に扱う
523 else
524 bit_sz = @bit_size
525 end
526 case bit_sz
527 when 8, 16, 32, 64, 128
528 return - ( 1 << ( bit_sz - 1 ))
529 else # -1, -2, -3, -4, -5, -11
530 return nil
531 end
532 else # @sign == :UNSIGNED
533 return 0
534 end
535 end
536
537 def get_max
538 if @bit_size == -1 then
539 if @sign == nil then
540 return 255 # char_t は、無符号に扱う
541 else
542 bit_sz = 8
543 end
544 else
545 bit_sz = @bit_size
546 end
547 if @sign == :SIGNED || @sign == nil then
548 case bit_sz
549 when 8, 16, 32, 64, 128
550 return ( 1 << ( bit_sz - 1 )) -1
551 else # -1, -2, -3, -4, -5, -11
552 return nil
553 end
554 else # @sign == :UNSIGNED
555 case bit_sz
556 when 8, 16, 32, 64, 128
557 return ( 1 << bit_sz ) - 1
558 else # -2, -3, -4, -5, -11
559 return nil
560 end
561 end
562 end
563
564 #=== IntType# C 言語における型名(修飾子付き)
565 def get_type_str
566 str = super
567
568 # NEW_MODE
569 case @sign
570 when :SIGNED
571 sign = ""
572 signL = "signed "
573 when :UNSIGNED
574 sign = "u"
575 signL = "unsigned "
576 else
577 sign = ""
578 signL = ""
579 end
580
581 # p "get_type_str: sign:#{@sign} signL=#{signL}"
582
583 case @bit_size
584 when -1 # char_t 型
585 if @sign == :SIGNED then
586 sign = "s"
587 end
588 str = "#{str}#{sign}char_t"
589 when -11 # char 型(obsolete)
590 str = "#{str}#{signL}char"
591 when -2 # short 型
592 str = "#{str}#{signL}short"
593 when -3 # int 型
594 str = "#{str}#{signL}int"
595 when -4 # long 型
596 str = "#{str}#{signL}long"
597 when -5 # long long 型
598 str = "#{str}#{signL}long long"
599 when 8, 16, 32, 64, 128 # int16, int32, int64, int128 型
600 str = "#{str}#{sign}int#{@bit_size}_t"
601 end
602
603 return str
604 end
605
606 #=== IntType# C 言語における型名(後置文字列)
607 def get_type_str_post
608 ""
609 end
610
611 #=== IntType#bit_size を得る
612 # 返される値は @bit_size の仕様を参照
613 def get_bit_size
614 return @bit_size
615 end
616
617 #=== IntType# sign を得る
618 # @sign の説明を参照
619 def get_sign
620 @sign
621 end
622
623 def show_tree( indent )
624 indent.times { print " " }
625 puts "IntType bit_size=#{@bit_size} sign=#{@sign} const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
626 super( indent + 1 )
627 end
628end
629
630class FloatType < Type
631# @bit_size:: 32, 64, (80), -32, -64
632
633 def initialize( bit_size )
634 super()
635 @bit_size = bit_size
636 end
637
638 def check # 意味的誤りがあれば、文字列を返す
639 nil
640 end
641
642 # mikan Float 型の C_EXP 対応 (generate.rb にも変更必要)
643 def check_init( locale, ident, initializer, kind, attribute = nil )
644 # 型に対する初期値に誤りがあれば、エラー文字列を返す
645 val = initializer
646 if val.instance_of?( Expression ) then
647 val = val.eval_const2( nil, attribute )
648 # 評価の結果 C_EXP や Array となる可能性がある
649 end
650
651 if val.instance_of? Token then
652 # val が Token の場合 == の右辺が String だとエラーを起こす
653 cdl_error2( locale, "T1018 $1: $2: not number" , ident, val )
654 return
655 elsif val.instance_of? Array then
656 cdl_error2( locale, "T1020 $1: unsuitable initializer for scalar type" , ident )
657 return
658 elsif val.instance_of? C_EXP then
659 return
660 elsif val == nil then
661 cdl_error2( locale, "T1019 $1: initializer is not constant" , ident )
662 return
663 elsif ! val.kind_of?( IntegerVal ) && ! val.kind_of?( FloatVal ) then
664 cdl_error2( locale, "T1037 $1: not number" , ident )
665 return
666 end
667 # else
668 # cdl_error2( locale, "T1020 $1: unsuitable initializer for scalar type" , ident )
669 # return
670 # end
671 return
672 end
673
674 def get_type_str
675 str = super
676
677 case @bit_size
678 when 32
679 str = "#{str}float32_t"
680 when 64
681 str = "#{str}double64_t"
682 when -32
683 str = "#{str}float"
684 when -64
685 str = "#{str}double"
686 end
687 return str
688 end
689
690 def get_type_str_post
691 ""
692 end
693
694 def get_bit_size
695 @bit_size
696 end
697
698 def show_tree( indent )
699 indent.times { print " " }
700 puts "FloatType bit_size=#{@bit_size} qualifier=#{@qualifier} #{locale_str}"
701 super( indent + 1 )
702 end
703end
704
705class EnumType < Type # mikan
706# @bit_size:: -1: enum
707# 8, 16, 32, 64, 128
708# @element:: []
709# @element_val:: []
710
711 def initialize( bit_size )
712 super()
713 @bit_size = bit_size
714 end
715
716 def check
717 # mikan enum check
718 end
719
720 def show_tree( indent )
721 indent.times { print " " }
722 puts "EnumType bit_size=#{@bit_size} qualifier=#{@qualifier} #{locale_str}"
723 super( indent + 1 )
724 # mikan element
725 end
726end
727
728class StructType < Type
729# @tag::
730# @b_define:: true if define, false if refer
731# @members_decl:: NamedList
732# @definition:: StructType
733# @b_has_pointer_member:: bool : メンバにポインタ型がある
734# @b_has_sized_pointer_member:: bool : メンバにポインタ型がある
735# @b_has_unsized_string_member:: bool : メンバにポインタ型がある
736# @b_hasTag:: bool : タグがある
737# @member_types_symbol:: Symbol : tag が無い時のみ設定 (それ以外では nil)
738
739 @@structtype_current_stack = []
740 @@structtype_current_sp = -1
741
742 # tag なし struct
743 @@no_struct_tag_num = 0
744 @@no_tag_struct_list = {}
745
746 def initialize( tag = nil )
747 super()
748 @tag = tag
749 if tag then
750 @b_hasTag = true
751 else
752 @b_hasTag = false
753 end
754 @@structtype_current_sp += 1
755 @@structtype_current_stack[@@structtype_current_sp] = self
756 @b_has_pointer_member = false
757 @b_has_sized_pointer_member = false
758 @b_has_unsized_string_member = false
759 @member_types_symbol = nil
760 end
761
762 def self.set_define( b_define )
763 @@structtype_current_stack[@@structtype_current_sp].set_define( b_define )
764 end
765
766 def set_define( b_define )
767 @b_define = b_define
768 if @b_define then
769 @members_decl = NamedList.new( nil, "in struct #{@tag}" )
770 # if @tag then 登録タイミングを終わりに変更 V1.0.2.19
771 # Namespace.new_structtype( self )
772 # end
773 else
774 @definition = Namespace.find_tag( @tag )
775 # check_struct_tag に移す V1.0.2.19
776 # if @definition == nil then
777 # cdl_error( "T1021 \'$1\': struct not defined" , @tag )
778 # end
779 end
780 end
781
782 def self.new_member( member_decl )
783 @@structtype_current_stack[@@structtype_current_sp].new_member( member_decl )
784 end
785
786 def new_member( member_decl )
787 member_decl.set_owner self # Decl (StructType)
788 @members_decl.add_item( member_decl )
789 if member_decl.get_type.has_pointer?
790 @b_has_pointer_member = true
791 end
792 if member_decl.get_type.has_sized_pointer?
793 @b_has_sized_pointer_member = true
794 end
795 if member_decl.get_type.has_unsized_string?
796 @b_has_unsized_string_member = true
797 end
798 end
799
800 def check # 意味的誤りがあれば、文字列を返す
801 nil
802 end
803
804 #=== 構造体のタグをチェック
805 # declarator の時点でチェックする
806 #kind:: Decl の @kind を参照
807 def check_struct_tag kind
808 if @tag == nil
809 return
810 end
811
812 st = Namespace.find_tag( @tag )
813 if st == nil then
814 cdl_error( "T1022 struct $1: not defined" , @tag )
815 end
816 end
817
818 # mikan Float 型の C_EXP 対応 (generate.rb にも変更必要)
819 def check_init( locale, ident, initializer, kind, attribute = nil )
820
821 st = Namespace.find_tag( @tag )
822 if st == nil then
823 cdl_error2( locale, "T1023 struct $1: not defined" , @tag )
824 return
825 end
826
827 # 初期化子が式の場合、型(タグ)が一致するかチェック
828 if initializer.instance_of?( Expression ) then
829 t = initializer.get_type( attribute )
830 # print "Check init #{t.class} #{t.get_name}\n"
831 if ! t.kind_of?( StructType ) then
832 if t then
833 str = t.get_type_str
834 else
835 str = "unknown"
836 end
837 cdl_error2( locale, "T1038 $1: initializer type mismatch. '$2' & '$3'" , ident, get_type_str, str )
838 elsif @tag != t.get_name then
839 cdl_error2( locale, "T1039 $1: struct tag mismatch $2 and $3" , ident, @tag, t.get_name )
840 end
841 initializer = initializer.eval_const( attribute )
842 end
843
844 if initializer.instance_of?( Array ) then
845 i = 0
846 st.get_members_decl.get_items.each { |d|
847 if initializer[i] then
848 d.get_type.check_init( locale, "#{ident}.#{d.get_identifier}", initializer[i], kind )
849 end
850 i += 1
851 }
852 else
853 cdl_error2( locale, "T1024 $1: unsuitable initializer for struct" , ident )
854 end
855 end
856
857 def self.end_of_parse()
858 @@structtype_current_stack[@@structtype_current_sp].end_of_parse
859 @@structtype_current_sp -= 1
860 end
861
862 def end_of_parse()
863 if @members_decl == nil # @b_define = false またはメンバーのない構造体(エラー)
864 return
865 end
866 @members_decl.get_items.each{ |md|
867 size = md.get_size_is
868 if size then
869 val = size.eval_const( @members_decl )
870 if val == nil then
871 type = size.get_type( @members_decl )
872 if ! type.kind_of?( IntType ) then
873 cdl_error( "T1025 size_is argument is not integer type" )
874 end
875 end
876 end
877 count = md.get_count_is
878 if count then
879 val = count.eval_const( @members_decl )
880 if val == nil then
881 type = count.get_type( @members_decl )
882 if ! type.kind_of?( IntType ) then
883 cdl_error( "T1026 count_is argument is not integer type" )
884 end
885 end
886 end
887 string = md.get_string
888 if string == -1 then
889 # 長さ指定なし
890 elsif string then
891 val = string.eval_const( @members_decl )
892 if val == nil then
893 type = string.get_type( @members_decl )
894 if ! type.kind_of?( IntType ) then
895 cdl_error( "T1027 string argument is not integer type" )
896 end
897 end
898 end
899 }
900
901 if @tag == nil then
902 @member_types_symbol = get_member_types_symbol
903 # print "member_types_symbol = #{get_member_types_symbol}\n"
904 if @@no_tag_struct_list[ @member_types_symbol ] then
905 @tag = @@no_tag_struct_list[ @member_types_symbol ]
906 else
907 @tag = :"TAG_#{@@no_struct_tag_num}_TECS_internal__"
908 @@no_struct_tag_num += 1
909 @@no_tag_struct_list[ @member_types_symbol ] = @tag
910 Namespace.new_structtype( self )
911 end
912 else
913 if @b_define then
914 Namespace.new_structtype( self )
915 end
916 end
917 end
918
919 def get_name
920 @tag
921 end
922
923 def get_type_str # mikan struct get_type_str
924 str = super
925
926 if @b_hasTag then
927 # typedef struct tag StructType; の形式の場合
928 # struct の本体は、別に生成される
929 return "#{str}struct #{@tag}"
930
931 else
932 # typedef struct { int a; } StructType; の形式の場合
933 str += "struct {"
934 @members_decl.get_items.each{ |i|
935 str += sprintf( "%s %s%s;", "#{i.get_type.get_type_str}", "#{i.get_name}", "#{i.get_type.get_type_str_post}" )
936 }
937 str += "} "
938
939 return str
940
941 end
942 end
943
944 def get_type_str_post
945 ""
946 end
947
948 def get_members_decl
949 return @members_decl if @members_decl
950
951 st = Namespace.find_tag( @tag )
952 if st then
953 return st.get_members_decl
954 end
955
956 return nil
957 end
958
959 def has_pointer?
960 if @definition
961 return @definition.has_pointer?
962 else
963 return @b_has_pointer_member
964 end
965 end
966
967 def has_sized_pointer?
968 if @definition
969 return @definition.has_sized_pointer?
970 else
971 return @b_has_sized_pointer_member
972 end
973 end
974
975 def has_unsized_string?
976 if @definition
977 return @definition.has_unsized_string?
978 else
979 return @b_has_unsized_string_member
980 end
981 end
982
983 #=== 同じ構造体かどうかチェックする
984 # tag のチェックは行わない
985 # すべてのメンバの名前と型が一致することを確認する
986 def same? another
987 md = another.get_members_decl
988 if @members_decl == nil || md == nil
989 return false
990 end
991
992 md1 = @members_decl.get_items
993 md2 = md.get_items
994 if( md1.length != md2.length )
995 return false
996 end
997
998 i = 0
999 while i < md1.length
1000 if md1[i].get_name != md2[i].get_name ||
1001 md1[i].get_type.get_type_str != md2[i].get_type.get_type_str ||
1002 md1[i].get_type.get_type_str_post != md2[i].get_type.get_type_str_post
1003 return false
1004 end
1005 i += 1
1006 end
1007
1008 return true
1009 end
1010
1011 def get_member_types_symbol
1012 mts = ''
1013 @members_decl.get_items.each { |member|
1014 mts += member.get_type.get_type_str + member.get_type.get_type_str_post + ';'
1015 }
1016 return mts.to_sym
1017 end
1018
1019 def show_tree( indent )
1020 indent.times { print " " }
1021 puts "StructType tag: #{@tag} qualifier=#{@qualifier} has_pointer=#{@b_has_pointer_member} #{locale_str}"
1022 super( indent + 1 )
1023 if @b_define then
1024 @members_decl.show_tree( indent + 1 )
1025 end
1026 end
1027end
1028
1029class FuncType < Type
1030# @paramlist:: ParamList
1031# @type:: return type : PtrType, ArrayType, FuncType, IntType, FloatType, ...
1032# @b_oneway:: bool: true, false
1033# @has_in:: bool : has [in] parameter
1034# @has_inout:: bool : has [inout] parameter
1035# @has_out:: bool : has [out] parameter
1036# @has_send:: bool : has [send] parameter
1037# @has_receive:: bool : has [receive] parameter
1038
1039 def initialize( paramlist = nil )
1040 super()
1041
1042 @has_in = false
1043 @has_inout = false
1044 @has_out = false
1045 @has_send = false
1046 @has_receive = false
1047
1048 @paramlist = paramlist
1049 @b_oneway = false
1050 if paramlist then
1051 paramlist.check_param
1052 else
1053 @paramlist = ParamList.new( nil )
1054 end
1055 @paramlist.set_owner self # ParamList
1056 @paramlist.get_items.each{ |p|
1057 case p.get_direction
1058 when :IN
1059 @has_in = true
1060 when :INOUT
1061 @has_inout = true
1062 when :OUT
1063 @has_out = true
1064 when :SEND
1065 @has_send = true
1066 when :RECEIVE
1067 @has_receive = true
1068 else
1069 raise "unkown direction"
1070 end
1071 }
1072
1073 end
1074
1075 def check # 意味的誤りがあれば、文字列を返す
1076 if @type.class == ArrayType then # 配列を返す関数
1077 return "function returning array"
1078 elsif @type.class == FuncType then # 関数を返す関数
1079 return "function returning function"
1080 end
1081 return @type.check # 関数の return する型のチェック
1082
1083 # パラメータの型のチェックは ParamList#check_param で行う
1084 end
1085
1086 def check_struct_tag kind
1087 @type.check_struct_tag kind
1088 # ParamDecl でもチェックされるので、ここではチェックしない
1089 # @paramlist.check_struct_tag kind
1090 end
1091
1092 def check_init( locale, ident, initializer, kind, attribute = nil )
1093 cdl_error2( locale, "T1028 $1: cannot initialize function pointer" , ident )
1094 return
1095 end
1096
1097 def set_type( type )
1098 unless @type then
1099 @type = type
1100 else
1101 @type.set_type( type )
1102 end
1103 end
1104
1105 #=== return type を返す
1106 #
1107 # return type を返す
1108 # get_return_type とすべきだった
1109 def get_type
1110 @type
1111 end
1112
1113 def get_type_str
1114 return @type.get_type_str
1115 end
1116
1117 def get_type_str_post
1118 # 型だけを返す (仮引数の名前を含めない)
1119 @paramlist.to_str( false )
1120 end
1121
1122 def get_paramlist
1123 @paramlist
1124 end
1125
1126 def set_oneway( b_oneway )
1127 @b_oneway = b_oneway
1128
1129 if ( ( @type.get_type_str != "ER" && @type.get_type_str != "void" ) || @type.get_type_str_post != "" ) then
1130 cdl_error( "T1029 oneway function cannot return type \'$1$2\', \'void\' or \'ER\' is permitted" , @type.get_type_str, @type.get_type_str_post )
1131 end
1132
1133 if @paramlist then
1134 @paramlist.get_items.each{ |p|
1135 if p.get_direction != :IN && p.get_direction != :SEND then
1136 cdl_error( "T1030 oneway function cannot have $1 parameter for \'$2\'" , p.get_direction, p.get_name )
1137 end
1138 }
1139 end
1140 end
1141
1142 def is_oneway?
1143 @b_oneway
1144 end
1145
1146 #=== Push Pop Allocator が必要か?
1147 # Transparent RPC の場合 oneway かつ in の配列(size_is, count_is, string のいずれかで修飾)がある
1148 def need_PPAllocator?( b_opaque = false )
1149 if @b_oneway || b_opaque then
1150 return @paramlist.need_PPAllocator?( b_opaque )
1151 else
1152 return false
1153 end
1154 end
1155
1156 #=== パラメータが in, inout, out, send, receive を持つか
1157 def has_in?
1158 @has_in
1159 end
1160 def has_inout?
1161 @has_inout
1162 end
1163 def has_out?
1164 @has_out
1165 end
1166 def has_send?
1167 @has_send
1168 end
1169 def has_receive?
1170 @has_receive
1171 end
1172
1173 #=== 入力方向のパラメータを持つか
1174 def has_inward?
1175 @has_in || @has_inout || @has_send
1176 end
1177 #=== 出力方向のパラメータを持つか
1178 def has_outward?
1179 @has_inout || @has_out || @has_receive
1180 end
1181
1182 def show_tree( indent )
1183 indent.times { print " " }
1184 if @b_oneway then
1185 puts "FunctType: oneway=true #{locale_str}"
1186 else
1187 puts "FunctType: oneway=false #{locale_str}"
1188 end
1189 super( indent + 1 )
1190 if @paramlist then
1191 @paramlist.show_tree( indent + 1 )
1192 end
1193 (indent+1).times { print " " }
1194 puts "return type:"
1195 @type.show_tree( indent + 2 )
1196 end
1197end
1198
1199class ArrayType < Type
1200# @type:: element type : ArrayType, FuncType, IntType, FloatType, ...
1201# @subscript:: Expression, nil if '[]'
1202
1203 include HasType
1204
1205 def initialize( subscript = nil )
1206 super()
1207 @subscript = subscript
1208 initHasType
1209 end
1210
1211 def set_type( type )
1212 unless @type then
1213 @type = type
1214 else
1215 @type.set_type( type )
1216 end
1217 end
1218
1219 #=== Array#qualifier(const, volatile) の設定
1220 def set_qualifier( qualifier )
1221 clone_type
1222 @type.set_qualifier( qualifier )
1223 super
1224 end
1225
1226 # 配列要素が const なら const
1227 def is_const?
1228 @type.is_const?
1229 end
1230
1231 # 配列要素が volatile なら volatile
1232 def is_volatile?
1233 @type.is_volatile?
1234 end
1235
1236 def get_type
1237 @type
1238 end
1239
1240 def get_subscript
1241 @subscript
1242 end
1243
1244 def get_type_str
1245 return "#{@type.get_type_str}"
1246 end
1247
1248 def get_type_str_post
1249 if @subscript
1250 "[#{@subscript.eval_const(nil)}]#{@type.get_type_str_post}"
1251 else
1252 "[]#{@type.get_type_str_post}"
1253 end
1254 # "[#{@subscript.to_s}]#{@type.get_type_str_post}"
1255 end
1256
1257 def check # 意味的誤りがあれば、文字列を返す
1258 if @type.class == FuncType then # 関数の配列
1259 return "array of function"
1260 elsif @type.class == ArrayType then # 添数なし配列の配列
1261 unless @type.get_subscript then
1262 return "subscript not specified"
1263 end
1264 end
1265
1266 return @type.check # 配列要素の型をチェック
1267 end
1268
1269 def check_struct_tag kind
1270 @type.check_struct_tag kind
1271 end
1272
1273 def check_init( locale, ident, initializer, kind, attribute = nil )
1274 if ( initializer.instance_of?( Array ) ) then
1275 # 要素数が指定されている場合、初期化要素数をチェック
1276 if @subscript then
1277 n_sub = @subscript.eval_const( nil )
1278 if n_sub then
1279 if initializer.length > n_sub then
1280 cdl_error2( locale, "T9999 $1: too many initializer, $2 for $3" , ident, initializer.length, n_sub )
1281 end
1282 end
1283 end
1284 index = 0
1285 initializer.each{ |i|
1286 @type.check_init( locale, "#{ident}[#{index}]", i, kind, attribute = nil )
1287 index += 1
1288 }
1289 else
1290 cdl_error2( locale, "T1031 $1: unsuitable initializer for array" , ident )
1291 end
1292 end
1293
1294 def has_pointer?
1295 @type.has_pointer?
1296 end
1297
1298 def has_sized_pointer?
1299 @type.has_sized_pointer?
1300 end
1301
1302 def has_unsized_string?
1303 @type.has_unsized_string?
1304 end
1305
1306 def show_tree( indent )
1307 indent.times { print " " }
1308 puts "ArrayType: #{locale_str}"
1309 super( indent + 1 )
1310 (indent+1).times { print " " }
1311 puts "type:"
1312 @type.show_tree( indent + 2 )
1313 (indent+1).times { print " " }
1314 puts "subscript:"
1315 if @subscript then
1316 @subscript.show_tree( indent + 2 )
1317 else
1318 (indent+2).times { print " " }
1319 puts "no subscript"
1320 end
1321 end
1322end
1323
1324class PtrType < Type
1325# @type:: refer to : PtrType, FuncType, ArrayType, IntType, FloatType, ...
1326# @size:: Expr, or nil if not specified
1327# @count:: Expr, or nil if not specified
1328# @string:: Expr or -1(if size not specified) (string 引数), or nil if not specified
1329
1330 include HasType
1331
1332 def initialize( referto = nil )
1333 super()
1334 @type = referto
1335 @size = nil
1336 @count = nil
1337 @string = nil
1338 initHasType
1339 end
1340
1341 def set_type( type )
1342 unless @type then
1343 @type = type
1344 else
1345 @type.set_type( type ) # 枝先の type を設定
1346 end
1347 end
1348
1349 def get_type_str
1350 if @type.kind_of?( ArrayType ) || @type.kind_of?( FuncType ) then
1351 parenthes = "("
1352 else
1353 parenthes = ""
1354 end
1355 return "#{@type.get_type_str}#{parenthes}*"
1356 end
1357
1358 def get_type_str_post
1359 if @type.kind_of?( ArrayType ) || @type.kind_of?( FuncType ) then
1360 parenthes = ")"
1361 else
1362 parenthes = ""
1363 end
1364 "#{parenthes}#{@type.get_type_str_post}"
1365 end
1366
1367 def check # 意味的誤りがあれば、文字列を返す
1368 return nil if @type == nil
1369 @type.check
1370 end
1371
1372 def check_struct_tag kind
1373 if kind != :MEMBER # 構造体メンバーの場合、ポインタの先の構造体タグをチェックしない
1374 @type.check_struct_tag kind
1375 end
1376 end
1377
1378 def check_init( locale, ident, initializer, kind, attribute = nil )
1379 if ( initializer.instance_of?( Expression ) ) then
1380 val = initializer.eval_const2( nil, attribute )
1381 if val.kind_of? PointerVal then
1382 type = val.get_type # PtrType
1383 t1 = self
1384 t2 = type
1385 while( t1.kind_of?( PtrType ) && t2.kind_of?( PtrType ) )
1386 t1 = t1.get_type
1387 t2 = t2.get_type
1388 if ( t1.class == t2.class ) && ( t1.get_bit_size == t2.get_bit_size ) then
1389 elsif ( t1.kind_of?( CDefinedType) || t2.kind_of?( CDefinedType ) )&& t1.get_type_str == t2.get_type_str && t1.get_type_str_post && t2.get_type_str_post then
1390 # int8_t などが、一方は .h に定義されているケース
1391 else
1392 cdl_error2( locale, "T1032 $1: incompatible pointer type" , ident )
1393 break
1394 end
1395 end
1396 elsif val.kind_of? IntegerVal then
1397 if val.to_i != 0 then
1398 cdl_error2( locale, "T1033 $1: need cast to assign integer to pointer" , ident )
1399 end
1400 elsif val.kind_of? StringVal then
1401 # 文字列定数
1402 # mikan L"wide string"
1403 if @type.get_bit_size != -1 && @type.get_bit_size != -11 then # -1: char_t
1404 cdl_error2( locale, "T1034 $1: unsuitable string constant" , ident )
1405 end
1406 elsif ( val.instance_of?( Array ) ) then
1407 i = 0
1408 val.each { |ini|
1409 @type.check_init( locale, "#{ident}[#{i}]", ini, kind, attribute = nil )
1410 i += 1
1411 }
1412 elsif val.instance_of?( C_EXP ) then
1413
1414 else
1415 cdl_error2( locale, "T1035 $1: unsuitable initializer for pointer" , ident )
1416 end
1417 elsif ( initializer.instance_of?( Array ) ) then
1418 if @size == nil && @count == nil then
1419 cdl_error2( locale, "T9999 $1: non-size_is pointer cannot have array initializer", ident )
1420 end
1421
1422 i = 0
1423 initializer.each { |ini|
1424 @type.check_init( locale, "#{ident}[#{i}]", ini, kind, attribute = nil )
1425 i += 1
1426 }
1427 elsif( initializer.instance_of?( C_EXP ) ) then
1428
1429 else
1430 cdl_error2( locale, "T1036 $1: unsuitable initializer for pointer" , ident )
1431 end
1432 end
1433
1434 def get_referto
1435 clone_type
1436 @type
1437 end
1438
1439 def set_scs( size, count, string, max, b_nullable )
1440 @size = size
1441 @count = count
1442 @max = max
1443 @b_nullable = b_nullable
1444
1445 # string は最も左側の ptr に作用する
1446 if @type.kind_of?( PtrType ) then
1447 # ptr_level が 2 以上であることは ParamDecl#initializer でチェックされる
1448 clone_type
1449 @type.set_scs( nil, nil, string, nil, false )
1450 elsif @type.kind_of?( VoidType ) && ( size || count || string ) then
1451 str = ""
1452 if size then
1453 str = "size_is"
1454 end
1455 if count then
1456 if str then
1457 str += ", "
1458 end
1459 str += "count_is"
1460 end
1461 if string then
1462 if str then
1463 str += ", "
1464 end
1465 str += "string"
1466 end
1467
1468 cdl_error( "T1040 $1 specified for void pointer type", str )
1469 else
1470 @string = string
1471 end
1472
1473 if (@size != nil) && (@b_nullable != false) then
1474 cdl_error( "T9999 size_is & nullable cannot be specified simultaneously. If size is zero, pointer must be null")
1475 end
1476 end
1477
1478 def clear_max
1479 @max = nil
1480 end
1481
1482 def get_size
1483 @size
1484 end
1485
1486 def get_count
1487 @count
1488 end
1489
1490 def get_string
1491 @string
1492 end
1493
1494 #=== PtrType# size_is の最大値
1495 def get_max
1496 @max
1497 end
1498
1499 def is_nullable?
1500 return @b_nullable
1501 end
1502
1503 def get_type
1504 clone_type
1505 @type
1506 end
1507
1508 def has_pointer?
1509 true
1510 end
1511
1512 def has_sized_pointer?
1513 @size != nil || @count != nil || @string.instance_of?( Expression ) || @type.has_sized_pointer?
1514 end
1515
1516 def has_unsized_string?
1517 @string == -1 || @type.has_unsized_string?
1518 end
1519
1520 def show_tree( indent )
1521 indent.times { print " " }
1522 puts "PtrType: qualifier=#{@qualifier}, nullable=#{@b_nullable} #{locale_str}"
1523 super( indent + 1 )
1524 (indent+1).times { print " " }
1525 if @size then
1526 print "size=#{@size.to_s}, "
1527 else
1528 print "size=nil, "
1529 end
1530 if @max then
1531 print "max=#{@size.to_s}, "
1532 else
1533 print "max=nil, "
1534 end
1535 if @count then
1536 print "count=#{@count.to_s}, "
1537 else
1538 print "count=nil, "
1539 end
1540 if @string then
1541 if @string.instance_of?( Expression ) then
1542 print "string=#{@string.to_s}\n"
1543 else
1544 print "string=yes\n"
1545 end
1546 else
1547 print "string=nil\n"
1548 end
1549
1550 (indent+1).times { print " " }
1551 puts "type:"
1552 @type.show_tree( indent + 2 )
1553 end
1554
1555end
1556
1557#== DescriptorType クラス
1558# 動的結合で渡すデスクリプタ型
1559class DescriptorType < Type
1560# @sinagure_nsp::NamespacePath
1561
1562 def initialize( signature_nsp )
1563 # p "Desc #{signature_nsp.to_s}"
1564 obj = Namespace.find signature_nsp
1565 if ! obj.kind_of? Signature then
1566 cdl_error( "T9999 '$1': not signature or not found", signature_nsp.to_s )
1567 @signature_nsp = signature_nsp
1568 else
1569 if obj.has_descriptor? then
1570 # cdl_error( "T9999 '$1': has Descriptor in function parameter", signature_nsp.to_s )
1571 end
1572 @signature_nsp = obj.get_namespace_path
1573 end
1574 end
1575
1576 def get_type_str
1577 "Descriptor( #{@signature_nsp.get_global_name} )"
1578 end
1579
1580 def get_type_str_post
1581 ""
1582 end
1583
1584 def set_qualifier( qualifier )
1585 cdl_error( "T9999 '$1' cannot be specified for Descriptor", qualfier.to_s )
1586 end
1587
1588 def check
1589 end
1590
1591 def check_init( locale, ident, initializer, kind, attribute = nil )
1592 case kind
1593 when :PARAMETER
1594 # 引数は初期化できない
1595 else
1596 cdl_error2( locale, "T9999 Descriptor cannot be used for $1", kind)
1597 end
1598 end
1599
1600 #== DescriptorType#
1601 def get_signature
1602 Namespace.find @signature_nsp
1603 end
1604end
1605
1606# 以下単体テストコード
1607if $unit_test then
1608 puts( "===== Unit Test: IntType ===== (types.rb)")
1609 sizes = [ 8, 16, 32, 64 ]
1610 sizes.each{ |n|
1611 int = IntType.new n
1612 printf( "%8s max: %d min:%d\n", "int#{n}_t", int.get_max, int.get_min )
1613 }
1614 puts ""
1615end
Note: See TracBrowser for help on using the repository browser.