ctags 生成不对的问题

ctags为系统提供的头文件生成的索引总是不太对。比如对于/usr/include/sys/socket.h,里面有很多函数在 ctags处理的时候没有能加到索引里去。最后发现是__TRHOW的问题。以listen函数为例,在socket.h中,它的原型是:

extern int listen (int __fd, int __n) __THROW;

socket.h间接包含了sys/cdefs.h,__THROW就是在这个头文件中被定义的。其定义如下:

# if !defined __cplusplus && __GNUC_PREREQ (3, 3)       
# define __THROW       __attribute__ ((__nothrow__))   
# define __NTH(fct)    __attribute__ ((__nothrow__)) fct
# else                                                  
# if defined __cplusplus && __GNUC_PREREQ (2,8)        
#   define __THROW      throw ()                        
#   define __NTH(fct)   fct throw ()                    
# else                                                 
#   define __THROW                                      
#   define __NTH(fct)   fct                             
# endif                                                
# endif                                                 

如 果gcc正在编译c++文件,并且gcc版本大于2.8那么__THROW会被定义为throw()。如果正在编译c文件并且gcc版本在2.8之 前,__THROW则是一个空的宏定义,如果版本大于3.3,则__THROW被定义成一个attribute内包含的nothrow的形式。最后这个形 式表示这段c代码不会抛出异常。

正是这个复杂的宏定义干扰了ctags,对于所有像listen这样含有__THROW的原型,ctags一律都不能正确解析。其原因是ctags本身不是一个编译器也没有专门的预处理器,它是通过直接解析源文件的语法来工作的,不进行语义的检查和宏展开。对于宏,它的能力仅限于识别定义、调用和简单的条件编译的猜测。

为了不让__THROW干扰ctags,需要在运行ctags时使用-I选项。我一般使用下面的命令生成系统头文件tags

ctags -I __THROW --file-scope=yes --langmap=c:+.h --languages=c,c++ --links=yes --c-kinds=+p -R -f ~/.vim/systags /usr/include /usr/local/include

其关键是-I __THROW部分和--c-kinds=+p部分。设置-I后,ctags会在处理文件时,就会忽略-I后面写出来的符号。而--c-kinds=+p则告诉ctags需要为函数原型的声明也生成tag。--langmap=c:+.h表示.h视为c文件而不是c++文件。

最后,设置你的~/.vimrc,加入一行:
set tags+=~/.vim/systags
就可以享受系统库函数名补全、原型预览等功能了。

转自:http://hi.baidu.com/zhshzhou/item/a999d8ebe6c9902b5a7cfb28

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25897606/viewspace-746989/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/25897606/viewspace-746989/

你可能感兴趣的:(c/c++,开发工具)