CTF: Move event metadata generation to the wrapper

This fixes the metadata generation when cross compiling. The metadata
needs to be generated based on the type info of the target. Currently
the metadata is generated in the tool based on the host type info.

Task-number: QTBUG-110270
Pick-to: 6.5
Change-Id: Ibcdcbd690620afc532d6007cf036229342bdcc31
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Antti Määttä 2023-01-17 08:22:19 +02:00
parent b652d9753b
commit c5d4c9345b
8 changed files with 180 additions and 119 deletions

View File

@ -181,9 +181,9 @@ inline QByteArray toByteArrayFromFlags(QFlags<T> value)
} // trace } // trace
#define _DEFINE_EVENT(provider, event, metadata, size, varSize) \ #define _DEFINE_EVENT(provider, event, metadata, size, varSize) \
static QCtfTracePointEvent _ctf_ ## event = QCtfTracePointEvent(_ctf_provider_ ## provider, QStringLiteral(QT_STRINGIFY(event)), QStringLiteral(metadata), size, varSize); static QCtfTracePointEvent _ctf_ ## event = QCtfTracePointEvent(_ctf_provider_ ## provider, QStringLiteral(QT_STRINGIFY(event)), metadata, size, varSize);
#define _DEFINE_METADATA(provider, name, metadata) \ #define _DEFINE_METADATA(provider, name, metadata) \
static QCtfTraceMetadata _ctf_metadata_ ## name = QCtfTraceMetadata(_ctf_provider_ ## provider, QStringLiteral(QT_STRINGIFY(name)), QStringLiteral(metadata)); static QCtfTraceMetadata _ctf_metadata_ ## name = QCtfTraceMetadata(_ctf_provider_ ## provider, QStringLiteral(QT_STRINGIFY(name)), metadata);
#define _DEFINE_TRACEPOINT_PROVIDER(provider) \ #define _DEFINE_TRACEPOINT_PROVIDER(provider) \
static QCtfTracePointProvider _ctf_provider_ ## provider = QCtfTracePointProvider(QStringLiteral(QT_STRINGIFY(provider))); static QCtfTracePointProvider _ctf_provider_ ## provider = QCtfTracePointProvider(QStringLiteral(QT_STRINGIFY(provider)));

View File

