aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp')
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp31
1 files changed, 24 insertions, 7 deletions
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
index dd0aca407..a90adca17 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
@@ -230,6 +230,7 @@ public:
int m_anonymousEnumCount = 0;
CodeModel::FunctionType m_currentFunctionType = CodeModel::Normal;
+ bool m_withinFriendDecl = false;
};
bool BuilderPrivate::addClass(const CXCursor &cursor, CodeModel::ClassType t)
@@ -964,14 +965,14 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
case CXCursor_ClassDecl:
case CXCursor_UnionDecl:
case CXCursor_StructDecl:
- if (clang_isCursorDefinition(cursor) == 0)
+ if (d->m_withinFriendDecl || clang_isCursorDefinition(cursor) == 0)
return Skip;
if (!d->addClass(cursor, codeModelClassTypeFromCursor(cursor.kind)))
return Error;
break;
case CXCursor_ClassTemplate:
case CXCursor_ClassTemplatePartialSpecialization:
- if (clang_isCursorDefinition(cursor) == 0)
+ if (d->m_withinFriendDecl || clang_isCursorDefinition(cursor) == 0)
return Skip;
d->addClass(cursor, CodeModel::Class);
d->m_currentClass->setName(d->m_currentClass->name() + templateBrackets());
@@ -1028,16 +1029,18 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
case CXCursor_FieldDecl:
d->addField(cursor);
break;
-#if CINDEX_VERSION_MAJOR > 0 || CINDEX_VERSION_MINOR >= 37 // Clang 4.0
case CXCursor_FriendDecl:
+ d->m_withinFriendDecl = true;
+ break;
+ case CXCursor_CompoundStmt: // Function bodies
return Skip;
-#endif
case CXCursor_Constructor:
case CXCursor_Destructor: // Note: Also use clang_CXXConstructor_is..Constructor?
case CXCursor_CXXMethod:
case CXCursor_ConversionFunction:
+ // Member functions of other classes can be declared to be friends.
// Skip inline member functions outside class, only go by declarations inside class
- if (!withinClassDeclaration(cursor))
+ if (d->m_withinFriendDecl || !withinClassDeclaration(cursor))
return Skip;
d->m_currentFunction = d->createMemberFunction(cursor, false);
d->m_scopeStack.back()->addFunction(d->m_currentFunction);
@@ -1059,8 +1062,19 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
d->m_scopeStack.back()->addFunction(d->m_currentFunction);
break;
case CXCursor_FunctionDecl:
- d->m_currentFunction = d->createFunction(cursor, CodeModel::Normal, false);
- d->m_scopeStack.back()->addFunction(d->m_currentFunction);
+ // Free functions or functions completely defined within "friend" (class
+ // operators). Note: CXTranslationUnit_SkipFunctionBodies must be off for
+ // clang_isCursorDefinition() to work here.
+ if (!d->m_withinFriendDecl || clang_isCursorDefinition(cursor) != 0) {
+ int scope = d->m_scopeStack.size() - 1; // enclosing class
+ if (d->m_withinFriendDecl) {
+ // Friend declaration: go back to namespace or file scope.
+ for (--scope; d->m_scopeStack.at(scope)->kind() == _CodeModelItem::Kind_Class; --scope) {
+ }
+ }
+ d->m_currentFunction = d->createFunction(cursor, CodeModel::Normal, false);
+ d->m_scopeStack.at(scope)->addFunction(d->m_currentFunction);
+ }
break;
case CXCursor_Namespace: {
const auto type = namespaceType(cursor);
@@ -1212,6 +1226,9 @@ bool Builder::endToken(const CXCursor &cursor)
d->m_scopeStack.back()->addEnum(d->m_currentEnum);
d->m_currentEnum.clear();
break;
+ case CXCursor_FriendDecl:
+ d->m_withinFriendDecl = false;
+ break;
case CXCursor_VarDecl:
case CXCursor_FieldDecl:
d->m_currentField.clear();