我试图了解如何使用libclang完成代码.我看过"思考超出编译器",我查看了c-index-test,我在这里找到了一个简单的示例程序
我编译了那个程序并在这个样本文件上运行它,我把它掀起来像是视频中的那个:
struct List {
int Data;
struct List *Next;
};
int sumListNode(struct List *Node) {
int result = 0;
for (; Node; Node = Node->Next)
result = result + Node->
}
void test() {
sumLi
}
Run Code Online (Sandbox Code Playgroud)
如果我在Node->之后将程序指向第一个不完整的空间,它会吐出几个C关键字,但它不会像视频所说的那样吐出Next或Data.
如果我将它指向sumLi之后的空格,它会打印出那些相同的C关键字.如果我将它指向sumLi中具有's'的列,我可以打印出sumListNode,但即便如此,它也会将其指定为与其他关键字相同的优先级值,所以它实际上只打印出我所有的内容可以放在那里,而不是阅读光标下的内容,并试图做出明智的猜测.我只是抓住吸管,希望无论如何将光标放在片段的开头而不是末尾都会有所帮助.
我已经了解了很多关于libclang可以给我的数据类型以及如何使用doxygen进行操作,以及在c-index-test中进行操作,但我还没学会如何让它给我相关数据,以便我有一些工作.
在下面的头文件中,我想获得+reflect对类和成员变量的相应注释:
#ifndef __HEADER_FOO
#define __HEADER_FOO
//+reflect
class Foo
{
public:
private:
int m_int; //+reflect
};
#endif
Run Code Online (Sandbox Code Playgroud)
使用libclang的python绑定和以下脚本:
import sys
import clang.cindex
def dumpnode(node, indent):
print ' ' * indent, node.kind, node.spelling
for i in node.get_children():
dumpnode(i, indent+2)
def main():
index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1], args=['-x', 'c++'])
dumpnode(tu.cursor, 0)
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
给我这个输出:
CursorKind.TRANSLATION_UNIT None
CursorKind.TYPEDEF_DECL __builtin_va_list
CursorKind.CLASS_DECL type_info
CursorKind.CLASS_DECL Foo
CursorKind.CXX_ACCESS_SPEC_DECL
CursorKind.CXX_ACCESS_SPEC_DECL
CursorKind.FIELD_DECL m_int
Run Code Online (Sandbox Code Playgroud)
问题是缺少评论.它们被预处理器剥离了吗?有什么方法可以阻止这种情况吗?
我在启动xCode(5.1.1)之后的每一次都有这个.
删除用户数据,关闭源代码控制(如某些帖子建议),没有效果,仍然崩溃(同时显示索引......永远不会完成).即使重新安装 xCode,没有任何影响,仍然说同样的.
有人修过这样的xCode吗?