@ -88,17 +88,94 @@ static void writeWrapper(QTextStream &stream,
<< "#endif // " << includeGuard << "\n\n"; << "#endif // " << includeGuard << "\n\n";
} }
static void writeMetadataGenerators(QTextStream &stream)
{
stream << R"CPP(
template <typename T>
inline QString integerToMetadata(const QString &name)
{
QString ret;
if (!std::is_signed<T>().value)
ret += QLatin1Char('u');
if (sizeof(T) == 8)
ret += QStringLiteral("int64_t ");
else if (sizeof(T) == 4)
ret += QStringLiteral("int32_t ");
else if (sizeof(T) == 2)
ret += QStringLiteral("int16_t ");
else if (sizeof(T) == 1)
ret += QStringLiteral("int8_t ");
ret += name + QLatin1Char(';');
return ret;
}
template <typename T>
inline QString integerArrayToMetadata(const QString &size, const QString &name)
{
QString ret;
if (!std::is_signed<T>().value)
ret += QLatin1Char('u');
if (sizeof(T) == 8)
ret += QStringLiteral("int64_t ");
else if (sizeof(T) == 4)
ret += QStringLiteral("int32_t ");
else if (sizeof(T) == 2)
ret += QStringLiteral("int16_t ");
else if (sizeof(T) == 1)
ret += QStringLiteral("int8_t ");
ret += name + QLatin1Char('[') + size + QStringLiteral("];");
return ret;
}
template <typename T>
inline QString floatToMetadata(const QString &name)
{
QString ret;
if (sizeof(T) == 8)
ret += QStringLiteral("double ");
else if (sizeof(T) == 4)
ret += QStringLiteral("float ");
ret += name + QLatin1Char(';');
return ret;
}
template <typename T>
inline QString floatArrayToMetadata(const QString &size, const QString &name)
{
QString ret;
if (sizeof(T) == 8)
ret += QStringLiteral("double ");
else if (sizeof(T) == 4)
ret += QStringLiteral("float ");
ret += name + QLatin1Char('[') + size + QStringLiteral("];");
return ret + QLatin1Char(';');
}
inline QString pointerToMetadata(const QString &name)
{
QString ret;
if (QT_POINTER_SIZE == 8)
ret += QStringLiteral("intptr64_t ");
else if (QT_POINTER_SIZE == 4)
ret += QStringLiteral("intptr32_t ");
ret += name + QLatin1Char(';');
return ret;
}
)CPP";
}
static void writeTracepoint(QTextStream &stream, static void writeTracepoint(QTextStream &stream,
const Tracepoint &tracepoint, const QString &providerName) const Tracepoint &tracepoint, const QString &providerName)
{ {
stream << "TRACEPOINT_EVENT(\n" stream << "TRACEPOINT_EVENT(\n"
<< " " << providerName << ",\n" << " " << providerName << ",\n"
<< " " << tracepoint.name << ",\n"; << " " << tracepoint.name << ",\n";
stream << "\"";
const auto checkUnknownArgs = [](const Tracepoint &tracepoint) { const auto checkUnknownArgs = [](const Tracepoint &tracepoint) {
for (auto &field : tracepoint.fields) { for (auto &field : tracepoint.fields) {
if (field.backendType.backendType == Tracepoint::Field::Unknown) if (field.backendType == Tracepoint::Field::Unknown)
return true; return true;
} }
return false; return false;
@ -110,114 +187,105 @@ static void writeTracepoint(QTextStream &stream,
ret = type.left(type.length() - 1).simplified(); ret = type.left(type.length() - 1).simplified();
if (ret.startsWith(QStringLiteral("const"))) if (ret.startsWith(QStringLiteral("const")))
ret = ret.right(ret.length() - 6).simplified(); ret = ret.right(ret.length() - 6).simplified();
return typeToName(ret); return typeToTypeName(ret);
}; };
int eventSize = 0; QString eventSize;
bool variableSize = false; bool variableSize = false;
if (!checkUnknownArgs(tracepoint)) { const bool emptyMetadata = checkUnknownArgs(tracepoint) || tracepoint.args.size() == 0;
if (!emptyMetadata) {
for (int i = 0; i < tracepoint.args.size(); i++) { for (int i = 0; i < tracepoint.args.size(); i++) {
auto &arg = tracepoint.args[i]; auto &arg = tracepoint.args[i];
auto &field = tracepoint.fields[i]; auto &field = tracepoint.fields[i];
if (i > 0) { if (i > 0) {
stream << " \\n\\\n"; stream << " + QStringLiteral(\"\\n\\\n \") + ";
stream << " "; eventSize += QStringLiteral(" + ");
} }
const bool array = field.arrayLen > 0; const bool array = field.arrayLen > 0;
switch (field.backendType.backendType) { switch (field.backendType) {
case Tracepoint::Field::Boolean: { case Tracepoint::Field::Boolean: {
stream << "Boolean " << arg.name << ";"; stream << "QStringLiteral(\"Boolean " << arg.name << ";\")";
eventSize += 8; eventSize += QStringLiteral("sizeof(bool)");
} break; } break;
case Tracepoint::Field::Integer: { case Tracepoint::Field::Integer: {
if (!field.backendType.isSigned) if (array) {
stream << "u"; stream << "integerArrayToMetadata<" << formatType(arg.type)
stream << "int" << field.backendType.bits << "_t "; << ">(QStringLiteral(\"" << field.arrayLen << "\"), QStringLiteral(\""
<< arg.name << "\"))";
} else {
stream << "integerToMetadata<" << formatType(arg.type) << ">(QStringLiteral(\""
<< arg.name << "\"))";
}
eventSize += QStringLiteral("sizeof(") + formatType(arg.type) + QStringLiteral(")");
if (array) if (array)
stream << arg.name << "[" << field.arrayLen << "];"; eventSize += QStringLiteral(" * ") + QString::number(field.arrayLen);
else
stream << arg.name << ";";
eventSize += field.backendType.bits * qMax(1, field.arrayLen);
} break;
case Tracepoint::Field::Pointer: {
if (QT_POINTER_SIZE == 8)
stream << "intptr64_t " << formatType(arg.type) << "_" << arg.name << ";";
else
stream << "intptr32_t " << formatType(arg.type) << "_" << arg.name << ";";
eventSize += QT_POINTER_SIZE * 8;
} break; } break;
case Tracepoint::Field::Pointer:
case Tracepoint::Field::IntegerHex: { case Tracepoint::Field::IntegerHex: {
if (field.backendType.bits == 64) stream << "pointerToMetadata(QStringLiteral(\"" << formatType(arg.type) << "_"
stream << "intptr64_t " << formatType(arg.name) << ";"; << arg.name << "\"))";
else eventSize += QStringLiteral("QT_POINTER_SIZE");
stream << "intptr32_t " << formatType(arg.name) << ";";
eventSize += field.backendType.bits;
} break; } break;
case Tracepoint::Field::Float: { case Tracepoint::Field::Float: {
if (field.backendType.bits == 32)
stream << "float " << arg.name;
else
stream << "double " << arg.name;
if (array) { if (array) {
stream << "[" << field.arrayLen << "];"; stream << "floatArrayToMetadata<" << formatType(arg.type)
<< ">(QStringLiteral(\"" << field.arrayLen << "\"), QStringLiteral(\""
<< arg.name << "\"))";
} else { } else {
stream << ";"; stream << "floatToMetadata<" << formatType(arg.type) << ">(QStringLiteral(\""
<< arg.name << "\"))";
} }
eventSize += field.backendType.bits * qMax(1, field.arrayLen); eventSize += QStringLiteral("sizeof(") + formatType(arg.type) + QStringLiteral(")");
if (array)
eventSize += QStringLiteral(" * ") + QString::number(field.arrayLen);
} break; } break;
case Tracepoint::Field::QtUrl:
case Tracepoint::Field::QtString:
case Tracepoint::Field::String: { case Tracepoint::Field::String: {
stream << "string " << arg.name << ";"; stream << "QStringLiteral(\"string " << arg.name << ";\")";
eventSize += 8; eventSize += QStringLiteral("1");
variableSize = true;
} break;
case Tracepoint::Field::QtString: {
stream << "string " << arg.name << ";";
eventSize += 8;
variableSize = true;
} break;
case Tracepoint::Field::QtByteArray:
break;
case Tracepoint::Field::QtUrl: {
stream << "string " << arg.name << ";";
eventSize += 8;
variableSize = true; variableSize = true;
} break; } break;
case Tracepoint::Field::QtRect: { case Tracepoint::Field::QtRect: {
stream << "int32_t QRect_" << arg.name << "_x;\\n\\\n "; stream << "QStringLiteral(\"int32_t QRect_" << arg.name << "_x;\\n\\\n \")";
stream << "int32_t QRect_" << arg.name << "_y;\\n\\\n "; stream << " + QStringLiteral(\"int32_t QRect_" << arg.name << "_y;\\n\\\n \")";
stream << "int32_t QRect_" << arg.name << "_width;\\n\\\n "; stream << " + QStringLiteral(\"int32_t QRect_" << arg.name << "_width;\\n\\\n \")";
stream << "int32_t QRect_" << arg.name << "_height;"; stream << " + QStringLiteral(\"int32_t QRect_" << arg.name << "_height;\\n\\\n \")";
eventSize += 32 * 4; eventSize += QStringLiteral("16");
} break; } break;
case Tracepoint::Field::QtSize: { case Tracepoint::Field::QtSize: {
stream << "int32_t QSize_" << arg.name << "_width;\\n\\\n "; stream << "QStringLiteral(\"int32_t QSize_" << arg.name << "_width;\\n\\\n \")";
stream << "int32_t QSize_" << arg.name << "_height;"; stream << " + QStringLiteral(\"int32_t QSize_" << arg.name << "_height;\\n\\\n \")";
eventSize += 32 * 2; eventSize += QStringLiteral("8");
} break; } break;
case Tracepoint::Field::Unknown: case Tracepoint::Field::Unknown:
break; break;
case Tracepoint::Field::EnumeratedType: { case Tracepoint::Field::EnumeratedType: {
QString type = arg.type; stream << "QStringLiteral(\"" << typeToTypeName(arg.type) << " " << arg.name << ";\")";
type.replace(QStringLiteral("::"), QStringLiteral("_")); eventSize += QString::number(field.enumValueSize / 8);
stream << type << " " << arg.name << ";";
eventSize += field.backendType.bits;
variableSize = true; variableSize = true;
} break; } break;
case Tracepoint::Field::FlagType: { case Tracepoint::Field::FlagType: {
QString type = arg.type; stream << "QStringLiteral(\"uint8_t " << arg.name << "_length;\\n\\\n ";
type.replace(QStringLiteral("::"), QStringLiteral("_")); stream << typeToTypeName(arg.type) << " " << arg.name << "[" << arg.name << "_length];\")";
stream << "uint8_t " << arg.name << "_length;\\n\\\n "; eventSize += QStringLiteral("2");
stream << type << " " << arg.name << "[" << arg.name << "_length];"; variableSize = true;
eventSize += 16;
} break; } break;
case Tracepoint::Field::QtByteArray:
case Tracepoint::Field::Sequence: case Tracepoint::Field::Sequence:
panic("Unhandled sequence '%s %s", qPrintable(arg.type), qPrintable(arg.name)); panic("Unhandled type '%s %s", qPrintable(arg.type), qPrintable(arg.name));
break; break;
} }
} }
} }
stream << "\",\n"; if (emptyMetadata)
stream << eventSize / 8 << ", \n"; stream << "{},\n";
else
stream << ",\n";
if (eventSize.length())
stream << eventSize << ", \n";
else
stream << "0, \n";
stream << (variableSize ? "true" : "false") << "\n"; stream << (variableSize ? "true" : "false") << "\n";
stream << ")\n\n"; stream << ")\n\n";
} }
@ -236,14 +304,14 @@ static void writeEnums(QTextStream &stream, const Provider &provider)
QString name = e.name; QString name = e.name;
name.replace(QStringLiteral("::"), QStringLiteral("_")); name.replace(QStringLiteral("::"), QStringLiteral("_"));
stream << "TRACEPOINT_METADATA(" << provider.name << ", " << name << ", \n"; stream << "TRACEPOINT_METADATA(" << provider.name << ", " << name << ", \n";
stream << "\"typealias enum : integer { size = " << e.valueSize << "; } {\\n\\\n"; stream << "QStringLiteral(\"typealias enum : integer { size = " << e.valueSize << "; } {\\n\\\n";
for (const auto &v : e.values) { for (const auto &v : e.values) {
if (v.range) if (v.range)
stream << v.name << " = " << v.value << " ... " << v.range << ", \\n\\\n"; stream << v.name << " = " << v.value << " ... " << v.range << ", \\n\\\n";
else else
stream << v.name << " = " << v.value << ", \\n\\\n"; stream << v.name << " = " << v.value << ", \\n\\\n";
} }
stream << "} := " << name << ";\\n\\n\");\n\n"; stream << "} := " << name << ";\\n\\n\"));\n\n";
} }
stream << "\n"; stream << "\n";
} }
@ -254,11 +322,11 @@ static void writeFlags(QTextStream &stream, const Provider &provider)
QString name = e.name; QString name = e.name;
name.replace(QStringLiteral("::"), QStringLiteral("_")); name.replace(QStringLiteral("::"), QStringLiteral("_"));
stream << "TRACEPOINT_METADATA(" << provider.name << ", " << name << ", \n"; stream << "TRACEPOINT_METADATA(" << provider.name << ", " << name << ", \n";
stream << "\"typealias enum : integer { size = 8; } {\\n\\\n"; stream << "QStringLiteral(\"typealias enum : integer { size = 8; } {\\n\\\n";
for (const auto &v : e.values) { for (const auto &v : e.values) {
stream << v.name << " = " << v.value << ", \\n\\\n"; stream << v.name << " = " << v.value << ", \\n\\\n";
} }
stream << "} := " << name << ";\\n\\n\");\n\n"; stream << "} := " << name << ";\\n\\n\"));\n\n";
} }
stream << "\n"; stream << "\n";
} }
@ -270,6 +338,7 @@ void writeCtf(QFile &file, const Provider &provider)
const QString fileName = QFileInfo(file.fileName()).fileName(); const QString fileName = QFileInfo(file.fileName()).fileName();
writePrologue(stream, fileName, provider); writePrologue(stream, fileName, provider);
writeMetadataGenerators(stream);
writeEnums(stream, provider); writeEnums(stream, provider);
writeFlags(stream, provider); writeFlags(stream, provider);
writeTracepoints(stream, provider); writeTracepoints(stream, provider);

