Add support for C++ functions attributes in moc
Done-with: Ryan Chu <ryan.chu@qt.io> Change-Id: Id7f2ba35ccea79e0a0c316ca2736101b8cd57f97 Fixes: QTBUG-58628 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
parent
1af234f24e
commit
de1e15af44
@ -159,6 +159,7 @@ Type Moc::parseType()
|
||||
bool isVoid = false;
|
||||
type.firstToken = lookup();
|
||||
for (;;) {
|
||||
skipCxxAttributes();
|
||||
switch (next()) {
|
||||
case SIGNED:
|
||||
case UNSIGNED:
|
||||
@ -188,8 +189,11 @@ Type Moc::parseType()
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
skipCxxAttributes();
|
||||
test(ENUM) || test(CLASS) || test(STRUCT);
|
||||
for(;;) {
|
||||
skipCxxAttributes();
|
||||
switch (next()) {
|
||||
case IDENTIFIER:
|
||||
// void mySlot(unsigned myArg)
|
||||
@ -356,6 +360,15 @@ bool Moc::testFunctionAttribute(Token tok, FunctionDef *def)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Moc::skipCxxAttributes()
|
||||
{
|
||||
auto rewind = index;
|
||||
if (test(LBRACK) && test(LBRACK) && until(RBRACK) && test(RBRACK))
|
||||
return true;
|
||||
index = rewind;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Moc::testFunctionRevision(FunctionDef *def)
|
||||
{
|
||||
if (test(Q_REVISION_TOKEN)) {
|
||||
@ -381,7 +394,7 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro)
|
||||
//skip modifiers and attributes
|
||||
while (test(INLINE) || (test(STATIC) && (def->isStatic = true) == true) ||
|
||||
(test(VIRTUAL) && (def->isVirtual = true) == true) //mark as virtual
|
||||
|| testFunctionAttribute(def) || testFunctionRevision(def)) {}
|
||||
|| skipCxxAttributes() || testFunctionAttribute(def) || testFunctionRevision(def)) {}
|
||||
bool templateFunction = (lookup() == TEMPLATE);
|
||||
def->type = parseType();
|
||||
if (def->type.name.isEmpty()) {
|
||||
@ -454,10 +467,11 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro)
|
||||
until(RBRACE);
|
||||
else if ((def->isAbstract = test(EQ)))
|
||||
until(SEMIC);
|
||||
else if (skipCxxAttributes())
|
||||
until(SEMIC);
|
||||
else
|
||||
error();
|
||||
}
|
||||
|
||||
if (scopedFunctionName) {
|
||||
const QByteArray msg = "Function declaration " + def->name
|
||||
+ " contains extra qualification. Ignoring as signal or slot.";
|
||||
@ -475,7 +489,7 @@ bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def)
|
||||
//skip modifiers and attributes
|
||||
while (test(EXPLICIT) || test(INLINE) || (test(STATIC) && (def->isStatic = true) == true) ||
|
||||
(test(VIRTUAL) && (def->isVirtual = true) == true) //mark as virtual
|
||||
|| testFunctionAttribute(def) || testFunctionRevision(def)) {}
|
||||
|| skipCxxAttributes() || testFunctionAttribute(def) || testFunctionRevision(def)) {}
|
||||
bool tilde = test(TILDE);
|
||||
def->type = parseType();
|
||||
if (def->type.name.isEmpty())
|
||||
|
@ -257,6 +257,8 @@ public:
|
||||
bool testFunctionAttribute(Token tok, FunctionDef *def);
|
||||
bool testFunctionRevision(FunctionDef *def);
|
||||
|
||||
bool skipCxxAttributes();
|
||||
|
||||
void checkSuperClasses(ClassDef *def);
|
||||
void checkProperties(ClassDef* cdef);
|
||||
};
|
||||
|
60
tests/auto/tools/moc/cxx-attributes.h
Normal file
60
tests/auto/tools/moc/cxx-attributes.h
Normal file
@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CXXATTRIBUTE_H
|
||||
#define CXXATTRIBUTE_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class CppAttribute : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
[[deprecated]] void deprecatedSignal();
|
||||
|
||||
public slots:
|
||||
[[deprecated]] void deprecatedSlot() {}
|
||||
[[deprecated]] [[tst_moc::maybe_unused]] int deprecatedSlot2() { return 42; }
|
||||
[[deprecated("reason")]] void deprecatedReason() {}
|
||||
[[deprecated("reason[")]] void deprecatedReasonWithLBRACK() {}
|
||||
[[deprecated("reason[[")]] void deprecatedReasonWith2LBRACK() {}
|
||||
[[deprecated("reason]")]] void deprecatedReasonWithRBRACK() {}
|
||||
[[deprecated("reason]]")]] void deprecatedReasonWith2RBRACK() {}
|
||||
void slotWithArguments([[tst_moc::maybe_unused]] int) {}
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1912
|
||||
// On MSVC it causes:
|
||||
// moc_cxx-attributes.cpp(133): fatal error C1001: An internal error has occurred in the compiler.
|
||||
Q_INVOKABLE [[tst_moc::noreturn]] void noreturnSlot() { throw "unused"; }
|
||||
[[tst_moc::noreturn]] Q_SCRIPTABLE void noreturnSlot2() { throw "unused"; }
|
||||
[[deprecated]] int returnInt() { return 0; }
|
||||
Q_SLOT [[tst_moc::noreturn]] [[deprecated]] void noreturnDeprecatedSlot() { throw "unused"; }
|
||||
Q_INVOKABLE void noreturnSlot3() [[tst_moc::noreturn]] { throw "unused"; }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // CXXATTRIBUTE_H
|
@ -29,7 +29,8 @@ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-n
|
||||
non-gadget-parent-class.h grand-parent-gadget-class.h \
|
||||
related-metaobjects-in-gadget.h \
|
||||
related-metaobjects-name-conflict.h \
|
||||
namespace.h cxx17-namespaces.h
|
||||
namespace.h cxx17-namespaces.h \
|
||||
cxx-attributes.h
|
||||
|
||||
|
||||
if(*-g++*|*-icc*|*-clang*|*-llvm):!win32-*: HEADERS += os9-newlines.h win-newlines.h
|
||||
|
@ -71,6 +71,7 @@
|
||||
#include "grand-parent-gadget-class.h"
|
||||
#include "namespace.h"
|
||||
#include "cxx17-namespaces.h"
|
||||
#include "cxx-attributes.h"
|
||||
|
||||
#ifdef Q_MOC_RUN
|
||||
// check that moc can parse these constructs, they are being used in Windows winsock2.h header
|
||||
@ -703,6 +704,7 @@ private slots:
|
||||
void optionsFileError();
|
||||
void testQNamespace();
|
||||
void cxx17Namespaces();
|
||||
void cxxAttributes();
|
||||
|
||||
signals:
|
||||
void sigWithUnsignedArg(unsigned foo);
|
||||
@ -3908,6 +3910,24 @@ void tst_Moc::cxx17Namespaces()
|
||||
QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::ClassInNamespace::GadEn>().value(0), 3);
|
||||
}
|
||||
|
||||
void tst_Moc::cxxAttributes()
|
||||
{
|
||||
auto so = CppAttribute::staticMetaObject;
|
||||
QCOMPARE(so.className(), "CppAttribute");
|
||||
QCOMPARE(so.enumeratorCount(), 0);
|
||||
QVERIFY(so.indexOfSignal("deprecatedSignal") != 1);
|
||||
for (auto a: {"deprecatedSlot", "deprecatedSlot2", "deprecatedReason", "deprecatedReasonWithLBRACK",
|
||||
"deprecatedReasonWith2LBRACK", "deprecatedReasonWithRBRACK", "deprecatedReasonWith2RBRACK",
|
||||
"slotWithArguments"
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1912
|
||||
, "noreturnSlot", "noreturnSlot2", "returnInt", "noreturnDeprecatedSlot",
|
||||
"noreturnSlot3"
|
||||
#endif
|
||||
}) {
|
||||
QVERIFY(so.indexOfSlot(a) != 1);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_Moc)
|
||||
|
||||
// the generated code must compile with QT_NO_KEYWORDS
|
||||
|
Loading…
x
Reference in New Issue
Block a user