Code completion

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. :frowning:

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.

Of course, this is my first foray into clang, so I may well be talking
complete nonsense.

Thanks for tracking this down! Fixed in Clang r120290.

  - Doug

Hi Doug,

Thanks for tracking this down! Fixed in Clang r120290.

No worries. Currently I'm in rapture integrating clang's code completion
into an IDE for embedded development to see whether it's feasible. I'm
poking around with what clang can do and am seriously impressed with the
ease of use and pretty good flexibility of the Index API. Sure, you can see
exactly how the clang Index API knits into XCode 4, and it's really sweet.
:slight_smile: