Skip to main content

libperl_macrogen/
semantic.rs

1//! 意味解析モジュール
2//!
3//! スコープ管理と型推論を行う。
4
5use std::collections::{HashMap, HashSet};
6
7use crate::apidoc::ApidocDict;
8use crate::ast::*;
9use crate::fields_dict::FieldsDict;
10use crate::inline_fn::InlineFnDict;
11use crate::intern::{InternedStr, StringInterner};
12use crate::parser::parse_type_from_string;
13use crate::rust_decl::RustDeclDict;
14use crate::source::{FileRegistry, SourceLocation};
15use crate::type_env::{TypeEnv, TypeConstraint as TypeEnvConstraint};
16use crate::type_repr::{
17    CTypeSource, CTypeSpecs, CDerivedType, InferredType,
18    RustTypeRepr, RustTypeSource, TypeRepr,
19};
20use crate::unified_type::{IntSize, UnifiedType};
21
22/// `Member` / `PtrMember` / `Deref` / `Cast` の連鎖を遡って leftmost の Ident
23/// を探す。Ident が macro params に含まれていれば `Some((name, expr_id))` を
24/// 返す。Call や Binary 等で連鎖が中断する場合は `None` を返す(誤推論を避ける)。
25///
26/// GCC StmtExpr による MUTABLE_PTR の展開
27/// `({ void *p_ = (expr); p_; })` も透過する(perl5 の MUTABLE_PTR は
28/// この形に展開されることがある)。
29fn leftmost_param_ident(
30    expr: &Expr,
31    params: &HashSet<InternedStr>,
32) -> Option<(InternedStr, ExprId)> {
33    let mut cur = expr;
34    loop {
35        match &cur.kind {
36            ExprKind::Member { expr: base, .. }
37            | ExprKind::PtrMember { expr: base, .. }
38            | ExprKind::Deref(base)
39            | ExprKind::Cast { expr: base, .. } => cur = base,
40            ExprKind::StmtExpr(compound) => {
41                if let Some(inner) = mutable_ptr_inner_expr(compound) {
42                    cur = inner;
43                } else {
44                    return None;
45                }
46            }
47            ExprKind::Ident(name) if params.contains(name) => {
48                return Some((*name, cur.id));
49            }
50            _ => return None,
51        }
52    }
53}
54
55/// `({ void *p_ = (expr); p_; })` という MUTABLE_PTR の GCC StmtExpr 展開を
56/// 検出し、内側の expr への参照を返す。`detect_mutable_ptr_pattern`
57/// (`src/rust_codegen.rs`) と同等の判定を semantic 側で行う。
58fn mutable_ptr_inner_expr(compound: &CompoundStmt) -> Option<&Expr> {
59    if compound.items.len() != 2 {
60        return None;
61    }
62    let decl = match &compound.items[0] {
63        BlockItem::Decl(d) => d,
64        _ => return None,
65    };
66    if decl.declarators.len() != 1 {
67        return None;
68    }
69    let init_decl = &decl.declarators[0];
70    let declared_name = init_decl.declarator.name?;
71    let init_expr = match init_decl.init.as_ref()? {
72        Initializer::Expr(e) => e.as_ref(),
73        _ => return None,
74    };
75    let last_expr = match &compound.items[1] {
76        BlockItem::Stmt(Stmt::Expr(Some(e), _)) => e,
77        _ => return None,
78    };
79    if let ExprKind::Ident(name) = &last_expr.kind {
80        if *name == declared_name {
81            return Some(init_expr);
82        }
83    }
84    None
85}
86
87/// `TypeRepr` が「無名 struct/union 型のフィールドそのもの」かを判定する。
88///
89/// 例: C で `union { ... } op_pmstashstartu;` のように書かれた anonymous
90/// union を fields_dict に格納すると、`CTypeSpecs::Struct { name: None,
91/// is_union: true }` で derived = [] となる。この場合
92/// `to_display_string` は `"union"` を返してしまい、後続 member access
93/// の base 型として使い物にならない。bindings.rs から bindgen 生成の
94/// named 型(例: `pmop__bindgen_ty_2`)に置き換える必要がある。
95fn is_anonymous_struct_or_union_field(t: &TypeRepr) -> bool {
96    if let TypeRepr::CType { specs, derived, .. } = t {
97        if !derived.is_empty() {
98            return false;
99        }
100        return matches!(
101            specs,
102            crate::type_repr::CTypeSpecs::Struct { name: None, .. }
103        );
104    }
105    false
106}
107
108/// `TypeRepr` から struct/union/typedef 名を文字列として取得する。
109///
110/// `TypeRepr::type_name()` は `InternedStr` を返すが、`RustTypeRepr` 側は
111/// String ベースで保持しているため常に `None` を返す。bindings.rs 由来の
112/// `RustType::Named("pmop__bindgen_ty_2")` のような名前も拾うために、
113/// 個別に String として取り出すヘルパーを提供する。
114fn extract_struct_name_str(t: &TypeRepr, interner: &crate::intern::StringInterner) -> Option<String> {
115    use crate::type_repr::{CTypeSpecs, RustTypeRepr};
116    match t {
117        TypeRepr::CType { specs, derived, .. } if derived.is_empty() => match specs {
118            CTypeSpecs::TypedefName(n) => Some(interner.get(*n).to_string()),
119            CTypeSpecs::Struct { name: Some(n), .. } => Some(interner.get(*n).to_string()),
120            _ => None,
121        },
122        TypeRepr::RustType { repr, .. } => match repr {
123            RustTypeRepr::Named(s) => Some(s.clone()),
124            _ => None,
125        },
126        TypeRepr::Inferred(inferred) => {
127            inferred.resolved_type().and_then(|t| extract_struct_name_str(t, interner))
128        }
129        _ => None,
130    }
131}
132
133/// 既存の `TypeRepr` の最も外側に Pointer derived を一段被せた新しい
134/// `TypeRepr` を返す。flexible array member (`T[1]`) を `T*` として扱う際に使う。
135/// 元が `RustType` や `Inferred` の場合はサポート外として `None` 相当ではなく
136/// 安全側で元をそのまま返す(呼び出し側は CType 由来のみ渡す想定)。
137fn wrap_with_outer_pointer(ty: TypeRepr, is_const: bool) -> TypeRepr {
138    use crate::type_repr::CDerivedType;
139    match ty {
140        TypeRepr::CType { specs, mut derived, source } => {
141            derived.push(CDerivedType::Pointer { is_const, is_volatile: false, is_restrict: false });
142            TypeRepr::CType { specs, derived, source }
143        }
144        other => other,
145    }
146}
147
148/// 型変数 ID (制約ベース型推論用)
149#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
150pub struct TypeVar(usize);
151
152/// 型制約 (マクロ引数の型推論用)
153#[derive(Debug, Clone)]
154pub enum TypeConstraint {
155    /// 関数呼び出しの引数として使用
156    FunctionArg {
157        var: TypeVar,
158        func_name: InternedStr,
159        arg_index: usize,
160    },
161    /// フィールドアクセスの基底として使用
162    HasField {
163        var: TypeVar,
164        field: InternedStr,
165    },
166}
167
168/// 解決済み型
169#[derive(Debug, Clone, PartialEq)]
170pub enum Type {
171    /// void
172    Void,
173    /// char
174    Char,
175    /// signed char
176    SignedChar,
177    /// unsigned char
178    UnsignedChar,
179    /// short
180    Short,
181    /// unsigned short
182    UnsignedShort,
183    /// int
184    Int,
185    /// unsigned int
186    UnsignedInt,
187    /// long
188    Long,
189    /// unsigned long
190    UnsignedLong,
191    /// long long
192    LongLong,
193    /// unsigned long long
194    UnsignedLongLong,
195    /// float
196    Float,
197    /// double
198    Double,
199    /// long double
200    LongDouble,
201    /// _Bool
202    Bool,
203    /// __int128
204    Int128,
205    /// unsigned __int128
206    UnsignedInt128,
207    /// ポインタ型
208    Pointer(Box<Type>, TypeQualifiers),
209    /// 配列型
210    Array(Box<Type>, Option<usize>),
211    /// 関数型
212    Function {
213        return_type: Box<Type>,
214        params: Vec<Type>,
215        variadic: bool,
216    },
217    /// 構造体型
218    Struct {
219        name: Option<InternedStr>,
220        /// メンバー (名前, 型)
221        members: Option<Vec<(InternedStr, Type)>>,
222    },
223    /// 共用体型
224    Union {
225        name: Option<InternedStr>,
226        members: Option<Vec<(InternedStr, Type)>>,
227    },
228    /// 列挙型
229    Enum {
230        name: Option<InternedStr>,
231    },
232    /// typedef名(未解決)
233    TypedefName(InternedStr),
234    /// 不明な型(エラー時)
235    Unknown,
236}
237
238impl Type {
239    /// 型を人間が読める形式で表示
240    pub fn display(&self, interner: &StringInterner) -> String {
241        match self {
242            Type::Void => "void".to_string(),
243            Type::Char => "char".to_string(),
244            Type::SignedChar => "signed char".to_string(),
245            Type::UnsignedChar => "unsigned char".to_string(),
246            Type::Short => "short".to_string(),
247            Type::UnsignedShort => "unsigned short".to_string(),
248            Type::Int => "int".to_string(),
249            Type::UnsignedInt => "unsigned int".to_string(),
250            Type::Long => "long".to_string(),
251            Type::UnsignedLong => "unsigned long".to_string(),
252            Type::LongLong => "long long".to_string(),
253            Type::UnsignedLongLong => "unsigned long long".to_string(),
254            Type::Float => "float".to_string(),
255            Type::Double => "double".to_string(),
256            Type::LongDouble => "long double".to_string(),
257            Type::Bool => "_Bool".to_string(),
258            Type::Int128 => "__int128".to_string(),
259            Type::UnsignedInt128 => "unsigned __int128".to_string(),
260            Type::Pointer(inner, quals) => {
261                let mut s = inner.display(interner);
262                s.push('*');
263                if quals.is_const {
264                    s.push_str(" const");
265                }
266                if quals.is_volatile {
267                    s.push_str(" volatile");
268                }
269                if quals.is_restrict {
270                    s.push_str(" restrict");
271                }
272                s
273            }
274            Type::Array(inner, size) => {
275                let inner_s = inner.display(interner);
276                match size {
277                    Some(n) => format!("{}[{}]", inner_s, n),
278                    None => format!("{}[]", inner_s),
279                }
280            }
281            Type::Function { return_type, params, variadic } => {
282                let params_s: Vec<_> = params.iter()
283                    .map(|p| p.display(interner))
284                    .collect();
285                let mut s = format!("(function {} ({}))", return_type.display(interner), params_s.join(", "));
286                if *variadic {
287                    s = s.replace("))", ", ...))");
288                }
289                s
290            }
291            Type::Struct { name, .. } => {
292                match name {
293                    Some(n) => format!("struct {}", interner.get(*n)),
294                    None => "struct <anonymous>".to_string(),
295                }
296            }
297            Type::Union { name, .. } => {
298                match name {
299                    Some(n) => format!("union {}", interner.get(*n)),
300                    None => "union <anonymous>".to_string(),
301                }
302            }
303            Type::Enum { name } => {
304                match name {
305                    Some(n) => format!("enum {}", interner.get(*n)),
306                    None => "enum <anonymous>".to_string(),
307                }
308            }
309            Type::TypedefName(name) => interner.get(*name).to_string(),
310            Type::Unknown => "<unknown>".to_string(),
311        }
312    }
313
314    /// 整数型かどうか
315    pub fn is_integer(&self) -> bool {
316        matches!(
317            self,
318            Type::Char
319                | Type::SignedChar
320                | Type::UnsignedChar
321                | Type::Short
322                | Type::UnsignedShort
323                | Type::Int
324                | Type::UnsignedInt
325                | Type::Long
326                | Type::UnsignedLong
327                | Type::LongLong
328                | Type::UnsignedLongLong
329                | Type::Bool
330                | Type::Int128
331                | Type::UnsignedInt128
332                | Type::Enum { .. }
333        )
334    }
335
336    /// 浮動小数点型かどうか
337    pub fn is_floating(&self) -> bool {
338        matches!(self, Type::Float | Type::Double | Type::LongDouble)
339    }
340
341    /// 算術型かどうか
342    pub fn is_arithmetic(&self) -> bool {
343        self.is_integer() || self.is_floating()
344    }
345
346    /// ポインタ型かどうか
347    pub fn is_pointer(&self) -> bool {
348        matches!(self, Type::Pointer(_, _))
349    }
350
351    /// UnifiedType に変換
352    pub fn to_unified(&self, interner: &StringInterner) -> UnifiedType {
353        match self {
354            Type::Void => UnifiedType::Void,
355            Type::Bool => UnifiedType::Bool,
356
357            Type::Char => UnifiedType::Char { signed: None },
358            Type::SignedChar => UnifiedType::Char { signed: Some(true) },
359            Type::UnsignedChar => UnifiedType::Char { signed: Some(false) },
360
361            Type::Short => UnifiedType::Int { signed: true, size: IntSize::Short },
362            Type::UnsignedShort => UnifiedType::Int { signed: false, size: IntSize::Short },
363            Type::Int => UnifiedType::Int { signed: true, size: IntSize::Int },
364            Type::UnsignedInt => UnifiedType::Int { signed: false, size: IntSize::Int },
365            Type::Long => UnifiedType::Int { signed: true, size: IntSize::Long },
366            Type::UnsignedLong => UnifiedType::Int { signed: false, size: IntSize::Long },
367            Type::LongLong => UnifiedType::Int { signed: true, size: IntSize::LongLong },
368            Type::UnsignedLongLong => UnifiedType::Int { signed: false, size: IntSize::LongLong },
369            Type::Int128 => UnifiedType::Int { signed: true, size: IntSize::Int128 },
370            Type::UnsignedInt128 => UnifiedType::Int { signed: false, size: IntSize::Int128 },
371
372            Type::Float => UnifiedType::Float,
373            Type::Double => UnifiedType::Double,
374            Type::LongDouble => UnifiedType::LongDouble,
375
376            Type::Pointer(inner, quals) => UnifiedType::Pointer {
377                inner: Box::new(inner.to_unified(interner)),
378                is_const: quals.is_const,
379            },
380
381            Type::Array(inner, size) => UnifiedType::Array {
382                inner: Box::new(inner.to_unified(interner)),
383                size: *size,
384            },
385
386            Type::Struct { name: Some(n), .. } => {
387                UnifiedType::Named(interner.get(*n).to_string())
388            }
389            Type::Struct { name: None, .. } => UnifiedType::Unknown,
390
391            Type::Union { name: Some(n), .. } => {
392                UnifiedType::Named(interner.get(*n).to_string())
393            }
394            Type::Union { name: None, .. } => UnifiedType::Unknown,
395
396            Type::Enum { name: Some(n) } => {
397                UnifiedType::Named(interner.get(*n).to_string())
398            }
399            Type::Enum { name: None } => UnifiedType::Int { signed: true, size: IntSize::Int },
400
401            Type::TypedefName(name) => {
402                UnifiedType::Named(interner.get(*name).to_string())
403            }
404
405            Type::Function { .. } => UnifiedType::Unknown, // 関数型は未サポート
406
407            Type::Unknown => UnifiedType::Unknown,
408        }
409    }
410}
411
412/// シンボル情報
413#[derive(Debug, Clone)]
414pub struct Symbol {
415    /// 名前
416    pub name: InternedStr,
417    /// 型
418    pub ty: Type,
419    /// 定義位置
420    pub loc: SourceLocation,
421    /// シンボルの種類
422    pub kind: SymbolKind,
423}
424
425/// シンボルの種類
426#[derive(Debug, Clone, PartialEq)]
427pub enum SymbolKind {
428    /// 変数
429    Variable,
430    /// 関数
431    Function,
432    /// typedef
433    Typedef,
434    /// 列挙定数
435    EnumConstant(i64),
436}
437
438/// スコープ
439#[derive(Debug)]
440pub struct Scope {
441    /// シンボルテーブル (名前 -> シンボル)
442    symbols: HashMap<InternedStr, Symbol>,
443    /// 親スコープID (グローバルスコープはNone)
444    parent: Option<ScopeId>,
445}
446
447impl Scope {
448    fn new(parent: Option<ScopeId>) -> Self {
449        Self {
450            symbols: HashMap::new(),
451            parent,
452        }
453    }
454}
455
456/// スコープID
457#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
458pub struct ScopeId(usize);
459
460/// 意味解析器
461pub struct SemanticAnalyzer<'a> {
462    /// 文字列インターナー
463    interner: &'a StringInterner,
464    /// スコープスタック
465    scopes: Vec<Scope>,
466    /// 現在のスコープID
467    current_scope: ScopeId,
468    /// 構造体定義 (名前 -> メンバーリスト)
469    struct_defs: HashMap<InternedStr, Vec<(InternedStr, Type)>>,
470    /// 共用体定義
471    union_defs: HashMap<InternedStr, Vec<(InternedStr, Type)>>,
472    /// typedef定義 (名前 -> 型)
473    typedef_defs: HashMap<InternedStr, Type>,
474    /// Apidoc辞書(関数/マクロのシグネチャ情報)
475    apidoc: Option<&'a ApidocDict>,
476    /// フィールド辞書(構造体フィールドの型情報)
477    fields_dict: Option<&'a FieldsDict>,
478    /// RustDeclDict への参照 (bindings.rs の関数型情報)
479    rust_decl_dict: Option<&'a RustDeclDict>,
480    /// InlineFnDict への参照 (inline関数のAST情報)
481    inline_fn_dict: Option<&'a InlineFnDict>,
482    /// 型変数マップ (引数名 -> TypeVar)
483    type_vars: HashMap<InternedStr, TypeVar>,
484    /// 次の型変数ID
485    next_type_var: usize,
486    /// 収集された制約
487    constraints: Vec<TypeConstraint>,
488    /// 制約収集モードか
489    constraint_mode: bool,
490    /// マクロパラメータ名の集合(型制約収集用)
491    macro_params: HashSet<InternedStr>,
492    /// 確定済みマクロの戻り値型(マクロ名 -> 戻り値型)への参照
493    macro_return_types: Option<&'a HashMap<String, String>>,
494    /// 確定済みマクロのパラメータ型(マクロ名 -> [(パラメータ名, 型)])への参照
495    /// ネストしたマクロ呼び出しからの型伝播に使用
496    macro_param_types: Option<&'a HashMap<String, Vec<(String, String)>>>,
497    /// ファイルレジストリ(型文字列パース用)
498    files: Option<&'a FileRegistry>,
499    /// typedef 名の集合(型文字列パース用)
500    parser_typedefs: Option<&'a HashSet<InternedStr>>,
501}
502
503impl<'a> SemanticAnalyzer<'a> {
504    /// 新しい意味解析器を作成
505    pub fn new(
506        interner: &'a StringInterner,
507        apidoc: Option<&'a ApidocDict>,
508        fields_dict: Option<&'a FieldsDict>,
509    ) -> Self {
510        Self::with_rust_decl_dict(interner, apidoc, fields_dict, None, None)
511    }
512
513    /// RustDeclDict と InlineFnDict を指定して意味解析器を作成
514    pub fn with_rust_decl_dict(
515        interner: &'a StringInterner,
516        apidoc: Option<&'a ApidocDict>,
517        fields_dict: Option<&'a FieldsDict>,
518        rust_decl_dict: Option<&'a RustDeclDict>,
519        inline_fn_dict: Option<&'a InlineFnDict>,
520    ) -> Self {
521        let global_scope = Scope::new(None);
522        Self {
523            interner,
524            scopes: vec![global_scope],
525            current_scope: ScopeId(0),
526            struct_defs: HashMap::new(),
527            union_defs: HashMap::new(),
528            typedef_defs: HashMap::new(),
529            apidoc,
530            fields_dict,
531            rust_decl_dict,
532            inline_fn_dict,
533            type_vars: HashMap::new(),
534            next_type_var: 0,
535            constraints: Vec::new(),
536            constraint_mode: false,
537            macro_params: HashSet::new(),
538            macro_return_types: None,
539            macro_param_types: None,
540            files: None,
541            parser_typedefs: None,
542        }
543    }
544
545    /// 確定済みマクロの戻り値型キャッシュへの参照を設定
546    pub fn set_macro_return_types(&mut self, cache: &'a HashMap<String, String>) {
547        self.macro_return_types = Some(cache);
548    }
549
550    /// 確定済みマクロのパラメータ型キャッシュへの参照を設定
551    pub fn set_macro_param_types(&mut self, cache: &'a HashMap<String, Vec<(String, String)>>) {
552        self.macro_param_types = Some(cache);
553    }
554
555    /// マクロの戻り値型を取得
556    pub fn get_macro_return_type(&self, macro_name: &str) -> Option<&str> {
557        self.macro_return_types
558            .and_then(|cache| cache.get(macro_name))
559            .map(|s| s.as_str())
560    }
561
562    /// マクロのパラメータ型を取得
563    pub fn get_macro_param_types(&self, macro_name: &str) -> Option<&Vec<(String, String)>> {
564        self.macro_param_types
565            .and_then(|cache| cache.get(macro_name))
566    }
567
568    /// 新しいスコープを開始
569    pub fn push_scope(&mut self) {
570        let new_scope = Scope::new(Some(self.current_scope));
571        let new_id = ScopeId(self.scopes.len());
572        self.scopes.push(new_scope);
573        self.current_scope = new_id;
574    }
575
576    /// 現在のスコープを終了
577    pub fn pop_scope(&mut self) {
578        if let Some(parent) = self.scopes[self.current_scope.0].parent {
579            self.current_scope = parent;
580        }
581    }
582
583    /// シンボルを現在のスコープに追加
584    pub fn define_symbol(&mut self, symbol: Symbol) {
585        let scope = &mut self.scopes[self.current_scope.0];
586        scope.symbols.insert(symbol.name, symbol);
587    }
588
589    /// シンボルを検索(現在のスコープから親スコープへ)
590    pub fn lookup_symbol(&self, name: InternedStr) -> Option<&Symbol> {
591        let mut scope_id = Some(self.current_scope);
592        while let Some(id) = scope_id {
593            let scope = &self.scopes[id.0];
594            if let Some(sym) = scope.symbols.get(&name) {
595                return Some(sym);
596            }
597            scope_id = scope.parent;
598        }
599        None
600    }
601
602    // ========================================
603    // 制約ベース型推論 (マクロ引数用)
604    // ========================================
605
606    /// 制約収集モードを開始し、パラメータを型変数として登録
607    pub fn begin_param_inference(&mut self, params: &[InternedStr]) {
608        self.constraint_mode = true;
609        self.type_vars.clear();
610        self.constraints.clear();
611        self.next_type_var = 0;
612
613        for &param in params {
614            let var = TypeVar(self.next_type_var);
615            self.next_type_var += 1;
616            self.type_vars.insert(param, var);
617        }
618    }
619
620    /// 制約を解いて引数型を取得し、制約収集モードを終了
621    pub fn end_param_inference(&mut self) -> HashMap<InternedStr, Type> {
622        self.constraint_mode = false;
623        let solutions = self.solve_constraints();
624
625        // 型変数名から Type へのマップを構築
626        let mut result = HashMap::new();
627        for (&name, &var) in &self.type_vars {
628            if let Some(ty) = solutions.get(&var) {
629                result.insert(name, ty.clone());
630            }
631        }
632
633        // クリーンアップ
634        self.type_vars.clear();
635        self.constraints.clear();
636        self.next_type_var = 0;
637
638        result
639    }
640
641    /// 制約を解く
642    fn solve_constraints(&self) -> HashMap<TypeVar, Type> {
643        let mut solutions = HashMap::new();
644
645        for constraint in &self.constraints {
646            match constraint {
647                TypeConstraint::FunctionArg { var, func_name, arg_index } => {
648                    if solutions.contains_key(var) {
649                        continue;
650                    }
651
652                    // RustDeclDict (bindings.rs) から関数シグネチャを取得
653                    if let Some(ty) = self.lookup_rust_decl_param_type(*func_name, *arg_index) {
654                        solutions.insert(*var, ty);
655                    }
656                }
657                TypeConstraint::HasField { var, field } => {
658                    if solutions.contains_key(var) {
659                        continue;
660                    }
661
662                    // FieldsDict からフィールドを持つ構造体を特定
663                    if let Some(fields_dict) = self.fields_dict {
664                        if let Some(struct_name) = fields_dict.lookup_unique(*field) {
665                            // struct_name は既に InternedStr なので直接使用
666                            solutions.insert(
667                                *var,
668                                Type::Pointer(
669                                    Box::new(Type::TypedefName(struct_name)),
670                                    TypeQualifiers::default(),
671                                ),
672                            );
673                        }
674                    }
675                }
676            }
677        }
678
679        solutions
680    }
681
682    /// RustDeclDict から関数の引数型を取得
683    fn lookup_rust_decl_param_type(&self, func_name: InternedStr, arg_index: usize) -> Option<Type> {
684        let rust_decl_dict = self.rust_decl_dict?;
685        let func_name_str = self.interner.get(func_name);
686        let rust_fn = rust_decl_dict.fns.get(func_name_str)?;
687        let param = rust_fn.params.get(arg_index)?;
688        // Rust型文字列 (e.g., "*mut *mut SV") を Type に変換
689        Some(self.parse_rust_type_string(&param.ty))
690    }
691
692    /// InlineFnDict から inline 関数の引数型を取得
693    /// InlineFnDict から inline 関数のパラメータ型を TypeRepr として直接取得
694    ///
695    /// AST (DeclSpecs + Declarator) から TypeRepr を直接構築する。
696    /// 文字列への変換・再パースを経由しないため、修飾子付きポインタ等も正確に処理できる。
697    fn lookup_inline_fn_param_type_repr(
698        &self,
699        func_name: InternedStr,
700        arg_index: usize,
701    ) -> Option<TypeRepr> {
702        let dict = self.inline_fn_dict?;
703        let func_def = dict.get(func_name)?;
704
705        let param_list = func_def.declarator.derived.iter()
706            .find_map(|d| match d {
707                DerivedDecl::Function(params) => Some(params),
708                _ => None,
709            })?;
710
711        let param = param_list.params.get(arg_index)?;
712
713        let specs = CTypeSpecs::from_decl_specs(&param.specs, self.interner);
714        let derived = param.declarator.as_ref()
715            .map(|d| {
716                // Function 派生型より前の部分のみ(パラメータ自体の型)
717                CDerivedType::from_derived_decls_with_base_const(
718                    &d.derived, param.specs.qualifiers.is_const)
719                    .into_iter()
720                    .take_while(|d| !matches!(d, CDerivedType::Function { .. }))
721                    .collect()
722            })
723            .unwrap_or_default();
724
725        Some(TypeRepr::CType {
726            specs,
727            derived,
728            source: CTypeSource::InlineFn { func_name },
729        })
730    }
731
732    /// InlineFnDict から inline 関数の戻り値型を TypeRepr として直接取得
733    fn lookup_inline_fn_return_type_repr(&self, func_name: InternedStr) -> Option<TypeRepr> {
734        let dict = self.inline_fn_dict?;
735        let func_def = dict.get(func_name)?;
736
737        let specs = CTypeSpecs::from_decl_specs(&func_def.specs, self.interner);
738
739        // Declarator の Function より前の derived 部分のみ(戻り値のポインタ等)
740        let derived: Vec<_> = CDerivedType::from_derived_decls_with_base_const(
741            &func_def.declarator.derived, func_def.specs.qualifiers.is_const)
742            .into_iter()
743            .take_while(|d| !matches!(d, CDerivedType::Function { .. }))
744            .collect();
745
746        Some(TypeRepr::CType {
747            specs,
748            derived,
749            source: CTypeSource::InlineFn { func_name },
750        })
751    }
752
753    /// DeclSpecs から Type を構築
754    pub fn resolve_decl_specs(&mut self, specs: &DeclSpecs) -> Type {
755        // 型指定子を集める
756        let mut is_signed = false;
757        let mut is_unsigned = false;
758        let mut is_short = false;
759        let mut is_long = 0u8; // longの個数
760        let mut base_type: Option<Type> = None;
761
762        for spec in &specs.type_specs {
763            match spec {
764                TypeSpec::Void => base_type = Some(Type::Void),
765                TypeSpec::Char => base_type = Some(Type::Char),
766                TypeSpec::Short => is_short = true,
767                TypeSpec::Int => {
768                    if base_type.is_none() {
769                        base_type = Some(Type::Int);
770                    }
771                }
772                TypeSpec::Long => is_long += 1,
773                TypeSpec::Float => base_type = Some(Type::Float),
774                TypeSpec::Double => base_type = Some(Type::Double),
775                TypeSpec::Signed => is_signed = true,
776                TypeSpec::Unsigned => is_unsigned = true,
777                TypeSpec::Bool => base_type = Some(Type::Bool),
778                TypeSpec::Int128 => base_type = Some(Type::Int128),
779                TypeSpec::Struct(s) => {
780                    let members = self.resolve_struct_members(s);
781                    if let (Some(name), Some(m)) = (s.name, &members) {
782                        self.struct_defs.insert(name, m.clone());
783                    }
784                    base_type = Some(Type::Struct {
785                        name: s.name,
786                        members,
787                    });
788                }
789                TypeSpec::Union(s) => {
790                    let members = self.resolve_struct_members(s);
791                    if let (Some(name), Some(m)) = (s.name, &members) {
792                        self.union_defs.insert(name, m.clone());
793                    }
794                    base_type = Some(Type::Union {
795                        name: s.name,
796                        members,
797                    });
798                }
799                TypeSpec::Enum(e) => {
800                    // 列挙定数を登録
801                    self.process_enum(e);
802                    base_type = Some(Type::Enum { name: e.name });
803                }
804                TypeSpec::TypedefName(name) => {
805                    // typedefを解決
806                    if let Some(ty) = self.typedef_defs.get(name) {
807                        base_type = Some(ty.clone());
808                    } else {
809                        base_type = Some(Type::TypedefName(*name));
810                    }
811                }
812                TypeSpec::TypeofExpr(_) => {
813                    // TODO: typeof式の型を推論
814                    base_type = Some(Type::Unknown);
815                }
816                _ => {}
817            }
818        }
819
820        // 型修飾子を組み合わせる
821        match (is_unsigned, is_signed, is_short, is_long, &base_type) {
822            // unsigned指定
823            (true, _, _, 0, None) | (true, _, _, 0, Some(Type::Int)) => Type::UnsignedInt,
824            (true, _, _, 1, _) => Type::UnsignedLong,
825            (true, _, _, 2, _) => Type::UnsignedLongLong,
826            (true, _, true, _, _) => Type::UnsignedShort,
827            (true, _, _, _, Some(Type::Char)) => Type::UnsignedChar,
828            (true, _, _, _, Some(Type::Int128)) => Type::UnsignedInt128,
829            // signed指定
830            (_, true, _, _, Some(Type::Char)) => Type::SignedChar,
831            // long指定
832            (_, _, _, 1, None) | (_, _, _, 1, Some(Type::Int)) => Type::Long,
833            (_, _, _, 2, _) => Type::LongLong,
834            (_, _, _, 1, Some(Type::Double)) => Type::LongDouble,
835            // short指定
836            (_, _, true, _, _) => Type::Short,
837            // デフォルト
838            _ => base_type.unwrap_or(Type::Int),
839        }
840    }
841
842    /// 構造体メンバーを解決
843    fn resolve_struct_members(&mut self, spec: &StructSpec) -> Option<Vec<(InternedStr, Type)>> {
844        spec.members.as_ref().map(|members| {
845            let mut result = Vec::new();
846            for member in members {
847                let base_ty = self.resolve_decl_specs(&member.specs);
848                for decl in &member.declarators {
849                    if let Some(ref d) = decl.declarator {
850                        if let Some(name) = d.name {
851                            let ty = self.apply_declarator(&base_ty, d);
852                            result.push((name, ty));
853                        }
854                    }
855                }
856            }
857            result
858        })
859    }
860
861    /// 列挙型を処理
862    fn process_enum(&mut self, spec: &EnumSpec) {
863        if let Some(ref enumerators) = spec.enumerators {
864            let mut value = 0i64;
865            for e in enumerators {
866                if e.value.is_some() {
867                    // TODO: 定数式を評価
868                    value = 0; // 仮
869                }
870                self.define_symbol(Symbol {
871                    name: e.name,
872                    ty: Type::Int,
873                    loc: spec.loc.clone(),
874                    kind: SymbolKind::EnumConstant(value),
875                });
876                value += 1;
877            }
878        }
879    }
880
881    /// Declarator を適用して型を構築
882    pub fn apply_declarator(&self, base_type: &Type, decl: &Declarator) -> Type {
883        let mut ty = base_type.clone();
884
885        for derived in &decl.derived {
886            ty = match derived {
887                DerivedDecl::Pointer(quals) => Type::Pointer(Box::new(ty), quals.clone()),
888                DerivedDecl::Array(arr) => {
889                    // TODO: サイズを評価
890                    let _size = &arr.size;
891                    Type::Array(Box::new(ty), None)
892                }
893                DerivedDecl::Function(params) => {
894                    let param_types: Vec<_> = params.params
895                        .iter()
896                        .map(|p| {
897                            let base = self.resolve_decl_specs_readonly(&p.specs);
898                            if let Some(ref d) = p.declarator {
899                                self.apply_declarator(&base, d)
900                            } else {
901                                base
902                            }
903                        })
904                        .collect();
905                    Type::Function {
906                        return_type: Box::new(ty),
907                        params: param_types,
908                        variadic: params.is_variadic,
909                    }
910                }
911            };
912        }
913
914        ty
915    }
916
917    /// DeclSpecs を読み取り専用で解決(再帰呼び出し用)
918    fn resolve_decl_specs_readonly(&self, specs: &DeclSpecs) -> Type {
919        // 簡略版: 主要な型のみ処理
920        let mut is_unsigned = false;
921        let mut is_long = 0u8;
922        let mut base_type: Option<Type> = None;
923
924        for spec in &specs.type_specs {
925            match spec {
926                TypeSpec::Void => base_type = Some(Type::Void),
927                TypeSpec::Char => base_type = Some(Type::Char),
928                TypeSpec::Int => base_type = Some(Type::Int),
929                TypeSpec::Long => is_long += 1,
930                TypeSpec::Float => base_type = Some(Type::Float),
931                TypeSpec::Double => base_type = Some(Type::Double),
932                TypeSpec::Unsigned => is_unsigned = true,
933                TypeSpec::Bool => base_type = Some(Type::Bool),
934                TypeSpec::TypedefName(name) => {
935                    if let Some(ty) = self.typedef_defs.get(name) {
936                        base_type = Some(ty.clone());
937                    } else {
938                        base_type = Some(Type::TypedefName(*name));
939                    }
940                }
941                _ => {}
942            }
943        }
944
945        match (is_unsigned, is_long, &base_type) {
946            (true, 0, None) | (true, 0, Some(Type::Int)) => Type::UnsignedInt,
947            (true, 1, _) => Type::UnsignedLong,
948            (_, 1, None) | (_, 1, Some(Type::Int)) => Type::Long,
949            (_, 2, _) => Type::LongLong,
950            _ => base_type.unwrap_or(Type::Int),
951        }
952    }
953
954    /// TypeName から型を解決
955    pub fn resolve_type_name(&self, type_name: &TypeName) -> Type {
956        let base_ty = self.resolve_decl_specs_readonly(&type_name.specs);
957        if let Some(ref abs_decl) = type_name.declarator {
958            self.apply_abstract_declarator(&base_ty, abs_decl)
959        } else {
960            base_ty
961        }
962    }
963
964    /// AbstractDeclarator を適用して型を構築
965    fn apply_abstract_declarator(&self, base_type: &Type, decl: &AbstractDeclarator) -> Type {
966        let mut ty = base_type.clone();
967
968        for derived in &decl.derived {
969            ty = match derived {
970                DerivedDecl::Pointer(quals) => Type::Pointer(Box::new(ty), quals.clone()),
971                DerivedDecl::Array(_) => {
972                    Type::Array(Box::new(ty), None)
973                }
974                DerivedDecl::Function(params) => {
975                    let param_types: Vec<_> = params.params
976                        .iter()
977                        .map(|p| {
978                            let base = self.resolve_decl_specs_readonly(&p.specs);
979                            if let Some(ref d) = p.declarator {
980                                self.apply_declarator(&base, d)
981                            } else {
982                                base
983                            }
984                        })
985                        .collect();
986                    Type::Function {
987                        return_type: Box::new(ty),
988                        params: param_types,
989                        variadic: params.is_variadic,
990                    }
991                }
992            };
993        }
994
995        ty
996    }
997
998    /// 宣言を処理してシンボルを登録
999    pub fn process_declaration(&mut self, decl: &Declaration) {
1000        let base_ty = self.resolve_decl_specs(&decl.specs);
1001
1002        // typedefの場合
1003        if decl.specs.storage == Some(StorageClass::Typedef) {
1004            for init_decl in &decl.declarators {
1005                if let Some(name) = init_decl.declarator.name {
1006                    let ty = self.apply_declarator(&base_ty, &init_decl.declarator);
1007                    self.typedef_defs.insert(name, ty);
1008                }
1009            }
1010            return;
1011        }
1012
1013        // 通常の変数宣言
1014        for init_decl in &decl.declarators {
1015            if let Some(name) = init_decl.declarator.name {
1016                let ty = self.apply_declarator(&base_ty, &init_decl.declarator);
1017                self.define_symbol(Symbol {
1018                    name,
1019                    ty,
1020                    loc: decl.loc().clone(),
1021                    kind: SymbolKind::Variable,
1022                });
1023            }
1024        }
1025    }
1026
1027    /// 関数定義を処理
1028    pub fn process_function_def(&mut self, func: &FunctionDef) {
1029        let return_ty = self.resolve_decl_specs(&func.specs);
1030        let func_ty = self.apply_declarator(&return_ty, &func.declarator);
1031
1032        // 関数をグローバルスコープに登録
1033        if let Some(name) = func.declarator.name {
1034            self.define_symbol(Symbol {
1035                name,
1036                ty: func_ty.clone(),
1037                loc: func.loc().clone(),
1038                kind: SymbolKind::Function,
1039            });
1040        }
1041
1042        // 関数本体用のスコープを開始
1043        self.push_scope();
1044
1045        // パラメータを登録
1046        if let Type::Function { params, .. } = &func_ty {
1047            for derived in &func.declarator.derived {
1048                if let DerivedDecl::Function(param_list) = derived {
1049                    for (param, param_ty) in param_list.params.iter().zip(params.iter()) {
1050                        if let Some(ref decl) = param.declarator {
1051                            if let Some(name) = decl.name {
1052                                self.define_symbol(Symbol {
1053                                    name,
1054                                    ty: param_ty.clone(),
1055                                    loc: func.loc().clone(),
1056                                    kind: SymbolKind::Variable,
1057                                });
1058                            }
1059                        }
1060                    }
1061                    break;
1062                }
1063            }
1064        }
1065
1066        // 関数本体を処理
1067        self.process_compound_stmt(&func.body);
1068
1069        self.pop_scope();
1070    }
1071
1072    /// 複合文を処理
1073    pub fn process_compound_stmt(&mut self, stmt: &CompoundStmt) {
1074        self.push_scope();
1075        for item in &stmt.items {
1076            match item {
1077                BlockItem::Decl(decl) => self.process_declaration(decl),
1078                BlockItem::Stmt(stmt) => self.process_stmt(stmt),
1079            }
1080        }
1081        self.pop_scope();
1082    }
1083
1084    /// 文を処理
1085    fn process_stmt(&mut self, stmt: &Stmt) {
1086        match stmt {
1087            Stmt::Compound(compound) => self.process_compound_stmt(compound),
1088            Stmt::For { init, .. } => {
1089                self.push_scope();
1090                if let Some(ForInit::Decl(decl)) = init {
1091                    self.process_declaration(decl);
1092                }
1093                // TODO: 本体を処理
1094                self.pop_scope();
1095            }
1096            _ => {}
1097        }
1098    }
1099
1100    // ========================================
1101    // TypeEnv への型制約収集
1102    // ========================================
1103
1104    /// マクロパラメータを設定
1105    pub fn set_macro_params(&mut self, params: &[InternedStr]) {
1106        self.macro_params.clear();
1107        for &param in params {
1108            self.macro_params.insert(param);
1109        }
1110    }
1111
1112    /// マクロパラメータをクリア
1113    pub fn clear_macro_params(&mut self) {
1114        self.macro_params.clear();
1115    }
1116
1117    /// マクロパラメータを apidoc 型情報付きでシンボルテーブルに登録
1118    ///
1119    /// # Arguments
1120    /// * `macro_name` - マクロ名
1121    /// * `params` - パラメータ名のリスト
1122    /// * `files` - ファイルレジストリ
1123    /// * `typedefs` - typedef 名セット
1124    pub fn register_macro_params_from_apidoc(
1125        &mut self,
1126        macro_name: InternedStr,
1127        params: &[InternedStr],
1128        files: &'a FileRegistry,
1129        typedefs: &'a HashSet<InternedStr>,
1130    ) {
1131        // files と typedefs を保存(後で型パース時に使用)
1132        self.files = Some(files);
1133        self.parser_typedefs = Some(typedefs);
1134
1135        // macro_params に名前を登録(既存の動作を維持)
1136        self.macro_params.clear();
1137        for &param in params {
1138            self.macro_params.insert(param);
1139        }
1140
1141        // apidoc からマクロ情報を取得
1142        let macro_name_str = self.interner.get(macro_name);
1143        if let Some(apidoc) = self.apidoc {
1144            if let Some(entry) = apidoc.get(macro_name_str) {
1145                // パラメータをシンボルとして登録
1146                for (i, &param_name) in params.iter().enumerate() {
1147                    if let Some(apidoc_arg) = entry.args.get(i) {
1148                        // parser で型文字列をパース
1149                        match parse_type_from_string(
1150                            &apidoc_arg.ty,
1151                            self.interner,
1152                            files,
1153                            typedefs,
1154                        ) {
1155                            Ok(type_name) => {
1156                                let ty = self.resolve_type_name(&type_name);
1157                                self.define_symbol(Symbol {
1158                                    name: param_name,
1159                                    ty,
1160                                    loc: SourceLocation::default(),
1161                                    kind: SymbolKind::Variable,
1162                                });
1163                            }
1164                            Err(_) => {}
1165                        }
1166                    }
1167                }
1168            }
1169        }
1170    }
1171
1172    /// C 型文字列から TypeRepr を作成
1173    ///
1174    /// `files` と `parser_typedefs` が設定されている場合は完全な C パーサーを使用。
1175    /// 設定されていない場合は簡易パーサーにフォールバック。
1176    fn parse_type_string(&self, s: &str) -> TypeRepr {
1177        if let (Some(files), Some(typedefs)) = (self.files, self.parser_typedefs) {
1178            TypeRepr::from_c_type_string(s, self.interner, files, typedefs)
1179        } else {
1180            TypeRepr::from_apidoc_string(s, self.interner)
1181        }
1182    }
1183
1184    /// 識別子がマクロパラメータかどうか
1185    fn is_macro_param(&self, name: InternedStr) -> bool {
1186        self.macro_params.contains(&name)
1187    }
1188
1189    /// *mut SV を表す TypeRepr を作成
1190    fn make_sv_ptr_type(&self) -> TypeRepr {
1191        let sv_name = self.interner.lookup("SV")
1192            .expect("SV should be interned");
1193        TypeRepr::CType {
1194            specs: CTypeSpecs::TypedefName(sv_name),
1195            derived: vec![CDerivedType::Pointer { is_const: false, is_volatile: false, is_restrict: false }],
1196            source: CTypeSource::SvFamilyCast,
1197        }
1198    }
1199
1200    /// `*mut <typedef>` 形式の SV ファミリー型を作成(共通マクロ由来、tier 3)
1201    fn make_sv_family_ptr_type(&self, typedef_name: InternedStr) -> TypeRepr {
1202        TypeRepr::CType {
1203            specs: CTypeSpecs::TypedefName(typedef_name),
1204            derived: vec![CDerivedType::Pointer { is_const: false, is_volatile: false, is_restrict: false }],
1205            source: CTypeSource::CommonMacroFieldInference,
1206        }
1207    }
1208
1209    /// 共通フィールドマクロ宣言フィールドへのアクセス経路から SV ファミリー
1210    /// パラメータ型を逆推論する。
1211    ///
1212    /// 例: `(cv)->sv_any->xcv_gv_u` の `xcv_gv_u` は `_XPVCV_COMMON` 由来 →
1213    /// 経路を辿って `cv` macro param に `*mut CV` 制約を追加。
1214    fn try_infer_sv_family_from_member(
1215        &self,
1216        member: InternedStr,
1217        base: &Expr,
1218        type_env: &mut TypeEnv,
1219    ) {
1220        let Some(fields_dict) = self.fields_dict else { return };
1221        let Some(macro_id) = fields_dict.defining_macro_of(member) else { return };
1222        let Some(sv_typedef) = fields_dict.sv_family_of_common_macro(macro_id) else { return };
1223        let Some((_param_name, param_node_id)) = leftmost_param_ident(base, &self.macro_params)
1224        else {
1225            return;
1226        };
1227        let sv_type = self.make_sv_family_ptr_type(sv_typedef);
1228        let typedef_str = self.interner.get(sv_typedef);
1229        let member_str = self.interner.get(member);
1230        type_env.add_constraint(TypeEnvConstraint::new(
1231            param_node_id,
1232            sv_type,
1233            format!("common-macro field {} implies {}*", member_str, typedef_str),
1234        ));
1235    }
1236
1237    /// type_env から式の TypeRepr を直接取得
1238    fn get_expr_type_repr(&self, expr_id: ExprId, type_env: &TypeEnv) -> Option<TypeRepr> {
1239        type_env.expr_constraints.get(&expr_id)
1240            .and_then(|c| c.first())
1241            .map(|c| c.ty.clone())
1242    }
1243
1244    /// type_env から式の TypeRepr を取得、無ければ "<unknown>" 由来の Void を返す。
1245    /// 旧 `get_expr_type_str` + `from_apidoc_string` round-trip を置き換える。
1246    /// round-trip だと RustType("*mut T" 等の Rust 表記)が C 専用パーサに
1247    /// 渡されて Void に潰れていたため、TypeRepr を直接保持することで型情報を
1248    /// 維持する。
1249    fn get_expr_type_repr_or_unknown(&self, expr_id: ExprId, type_env: &TypeEnv) -> TypeRepr {
1250        self.get_expr_type_repr(expr_id, type_env)
1251            .unwrap_or_else(|| TypeRepr::from_apidoc_string("<unknown>", self.interner))
1252    }
1253
1254    /// type_env から式の型文字列を取得
1255    fn get_expr_type_str(&self, expr_id: ExprId, type_env: &TypeEnv) -> String {
1256        if let Some(constraints) = type_env.expr_constraints.get(&expr_id) {
1257            if let Some(c) = constraints.first() {
1258                return c.ty.to_display_string(self.interner);
1259            }
1260        }
1261        "<unknown>".to_string()
1262    }
1263
1264    /// 二項演算の結果型を計算(文字列ベース)
1265    fn compute_binary_type_str(&self, op: &BinOp, lhs_id: ExprId, rhs_id: ExprId, type_env: &TypeEnv) -> String {
1266        match op {
1267            // 比較演算子・論理演算子は int を返す
1268            BinOp::Lt | BinOp::Gt | BinOp::Le | BinOp::Ge |
1269            BinOp::Eq | BinOp::Ne | BinOp::LogAnd | BinOp::LogOr => "int".to_string(),
1270            // 算術演算子は通常の型昇格
1271            _ => {
1272                let lhs_ty = self.get_expr_type_str(lhs_id, type_env);
1273                let rhs_ty = self.get_expr_type_str(rhs_id, type_env);
1274                self.usual_arithmetic_conversion_str(&lhs_ty, &rhs_ty)
1275            }
1276        }
1277    }
1278
1279    /// 通常の算術型変換(文字列ベース)
1280    fn usual_arithmetic_conversion_str(&self, lhs: &str, rhs: &str) -> String {
1281        // ポインタ型が含まれる場合はポインタ型を優先
1282        let is_ptr = |ty: &str| ty.contains('*');
1283        if is_ptr(lhs) && !is_ptr(rhs) {
1284            return lhs.to_string();
1285        }
1286        if is_ptr(rhs) && !is_ptr(lhs) {
1287            return rhs.to_string();
1288        }
1289
1290        // 簡易的な実装:ランク付けで大きい方を返す
1291        let rank = |ty: &str| -> u8 {
1292            match ty {
1293                "long double" => 10,
1294                "double" => 9,
1295                "float" => 8,
1296                "unsigned long long" => 7,
1297                "long long" => 6,
1298                "unsigned long" => 5,
1299                "long" => 4,
1300                "unsigned int" => 3,
1301                "int" => 2,
1302                "unsigned short" => 1,
1303                "short" => 1,
1304                _ => 0,
1305            }
1306        };
1307
1308        if rank(lhs) >= rank(rhs) {
1309            lhs.to_string()
1310        } else {
1311            rhs.to_string()
1312        }
1313    }
1314
1315    /// 条件演算の結果型を計算(文字列ベース)
1316    fn compute_conditional_type_str(&self, then_id: ExprId, else_id: ExprId, type_env: &TypeEnv) -> String {
1317        let then_ty = self.get_expr_type_str(then_id, type_env);
1318        let else_ty = self.get_expr_type_str(else_id, type_env);
1319        // void * vs 具体的ポインタ → 具体的な方を優先
1320        let is_void_ptr = |s: &str| s.contains("void") && s.contains('*');
1321        let is_concrete_ptr = |s: &str| !s.contains("void") && s.contains('*');
1322        if is_void_ptr(&then_ty) && is_concrete_ptr(&else_ty) {
1323            return else_ty;
1324        }
1325        if is_void_ptr(&else_ty) && is_concrete_ptr(&then_ty) {
1326            return then_ty;
1327        }
1328        self.usual_arithmetic_conversion_str(&then_ty, &else_ty)
1329    }
1330
1331    /// 文から式の型制約を収集(再帰的に走査)
1332    ///
1333    /// 文に含まれる式に対して `collect_expr_constraints` を呼び出す。
1334    pub fn collect_stmt_constraints(&mut self, stmt: &Stmt, type_env: &mut TypeEnv) {
1335        match stmt {
1336            Stmt::Compound(compound) => {
1337                for item in &compound.items {
1338                    match item {
1339                        BlockItem::Stmt(s) => self.collect_stmt_constraints(s, type_env),
1340                        BlockItem::Decl(_) => {} // 宣言は型制約収集の対象外
1341                    }
1342                }
1343            }
1344            Stmt::Expr(Some(expr), _) => {
1345                self.collect_expr_constraints(expr, type_env);
1346            }
1347            Stmt::If { cond, then_stmt, else_stmt, .. } => {
1348                self.collect_expr_constraints(cond, type_env);
1349                self.collect_stmt_constraints(then_stmt, type_env);
1350                if let Some(else_s) = else_stmt {
1351                    self.collect_stmt_constraints(else_s, type_env);
1352                }
1353            }
1354            Stmt::While { cond, body, .. } => {
1355                self.collect_expr_constraints(cond, type_env);
1356                self.collect_stmt_constraints(body, type_env);
1357            }
1358            Stmt::DoWhile { body, cond, .. } => {
1359                self.collect_stmt_constraints(body, type_env);
1360                self.collect_expr_constraints(cond, type_env);
1361            }
1362            Stmt::For { init, cond, step, body, .. } => {
1363                if let Some(ForInit::Expr(e)) = init {
1364                    self.collect_expr_constraints(e, type_env);
1365                }
1366                if let Some(c) = cond {
1367                    self.collect_expr_constraints(c, type_env);
1368                }
1369                if let Some(s) = step {
1370                    self.collect_expr_constraints(s, type_env);
1371                }
1372                self.collect_stmt_constraints(body, type_env);
1373            }
1374            Stmt::Return(Some(expr), _) => {
1375                self.collect_expr_constraints(expr, type_env);
1376            }
1377            Stmt::Switch { expr, body, .. } => {
1378                self.collect_expr_constraints(expr, type_env);
1379                self.collect_stmt_constraints(body, type_env);
1380            }
1381            Stmt::Case { expr, stmt, .. } => {
1382                self.collect_expr_constraints(expr, type_env);
1383                self.collect_stmt_constraints(stmt, type_env);
1384            }
1385            Stmt::Default { stmt, .. } | Stmt::Label { stmt, .. } => {
1386                self.collect_stmt_constraints(stmt, type_env);
1387            }
1388            _ => {} // Break, Continue, Goto, Asm, Expr(None), Return(None)
1389        }
1390    }
1391
1392    /// `c_field_type` が anonymous struct/union だった場合、bindings.rs
1393    /// (rust_decl_dict) から同じ親 struct + 同名フィールドを引いて、
1394    /// bindgen が生成した named 型 (`pmop__bindgen_ty_2` 等) で置き換える。
1395    ///
1396    /// これは perl の C ヘッダがインライン anonymous union を多用しており
1397    /// (例: `union { HV *op_pmstash; PADOFFSET op_pmstashoff; } op_pmstashstartu;`)、
1398    /// その内部メンバへの member access を解決するために必要。
1399    /// fields_dict 単体では anonymous union のフィールドを引けないが、
1400    /// bindings.rs では bindgen が `pmop__bindgen_ty_2` のような名前を
1401    /// 与えており、そこには `op_pmstash: *mut HV` 等のフィールドが
1402    /// 登録されている。
1403    /// `name` が typedef なら base struct 名へ展開する
1404    /// 例: "PMOP" → "pmop"。base が struct でない、または再帰深度
1405    /// が深すぎる場合は元の名前を返す。
1406    fn resolve_typedef_to_struct_name<'b>(&self, name: &'b str) -> std::borrow::Cow<'b, str> {
1407        let Some(rd) = self.rust_decl_dict else {
1408            return std::borrow::Cow::Borrowed(name);
1409        };
1410        let mut current = std::borrow::Cow::Borrowed(name);
1411        for _ in 0..8 {
1412            // 既に struct として登録されていれば終了
1413            if rd.structs.contains_key(current.as_ref()) {
1414                return current;
1415            }
1416            // typedef を辿る
1417            let Some(alias) = rd.types.get(current.as_ref()) else {
1418                return current;
1419            };
1420            current = std::borrow::Cow::Owned(alias.ty.clone());
1421        }
1422        current
1423    }
1424
1425    fn replace_anonymous_with_bindings(
1426        &self,
1427        parent_struct_name_str: &str,
1428        field_name_str: &str,
1429        c_field_type: TypeRepr,
1430    ) -> TypeRepr {
1431        if !is_anonymous_struct_or_union_field(&c_field_type) {
1432            return c_field_type;
1433        }
1434        let Some(rd) = self.rust_decl_dict else {
1435            return c_field_type;
1436        };
1437        let resolved = self.resolve_typedef_to_struct_name(parent_struct_name_str);
1438        let Some(rust_struct) = rd.structs.get(resolved.as_ref()) else {
1439            return c_field_type;
1440        };
1441        let Some(rust_field) = rust_struct.fields.iter().find(|f| f.name == field_name_str) else {
1442            return c_field_type;
1443        };
1444        // 構造化された RustField.uty (UnifiedType) を直接 TypeRepr に変換。
1445        // 文字列 round-trip (`from_rust_string` / `from_apidoc_string` 経由) は
1446        // prefix 剥がしの累積で破綻するため使わない。
1447        TypeRepr::from_unified_type(&rust_field.uty, self.interner)
1448    }
1449
1450    /// fields_dict (C 由来) でフィールドが見つからなかった場合の
1451    /// bindings.rs フォールバックルックアップ。bindgen 生成の anonymous
1452    /// union (`pmop__bindgen_ty_2` 等) は fields_dict には登録されない
1453    /// ため、その内部メンバアクセスはこの経路でのみ解決できる。
1454    fn lookup_field_in_bindings(
1455        &self,
1456        parent_struct_name_str: &str,
1457        field_name_str: &str,
1458    ) -> Option<TypeRepr> {
1459        let rd = self.rust_decl_dict?;
1460        let resolved = self.resolve_typedef_to_struct_name(parent_struct_name_str);
1461        let rust_struct = rd.structs.get(resolved.as_ref())?;
1462        let rust_field = rust_struct.fields.iter().find(|f| f.name == field_name_str)?;
1463        Some(TypeRepr::from_unified_type(&rust_field.uty, self.interner))
1464    }
1465
1466    /// 式全体から型制約を収集し、全式の型を計算(再帰的に走査)
1467    ///
1468    /// 子式を先に処理し、親式の型を後で計算する。
1469    pub fn collect_expr_constraints(&mut self, expr: &Expr, type_env: &mut TypeEnv) {
1470        match &expr.kind {
1471            // リテラル
1472            ExprKind::IntLit(_) => {
1473                type_env.add_constraint(TypeEnvConstraint::new(
1474                    expr.id,
1475                    TypeRepr::Inferred(InferredType::IntLiteral),
1476                    "integer literal",
1477                ));
1478            }
1479            ExprKind::UIntLit(_) => {
1480                type_env.add_constraint(TypeEnvConstraint::new(
1481                    expr.id,
1482                    TypeRepr::Inferred(InferredType::UIntLiteral),
1483                    "unsigned integer literal",
1484                ));
1485            }
1486            ExprKind::FloatLit(_) => {
1487                type_env.add_constraint(TypeEnvConstraint::new(
1488                    expr.id,
1489                    TypeRepr::Inferred(InferredType::FloatLiteral),
1490                    "float literal",
1491                ));
1492            }
1493            ExprKind::CharLit(_) => {
1494                type_env.add_constraint(TypeEnvConstraint::new(
1495                    expr.id,
1496                    TypeRepr::Inferred(InferredType::CharLiteral),
1497                    "char literal",
1498                ));
1499            }
1500            ExprKind::StringLit(_) => {
1501                type_env.add_constraint(TypeEnvConstraint::new(
1502                    expr.id,
1503                    TypeRepr::Inferred(InferredType::StringLiteral),
1504                    "string literal",
1505                ));
1506            }
1507
1508            // 識別子
1509            ExprKind::Ident(name) => {
1510                let name_str = self.interner.get(*name);
1511
1512                // シンボルテーブルから型を取得
1513                if let Some(sym) = self.lookup_symbol(*name) {
1514                    let ty_str = sym.ty.display(self.interner);
1515                    // シンボル参照を示す TypeRepr を作成
1516                    // resolved_type は文字列からパースした C 型
1517                    let resolved = TypeRepr::from_apidoc_string(&ty_str, self.interner);
1518                    type_env.add_constraint(TypeEnvConstraint::new(
1519                        expr.id,
1520                        TypeRepr::Inferred(InferredType::SymbolLookup {
1521                            name: *name,
1522                            resolved_type: Box::new(resolved),
1523                        }),
1524                        "symbol lookup",
1525                    ));
1526                // RustDeclDict から定数の型を取得
1527                } else if let Some(rust_decl_dict) = self.rust_decl_dict {
1528                    if let Some(rust_const) = rust_decl_dict.lookup_const(name_str) {
1529                        type_env.add_constraint(TypeEnvConstraint::new(
1530                            expr.id,
1531                            TypeRepr::RustType {
1532                                repr: RustTypeRepr::from_type_string(&rust_const.ty),
1533                                source: RustTypeSource::Const {
1534                                    const_name: name_str.to_string(),
1535                                },
1536                            },
1537                            "bindings constant",
1538                        ));
1539                    } else if name_str == "my_perl" {
1540                        // THX 由来の my_perl はデフォルトで *mut PerlInterpreter
1541                        type_env.add_constraint(TypeEnvConstraint::new(
1542                            expr.id,
1543                            TypeRepr::Inferred(InferredType::ThxDefault),
1544                            "THX default type",
1545                        ));
1546                    }
1547                } else if name_str == "my_perl" {
1548                    // THX 由来の my_perl はデフォルトで *mut PerlInterpreter
1549                    type_env.add_constraint(TypeEnvConstraint::new(
1550                        expr.id,
1551                        TypeRepr::Inferred(InferredType::ThxDefault),
1552                        "THX default type",
1553                    ));
1554                }
1555
1556                // パラメータ参照の場合、ExprId とパラメータを紐付け
1557                if self.is_macro_param(*name) {
1558                    type_env.link_expr_to_param(expr.id, *name, "parameter reference");
1559                }
1560            }
1561
1562            // 関数呼び出し
1563            ExprKind::Call { func, args } => {
1564                // 子式を先に処理
1565                self.collect_expr_constraints(func, type_env);
1566                for arg in args {
1567                    self.collect_expr_constraints(arg, type_env);
1568                }
1569                // Call の型制約を追加(RustDeclDict / Apidoc から)
1570                self.collect_call_constraints(expr.id, func, args, type_env);
1571            }
1572
1573            // 二項演算子
1574            ExprKind::Binary { op, lhs, rhs } => {
1575                // 子式を先に処理
1576                self.collect_expr_constraints(lhs, type_env);
1577                self.collect_expr_constraints(rhs, type_env);
1578                // 親式の型を計算
1579                let result_ty_str = self.compute_binary_type_str(op, lhs.id, rhs.id, type_env);
1580                let result_type = TypeRepr::from_apidoc_string(&result_ty_str, self.interner);
1581                type_env.add_constraint(TypeEnvConstraint::new(
1582                    expr.id,
1583                    TypeRepr::Inferred(InferredType::BinaryOp {
1584                        op: *op,
1585                        result_type: Box::new(result_type),
1586                    }),
1587                    "binary expression",
1588                ));
1589            }
1590
1591            // 条件演算子
1592            ExprKind::Conditional { cond, then_expr, else_expr } => {
1593                self.collect_expr_constraints(cond, type_env);
1594                self.collect_expr_constraints(then_expr, type_env);
1595                self.collect_expr_constraints(else_expr, type_env);
1596                let then_type = self.get_expr_type_repr_or_unknown(then_expr.id, type_env);
1597                let else_type = self.get_expr_type_repr_or_unknown(else_expr.id, type_env);
1598                // result_type は void* と具体型の選択など文字列ベースのルールが
1599                // 残っているため当面 from_apidoc_string 経由のままとする
1600                let result_ty_str = self.compute_conditional_type_str(then_expr.id, else_expr.id, type_env);
1601                let result_type = TypeRepr::from_apidoc_string(&result_ty_str, self.interner);
1602                type_env.add_constraint(TypeEnvConstraint::new(
1603                    expr.id,
1604                    TypeRepr::Inferred(InferredType::Conditional {
1605                        then_type: Box::new(then_type),
1606                        else_type: Box::new(else_type),
1607                        result_type: Box::new(result_type),
1608                    }),
1609                    "conditional expression",
1610                ));
1611            }
1612
1613            // キャスト
1614            ExprKind::Cast { type_name, expr: inner } => {
1615                self.collect_expr_constraints(inner, type_env);
1616                // AST → TypeRepr 直接変換(Type→String→TypeRepr roundtrip を排除)
1617                let specs = CTypeSpecs::from_decl_specs(&type_name.specs, self.interner);
1618                let derived: Vec<CDerivedType> = type_name.declarator.as_ref()
1619                    .map(|d| {
1620                        CDerivedType::from_derived_decls_with_base_const(
1621                            &d.derived, type_name.specs.qualifiers.is_const)
1622                            .into_iter()
1623                            .take_while(|d| !matches!(d, CDerivedType::Function { .. }))
1624                            .collect()
1625                    })
1626                    .unwrap_or_default();
1627                let target_type = TypeRepr::CType {
1628                    specs: specs.clone(),
1629                    derived: derived.clone(),
1630                    source: CTypeSource::Cast,
1631                };
1632                type_env.add_constraint(TypeEnvConstraint::new(
1633                    expr.id,
1634                    TypeRepr::Inferred(InferredType::Cast {
1635                        target_type: Box::new(target_type),
1636                    }),
1637                    "cast expression",
1638                ));
1639
1640                // SV ファミリーキャストからのパラメータ型推論
1641                // (SV_FAMILY_TYPE *)param → param に *mut SV 制約を追加
1642                if let Some(fields_dict) = self.fields_dict {
1643                    let is_single_ptr = derived.len() == 1
1644                        && matches!(derived[0], CDerivedType::Pointer { .. });
1645                    if is_single_ptr {
1646                        if let Some(type_name_id) = specs.type_name() {
1647                            if fields_dict.is_sv_family_type(type_name_id) {
1648                                if let ExprKind::Ident(param_name) = &inner.kind {
1649                                    if self.is_macro_param(*param_name) {
1650                                        let sv_type = self.make_sv_ptr_type();
1651                                        type_env.add_constraint(TypeEnvConstraint::new(
1652                                            inner.id,
1653                                            sv_type,
1654                                            "SV family cast",
1655                                        ));
1656                                    }
1657                                }
1658                            }
1659                        }
1660                    }
1661                }
1662            }
1663
1664            // 配列添字
1665            ExprKind::Index { expr: base, index } => {
1666                self.collect_expr_constraints(base, type_env);
1667                self.collect_expr_constraints(index, type_env);
1668                // 配列/ポインタの要素型を推論
1669                let base_ty_str = self.get_expr_type_str(base.id, type_env);
1670                let elem_ty_str = if base_ty_str.ends_with('*') {
1671                    base_ty_str.trim_end_matches('*').trim().to_string()
1672                } else if base_ty_str.contains('[') {
1673                    base_ty_str.split('[').next().unwrap_or(&base_ty_str).trim().to_string()
1674                } else {
1675                    "<unknown>".to_string()
1676                };
1677                let base_type = TypeRepr::from_apidoc_string(&base_ty_str, self.interner);
1678                let element_type = TypeRepr::from_apidoc_string(&elem_ty_str, self.interner);
1679                type_env.add_constraint(TypeEnvConstraint::new(
1680                    expr.id,
1681                    TypeRepr::Inferred(InferredType::ArraySubscript {
1682                        base_type: Box::new(base_type),
1683                        element_type: Box::new(element_type),
1684                    }),
1685                    "array subscript",
1686                ));
1687            }
1688
1689            // メンバーアクセス
1690            ExprKind::Member { expr: base, member } => {
1691                self.collect_expr_constraints(base, type_env);
1692
1693                let base_ty = self.get_expr_type_str(base.id, type_env);
1694                let member_name = self.interner.get(*member);
1695
1696                // sv_u フィールドアクセスの特殊処理
1697                // base が ->sv_u パターンの場合、sv_u 辞書から型を解決
1698                // それ以外は FieldsDict から TypeRepr を直接取得
1699                let field_type = if self.is_sv_u_access(base) {
1700                    // sv_u フィールドは C 形式の型文字列で格納されている
1701                    self.lookup_sv_u_field_type(*member)
1702                        .map(|c_type| Box::new(TypeRepr::from_apidoc_string(&c_type, self.interner)))
1703                } else {
1704                    // TypeRepr ベースのフィールドルックアップ
1705                    let base_type_repr = self.get_expr_type_repr(base.id, type_env);
1706                    let struct_name_id = base_type_repr.as_ref().and_then(|t| t.type_name());
1707                    // bindings.rs 由来の RustType::Named (`pmop__bindgen_ty_2` 等) も拾う
1708                    let struct_name_str = base_type_repr.as_ref()
1709                        .and_then(|t| extract_struct_name_str(t, self.interner));
1710                    let field_str = self.interner.get(*member);
1711                    // flexible array member の特別扱い: 配列ではなく要素型へのポインタ
1712                    let flex_ptr = struct_name_id.and_then(|n| {
1713                        self.fields_dict?
1714                            .flexible_array_element(n, *member)
1715                            .map(|elem| Box::new(wrap_with_outer_pointer(elem.clone(), false)))
1716                    });
1717                    // anonymous struct/union の type_repr は bindings.rs の named 型で置換
1718                    let direct = flex_ptr.or_else(|| {
1719                        struct_name_id.and_then(|n| {
1720                            self.fields_dict?.get_field_type(n, *member).map(|ft| {
1721                                let parent_str = self.interner.get(n);
1722                                let patched = self.replace_anonymous_with_bindings(
1723                                    parent_str, field_str, ft.type_repr.clone(),
1724                                );
1725                                Box::new(patched)
1726                            })
1727                        })
1728                    });
1729                    // fields_dict にない場合は bindings.rs から直接引く
1730                    // (bindgen 生成の anonymous union のメンバアクセス用)
1731                    let direct = direct.or_else(|| {
1732                        struct_name_str.as_deref().and_then(|parent_str| {
1733                            self.lookup_field_in_bindings(parent_str, field_str)
1734                                .map(Box::new)
1735                        })
1736                    });
1737                    // フォールバック: 共通フィールドマクロ × bindings.rs マッピング
1738                    // (無名 union メンバ等、上の経路で解決できないケース)
1739                    direct.or_else(|| {
1740                        self.fields_dict
1741                            .and_then(|fd| fd.rust_type_of_common_field(*member))
1742                            .cloned()
1743                            .map(Box::new)
1744                    })
1745                };
1746
1747                type_env.add_constraint(TypeEnvConstraint::new(
1748                    expr.id,
1749                    TypeRepr::Inferred(InferredType::MemberAccess {
1750                        base_type: base_ty.clone(),
1751                        member: *member,
1752                        field_type,
1753                    }),
1754                    format!("{}.{}", base_ty, member_name),
1755                ));
1756
1757                // 共通フィールドマクロ宣言フィールド → SV ファミリー型逆推論
1758                self.try_infer_sv_family_from_member(*member, base, type_env);
1759            }
1760
1761            // ポインタメンバーアクセス
1762            ExprKind::PtrMember { expr: base, member } => {
1763                self.collect_expr_constraints(base, type_env);
1764
1765                // ベース型からメンバー型を推論
1766                let base_ty = self.get_expr_type_str(base.id, type_env);
1767                let member_name = self.interner.get(*member);
1768
1769                // === ベース型の逆推論 ===
1770                // フィールド名から構造体を特定できる場合、ベース型を推論
1771                if let Some(fields_dict) = self.fields_dict {
1772                    // ベース型がまだ不明(unknown または Ident)の場合のみ逆推論を試みる
1773                    if base_ty == "/* unknown */" || self.is_ident_expr(base) {
1774                        // 1. まず一意なフィールドを試す (Phase 1)
1775                        // 2. 次に SV ファミリー共通フィールドを試す (Phase 2)
1776                        let inferred_struct = fields_dict.lookup_unique(*member)
1777                            .or_else(|| fields_dict.get_consistent_base_type(*member, self.interner));
1778
1779                        if let Some(struct_name) = inferred_struct {
1780                            // typedef 名があれば使用(例: sv → SV)
1781                            let type_name = fields_dict.get_typedef_for_struct(struct_name)
1782                                .unwrap_or(struct_name);
1783                            let type_name_str = self.interner.get(type_name);
1784                            let base_type = TypeRepr::CType {
1785                                specs: CTypeSpecs::TypedefName(type_name),
1786                                derived: vec![CDerivedType::Pointer {
1787                                    is_const: false,
1788                                    is_volatile: false,
1789                                    is_restrict: false,
1790                                }],
1791                                source: CTypeSource::FieldInference { field_name: *member },
1792                            };
1793                            type_env.add_constraint(TypeEnvConstraint::new(
1794                                base.id,
1795                                base_type,
1796                                format!("field {} implies {}*", member_name, type_name_str),
1797                            ));
1798                        }
1799                    }
1800                }
1801
1802                // TypeRepr ベースのフィールドルックアップ
1803                let base_type_repr = self.get_expr_type_repr(base.id, type_env);
1804                let pointee = base_type_repr.as_ref().and_then(|t| t.pointee_name());
1805                let (field_type, used_consistent_type) = if let Some(name) = pointee {
1806                    // flexible array member の特別扱い: 配列ではなく要素型へのポインタ
1807                    let flex_ptr = self.fields_dict.and_then(|fd| {
1808                        fd.flexible_array_element(name, *member)
1809                            .map(|elem| Box::new(wrap_with_outer_pointer(elem.clone(), false)))
1810                    });
1811                    let parent_str = self.interner.get(name);
1812                    let field_str = self.interner.get(*member);
1813                    // ベース型が既知のポインタ型:構造体名で直接ルックアップ
1814                    // anonymous struct/union の場合は bindings.rs の named 型で置換
1815                    let direct = flex_ptr.or_else(|| {
1816                        self.fields_dict
1817                            .and_then(|fd| fd.get_field_type(name, *member))
1818                            .map(|ft| {
1819                                let patched = self.replace_anonymous_with_bindings(
1820                                    parent_str, field_str, ft.type_repr.clone(),
1821                                );
1822                                Box::new(patched)
1823                            })
1824                    });
1825                    // fields_dict にない場合は bindings.rs から直接引く
1826                    // (bindgen 生成の anonymous union のメンバアクセス用)
1827                    let direct = direct.or_else(|| {
1828                        self.lookup_field_in_bindings(parent_str, field_str)
1829                            .map(Box::new)
1830                    });
1831                    let ty = direct.or_else(|| {
1832                        // 共通フィールドマクロ × bindings.rs マッピング(無名 union 等)
1833                        self.fields_dict
1834                            .and_then(|fd| fd.rust_type_of_common_field(*member))
1835                            .cloned()
1836                            .map(Box::new)
1837                    });
1838                    (ty, false)
1839                } else if let Some(fields_dict) = self.fields_dict {
1840                    // ベース型が不明な場合:一致型があればそれを使用(O(1))
1841                    let consistent = fields_dict.get_consistent_field_type(*member)
1842                        .cloned()
1843                        .map(Box::new);
1844                    let ty = consistent.or_else(|| {
1845                        fields_dict.rust_type_of_common_field(*member)
1846                            .cloned()
1847                            .map(Box::new)
1848                    });
1849                    (ty, true)
1850                } else {
1851                    (None, false)
1852                };
1853
1854                type_env.add_constraint(TypeEnvConstraint::new(
1855                    expr.id,
1856                    TypeRepr::Inferred(InferredType::PtrMemberAccess {
1857                        base_type: base_ty.clone(),
1858                        member: *member,
1859                        field_type,
1860                        used_consistent_type,
1861                    }),
1862                    format!("{}->{}", base_ty, member_name),
1863                ));
1864
1865                // 共通フィールドマクロ宣言フィールド → SV ファミリー型逆推論
1866                self.try_infer_sv_family_from_member(*member, base, type_env);
1867            }
1868
1869            // 代入演算子
1870            ExprKind::Assign { lhs, rhs, .. } => {
1871                self.collect_expr_constraints(lhs, type_env);
1872                self.collect_expr_constraints(rhs, type_env);
1873                // 代入式の型は左辺の型
1874                let lhs_type = self.get_expr_type_repr_or_unknown(lhs.id, type_env);
1875                type_env.add_constraint(TypeEnvConstraint::new(
1876                    expr.id,
1877                    TypeRepr::Inferred(InferredType::Assignment {
1878                        lhs_type: Box::new(lhs_type),
1879                    }),
1880                    "assignment expression",
1881                ));
1882            }
1883
1884            // コンマ演算子
1885            ExprKind::Comma { lhs, rhs } => {
1886                self.collect_expr_constraints(lhs, type_env);
1887                self.collect_expr_constraints(rhs, type_env);
1888                // コンマ式の型は右辺の型
1889                let rhs_type = self.get_expr_type_repr_or_unknown(rhs.id, type_env);
1890                type_env.add_constraint(TypeEnvConstraint::new(
1891                    expr.id,
1892                    TypeRepr::Inferred(InferredType::Comma {
1893                        rhs_type: Box::new(rhs_type),
1894                    }),
1895                    "comma expression",
1896                ));
1897            }
1898
1899            // 前置/後置インクリメント/デクリメント
1900            ExprKind::PreInc(inner) | ExprKind::PreDec(inner) |
1901            ExprKind::PostInc(inner) | ExprKind::PostDec(inner) => {
1902                self.collect_expr_constraints(inner, type_env);
1903                let inner_type = self.get_expr_type_repr_or_unknown(inner.id, type_env);
1904                type_env.add_constraint(TypeEnvConstraint::new(
1905                    expr.id,
1906                    TypeRepr::Inferred(InferredType::IncDec {
1907                        inner_type: Box::new(inner_type),
1908                    }),
1909                    "increment/decrement",
1910                ));
1911            }
1912
1913            // アドレス取得
1914            ExprKind::AddrOf(inner) => {
1915                self.collect_expr_constraints(inner, type_env);
1916                let inner_type = self.get_expr_type_repr_or_unknown(inner.id, type_env);
1917                type_env.add_constraint(TypeEnvConstraint::new(
1918                    expr.id,
1919                    TypeRepr::Inferred(InferredType::AddressOf {
1920                        inner_type: Box::new(inner_type),
1921                    }),
1922                    "address-of",
1923                ));
1924            }
1925
1926            // 間接参照
1927            ExprKind::Deref(inner) => {
1928                self.collect_expr_constraints(inner, type_env);
1929                let pointer_type = self.get_expr_type_repr_or_unknown(inner.id, type_env);
1930                type_env.add_constraint(TypeEnvConstraint::new(
1931                    expr.id,
1932                    TypeRepr::Inferred(InferredType::Dereference {
1933                        pointer_type: Box::new(pointer_type),
1934                    }),
1935                    "dereference",
1936                ));
1937            }
1938
1939            // 単項プラス/マイナス
1940            ExprKind::UnaryPlus(inner) | ExprKind::UnaryMinus(inner) => {
1941                self.collect_expr_constraints(inner, type_env);
1942                let inner_type = self.get_expr_type_repr_or_unknown(inner.id, type_env);
1943                type_env.add_constraint(TypeEnvConstraint::new(
1944                    expr.id,
1945                    TypeRepr::Inferred(InferredType::UnaryArithmetic {
1946                        inner_type: Box::new(inner_type),
1947                    }),
1948                    "unary plus/minus",
1949                ));
1950            }
1951
1952            // ビット反転
1953            ExprKind::BitNot(inner) => {
1954                self.collect_expr_constraints(inner, type_env);
1955                let inner_type = self.get_expr_type_repr_or_unknown(inner.id, type_env);
1956                type_env.add_constraint(TypeEnvConstraint::new(
1957                    expr.id,
1958                    TypeRepr::Inferred(InferredType::UnaryArithmetic {
1959                        inner_type: Box::new(inner_type),
1960                    }),
1961                    "bitwise not",
1962                ));
1963            }
1964
1965            // 論理否定
1966            ExprKind::LogNot(inner) => {
1967                self.collect_expr_constraints(inner, type_env);
1968                type_env.add_constraint(TypeEnvConstraint::new(
1969                    expr.id,
1970                    TypeRepr::Inferred(InferredType::LogicalNot),
1971                    "logical not",
1972                ));
1973            }
1974
1975            // sizeof(式)
1976            ExprKind::Sizeof(inner) => {
1977                self.collect_expr_constraints(inner, type_env);
1978                type_env.add_constraint(TypeEnvConstraint::new(
1979                    expr.id,
1980                    TypeRepr::Inferred(InferredType::Sizeof),
1981                    "sizeof expression",
1982                ));
1983            }
1984
1985            // sizeof(型)
1986            ExprKind::SizeofType(_) => {
1987                type_env.add_constraint(TypeEnvConstraint::new(
1988                    expr.id,
1989                    TypeRepr::Inferred(InferredType::Sizeof),
1990                    "sizeof type",
1991                ));
1992            }
1993
1994            // alignof
1995            ExprKind::Alignof(_) => {
1996                type_env.add_constraint(TypeEnvConstraint::new(
1997                    expr.id,
1998                    TypeRepr::Inferred(InferredType::Alignof),
1999                    "alignof",
2000                ));
2001            }
2002
2003            // 複合リテラル
2004            ExprKind::CompoundLit { type_name, .. } => {
2005                let ty = self.resolve_type_name(type_name);
2006                let ty_str = ty.display(self.interner);
2007                let type_name_repr = TypeRepr::from_apidoc_string(&ty_str, self.interner);
2008                type_env.add_constraint(TypeEnvConstraint::new(
2009                    expr.id,
2010                    TypeRepr::Inferred(InferredType::CompoundLiteral {
2011                        type_name: Box::new(type_name_repr),
2012                    }),
2013                    "compound literal",
2014                ));
2015            }
2016
2017            // Statement Expression (GCC拡張)
2018            ExprKind::StmtExpr(compound) => {
2019                self.collect_compound_constraints(compound, type_env);
2020                // 最後の式の型を取得
2021                if let Some(last_expr_id) = self.get_last_expr_id(compound) {
2022                    let last_expr_type = self.get_expr_type_repr_or_unknown(last_expr_id, type_env);
2023                    type_env.add_constraint(TypeEnvConstraint::new(
2024                        expr.id,
2025                        TypeRepr::Inferred(InferredType::StmtExpr {
2026                            last_expr_type: Some(Box::new(last_expr_type)),
2027                        }),
2028                        "statement expression",
2029                    ));
2030                } else {
2031                    type_env.add_constraint(TypeEnvConstraint::new(
2032                        expr.id,
2033                        TypeRepr::Inferred(InferredType::StmtExpr {
2034                            last_expr_type: None,
2035                        }),
2036                        "statement expression (empty)",
2037                    ));
2038                }
2039            }
2040
2041            // アサーション式
2042            ExprKind::Assert { condition, .. } => {
2043                self.collect_expr_constraints(condition, type_env);
2044                type_env.add_constraint(TypeEnvConstraint::new(
2045                    expr.id,
2046                    TypeRepr::Inferred(InferredType::Assert),
2047                    "assertion",
2048                ));
2049            }
2050
2051            // ビルトイン呼び出し(offsetof 等)
2052            ExprKind::BuiltinCall { name, args } => {
2053                // 引数内の式の型制約を収集
2054                for arg in args {
2055                    if let crate::ast::BuiltinArg::Expr(e) = arg {
2056                        self.collect_expr_constraints(e, type_env);
2057                    }
2058                }
2059                // offsetof → size_t (same as sizeof)
2060                let func_name = self.interner.get(*name);
2061                if func_name == "offsetof" || func_name == "__builtin_offsetof"
2062                    || func_name == "STRUCT_OFFSET"
2063                {
2064                    type_env.add_constraint(TypeEnvConstraint::new(
2065                        expr.id,
2066                        TypeRepr::Inferred(InferredType::Sizeof),
2067                        "offsetof returns size_t",
2068                    ));
2069                }
2070            }
2071
2072            // マクロ呼び出し(展開結果の型を使用)
2073            ExprKind::MacroCall { name, args, expanded, .. } => {
2074                // 引数の型制約を収集
2075                for arg in args {
2076                    self.collect_expr_constraints(arg, type_env);
2077                }
2078
2079                // 確定済みマクロのパラメータ型を参照(ネストしたマクロ呼び出しからの型伝播)
2080                let macro_name_str = self.interner.get(*name);
2081                if let Some(param_types) = self.get_macro_param_types(macro_name_str) {
2082                    for (i, arg) in args.iter().enumerate() {
2083                        if let Some((param_name, type_str)) = param_types.get(i) {
2084                            // キャッシュには Rust 形式の型文字列が保存されている。
2085                            // 中身は推論結果なので Propagated (Tier 4) として登録し、
2086                            // apidoc 宣言 (Tier 3) を上書きしない。
2087                            let constraint = TypeEnvConstraint::new(
2088                                arg.id,
2089                                TypeRepr::from_rust_string_propagated(type_str),
2090                                format!("arg {} ({}) of macro {}()", i, param_name, macro_name_str),
2091                            );
2092                            type_env.add_constraint(constraint);
2093                        }
2094                    }
2095                }
2096
2097                // 展開結果の型制約を収集
2098                self.collect_expr_constraints(expanded, type_env);
2099                // MacroCall 式全体の型は expanded と同じ
2100                if let Some(constraints) = type_env.get_expr_constraints(expanded.id) {
2101                    if let Some(constraint) = constraints.first() {
2102                        type_env.add_constraint(TypeEnvConstraint::new(
2103                            expr.id,
2104                            constraint.ty.clone(),
2105                            "macro call (expanded)",
2106                        ));
2107                    }
2108                }
2109            }
2110        }
2111    }
2112
2113    /// 複合文の最後の式の ExprId を取得
2114    fn get_last_expr_id(&self, compound: &CompoundStmt) -> Option<ExprId> {
2115        if let Some(BlockItem::Stmt(Stmt::Expr(Some(expr), _))) = compound.items.last() {
2116            Some(expr.id)
2117        } else {
2118            None
2119        }
2120    }
2121
2122    /// base が ->sv_u アクセスかどうかを判定
2123    ///
2124    /// `sv->sv_u.svu_pv` のような式で、`.svu_pv` の base が `sv->sv_u` かどうかを判定する。
2125    fn is_sv_u_access(&self, base: &Expr) -> bool {
2126        if let ExprKind::PtrMember { member, .. } = &base.kind {
2127            let sv_u_id = self.interner.lookup("sv_u");
2128            sv_u_id.map_or(false, |id| *member == id)
2129        } else {
2130            false
2131        }
2132    }
2133
2134    /// 式が単純な識別子かどうかを判定
2135    ///
2136    /// マクロパラメータのように、まだ型が決まっていない識別子の場合に true を返す。
2137    fn is_ident_expr(&self, expr: &Expr) -> bool {
2138        matches!(expr.kind, ExprKind::Ident(_))
2139    }
2140
2141    /// sv_u ユニオンフィールドの型を取得
2142    ///
2143    /// sv_u union のフィールド名から対応する C 型を返す。
2144    /// 例: svu_pv → "char*", svu_hash → "HE**"
2145    fn lookup_sv_u_field_type(&self, field: InternedStr) -> Option<String> {
2146        self.fields_dict?
2147            .get_sv_u_field_type(field)
2148            .map(|s| s.to_string())
2149    }
2150
2151    /// 関数呼び出しから型制約を収集
2152    fn collect_call_constraints(
2153        &mut self,
2154        call_expr_id: ExprId,
2155        func: &Expr,
2156        args: &[Expr],
2157        type_env: &mut TypeEnv,
2158    ) {
2159        // 関数名を取得
2160        let func_name = match &func.kind {
2161            ExprKind::Ident(name) => *name,
2162            _ => return, // 間接呼び出しは未対応
2163        };
2164
2165        let func_name_str = self.interner.get(func_name);
2166
2167        // RustDeclDict から引数の型を取得
2168        if let Some(rust_decl_dict) = self.rust_decl_dict {
2169            if let Some(rust_fn) = rust_decl_dict.fns.get(func_name_str) {
2170                for (i, arg) in args.iter().enumerate() {
2171                    if let Some(param) = rust_fn.params.get(i) {
2172                        let constraint = TypeEnvConstraint::new(
2173                            arg.id,
2174                            TypeRepr::RustType {
2175                                repr: RustTypeRepr::from_type_string(&param.ty),
2176                                source: RustTypeSource::FnParam {
2177                                    func_name: func_name_str.to_string(),
2178                                    param_index: i,
2179                                },
2180                            },
2181                            format!("arg {} of {}()", i, func_name_str),
2182                        );
2183                        type_env.add_constraint(constraint);
2184                    }
2185                }
2186
2187                // 戻り値型も制約として追加
2188                if let Some(ref ret_ty) = rust_fn.ret_ty {
2189                    let return_constraint = TypeEnvConstraint::new(
2190                        call_expr_id,
2191                        TypeRepr::RustType {
2192                            repr: RustTypeRepr::from_type_string(ret_ty),
2193                            source: RustTypeSource::FnReturn {
2194                                func_name: func_name_str.to_string(),
2195                            },
2196                        },
2197                        format!("return type of {}()", func_name_str),
2198                    );
2199                    type_env.add_constraint(return_constraint);
2200                }
2201            }
2202        }
2203
2204        // Apidoc から型を取得
2205        if let Some(apidoc) = self.apidoc {
2206            if let Some(entry) = apidoc.get(func_name_str) {
2207                // 引数の型
2208                for (i, arg) in args.iter().enumerate() {
2209                    if let Some(apidoc_arg) = entry.args.get(i) {
2210                        let constraint = TypeEnvConstraint::new(
2211                            arg.id,
2212                            self.parse_type_string(&apidoc_arg.ty),
2213                            format!("arg {} ({}) of {}()", i, apidoc_arg.name, func_name_str),
2214                        );
2215                        type_env.add_constraint(constraint);
2216                    }
2217                }
2218
2219                // 戻り値型
2220                if let Some(ref return_type) = entry.return_type {
2221                    let return_constraint = TypeEnvConstraint::new(
2222                        call_expr_id,
2223                        self.parse_type_string(return_type),
2224                        format!("return type of {}()", func_name_str),
2225                    );
2226                    type_env.add_constraint(return_constraint);
2227                }
2228            }
2229        }
2230
2231        // InlineFnDict から型を取得(AST から TypeRepr を直接構築)
2232        if self.inline_fn_dict.is_some() {
2233            // 引数の型
2234            for (i, arg) in args.iter().enumerate() {
2235                if let Some(type_repr) = self.lookup_inline_fn_param_type_repr(func_name, i) {
2236                    let constraint = TypeEnvConstraint::new(
2237                        arg.id,
2238                        type_repr,
2239                        format!("arg {} of inline {}()", i, func_name_str),
2240                    );
2241                    type_env.add_constraint(constraint);
2242                }
2243            }
2244
2245            // 戻り値型
2246            if let Some(type_repr) = self.lookup_inline_fn_return_type_repr(func_name) {
2247                let return_constraint = TypeEnvConstraint::new(
2248                    call_expr_id,
2249                    type_repr,
2250                    format!("return type of inline {}()", func_name_str),
2251                );
2252                type_env.add_constraint(return_constraint);
2253            }
2254        }
2255
2256        // 確定済みマクロのパラメータ型を参照(ネストしたマクロ呼び出しからの型伝播)
2257        if let Some(param_types) = self.get_macro_param_types(func_name_str) {
2258            for (i, arg) in args.iter().enumerate() {
2259                if let Some((param_name, type_str)) = param_types.get(i) {
2260                    // キャッシュには Rust 形式の型文字列が保存されている。
2261                    // 中身は推論結果なので Propagated (Tier 4) として登録し、
2262                    // apidoc 宣言 (Tier 3) を上書きしない。
2263                    let constraint = TypeEnvConstraint::new(
2264                        arg.id,
2265                        TypeRepr::from_rust_string_propagated(type_str),
2266                        format!("arg {} ({}) of macro {}()", i, param_name, func_name_str),
2267                    );
2268                    type_env.add_constraint(constraint);
2269                }
2270            }
2271        }
2272
2273        // 確定済みマクロの戻り値型を参照
2274        if let Some(return_type_str) = self.get_macro_return_type(func_name_str) {
2275            // キャッシュには Rust 形式の型文字列が保存されている
2276            let return_constraint = TypeEnvConstraint::new(
2277                call_expr_id,
2278                TypeRepr::from_rust_string(return_type_str),
2279                format!("return type of macro {}()", func_name_str),
2280            );
2281            type_env.add_constraint(return_constraint);
2282        }
2283    }
2284
2285    /// 複合文から型制約を収集
2286    fn collect_compound_constraints(&mut self, compound: &CompoundStmt, type_env: &mut TypeEnv) {
2287        for item in &compound.items {
2288            match item {
2289                BlockItem::Decl(decl) => {
2290                    // 宣言の初期化子内の式を処理
2291                    self.collect_decl_initializer_constraints(decl, type_env);
2292                }
2293                BlockItem::Stmt(Stmt::Expr(Some(expr), _)) => {
2294                    self.collect_expr_constraints(expr, type_env);
2295                }
2296                BlockItem::Stmt(Stmt::Return(Some(expr), _)) => {
2297                    self.collect_expr_constraints(expr, type_env);
2298                }
2299                BlockItem::Stmt(Stmt::Compound(inner)) => {
2300                    self.collect_compound_constraints(inner, type_env);
2301                }
2302                _ => {}
2303            }
2304        }
2305    }
2306
2307    /// 宣言の初期化子から型制約を収集
2308    fn collect_decl_initializer_constraints(&mut self, decl: &Declaration, type_env: &mut TypeEnv) {
2309        for init_decl in &decl.declarators {
2310            if let Some(ref init) = init_decl.init {
2311                self.collect_initializer_constraints(init, type_env);
2312            }
2313        }
2314    }
2315
2316    /// 初期化子から型制約を収集(再帰)
2317    fn collect_initializer_constraints(&mut self, init: &Initializer, type_env: &mut TypeEnv) {
2318        match init {
2319            Initializer::Expr(expr) => {
2320                self.collect_expr_constraints(expr, type_env);
2321            }
2322            Initializer::List(items) => {
2323                for item in items {
2324                    self.collect_initializer_constraints(&item.init, type_env);
2325                }
2326            }
2327        }
2328    }
2329
2330    /// Rust型文字列を Type に変換
2331    fn parse_rust_type_string(&self, type_str: &str) -> Type {
2332        // synのto_token_stream().to_string()は "* mut" のようにスペースを入れるため正規化
2333        let normalized = type_str
2334            .replace("* mut", "*mut")
2335            .replace("* const", "*const");
2336        let trimmed = normalized.trim();
2337
2338        // ポインタ型
2339        if let Some(rest) = trimmed.strip_prefix("*mut ") {
2340            return Type::Pointer(
2341                Box::new(self.parse_rust_type_string(rest)),
2342                TypeQualifiers::default(),
2343            );
2344        }
2345        if let Some(rest) = trimmed.strip_prefix("*const ") {
2346            return Type::Pointer(
2347                Box::new(self.parse_rust_type_string(rest)),
2348                TypeQualifiers { is_const: true, ..Default::default() },
2349            );
2350        }
2351
2352        // 基本型
2353        match trimmed {
2354            "()" => Type::Void,
2355            "c_char" => Type::Char,
2356            "c_int" => Type::Int,
2357            "c_uint" => Type::UnsignedInt,
2358            "c_long" => Type::Long,
2359            "c_ulong" => Type::UnsignedLong,
2360            "bool" => Type::Bool,
2361            "usize" => Type::UnsignedLong,
2362            "isize" => Type::Long,
2363            _ => {
2364                // typedef名として扱う
2365                if let Some(interned) = self.interner.lookup(trimmed) {
2366                    Type::TypedefName(interned)
2367                } else {
2368                    Type::Unknown
2369                }
2370            }
2371        }
2372    }
2373}
2374
2375#[cfg(test)]
2376mod tests {
2377    use super::*;
2378
2379    #[test]
2380    fn test_type_display() {
2381        let interner = StringInterner::new();
2382
2383        assert_eq!(Type::Int.display(&interner), "int");
2384        assert_eq!(Type::UnsignedLong.display(&interner), "unsigned long");
2385        assert_eq!(
2386            Type::Pointer(Box::new(Type::Char), TypeQualifiers::default()).display(&interner),
2387            "char*"
2388        );
2389    }
2390
2391    #[test]
2392    fn test_scope_management() {
2393        let mut interner = StringInterner::new();
2394        let x = interner.intern("x");
2395        let mut analyzer = SemanticAnalyzer::new(&interner, None, None);
2396
2397        // グローバルスコープでxを定義
2398        analyzer.define_symbol(Symbol {
2399            name: x,
2400            ty: Type::Int,
2401            loc: SourceLocation::default(),
2402            kind: SymbolKind::Variable,
2403        });
2404
2405        assert!(analyzer.lookup_symbol(x).is_some());
2406
2407        // 新しいスコープを開始
2408        analyzer.push_scope();
2409
2410        // まだxが見える
2411        assert!(analyzer.lookup_symbol(x).is_some());
2412
2413        // ローカルスコープでxをシャドウイング
2414        analyzer.define_symbol(Symbol {
2415            name: x,
2416            ty: Type::Float, // 異なる型
2417            loc: SourceLocation::default(),
2418            kind: SymbolKind::Variable,
2419        });
2420
2421        // ローカルのxが見える
2422        let sym = analyzer.lookup_symbol(x).unwrap();
2423        assert_eq!(sym.ty, Type::Float);
2424
2425        // スコープを終了
2426        analyzer.pop_scope();
2427
2428        // グローバルのxが見える
2429        let sym = analyzer.lookup_symbol(x).unwrap();
2430        assert_eq!(sym.ty, Type::Int);
2431    }
2432}