Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
ctf.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "ctf.h"
5#include "provider.h"
6#include "helpers.h"
7#include "panic.h"
8#include "qtheaders.h"
9
10#include <qfile.h>
11#include <qfileinfo.h>
12#include <qtextstream.h>
13#include <qdebug.h>
14
15
16static void writePrologue(QTextStream &stream, const QString &fileName, const Provider &provider)
17{
19 const QString guard = includeGuard(fileName);
20
21 // include prefix text or qt headers only once
22 stream << "#if !defined(" << guard << ")\n";
23 stream << qtHeaders();
24 stream << "\n";
25 if (!provider.prefixText.isEmpty())
26 stream << provider.prefixText.join(u'\n') << "\n\n";
27 stream << "#endif\n\n";
28
29 /* the first guard is the usual one, the second is required
30 * by LTTNG to force the re-evaluation of TRACEPOINT_* macros
31 */
32 stream << "#if !defined(" << guard << ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n";
33
34 stream << "#define " << guard << "\n\n"
35 << "#undef TRACEPOINT_INCLUDE\n"
36 << "#define TRACEPOINT_INCLUDE \"" << fileName << "\"\n\n";
37
38 stream << "#include <private/qctf_p.h>\n\n";
39
40 const QString namespaceGuard = guard + QStringLiteral("_USE_NAMESPACE");
41 stream << "#if !defined(" << namespaceGuard << ")\n"
42 << "#define " << namespaceGuard << "\n"
43 << "QT_USE_NAMESPACE\n"
44 << "#endif // " << namespaceGuard << "\n\n";
45
46 stream << "TRACEPOINT_PROVIDER(" << provider.name << ");\n\n";
47}
48
50{
51 stream << "\n";
52 stream << "#endif // " << includeGuard(fileName) << "\n"
53 << "#include <private/qtrace_p.h>\n";
54}
55
57 const Tracepoint &tracepoint, const Provider &provider)
58{
59 const QString argList = formatFunctionSignature(tracepoint.args);
60 const QString paramList = formatParameterList(provider, tracepoint.args, tracepoint.fields, CTF);
61 const QString &name = tracepoint.name;
62 const QString includeGuard = QStringLiteral("TP_%1_%2").arg(provider.name).arg(name).toUpper();
63
64 /* prevents the redefinion of the inline wrapper functions
65 */
66 stream << "\n"
67 << "#ifndef " << includeGuard << "\n"
68 << "#define " << includeGuard << "\n"
69 << "QT_BEGIN_NAMESPACE\n"
70 << "namespace QtPrivate {\n";
71
72 stream << "inline void trace_" << name << "(" << argList << ")\n"
73 << "{\n"
74 << " tracepoint(" << provider.name << ", " << name << paramList << ");\n"
75 << "}\n";
76
77 stream << "inline void do_trace_" << name << "(" << argList << ")\n"
78 << "{\n"
79 << " do_tracepoint(" << provider.name << ", " << name << paramList << ");\n"
80 << "}\n";
81
82 stream << "inline bool trace_" << name << "_enabled()\n"
83 << "{\n"
84 << " return tracepoint_enabled(" << provider.name << ", " << name << ");\n"
85 << "}\n";
86
87 stream << "} // namespace QtPrivate\n"
88 << "QT_END_NAMESPACE\n"
89 << "#endif // " << includeGuard << "\n\n";
90}
91
92
94{
95 stream << R"CPP(
96template <typename T>
97inline QString integerToMetadata(const QString &name)
99 QString ret;
100 if (!std::is_signed<T>().value)
101 ret += QLatin1Char('u');
102 if (sizeof(T) == 8)
103 ret += QStringLiteral("int64_t ");
104 else if (sizeof(T) == 4)
105 ret += QStringLiteral("int32_t ");
106 else if (sizeof(T) == 2)
107 ret += QStringLiteral("int16_t ");
108 else if (sizeof(T) == 1)
109 ret += QStringLiteral("int8_t ");
110 ret += name + QLatin1Char(';');
111 return ret;
112}
113
114template <typename T>
115inline QString integerArrayToMetadata(const QString &size, const QString &name)
116{
117 QString ret;
118 if (!std::is_signed<T>().value)
119 ret += QLatin1Char('u');
120 if (sizeof(T) == 8)
121 ret += QStringLiteral("int64_t ");
122 else if (sizeof(T) == 4)
123 ret += QStringLiteral("int32_t ");
124 else if (sizeof(T) == 2)
125 ret += QStringLiteral("int16_t ");
126 else if (sizeof(T) == 1)
127 ret += QStringLiteral("int8_t ");
128 ret += name + QLatin1Char('[') + size + QStringLiteral("];");
129 return ret;
130}
131
132template <typename T>
133inline QString floatToMetadata(const QString &name)
134{
135 QString ret;
136 if (sizeof(T) == 8)
137 ret += QStringLiteral("double ");
138 else if (sizeof(T) == 4)
139 ret += QStringLiteral("float ");
140 ret += name + QLatin1Char(';');
141 return ret;
142}
143
144template <typename T>
145inline QString floatArrayToMetadata(const QString &size, const QString &name)
146{
147 QString ret;
148 if (sizeof(T) == 8)
149 ret += QStringLiteral("double ");
150 else if (sizeof(T) == 4)
151 ret += QStringLiteral("float ");
152 ret += name + QLatin1Char('[') + size + QLatin1Char(']');
153 return ret + QLatin1Char(';');
154}
155
156inline QString pointerToMetadata(const QString &name)
157{
158 QString ret;
159 if (QT_POINTER_SIZE == 8)
160 ret += QStringLiteral("intptr64_t ");
161 else if (QT_POINTER_SIZE == 4)
162 ret += QStringLiteral("intptr32_t ");
163 ret += name + QLatin1Char(';');
164 return ret;
165}
166
167)CPP";
168}
169
171 const Tracepoint &tracepoint, const QString &providerName)
172{
173 stream << "TRACEPOINT_EVENT(\n"
174 << " " << providerName << ",\n"
175 << " " << tracepoint.name << ",\n";
176
177 const auto checkUnknownArgs = [](const Tracepoint &tracepoint) {
178 for (auto &field : tracepoint.fields) {
179 if (field.backendType == Tracepoint::Field::Unknown)
180 return true;
181 }
182 return false;
183 };
184
185 const auto formatType = [](const QString &type) {
186 QString ret = type;
187 if (type.endsWith(QLatin1Char('*')) || type.endsWith(QLatin1Char('&')))
188 ret = type.left(type.length() - 1).simplified();
189 if (ret.startsWith(QStringLiteral("const")))
190 ret = ret.right(ret.length() - 6).simplified();
191 return typeToTypeName(ret);
192 };
193 QString eventSize;
194 bool variableSize = false;
195 const bool emptyMetadata = checkUnknownArgs(tracepoint) || tracepoint.args.size() == 0;
196 if (!emptyMetadata) {
197 for (int i = 0; i < tracepoint.args.size(); i++) {
198 auto &arg = tracepoint.args[i];
199 auto &field = tracepoint.fields[i];
200 if (i > 0) {
201 stream << " + QStringLiteral(\"\\n\\\n \") + ";
202 eventSize += QStringLiteral(" + ");
203 }
204 const bool array = field.arrayLen > 0;
205 switch (field.backendType) {
207 stream << "QStringLiteral(\"Boolean " << arg.name << ";\")";
208 eventSize += QStringLiteral("sizeof(bool)");
209 } break;
211 if (array) {
212 stream << "integerArrayToMetadata<" << formatType(arg.type)
213 << ">(QStringLiteral(\"" << field.arrayLen << "\"), QStringLiteral(\""
214 << arg.name << "\"))";
215 } else {
216 stream << "integerToMetadata<" << formatType(arg.type) << ">(QStringLiteral(\""
217 << arg.name << "\"))";
218 }
219 eventSize += QStringLiteral("sizeof(") + formatType(arg.type) + QStringLiteral(")");
220 if (array)
221 eventSize += QStringLiteral(" * ") + QString::number(field.arrayLen);
222 } break;
225 stream << "pointerToMetadata(QStringLiteral(\"" << formatType(arg.type) << "_"
226 << arg.name << "\"))";
227 eventSize += QStringLiteral("QT_POINTER_SIZE");
228 } break;
230 if (array) {
231 stream << "floatArrayToMetadata<" << formatType(arg.type)
232 << ">(QStringLiteral(\"" << field.arrayLen << "\"), QStringLiteral(\""
233 << arg.name << "\"))";
234 } else {
235 stream << "floatToMetadata<" << formatType(arg.type) << ">(QStringLiteral(\""
236 << arg.name << "\"))";
237 }
238 eventSize += QStringLiteral("sizeof(") + formatType(arg.type) + QStringLiteral(")");
239 if (array)
240 eventSize += QStringLiteral(" * ") + QString::number(field.arrayLen);
241 } break;
245 stream << "QStringLiteral(\"string " << arg.name << ";\")";
246 eventSize += QStringLiteral("1");
247 variableSize = true;
248 } break;
250 stream << "QStringLiteral(\"int32_t QRect_" << arg.name << "_x;\\n\\\n \")";
251 stream << " + QStringLiteral(\"int32_t QRect_" << arg.name << "_y;\\n\\\n \")";
252 stream << " + QStringLiteral(\"int32_t QRect_" << arg.name << "_width;\\n\\\n \")";
253 stream << " + QStringLiteral(\"int32_t QRect_" << arg.name << "_height;\\n\\\n \")";
254 eventSize += QStringLiteral("16");
255 } break;
257 stream << "QStringLiteral(\"int32_t QSize_" << arg.name << "_width;\\n\\\n \")";
258 stream << " + QStringLiteral(\"int32_t QSize_" << arg.name << "_height;\\n\\\n \")";
259 eventSize += QStringLiteral("8");
260 } break;
262 stream << "QStringLiteral(\"float QRectF_" << arg.name << "_x;\\n\\\n \")";
263 stream << " + QStringLiteral(\"float QRectF_" << arg.name << "_y;\\n\\\n \")";
264 stream << " + QStringLiteral(\"float QRectF_" << arg.name << "_width;\\n\\\n \")";
265 stream << " + QStringLiteral(\"float QRectF_" << arg.name << "_height;\\n\\\n \")";
266 eventSize += QStringLiteral("16");
267 } break;
269 stream << "QStringLiteral(\"float QSizeF_" << arg.name << "_width;\\n\\\n \")";
270 stream << " + QStringLiteral(\"float QSizeF_" << arg.name << "_height;\\n\\\n \")";
271 eventSize += QStringLiteral("8");
272 } break;
274 break;
276 stream << "QStringLiteral(\"" << typeToTypeName(arg.type) << " " << arg.name << ";\")";
277 eventSize += QString::number(field.enumValueSize / 8);
278 variableSize = true;
279 } break;
281 stream << "QStringLiteral(\"uint8_t " << arg.name << "_length;\\n\\\n ";
282 stream << typeToTypeName(arg.type) << " " << arg.name << "[" << arg.name << "_length];\")";
283 eventSize += QStringLiteral("2");
284 variableSize = true;
285 } break;
288 panic("Unhandled type '%s %s", qPrintable(arg.type), qPrintable(arg.name));
289 break;
290 }
291 }
293
294 if (emptyMetadata)
295 stream << "{},\n";
296 else
297 stream << ",\n";
298 if (eventSize.length())
299 stream << eventSize << ", \n";
300 else
301 stream << "0, \n";
302 stream << (variableSize ? "true" : "false") << "\n";
303 stream << ")\n\n";
304}
305
306static void writeTracepoints(QTextStream &stream, const Provider &provider)
307{
308 for (const Tracepoint &t : provider.tracepoints) {
309 writeTracepoint(stream, t, provider.name);
310 writeWrapper(stream, t, provider);
311 }
312}
313
314static void writeEnums(QTextStream &stream, const Provider &provider)
315{
316 for (const auto &e : provider.enumerations) {
317 QString name = e.name;
319 stream << "TRACEPOINT_METADATA(" << provider.name << ", " << name << ", \n";
320 stream << "QStringLiteral(\"typealias enum : integer { size = " << e.valueSize << "; } {\\n\\\n";
321
322 const auto values = e.values;
323 QList<int> handledValues;
324
325 for (const auto &v : values) {
326 if (handledValues.contains(v.value))
327 continue;
328 if (v.range) {
329 stream << v.name << " = " << v.value << " ... " << v.range << ", \\n\\\n";
330 } else {
331 const QString names = aggregateListValues(v.value, values);
332 stream << names << " = " << v.value << ", \\n\\\n";
333 handledValues.append(v.value);
334 }
335 }
336 stream << "} := " << name << ";\\n\\n\"));\n\n";
337 }
338 stream << "\n";
339}
340
341static void writeFlags(QTextStream &stream, const Provider &provider)
342{
343 for (const auto &e : provider.flags) {
344 QString name = e.name;
346 stream << "TRACEPOINT_METADATA(" << provider.name << ", " << name << ", \n";
347 stream << "QStringLiteral(\"typealias enum : integer { size = 8; } {\\n\\\n";
348
349 const auto values = e.values;
350 QList<int> handledValues;
351
352 for (const auto &v : values) {
353 if (handledValues.contains(v.value))
354 continue;
355 const QString names = aggregateListValues(v.value, values);
356 stream << names << " = " << v.value << ", \\n\\\n";
357 handledValues.append(v.value);
358 }
359 stream << "} := " << name << ";\\n\\n\"));\n\n";
360 }
361 stream << "\n";
362}
363
364void writeCtf(QFile &file, const Provider &provider)
365{
367
369
370 writePrologue(stream, fileName, provider);
372 writeEnums(stream, provider);
373 writeFlags(stream, provider);
374 writeTracepoints(stream, provider);
376}
QString fileName() const
\inmodule QtCore
Definition qfile.h:93
QString fileName() const override
Returns the name set by setFileName() or to the QFile constructors.
Definition qfile.cpp:277
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString left(qsizetype n) const &
Definition qstring.h:363
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition qstring.cpp:3824
QString right(qsizetype n) const &
Definition qstring.h:375
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
\inmodule QtCore
static void writeMetadataGenerators(QTextStream &stream)
Definition ctf.cpp:93
static void writeEpilogue(QTextStream &stream, const QString &fileName)
Definition ctf.cpp:49
static void writeEnums(QTextStream &stream, const Provider &provider)
Definition ctf.cpp:242
void writeCtf(QFile &file, const Provider &provider)
Definition ctf.cpp:292
static void writeWrapper(QTextStream &stream, const Tracepoint &tracepoint, const Provider &provider)
Definition ctf.cpp:56
static void writeTracepoint(QTextStream &stream, const Tracepoint &tracepoint, const QString &providerName)
Definition ctf.cpp:98
static void writePrologue(QTextStream &stream, const QString &fileName, const Provider &provider)
Definition ctf.cpp:16
static void writeFlags(QTextStream &stream, const Provider &provider)
Definition ctf.cpp:269
static void writeTracepoints(QTextStream &stream, const Provider &provider)
Definition ctf.cpp:234
void writeCommonPrologue(QTextStream &stream)
Definition helpers.cpp:9
QString typeToTypeName(const QString &name)
Definition helpers.cpp:14
QString includeGuard(const QString &filename)
Definition helpers.cpp:20
QString formatFunctionSignature(const QList< Tracepoint::Argument > &args)
Definition helpers.cpp:50
QString formatParameterList(const Provider &provider, const QList< Tracepoint::Argument > &args, const QList< Tracepoint::Field > &fields, ParamType type)
Definition helpers.cpp:57
@ CTF
Definition helpers.h:16
static QString aggregateListValues(int value, const QList< T > &list)
Definition helpers.h:27
void panic(const char *fmt,...)
Definition panic.cpp:10
#define tracepoint(provider, name,...)
Definition qctf_p.h:214
EGLStreamKHR stream
return ret
GLenum GLsizei GLsizei GLint * values
[15]
GLsizei const GLfloat * v
[13]
GLenum type
GLbitfield flags
GLuint name
GLuint GLuint * names
GLenum array
GLdouble GLdouble t
Definition qopenglext.h:243
SSL_CTX int void * arg
#define qPrintable(string)
Definition qstring.h:1531
#define QStringLiteral(str)
const char * qtHeaders()
Definition qtheaders.cpp:6
QFile file
[0]
QStringList prefixText
Definition provider.h:85
QString name
Definition provider.h:83
QList< Tracepoint > tracepoints
Definition provider.h:84
\inmodule QtCore \reentrant
Definition qchar.h:18