diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index c0e54ee8..964fbe9c 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -717,7 +717,7 @@ private void VisitFunctionDecl(FunctionDecl functionDecl) { outputBuilder.Write("Base"); } - + outputBuilder.Write('.'); outputBuilder.Write(name); outputBuilder.Write('('); @@ -1817,7 +1817,11 @@ private void VisitRecordDecl(RecordDecl recordDecl) { var cxxDestructorDecl = cxxRecordDecl.Destructor; - if (!cxxDestructorDecl.IsVirtual && !IsExcluded(cxxDestructorDecl)) + if (cxxDestructorDecl == null) + { + AddDiagnostic(DiagnosticLevel.Warning, "Record has user declared destructor, but Destructor property was null. Generated bindings may be incomplete.", cxxRecordDecl); + } + else if (!cxxDestructorDecl.IsVirtual && !IsExcluded(cxxDestructorDecl)) { Visit(cxxDestructorDecl); _outputBuilder.WriteDivider(); diff --git a/sources/ClangSharp/Cursors/Decls/CXXRecordDecl.cs b/sources/ClangSharp/Cursors/Decls/CXXRecordDecl.cs index 3faaea16..41915f62 100644 --- a/sources/ClangSharp/Cursors/Decls/CXXRecordDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/CXXRecordDecl.cs @@ -14,7 +14,7 @@ public class CXXRecordDecl : RecordDecl private readonly Lazy> _ctors; private readonly Lazy _dependentLambdaCallOperator; private readonly Lazy _describedClassTemplate; - private readonly Lazy _destructor; + private readonly Lazy _destructor; private readonly Lazy> _friends; private readonly Lazy _instantiatedFromMemberClass; private readonly Lazy _lambdaCallOperator; @@ -63,7 +63,10 @@ private protected CXXRecordDecl(CXCursor handle, CXCursorKind expectedCursorKind _dependentLambdaCallOperator = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DependentLambdaCallOperator)); _describedClassTemplate = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DescribedCursorTemplate)); - _destructor = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Destructor)); + _destructor = new Lazy(() => { + CXCursor destructor = Handle.Destructor; + return destructor.IsNull ? null : TranslationUnit.GetOrCreate(Handle.Destructor); + }); _friends = new Lazy>(() => { var numFriends = Handle.NumFriends; @@ -126,7 +129,7 @@ private protected CXXRecordDecl(CXCursor handle, CXCursorKind expectedCursorKind public ClassTemplateDecl DescribedClassTemplate => _describedClassTemplate.Value; - public CXXDestructorDecl Destructor => _destructor.Value; + public CXXDestructorDecl? Destructor => _destructor.Value; public IReadOnlyList Friends => _friends.Value; diff --git a/sources/libClangSharp/ClangSharp.cpp b/sources/libClangSharp/ClangSharp.cpp index 605c1490..02c76f2d 100644 --- a/sources/libClangSharp/ClangSharp.cpp +++ b/sources/libClangSharp/ClangSharp.cpp @@ -2813,6 +2813,11 @@ CXCursor clangsharp_Cursor_getLambdaStaticInvoker(CXCursor C) { const Decl* D = getCursorDecl(C); if (const CXXRecordDecl* CRD = dyn_cast(D)) { + CXXMethodDecl *CallOp = CRD->getLambdaCallOperator(); + // Work around a Clang bug: CRD->getLambdaStaticInvoker will crash if getLambdaCallOperator returns null. + if (CallOp == nullptr) { + return clang_getNullCursor(); + } return MakeCXCursor(CRD->getLambdaStaticInvoker(), getCursorTU(C)); } } @@ -3088,6 +3093,9 @@ int clangsharp_Cursor_getNumAssociatedConstraints(CXCursor C) { int clangsharp_Cursor_getNumAttrs(CXCursor C) { if (isDeclOrTU(C.kind)) { const Decl* D = getCursorDecl(C); + if (!D->hasAttrs()) { + return 0; + } return D->getAttrs().size(); }