jkorous-apple added a comment. Sorry for delays, I'm working on this on and off when there's nothing more important.
Let me specify a little narrower scope of this change: - Make code completion contain constructor item for out-of-line constructor definition: struct foo { foo(); }; foo::<CODE_COMPLETE> // result should contain constructor foo() I would rather leave issues with destructors for other patch. I haven't previously realized issue with initialization you mentioned and there are other cases where completing after id qualified with class prefix shouldn't end up containing constructors (e. g. typedef foo::some_embedded_type bar;) I assume the proper way is to add constructors to code completion results only in these contexts: - http://nongnu.org/hcb/#translation-unit - http://nongnu.org/hcb/#declaration-seq - http://nongnu.org/hcb/#declaration - http://nongnu.org/hcb/#function-definition - CODE_COMPLETE_CTOR - http://nongnu.org/hcb/#namespace-definition - http://nongnu.org/hcb/#named-namespace-definition - http://nongnu.org/hcb/#original-namespace-definition | http://nongnu.org/hcb/#extension-namespace-definition - http://nongnu.org/hcb/#namespace-body - http://nongnu.org/hcb/#declaration-seq - ... - CODE_COMPLETE_CTOR - http://nongnu.org/hcb/#unnamed-namespace-definition - http://nongnu.org/hcb/#namespace-body - http://nongnu.org/hcb/#declaration-seq - ... - CODE_COMPLETE_CTOR Which I think is equivalent to saying that the only parent nodes in ASTContext should either be NamespaceDecl or TranslationUnitDecl. If you think my assumptions are wrong here please let me know. Basically I need to distinguish between this callstack (foo::<CODE_COMPLETE>) * frame #0: 0x000000010bab9e7e libclang.dylib` clang::Sema::CodeCompleteQualifiedId(this=0x000000011d8b3a00, S=0x000000011d736fe0, SS=0x0000700008072538, EnteringContext=true, AddCtorsToResult=false) + 46 at SemaCodeComplete.cpp:4550 frame #1: 0x000000010f9a8343 libclang.dylib` clang::Parser::ParseOptionalCXXScopeSpecifier(this=0x000000011d8b7a00, SS=0x0000700008072538, ObjectType=(Ptr = 0x0000000000000000), EnteringContext=true, MayBePseudoDestructor=0x0000000000000000, IsTypename=false, LastII=0x0000000000000000, OnlyNamespace=false) + 1987 at ParseExprCXX.cpp:253 frame #2: 0x000000010fa34d69 libclang.dylib` clang::Parser::TryAnnotateCXXScopeToken(this=0x000000011d8b7a00, EnteringContext=true) + 457 at Parser.cpp:1861 frame #3: 0x000000010f9466d7 libclang.dylib` clang::Parser::ParseDeclarationSpecifiers(this=0x000000011d8b7a00, DS=0x0000700008073738, TemplateInfo=0x0000700008073668, AS=AS_none, DSContext=DSC_top_level, LateAttrs=0x0000000000000000) + 5111 at ParseDecl.cpp:3224 frame #4: 0x000000010fa2f63b libclang.dylib` clang::Parser::ParseDeclOrFunctionDefInternal(this=0x000000011d8b7a00, attrs=0x0000700008073d08, DS=0x0000700008073738, AS=AS_none) + 139 at Parser.cpp:922 frame #5: 0x000000010fa2f152 libclang.dylib` clang::Parser::ParseDeclarationOrFunctionDefinition(this=0x000000011d8b7a00, attrs=0x0000700008073d08, DS=0x0000000000000000, AS=AS_none) + 194 at Parser.cpp:1003 frame #6: 0x000000010fa2e27f libclang.dylib` clang::Parser::ParseExternalDeclaration(this=0x000000011d8b7a00, attrs=0x0000700008073d08, DS=0x0000000000000000) + 3599 at Parser.cpp:853 frame #7: 0x000000010f965a38 libclang.dylib` clang::Parser::ParseInnerNamespace(this=0x000000011d8b7a00, IdentLoc=size=1, Ident=size=1, NamespaceLoc=size=1, index=0, InlineLoc=0x00007000080743b8, attrs=0x0000700008074300, Tracker=0x00007000080741c0) + 312 at ParseDeclCXX.cpp:221 frame #8: 0x000000010f9651a4 libclang.dylib` clang::Parser::ParseNamespace(this=0x000000011d8b7a00, Context=0, DeclEnd=0x0000700008074e38, InlineLoc=(ID = 0)) + 8180 at ParseDeclCXX.cpp:196 frame #9: 0x000000010f944d59 libclang.dylib` clang::Parser::ParseDeclaration(this=0x000000011d8b7a00, Context=0, DeclEnd=0x0000700008074e38, attrs=0x0000700008075030) + 505 at ParseDecl.cpp:1727 frame #10: 0x000000010fa2ddc2 libclang.dylib` clang::Parser::ParseExternalDeclaration(this=0x000000011d8b7a00, attrs=0x0000700008075030, DS=0x0000000000000000) + 2386 at Parser.cpp:786 frame #11: 0x000000010fa2cab8 libclang.dylib` clang::Parser::ParseTopLevelDecl(this=0x000000011d8b7a00, Result=0x0000700008075190) + 1240 at Parser.cpp:621 frame #12: 0x000000010f92d143 libclang.dylib` clang::ParseAST(S=0x000000011d8b3a00, PrintStats=false, SkipFunctionBodies=false) + 963 at ParseAST.cpp:147 frame #13: 0x000000010b5bb755 libclang.dylib` clang::ASTFrontendAction::ExecuteAction(this=0x000000011d720de0) + 485 at FrontendAction.cpp:1005 frame #14: 0x000000010b5ba630 libclang.dylib` clang::FrontendAction::Execute(this=0x000000011d720de0) + 112 at FrontendAction.cpp:904 frame #15: 0x000000010b4962fb libclang.dylib` clang::ASTUnit::CodeComplete(this=0x000000011f001200, File=(Data = "/Users/jankorous/src/issues/ctor-dtor-autocomplete/test-ctor-dtor-completion/test-ctor-dtor-completion/main.cpp", Length = 111), Line=34, Column=8, RemappedFiles=ArrayRef<std::__1::pair<std::__1::basic_string<char>, llvm::MemoryBuffer *> > @ 0x0000700008076640, IncludeMacros=true, IncludeCodePatterns=false, IncludeBriefComments=false, Consumer=0x0000700008076b78, PCHContainerOps=std::__1::shared_ptr<clang::PCHContainerOperations>::element_type @ 0x000000011d720978 strong=3 weak=1, Diag=0x000000011d8a1a00, LangOpts=0x000000011d862f90, SourceMgr=0x000000011d72a950, FileMgr=0x000000011d722880, StoredDiagnostics=0x000000011d862c10, OwnedBuffers=0x000000011d863130) + 9259 at ASTUnit.cpp:2209 frame #16: 0x000000010aa8e29a libclang.dylib` clang_codeCompleteAt_Impl(TU=0x000000011d721d80, complete_filename="/Users/jankorous/src/issues/ctor-dtor-autocomplete/test-ctor-dtor-completion/test-ctor-dtor-completion/main.cpp", complete_line=34, complete_column=8, unsaved_files=ArrayRef<CXUnsavedFile> @ 0x00007000080768d8, options=1) + 2746 at CIndexCodeCompletion.cpp:694 frame #17: 0x000000010aa8cade libclang.dylib` clang_codeCompleteAt::$_0::operator(this=0x0000700007873bc0)() const + 126 at CIndexCodeCompletion.cpp:804 frame #18: 0x000000010aa93f65 libclang.dylib` void llvm::function_ref<void ()>::callback_fn<clang_codeCompleteAt::$_0>(callable=123145428614080) + 21 at STLExtras.h:96 frame #19: 0x000000010ebf34a9 libclang.dylib` llvm::function_ref<void ()>::operator(this=0x0000700008076e78)() const + 25 at STLExtras.h:111 frame #20: 0x000000010ebf344d libclang.dylib` llvm::CrashRecoveryContext::RunSafely(this=0x0000700007873bb0, Fn=function_ref<void ()> @ 0x0000700008076e78)>) + 221 at CrashRecoveryContext.cpp:359 frame #21: 0x000000010ebf36ff libclang.dylib` RunSafelyOnThread_Dispatch(UserData=0x0000700007873ab0) + 79 at CrashRecoveryContext.cpp:402 frame #22: 0x000000010ed2bb10 libclang.dylib` ExecuteOnThread_Dispatch(Arg=0x0000700007873a20) + 48 at Threading.inc:53 frame #23: 0x00007fff6c83c6c1 libsystem_pthread.dylib` _pthread_body + 340 frame #24: 0x00007fff6c83c56d libsystem_pthread.dylib` _pthread_start + 377 frame #25: 0x00007fff6c83bc5d libsystem_pthread.dylib` thread_start + 13 and this callstack which is initialization (int x = foo::<CODE_COMPLETE>): * frame #0: 0x000000010bab9e7e libclang.dylib` clang::Sema::CodeCompleteQualifiedId(this=0x000000011f80dc00, S=0x000000011e10c940, SS=0x000070000c556838, EnteringContext=false, AddCtorsToResult=false) + 46 at SemaCodeComplete.cpp:4550 frame #1: 0x000000010f9a8343 libclang.dylib` clang::Parser::ParseOptionalCXXScopeSpecifier(this=0x000000011f844800, SS=0x000070000c556838, ObjectType=(Ptr = 0x0000000000000000), EnteringContext=false, MayBePseudoDestructor=0x0000000000000000, IsTypename=false, LastII=0x0000000000000000, OnlyNamespace=false) + 1987 at ParseExprCXX.cpp:253 frame #2: 0x000000010fa34ac2 libclang.dylib` clang::Parser::TryAnnotateTypeOrScopeToken(this=0x000000011f844800) + 2610 at Parser.cpp:1736 frame #3: 0x000000010f999e46 libclang.dylib` clang::Parser::ParseCastExpression(this=0x000000011f844800, isUnaryExpression=false, isAddressOfOperand=false, NotCastExpr=0x000070000c559646, isTypeCast=NotTypeCast, isVectorLiteral=false) + 14582 at ParseExpr.cpp:921 frame #4: 0x000000010f993de5 libclang.dylib` clang::Parser::ParseCastExpression(this=0x000000011f844800, isUnaryExpression=false, isAddressOfOperand=false, isTypeCast=NotTypeCast, isVectorLiteral=false) + 101 at ParseExpr.cpp:521 frame #5: 0x000000010f992263 libclang.dylib` clang::Parser::ParseAssignmentExpression(this=0x000000011f844800, isTypeCast=NotTypeCast) + 243 at ParseExpr.cpp:168 frame #6: 0x000000010f976980 libclang.dylib` clang::Parser::ParseInitializer(this=0x000000011f844800) + 64 at Parser.h:1684 frame #7: 0x000000010f94d233 libclang.dylib` clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(this=0x000000011f844800, D=0x000070000c55a1c8, TemplateInfo=0x000070000c559f38, FRI=0x0000000000000000) + 2323 at ParseDecl.cpp:2302 frame #8: 0x000000010f94b14e libclang.dylib` clang::Parser::ParseDeclGroup(this=0x000000011f844800, DS=0x000070000c55aab8, Context=0, DeclEnd=0x0000000000000000, FRI=0x0000000000000000) + 2174 at ParseDecl.cpp:2064 frame #9: 0x000000010fa2fb18 libclang.dylib` clang::Parser::ParseDeclOrFunctionDefInternal(this=0x000000011f844800, attrs=0x000070000c55b030, DS=0x000070000c55aab8, AS=AS_none) + 1384 at Parser.cpp:987 frame #10: 0x000000010fa2f152 libclang.dylib` clang::Parser::ParseDeclarationOrFunctionDefinition(this=0x000000011f844800, attrs=0x000070000c55b030, DS=0x0000000000000000, AS=AS_none) + 194 at Parser.cpp:1003 frame #11: 0x000000010fa2e27f libclang.dylib` clang::Parser::ParseExternalDeclaration(this=0x000000011f844800, attrs=0x000070000c55b030, DS=0x0000000000000000) + 3599 at Parser.cpp:853 frame #12: 0x000000010fa2cab8 libclang.dylib` clang::Parser::ParseTopLevelDecl(this=0x000000011f844800, Result=0x000070000c55b190) + 1240 at Parser.cpp:621 frame #13: 0x000000010f92d143 libclang.dylib` clang::ParseAST(S=0x000000011f80dc00, PrintStats=false, SkipFunctionBodies=false) + 963 at ParseAST.cpp:147 frame #14: 0x000000010b5bb755 libclang.dylib` clang::ASTFrontendAction::ExecuteAction(this=0x000000011e1038a0) + 485 at FrontendAction.cpp:1005 frame #15: 0x000000010b5ba630 libclang.dylib` clang::FrontendAction::Execute(this=0x000000011e1038a0) + 112 at FrontendAction.cpp:904 frame #16: 0x000000010b4962fb libclang.dylib` clang::ASTUnit::CodeComplete(this=0x000000011f801200, File=(Data = "/Users/jankorous/src/issues/ctor-dtor-autocomplete/test-ctor-dtor-completion/test-ctor-dtor-completion/main.cpp", Length = 111), Line=52, Column=14, RemappedFiles=ArrayRef<std::__1::pair<std::__1::basic_string<char>, llvm::MemoryBuffer *> > @ 0x000070000c55c640, IncludeMacros=true, IncludeCodePatterns=false, IncludeBriefComments=false, Consumer=0x000070000c55cb78, PCHContainerOps=std::__1::shared_ptr<clang::PCHContainerOperations>::element_type @ 0x000000011e020a08 strong=3 weak=1, Diag=0x000000011f801a00, LangOpts=0x000000011f800f90, SourceMgr=0x000000011e1000f0, FileMgr=0x000000011e023640, StoredDiagnostics=0x000000011f800c10, OwnedBuffers=0x000000011f801130) + 9259 at ASTUnit.cpp:2209 frame #17: 0x000000010aa8e29a libclang.dylib` clang_codeCompleteAt_Impl(TU=0x000000011e020db0, complete_filename="/Users/jankorous/src/issues/ctor-dtor-autocomplete/test-ctor-dtor-completion/test-ctor-dtor-completion/main.cpp", complete_line=52, complete_column=14, unsaved_files=ArrayRef<CXUnsavedFile> @ 0x000070000c55c8d8, options=1) + 2746 at CIndexCodeCompletion.cpp:694 frame #18: 0x000000010aa8cade libclang.dylib` clang_codeCompleteAt::$_0::operator(this=0x000070000bd59bc0)() const + 126 at CIndexCodeCompletion.cpp:804 frame #19: 0x000000010aa93f65 libclang.dylib` void llvm::function_ref<void ()>::callback_fn<clang_codeCompleteAt::$_0>(callable=123145500859328) + 21 at STLExtras.h:96 frame #20: 0x000000010ebf34a9 libclang.dylib` llvm::function_ref<void ()>::operator(this=0x000070000c55ce78)() const + 25 at STLExtras.h:111 frame #21: 0x000000010ebf344d libclang.dylib` llvm::CrashRecoveryContext::RunSafely(this=0x000070000bd59bb0, Fn=function_ref<void ()> @ 0x000070000c55ce78)>) + 221 at CrashRecoveryContext.cpp:359 frame #22: 0x000000010ebf36ff libclang.dylib` RunSafelyOnThread_Dispatch(UserData=0x000070000bd59ab0) + 79 at CrashRecoveryContext.cpp:402 frame #23: 0x000000010ed2bb10 libclang.dylib` ExecuteOnThread_Dispatch(Arg=0x000070000bd59a20) + 48 at Threading.inc:53 frame #24: 0x00007fff6c83c6c1 libsystem_pthread.dylib` _pthread_body + 340 frame #25: 0x00007fff6c83c56d libsystem_pthread.dylib` _pthread_start + 377 frame #26: 0x00007fff6c83bc5d libsystem_pthread.dylib` thread_start + 13 I tried using ASTContext::getParents() but for some reason I never get any parents for my Decl node. if (isa<CXXConstructorDecl>(R.Declaration)) { assert(CurContext != nullptr && "Code completion result builder should be provided with non-null CurContext"); const Decl* const CurContextDecl = dyn_cast<Decl>(CurContext); if (CurContextDecl == nullptr) return; const auto ParentNodes = CurContext->getParentASTContext().getParents(*CurContextDecl); for(const auto ParentNode : ParentNodes) { const Decl* const ParentDecl = ParentNode.get<Decl>(); if( ParentDecl == nullptr || ( !isa<TranslationUnitDecl>(ParentDecl) && !isa<NamespaceDecl>(ParentDecl) && !isa<CXXConstructorDecl>(ParentDecl) ) ) return; } } I am currently looking into how and when is actually ASTContext produced and into getParents() and ParentMapASTVisitor implementation but have no idea what's wrong yet. https://reviews.llvm.org/D39730 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits