[cfe-dev] Code completion

Paul Curtis plc at rowley.co.uk
Thu Nov 25 06:39:17 PST 2010


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.

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

--
Paul Curtis, Rowley Associates Ltd   http://www.rowley.co.uk
SolderCore arriving Winter 2010!   http://www.soldercore.com







More information about the cfe-dev mailing list