我正在研究使用clang的代码完成机制时潜在的代码完成速度.下面描述的流程是我在rtags中发现的Anders Bakken.
翻译单元由守护程序监视文件进行解析以进行更改.这是通过被调用的clang_parseTranslationUnit
和相关的函数(reparse*
,dispose*
)来完成的.当用户在源文件中的给定行和列请求完成时,守护程序将缓存的转换单元传递给源文件的最后保存版本和当前源文件clang_codeCompleteAt
.(Clang CodeComplete docs).
传递给clang_parseTranslationUnit
(来自CompletionThread :: process,第271行)的标志是CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes
.传递给clang_codeCompleteAt
(来自CompletionThread :: process,第305行)的标志是CXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns
.
调用clang_codeCompleteAt
非常慢 - 即使在完成位置是合法成员访问代码的情况下,也需要大约3-5秒来获得完成,这是文档中提到的预期用例的子集clang_codeCompleteAt
.IDE代码完成标准似乎太慢了.有没有办法加速这个?
有没有办法使用libclang检测匿名枚举而不依赖于拼写名称中的文本?
对libclang的python绑定包括使用clang.cindex.Cursor.is_anonymous来检测C/C++结构或联合是否是匿名的功能,最终调用clang_Cursor_isAnonymous.
以下示例演示了此问题.
import sys
from clang.cindex import *
def nodeinfo(n):
return (n.kind, n.is_anonymous(), n.spelling, n.type.spelling)
idx = Index.create()
# translation unit parsed correctly
tu = idx.parse(sys.argv[1], ['-std=c++11'])
assert(len(tu.diagnostics) == 0)
for n in tu.cursor.walk_preorder():
if n.kind == CursorKind.STRUCT_DECL and n.is_anonymous():
print nodeinfo(n)
if n.kind == CursorKind.UNION_DECL and n.is_anonymous():
print nodeinfo(n)
if n.kind == CursorKind.ENUM_DECL:
if n.is_anonymous():
print nodeinfo(n)
else:
print 'INCORRECT', nodeinfo(n)
Run Code Online (Sandbox Code Playgroud)
哪个在sample.cpp上运行
enum
{
VAL = 1
};
struct s …
Run Code Online (Sandbox Code Playgroud) 我在Windows上使用64位Vim,这个版本由Haroogan:
+python27
+python33
+huge
Run Code Online (Sandbox Code Playgroud)
我试图用clang_complete,所以我把libclang.dll
图书馆在这里,我建立了我的vimrc
正确.libclang.dll
找到了.
但是当我打开*.cpp
文件时,我现在有一条消息:
libclang
找不到内置包含这将导致缓慢完成代码
但我根本没有完成......
我发现这篇文章的内容是我使用的构建Vim版本的人,但没有明确指示该怎么做.有人可以帮忙吗?
这是我做的:
它几乎工作(我没有任何错误消息),但我仍然得到:
使用libclang,我有一个AST的游标,它对应于宏扩展产生的语句.我想检索原始的,未展开的宏文本.
我已经找了一个libclang API来做这个,但找不到一个.我错过了什么吗?
假设这样的API不存在,我会看到几种方法可以做到这一点,两者都基于使用clang_getCursorExtent()来获取光标的源范围 - 可能是原始文本的范围.
第一个想法是使用clang_getFileLocation()来获取范围开始和结束的文件名和位置,并直接从文件中读取文本.如果我是从未保存的文件编译的,那么我需要处理它,但我对这种方法的主要关注是,当我确定clang在内部保存所有这些信息时,出门到文件系统似乎是不对的. .如果AST已加载而不是生成,或者源文件自解析后已被修改,也会有影响.
第二种方法是在游标范围上调用clang_tokenize().我尝试这样做,发现它无法为AST中的大多数游标生成令牌列表.跟踪代码,结果是内部clang_tokenize()操纵提供的范围并最终得出结论它跨越多个文件(可能是由于宏扩展的某些影响),并且中止.这对我来说似乎不对,但我确实觉得无论如何我都在滥用clang_tokenize()试图这样做.
那么,最好的方法是什么?
我有一个实例CXCursor
样的CXCursor_CXXMethod
.我想知道函数是否是,const
或者volatile
,例如:
class Foo {
public:
void bar() const;
void baz() volatile;
void qux() const volatile;
};
Run Code Online (Sandbox Code Playgroud)
我在libclang的文档中找不到任何有用的东西.我试过clang_isConstQualifiedType
,clang_isVolatileQualifiedType
但这些似乎总是返回0
C++成员函数类型.
我最近开始使用libclang来解析C文件.我遇到的问题是,显然,libclang在生成AST之前启动预处理器.我想禁止预处理程序运行,而是给出预处理程序指令在文件中的信息......
我使用以下python脚本(cindex.py和libclang)
import codecs
from clang.cindex import *
class SourceFile(object):
def __init__(self, path):
with codecs.open(path, 'r', 'utf-8') as file:
self.file_content = file.read()
index = Index.create()
root_node = index.parse(path)
for included in root_node.get_includes():
print included.include
self.print_declerations(root_node.cursor)
def print_declerations(self, root, recurse=True):
print root.kind.name, root.spelling
if root.kind.is_declaration():
node_def = root.get_definition()
if node_def is not None:
start_offset = node_def.extent.start.offset
end_offset = node_def.extent.end.offset + 1
print self.file_content[start_offset:end_offset], '\n'
if recurse:
for child in root.get_children():
self.print_declerations(child, False)
if __name__ == '__main__':
path = 'Sample.cpp'
print 'Translation …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个实用程序,它应该解析C++(和C)头文件,提取结构,枚举,字段等,并根据提取的信息生成其他语言的代码.我决定使用libclang.
我正在使用a RecursiveASTVisitor
,似乎我能够提取我需要的所有信息,除了评论.
我希望在每个声明(字段,结构,类,枚举)的上方出现注释,并在我用其他语言生成代码时添加其文本.
问题是我看到的所有使用注释的样本CxCursor
和clang的C接口,我不知道如何CxCursor
在我的上下文中获取.
那么 - 如何在仍然使用时提取注释RecursiveASTVisitor
?
我使用libclang来解析源文件并引用某些类型CXType
,比如它是" const std::__1::basic_string<char>
"(如报告所述 clang_getTypeSpelling
).如何获得相同类型的引用但没有const限定符?
我一直在寻找一些易于理解的libclang指南.我在这里或其他论坛上看过一些线程,但唯一推荐的信息来源是libclang source/doxygen doc,vng的clang完整插件或Thinking Beyond the Compiler演示文稿.但是,它们都没有提供有关实际使用的信息.我对实现代码完成/语法突出显示感兴趣(可能是一些基本的重构/解析).
所以我的问题是,除了上面提到的那些之外,还有任何易于理解的教程吗?也许一些高级libclang用户可以写一个:)
注意:我对编写clang插件不感兴趣.
libclang只定义了5种类型的令牌:
是否有可能获得有关令牌的更详细信息?例如,对于以下源代码:
struct Type;
void foo(Type param);
Run Code Online (Sandbox Code Playgroud)
我希望输出如下:
我还需要将这些实体映射到文件位置.