aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp3
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp5
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h8
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp45
-rw-r--r--sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst4
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.cpp22
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.h13
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel_enums.h6
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp5
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h13
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp8
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml2
12 files changed, 77 insertions, 57 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 1afc7d135..c38a145bd 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -1055,7 +1055,7 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte
nspace = QStringList(names.mid(0, names.size() - 1)).join(colonColon());
typeEntry = new EnumTypeEntry(nspace, enumName, QVersionNumber(0, 0));
TypeDatabase::instance()->addType(typeEntry);
- } else if (!enumItem->isAnonymous()) {
+ } else if (enumItem->enumKind() != AnonymousEnum) {
typeEntry = TypeDatabase::instance()->findType(qualifiedName);
} else {
QStringList tmpQualifiedName = enumItem->qualifiedName();
@@ -1096,6 +1096,7 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte
}
AbstractMetaEnum *metaEnum = new AbstractMetaEnum;
+ metaEnum->setEnumKind(enumItem->enumKind());
if (enumsDeclarations.contains(qualifiedName)
|| enumsDeclarations.contains(enumName)) {
metaEnum->setHasQEnumsDeclaration(true);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 4e507cd38..905504ca3 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -2457,8 +2457,3 @@ QString AbstractMetaEnum::package() const
{
return m_typeEntry->targetLangPackage();
}
-
-bool AbstractMetaEnum::isAnonymous() const
-{
- return m_typeEntry->isAnonymous();
-}
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 45a55e570..c51f7704b 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -1168,6 +1168,11 @@ public:
return package() + QLatin1Char('.') + qualifier() + QLatin1Char('.') + name();
}
+ EnumKind enumKind() const { return m_enumKind; }
+ void setEnumKind(EnumKind kind) { m_enumKind = kind; }
+
+ bool isAnonymous() const { return m_enumKind == AnonymousEnum; }
+
// Has the enum been declared inside a Q_ENUMS() macro in its enclosing class?
void setHasQEnumsDeclaration(bool on)
{
@@ -1199,13 +1204,12 @@ public:
m_class = c;
}
- bool isAnonymous() const;
-
private:
AbstractMetaEnumValueList m_enumValues;
EnumTypeEntry *m_typeEntry = nullptr;
AbstractMetaClass *m_class = nullptr;
+ EnumKind m_enumKind = CEnum;
uint m_hasQenumsDeclaration : 1;
};
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index 1ed054d91..0984246c8 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -41,6 +41,7 @@
#include <QtCore/QVector>
#include <string.h>
+#include <ctype.h>
#if QT_VERSION < 0x050800
# define Q_FALLTHROUGH() (void)0
@@ -437,6 +438,36 @@ QString BuilderPrivate::cursorValueExpression(BaseVisitor *bv, const CXCursor &c
return QString::fromLocal8Bit(equalSign, int(snippet.second - equalSign)).trimmed();
}
+// A hacky reimplementation of clang_EnumDecl_isScoped() for Clang < 5.0
+// which simply checks for a blank-delimited " class " keyword in the enum snippet.
+
+#define CLANG_NO_ENUMDECL_ISSCOPED \
+ (CINDEX_VERSION_MAJOR == 0 && CINDEX_VERSION_MINOR < 43)
+
+#if CLANG_NO_ENUMDECL_ISSCOPED
+static const char *indexOf(const BaseVisitor::CodeSnippet &snippet, const char *needle)
+{
+ const size_t snippetLength = snippet.first ? size_t(snippet.second - snippet.first) : 0;
+ const size_t needleLength = strlen(needle);
+ if (needleLength > snippetLength)
+ return nullptr;
+ for (const char *c = snippet.first, *end = snippet.second - needleLength; c < end; ++c) {
+ if (memcmp(c, needle, needleLength) == 0)
+ return c;
+ }
+ return nullptr;
+}
+
+long clang_EnumDecl_isScoped4(BaseVisitor *bv, const CXCursor &cursor)
+{
+ BaseVisitor::CodeSnippet snippet = bv->getCodeSnippet(cursor);
+ const char *classSpec = indexOf(snippet, "class");
+ const bool isClass = classSpec && classSpec > snippet.first
+ && isspace(*(classSpec - 1)) && isspace(*(classSpec + 5));
+ return isClass ? 1 : 0;
+}
+#endif // CLANG_NO_ENUMDECL_ISSCOPED
+
// Add a base class to the current class from CXCursor_CXXBaseSpecifier
void BuilderPrivate::addBaseClass(const CXCursor &cursor)
{
@@ -641,13 +672,21 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
break;
case CXCursor_EnumDecl: {
QString name = getCursorSpelling(cursor);
- const bool anonymous = name.isEmpty();
- if (anonymous)
+ EnumKind kind = CEnum;
+ if (name.isEmpty()) {
+ kind = AnonymousEnum;
name = QStringLiteral("enum_") + QString::number(++d->m_anonymousEnumCount);
+#if !CLANG_NO_ENUMDECL_ISSCOPED
+ } else if (clang_EnumDecl_isScoped(cursor) != 0) {
+#else
+ } else if (clang_EnumDecl_isScoped4(this, cursor) != 0) {
+#endif
+ kind = EnumClass;
+ }
d->m_currentEnum.reset(new _EnumModelItem(d->m_model, name));
setFileName(cursor, d->m_currentEnum.data());
d->m_currentEnum->setScope(d->m_scope);
- d->m_currentEnum->setAnonymous(anonymous);
+ d->m_currentEnum->setEnumKind(kind);
if (!qSharedPointerDynamicCast<_ClassModelItem>(d->m_scopeStack.back()).isNull())
d->m_currentEnum->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor)));
d->m_scopeStack.back()->addEnum(d->m_currentEnum);
diff --git a/sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst b/sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst
index 646e76043..322f9bca6 100644
--- a/sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst
@@ -180,10 +180,6 @@ enum-type
Notice that the **enum-type** tag can either have **name** or **identified-by-value**
but not both.
- The *optional* boolean attribute **class** specifies whether the underlying
- enumeration is a C++ 11 enumeration class. In that case, the enumeration values
- need to be qualified by the enumeration name to match the C++ Syntax.
-
The **revision** attribute can be used to specify a revision for each type, easing the
production of ABI compatible bindings.
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
index a35ca314b..fbfeaadf7 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
@@ -1014,22 +1014,20 @@ void _EnumModelItem::addEnumerator(EnumeratorModelItem item)
m_enumerators.append(item);
}
-bool _EnumModelItem::isAnonymous() const
-{
- return m_anonymous;
-}
-
-void _EnumModelItem::setAnonymous(bool anonymous)
-{
- m_anonymous = anonymous;
-}
-
#ifndef QT_NO_DEBUG_STREAM
void _EnumModelItem::formatDebug(QDebug &d) const
{
_CodeModelItem::formatDebug(d);
- if (m_anonymous)
- d << " (anonymous)";
+ switch (m_enumKind) {
+ case CEnum:
+ break;
+ case AnonymousEnum:
+ d << " (anonymous)";
+ break;
+ case EnumClass:
+ d << " (class)";
+ break;
+ }
formatModelItemList(d, ", enumerators=", m_enumerators);
}
#endif // !QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index 2aaea1f78..b300cf249 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -631,10 +631,8 @@ class _EnumModelItem: public _CodeModelItem
public:
DECLARE_MODEL_NODE(Enum)
- explicit _EnumModelItem(CodeModel *model, int kind = __node_kind)
- : _CodeModelItem(model, kind), m_accessPolicy(CodeModel::Public), m_anonymous(false) {}
explicit _EnumModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _CodeModelItem(model, name, kind), m_accessPolicy(CodeModel::Public), m_anonymous(false) {}
+ : _CodeModelItem(model, name, kind) {}
~_EnumModelItem();
CodeModel::AccessPolicy accessPolicy() const;
@@ -642,17 +640,18 @@ public:
EnumeratorList enumerators() const;
void addEnumerator(EnumeratorModelItem item);
- bool isAnonymous() const;
- void setAnonymous(bool anonymous);
+
+ EnumKind enumKind() const { return m_enumKind; }
+ void setEnumKind(EnumKind kind) { m_enumKind = kind; }
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
private:
- CodeModel::AccessPolicy m_accessPolicy;
+ CodeModel::AccessPolicy m_accessPolicy = CodeModel::Public;
EnumeratorList m_enumerators;
- bool m_anonymous;
+ EnumKind m_enumKind = CEnum;
};
class _EnumeratorModelItem: public _CodeModelItem
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h b/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
index aa8b051d8..3115a9a94 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
@@ -35,4 +35,10 @@ enum ReferenceType {
RValueReference
};
+enum EnumKind {
+ CEnum, // Standard C: enum Foo { value1, value2 }
+ AnonymousEnum, // enum { value1, value2 }
+ EnumClass // C++ 11 : enum class Foo { value1, value2 }
+};
+
#endif // CODEMODEL_ENUMS_H
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index 600536aba..0a47b9b17 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -963,11 +963,6 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts
m_currentEnum =
new EnumTypeEntry(QStringList(names.mid(0, names.size() - 1)).join(colonColon()),
names.constLast(), since);
- if (!attributes.value(enumIdentifiedByValueAttribute()).isEmpty()) {
- m_currentEnum->setEnumKind(EnumTypeEntry::AnonymousEnum);
- } else if (convertBoolean(attributes.value(classAttribute()), classAttribute(), false)) {
- m_currentEnum->setEnumKind(EnumTypeEntry::EnumClass);
- }
element->entry = m_currentEnum;
m_currentEnum->setCodeGeneration(m_generate);
m_currentEnum->setTargetLangPackage(m_defaultPackage);
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 2f534c93d..eae064134 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -1041,12 +1041,6 @@ private:
class EnumTypeEntry : public TypeEntry
{
public:
- enum EnumKind {
- CEnum, // Standard C: enum Foo { value1, value2 }
- AnonymousEnum, // enum { value1, value2 }
- EnumClass // C++ 11 : enum class Foo { value1, value2 }
- };
-
explicit EnumTypeEntry(const QString &nspace, const QString &enumName,
const QVersionNumber &vr);
@@ -1068,9 +1062,6 @@ public:
m_qualifier = q;
}
- EnumKind enumKind() const { return m_enumKind; }
- void setEnumKind(EnumKind kind) { m_enumKind = kind; }
-
bool preferredConversion() const override;
bool isBoundsChecked() const
@@ -1136,8 +1127,6 @@ public:
m_forceInteger = force;
}
- bool isAnonymous() const { return m_enumKind == AnonymousEnum; }
-
private:
QString m_packageName;
QString m_qualifier;
@@ -1150,8 +1139,6 @@ private:
FlagsTypeEntry *m_flags = nullptr;
- EnumKind m_enumKind = CEnum;
-
bool m_extensible = false;
bool m_forceInteger = false;
};
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 18670eae6..72da73aa4 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -4532,8 +4532,8 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
enumValueText += QString::number(enumValue->value());
}
- switch (enumTypeEntry->enumKind()) {
- case EnumTypeEntry::AnonymousEnum:
+ switch (cppEnum->enumKind()) {
+ case AnonymousEnum:
if (enclosingClass || hasUpperEnclosingClass) {
s << INDENT << '{' << endl;
{
@@ -4557,7 +4557,7 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
}
}
break;
- case EnumTypeEntry::CEnum: {
+ case CEnum: {
s << INDENT << "if (!Shiboken::Enum::";
s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnumItem" : "createGlobalEnumItem");
s << '(' << enumVarTypeObj << ',' << endl;
@@ -4567,7 +4567,7 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
s << INDENT << "return " << m_currentErrorCode << ';' << endl;
}
break;
- case EnumTypeEntry::EnumClass: {
+ case EnumClass: {
s << INDENT << "if (!Shiboken::Enum::createScopedEnumItem("
<< enumVarTypeObj << ',' << endl;
Indentation indent(INDENT);
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 5a12eeccd..3cc80860d 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -798,7 +798,7 @@
<value-type name="Event">
<enum-type name="EventType"/>
- <enum-type name="EventTypeClass" class="yes"/>
+ <enum-type name="EventTypeClass"/>
</value-type>
<value-type name="BlackBox">