Re-format new C++ files
[babeltrace.git] / src / plugins / ctf / common / metadata / ctf-meta-update-in-ir.cpp
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
5 */
6
7 #include <babeltrace2/babeltrace.h>
8 #include "common/macros.h"
9 #include "common/assert.h"
10 #include "compat/glib.h"
11 #include <glib.h>
12 #include <stdbool.h>
13 #include <stdint.h>
14 #include <string.h>
15 #include <inttypes.h>
16 #include "common/assert.h"
17
18 #include "ctf-meta-visitors.hpp"
19
20 static void force_update_field_class_in_ir(struct ctf_field_class *fc, bool in_ir)
21 {
22 uint64_t i;
23
24 if (!fc) {
25 goto end;
26 }
27
28 fc->in_ir = in_ir;
29
30 switch (fc->type) {
31 case CTF_FIELD_CLASS_TYPE_STRUCT:
32 {
33 struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc);
34
35 for (i = 0; i < struct_fc->members->len; i++) {
36 struct ctf_named_field_class *named_fc =
37 ctf_field_class_struct_borrow_member_by_index(struct_fc, i);
38
39 force_update_field_class_in_ir(named_fc->fc, in_ir);
40 }
41
42 break;
43 }
44 case CTF_FIELD_CLASS_TYPE_VARIANT:
45 {
46 struct ctf_named_field_class *named_fc;
47 struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc);
48
49 for (i = 0; i < var_fc->options->len; i++) {
50 named_fc = ctf_field_class_variant_borrow_option_by_index(var_fc, i);
51
52 force_update_field_class_in_ir(named_fc->fc, in_ir);
53 }
54
55 break;
56 }
57 case CTF_FIELD_CLASS_TYPE_ARRAY:
58 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
59 {
60 struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc);
61
62 force_update_field_class_in_ir(array_fc->elem_fc, in_ir);
63 break;
64 }
65 default:
66 break;
67 }
68
69 end:
70 return;
71 }
72
73 static void update_field_class_in_ir(struct ctf_field_class *fc, GHashTable *ft_dependents)
74 {
75 int64_t i;
76
77 if (!fc) {
78 goto end;
79 }
80
81 switch (fc->type) {
82 case CTF_FIELD_CLASS_TYPE_INT:
83 case CTF_FIELD_CLASS_TYPE_ENUM:
84 {
85 struct ctf_field_class_int *int_fc = ctf_field_class_as_int(fc);
86
87 /*
88 * Conditions to be in trace IR; one of:
89 *
90 * 1. Does NOT have a mapped clock class AND does not
91 * have a special meaning.
92 * 2. Another field class depends on it.
93 */
94 if ((!int_fc->mapped_clock_class && int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE) ||
95 bt_g_hash_table_contains(ft_dependents, fc)) {
96 fc->in_ir = true;
97 }
98
99 break;
100 }
101 case CTF_FIELD_CLASS_TYPE_STRUCT:
102 {
103 struct ctf_field_class_struct *struct_fc = ctf_field_class_as_struct(fc);
104
105 /*
106 * Make it part of IR if it's empty because it was
107 * originally empty.
108 */
109 if (struct_fc->members->len == 0) {
110 fc->in_ir = true;
111 }
112
113 /* Reverse order */
114 for (i = (int64_t) struct_fc->members->len - 1; i >= 0; i--) {
115 struct ctf_named_field_class *named_fc =
116 ctf_field_class_struct_borrow_member_by_index(struct_fc, i);
117
118 update_field_class_in_ir(named_fc->fc, ft_dependents);
119
120 if (named_fc->fc->in_ir) {
121 /* At least one member is part of IR */
122 fc->in_ir = true;
123 }
124 }
125
126 break;
127 }
128 case CTF_FIELD_CLASS_TYPE_VARIANT:
129 {
130 struct ctf_named_field_class *named_fc;
131 struct ctf_field_class_variant *var_fc = ctf_field_class_as_variant(fc);
132
133 /*
134 * Reverse order, although it is not important for this
135 * loop because a field class within a variant field
136 * type's option cannot depend on a field class in
137 * another option of the same variant field class.
138 */
139 for (i = (int64_t) var_fc->options->len - 1; i >= 0; i--) {
140 named_fc = ctf_field_class_variant_borrow_option_by_index(var_fc, i);
141
142 update_field_class_in_ir(named_fc->fc, ft_dependents);
143
144 if (named_fc->fc->in_ir) {
145 /* At least one option is part of IR */
146 fc->in_ir = true;
147 }
148 }
149
150 if (fc->in_ir) {
151 /*
152 * At least one option will make it to IR. In
153 * this case, make all options part of IR
154 * because the variant's tag could still select
155 * (dynamically) a removed option. This can mean
156 * having an empty structure as an option, for
157 * example, but at least all the options are
158 * selectable.
159 */
160 for (i = 0; i < var_fc->options->len; i++) {
161 ctf_field_class_variant_borrow_option_by_index(var_fc, i)->fc->in_ir = true;
162 }
163
164 /*
165 * This variant field class is part of IR and
166 * depends on a tag field class (which must also
167 * be part of IR).
168 */
169 g_hash_table_insert(ft_dependents, var_fc->tag_fc, var_fc->tag_fc);
170 }
171
172 break;
173 }
174 case CTF_FIELD_CLASS_TYPE_ARRAY:
175 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
176 {
177 struct ctf_field_class_array_base *array_fc = ctf_field_class_as_array_base(fc);
178
179 update_field_class_in_ir(array_fc->elem_fc, ft_dependents);
180 fc->in_ir = array_fc->elem_fc->in_ir;
181
182 if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY) {
183 struct ctf_field_class_array *arr_fc = ctf_field_class_as_array(fc);
184
185 assert(arr_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE ||
186 arr_fc->meaning == CTF_FIELD_CLASS_MEANING_UUID);
187
188 /*
189 * UUID field class: nothing depends on this, so
190 * it's not part of IR.
191 */
192 if (arr_fc->meaning == CTF_FIELD_CLASS_MEANING_UUID) {
193 fc->in_ir = false;
194 array_fc->elem_fc->in_ir = false;
195 }
196 } else if (fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) {
197 if (fc->in_ir) {
198 struct ctf_field_class_sequence *seq_fc = ctf_field_class_as_sequence(fc);
199
200 /*
201 * This sequence field class is part of
202 * IR and depends on a length field class
203 * (which must also be part of IR).
204 */
205 g_hash_table_insert(ft_dependents, seq_fc->length_fc, seq_fc->length_fc);
206 }
207 }
208
209 break;
210 }
211 default:
212 fc->in_ir = true;
213 break;
214 }
215
216 end:
217 return;
218 }
219
220 /*
221 * Scopes and field classes are processed in reverse order because we need
222 * to know if a given integer field class has dependents (sequence or
223 * variant field classes) when we reach it. Dependents can only be located
224 * after the length/tag field class in the metadata tree.
225 */
226 BT_HIDDEN
227 int ctf_trace_class_update_in_ir(struct ctf_trace_class *ctf_tc)
228 {
229 int ret = 0;
230 uint64_t i;
231
232 GHashTable *ft_dependents = g_hash_table_new(g_direct_hash, g_direct_equal);
233
234 BT_ASSERT(ft_dependents);
235
236 for (i = 0; i < ctf_tc->stream_classes->len; i++) {
237 ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i];
238 uint64_t j;
239
240 for (j = 0; j < sc->event_classes->len; j++) {
241 ctf_event_class *ec = (ctf_event_class *) sc->event_classes->pdata[j];
242
243 if (ec->is_translated) {
244 continue;
245 }
246
247 update_field_class_in_ir(ec->payload_fc, ft_dependents);
248 update_field_class_in_ir(ec->spec_context_fc, ft_dependents);
249 }
250
251 if (!sc->is_translated) {
252 update_field_class_in_ir(sc->event_common_context_fc, ft_dependents);
253 force_update_field_class_in_ir(sc->event_header_fc, false);
254 update_field_class_in_ir(sc->packet_context_fc, ft_dependents);
255 }
256 }
257
258 if (!ctf_tc->is_translated) {
259 force_update_field_class_in_ir(ctf_tc->packet_header_fc, false);
260 }
261
262 g_hash_table_destroy(ft_dependents);
263 return ret;
264 }
This page took 0.033639 seconds and 4 git commands to generate.