Files
RedBear-OS/local/recipes/qt/qtdeclarative/source/tools/qmltc/qmltccompiler.h
T
vasilito f31522130f fix: comprehensive boot warnings and exceptions — fixable silenced, unfixable diagnosed
Build system (5 gaps hardened):
- COOKBOOK_OFFLINE defaults to true (fork-mode)
- normalize_patch handles diff -ruN format
- New 'repo validate-patches' command (25/25 relibc patches)
- 14 patched Qt/Wayland/display recipes added to protected list
- relibc archive regenerated with current patch chain

Boot fixes (fixable):
- Full ISO EFI partition: 16 MiB → 1 MiB (matches mini, BIOS hardcoded 2 MiB offset)
- D-Bus system bus: absolute /usr/bin/dbus-daemon path (was skipped)
- redbear-sessiond: absolute /usr/bin/redbear-sessiond path (was skipped)
- daemon framework: silenced spurious INIT_NOTIFY warnings for oneshot_async services (P0-daemon-silence-init-notify.patch)
- udev-shim: demoted INIT_NOTIFY warning to INFO (expected for oneshot_async)
- relibc: comprehensive named semaphores (sem_open/close/unlink) replacing upstream todo!() stubs
- greeterd: Wayland socket timeout 15s → 30s (compositor DRM wait)
- greeter-ui: built and linked (header guard unification, sem_compat stubs removed)
- mc: un-ignored in both configs, fixed glib/libiconv/pcre2 transitive deps
- greeter config: removed stale keymapd dependency from display/greeter services
- prefix toolchain: relibc headers synced, _RELIBC_STDLIB_H guard unified

Unfixable (diagnosed, upstream):
- i2c-hidd: abort on no-I2C-hardware (QEMU) — process::exit → relibc abort
- kded6/greeter-ui: page fault 0x8 — Qt library null deref
- Thread panics fd != -1 — Rust std library on Redox
- DHCP timeout / eth0 MAC — QEMU user-mode networking
- hwrngd/thermald — no hardware RNG/thermal in VM
- live preload allocation — BIOS memory fragmentation, continues on demand
2026-05-05 20:20:37 +01:00

217 lines
8.4 KiB
C++

// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef QMLTCCOMPILER_H
#define QMLTCCOMPILER_H
#include "qmltctyperesolver.h"
#include "qmltcvisitor.h"
#include "qmltcoutputir.h"
#include <QtCore/qcommandlineparser.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qstring.h>
#include <QtCore/qhash.h>
#include <private/qqmljslogger_p.h>
#include <memory>
QT_BEGIN_NAMESPACE
struct QmltcCompilerInfo
{
QString outputCppFile;
QString outputHFile;
QString outputNamespace;
QString resourcePath;
QString exportMacro;
QString exportInclude;
};
class QmltcCompiler
{
using InlineComponentOrDocumentRootName = QQmlJSScope::InlineComponentOrDocumentRootName;
using InlineComponentNameType = QQmlJSScope::InlineComponentNameType;
using RootDocumentNameType = QQmlJSScope::RootDocumentNameType;
public:
QmltcCompiler(const QString &url, QmltcTypeResolver *resolver, QmltcVisitor *visitor,
QQmlJSLogger *logger);
void compile(const QmltcCompilerInfo &info);
~QmltcCompiler();
/*! \internal
Returns \c true if \a binding is considered complex by the compiler
(requires special code generation)
*/
static bool isComplexBinding(const QQmlJSMetaPropertyBinding &binding)
{
// TODO: translation bindings (once supported) are also complex?
return binding.bindingType() == QQmlSA::BindingType::Script;
}
private:
QString m_url; // QML input file url
QmltcTypeResolver *m_typeResolver = nullptr;
QmltcVisitor *m_visitor = nullptr;
QQmlJSLogger *m_logger = nullptr;
QmltcCompilerInfo m_info {}; // miscellaneous input/output information
QString m_urlMethodName;
uint m_currentVariableNumber = 0;
struct UniqueStringId;
struct QmltcTypeLocalData;
// per-type, per-property code generation cache of created symbols
QHash<UniqueStringId, QmltcTypeLocalData> m_uniques;
void compileUrlMethod(QmltcMethod &urlMethod, const QString &urlMethodName);
void
compileType(QmltcType &current, const QQmlJSScope::ConstPtr &type,
std::function<void(QmltcType &, const QQmlJSScope::ConstPtr &)> compileElements);
void compileTypeElements(QmltcType &current, const QQmlJSScope::ConstPtr &type);
void compileEnum(QmltcType &current, const QQmlJSMetaEnum &e);
void compileMethod(QmltcType &current, const QQmlJSMetaMethod &m,
const QQmlJSScope::ConstPtr &owner);
void compileProperty(QmltcType &current, const QQmlJSMetaProperty &p,
const QQmlJSScope::ConstPtr &owner);
void compileAlias(QmltcType &current, const QQmlJSMetaProperty &alias,
const QQmlJSScope::ConstPtr &owner);
void compileExtraListMethods(QmltcType &current, const QQmlJSMetaProperty &p);
QString uniqueVariableName(const QString &qmlName)
{
QString result = u"m_"_s + QString::number(++m_currentVariableNumber) + qmlName;
result.replace(u'.', u'_');
return result;
}
/*!
\internal
Helper structure that holds the information necessary for most bindings,
such as accessor name, which is used to reference the properties. For
example:
> (accessor.name)->(propertyName) results in "this->myProperty"
This data is also used in more advanced scenarios by attached and
grouped properties
*/
struct BindingAccessorData
{
QQmlJSScope::ConstPtr scope; // usually the current type
QString name = QStringLiteral("this");
QString propertyName = QString();
bool isValueType = false;
};
QStringList unprocessedListBindings;
QQmlJSMetaProperty unprocessedListProperty;
void processLastListBindings(QmltcType &current, const QQmlJSScope::ConstPtr &type,
const BindingAccessorData &accessor);
void compileBinding(QmltcType &current, QList<QQmlJSMetaPropertyBinding>::iterator bindingStart,
QList<QQmlJSMetaPropertyBinding>::iterator bindingEnd,
const QQmlJSScope::ConstPtr &type, const BindingAccessorData &accessor);
void compileBindingByType(QmltcType &current, const QQmlJSMetaPropertyBinding &binding,
const QQmlJSScope::ConstPtr &type,
const BindingAccessorData &accessor);
void compileObjectBinding(QmltcType &current, const QQmlJSMetaPropertyBinding &binding,
const QQmlJSScope::ConstPtr &type,
const BindingAccessorData &accessor);
void compileValueSourceOrInterceptorBinding(QmltcType &current,
const QQmlJSMetaPropertyBinding &binding,
const QQmlJSScope::ConstPtr &type,
const BindingAccessorData &accessor);
void compileAttachedPropertyBinding(QmltcType &current,
const QQmlJSMetaPropertyBinding &binding,
const QQmlJSScope::ConstPtr &type,
const BindingAccessorData &accessor);
void compileGroupPropertyBinding(QmltcType &current, const QQmlJSMetaPropertyBinding &binding,
const QQmlJSScope::ConstPtr &type,
const BindingAccessorData &accessor);
void compileTranslationBinding(QmltcType &current, const QQmlJSMetaPropertyBinding &binding,
const QQmlJSScope::ConstPtr &type,
const BindingAccessorData &accessor);
// special case (for simplicity)
void compileScriptBinding(QmltcType &current, const QQmlJSMetaPropertyBinding &binding,
const QString &bindingSymbolName, const QQmlJSScope::ConstPtr &type,
const QString &propertyName,
const QQmlJSScope::ConstPtr &propertyType,
const BindingAccessorData &accessor);
void compilePropertyInitializer(QmltcType &current, const QQmlJSScope::ConstPtr &type);
/*!
\internal
Helper structure that acts as a key in a hash-table of
QmltcType-specific data (such as local variable names). Using a
hash-table allows to avoid creating the same variables multiple times
during binding compilation, which leads to better code generation and
faster object creation. This is really something that the QML optimizer
should do, but we have only this home-grown alternative at the moment
*/
struct UniqueStringId
{
QString unique;
UniqueStringId(const QmltcType &context, const QString &property)
: unique(context.cppType + u"_" + property) // this is unique enough
{
Q_ASSERT(!context.cppType.isEmpty());
Q_ASSERT(!property.isEmpty());
}
friend bool operator==(const UniqueStringId &x, const UniqueStringId &y)
{
return x.unique == y.unique;
}
friend bool operator!=(const UniqueStringId &x, const UniqueStringId &y)
{
return !(x == y);
}
friend size_t qHash(const UniqueStringId &x, size_t seed = 0)
{
return qHash(x.unique, seed);
}
};
struct QmltcTypeLocalData
{
// empty QString() means that the local data is not present (yet)
QString qmlListVariableName;
QString onAssignmentObjectName;
QString attachedVariableName;
};
QHash<QString, qsizetype> m_symbols;
QString newSymbol(const QString &base);
bool hasErrors() const { return m_logger->hasErrors(); }
void recordError(const QQmlJS::SourceLocation &location, const QString &message,
QQmlJS::LoggerWarningId id = qmlCompiler)
{
// pretty much any compiler error is a critical error (we cannot
// generate code - compilation fails)
m_logger->log(message, id, location);
}
void recordError(const QV4::CompiledData::Location &location, const QString &message,
QQmlJS::LoggerWarningId id = qmlCompiler)
{
recordError(QQmlJS::SourceLocation { 0, 0, location.line(), location.column() }, message,
id);
}
};
QT_END_NAMESPACE
#endif // QMLTCCOMPILER_H