11#include <qtextstream.h>
15#include "../../3rdparty/sha1/sha1.cpp"
17using namespace Qt::StringLiterals;
21 return providerName +
"_provider"_L1;
24static void writeEtwMacro(QTextStream &stream,
const Tracepoint::Field &field)
26 const QString &name = field.name;
28 if (field.arrayLen > 0) {
29 for (
int i = 0; i < field.arrayLen; i++) {
30 stream <<
"TraceLoggingValue(" << name <<
"[" << i <<
"], \"" << name <<
"[" << i <<
"]\")";
31 if (i + 1 < field.arrayLen)
37 switch (field.backendType) {
38 case Tracepoint::Field::QtString:
39 stream <<
"TraceLoggingCountedWideString(reinterpret_cast<LPCWSTR>("
40 << name <<
".utf16()), static_cast<ULONG>(" << name <<
".size()), \""
43 case Tracepoint::Field::QtByteArray:
44 stream <<
"TraceLoggingBinary(" << name <<
".constData(), "
45 << name <<
".size(), \"" << name <<
"\")";
47 case Tracepoint::Field::QtUrl:
48 stream <<
"TraceLoggingValue(" << name <<
".toEncoded().constData(), \"" << name <<
"\")";
50 case Tracepoint::Field::QtRect:
51 case Tracepoint::Field::QtRectF:
52 stream <<
"TraceLoggingValue(" << name <<
".x(), \"x\"), "
53 <<
"TraceLoggingValue(" << name <<
".y(), \"y\"), "
54 <<
"TraceLoggingValue(" << name <<
".width(), \"width\"), "
55 <<
"TraceLoggingValue(" << name <<
".height(), \"height\")";
57 case Tracepoint::Field::QtSize:
58 case Tracepoint::Field::QtSizeF:
59 stream <<
"TraceLoggingValue(" << name <<
".width(), \"width\"), "
60 <<
"TraceLoggingValue(" << name <<
".height(), \"height\")";
62 case Tracepoint::Field::Pointer:
63 stream <<
"TraceLoggingPointer(" << name <<
", \"" << name <<
"\")";
65 case Tracepoint::Field::Unknown:
69 stream <<
"TraceLoggingCountedWideString(reinterpret_cast<LPCWSTR>(" << name
70 <<
"Str.utf16()), static_cast<ULONG>(" << name <<
"Str.size()), \"" << name <<
"\")";
72 case Tracepoint::Field::EnumeratedType:
73 case Tracepoint::Field::FlagType:
74 stream <<
"TraceLoggingString(trace_convert_" << typeToTypeName(field.paramType) <<
"(" << name <<
").toUtf8().constData(), \"" << name <<
"\")";
80 stream <<
"TraceLoggingValue(" << name <<
", \"" << name <<
"\")";
88 sha1InitState(&state);
89#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
91 sha1Update(&state, uuid, 16);
93 sha1Update(&state,
reinterpret_cast<
const uchar *>(name.data()), name.size());
94 sha1FinalizeState(&state);
96 sha1ToHash(&state, uuid);
99 uuid[6] = (uuid[6] & 0xF) | 0x50;
100 uuid[8] = (uuid[8] & 0x3F) | 0x80;
107 Qt::showbase(stream);
110 << qFromBigEndian<quint32>(uuid + 0) <<
", "
111 << qFromBigEndian<quint16>(uuid + 4) <<
", "
112 << qFromBigEndian<quint16>(uuid + 6) <<
", "
126static void writePrologue(QTextStream &stream,
const QString &fileName,
const Provider &provider)
128 writeCommonPrologue(stream);
130 const QString providerV = providerVar(provider.name);
131 const QString guard = includeGuard(fileName);
132 const QString guid = createGuid(provider.name.toLocal8Bit());
134 stream <<
"#ifndef " << guard <<
"\n"
135 <<
"#define " << guard <<
"\n"
137 <<
"#include <qt_windows.h>\n"
138 <<
"#include <TraceLoggingProvider.h>\n"
142
143
144 stream <<
"#undef _TlgPragmaUtf8Begin\n"
145 "#undef _TlgPragmaUtf8End\n"
146 "#define _TlgPragmaUtf8Begin\n"
147 "#define _TlgPragmaUtf8End\n";
150 stream << qtHeaders();
153 if (!provider.prefixText.isEmpty())
154 stream << provider.prefixText.join(u'\n') <<
"\n\n";
156 stream <<
"#ifdef TRACEPOINT_DEFINE\n"
157 <<
"TRACELOGGING_DEFINE_PROVIDER(" << providerV <<
", \""
158 << provider.name <<
"\", " << guid <<
");\n\n";
160 stream <<
"static inline void registerProvider()\n"
162 <<
" TraceLoggingRegister(" << providerV <<
");\n"
165 stream <<
"static inline void unregisterProvider()\n"
167 <<
" TraceLoggingUnregister(" << providerV <<
");\n"
170 stream <<
"Q_CONSTRUCTOR_FUNCTION(registerProvider)\n"
171 <<
"Q_DESTRUCTOR_FUNCTION(unregisterProvider)\n\n";
174 <<
"TRACELOGGING_DECLARE_PROVIDER(" << providerV <<
");\n"
175 <<
"#endif // TRACEPOINT_DEFINE\n\n";
180 stream <<
"\n#endif // " << includeGuard(fileName) <<
"\n"
181 <<
"#include <private/qtrace_p.h>\n";
184static void writeWrapper(QTextStream &stream,
const Provider &provider,
const Tracepoint &tracepoint,
185 const QString &providerName)
187 const QString argList = formatFunctionSignature(tracepoint.args);
188 const QString paramList = formatParameterList(provider, tracepoint.args, tracepoint.fields, ETW);
189 const QString &name = tracepoint.name;
190 const QString includeGuard = QStringLiteral(
"TP_%1_%2").arg(providerName).arg(name).toUpper();
191 const QString provar = providerVar(providerName);
195 stream <<
"inline void trace_" << name <<
"(" << argList <<
")\n"
200 for (
const Tracepoint::Field &field : tracepoint.fields) {
201 if (field.backendType == Tracepoint::Field::Unknown) {
202 stream <<
" const QString " << field.name <<
"Str = QDebug::toString(" << field.name
206 stream <<
" TraceLoggingWrite(" << provar <<
", \"" << name <<
"\"";
208 for (
const Tracepoint::Field &field : tracepoint.fields) {
211 writeEtwMacro(stream, field);
217 stream <<
"inline void do_trace_" << name <<
"(" << argList <<
")\n"
219 <<
" trace_" << name <<
"(" << paramList <<
");\n"
222 stream <<
"inline bool trace_" << name <<
"_enabled()\n"
224 <<
" return TraceLoggingProviderEnabled(" << provar <<
", 0, 0);\n"
230 stream <<
"inline QString trace_convert_" << typeToTypeName(enumeration.name) <<
"(" << enumeration.name <<
" val)\n";
232 for (
const auto &v : enumeration.values) {
234 stream <<
" if (val >= " << v.value <<
" && val <= " << v.range <<
")\n"
235 <<
" return QStringLiteral(\"" << v.name <<
" + \") + QString::number((int)val - " << v.value <<
");\n";
238 stream <<
"\n QString ret;\n switch (val) {\n";
240 QList<
int> handledValues;
241 for (
const auto &v : enumeration.values) {
242 if (v.range == 0 && !handledValues.contains(v.value)) {
243 stream <<
" case " << v.value <<
": ret = QStringLiteral(\""
244 << aggregateListValues(v.value, enumeration.values) <<
"\"); break;\n";
245 handledValues.append(v.value);
249 stream <<
" }\n return ret;\n}\n";
254 stream <<
"inline QString trace_convert_" << typeToTypeName(flag.name) <<
"(" << flag.name <<
" val)\n";
255 stream <<
"{\n QString ret;\n";
256 for (
const auto &v : flag.values) {
258 stream <<
" if (val == 0)\n return QStringLiteral(\""
259 << aggregateListValues(v.value, flag.values) <<
"\");\n";
263 QList<
int> handledValues;
264 for (
const auto &v : flag.values) {
265 if (v.value != 0 && !handledValues.contains(v.value)) {
266 stream <<
" if (val & " << (1 << (v.value - 1))
267 <<
") { if (ret.length()) ret += QLatin1Char(\'|\'); ret += QStringLiteral(\"" << v.name <<
"\"); }\n";
268 handledValues.append(v.value);
271 stream <<
" return ret;\n}\n";
276 if (provider.tracepoints.isEmpty())
279 const QString includeGuard = QStringLiteral(
"TP_%1_PROVIDER").arg(provider.name).toUpper();
281 stream <<
"#if !defined(" << includeGuard <<
") && !defined(TRACEPOINT_DEFINE)\n"
282 <<
"#define " << includeGuard <<
"\n"
283 <<
"QT_BEGIN_NAMESPACE\n"
284 <<
"namespace QtPrivate {\n";
286 for (
const auto &enumeration : provider.enumerations)
287 writeEnumConverter(stream, enumeration);
289 for (
const auto &flag : provider.flags)
290 writeFlagConverter(stream, flag);
292 for (
const Tracepoint &t : provider.tracepoints)
293 writeWrapper(stream, provider, t, provider.name);
295 stream <<
"} // namespace QtPrivate\n"
296 <<
"QT_END_NAMESPACE\n"
297 <<
"#endif // " << includeGuard <<
"\n\n";
304 const QString fileName = QFileInfo(file.fileName()).fileName();
306 writePrologue(stream, fileName, provider);
307 writeTracepoints(stream, provider);
308 writeEpilogue(stream, fileName);
QT_FORWARD_DECLARE_CLASS(QTextStream)
static QString providerVar(const QString &providerName)
static void writeEpilogue(QTextStream &stream, const QString &fileName)
void writeEtw(QFile &file, const Provider &provider)
static void writeEnumConverter(QTextStream &stream, const TraceEnum &enumeration)
static void writeFlagConverter(QTextStream &stream, const TraceFlags &flag)
static void writeEtwMacro(QTextStream &stream, const Tracepoint::Field &field)
static void writeWrapper(QTextStream &stream, const Provider &provider, const Tracepoint &tracepoint, const QString &providerName)
static QString createGuid(QByteArrayView name)
static void writePrologue(QTextStream &stream, const QString &fileName, const Provider &provider)
static void writeTracepoints(QTextStream &stream, const Provider &provider)