summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-06-22 14:01:13 -0700
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-06-25 02:06:20 +0000
commit115cd00f0c4d17c6b521b987bcb1539074028e23 (patch)
tree678f40aa4cf8993d7a758ccd47a2a3ad88f41a46 /src
parent720b592975d52507317b1153e5d3e0a49171bdd8 (diff)
moc: remove the attempt to create one large string literal
Commit dda9c9e2bc4fd2efe9e3fb0e451a8c3512f9a4d2 fixed some outstanding issues with moc's calculation of the maximum string length, but it missed one. This commit instead opts to remove the calculation entirely and instead have multiple char array members in the qt_meta_stringdata. We needed a single string back in Qt 4.0 when the stringdata *was* a single char array. Since 5.0, we've used a structure with multiple members and pointer arithmetic going past the end of the arrays, from the top of the object. That's UB, but since it's always been UB and can't be fixed until Qt 7 anyway, let's go full monty on it and have one char array per meta object string. The struct qt_meta_stringdata_Qt_t for namespace Qt now has 1217 stringdataXXX members. Change-Id: I6d3880c7d99d4fc494c8fffd16fb0d1573e387dc Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 0978646a65f517f0026fbdd0639415d265876512) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r--src/tools/moc/generator.cpp88
1 files changed, 30 insertions, 58 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 3a54593459..5c19697d7f 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -106,6 +106,27 @@ static inline uint lengthOfEscapedString(const QByteArray &str)
return str.length() - extra;
}
+// Prints \a s to \a out, breaking it into lines of at most ColumnWidth. The
+// opening and closing quotes are NOT included (it's up to the caller).
+static void printStringWithIndentation(FILE *out, const QByteArray &s)
+{
+ static constexpr int ColumnWidth = 72;
+ int len = s.length();
+ int idx = 0;
+
+ do {
+ int spanLen = qMin(ColumnWidth - 2, len - idx);
+ // don't cut escape sequences at the end of a line
+ int backSlashPos = s.lastIndexOf('\\', idx + spanLen - 1);
+ if (backSlashPos >= idx) {
+ int escapeLen = lengthOfEscapeSequence(s, backSlashPos);
+ spanLen = qBound(spanLen, backSlashPos + escapeLen - idx, len - idx);
+ }
+ fprintf(out, "\n \"%.*s\"", spanLen, s.constData() + idx);
+ idx += spanLen;
+ } while (idx < len);
+}
+
void Generator::strreg(const QByteArray &s)
{
if (!strings.contains(s))
@@ -231,23 +252,11 @@ void Generator::generateCode()
//
// Build stringdata struct
//
- const int constCharArraySizeLimit = 65535;
fprintf(out, "struct qt_meta_stringdata_%s_t {\n", qualifiedClassNameIdentifier.constData());
fprintf(out, " uint offsetsAndSizes[%d];\n", int(strings.size() * 2));
- {
- int stringDataLength = 0;
- int stringDataCounter = 0;
- for (int i = 0; i < strings.size(); ++i) {
- int thisLength = lengthOfEscapedString(strings.at(i)) + 1;
- stringDataLength += thisLength;
- if (stringDataLength / constCharArraySizeLimit) {
- // save previous stringdata and start computing the next one.
- fprintf(out, " char stringdata%d[%d];\n", stringDataCounter++, stringDataLength - thisLength);
- stringDataLength = thisLength;
- }
- }
- fprintf(out, " char stringdata%d[%d];\n", stringDataCounter, stringDataLength);
-
+ for (int i = 0; i < strings.size(); ++i) {
+ int thisLength = lengthOfEscapedString(strings.at(i)) + 1;
+ fprintf(out, " char stringdata%d[%d];\n", i, thisLength);
}
fprintf(out, "};\n");
@@ -272,56 +281,19 @@ void Generator::generateCode()
idx += len + 1;
}
- fprintf(out, "\n },\n");
+ fprintf(out, "\n }");
}
//
-// Build stringdata array
+// Build stringdata arrays
//
- fprintf(out, " \"");
- int col = 0;
- int len = 0;
- int stringDataLength = 0;
- for (int i = 0; i < strings.size(); ++i) {
- QByteArray s = strings.at(i);
- len = s.length();
- stringDataLength += len + 1;
- if (stringDataLength >= constCharArraySizeLimit) {
- fprintf(out, "\",\n \"");
- stringDataLength = len + 1;
- col = 0;
- } else if (i)
- fputs("\\0", out); // add \0 at the end of each string
-
- if (col && col + len >= 72) {
- fprintf(out, "\"\n \"");
- col = 0;
- } else if (len && s.at(0) >= '0' && s.at(0) <= '9') {
- fprintf(out, "\"\"");
- len += 2;
- }
- int idx = 0;
- while (idx < s.length()) {
- if (idx > 0) {
- col = 0;
- fprintf(out, "\"\n \"");
- }
- int spanLen = qMin(70, s.length() - idx);
- // don't cut escape sequences at the end of a line
- int backSlashPos = s.lastIndexOf('\\', idx + spanLen - 1);
- if (backSlashPos >= idx) {
- int escapeLen = lengthOfEscapeSequence(s, backSlashPos);
- spanLen = qBound(spanLen, backSlashPos + escapeLen - idx, s.length() - idx);
- }
- fprintf(out, "%.*s", spanLen, s.constData() + idx);
- idx += spanLen;
- col += spanLen;
- }
- col += len + 2;
+ for (const QByteArray &s : qAsConst(strings)) {
+ fputc(',', out);
+ printStringWithIndentation(out, s);
}
// Terminate stringdata struct
- fprintf(out, "\"\n};\n");
+ fprintf(out, "\n};\n");
fprintf(out, "#undef QT_MOC_LITERAL\n\n");
//