xavierd / clang_complete

Vim plugin that use clang for completing C/C++ code.
http://www.vim.org/scripts/script.php?script_id=3302
1.95k stars 308 forks source link

Seems not working well in Linux kernel #272

Closed Kelvin-Ng closed 11 years ago

Kelvin-Ng commented 11 years ago

Here is a great challenge that I want to try this with Linux kernel. It does not work well with it. It may because clang cannot compile the kernel properly.

For example, in fs/ext4/inode.c, in the function ext4_inode_csum, you can see that there is a line csum_lo = raw->i_checksum_lo;. It shows that raw has a member called i_checksum_lo. Unfortunately, the autocomplete does not show i_checksum_lo.

Looking at the declaration of ext4_inode, I found that there is NO member i_checksum_lo. But the source code really use csum_lo = raw->i_checksum_lo;. What's wrong with this?

tobiasgrosser commented 11 years ago

On 02/12/2013 10:05 AM, Kelvin Ng wrote:

Here is a great challenge that I want to try this with Linux kernel. It does not work well with it. It may because clang cannot compile the kernel properly.

For example, in fs/ext4/inode.c, in the function ext4_inode_csum, you can see that there is a line csum_lo = raw->i_checksum_lo;. It shows that raw has a member called i_checksum_lo. Unfortunately, the autocomplete does not show i_checksum_lo.

Looking at the declaration of ext4_inode, I found that there is really the member i_checksum_lo. Although there is a known issue that it does not support macro well, it is not in macro. What's wrong with this? (There are still some more examples)

This problem does not seem to be specific to clang_complete, but it is rather a generic clang completion problem.

Please enable g:clang_debug=1 and type ":mess" after having performed the completion. This will provide you with a command line that will allow you to reproduce the same completion with the clang binary. If this completion does not yield the expected result, please open a bug report in the clang bug database.

Tobias

Kelvin-Ng commented 11 years ago

@tobig It seems that this is some sort of gcc extension. Actually, the definition of ext4_inode is:

struct ext4_inode {
    __le16  i_mode;     /* File mode */
    __le16  i_uid;      /* Low 16 bits of Owner Uid */
    __le32  i_size_lo;  /* Size in bytes */
    __le32  i_atime;    /* Access time */
    __le32  i_ctime;    /* Inode Change time */
    __le32  i_mtime;    /* Modification time */
    __le32  i_dtime;    /* Deletion Time */
    __le16  i_gid;      /* Low 16 bits of Group Id */
    __le16  i_links_count;  /* Links count */
    __le32  i_blocks_lo;    /* Blocks count */
    __le32  i_flags;    /* File flags */
    union {
        struct {
            __le32  l_i_version;
        } linux1;
        struct {
            __u32  h_i_translator;
        } hurd1;
        struct {
            __u32  m_i_reserved1;
        } masix1;
    } osd1;             /* OS dependent 1 */
    __le32  i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
    __le32  i_generation;   /* File version (for NFS) */
    __le32  i_file_acl_lo;  /* File ACL */
    __le32  i_size_high;
    __le32  i_obso_faddr;   /* Obsoleted fragment address */
    union {
        struct {
            __le16  l_i_blocks_high; /* were l_i_reserved1 */
            __le16  l_i_file_acl_high;
            __le16  l_i_uid_high;   /* these 2 fields */
            __le16  l_i_gid_high;   /* were reserved2[0] */
            __le16  l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
            __le16  l_i_reserved;
        } linux2;
        struct {
            __le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
            __u16   h_i_mode_high;
            __u16   h_i_uid_high;
            __u16   h_i_gid_high;
            __u32   h_i_author;
        } hurd2;
        struct {
            __le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
            __le16  m_i_file_acl_high;
            __u32   m_i_reserved2[2];
        } masix2;
    } osd2;             /* OS dependent 2 */
    __le16  i_extra_isize;
    __le16  i_checksum_hi;  /* crc32c(uuid+inum+inode) BE */
    __le32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */
    __le32  i_mtime_extra;  /* extra Modification time(nsec << 2 | epoch) */
    __le32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */
    __le32  i_crtime;       /* File Creation time */
    __le32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
    __le32  i_version_hi;   /* high 32 bits for 64-bit version */
};

