[cfe-dev] Code completion

Douglas Gregor dgregor at apple.com
Mon Nov 29 08:16:12 PST 2010


On Nov 25, 2010, at 6:39 AM, Paul Curtis wrote:

> Hi All,
> 
> I'm trying to get libclang to perform code completion on an in-memory
> buffer, but without much success.  I'm using the wavefront clang sources;
> there are a couple of issues.  Here's the first, which is a plain crash.
> 
> I can illustrate the problem I'm having just using c-index-test without any
> of my code involved.  Here's the contents of "bar.c" in the current
> directory:
> 
> struct { int x; int y; void (*fn)(void); } str;
> 
> void foo(void)
> {
>  str.
> }
> 
> I'm going to complete at the ".".  Invoking c-index-test works just find in
> plain-vanilla guise:
> 
>> c-index-test -code-completion-at=bar.c:5:7 bar.c  -I.
> FieldDecl:{ResultType void (*)(void)}{TypedText fn} (35)
> FieldDecl:{ResultType int}{TypedText x} (35)
> FieldDecl:{ResultType int}{TypedText y} (35)
> 
> Now, I want to use -remap-file so that bar.c is compiled as "foo.c".  Ok,
> just fine:
> 
>> c-index-test -code-completion-at=foo.c:5:7 -remap-file=foo.c;bar.c foo.c
> -I.
> FieldDecl:{ResultType void (*)(void)}{TypedText fn} (35)
> FieldDecl:{ResultType int}{TypedText x} (35)
> FieldDecl:{ResultType int}{TypedText y} (35)
> 
> How about mapping bar.c to /tmp/foo.c?
> 
>> c-index-test -code-completion-at=foo.c:5:7 -remap-file=/tmp/foo.c;bar.c
> /tmp/foo.c  -I.
> 
> Ahh, now we have a crash with a problematic delete.  :-(
> 
> The problem seems to be that in ASTUnit.cpp there is:
> 
>  // Use the code completion consumer we were given, but adding any cached
>  // code-completion results.
>  AugmentedCodeCompleteConsumer 
>  AugmentedConsumer(*this, Consumer,
> FrontendOpts.ShowMacrosInCodeCompletion,
>                    FrontendOpts.ShowCodePatternsInCodeCompletion,
>                    FrontendOpts.ShowGlobalSymbolsInCodeCompletion);
>  Clang.setCodeCompletionConsumer(&AugmentedConsumer);
> 
> ...and in CompilerInstance.cpp this does:
> 
> void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer
> *Value) {
>  CompletionConsumer.reset(Value);
> }
> 
> What the OwnedPointer is now marshalling is a stack-allocated local which
> causes real problems when CompilerInstance::createCodeCompletionConsumer()
> calls CompletionConsumer.reset() in the else branch of its first if.  If the
> stack-allocated local is replaced with a new then we're all sweet again as
> there's no delete of the stack-allocated local.


Thanks for tracking this down! Fixed in Clang r120290.

	- Doug



More information about the cfe-dev mailing list