[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