So, it is not normal that clang support it.

tobiasgrosser commented 11 years ago

On 02/12/2013 10:45 AM, Kelvin Ng wrote:

@tobig It seems that this is some sort of gcc extension. Actually, the definition of ext4_inode is:

[..] A lot of code.

So, it is not normal that clang support it.

clang is certainly aiming at supporting the linux kernel. However, to report such bugs clang_complete is the wrong place. Please open a bug report with a minimal test case in the clang bug tracker. Chances are high that it gets fixed.

Tobi

Kelvin-Ng commented 11 years ago

@tobig

I actually don't know how gcc can support such kind of syntax so I don't know how to create a test case. Anyway, I will try to report this bug in a right place.

Kelvin-Ng commented 11 years ago

I think I have missed something... Here is a macro #define i_checksum_lo osd2.linux2.l_i_checksum_lo so I understand what have happened (This is in #if defined(__KERNEL__) || defined(__linux__)). I think clang should support such kind of thing, but the auto complete does not.

tobiasgrosser commented 11 years ago

On 02/12/2013 10:53 AM, Kelvin Ng wrote:

I think I have missed something... Here is a macro #define i_checksum_lo osd2.linux2.l_i_checksum_lo so I understand what have happened. I think clang should support such kind of thing, but the auto complete does not.

Can you provide a minimal test case?

Tobi

Kelvin-Ng commented 11 years ago

@tobig

Here is a test case:

/* In test.h */
#define sth2_1 sth2.sth1_in_sth2

struct test_struct
{
    int sth1;
    struct
    {
        int sth1_in_sth2;
        int sth2_in_sth2;
    } sth2;
};

/* In test.c */
#include "test.h"
#include <stdio.h>

int main()
{
    struct test_struct test;
    test.sth2_1 = 123;

    printf("%d\n", test.sth2.sth1_in_sth2);
}

It works when compiling the above code with clang (program outputs '123') but sth2_1 does not appear when completing test.

tobiasgrosser commented 11 years ago

On 02/12/2013 11:07 AM, Kelvin Ng wrote:

Here is a test case:

/* In test.h */
#define sth2_1 sth2.sth1_in_sth2

struct test_struct
{
  int sth1;
  struct
  {
      int sth1_in_sth2;
      int sth2_in_sth2;
  } sth2;
};

/* In test.c */
#include "test.h"
#include <stdio.h>

int main()
{
  struct test_struct test;
  test.sth2_1 = 123;

  printf("%d\n", test.sth2.sth1_in_sth2);
}

If you set g:clang_complete_macros = 1 and press CTRL-C CTRL-U at some random point, clang proposes the strh2_1 macro for completion. However, it seems after 'test.' no macros are proposed. You can report this a bug to clang.

Tobias

Kelvin-Ng commented 11 years ago

@tobig

Sorry, I cannot get what you mean. You mean after setting g:clang_complete_macros = 1 and pressing CTRL-C CTRL-U at some random point, strh2_1 will show after 'test.'? I have tried it but it doesn't.

tobiasgrosser commented 11 years ago

On 02/12/2013 11:31 AM, Kelvin Ng wrote:

@tobig

Sorry, I cannot get what you mean. You mean after setting g:clang_complete_macros = 1 and pressing CTRL-C CTRL-U at some random point, strh2_1 will show after 'test.'?

By setting g:clang_complete_macros in your .vimrc file, you can enable macro completion. When you now trigger code completion at an empty line, the completion results will contain strh2_1. However, this does not work after 'test.', which seems to be a bug in clang.

Tobi

Kelvin-Ng commented 11 years ago

@tobig

That's true. I will report the bug to clang. Thank you.

tobiasgrosser commented 11 years ago

On 02/12/2013 11:35 AM, Kelvin Ng wrote:

@tobig

That's true. I will report the bug to clang. Thank you.

Feel free to copy me in the bug report.

Tobi

Kelvin-Ng commented 11 years ago

@tobig

Here it is: http://llvm.org/bugs/show_bug.cgi?id=15244

Sorry, what is the meaning of 'copy me in the bug report'?...

xavierd commented 11 years ago

Closing this one as this is not related to clang_complete.