Skip to content

Instantly share code, notes, and snippets.

@yifu
Created September 21, 2012 14:37
Show Gist options
  • Save yifu/3761845 to your computer and use it in GitHub Desktop.
Save yifu/3761845 to your computer and use it in GitHub Desktop.
Clang framework tutorial.
#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