summaryrefslogtreecommitdiffstats
path: root/src/tools/moc
Commit message (Collapse)AuthorAgeFilesLines
* Remove the timestamp info in genarated filesLiang Qi2012-12-151-5/+1
| | | | | | | | | | | | | For moc, rcc and uic, then it's friendly for tools like ccache. ccache is using md5 to check file modification, but the different timestamp info will cause different md5 for same meaningful contents, it will disabled ccache. Updated the autotest for uic and rcc. Task-number: QTBUG-26589 Change-Id: I9f1dcf6cd826ad9603af6e183757bcd748c32bd1 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Change license header from Nokia to DigiaSergio Ahumada2012-11-262-2/+2
| | | | | Change-Id: I2be215284d7670f60f8b5838fce1e6832dde2270 Reviewed-by: Martin Smith <martin.smith@digia.com>
* moc: Fix assertion in QVector::first()Konstantin Ritt2012-11-251-6/+10
| | | | | | | introduced in aea68c93ae437a761584719f0f1ca93eaf6f7484 Change-Id: I05c1dfa16c42019ee0a0b44ffc50ad2c2c0d209b Reviewed-by: Lars Knoll <lars.knoll@digia.com>
* Proper macro replacment and branch evaluationLars Knoll2012-11-233-80/+144
| | | | | | | | | | | | Correclty replace macros according to the C++ standard. Use the correct replacement method also to evaluate With this moc correctly processes boost headers. Task-number: QTBUG-27546 Change-Id: I001b3054c5fcdc34d46cfa53d1387bd19436f361 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Correctly expand arguments in function macrosLars Knoll2012-11-231-11/+12
| | | | | | | | Arguments in function macros are only expanded if they aren't used in conjunction with a # or ## operator. Change-Id: I8c80e11902a592128504c4637545e75866566965 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Remove additional whitespaces from the macro tokensLars Knoll2012-11-231-2/+24
| | | | | | | | | According to the spec, we should ignore whitespace tokens at the beginning and end of the macro definition. In addition, whitespaces after a # and around ## should be ignored Change-Id: I830d0f4aaed3bcfac345d7da6df65693ec3315b8 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* make qt_tool support building bootstrapped toolsOswald Buddenhagen2012-11-161-6/+1
| | | | | | | | | | as a "side effect", this fixes the build of bootstrapped tools when doing a debug build under msvc: qt.prf would add CONFIG+=release after default_post.prf already loaded debug.prf. Change-Id: Idd17cf28d358950fd90bb18ca7a8d67e06953bc1 Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com> Reviewed-by: Jan Arve Sæther <jan-arve.saether@digia.com>
* remove pointless TARGET assignmentsOswald Buddenhagen2012-11-161-1/+0
| | | | | | | TARGET defaults to the project file's basename Change-Id: I0cd204ae6559e6c51d3c987bc38ae372e2b4a3dd Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
* Generate a proper static QtBootstrap moduleOswald Buddenhagen2012-11-081-9/+7
| | | | | | | | | | | Making a properly installed libQtBootstrap simplifies our tools build process a little and in addition allows other comand line tools to use the bootstrap lib and link against it. Initial-version-by: Lars Knoll Change-Id: Iddf4568a5505bc24898ec1abf7e7022e19f0a454 Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
* fix warnings about empty "while" bodiesOswald Buddenhagen2012-11-071-7/+7
| | | | | | | as it happens, this matches our coding style ... Change-Id: I88d0916499a05a48d12691f5df5999c5ffd7a91c Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
* moc: parse properly the gcc extension for variadic macroOlivier Goffart2012-10-141-2/+12
| | | | | | | Task-number: QTBUG-27547 Change-Id: I983b96b09c405e5330327092e56164b9921a2d0f Reviewed-by: Lars Knoll <lars.knoll@digia.com>
* Fix moc preprocessor-only mode with input that contains seemingly invalid ↵Simon Hausmann2012-10-131-2/+5
| | | | | | | | | | | | | | | | | | | | | identifiers In WebKit we use moc -E to pre-process various files before throwing at further build creation tools. The pre-processing is used to filter out code depending in #ifdef'fed features. The latest addition to the family of pre-processed files is the CSS grammar, which is written in Bison. It contains rule lines like $$ = parser->createFoo() and when pre-processing this moc stumbles over the dollar sign. Instead of ignoring un-tokenizable input we should add it to the current token if we're in preprocessor-only mode, otherwise the $$ gets eaten and we produce data-loss by printing out less characters than. Change-Id: Ib32e7c04b38dd2ba3726201e76f27405f7ea6c0d Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Fix moc stumbling over gcc __attribute__ extensionsSimon Hausmann2012-10-011-0/+8
| | | | | | | | | | | | | | | | | Reported by David Faure. In KDE a DEPRECATED macro gets defined in a header file created by cmake. The define is not guarded with #if Q_CC_GNU or similar because at cmake time the compiler is determined. Therefore moc suddenly sees this gcc specific token and stumbles over it. This patch simply defines an empty __attribute__ macro that will expand to nothing and thus become invisible to moc's "C++ parser" after the pre-processing. Change-Id: I4448b9ac3f72b6334e32b27484401fb0fca23a0c Reviewed-by: David Faure <faure@kde.org> Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Moc: Correctly expand macros with argumentsLars Knoll2012-09-252-19/+163
| | | | | | | | | Moc now supports full expansion of macros with arguments with the exception of some keywords such as Q_OBJECT and others that are used internally Change-Id: I283d47152f75de81ec68a3df1f0f2273f11c5149 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Moc: Make # and ## valid tokens in cpp parsing modeLars Knoll2012-09-252-4/+6
| | | | | | | | This is required so preprocessing macros with arguments can work correctly. Change-Id: Ia30ede6a3579be13800bf1255d313748e2d696f9 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Correctly parse function macrosLars Knoll2012-09-253-8/+75
| | | | | | | | Parse function macros and add it's list of arguments to the Macro definition. Change-Id: Id22f5cf4a1c098f7b4f5b72f002900cd40d03e0f Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Correctly expand macros without arguments in mocLars Knoll2012-09-252-15/+51
| | | | | | | | | | | | This helps e.g. cases where a namespace is defined through a macro and moc doesn't see it at all. Expanding macros with arguments is significantly more work, and should happen in a separate commit. Change-Id: Ic8d0443d06fab2ed343115d8c43022f2c67ec3cd Reviewed-by: Qt Doc Bot <qt_docbot@qt-project.org> Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Change copyrights from Nokia to DigiaIikka Eklund2012-09-2221-503/+503
| | | | | | | | Change copyrights and license headers from Nokia to Digia Change-Id: If1cc974286d29fd01ec6c19dd4719a67f4c3f00e Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Sergio Ahumada <sergio.ahumada@digia.com>
* make src/tools/ compile without CamelCase headersOswald Buddenhagen2012-09-197-19/+19
| | | | | | | | so the build works with syncqt -minimal Change-Id: Ief5e8eb9a504dd6c84cff76cc3e5257450386a0f Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Use the same hash for 8 bit strings as in QByteArrayLars Knoll2012-09-091-12/+1
| | | | | | | | | Moc still used a different and quite a bit more complicated algorithm to hash 8bit strings then QByteArray. Change-Id: I86efb08d5ab7de1863fc168dcfc73399e72e1331 Reviewed-by: Qt Doc Bot <qt_docbot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Generate includes for Qt containers used as auto-metatypes.Stephen Kelly2012-09-031-0/+42
| | | | | | | | | | | | Otherwise the containers might be forward declared in the moc file, and when the moc file is compiled in a standalone translation unit, the full definition of it would not be available. This results in odd compile errors, so instead generate the includes if required. Change-Id: Ie01c5a5d45314daad0b00dec03b3e1e18cdbae64 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Volker Krause <volker.krause@kdab.com> Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Fix moc generating invalid code for slots with reference types as argument.Volker Krause2012-09-021-2/+2
| | | | | | | | | | | We can't have T& declared/registered as a metatype (wont compile), but using it as type for a slot argument is possible. With the recent introduction of metatype auto-registration we have to make sure that moc doesn't attempt to auto-register those. Simple types are handled correctly already, this fixes containers and smart pointers. Change-Id: Id96857c57d6ebf158a67e9d527c89dc195473b1b Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
* Fix static plugins for classes in namespaces.Friedemann Kleint2012-08-301-1/+2
| | | | | | | | | | | Breakage introduced by 819d0203e6fd9d27dc4c22e8c3cb8b437998f62a . Extend QT_MOC_EXPORT to take the unqualified class name as well for the function names. Change-Id: I736097b564caa37c522d723780663d03341f9032 Reviewed-by: Lars Knoll <lars.knoll@nokia.com> Reviewed-by: Lukas Geyer <lgeyer@gmx.at>
* Use qualified name for QT_MOC_EXPORT_PLUGIN()Lukas Geyer2012-08-291-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Using non-qualified name for QT_MOC_EXPORT_PLUGIN() breaks template instatiation for QPointer<T>::operator=(T*) in qt_plugin_instance() when the class is embedded a namespace with the same name. namespace Test { class Test : public QObject { Q_OBJECT Q_PLUGIN_METADATA(IID "Test") public: Test(QObject *parent = 0) : QObject(parent) {} }; } // namespace Test In function 'QObject* qt_plugin_instance()': error: expected type-specifier before 'Test' error: no match for 'operator=' in '_instance = (int*)operator new(4u)' note: candidates are: In file included from qtbase\include\QtCore/qpointer.h:1:0, from qtbase\include\QtCore/QtCore:68, from test.cpp:1: qtbase/src/corelib/kernel/qpointer.h:87:25: note: QPointer<T>& QPointer<T>::operator=(T*) [with T = QObject] qtbase/src/corelib/kernel/qpointer.h:87:25: note: no known conversion for argument 1 from 'int*' to 'QObject*' qtbase/src/corelib/kernel/qpointer.h:79:7: note: QPointer<QObject>& QPointer<QObject>::operator=(const QPointer<QObject>&) qtbase/src/corelib/kernel/qpointer.h:79:7: note: no known conversion for argument 1 from 'int*' to 'const QPointer<QObject>&' error: expected ';' before 'Test' Change-Id: Idd3e57ab1c888352ad2a8e8f6efca75d858089df Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
* Add automatic metatype registration for invokable methods.Stephen Kelly2012-08-282-1/+52
| | | | | | | | | | | This works similarly to the automatic registration for Q_PROPERTY types, but in this case it mostly affects the need for users to call qRegisterMetaType<T>() before using queued connections with methods using non-built-in metatypes, or before using invokeMethod manually. Change-Id: Ib17d0606b77b0130624b6a88b57c36d26e97d12d Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
* Add automatic metatype registration for Q_PROPERTY types.Stephen Kelly2012-08-283-5/+93
| | | | | | | | | | | | | | | | In Qt 4, the user needs to call qRegisterMetaType if the property could otherwise be read before the type is registered with the metatype system. This patch makes that unnecessary and automatic by registering it when the first read indicates that it is not yet registered instead or when QMetaProperty::userType is called before it is registered. The types which are automatically registered exclude the built-in types, which do not need to be registered, and include metatypes which are automatically declared, such as pointers to QObject derived types and containers of existing metatypes. Change-Id: I0a06d8efdcb64121618e2378366d0142fa0771f5 Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
* moc: parse classes that use Q_DECL_FINAL|final|sealedMarc Mutz2012-08-261-1/+11
| | | | | | | | | | | | | | | | | | | | This only works with the C++11 contextual keyword directly, the MSVC equivalent 'sealed', or the Qt define for it. While this isn't a problem for syncqt, being an internal tool, moc should eventually be able to parse user code using local C++11-final-wrapping macros. For this, I guess moc would have to be taught to expand macros in code and not just test #if clauses, potentially driven by something like #pragma qt-moc expand-this #define MY_FINAL_CLASS final but that's something for someone more intimately familiar with moc's source than I am. Change-Id: Id6aec961a881e8d5a9b76a7fc8e1c02c71913f64 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Search the include paths for json files containing plugin infoLars Knoll2012-07-314-8/+22
| | | | | | | | This fixes shadow builds with autogenerated .json files as e.g. used by Qt Creator. Change-Id: Ibb783b05d97d996100da4b0dca859fa3f310dc83 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
* Simplify the moc code related to private signals a bit.Stephen Kelly2012-07-132-10/+21
| | | | | Change-Id: I0e9bae82c7c6d313e4161c35d0b988f633d5ae60 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Create a way to inform moc about private signals.Stephen Kelly2012-07-133-8/+36
| | | | | | | | | | | | | | | | | | Moc checks for the use of the QPrivateSignal struct, which is part of the Q_OBJECT macro and is private to each class that uses it. Moc then generates a name of the signal which does not include the private struct, and generates code to invoke such signals with an instance of the private struct. This way we can mark private signals as such and prevent them from being emitted from subclasses or from outside of the class entirely. The drawback to this is that it only works if the private signal has no default arguments. However, at least in Qt, there are no such signals. Change-Id: Id16eadaa8d3c36a2c3b265077877f3e1d8304c84 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Revert "Allow moc to handle symbols that have been redefined."Matthew Vogt2012-07-043-120/+4
| | | | | | | | | | | | This reverts commit 5bb1408927b4eb5a03e8ab9f7cbc68f80d8a3962. The temporary measure used to support redefinition of QtDeclarative class names during the transition period is no longer required. Task-number: QTBUG-24517 Change-Id: Ib90f08fcdfb02e004e594ac72b698eaa0325d98d Reviewed-by: Kent Hansen <kent.hansen@nokia.com> Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Merge "Merge branch 'buildsystem'" into refs/staging/masterOswald Buddenhagen2012-06-201-2/+3
|\
| * remove some qmake -project boilerplate from project filesOswald Buddenhagen2012-06-191-2/+2
| | | | | | | | | | Change-Id: I5e6103db42b4fcca4ed4c2ffaec71e71e73d5b95 Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
| * properly declare the host tools as such in the project filesOswald Buddenhagen2012-06-191-0/+1
| | | | | | | | | | | | | | don't mess with the qmake cmdline args any more. Change-Id: I399d87145d31d25e29951b6acd96387a3c7282f0 Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
* | MOC: Avoiding MAX_PATH limit on WindowsYuchen Deng2012-06-201-1/+9
|/ | | | | | | | | See: http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx Task-number: QTBUG-26157 Change-Id: Ie74481cd06c31149a060a432352da5b2731caaef Reviewed-by: Debao Zhang <dbzhang800@gmail.com> Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
* It should be a moc error for the specified file to not exist.Stephen Kelly2012-06-141-1/+1
| | | | | | | Currently the missing file is ignored and plugin data is created anyway. Change-Id: I118fd57b7d05a135e3ff58c0298b25e67cd12587 Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
* Fix shadow build compilation with MSVCThiago Macieira2012-05-292-2/+2
| | | | | | | | \#include "foo" in MSVC does not search the output path, so we need to pass the proper -I flag to find the build dir's src/corelib/global. Change-Id: I546051c99fd29d7734f8bf35d058ea283ec9bca7 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Encapsulate the dynamic meta object pointerAaron Kennedy2012-05-181-1/+1
| | | | | | | | | This change allows us to delay creating the actual meta object until it is actually required. Change-Id: I1c4a4226bd82fa606b206dd60322f49b49c32463 Reviewed-by: Kent Hansen <kent.hansen@nokia.com> Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
* Bump moc revision after introducing QMetaType::SChar.Jędrzej Nowacki2012-05-091-1/+1
| | | | | | | | | Normally we do not have to change moc version if a new type is added, but for this particular case we need to do it. It is so because the old moc could generate wrong type id (QMetaType::Char) for signed char. Change-Id: I20be2a24adc59a305674595dafe23fb1774b475d Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
* Remove QMetaObjectExtraData and put everything into QMetaObjectOlivier Goffart2012-04-252-22/+10
| | | | | | | | | | | | | | | | QMetaObjectExtraData was added when support for QMetaObject::newInstance was added. One needed a place to put the pointer to static_metacall in the QMetaObject. But as we break binary compatibility, one can change the size of QMetaObject, and put everything back inside QMetaObject's own structure. Meaning it is not required anymore to have one QMetaObjectExtraData instance per QMetaObject anymore. Change-Id: If0b8f586cbaf633eed10045adee3ba3366826c86 Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com> Reviewed-by: Kent Hansen <kent.hansen@nokia.com> Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
* Merge remote-tracking branch 'origin/master' into api_changesLars Knoll2012-04-162-2/+10
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: configure src/corelib/io/qurl.cpp src/gui/kernel/qwindow.cpp src/tools/moc/generator.cpp src/widgets/kernel/qwidget_qpa.cpp src/widgets/styles/qstyle.h src/widgets/widgets/qtabbar.cpp tests/auto/corelib/codecs/utf8/tst_utf8.cpp Change-Id: Ia457228d6f684ec8184e13e8fcc9d25857b1751e
| * moc: Fix parsing of the empty preprocessor commandOlivier Goffart2012-04-161-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | When encountering a null preprocessing directive (which is supposed to be ignored), the moc preprocessor will leave a PP_NEWLINE token in the token stream. That will confuse the parser. The PP_NEWLINE token need to be ignored in the preprocessing phase. Task-number: QTBUG-22717 Change-Id: I1e502a7e5bc6fa8ce2f82109ba7199b95747ff0a Reviewed-by: João Abecasis <joao.abecasis@nokia.com> Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
| * moc: fix compilation of signals returning pointers.Olivier Goffart2012-04-131-2/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | That was a regression introduced in 1c5db1aff Example: signals: int *someSignal(); would produce this code: int* _t0 = int*(); which does not compile So have special handling for pointer to change it to '= 0' Change-Id: Ie695e15e309d15c3cfd5c5a69ac8bf6d61ae9915 Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
* | Deprecate qMemCopy/qMemSet in favour of their stdlib equivilents.Robin Burchell2012-04-111-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Just like qMalloc/qRealloc/qFree, there is absolutely no reason to wrap these functions just to avoid an include, except to pay for it with worse runtime performance. On OS X, on byte sizes from 50 up to 1000, calling memset directly is 28-15% faster(!) than adding an additional call to qMemSet. The advantage on sizes above that is unmeasurable. For qMemCopy, the benefits are a little more modest: 16-7%. Change-Id: I98aa92bb765aea0448e3f20af42a039b369af0b3 Reviewed-by: Giuseppe D'Angelo <dangelog@gmail.com> Reviewed-by: John Brooks <john.brooks@dereferenced.net> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
* | Introduce initializer macros for QString- and QByteArrayDataJoão Abecasis2012-04-041-3/+3
| | | | | | | | | | | | | | | | | | This enables easier updating of those structs, by reducing the amount of code that needs to be fixed. The common (and known) use cases are covered by the two macros being introduced in each case. Change-Id: I44981ca9b9b034f99238a11797b30bb85471cfb7 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* | Remove compression support from moc.Jędrzej Nowacki2012-03-291-1/+1
| | | | | | | | | | | | | | | | Moc doesn't compress anything so it doesn't have to link against zlib. In practice it is a build fix for a bug exposed by previous patches. Change-Id: I0debfccc903b3addd7c16be8421a51b6be9ceb2f Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
* | Ensure that moc doesn't resolve the qreal meta-type idKent Hansen2012-03-182-23/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When cross-compiling, the qreal type can be different on the target than on the host (e.g. double on host, and float on target). moc is a host binary, so it shouldn't try to resolve the type id of qreal, but instead always output "QMetaType::QReal" (which is just an alias for QMetaType::Double or QMetaType::Float, depending on the target). This was a regression introduced in commit f95181c7bb340744a0ce172e8c5a8fcdc2543297 (new meta-object format); the special-casing for qreal should have been kept. Moved the code that generates the type info into its own function so the logic is shared by generateFunctions() and generateProperties(). Change-Id: I2b76cf063a08ba95a7e6033549452355f67283ac Reviewed-by: Olivier Goffart <ogoffart@woboq.com> Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
* | Fix comparison type warning.Stephen Kelly2012-03-161-1/+1
| | | | | | | | | | | | | | Change-Id: I4051c5bc204215f368e4381e508dd870be240f8f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andreas Holzammer <andreas.holzammer@kdab.com> Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
* | Add an overload to Moc to allow reading from a QIODevice.Stephen Kelly2012-03-142-2/+9
| | | | | | | | | | | | | | | | This allows external code to provide the input data, such as a bootstrapped version of qdbuscpp2xml. Change-Id: I163062efc6495b3ab92573f94523967a67601191 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* | Merge remote-tracking branch 'origin/api_changes' into containtersJoão Abecasis2012-03-084-6/+121
|\ \ | |/ | | | | | | | | | | | | | | Conflicts: src/corelib/kernel/qmetaobject.cpp src/corelib/kernel/qvariant.cpp src/tools/moc/moc.h Change-Id: I2cd3d95b41d2636738c6b98064864941e3b0b4e6