这是崩溃的线程:
Thread 7 Crashed:: Dispatch queue: IDEIndex PCH Creation Lock
0 libclang.dylib 0x00000001080c60d9 void llvm::BitstreamWriter::EmitRecordWithAbbrevImpl<unsigned long long>(unsigned int, llvm::SmallVectorImpl<unsigned long long>&, llvm::StringRef) + 809
1 libclang.dylib 0x00000001080c5867 void llvm::BitstreamWriter::EmitRecord<unsigned long long>(unsigned int, llvm::SmallVectorImpl<unsigned long long>&, unsigned int) + 71
2 libclang.dylib 0x00000001081e9f25 clang::ASTWriter::WriteASTCore(clang::Sema&, llvm::StringRef, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, clang::Module*) + 35045
3 libclang.dylib 0x00000001081e160e clang::ASTWriter::WriteAST(clang::Sema&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, clang::Module*, llvm::StringRef, bool) + 6830
4 libclang.dylib 0x00000001080719a3 clang::ASTUnit::Save(llvm::StringRef) + 691
5 …Run Code Online (Sandbox Code Playgroud) 我一直在使用优秀的C接口libclang(http://clang.llvm.org/doxygen/group__CINDEX.html)编写C++ AST解析器.不幸的是,在C++ 11作用域枚举和旧式枚举之间似乎没有消歧:两者都有一个游标类型CXCursor_EnumDecl和一个类型CXType_Enum即相同.
我试过拜访孩子,看他们的父母类型是否不同 - 遗憾的是没有.我试过要求底层类型,我得到两个整数.我已经检查了Enum之后声明的所有项目,看看是否可能出现旧式枚举的bind或typedef,再次没有明显区别.
我开始认为我必须遗漏一些东西.我是否必须使用代码完成API来确定它是哪种枚举?
当从 Python 使用 libclang 时,它似乎不会自动搜索系统的包含路径。
有没有可靠的方法来获取这些路径?我不喜欢硬编码路径,因为我正在编写将在各种 UNIX 系统上运行的代码。
例如,给定 test.cpp
#include <stdio.h>
int main()
{
puts("Hello, world!");
}
Run Code Online (Sandbox Code Playgroud)
和测试.py
from clang.cindex import Index
tu = Index.create().parse(None, ["test.cpp"])
print(list(tu.diagnostics))
Run Code Online (Sandbox Code Playgroud)
运行python test.py将打印:
[<Diagnostic severity 4, location <SourceLocation file 'test.cpp', line 1,
column 10>, spelling "'stdio.h' file not found">]
Run Code Online (Sandbox Code Playgroud)
当然,我可以通过以下方式找到系统包含路径
$ clang -v -E test.cpp
Run Code Online (Sandbox Code Playgroud)
并添加"-Isome/path"到parse参数列表中,即
args = ["-I/Applications/[...]", "test.cpp"]
Run Code Online (Sandbox Code Playgroud)
这确实有效并且不会产生任何错误。
然而,这不是可移植的,如果我能够以编程方式让 clang 自动使用它们,那就太好了。
我正在使用libclang的python绑定,但我认为这个问题是由libclang而不是python绑定引起的.
我有一个标题 object.h
#ifndef OBJECT_H
#define OBJECT_H
class Object {
public:
int run();
};
#endif
Run Code Online (Sandbox Code Playgroud)
并实施 object.cpp
#include "object.h"
int Object::run() {
int a = 0;
return a*a;
}
Run Code Online (Sandbox Code Playgroud)
如果我访问翻译单元的object.hAST,那么最后一个AST节点就是VAR_DECL class Object它.它不会访问public:...部分.如果我用clang直接检查语法就会抱怨我的头文件是错误的.
$ clang -Xclang -ast-dump -fsyntax-only object/object.h
object/object.h:4:1: error: unknown type name 'class'
class Object {
^
object/object.h:4:13: error: expected ';' after top level declarator
class Object {
^
;
TranslationUnitDecl 0x7f816102d2d0 <<invalid sloc>>
|-TypedefDecl 0x7f816102d7d0 <<invalid sloc>> __int128_t '__int128'
|-TypedefDecl 0x7f816102d830 <<invalid …Run Code Online (Sandbox Code Playgroud) 我有以下使用clang-c API的代码.
#include <iostream>
#include <string>
#include <clang-c/Index.h>
CXChildVisitResult printVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
{
CXCursor cursor1 = clang_getCursorReferenced(cursor);
CXType type = clang_getCursorType(cursor1);
CXCursorKind kind = clang_getCursorKind(cursor1);
CXString str = clang_getTypeSpelling(type);
CXString str1 = clang_getCursorSpelling(cursor1);
std::string cstr = clang_getCString(str);
std::string cstr1 = clang_getCString(str1);
if(type.kind != 0 && kind == CXCursorKind::CXCursor_FunctionDecl)
{
std::cout << "Declaration!\n" << "type is: " << cstr << std::endl;
std::cout << "name is: " << cstr1 << std::endl;
}
return CXChildVisit_Recurse;
}
int main (int argc, …Run Code Online (Sandbox Code Playgroud) 我正在使用linux mint,我已经使用Clang Complete的makefile安装了clang_complete .但它不起作用.当我打开一个cpp文件时,会出现一条错误消息:
Loading libclang failed, completion won't be available. Consider setting g:clang_library_path
Run Code Online (Sandbox Code Playgroud)
我已经对这个主题做过一些研究,并试图找到libclang.so文件,将g:clang_library_path ='...'放入我的vimrc中.但我找不到该文件.所以我无法在我的vimrc中定义路径.
$ find / -name libclang -type f 2> /dev/null 没有任何回报.
我很乐意得到一些帮助,以使clang_complete工作.
假设我有一个枚举定义,例如:
// myenum.h
enum MyEnum {
First = 1,
Second,
Third,
TwoAgain = Second
};
Run Code Online (Sandbox Code Playgroud)
我想以编程方式从任何给定的枚举定义生成一个映射,其中键是枚举元素的名称,值是枚举元素的数值(例如myMap["TwoAgain"] == 2)
到目前为止,我知道如何使用遍历源文件clang_visitChildren(),并使用提取单个标记clang_tokenize().通过AST递归,我按以下顺序获取游标/标记:
我想我可以编写一个算法,使用这些信息来计算每个值.但是,我想知道是否有更简单的方法?我可以直接从libclang API获取数值吗?
简短说明:libclang用于自动完成代码不适用于与 Sublime Text 3 捆绑在一起的 python。
详细信息:Github上的 repo 中有一个可验证的小示例
本质上,有一个脚本使用稍微改变的cindex.py(兼容 python 3 和 clang 3.8)并从测试源文件构建翻译单元。然后它重新解析它并尝试完成。
该脚本在使用来自 Powershell 的 Python 3.3.5 时按预期工作。
当放入 Sublime Text 3 上的 Packages 文件夹时,它会产生错误。Sublime Text 3 报告的 Python 版本是 3.3.6。错误:
Traceback (most recent call last):
File "C:\Program Files\Sublime Text 3\sublime_plugin.py", line 78, in reload_plugin
m = importlib.import_module(modulename)
File "./python3.3/importlib/__init__.py", line 90, in import_module
File "<frozen importlib._bootstrap>", line 1584, in _gcd_import
File "<frozen importlib._bootstrap>", line 1565, in _find_and_load
File …Run Code Online (Sandbox Code Playgroud) libclang ×10
clang ×7
c++ ×4
python ×3
llvm ×2
c++11 ×1
enums ×1
ios ×1
llvm-clang ×1
python-3.x ×1
sublimetext3 ×1
vim ×1
windows ×1
xcode ×1
xcode5 ×1