aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp58
1 files changed, 47 insertions, 11 deletions
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index 944445579..dd0aca407 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -176,7 +176,8 @@ public:
FunctionModelItem createMemberFunction(const CXCursor &cursor,
bool isTemplateCode = false);
void qualifyConstructor(const CXCursor &cursor);
- TypeInfo createTypeInfoHelper(const CXType &type) const; // uncashed
+ TypeInfo createTypeInfoUncached(const CXType &type,
+ bool *cacheable = nullptr) const;
TypeInfo createTypeInfo(const CXType &type) const;
TypeInfo createTypeInfo(const CXCursor &cursor) const
{ return createTypeInfo(clang_getCursorType(cursor)); }
@@ -186,6 +187,7 @@ public:
bool addTemplateInstantiationsRecursion(const CXType &type, TypeInfo *t) const;
void addTypeDef(const CXCursor &cursor, const CXType &cxType);
+ ClassModelItem currentTemplateClass() const;
void startTemplateTypeAlias(const CXCursor &cursor);
void endTemplateTypeAlias(const CXCursor &typeAliasCursor);
@@ -333,7 +335,7 @@ FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor,
name = fixTypeName(name);
FunctionModelItem result(new _FunctionModelItem(m_model, name));
setFileName(cursor, result.data());
- result->setType(createTypeInfoHelper(clang_getCursorResultType(cursor)));
+ result->setType(createTypeInfo(clang_getCursorResultType(cursor)));
result->setFunctionType(t);
result->setScope(m_scope);
result->setStatic(clang_Cursor_getStorageClass(cursor) == CX_SC_Static);
@@ -415,7 +417,7 @@ TemplateParameterModelItem BuilderPrivate::createTemplateParameter(const CXCurso
TemplateParameterModelItem BuilderPrivate::createNonTypeTemplateParameter(const CXCursor &cursor) const
{
TemplateParameterModelItem result = createTemplateParameter(cursor);
- result->setType(createTypeInfoHelper(clang_getCursorType(cursor)));
+ result->setType(createTypeInfo(clang_getCursorType(cursor)));
return result;
}
@@ -477,7 +479,7 @@ bool BuilderPrivate::addTemplateInstantiationsRecursion(const CXType &type, Type
// of a non-type template (template <int v>).
if (argType.kind == CXType_Invalid)
return false;
- t->addInstantiation(createTypeInfoHelper(argType));
+ t->addInstantiation(createTypeInfoUncached(argType));
}
}
break;
@@ -513,16 +515,19 @@ void BuilderPrivate::addTemplateInstantiations(const CXType &type,
typeName->remove(pos.first, pos.second - pos.first);
}
-TypeInfo BuilderPrivate::createTypeInfoHelper(const CXType &type) const
+TypeInfo BuilderPrivate::createTypeInfoUncached(const CXType &type,
+ bool *cacheable) const
{
if (type.kind == CXType_Pointer) { // Check for function pointers, first.
const CXType pointeeType = clang_getPointeeType(type);
const int argCount = clang_getNumArgTypes(pointeeType);
if (argCount >= 0) {
- TypeInfo result = createTypeInfoHelper(clang_getResultType(pointeeType));
+ TypeInfo result = createTypeInfoUncached(clang_getResultType(pointeeType),
+ cacheable);
result.setFunctionPointer(true);
for (int a = 0; a < argCount; ++a)
- result.addArgument(createTypeInfoHelper(clang_getArgType(pointeeType, unsigned(a))));
+ result.addArgument(createTypeInfoUncached(clang_getArgType(pointeeType, unsigned(a)),
+ cacheable));
return result;
}
}
@@ -562,6 +567,23 @@ TypeInfo BuilderPrivate::createTypeInfoHelper(const CXType &type) const
|| TypeInfo::stripLeadingVolatile(&typeName)) {
}
+ // For typedefs within templates or nested classes within templates (iterators):
+ // "template <class T> class QList { using Value=T; .."
+ // the typedef source is named "type-parameter-0-0". Convert it back to the
+ // template parameter name. The CXTypes are the same for all templates and
+ // must not be cached.
+ if (!m_currentClass.isNull() && typeName.startsWith(QLatin1String("type-parameter-0-"))) {
+ if (cacheable != nullptr)
+ *cacheable = false;
+ bool ok;
+ const int n = QStringView{typeName}.mid(17).toInt(&ok);
+ if (ok) {
+ auto currentTemplate = currentTemplateClass();
+ if (!currentTemplate.isNull() && n < currentTemplate->templateParameters().size())
+ typeName = currentTemplate->templateParameters().at(n)->name();
+ }
+ }
+
// Obtain template instantiations if the name has '<' (thus excluding
// typedefs like "std::string".
if (typeName.contains(QLatin1Char('<')))
@@ -575,10 +597,14 @@ TypeInfo BuilderPrivate::createTypeInfoHelper(const CXType &type) const
TypeInfo BuilderPrivate::createTypeInfo(const CXType &type) const
{
- TypeInfoHash::iterator it = m_typeInfoHash.find(type);
- if (it == m_typeInfoHash.end())
- it = m_typeInfoHash.insert(type, createTypeInfoHelper(type));
- return it.value();
+ const auto it = m_typeInfoHash.constFind(type);
+ if (it != m_typeInfoHash.constEnd())
+ return it.value();
+ bool cacheable = true;
+ TypeInfo result = createTypeInfoUncached(type, &cacheable);
+ if (cacheable)
+ m_typeInfoHash.insert(type, result);
+ return result;
}
void BuilderPrivate::addTypeDef(const CXCursor &cursor, const CXType &cxType)
@@ -592,6 +618,16 @@ void BuilderPrivate::addTypeDef(const CXCursor &cursor, const CXType &cxType)
m_cursorTypedefHash.insert(cursor, item);
}
+ClassModelItem BuilderPrivate::currentTemplateClass() const
+{
+ for (int i = m_scopeStack.size() - 1; i >= 0; --i) {
+ auto klass = qSharedPointerDynamicCast<_ClassModelItem>(m_scopeStack.at(i));
+ if (!klass.isNull() && klass->isTemplate())
+ return klass;
+ }
+ return {};
+}
+
void BuilderPrivate::startTemplateTypeAlias(const CXCursor &cursor)
{
const QString target = getCursorSpelling(cursor);