Created
September 21, 2012 14:37
-
-
Save yifu/3761845 to your computer and use it in GitHub Desktop.
Clang framework tutorial.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <clang-c/Index.h> | |
#include <iostream> | |
#include <string> | |
///////////////////////////////////////////////////// | |
///////////////////////////////////////////////////// | |
// gcc -I /data/mag/ut0tyb/llvm-3.0/include/ /data/mag/ut0tyb/llvm-3.0/lib/libclang.a syntax-check.cpp | |
///////////////////////////////////////////////////// | |
///////////////////////////////////////////////////// | |
// export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/data/mag/ut0tyb/llvm-3.0/lib/ | |
// gcc -I /data/mag/ut0tyb/llvm-3.0/include/ -L /data/mag/ut0tyb/llvm-3.0/lib/ -lclang syntax-check.cpp | |
///////////////////////////////////////////////////// | |
CXTranslationUnit tr_unit; | |
///////////////////////////////////////////////////// | |
std::string getClangFileName(const CXFile& file) | |
{ | |
std::string filename; | |
CXString cxfilename = clang_getFileName(file); | |
if (clang_getCString(cxfilename) != 0) filename = clang_getCString(cxfilename); | |
clang_disposeString(cxfilename); | |
return "\"" + filename + "\""; | |
} | |
///////////////////////////////////////////////////// | |
void printLocation(CXSourceLocation location) | |
{ | |
CXFile file; | |
unsigned int line = 0, col = 0, offset = 0; | |
clang_getSpellingLocation(location, &file, &line, &col, &offset); | |
std::cout << line << ", " << col << ", " << offset << ", " << getClangFileName(file); | |
} | |
///////////////////////////////////////////////////// | |
void printExtent(CXSourceRange range) | |
{ | |
/* | |
std::cout << "Extent begin at location ["; | |
printLocation(clang_getRangeStart(range)); | |
std::cout << "]. \n"; | |
std::cout << "Extent finish at location ["; | |
printLocation(clang_getRangeEnd(range)); | |
std::cout << "]. \n"; | |
*/ | |
CXToken* tokens = 0; | |
unsigned int nTokens = 0; | |
clang_tokenize(tr_unit, range, &tokens, &nTokens); | |
for(int i = 0; i < nTokens; ++i) | |
{ | |
CXString cxtoken = clang_getTokenSpelling(tr_unit, tokens[i]); | |
std::cout << clang_getCString(cxtoken) << " "; | |
clang_disposeString(cxtoken); | |
} | |
clang_disposeTokens(tr_unit, tokens, nTokens); | |
} | |
///////////////////////////////////////////////////// | |
//CXCursorVisitor visit | |
enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent, CXClientData client_data) | |
{ | |
CXString cxcursor = clang_getCursorSpelling(cursor); | |
CXString cxcursorKind = clang_getCursorKindSpelling(clang_getCursorKind(cursor)); | |
std::cout << "Cursor name is \"" << clang_getCString(cxcursor) << "\", " | |
<< "type is (" << clang_getCString(cxcursorKind) << "). "; | |
clang_disposeString(cxcursorKind); | |
clang_disposeString(cxcursor); | |
std::cout << "Location is "; | |
printLocation(clang_getCursorLocation(cursor)); | |
std::cout << ". "; | |
std::cout << "||"; | |
printExtent(clang_getCursorExtent(cursor)); | |
std::cout << "||"; | |
std::cout << "\n"; | |
return CXChildVisit_Recurse; | |
} | |
///////////////////////////////////////////////////// | |
void printDiagInfos(CXDiagnostic diag) | |
{ | |
/* fprintf(stderr, "diag severity: %i\n", clang_getDiagnosticSeverity(diag));*/ | |
/* fprintf(stderr, "diag location: %s\n", clang_getDiagnosticLocation(diag));*/ | |
/* | |
CXString diagSpelling_str = clang_getDiagnosticSpelling(diag); | |
fprintf(stderr, "%s\n", clang_getCString(diagSpelling_str)); | |
clang_disposeString(diagSpelling_str); | |
*/ | |
} | |
///////////////////////////////////////////////////// | |
void printFixIts(CXDiagnostic diag) | |
{ | |
int numFixIts = clang_getDiagnosticNumFixIts(diag); | |
for (int j = 0; j != numFixIts; ++j) | |
{ | |
CXSourceRange src_range; | |
CXString fixIt_str = clang_getDiagnosticFixIt(diag, j, &src_range); | |
std::cout << clang_getCString(fixIt_str) << std::endl; | |
clang_disposeString(fixIt_str); | |
} | |
} | |
///////////////////////////////////////////////////// | |
int main(int argc, char* argv[]) | |
{ | |
///////////////////////////////////////////////////// | |
// 0 - Init. | |
CXIndex index = clang_createIndex(0,0); | |
/*CXTranslationUnit*/ tr_unit = clang_parseTranslationUnit(index, 0, argv, argc, 0, 0, CXTranslationUnit_None); | |
///////////////////////////////////////////////////// | |
// 1 - Diagnose Warnings and Errors. | |
int n = clang_getNumDiagnostics(tr_unit); | |
for (int i = 0; i != n; ++i) | |
{ | |
CXDiagnostic diag = clang_getDiagnostic(tr_unit, i); | |
CXString diag_str = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions()); | |
std::cout << clang_getCString(diag_str) << std::endl; | |
clang_disposeString(diag_str); | |
printDiagInfos(diag); | |
printFixIts(diag); | |
} | |
///////////////////////////////////////////////////// | |
// 2 - Browse AST. | |
// CXFile file = clang_getFile(tr_unit, argv[1]); | |
CXCursor root = clang_getTranslationUnitCursor(tr_unit); | |
clang_visitChildren(root, visit, (void*)0/*client_data*/); | |
///////////////////////////////////////////////////// | |
// Last - Cleanup | |
clang_disposeTranslationUnit(tr_unit); | |
clang_disposeIndex(index); | |
std::cout << "end" << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment