moc: Add support for C++17 nested namespaces (N4230)
[ChangeLog][moc] Added Support for C++17 nested namespaces Change-Id: Ib83fc5bf48f66546fa97b49710582fbf9c984503 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
parent
11d60dcad6
commit
5675334b6e
@ -549,12 +549,20 @@ void Moc::parse()
|
||||
case NAMESPACE: {
|
||||
int rewind = index;
|
||||
if (test(IDENTIFIER)) {
|
||||
QByteArray nsName = lexem();
|
||||
QByteArrayList nested;
|
||||
while (test(SCOPE)) {
|
||||
next(IDENTIFIER);
|
||||
nested.append(nsName);
|
||||
nsName = lexem();
|
||||
}
|
||||
if (test(EQ)) {
|
||||
// namespace Foo = Bar::Baz;
|
||||
until(SEMIC);
|
||||
} else if (!test(SEMIC)) {
|
||||
NamespaceDef def;
|
||||
def.classname = lexem();
|
||||
def.classname = nsName;
|
||||
|
||||
next(LBRACE);
|
||||
def.begin = index - 1;
|
||||
until(RBRACE);
|
||||
@ -568,11 +576,23 @@ void Moc::parse()
|
||||
def.qualified.prepend(namespaceList.at(i).classname + "::");
|
||||
}
|
||||
}
|
||||
for (const QByteArray &ns : nested) {
|
||||
NamespaceDef parentNs;
|
||||
parentNs.classname = ns;
|
||||
parentNs.qualified = def.qualified;
|
||||
def.qualified += ns + "::";
|
||||
parentNs.begin = def.begin;
|
||||
parentNs.end = def.end;
|
||||
namespaceList += parentNs;
|
||||
}
|
||||
}
|
||||
|
||||
while (parseNamespace && inNamespace(&def) && hasNext()) {
|
||||
switch (next()) {
|
||||
case NAMESPACE:
|
||||
if (test(IDENTIFIER)) {
|
||||
while (test(SCOPE))
|
||||
next(IDENTIFIER);
|
||||
if (test(EQ)) {
|
||||
// namespace Foo = Bar::Baz;
|
||||
until(SEMIC);
|
||||
|
64
tests/auto/tools/moc/cxx17-namespaces.h
Normal file
64
tests/auto/tools/moc/cxx17-namespaces.h
Normal file
@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Olivier Goffart.
|
||||
** 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 CXX17_NAMESPACES_H
|
||||
#define CXX11_NAMESPACES_H
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#if defined(__cpp_nested_namespace_definitions) || defined(Q_MOC_RUN)
|
||||
namespace CXX17Namespace::A::B {
|
||||
namespace C::D {
|
||||
namespace E::F::G { } // don't confuse moc
|
||||
#else
|
||||
namespace CXX17Namespace { namespace A { namespace B {
|
||||
namespace C { namespace D {
|
||||
#endif
|
||||
|
||||
Q_NAMESPACE
|
||||
|
||||
class ClassInNamespace
|
||||
{
|
||||
Q_GADGET
|
||||
public:
|
||||
enum GadEn { Value = 3 };
|
||||
Q_ENUM(GadEn)
|
||||
};
|
||||
|
||||
enum NamEn { Value = 4 };
|
||||
Q_ENUM_NS(NamEn);
|
||||
|
||||
|
||||
#if defined(__cpp_nested_namespace_definitions) || defined(Q_MOC_RUN)
|
||||
}
|
||||
}
|
||||
#else
|
||||
} } }
|
||||
} }
|
||||
#endif
|
||||
|
||||
#endif
|
@ -29,7 +29,7 @@ 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
|
||||
namespace.h cxx17-namespaces.h
|
||||
|
||||
|
||||
if(*-g++*|*-icc*|*-clang*|*-llvm):!irix-*:!win32-*: HEADERS += os9-newlines.h win-newlines.h
|
||||
|
@ -70,6 +70,7 @@
|
||||
#include "non-gadget-parent-class.h"
|
||||
#include "grand-parent-gadget-class.h"
|
||||
#include "namespace.h"
|
||||
#include "cxx17-namespaces.h"
|
||||
|
||||
#ifdef Q_MOC_RUN
|
||||
// check that moc can parse these constructs, they are being used in Windows winsock2.h header
|
||||
@ -700,6 +701,7 @@ private slots:
|
||||
void optionsFileError_data();
|
||||
void optionsFileError();
|
||||
void testQNamespace();
|
||||
void cxx17Namespaces();
|
||||
|
||||
signals:
|
||||
void sigWithUnsignedArg(unsigned foo);
|
||||
@ -3803,6 +3805,25 @@ void tst_Moc::testQNamespace()
|
||||
QCOMPARE(FooNamespace::FooNestedNamespace::FooMoreNestedNamespace::staticMetaObject.enumeratorCount(), 1);
|
||||
}
|
||||
|
||||
void tst_Moc::cxx17Namespaces()
|
||||
{
|
||||
QCOMPARE(CXX17Namespace::A::B::C::D::staticMetaObject.className(),
|
||||
"CXX17Namespace::A::B::C::D");
|
||||
QCOMPARE(CXX17Namespace::A::B::C::D::staticMetaObject.enumeratorCount(), 1);
|
||||
QCOMPARE(CXX17Namespace::A::B::C::D::staticMetaObject.enumerator(0).name(), "NamEn");
|
||||
QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::NamEn>().name(), "NamEn");
|
||||
QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::NamEn>().keyCount(), 1);
|
||||
QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::NamEn>().value(0), 4);
|
||||
|
||||
QCOMPARE(CXX17Namespace::A::B::C::D::ClassInNamespace::staticMetaObject.className(),
|
||||
"CXX17Namespace::A::B::C::D::ClassInNamespace");
|
||||
QCOMPARE(CXX17Namespace::A::B::C::D::ClassInNamespace::staticMetaObject.enumeratorCount(), 1);
|
||||
QCOMPARE(CXX17Namespace::A::B::C::D::ClassInNamespace::staticMetaObject.enumerator(0).name(), "GadEn");
|
||||
QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::ClassInNamespace::GadEn>().name(), "GadEn");
|
||||
QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::ClassInNamespace::GadEn>().keyCount(), 1);
|
||||
QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::ClassInNamespace::GadEn>().value(0), 3);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_Moc)
|
||||
|
||||
// the generated code must compile with QT_NO_KEYWORDS
|
||||
|
Loading…
Reference in New Issue
Block a user