View File

@ -31,7 +31,7 @@ static void writeEtwMacro(QTextStream &stream, const Tracepoint::Field &field)
return; return;
} }
switch (field.backendType.backendType) { switch (field.backendType) {
case Tracepoint::Field::QtString: case Tracepoint::Field::QtString:
stream << "TraceLoggingCountedWideString(reinterpret_cast<LPCWSTR>(" stream << "TraceLoggingCountedWideString(reinterpret_cast<LPCWSTR>("
<< name << ".utf16()), static_cast<ULONG>(" << name << ".size()), \"" << name << ".utf16()), static_cast<ULONG>(" << name << ".size()), \""
@ -66,7 +66,7 @@ static void writeEtwMacro(QTextStream &stream, const Tracepoint::Field &field)
return; return;
case Tracepoint::Field::EnumeratedType: case Tracepoint::Field::EnumeratedType:
case Tracepoint::Field::FlagType: case Tracepoint::Field::FlagType:
stream << "TraceLoggingString(trace_convert_" << typeToName(field.paramType) << "(" << name << ").toUtf8().constData(), \"" << name << "\")"; stream << "TraceLoggingString(trace_convert_" << typeToTypeName(field.paramType) << "(" << name << ").toUtf8().constData(), \"" << name << "\")";
return; return;
default: default:
break; break;
@ -177,7 +177,7 @@ static void writeWrapper(QTextStream &stream, const Provider &provider, const Tr
// Convert all unknown types to QString's using QDebug. // Convert all unknown types to QString's using QDebug.
// Note the naming convention: it's field.name##Str // Note the naming convention: it's field.name##Str
for (const Tracepoint::Field &field : tracepoint.fields) { for (const Tracepoint::Field &field : tracepoint.fields) {
if (field.backendType.backendType == Tracepoint::Field::Unknown) { if (field.backendType == Tracepoint::Field::Unknown) {
stream << " const QString " << field.name << "Str = QDebug::toString(" << field.name stream << " const QString " << field.name << "Str = QDebug::toString(" << field.name
<< ");\n"; << ");\n";
} }
@ -206,7 +206,7 @@ static void writeWrapper(QTextStream &stream, const Provider &provider, const Tr
static void writeEnumConverter(QTextStream &stream, const TraceEnum &enumeration) static void writeEnumConverter(QTextStream &stream, const TraceEnum &enumeration)
{ {
stream << "inline QString trace_convert_" << typeToName(enumeration.name) << "(" << enumeration.name << " val)\n"; stream << "inline QString trace_convert_" << typeToTypeName(enumeration.name) << "(" << enumeration.name << " val)\n";
stream << "{\n"; stream << "{\n";
for (const auto &v : enumeration.values) { for (const auto &v : enumeration.values) {
if (v.range != 0) { if (v.range != 0) {
@ -225,7 +225,7 @@ static void writeEnumConverter(QTextStream &stream, const TraceEnum &enumeration
static void writeFlagConverter(QTextStream &stream, const TraceFlags &flag) static void writeFlagConverter(QTextStream &stream, const TraceFlags &flag)
{ {
stream << "inline QString trace_convert_" << typeToName(flag.name) << "(" << flag.name << " val)\n"; stream << "inline QString trace_convert_" << typeToTypeName(flag.name) << "(" << flag.name << " val)\n";
stream << "{\n QString ret;\n"; stream << "{\n QString ret;\n";
for (const auto &v : flag.values) { for (const auto &v : flag.values) {
if (v.value == 0) { if (v.value == 0) {

View File

@ -6,7 +6,7 @@
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
QString typeToName(const QString &name) QString typeToTypeName(const QString &name)
{ {
QString ret = name; QString ret = name;
return ret.replace(QStringLiteral("::"), QStringLiteral("_")); return ret.replace(QStringLiteral("::"), QStringLiteral("_"));
@ -57,8 +57,8 @@ QString formatParameterList(const Provider &provider, const QList<Tracepoint::Ar
for (int i = 0; i < args.size(); i++) { for (int i = 0; i < args.size(); i++) {
const Tracepoint::Argument &arg = args[i]; const Tracepoint::Argument &arg = args[i];
const Tracepoint::Field &field = fields[i]; const Tracepoint::Field &field = fields[i];
if (field.backendType.backendType == Tracepoint::Field::FlagType) if (field.backendType == Tracepoint::Field::FlagType)
ret += ", trace_convert_"_L1 + typeToName(arg.type) + "("_L1 + arg.name + ")"_L1; ret += ", trace_convert_"_L1 + typeToTypeName(arg.type) + "("_L1 + arg.name + ")"_L1;
else else
ret += ", "_L1 + arg.name; ret += ", "_L1 + arg.name;
} }
@ -81,7 +81,7 @@ QString formatParameterList(const Provider &provider, const QList<Tracepoint::Ar
const Tracepoint::Field &field = fields[i]; const Tracepoint::Field &field = fields[i];
if (arg.arrayLen > 1) { if (arg.arrayLen > 1) {
ret += ", trace::toByteArrayFromArray("_L1 + arg.name + ", "_L1 + QString::number(arg.arrayLen) + ") "_L1; ret += ", trace::toByteArrayFromArray("_L1 + arg.name + ", "_L1 + QString::number(arg.arrayLen) + ") "_L1;
} else if (field.backendType.backendType == Tracepoint::Field::EnumeratedType) { } else if (field.backendType == Tracepoint::Field::EnumeratedType) {
const TraceEnum &e = findEnumeration(provider.enumerations, arg.type); const TraceEnum &e = findEnumeration(provider.enumerations, arg.type);
QString integerType; QString integerType;
if (e.valueSize == 8) if (e.valueSize == 8)
@ -91,9 +91,9 @@ QString formatParameterList(const Provider &provider, const QList<Tracepoint::Ar
else else
integerType = QStringLiteral("quint32"); integerType = QStringLiteral("quint32");
ret += ", trace::toByteArrayFromEnum<"_L1 + integerType + ">("_L1 + arg.name + ")"_L1; ret += ", trace::toByteArrayFromEnum<"_L1 + integerType + ">("_L1 + arg.name + ")"_L1;
} else if (field.backendType.backendType == Tracepoint::Field::FlagType) { } else if (field.backendType == Tracepoint::Field::FlagType) {
ret += ", trace::toByteArrayFromFlags("_L1 + arg.name + ")"_L1; ret += ", trace::toByteArrayFromFlags("_L1 + arg.name + ")"_L1;
} else if (field.backendType.backendType == Tracepoint::Field::String) { } else if (field.backendType == Tracepoint::Field::String) {
ret += ", trace::toByteArrayFromCString("_L1 + arg.name + ")"_L1; ret += ", trace::toByteArrayFromCString("_L1 + arg.name + ")"_L1;
} else { } else {
ret += ", "_L1 + arg.name; ret += ", "_L1 + arg.name;

View File

@ -15,7 +15,7 @@ enum ParamType {
CTF CTF
}; };
QString typeToName(const QString &name); QString typeToTypeName(const QString &type);
QString includeGuard(const QString &filename); QString includeGuard(const QString &filename);
QString formatFunctionSignature(const QList<Tracepoint::Argument> &args); QString formatFunctionSignature(const QList<Tracepoint::Argument> &args);
QString formatParameterList(const Provider &provider, const QList<Tracepoint::Argument> &args, const QList<Tracepoint::Field> &fields, ParamType type); QString formatParameterList(const Provider &provider, const QList<Tracepoint::Argument> &args, const QList<Tracepoint::Field> &fields, ParamType type);

View File

@ -25,7 +25,7 @@ static void writeCtfMacro(QTextStream &stream, const Provider &provider, const T
return; return;
} }
switch (field.backendType.backendType) { switch (field.backendType) {
case Tracepoint::Field::Sequence: case Tracepoint::Field::Sequence:
stream << "ctf_sequence(" << paramType stream << "ctf_sequence(" << paramType
<< ", " << name << ", " << name << ", " << name << ", " << name
@ -66,7 +66,7 @@ static void writeCtfMacro(QTextStream &stream, const Provider &provider, const T
<< "ctf_integer(int, height, " << name << ".height()) "; << "ctf_integer(int, height, " << name << ".height()) ";
return; return;
case Tracepoint::Field::EnumeratedType: case Tracepoint::Field::EnumeratedType:
stream << "ctf_enum(" << provider.name << ", " << typeToName(paramType) << ", int, " << name << ", " << name << ") "; stream << "ctf_enum(" << provider.name << ", " << typeToTypeName(paramType) << ", int, " << name << ", " << name << ") ";
return; return;
case Tracepoint::Field::FlagType: case Tracepoint::Field::FlagType:
stream << "ctf_sequence(const char , " << name << ", " stream << "ctf_sequence(const char , " << name << ", "
@ -170,7 +170,7 @@ static void writeTracepoint(QTextStream &stream, const Provider &provider,
for (int i = 0; i < tracepoint.args.size(); i++) { for (int i = 0; i < tracepoint.args.size(); i++) {
const auto &arg = tracepoint.args[i]; const auto &arg = tracepoint.args[i];
const auto &field = tracepoint.fields[i]; const auto &field = tracepoint.fields[i];
if (field.backendType.backendType == Tracepoint::Field::FlagType) if (field.backendType == Tracepoint::Field::FlagType)
stream << comma << "QByteArray, " << arg.name; stream << comma << "QByteArray, " << arg.name;
else else
stream << comma << arg.type << ", " << arg.name; stream << comma << arg.type << ", " << arg.name;
@ -196,7 +196,7 @@ static void writeEnums(QTextStream &stream, const Provider &provider)
for (const auto &e : provider.enumerations) { for (const auto &e : provider.enumerations) {
stream << "TRACEPOINT_ENUM(\n" stream << "TRACEPOINT_ENUM(\n"
<< " " << provider.name << ",\n" << " " << provider.name << ",\n"
<< " " << typeToName(e.name) << ",\n" << " " << typeToTypeName(e.name) << ",\n"
<< " TP_ENUM_VALUES(\n"; << " TP_ENUM_VALUES(\n";
for (const auto &v : e.values) { for (const auto &v : e.values) {
if (v.range > 0) if (v.range > 0)
@ -213,7 +213,7 @@ static void writeFlags(QTextStream &stream, const Provider &provider)
for (const auto &f : provider.flags) { for (const auto &f : provider.flags) {
stream << "TRACEPOINT_ENUM(\n" stream << "TRACEPOINT_ENUM(\n"
<< " " << provider.name << ",\n" << " " << provider.name << ",\n"
<< " " << typeToName(f.name) << ",\n" << " " << typeToTypeName(f.name) << ",\n"
<< " TP_ENUM_VALUES(\n"; << " TP_ENUM_VALUES(\n";
for (const auto &v : f.values) for (const auto &v : f.values)
stream << " ctf_enum_value(\"" << v.name << "\", " << v.value << ")\n"; stream << " ctf_enum_value(\"" << v.name << "\", " << v.value << ")\n";
@ -228,7 +228,7 @@ static void writeFlags(QTextStream &stream, const Provider &provider)
stream << "QT_BEGIN_NAMESPACE\n"; stream << "QT_BEGIN_NAMESPACE\n";
stream << "namespace QtPrivate {\n"; stream << "namespace QtPrivate {\n";
for (const auto &f : provider.flags) { for (const auto &f : provider.flags) {
stream << "inline QByteArray trace_convert_" << typeToName(f.name) << "(" << f.name << " val)\n"; stream << "inline QByteArray trace_convert_" << typeToTypeName(f.name) << "(" << f.name << " val)\n";
stream << "{\n"; stream << "{\n";
stream << " QByteArray ret;\n"; stream << " QByteArray ret;\n";
stream << " if (val == 0) { ret.append((char)0); return ret; }\n"; stream << " if (val == 0) { ret.append((char)0); return ret; }\n";

View File

@ -97,17 +97,14 @@ static QString removeBraces(QString type)
} }
#define TYPEDATA_ENTRY(type, backendType) \ #define TYPEDATA_ENTRY(type, backendType) \
{ QT_STRINGIFY(type), backendType, sizeof(type) * 8, std::is_signed<type>::value } { QT_STRINGIFY(type), backendType }
static Tracepoint::Field::BackendType backendType(QString rawType) static Tracepoint::Field::Type backendType(QString rawType)
{ {
static const struct TypeData { static const struct TypeData {
const char *type; const char *type;
Tracepoint::Field::Type backendType; Tracepoint::Field::Type backendType;
int bits;
bool isSigned;
} typeTable[] = { } typeTable[] = {
#ifdef UNDERSCORE_TYPES_DEFINED
TYPEDATA_ENTRY(short_int, Tracepoint::Field::Integer), TYPEDATA_ENTRY(short_int, Tracepoint::Field::Integer),
TYPEDATA_ENTRY(signed_short, Tracepoint::Field::Integer), TYPEDATA_ENTRY(signed_short, Tracepoint::Field::Integer),
TYPEDATA_ENTRY(signed_short_int, Tracepoint::Field::Integer), TYPEDATA_ENTRY(signed_short_int, Tracepoint::Field::Integer),
@ -125,7 +122,6 @@ static Tracepoint::Field::BackendType backendType(QString rawType)
TYPEDATA_ENTRY(signed_long_long, Tracepoint::Field::Integer), TYPEDATA_ENTRY(signed_long_long, Tracepoint::Field::Integer),
TYPEDATA_ENTRY(signed_long_long_int, Tracepoint::Field::Integer), TYPEDATA_ENTRY(signed_long_long_int, Tracepoint::Field::Integer),
TYPEDATA_ENTRY(unsigned_long_long, Tracepoint::Field::Integer), TYPEDATA_ENTRY(unsigned_long_long, Tracepoint::Field::Integer),
#endif
TYPEDATA_ENTRY(bool, Tracepoint::Field::Boolean), TYPEDATA_ENTRY(bool, Tracepoint::Field::Boolean),
TYPEDATA_ENTRY(int, Tracepoint::Field::Integer), TYPEDATA_ENTRY(int, Tracepoint::Field::Integer),
TYPEDATA_ENTRY(signed, Tracepoint::Field::Integer), TYPEDATA_ENTRY(signed, Tracepoint::Field::Integer),
@ -140,11 +136,11 @@ static Tracepoint::Field::BackendType backendType(QString rawType)
TYPEDATA_ENTRY(float, Tracepoint::Field::Float), TYPEDATA_ENTRY(float, Tracepoint::Field::Float),
TYPEDATA_ENTRY(double, Tracepoint::Field::Float), TYPEDATA_ENTRY(double, Tracepoint::Field::Float),
TYPEDATA_ENTRY(long double, Tracepoint::Field::Float), TYPEDATA_ENTRY(long double, Tracepoint::Field::Float),
{ "QString", Tracepoint::Field::QtString , 0, false}, TYPEDATA_ENTRY(QString, Tracepoint::Field::QtString),
{ "QByteArray", Tracepoint::Field::QtByteArray , 0, false}, TYPEDATA_ENTRY(QByteArray, Tracepoint::Field::QtByteArray),
{ "QUrl", Tracepoint::Field::QtUrl , 0, false}, TYPEDATA_ENTRY(QUrl, Tracepoint::Field::QtUrl),
{ "QRect", Tracepoint::Field::QtRect , 0, false}, TYPEDATA_ENTRY(QRect, Tracepoint::Field::QtRect),
{ "QSize", Tracepoint::Field::QtSize , 0, false} TYPEDATA_ENTRY(QSize, Tracepoint::Field::QtSize)
}; };
auto backendType = [](const QString &rawType) { auto backendType = [](const QString &rawType) {
@ -155,7 +151,7 @@ static Tracepoint::Field::BackendType backendType(QString rawType)
return typeTable[i]; return typeTable[i];
} }
TypeData unknown = { nullptr, Tracepoint::Field::Unknown, 0, false }; TypeData unknown = { nullptr, Tracepoint::Field::Unknown };
return unknown; return unknown;
}; };
@ -164,7 +160,7 @@ static Tracepoint::Field::BackendType backendType(QString rawType)
rawType = removeBraces(rawType); rawType = removeBraces(rawType);
if (!sequenceLength(rawType).isNull()) if (!sequenceLength(rawType).isNull())
return { Tracepoint::Field::Sequence, 0, false }; return Tracepoint::Field::Sequence;
static const QRegularExpression constMatch(QStringLiteral("\\bconst\\b")); static const QRegularExpression constMatch(QStringLiteral("\\bconst\\b"));
rawType.remove(constMatch); rawType.remove(constMatch);
@ -176,13 +172,13 @@ static Tracepoint::Field::BackendType backendType(QString rawType)
rawType.replace(QStringLiteral(" "), QStringLiteral("_")); rawType.replace(QStringLiteral(" "), QStringLiteral("_"));
if (rawType == "char_ptr"_L1) if (rawType == "char_ptr"_L1)
return { Tracepoint::Field::String, 0, false }; return Tracepoint::Field::String;
if (rawType.endsWith("_ptr"_L1)) if (rawType.endsWith("_ptr"_L1))
return {Tracepoint::Field::Pointer, QT_POINTER_SIZE, false }; return Tracepoint::Field::Pointer;
TypeData d = backendType(rawType); TypeData d = backendType(rawType);
return { d.backendType, d.bits, d.isSigned }; return d.backendType;
} }
static Tracepoint parseTracepoint(const Provider &provider, const QString &name, const QStringList &args, static Tracepoint parseTracepoint(const Provider &provider, const QString &name, const QStringList &args,
@ -246,9 +242,10 @@ static Tracepoint parseTracepoint(const Provider &provider, const QString &name,
const TraceEnum &e = findEnumeration(provider.enumerations, type); const TraceEnum &e = findEnumeration(provider.enumerations, type);
const TraceFlags &f = findFlags(provider.flags, type); const TraceFlags &f = findFlags(provider.flags, type);
if (!e.name.isEmpty()) { if (!e.name.isEmpty()) {
field.backendType = { Tracepoint::Field::EnumeratedType, e.valueSize, false }; field.backendType = Tracepoint::Field::EnumeratedType;
field.enumValueSize = e.valueSize;
} else if (!f.name.isEmpty()) { } else if (!f.name.isEmpty()) {
field.backendType = { Tracepoint::Field::FlagType, 0, false }; field.backendType = Tracepoint::Field::FlagType;
} else { } else {
field.backendType = backendType(type); field.backendType = backendType(type);
} }

View File

@ -37,15 +37,11 @@ struct Tracepoint
FlagType, FlagType,
Unknown Unknown
}; };
struct BackendType { Type backendType;
Type backendType;
int bits;
bool isSigned;
};
BackendType backendType;
QString paramType; QString paramType;
QString name; QString name;
int arrayLen; int arrayLen;
int enumValueSize;
QString seqLen; QString seqLen;
}; };
@ -77,7 +73,6 @@ struct TraceFlags {
Q_DECLARE_TYPEINFO(TraceEnum, Q_RELOCATABLE_TYPE); Q_DECLARE_TYPEINFO(TraceEnum, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(TraceFlags, Q_RELOCATABLE_TYPE); Q_DECLARE_TYPEINFO(TraceFlags, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(Tracepoint::Argument, Q_RELOCATABLE_TYPE); Q_DECLARE_TYPEINFO(Tracepoint::Argument, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(Tracepoint::Field::BackendType, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(Tracepoint::Field, Q_RELOCATABLE_TYPE); Q_DECLARE_TYPEINFO(Tracepoint::Field, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(Tracepoint, Q_RELOCATABLE_TYPE); Q_DECLARE_TYPEINFO(Tracepoint, Q_RELOCATABLE_TYPE);