[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