clang -std=c++11 -Xclang -ast-dump ////cpp -I/////include/ -D_ -fsyntax-only
TranslationUnitDecl 0x576e190 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x576e718 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x576e400 '__int128'
|-TypedefDecl 0x576e778 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x576e420 'unsigned __int128'
|-TypedefDecl 0x576eaa8 <<invalid sloc>> <invalid sloc> implicit __NSConstantString 'struct __NSConstantString_tag'
| `-RecordType 0x576e860 'struct __NSConstantString_tag'
| `-CXXRecord 0x576e7c8 '__NSConstantString_tag'
|-TypedefDecl 0x576eb38 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 0x576eb00 'char *'
| `-BuiltinType 0x576e220 'char'
|-TypedefDecl 0x576ee58 <<invalid sloc>> <invalid sloc> implicit referenced __builtin_va_list 'struct __va_list_tag [1]'
| `-ConstantArrayType 0x576ee00 'struct __va_list_tag [1]' 1
| `-RecordType 0x576ec20 'struct __va_list_tag'
| `-CXXRecord 0x576eb88 '__va_list_tag'
|-NamespaceDecl 0x57cc578 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:18:1, line:31:1> line:18:11 clang
| |-CXXRecordDecl 0x57cc5e0 <line:20:1, col:7> col:7 class Decl
| |-CXXRecordDecl 0x57cc6a0 <line:21:29, <scratch space>:2:1> col:1 referenced class AccessSpecDecl
| |-CXXRecordDecl 0x57cc760 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:3:1> col:1 class BlockDecl
| |-CXXRecordDecl 0x57cc820 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:4:1> col:1 class CapturedDecl
| |-CXXRecordDecl 0x57cc8e0 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:5:1> col:1 referenced class ClassScopeFunctionSpecializationDecl
| |-CXXRecordDecl 0x57cc9a0 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:6:1> col:1 class EmptyDecl
| |-CXXRecordDecl 0x57cca60 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:7:1> col:1 class ExternCContextDecl
| |-CXXRecordDecl 0x57ccb20 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:8:1> col:1 class FileScopeAsmDecl
| |-CXXRecordDecl 0x57ccbe0 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:9:1> col:1 referenced class FriendDecl
| |-CXXRecordDecl 0x57ccca0 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:10:1> col:1 referenced class FriendTemplateDecl
| |-CXXRecordDecl 0x57ccd60 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:11:1> col:1 class ImportDecl
| |-CXXRecordDecl 0x57cce20 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:12:1> col:1 class LinkageSpecDecl
| |-CXXRecordDecl 0x57ccee0 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:13:1> col:1 class NamedDecl
| |-CXXRecordDecl 0x57ccfa0 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:14:1> col:1 class LabelDecl
| |-CXXRecordDecl 0x57cd060 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:15:1> col:1 class NamespaceDecl
| |-CXXRecordDecl 0x57cd120 </home/user/LLVM/llvm-3.7.1.src/tools/cfe-3.7.1.src/include/clang/AST/ASTFwd.h:21:29, <scratch space>:16:1> col:1 class NamespaceAliasDecl
// file foo.h void foo(int x, int y); // file main.c #include "foo.h" typedef struct { int x, y; } st_coord; int main() { st_coord coord; foo(coord.x, coord.y); }
#include <clang-c/Index.h> #include <iostream> #include <string> using namespace clang; void printCursor(CXCursor cursor) { CXString displayName = clang_getCursorDisplayName(cursor); std::cout << clang_getCString(displayName) << "\n"; clang_disposeString(displayName); } CXChildVisitResult visitor( CXCursor cursor, CXCursor /* parent */, CXClientData /*clientData*/ ) { CXSourceLocation location = clang_getCursorLocation( cursor ); if( clang_Location_isFromMainFile( location ) == 0 ) return CXChildVisit_Continue; printCursor(cursor); clang_visitChildren( cursor, visitor, nullptr ); return CXChildVisit_Continue; } int main (int argc, char** argv) { CXIndex index = clang_createIndex ( 0, // excludeDeclarationFromPCH 1 // displayDiagnostics ); CXTranslationUnit unit = clang_parseTranslationUnit ( index, // CIdx 0, // source_filename argv, // command_line_args argc, // num_command_line_args 0, // unsave_files 0, // num_unsaved_files CXTranslationUnit_None // options ); if (!unit) { std::cout << "Translation unit was not created\n"; } else { CXCursor root = clang_getTranslationUnitCursor(unit); clang_visitChildren(root, visitor, nullptr); } clang_disposeTranslationUnit(unit); clang_disposeIndex(index); }
CXCursorKind cursorKind = clang_getCursorKind( cursor ); // finding local variables if(clang_getCursorKind(cursor) == CXCursor_VarDecl) { if(const VarDecl* VD = dyn_cast_or_null<const VarDecl>(getCursorDecl(cursor))) { if( VD->isLocalVarDecl()) { std::cout << "local variable: "; printCursor(cursor); } } }
//logging functions std::string getLocationString(CXSourceLocation Loc) { CXFile File; unsigned Line, Column; clang_getFileLocation(Loc, &File, &Line, &Column, nullptr); CXString FileName = clang_getFileName(File); std::ostringstream ostr; ostr << clang_getCString(FileName) << ":" << Line << ":" << Column; clang_disposeString(FileName); return ostr.str(); } void printCursor(CXCursor cursor) { CXString displayName = clang_getCursorDisplayName(cursor); std::cout << clang_getCString(displayName) << "@" << getLocationString(clang_getCursorLocation(cursor)) << "\n"; clang_disposeString(displayName); }
// extracted from CXCursor.cpp const Decl *getCursorDecl(CXCursor Cursor) { return static_cast<const Decl *>(Cursor.data[0]); } const Stmt *getCursorStmt(CXCursor Cursor) { if (Cursor.kind == CXCursor_ObjCSuperClassRef || Cursor.kind == CXCursor_ObjCProtocolRef || Cursor.kind == CXCursor_ObjCClassRef) return nullptr; return static_cast<const Stmt *>(Cursor.data[1]); } const Expr *getCursorExpr(CXCursor Cursor) { return dyn_cast_or_null<Expr>(getCursorStmt(Cursor)); }
// finding referenced variables if(cursorKind == CXCursor_DeclRefExpr) { if(const DeclRefExpr* DRE = dyn_cast_or_null<const DeclRefExpr>(getCursorExpr(cursor))) { if(const VarDecl* VD = dyn_cast_or_null<const VarDecl>(DRE->getDecl())) { if(VD->isLocalVarDecl()) { std::cout << "reference to local variable: "; printCursor(cursor); } } } }
// finding functions not defined in the module if(cursorKind == CXCursor_CallExpr) { if (const Expr *E = getCursorExpr(cursor)) { if(isa<const CallExpr>(E)) { CXCursor Definition = clang_getCursorDefinition(cursor); if (clang_equalCursors(Definition, clang_getNullCursor())) { std::cout << "function is not defined here: "; printCursor(cursor); } } } }
//file func.h void foo_ext(int x); //file simple.c #include "func.h" int global1; int foo(int x) { return x; } int global2; int main(int arg) { int local; local = arg; foo_ext(arg); return foo(local); }
local variable: local@simple.c:13:9 reference to local variable: local@simple.c:14:5 function is not defined here: foo_ext@simple.c:15:5 reference to local variable: local@simple.c:16:16
#include "func.h" class MyClass { public: MyClass() { int SomeLocal_1; } void foo() { int SomeLocal_2; } ~MyClass() { int SomeLocal_3; } }; MyClass myClass_global; int foo(int x) {return 0;} int main(int argc, char** argv) { int local; MyClass myClass_local; foo(argc); foo_ext(local); return 1; }
local variable: SomeLocal_1@cpptest.cpp:6:13 local variable: SomeLocal_2@cpptest.cpp:9:13 local variable: SomeLocal_3@cpptest.cpp:12:13 local variable: local@cpptest.cpp:22:9 local variable: myClass_local@cpptest.cpp:23:13 function is not defined here: foo_ext@cpptest.cpp:25:5 reference to local variable: local@cpptest.cpp:25:13
Source: https://habr.com/ru/post/320074/
All Articles