Golevka / emacs-clang-complete-async

An emacs plugin to complete C and C++ code using libclang
360 stars 71 forks source link

Overloaded functions are completed to duplicates #39

Open elemakil opened 11 years ago

elemakil commented 11 years ago

Hey,

If I use ac-clang-async to complete member functions which have different signatures, the function name gets inserted twice. I think its best to show you the problem using images:

First Step: Completion menu shows all member function and also that the function has three signatures.

Step 01

Second Step: I have hit ret and the function's base name is inserted, now I'm selecting the function signature. At this step the function's name is already inserted twice.

Step 02

Third Step: I accept the completion candidate (hitting ret) and the malformatted function was inserted.

Step 03

toojays commented 11 years ago

It would be useful to know which revision of emacs-clang-complete-async this occurred with, and which version of clang it is built against.

Can you reproduce it with a simpler example (e.g. std::vector::assign())?

toojays commented 11 years ago

I can reproduce something like this now. In my case, it's is not because the functions are overloaded, but that they are initially defined in a base class, then overridden. This causes clang to output extra information about where the function was declared. Then auto-complete-clang.el incorrectly parses this information, which leads to the incorrect expansion you see.

I initially ran into my case when trying to expand std::domain_error::what(). Here's a small self-contained example to reproduce the problem.

class Interface
{
    virtual const char *what () const throw () = 0;
};

class Implementation : public Interface
{
    const char *what () const throw () { return "What?"; }
};

class Derived : public Implementation
{
    const char *something_else (int x);
};

int main (void)
{
    Derived obj;

    obj.|
}

The | shows where to put the cursor to reproduce the issue. At this point, the completion options include what and something_else. something_else completes as expected, but selecting what expands it to what:what() const, which matches the behaviour reported in this issue.

Looking in the `clang-complete buffer, the returned results for the two methods of interest here:

COMPLETION: something_else : [#const char *#]something_else(<#int x#>)
COMPLETION: what : [#const char *#]Implementation::what() const
COMPLETION: what : [#const char *#]Interface::what() const

We can see that the results for what include the class where they were declared, while the result for something_else does not. This makes a difference in the elisp function ac-clang-action, because what is getting picked up by the first string-match condition, rather than the second. This leads to us incorrectly deciding that the argument list is :what() instead of ().

Looking through the history, this first condition was originally added in hara/auto-complete-clang@4939442 then merged into this project in Golevka/emacs-clang-complete-async@3176ea3b.

I've added a trivial workaround for this in toojays/emacs-clang-complete-async@229e5ba.

@elemakil, does this fix the problem you are seeing?

elemakil commented 11 years ago

@toojays Indeed, this seems to fix it. Can we expect that this fix gets merged into @Golevka 's repository or should I use yours instead?

toojays commented 11 years ago

Can we expect that this fix gets merged into @Golevka 's repository or should I use yours instead?

I've submitted a pull request for this fix as #43. I imagine a fix will eventually be merged in some form but that's up to @Golevka.