aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
-rw-r--r--sources/shiboken2/ApiExtractor/CMakeLists.txt4
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp246
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h7
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp12
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h17
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp72
-rw-r--r--sources/shiboken2/ApiExtractor/doc/CMakeLists.txt10
-rw-r--r--sources/shiboken2/ApiExtractor/doc/conf.py.in3
-rw-r--r--sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst4
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.cpp33
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.h30
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel_enums.h6
-rw-r--r--sources/shiboken2/ApiExtractor/parser/enumvalue.cpp76
-rw-r--r--sources/shiboken2/ApiExtractor/parser/enumvalue.h70
-rw-r--r--sources/shiboken2/ApiExtractor/qtdocparser.cpp14
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp4
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testenum.cpp69
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp5
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h13
19 files changed, 379 insertions, 316 deletions
diff --git a/sources/shiboken2/ApiExtractor/CMakeLists.txt b/sources/shiboken2/ApiExtractor/CMakeLists.txt
index 4355e32ef..8d68b0dcf 100644
--- a/sources/shiboken2/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/CMakeLists.txt
@@ -1,5 +1,7 @@
project(apiextractor)
+cmake_minimum_required(VERSION 3.1)
+cmake_policy(VERSION 3.1)
find_package(LibXml2 2.6.32)
find_package(LibXslt 1.1.19)
@@ -55,11 +57,13 @@ clangparser/clangdebugutils.cpp
clangparser/clangutils.cpp
# Old parser
parser/codemodel.cpp
+parser/enumvalue.cpp
)
set(APIEXTRACTOR_EXTRA_INCLUDES ${CLANG_EXTRA_INCLUDES})
set(APIEXTRACTOR_EXTRA_LIBRARIES ${CLANG_EXTRA_LIBRARIES})
+add_subdirectory(doc)
if (NOT DISABLE_DOCSTRINGS)
set(apiextractor_SRC
${apiextractor_SRC}
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 1afc7d135..b862ba548 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -508,8 +508,6 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
addAbstractMetaClass(cls);
}
- figureOutEnumValues();
-
for (const ClassModelItem &item : typeValues)
traverseClassMembers(item);
@@ -684,7 +682,6 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
traverseStreamOperator(item);
}
- figureOutDefaultEnumArguments();
checkFunctionModifications();
// sort all classes topologically
@@ -839,207 +836,6 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
return metaClass;
}
-struct Operator
-{
- enum Type { Complement, Plus, ShiftRight, ShiftLeft, None };
-
- Operator() : type(None) {}
-
- int calculate(int x)
- {
- switch (type) {
- case Complement: return ~value;
- case Plus: return x + value;
- case ShiftRight: return x >> value;
- case ShiftLeft: return x << value;
- case None: return x;
- }
- return x;
- }
-
- Type type;
- int value;
-};
-
-
-
-Operator findOperator(QString* s)
-{
- const char *names[] = {
- "~",
- "+",
- ">>",
- "<<"
- };
-
- for (int i = 0; i < Operator::None; ++i) {
- QString name = QLatin1String(names[i]);
- QString str = *s;
- int splitPoint = str.indexOf(name);
- if (splitPoint > -1) {
- bool ok;
- QString right = str.mid(splitPoint + name.length());
- Operator op;
-
- op.value = right.toInt(&ok);
- if (!ok && right.length() > 0 && right.at(right.length() - 1).toLower() == QLatin1Char('u'))
- op.value = right.left(right.length() - 1).toUInt(&ok, 0);
-
- if (ok) {
- op.type = Operator::Type(i);
- if (splitPoint > 0)
- *s = str.left(splitPoint).trimmed();
- else
- *s = QString();
- return op;
- }
- }
- }
- return Operator();
-}
-
-int AbstractMetaBuilderPrivate::figureOutEnumValue(const QString &stringValue,
- int oldValuevalue,
- AbstractMetaEnum *metaEnum,
- AbstractMetaFunction *metaFunction)
-{
- if (stringValue.isEmpty())
- return oldValuevalue;
-
- QStringList stringValues = stringValue.split(QLatin1Char('|'));
-
- int returnValue = 0;
-
- bool matched = false;
-
- for (int i = 0; i < stringValues.size(); ++i) {
- QString s = stringValues.at(i).trimmed();
-
- bool ok;
- int v;
-
- Operator op = findOperator(&s);
-
- if (s.length() > 0 && s.at(0) == QLatin1Char('0'))
- v = s.toUInt(&ok, 0);
- else if (s.length() > 0 && s.at(s.length() - 1).toLower() == QLatin1Char('u'))
- v = s.left(s.length() - 1).toUInt(&ok, 0);
- else
- v = s.toInt(&ok);
-
- if (ok || s.isEmpty()) {
- matched = true;
- } else if (m_enumValues.contains(s)) {
- v = m_enumValues[s]->value();
- matched = true;
- } else {
- if (metaEnum) {
- v = findOutValueFromString(s, matched);
- if (!matched) {
- QString enclosingClass = QString(metaEnum->enclosingClass() ? metaEnum->enclosingClass()->name() + colonColon() : QString());
- qCWarning(lcShiboken).noquote().nospace()
- << "unhandled enum value: " << s << " in "
- << enclosingClass << metaEnum->name() << " from header '"
- << metaEnum->typeEntry()->include().name() << '\'';
- }
- } else {
- qCWarning(lcShiboken) << "unhandled enum value: Unknown enum";
- }
- }
-
- if (matched)
- returnValue |= op.calculate(v);
- }
-
- if (!matched) {
- QString warn = QStringLiteral("unmatched enum %1").arg(stringValue);
-
- if (metaFunction) {
- warn += QStringLiteral(" when parsing default value of '%1' in class '%2'")
- .arg(metaFunction->name(), metaFunction->implementingClass()->name());
- }
- warn += QLatin1String(" from header '") + metaEnum->typeEntry()->include().name()
- + QLatin1Char('\'');
-
- qCWarning(lcShiboken).noquote().nospace() << warn;
- returnValue = oldValuevalue;
- }
-
- return returnValue;
-}
-
-void AbstractMetaBuilderPrivate::figureOutEnumValuesForClass(AbstractMetaClass *metaClass,
- QSet<AbstractMetaClass *> *classes)
-{
- AbstractMetaClass* base = metaClass->baseClass();
-
- if (base && !classes->contains(base))
- figureOutEnumValuesForClass(base, classes);
-
- if (classes->contains(metaClass))
- return;
-
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (AbstractMetaEnum* e : enums) {
- if (!e) {
- qCWarning(lcShiboken).noquote().nospace() << "bad enum in class " << metaClass->name();
- continue;
- }
- AbstractMetaEnumValueList lst = e->values();
- int value = 0;
- for (int i = 0; i < lst.size(); ++i) {
- value = figureOutEnumValue(lst.at(i)->stringValue(), value, e);
- lst.at(i)->setValue(value);
- value++;
- }
- }
-
- *classes += metaClass;
-}
-
-
-void AbstractMetaBuilderPrivate::figureOutEnumValues()
-{
- // Keep a set of classes that we already traversed. We use this to
- // enforce that we traverse base classes prior to subclasses.
- QSet<AbstractMetaClass*> classes;
- for (AbstractMetaClass *c : qAsConst(m_metaClasses))
- figureOutEnumValuesForClass(c, &classes);
-
- for (AbstractMetaEnum* metaEnum : qAsConst(m_globalEnums)) {
- AbstractMetaEnumValueList enumValues = metaEnum->values();
- int value = 0;
- for (int i = 0; i < enumValues.size(); ++i) {
- value = figureOutEnumValue(enumValues.at(i)->stringValue(), value, metaEnum);
- enumValues.at(i)->setValue(value);
- value++;
- }
- }
-}
-
-void AbstractMetaBuilderPrivate::figureOutDefaultEnumArguments()
-{
- for (AbstractMetaClass* metaClass : qAsConst(m_metaClasses)) {
- const AbstractMetaFunctionList &functions = metaClass->functions();
- for (AbstractMetaFunction* metaFunction : functions) {
- const AbstractMetaArgumentList &arguments = metaFunction->arguments();
- for (AbstractMetaArgument *arg : arguments) {
- QString expr = arg->defaultValueExpression();
- if (expr.isEmpty())
- continue;
-
- if (!metaFunction->replacedDefaultExpression(metaFunction->implementingClass(),
- arg->argumentIndex() + 1).isEmpty()) {
- continue;
- }
-
- arg->setDefaultValueExpression(expr);
- }
- }
- }
-}
-
-
AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumItem,
AbstractMetaClass *enclosing,
const QSet<QString> &enumsDeclarations)
@@ -1055,7 +851,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,12 +892,15 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte
}
AbstractMetaEnum *metaEnum = new AbstractMetaEnum;
+ metaEnum->setEnumKind(enumItem->enumKind());
+ metaEnum->setSigned(enumItem->isSigned());
if (enumsDeclarations.contains(qualifiedName)
|| enumsDeclarations.contains(enumName)) {
metaEnum->setHasQEnumsDeclaration(true);
}
- metaEnum->setTypeEntry((EnumTypeEntry*) typeEntry);
+ EnumTypeEntry *enumTypeEntry = static_cast<EnumTypeEntry *>(typeEntry);
+ metaEnum->setTypeEntry(enumTypeEntry);
switch (enumItem->accessPolicy()) {
case CodeModel::Public:
*metaEnum += AbstractMetaAttributes::Public;
@@ -1127,7 +926,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte
metaEnumValue->setName(value->name());
// Deciding the enum value...
- metaEnumValue->setStringValue(value->value());
+ metaEnumValue->setStringValue(value->stringValue());
+ metaEnumValue->setValue(value->value());
metaEnum->addEnumValue(metaEnumValue);
if (ReportHandler::isDebug(ReportHandler::FullDebug)) {
@@ -1158,7 +958,9 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte
name += colonColon();
}
name += e->name();
- EnumValueTypeEntry* enumValue = new EnumValueTypeEntry(name, e->value(), static_cast<EnumTypeEntry*>(typeEntry), typeEntry->version());
+ EnumValueTypeEntry *enumValue =
+ new EnumValueTypeEntry(name, e->stringValue(),
+ enumTypeEntry, enumTypeEntry->version());
TypeDatabase::instance()->addType(enumValue);
}
@@ -2286,6 +2088,20 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
bool ok;
AbstractMetaType* metaType = translateType(arg->type(), &ok);
if (!ok) {
+ // If an invalid argument has a default value, simply remove it
+ if (arg->defaultValue()) {
+ if (!m_currentClass
+ || (m_currentClass->typeEntry()->codeGeneration()
+ & TypeEntry::GenerateTargetLang)) {
+ qCWarning(lcShiboken).noquote().nospace()
+ << "Stripping argument #" << (i + 1) << " of "
+ << originalQualifiedSignatureWithReturn
+ << " due to unmatched type \"" << arg->type().toString()
+ << "\" with default expression \""
+ << arg->defaultValueExpression() << "\".";
+ }
+ break;
+ }
Q_ASSERT(metaType == 0);
const QString reason = msgUnmatchedParameterType(arg, i);
qCWarning(lcShiboken).noquote().nospace()
@@ -2321,7 +2137,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
metaFunction->setArguments(metaArguments);
// Find the correct default values
- for (int i = 0; i < arguments.size(); ++i) {
+ for (int i = 0, size = metaArguments.size(); i < size; ++i) {
ArgumentModelItem arg = arguments.at(i);
AbstractMetaArgument* metaArg = metaArguments.at(i);
@@ -2570,9 +2386,9 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
arrayType->setArrayElementType(elementType);
if (!typeInfo.arrays.at(i).isEmpty()) {
bool _ok;
- const int elems = findOutValueFromString(typeInfo.arrays.at(i), _ok);
+ const qint64 elems = findOutValueFromString(typeInfo.arrays.at(i), _ok);
if (_ok)
- arrayType->setArrayElementCount(elems);
+ arrayType->setArrayElementCount(int(elems));
}
arrayType->setTypeEntry(new ArrayTypeEntry(elementType->typeEntry() , elementType->typeEntry()->version()));
decideUsagePattern(arrayType);
@@ -2712,9 +2528,9 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
}
-int AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValue, bool &ok)
+qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValue, bool &ok)
{
- int value = stringValue.toInt(&ok);
+ qint64 value = stringValue.toLongLong(&ok);
if (ok)
return value;
@@ -2735,13 +2551,13 @@ int AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValu
AbstractMetaEnumValue *enumValue = AbstractMetaClass::findEnumValue(m_metaClasses, stringValue);
if (enumValue) {
ok = true;
- return enumValue->value();
+ return enumValue->value().value();
}
for (AbstractMetaEnum *metaEnum : qAsConst(m_globalEnums)) {
if (const AbstractMetaEnumValue *ev = metaEnum->findEnumValue(stringValue)) {
ok = true;
- return ev->value();
+ return ev->value().value();
}
}
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index 7a2565914..7f5e866ab 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -60,11 +60,6 @@ public:
AbstractMetaClass *argumentToClass(ArgumentModelItem);
- void figureOutEnumValuesForClass(AbstractMetaClass *metaClass, QSet<AbstractMetaClass *> *classes);
- int figureOutEnumValue(const QString &name, int value, AbstractMetaEnum *meta_enum, AbstractMetaFunction *metaFunction = 0);
- void figureOutEnumValues();
- void figureOutDefaultEnumArguments();
-
void addAbstractMetaClass(AbstractMetaClass *cls);
AbstractMetaClass *traverseTypeDef(const FileModelItem &dom,
const TypeDefModelItem &typeDef);
@@ -129,7 +124,7 @@ public:
bool resolveType = true,
bool resolveScope = true);
- int findOutValueFromString(const QString &stringValue, bool &ok);
+ qint64 findOutValueFromString(const QString &stringValue, bool &ok);
void decideUsagePattern(AbstractMetaType *type);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 4e507cd38..235413165 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -1700,7 +1700,10 @@ QDebug operator<<(QDebug d, const AbstractMetaEnum *ae)
d.nospace();
d << "AbstractMetaEnum(";
if (ae) {
- d << ae->fullName() << '[';
+ d << ae->fullName();
+ if (!ae->isSigned())
+ d << " (unsigned) ";
+ d << '[';
const AbstractMetaEnumValueList &values = ae->values();
for (int i = 0, count = values.size(); i < count; ++i) {
if (i)
@@ -2411,7 +2414,7 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
*/
AbstractMetaEnum::AbstractMetaEnum() :
- m_hasQenumsDeclaration(false)
+ m_hasQenumsDeclaration(false), m_signed(true)
{
}
@@ -2457,8 +2460,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..7e0bfa322 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -34,6 +34,7 @@
#include "typesystem_typedefs.h"
#include "parser/codemodel_enums.h"
+#include "parser/enumvalue.h"
#include <QtCore/qobjectdefs.h>
#include <QtCore/QStringList>
@@ -1090,12 +1091,12 @@ class AbstractMetaEnumValue
public:
AbstractMetaEnumValue() {}
- int value() const
+ EnumValue value() const
{
return m_value;
}
- void setValue(int value)
+ void setValue(EnumValue value)
{
m_value = value;
}
@@ -1134,7 +1135,7 @@ private:
QString m_name;
QString m_stringValue;
- int m_value = 0;
+ EnumValue m_value;
Documentation m_doc;
};
@@ -1168,6 +1169,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,14 +1205,17 @@ public:
m_class = c;
}
- bool isAnonymous() const;
+ bool isSigned() const { return m_signed; }
+ void setSigned(bool s) { m_signed = s; }
private:
AbstractMetaEnumValueList m_enumValues;
EnumTypeEntry *m_typeEntry = nullptr;
AbstractMetaClass *m_class = nullptr;
+ EnumKind m_enumKind = CEnum;
uint m_hasQenumsDeclaration : 1;
+ uint m_signed : 1;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index 1ed054d91..b57ef2f43 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
@@ -123,6 +124,24 @@ static void setFileName(const CXCursor &cursor, _CodeModelItem *item)
}
}
+static bool isSigned(CXTypeKind kind)
+{
+ switch (kind) {
+ case CXType_UChar:
+ case CXType_Char16:
+ case CXType_Char32:
+ case CXType_UShort:
+ case CXType_UInt:
+ case CXType_ULong:
+ case CXType_ULongLong:
+ case CXType_UInt128:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
class BuilderPrivate {
public:
typedef QHash<CXCursor, ClassModelItem> CursorClassHash;
@@ -437,6 +456,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 +690,22 @@ 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);
+ d->m_currentEnum->setSigned(isSigned(clang_getEnumDeclIntegerType(cursor).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);
@@ -661,8 +719,14 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
appendDiagnostic(d);
return Error;
}
+ EnumValue enumValue;
+ if (d->m_currentEnum->isSigned())
+ enumValue.setValue(clang_getEnumConstantDeclValue(cursor));
+ else
+ enumValue.setUnsignedValue(clang_getEnumConstantDeclUnsignedValue(cursor));
EnumeratorModelItem enumConstant(new _EnumeratorModelItem(d->m_model, name));
- enumConstant->setValue(d->cursorValueExpression(this, cursor));
+ enumConstant->setStringValue(d->cursorValueExpression(this, cursor));
+ enumConstant->setValue(enumValue);
d->m_currentEnum->addEnumerator(enumConstant);
}
break;
diff --git a/sources/shiboken2/ApiExtractor/doc/CMakeLists.txt b/sources/shiboken2/ApiExtractor/doc/CMakeLists.txt
index d78844dc8..a1995e96f 100644
--- a/sources/shiboken2/ApiExtractor/doc/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/doc/CMakeLists.txt
@@ -1,10 +1,10 @@
-
+message("Building ApiExtractor documentation")
find_program(SPHINX sphinx-build DOC "Path to sphinx-build binary.")
if (SPHINX)
- message("-- sphinx-build - found")
+ message(STATUS "sphinx-build - found")
configure_file(conf.py.in conf.py @ONLY)
- add_custom_target(doc ${SPHINX} -b html -c . ${CMAKE_CURRENT_SOURCE_DIR} html )
+ add_custom_target(doc_apiextractor ${SPHINX} -b html -c . ${CMAKE_CURRENT_SOURCE_DIR} html )
else()
- message("-- sphinx-build - not found! doc target disabled")
-endif() \ No newline at end of file
+ message(STATUS "sphinx-build - not found! doc_apiextractor target disabled")
+endif()
diff --git a/sources/shiboken2/ApiExtractor/doc/conf.py.in b/sources/shiboken2/ApiExtractor/doc/conf.py.in
index 3a42707ad..7251aaccd 100644
--- a/sources/shiboken2/ApiExtractor/doc/conf.py.in
+++ b/sources/shiboken2/ApiExtractor/doc/conf.py.in
@@ -22,7 +22,8 @@ import sys, os
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.ifconfig', 'sphinx.ext.refcounting', 'sphinx.ext.coverage']
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest',
+ 'sphinx.ext.ifconfig', 'sphinx.ext.coverage']
rst_epilog = """
.. |project| replace:: API Extractor
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..1262f5901 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
@@ -1014,22 +1014,32 @@ void _EnumModelItem::addEnumerator(EnumeratorModelItem item)
m_enumerators.append(item);
}
-bool _EnumModelItem::isAnonymous() const
+bool _EnumModelItem::isSigned() const
{
- return m_anonymous;
+ return m_signed;
}
-void _EnumModelItem::setAnonymous(bool anonymous)
+void _EnumModelItem::setSigned(bool s)
{
- m_anonymous = anonymous;
+ m_signed = s;
}
#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;
+ }
+ if (!m_signed)
+ d << " (unsigned)";
formatModelItemList(d, ", enumerators=", m_enumerators);
}
#endif // !QT_NO_DEBUG_STREAM
@@ -1039,22 +1049,21 @@ _EnumeratorModelItem::~_EnumeratorModelItem()
{
}
-QString _EnumeratorModelItem::value() const
+QString _EnumeratorModelItem::stringValue() const
{
- return m_value;
+ return m_stringValue;
}
-void _EnumeratorModelItem::setValue(const QString &value)
+void _EnumeratorModelItem::setStringValue(const QString &value)
{
- m_value = value;
+ m_stringValue = value;
}
#ifndef QT_NO_DEBUG_STREAM
void _EnumeratorModelItem::formatDebug(QDebug &d) const
{
_CodeModelItem::formatDebug(d);
- if (!m_value.isEmpty())
- d << ", value=\"" << m_value << '"';
+ d << ", value=" << m_value << ", stringValue=\"" << m_stringValue << '"';
}
#endif // !QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index 2aaea1f78..ed0eedf7d 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -33,6 +33,7 @@
#include "codemodel_fwd.h"
#include "codemodel_enums.h"
+#include "enumvalue.h"
#include <QtCore/QHash>
#include <QtCore/QSet>
@@ -631,10 +632,10 @@ 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) {}
+ explicit _EnumModelItem(CodeModel *model, int kind = __node_kind)
+ : _CodeModelItem(model, kind) {}
~_EnumModelItem();
CodeModel::AccessPolicy accessPolicy() const;
@@ -642,17 +643,22 @@ 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
+ bool isSigned() const;
+ void setSigned(bool s);
+
private:
- CodeModel::AccessPolicy m_accessPolicy;
+ CodeModel::AccessPolicy m_accessPolicy = CodeModel::Public;
EnumeratorList m_enumerators;
- bool m_anonymous;
+ EnumKind m_enumKind = CEnum;
+ bool m_signed = true;
};
class _EnumeratorModelItem: public _CodeModelItem
@@ -666,15 +672,19 @@ public:
: _CodeModelItem(model, name, kind) {}
~_EnumeratorModelItem();
- QString value() const;
- void setValue(const QString &value);
+ QString stringValue() const;
+ void setStringValue(const QString &stringValue);
+
+ EnumValue value() const { return m_value; }
+ void setValue(EnumValue v) { m_value = v; }
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
private:
- QString m_value;
+ QString m_stringValue;
+ EnumValue m_value;
};
class _TemplateParameterModelItem: 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/parser/enumvalue.cpp b/sources/shiboken2/ApiExtractor/parser/enumvalue.cpp
new file mode 100644
index 000000000..84723eb14
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/parser/enumvalue.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#include "enumvalue.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QString>
+#include <QtCore/QTextStream>
+
+QString EnumValue::toString() const
+{
+ return m_type == EnumValue::Signed
+ ? QString::number(m_value) : QString::number(m_unsignedValue);
+}
+
+void EnumValue::setValue(qint64 v)
+{
+ m_value = v;
+ m_type = Signed;
+}
+
+void EnumValue::setUnsignedValue(quint64 v)
+{
+ m_unsignedValue = v;
+ m_type = Unsigned;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d,const EnumValue &v)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d.noquote();
+ d << "EnumValue(";
+ if (v.m_type == EnumValue::Signed)
+ d << v.m_value;
+ else
+ d << v.m_unsignedValue << 'u';
+ d << ')';
+ return d;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+QTextStream &operator<<(QTextStream &s, const EnumValue &v)
+{
+ if (v.m_type == EnumValue::Signed)
+ s << v.m_value;
+ else
+ s << v.m_unsignedValue;
+ return s;
+}
diff --git a/sources/shiboken2/ApiExtractor/parser/enumvalue.h b/sources/shiboken2/ApiExtractor/parser/enumvalue.h
new file mode 100644
index 000000000..2e2070306
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/parser/enumvalue.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of PySide2.
+**
+** $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 ENUMVALUE_H
+#define ENUMVALUE_H
+
+#include <QtCore/QtGlobal>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+QT_FORWARD_DECLARE_CLASS(QString)
+QT_FORWARD_DECLARE_CLASS(QTextStream)
+
+class EnumValue
+{
+public:
+ enum Type
+ {
+ Signed,
+ Unsigned
+ };
+
+ QString toString() const;
+
+ Type type() { return m_type; }
+ qint64 value() const { return m_value; }
+ quint64 unsignedValue() const { return m_unsignedValue; }
+
+ void setValue(qint64 v);
+ void setUnsignedValue(quint64 v);
+
+private:
+#ifndef QT_NO_DEBUG_STREAM
+ friend QDebug operator<<(QDebug, const EnumValue &);
+#endif
+ friend QTextStream &operator<<(QTextStream &, const EnumValue &);
+
+ union
+ {
+ qint64 m_value = 0;
+ quint64 m_unsignedValue;
+ };
+ Type m_type = Signed;
+};
+
+#endif // ENUMVALUE_H
diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
index 0ac87bd16..85c3473cd 100644
--- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp
+++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
@@ -68,6 +68,17 @@ static void formatFunctionArgTypeQuery(QTextStream &str, const AbstractMetaArgum
str << name;
}
break;
+ case AbstractMetaType::ContainerPattern: { // QVector<int>
+ str << metaType->typeEntry()->qualifiedCppName() << '<';
+ const auto instantiations = metaType->instantiations();
+ for (int i = 0, size = instantiations.size(); i < size; ++i) {
+ if (i)
+ str << ", ";
+ str << instantiations.at(i)->typeEntry()->qualifiedCppName();
+ }
+ str << '>';
+ }
+ break;
default: // Fully qualify enums (Qt::AlignmentFlag), nested classes, etc.
str << metaType->typeEntry()->qualifiedCppName();
break;
@@ -218,7 +229,8 @@ Documentation QtDocParser::retrieveModuleDocumentation(const QString& name)
xquery.setFocus(QUrl(sourceFile));
// Module documentation
- QString query = QLatin1String("/WebXML/document/page[@name=\"") + moduleName + QLatin1String("\"]/description");
+ QString query = QLatin1String("/WebXML/document/module[@name=\"")
+ + moduleName + QLatin1String("\"]/description");
const Documentation doc = getDocumentation(xquery, query, DocModificationList());
if (doc.isEmpty())
qCWarning(lcShiboken(), "%s", qPrintable(msgCannotFindDocumentation(sourceFile, "module", name, query)));
diff --git a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp
index cbeb216c9..eb10fc8a0 100644
--- a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp
@@ -133,7 +133,7 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValue()
const AbstractMetaArgument* arg = classA->functions().last()->arguments().first();
QVERIFY(arg->type()->isArray());
- QCOMPARE(arg->type()->arrayElementCount(), nvalues->value());
+ QCOMPARE(arg->type()->arrayElementCount(), nvalues->value().value());
QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double"));
};
@@ -164,7 +164,7 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnu
const AbstractMetaArgument* arg = classA->functions().last()->arguments().first();
QVERIFY(arg->type()->isArray());
- QCOMPARE(arg->type()->arrayElementCount(), nvalues->value());
+ QCOMPARE(arg->type()->arrayElementCount(), nvalues->value().value());
QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double"));
};
diff --git a/sources/shiboken2/ApiExtractor/tests/testenum.cpp b/sources/shiboken2/ApiExtractor/tests/testenum.cpp
index 55c098840..970f6d00c 100644
--- a/sources/shiboken2/ApiExtractor/tests/testenum.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testenum.cpp
@@ -149,12 +149,12 @@ void TestEnum::testAnonymousEnum()
AbstractMetaEnumValue* enumValueA0 = anonEnumA1->values().first();
QCOMPARE(enumValueA0->name(), QLatin1String("A0"));
- QCOMPARE(enumValueA0->value(), 0);
+ QCOMPARE(enumValueA0->value().value(), 0);
QCOMPARE(enumValueA0->stringValue(), QString());
AbstractMetaEnumValue* enumValueA1 = anonEnumA1->values().last();
QCOMPARE(enumValueA1->name(), QLatin1String("A1"));
- QCOMPARE(enumValueA1->value(), 1);
+ QCOMPARE(enumValueA1->value().value(), 1);
QCOMPARE(enumValueA1->stringValue(), QString());
AbstractMetaEnum* anonEnumIsThis = classes[0]->findEnum(QLatin1String("isThis"));
@@ -164,12 +164,12 @@ void TestEnum::testAnonymousEnum()
AbstractMetaEnumValue* enumValueIsThis = anonEnumIsThis->values().first();
QCOMPARE(enumValueIsThis->name(), QLatin1String("isThis"));
- QCOMPARE(enumValueIsThis->value(), static_cast<int>(true));
+ QCOMPARE(enumValueIsThis->value().value(), static_cast<int>(true));
QCOMPARE(enumValueIsThis->stringValue(), QLatin1String("true"));
AbstractMetaEnumValue* enumValueIsThat = anonEnumIsThis->values().last();
QCOMPARE(enumValueIsThat->name(), QLatin1String("isThat"));
- QCOMPARE(enumValueIsThat->value(), static_cast<int>(false));
+ QCOMPARE(enumValueIsThat->value().value(), static_cast<int>(false));
QCOMPARE(enumValueIsThat->stringValue(), QLatin1String("false"));
}
@@ -195,12 +195,12 @@ void TestEnum::testGlobalEnums()
AbstractMetaEnumValue* enumValueA0 = enumA->values().first();
QCOMPARE(enumValueA0->name(), QLatin1String("A0"));
- QCOMPARE(enumValueA0->value(), 0);
+ QCOMPARE(enumValueA0->value().value(), 0);
QCOMPARE(enumValueA0->stringValue(), QString());
AbstractMetaEnumValue* enumValueA1 = enumA->values().last();
QCOMPARE(enumValueA1->name(), QLatin1String("A1"));
- QCOMPARE(enumValueA1->value(), 1);
+ QCOMPARE(enumValueA1->value().value(), 1);
QCOMPARE(enumValueA1->stringValue(), QString());
AbstractMetaEnum* enumB = globalEnums.last();
@@ -208,12 +208,12 @@ void TestEnum::testGlobalEnums()
AbstractMetaEnumValue* enumValueB0 = enumB->values().first();
QCOMPARE(enumValueB0->name(), QLatin1String("B0"));
- QCOMPARE(enumValueB0->value(), 2);
+ QCOMPARE(enumValueB0->value().value(), 2);
QCOMPARE(enumValueB0->stringValue(), QLatin1String("2"));
AbstractMetaEnumValue* enumValueB1 = enumB->values().last();
QCOMPARE(enumValueB1->name(), QLatin1String("B1"));
- QCOMPARE(enumValueB1->value(), 4);
+ QCOMPARE(enumValueB1->value().value(), 4);
QCOMPARE(enumValueB1->stringValue(), QLatin1String("0x4"));
}
@@ -245,12 +245,12 @@ void TestEnum::testEnumValueFromNeighbourEnum()
AbstractMetaEnumValue* enumValueA0 = enumA->values().first();
QCOMPARE(enumValueA0->name(), QLatin1String("ValueA0"));
- QCOMPARE(enumValueA0->value(), 0);
+ QCOMPARE(enumValueA0->value().value(), 0);
QCOMPARE(enumValueA0->stringValue(), QString());
AbstractMetaEnumValue* enumValueA1 = enumA->values().last();
QCOMPARE(enumValueA1->name(), QLatin1String("ValueA1"));
- QCOMPARE(enumValueA1->value(), 1);
+ QCOMPARE(enumValueA1->value().value(), 1);
QCOMPARE(enumValueA1->stringValue(), QString());
AbstractMetaEnum* enumB = classes[0]->findEnum(QLatin1String("EnumB"));
@@ -259,12 +259,12 @@ void TestEnum::testEnumValueFromNeighbourEnum()
AbstractMetaEnumValue* enumValueB0 = enumB->values().first();
QCOMPARE(enumValueB0->name(), QLatin1String("ValueB0"));
- QCOMPARE(enumValueB0->value(), 1);
+ QCOMPARE(enumValueB0->value().value(), 1);
QCOMPARE(enumValueB0->stringValue(), QLatin1String("A::ValueA1"));
AbstractMetaEnumValue* enumValueB1 = enumB->values().last();
QCOMPARE(enumValueB1->name(), QLatin1String("ValueB1"));
- QCOMPARE(enumValueB1->value(), 0);
+ QCOMPARE(enumValueB1->value().value(), 0);
QCOMPARE(enumValueB1->stringValue(), QLatin1String("ValueA0"));
}
@@ -272,21 +272,25 @@ void TestEnum::testEnumValueFromExpression()
{
const char* cppCode ="\
struct A {\n\
- enum EnumA {\n\
+ enum EnumA : unsigned {\n\
ValueA0 = 3u,\n\
ValueA1 = ~3u,\n\
- ValueA2 = ~3,\n\
+ ValueA2 = 0xffffffff,\n\
ValueA3 = 0xf0,\n\
ValueA4 = 8 |ValueA3,\n\
ValueA5 = ValueA3|32,\n\
ValueA6 = ValueA3 >> 1,\n\
ValueA7 = ValueA3 << 1\n\
};\n\
+ enum EnumB : int {\n\
+ ValueB0 = ~3,\n\
+ };\n\
};\n";
const char* xmlCode = "\
<typesystem package=\"Foo\">\n\
<value-type name='A'>\n\
<enum-type name='EnumA'/>\n\
+ <enum-type name='EnumB'/>\n\
</value-type>\n\
</typesystem>\n";
@@ -298,47 +302,58 @@ void TestEnum::testEnumValueFromExpression()
AbstractMetaEnum* enumA = classA->findEnum(QLatin1String("EnumA"));
QVERIFY(enumA);
+ QVERIFY(!enumA->isSigned());
QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumA"));
AbstractMetaEnumValue* valueA0 = enumA->values().at(0);
QCOMPARE(valueA0->name(), QLatin1String("ValueA0"));
QCOMPARE(valueA0->stringValue(), QLatin1String("3u"));
- QCOMPARE(valueA0->value(), (int) 3u);
+ QCOMPARE(valueA0->value().unsignedValue(), 3u);
AbstractMetaEnumValue* valueA1 = enumA->values().at(1);
QCOMPARE(valueA1->name(), QLatin1String("ValueA1"));
QCOMPARE(valueA1->stringValue(), QLatin1String("~3u"));
- QCOMPARE(valueA1->value(), (int) ~3u);
+ QCOMPARE(valueA1->value().unsignedValue(), ~3u);
AbstractMetaEnumValue* valueA2 = enumA->values().at(2);
QCOMPARE(valueA2->name(), QLatin1String("ValueA2"));
- QCOMPARE(valueA2->stringValue(), QLatin1String("~3"));
- QCOMPARE(valueA2->value(), ~3);
+ QCOMPARE(valueA2->stringValue(), QLatin1String("0xffffffff"));
+ QCOMPARE(valueA2->value().unsignedValue(), 0xffffffffu);
AbstractMetaEnumValue* valueA3 = enumA->values().at(3);
QCOMPARE(valueA3->name(), QLatin1String("ValueA3"));
QCOMPARE(valueA3->stringValue(), QLatin1String("0xf0"));
- QCOMPARE(valueA3->value(), 0xf0);
+ QCOMPARE(valueA3->value().unsignedValue(), 0xf0u);
AbstractMetaEnumValue* valueA4 = enumA->values().at(4);
QCOMPARE(valueA4->name(), QLatin1String("ValueA4"));
QCOMPARE(valueA4->stringValue(), QLatin1String("8 |ValueA3"));
- QCOMPARE(valueA4->value(), 8|0xf0);
+ QCOMPARE(valueA4->value().unsignedValue(), 8|0xf0u);
AbstractMetaEnumValue* valueA5 = enumA->values().at(5);
QCOMPARE(valueA5->name(), QLatin1String("ValueA5"));
QCOMPARE(valueA5->stringValue(), QLatin1String("ValueA3|32"));
- QCOMPARE(valueA5->value(), 0xf0|32);
+ QCOMPARE(valueA5->value().unsignedValue(), 0xf0u|32);
AbstractMetaEnumValue* valueA6 = enumA->values().at(6);
QCOMPARE(valueA6->name(), QLatin1String("ValueA6"));
QCOMPARE(valueA6->stringValue(), QLatin1String("ValueA3 >> 1"));
- QCOMPARE(valueA6->value(), 0xf0 >> 1);
+ QCOMPARE(valueA6->value().unsignedValue(), 0xf0u >> 1);
AbstractMetaEnumValue* valueA7 = enumA->values().at(7);
QCOMPARE(valueA7->name(), QLatin1String("ValueA7"));
QCOMPARE(valueA7->stringValue(), QLatin1String("ValueA3 << 1"));
- QCOMPARE(valueA7->value(), 0xf0 << 1);
+ QCOMPARE(valueA7->value().unsignedValue(), 0xf0u << 1);
+
+ const AbstractMetaEnum *enumB = classA->findEnum(QLatin1String("EnumB"));
+ QVERIFY(enumB);
+ QVERIFY(enumB->isSigned());
+ QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumB"));
+ QCOMPARE(enumB->values().size(), 1);
+ const AbstractMetaEnumValue *valueB0 = enumB->values().at(0);
+ QCOMPARE(valueB0->name(), QLatin1String("ValueB0"));
+ QCOMPARE(valueB0->stringValue(), QLatin1String("~3"));
+ QCOMPARE(valueB0->value().value(), ~3);
}
void TestEnum::testPrivateEnum()
@@ -375,12 +390,12 @@ void TestEnum::testPrivateEnum()
AbstractMetaEnumValue* pub0 = publicEnum->values().first();
QCOMPARE(pub0->name(), QLatin1String("Pub0"));
- QCOMPARE(pub0->value(), 0x0f);
+ QCOMPARE(pub0->value().value(), 0x0f);
QCOMPARE(pub0->stringValue(), QLatin1String("Priv0"));
AbstractMetaEnumValue* pub1 = publicEnum->values().last();
QCOMPARE(pub1->name(), QLatin1String("Pub1"));
- QCOMPARE(pub1->value(), 0xf0);
+ QCOMPARE(pub1->value().value(), 0xf0);
QCOMPARE(pub1->stringValue(), QLatin1String("A::Priv1"));
}
@@ -408,12 +423,12 @@ void TestEnum::testTypedefEnum()
AbstractMetaEnumValue* enumValueA0 = enumA->values().first();
QCOMPARE(enumValueA0->name(), QLatin1String("A0"));
- QCOMPARE(enumValueA0->value(), 0);
+ QCOMPARE(enumValueA0->value().value(), 0);
QCOMPARE(enumValueA0->stringValue(), QLatin1String(""));
AbstractMetaEnumValue* enumValueA1 = enumA->values().last();
QCOMPARE(enumValueA1->name(), QLatin1String("A1"));
- QCOMPARE(enumValueA1->value(), 1);
+ QCOMPARE(enumValueA1->value().value(), 1);
QCOMPARE(enumValueA1->stringValue(), QString());
}
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;
};