diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-04-26 08:03:54 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-04-26 08:04:41 +0200 |
commit | 9b01aae7777c7ccde9eed1a8c55aead1524e00e5 (patch) | |
tree | c62834ca412f290485dd96d2a7522809b8fce6e1 /sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp | |
parent | 2156651b39fbb6717ed936c94dcd28295436e0a4 (diff) | |
parent | 0b842db3a95a44fbda3379d2093cb52f8ae2a1ff (diff) |
Merge remote-tracking branch 'origin/5.9' into 5.11
Change-Id: Id40dab17b02800199f70072115d7473041f683d8
Diffstat (limited to 'sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp')
-rw-r--r-- | sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp | 72 |
1 files changed, 68 insertions, 4 deletions
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; |