标签: libclang

libclang从游标中获取类名

我试图将一个参数的类名提取到objective-C中的方法调用.我正在解析的代码是:

- (void)testAddConcreteDataModel:(DFDemoDataModelOne*)helpmeh {
    [self.dataModels addObject:helpmeh];
}
Run Code Online (Sandbox Code Playgroud)

我需要的结果是helpmeh类的类型,即"DFDemoDataModelOne".

到目前为止,我有以下代码,其中输出: "[(DFDataModelContainer).dataModels addObject:helpmeh]"

    if (cursor.kind == CXCursor_ObjCMessageExpr) {
        __block NSString* memberName = nil;
        __block NSString* ownerClassName = nil;
        __block NSString* methodName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))];

        clang_visitChildrenWithBlock(cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) {
            if (cursor.kind == CXCursor_MemberRefExpr) {
                memberName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))];
                ownerClassName = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(clang_getCursorSemanticParent(clang_getCursorReferenced(cursor))))];
            } else {
                if (memberName) {
                    NSString* param = [NSString stringWithUTF8String:clang_getCString(clang_getCursorDisplayName(cursor))];
                    NSLog(@"[(%@).%@ %@%@]", ownerClassName, memberName, methodName, param);
                    clang_visitChildrenWithBlock(cursor, ^enum CXChildVisitResult(CXCursor cursor, CXCursor parent) {

                         // test
                         if ([param …
Run Code Online (Sandbox Code Playgroud)

objective-c clang libclang

5
推荐指数
2
解决办法
1454
查看次数

我如何跳过包含使用libclang?

我使用libclang来解析一个客观的c源代码文件.以下代码查找所有Objective-C实例方法声明,但它也在包含中找到声明:

 enum CXCursorKind curKind  = clang_getCursorKind(cursor);
 CXString curKindName  = clang_getCursorKindSpelling(curKind);

 const char *funcDecl="ObjCInstanceMethodDecl";

 if(strcmp(clang_getCString(curKindName),funcDecl)==0{


 }
Run Code Online (Sandbox Code Playgroud)

如何跳过包含标题的所有内容?我只对源文件中我自己的Objective-C实例方法声明感兴趣,而不是任何包含.

例如,不应包括以下内容

...

Location: /System/Library/Frameworks/Foundation.framework/Headers/NSObject.h:15:9:315
Type: 
TypeKind: Invalid
CursorKind: ObjCInstanceMethodDecl

...
Run Code Online (Sandbox Code Playgroud)

parsing objective-c libclang

4
推荐指数
1
解决办法
1208
查看次数

用 libclang 解析;无法解析某些标记(Windows 中的 Python)

我有一些代码(从这里这里获取和改编),它使用libclang 解析Python(Widnows)中的C++ 源文件并获取其所有声明语句,如下所示:

import clang.cindex

def parse_decl(node):
    reference_node = node.get_definition()
    if node.kind.is_declaration():
        print(node.kind, node.kind.name, 
              node.location.line, ',', node.location.column, 
              reference_node.displayname)

    for ch in node.get_children():
        parse_decl(ch)

# configure path
clang.cindex.Config.set_library_file('C:/Program Files (x86)/LLVM/bin/libclang.dll')

index = clang.cindex.Index.create()
trans_unit = index.parse(r'C:\path\to\sourcefile\test.cpp', args=['-std=c++11'])

parse_decl(trans_unit.cursor)
Run Code Online (Sandbox Code Playgroud)

对于以下 C++ 源文件 ( test_ok.cpp):

/* test_ok.cpp
 */

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std;

int main (int argc, char *argv[]) {
  int linecount …
Run Code Online (Sandbox Code Playgroud)

python parsing clang c++11 libclang

4
推荐指数
1
解决办法
1990
查看次数

如何在 Clang 中将函数定义/签名作为字符串获取?

假设我有它的 CXCursor 左右,如何使用 Clang/Libclang 将函数的签名(或至少整个定义?)作为字符串获取?

我认为可以通过使用游标的范围以某种方式获得该定义,但我真的不知道如何(使用什么函数)。

clang libclang

4
推荐指数
1
解决办法
2743
查看次数

无法安装 RStudio,无法安装“libclang-dev”

我使用 ubuntu 20.04.2。我在使用 rStudio 时遇到了一些问题,因此我从计算机上完全卸载了。我已经安装了 r,但现在我想安装 rStudio,但是当我尝试安装时,我发现“libclang-dev”是可卸载的。

$ sudo gdebi rstudio-1.4.1106-amd64.deb

Reading package lists... Done
Building dependency tree        
Reading state information... Done
Reading state information... Done
This package is uninstallable
Cannot install 'libclang-dev'
Run Code Online (Sandbox Code Playgroud)

我尝试安装 clang,但出现更多错误:

$ sudo apt install clang

Reading package lists... Done
Building dependency tree       
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have …
Run Code Online (Sandbox Code Playgroud)

ubuntu libclang

4
推荐指数
2
解决办法
1395
查看次数

使用libclang从内存中的C代码生成程序集

我需要实现一个库,它使用LLVM/Clang作为后端将C代码编译为eBPF字节码.代码将从内存中读取,我需要将结果汇编代码也存储在内存中.

到目前为止,我已经能够使用以下代码编译为LLVM IR:

#include <string>
#include <vector>

#include <clang/Frontend/CompilerInstance.h>
#include <clang/Basic/DiagnosticOptions.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/CodeGen/CodeGenAction.h>
#include <clang/Basic/TargetInfo.h>
#include <llvm/Support/TargetSelect.h>

using namespace std;
using namespace clang;
using namespace llvm;

int main() {

    constexpr auto testCodeFileName = "test.cpp";
    constexpr auto testCode = "int test() { return 2+2; }";

    // Prepare compilation arguments
    vector<const char *> args;
    args.push_back(testCodeFileName);

    // Prepare DiagnosticEngine 
    DiagnosticOptions DiagOpts;
    TextDiagnosticPrinter *textDiagPrinter =
            new clang::TextDiagnosticPrinter(errs(),
                                         &DiagOpts);
    IntrusiveRefCntPtr<clang::DiagnosticIDs> pDiagIDs;
    DiagnosticsEngine *pDiagnosticsEngine =
            new DiagnosticsEngine(pDiagIDs,
                                         &DiagOpts,
                                         textDiagPrinter);

    // Initialize CompilerInvocation
    CompilerInvocation *CI …
Run Code Online (Sandbox Code Playgroud)

c++ llvm clang libclang

3
推荐指数
1
解决办法
1452
查看次数

如何使用 libclang 检索完全限定的函数名称?

我需要解析一个 C++ 代码文件,并使用完全限定名称查找其中的所有函数调用。我正在使用 libclang 的 Python 绑定,因为它似乎比编写我自己的 C++ 解析器更容易,即使文档很少。

示例 C++ 代码:

namespace a {
  namespace b {
    class Thing {
    public:
      Thing();
      void DoSomething();
      int DoAnotherThing();
    private:
      int thisThing;
    };
  }
}

int main()
{
  a::b::Thing *thing = new a::b::Thing();
  thing->DoSomething();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

蟒蛇脚本:

import clang.cindex
import sys

def find_function_calls(node):
  if node.kind == clang.cindex.CursorKind.CALL_EXPR:
    # What do I do here?
    pass
  for child in node.get_children():
    find_function_calls(child)

index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1])
find_function_calls(tu.cursor)
Run Code Online (Sandbox Code Playgroud)

我正在寻找的输出是被调用函数的完全限定名称列表:

a::b::Thing::Thing
a::b::Thing::DoSomething
Run Code Online (Sandbox Code Playgroud)

我可以使用 获得函数的“短”名称 …

c++ python libclang

3
推荐指数
1
解决办法
2212
查看次数

使用libclang获取typedef类型和名称?

我可以得到typedef的名称和类型,如果它们是匿名结构等,但普通的typedef(例如typedef int size_t)我只能得到size_t.我怎样才能得到"int"类型?

c typedef libclang

2
推荐指数
1
解决办法
992
查看次数

在Python中使用libclang在C ++中进行解析

经过一些研究和几个问题,我最终探索了libclang库,以便用Python解析C ++源文件。

给定C ++源代码

int fac(int n) {
    return (n>1) ? n?fac(n?1) : 1;
}

for (int i = 0; i < linecount; i++) {
   sum += array[i];
}

double mean = sum/linecount;
Run Code Online (Sandbox Code Playgroud)

我试图将标记识别 fac为函数名称,n变量名称,i变量名称,mean变量名称以及每个位置。我有兴趣最终将它们标记化

我已经阅读了一些非常有用的文章(eli的Gaetan的),以及一些堆栈溢出问题3511319713236500

但是,鉴于我是Python的新手,并且努力理解libclang的基础知识,因此,我非常感谢一些示例代码块,这些代码实现了以上内容,供我学习和理解。

c++ python parsing libclang

2
推荐指数
1
解决办法
4396
查看次数

展开宏并检索宏值

我试图使用libclang python绑定来解析我的c ++源文件.我无法获得宏的值或扩展宏.
这是我的示例c ++代码

#define FOO 6001
#define EXPAND_MACR \
        int \
        foo = 61
int main()
{
    EXPAND_MACR;
    cout <<  foo;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


这是我的python脚本

import sys
import clang.cindex

def visit(node):
    if node.kind in (clang.cindex.CursorKind.MACRO_INSTANTIATION,   clang.cindex.CursorKind.MACRO_DEFINITION):           
    print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (node.displayname, node.kind, node.data, node.extent, node.location.line, node.location.column)
for c in node.get_children():
    visit(c)

if __name__ == '__main__':
    index = clang.cindex.Index.create()
    tu = index.parse(sys.argv[1], options=clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD)
    print 'Translation unit:', tu.spelling
    visit(tu.cursor)
Run Code Online (Sandbox Code Playgroud)


这是我从clang回来的信息:

Found …
Run Code Online (Sandbox Code Playgroud)

c++ python clang libclang

2
推荐指数
1
解决办法
1176
查看次数

为什么 libclang 会错误解析带有 .h 前缀的 C++ 标头?

我尝试使用 libclang 解析 C++ 标头,但解析器仅解析类名 - 并将其类型显示为 VarDec1。当文件扩展名从 .h 更改为 .cpp 时,它就可以正常工作。经过几天的搜索找不到答案,有人可以帮我解决这个问题吗?

以下是parser.cpp:

#include <iostream>
#include <clang-c/Index.h>  // This is libclang.
using namespace std;

ostream& operator<<(ostream& stream, const CXString& str)
{
  stream << clang_getCString(str);
  clang_disposeString(str);
  return stream;
}

int main()
{
  CXIndex index = clang_createIndex(0, 0);
  CXTranslationUnit unit = clang_parseTranslationUnit(
    index,
    "tt.h", nullptr, 0,
    nullptr, 0,
    CXTranslationUnit_None);
  if (unit == nullptr)
  {
    cerr << "Unable to parse translation unit. Quitting." << endl;
    exit(-1);
  }

  CXCursor cursor = clang_getTranslationUnitCursor(unit);
  clang_visitChildren(
    cursor, …
Run Code Online (Sandbox Code Playgroud)

c c++ clang clang++ libclang

2
推荐指数
1
解决办法
2299
查看次数

LibClang clang_getArgType() 返回错误类型

我尝试使用 libClang 解析 C++ 方法,但是当尝试获取函数的参数/参数时,有时会给出错误的类型。

例子:

我有两种不同的方法

std::string Method::exportMethod(std::map<std::string, std::string> &defines) const
Run Code Online (Sandbox Code Playgroud)

std::string Field::exportField(std::map<std::string, std::string> &defines) const
Run Code Online (Sandbox Code Playgroud)

我打印 AST(用于调试目的)

CXChildVisitResult printer::printVisitor(CXCursor c, CXCursor parent, CXClientData clientData) {
    recursivePrintData data = *static_cast<recursivePrintData *>(clientData);

    *(data.stream) <<
                   data.indent <<
                   clang_getCursorKindSpelling(clang_getCursorKind(c)) <<
                   "; name: " << clang_getCursorSpelling(c) <<
                   ", type: " << clang_getCursorType(c) <<
                   ", arg0Type: " << clang_getArgType(clang_getCursorType(c), 0) <<
                   std::endl;

    recursivePrintData newDat(data);
    data.indent += "    ";

    clang_visitChildren(c, printVisitor, (void *) &data);

    return CXChildVisit_Recurse;
}
Run Code Online (Sandbox Code Playgroud)

(recursivePrintData 是一个包含输出流和当前缩进级别的结构)

对于这两种方法,输出如下:

导出方法:

    CXXMethod; name: exportMethod, …
Run Code Online (Sandbox Code Playgroud)

c++ clang abstract-syntax-tree libclang

2
推荐指数
1
解决办法
522
查看次数

sublime text 3插件主机崩溃恢复

我为Sublime Text 3开发了一个插件,我的python代码使用c类型绑定来实现clang.有时调用libclang会出现段错误libclang: crash detected during reparsing(我还不明白原因,但这与这个问题无关).这会导致插件主机崩溃.

所以问题是:在python中有什么方法可以从底层c绑定中的失败中恢复?我很乐意在这个遇到崩溃的特定文件中跳过这个动作.

谢谢!

UPD:评论中有一个简短的讨论,有必要进一步阐述缺乏一个适当的小型可重复的例子.这并不是因为我的懒惰,我尽量让它尽可能容易地理解我希望得到帮助的人的问题.但在这种情况下,这真的很难.最初的问题是由libclang segfaulting导致的一些奇怪的情况,我还没有确定.它可能与一个没有c ++ 11支持编译的库有关,另一个在使用c ++ 11支持编译时使用它,但我想强调 - 这与问题无关.这里的问题是python正在调用的东西中有一个段错误,这个段错误导致Sublime Text plugin_host退出.所以这里有一个简单的例子,但不是缺乏尝试.如果你有如何构建一个想法,我也愿意接受建议.抱歉这个问题的质量很差,这是目前我最好的.

python sublimetext libclang sublimetext3 sublime-text-plugin

0
推荐指数
1
解决办法
265
查看次数