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