繁体   English   中英

如何使用clang仅获取主要功能的AST

[英]How to get AST only of main function using clang

我想在源文件中获取主要功能的AST(假设有一个),以从中构建控制流程图。 我在这里找到了生成和遍历AST的代码: https : //shaharmike.com/cpp/libclang/ 但是问题是它进入了所有包含的文件中。 我也找到了这个主题: Clang AST访问者,避免遍历包含文件 但是似乎在clang10中做了一些更改,建议的解决方案现在不起作用。 也许还有其他方法可以获取AST的构建控制流程图? 唯一的要求-它必须可以使用C ++源代码。

阅读文档会告诉我,如果返回CXChildVisit_Recurse ,则clang_visitChildren只会“指向”它指向的CXChildVisit_Recurse 因此,您的访问函数应检查游标的种类并返回CXChildVisit_Continue直到达到名称等于main的函数定义为止。 它对main作用取决于您,但是我建议返回CXChildVisit_Break

因此,感谢Botje和这篇文章( https://www.phototalks.idv.tw/academic/?p=1932 ),我找到了解决方案。 无论如何,这都不是最好的代码,但是它可以工作。 希望对别人有帮助。

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

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

std::string getCursorKindName( CXCursorKind cursorKind )
{
  CXString kindName  = clang_getCursorKindSpelling( cursorKind );
  std::string result = clang_getCString( kindName );

  clang_disposeString( kindName );
  return result;
}

std::string getCursorSpelling( CXCursor cursor )
{
  CXString cursorSpelling = clang_getCursorSpelling( cursor );
  std::string result      = clang_getCString( cursorSpelling );

  clang_disposeString( cursorSpelling );
  return result;
}
CXChildVisitResult visitor1( CXCursor cursor, CXCursor /* parent */, CXClientData clientData )
{
  CXSourceLocation location = clang_getCursorLocation( cursor );
    unsigned int locationstring =0;
     clang_getSpellingLocation  (   location, NULL, &locationstring, NULL,NULL);
  if( clang_Location_isFromMainFile( location ) == 0 )
    return CXChildVisit_Continue;
  CXCursorKind kind = clang_getCursorKind(cursor);
    std::string str2 ("main");
  CXCursorKind cursorKind = clang_getCursorKind( cursor );
  unsigned int curLevel  = *( reinterpret_cast<unsigned int*>( clientData ) );
  unsigned int nextLevel = curLevel + 1;
    std::cout << std::string( curLevel, '-' ) << " " << getCursorKindName(
    cursorKind ) << " (" << getCursorSpelling( cursor ) << ") ";
    std::cout << locationstring ;
    std::cout << endl;

    clang_visitChildren( cursor,
                         visitor1,
                         &nextLevel );
    return CXChildVisit_Continue;

}

CXChildVisitResult visitor( CXCursor cursor, CXCursor /* parent */, CXClientData clientData )
{
  CXSourceLocation location = clang_getCursorLocation( cursor );
  if( clang_Location_isFromMainFile( location ) == 0 )
    return CXChildVisit_Continue;
  CXCursorKind kind = clang_getCursorKind(cursor);
    std::string str2 ("main");
  CXCursorKind cursorKind = clang_getCursorKind( cursor );

  unsigned int curLevel  = *( reinterpret_cast<unsigned int*>( clientData ) );
  unsigned int nextLevel = curLevel + 1;
  if (!((str2.compare(getCursorSpelling(cursor)))))
  {
    std::cout << std::string( curLevel, '-' ) << " " << getCursorKindName(
    cursorKind ) << " (" << getCursorSpelling( cursor ) << ")\n";

    clang_visitChildren( cursor,
                         visitor1,
                         &nextLevel );
    return CXChildVisit_Continue;
  }
  else
  {
  return CXChildVisit_Continue;
  }
}

int main()
{
  CXIndex index = clang_createIndex(0, 0);
  CXTranslationUnit unit = clang_parseTranslationUnit(
     index,
     <source_file_name>, nullptr, 0,
    nullptr, 0,
     CXTranslationUnit_None);
      CXCursor cursor = clang_getTranslationUnitCursor(unit);
      unsigned int treeLevel = 0;
      clang_visitChildren( cursor, visitor, &treeLevel );
  clang_disposeTranslationUnit(unit);
  clang_disposeIndex(index);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM