1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//! Tagged union pattern detection (DECY-080).
//!
//! Detects C tagged union patterns and extracts variant information.
//!
//! # Overview
//!
//! This module analyzes C structs to detect the "tagged union" pattern, where a struct
//! combines an enum discriminant (tag) with a union containing variant data. This is a
//! common C idiom for creating variant types, but it's unsafe because the compiler doesn't
//! verify that the tag matches the union field being accessed.
//!
//! # Tagged Union Pattern
//!
//! A typical C tagged union looks like:
//!
//! ```c
//! enum ValueType { TYPE_INT, TYPE_FLOAT, TYPE_STRING };
//!
//! struct Value {
//! enum ValueType tag; // Discriminant
//! union { // Payload
//! int int_val;
//! float float_val;
//! char* string_val;
//! } data;
//! };
//! ```
//!
//! This module detects such patterns and extracts the tag field, union field, and variant
//! information, enabling transformation to Rust's type-safe `enum` with pattern matching.
//!
//! # Example
//!
//! ```no_run
//! use decy_analyzer::tagged_union_analysis::TaggedUnionAnalyzer;
//! use decy_hir::{HirStruct, HirStructField, HirType};
//!
//! // C struct: struct Value { enum Tag tag; union { int i; float f; } data; };
//! let struct_def = HirStruct::new(
//! "Value".to_string(),
//! vec![
//! HirStructField::new("tag".to_string(), HirType::Enum("Tag".to_string())),
//! HirStructField::new("data".to_string(), HirType::Union(vec![
//! ("i".to_string(), HirType::Int),
//! ("f".to_string(), HirType::Float),
//! ])),
//! ],
//! );
//!
//! let analyzer = TaggedUnionAnalyzer::new();
//! let info = analyzer.analyze_struct(&struct_def);
//!
//! assert!(info.is_some());
//! let info = info.unwrap();
//! assert_eq!(info.struct_name, "Value");
//! assert_eq!(info.tag_field_name, "tag");
//! assert_eq!(info.union_field_name, "data");
//! assert_eq!(info.variants.len(), 2);
//! ```
//!
//! # Algorithm
//!
//! The detection algorithm:
//!
//! 1. Scan struct fields for the first enum type (tag discriminant)
//! 2. Scan struct fields for the first union type (variant payload)
//! 3. If both exist and the union is non-empty, extract variant metadata
//! 4. Return `TaggedUnionInfo` with complete information for code generation
//!
//! Empty unions are rejected because they represent invalid tagged unions.
use ;
/// Information about a variant in a tagged union.
///
/// Each variant corresponds to a field in the C union, representing one possible
/// type that the tagged union can hold.
/// Information about a detected tagged union.
///
/// Contains all metadata needed to transform a C tagged union into a Rust enum.
/// Analyzes structs to detect tagged union patterns.
///
/// This analyzer identifies C structs that follow the tagged union idiom and extracts
/// the necessary metadata for safe transformation to Rust enums.
;