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