| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- #ifdef WITH_LIBCLANG
- #include "squirrel.h"
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "sqstdblobimpl.h"
- #include "dynamic_library.h"
- #include <clang-c/Index.h>
- #include <clang-c/Platform.h>
- /*SquiLu
- local dynamic_functions = [
- ["CXIndex", "clang_createIndex",
- @"int excludeDeclarationsFromPCH, int displayDiagnostics"],
- ["void", "clang_disposeIndex", "CXIndex index"],
- ["CXTranslationUnit", "clang_parseTranslationUnit",
- @"CXIndex CIdx,
- const char *source_filename,
- const char *const *command_line_args,
- int num_command_line_args,
- struct CXUnsavedFile *unsaved_files,
- unsigned num_unsaved_files,
- unsigned options"],
- ["CXCursor", "clang_getTranslationUnitCursor", "CXTranslationUnit"],
- ["void", "clang_disposeTranslationUnit", "CXTranslationUnit"],
- ["unsigned", "clang_visitChildren",
- @"CXCursor parent,
- CXCursorVisitor visitor,
- CXClientData client_data"],
- ["enum CXCursorKind", "clang_getCursorKind", "CXCursor"],
- ["CXType", "clang_getCursorType", "CXCursor"],
- ["CXString", "clang_getCursorSpelling", "CXCursor"],
- ["CXString", "clang_getTypeSpelling", "CXType CT"],
- ["CXString", "clang_getCursorKindSpelling", "enum CXCursorKind"],
- ["const char *", "clang_getCString", "CXString string"],
- ["void", "clang_disposeString", "CXString str"],
- ["CXSourceLocation", "clang_getCursorLocation", "CXCursor"],
- ["void", "clang_getPresumedLocation",
- @"CXSourceLocation location,
- CXString *filename,
- unsigned *line,
- unsigned *column"],
- ["enum CXLinkageKind", "clang_getCursorLinkage", "CXCursor"],
- ["CXType", "clang_getResultType", "CXType"],
- ];
- function write_dynamic_functions_declaration(){
- foreach(k,v in dynamic_functions) {
- putsnl("typedef " + v[0] + " (*" + v[1] + "_t)(" + v[2] + ");");
- putsnl("static " + v[1] + "_t dl" + v[1] + " = 0;");
- }
- }
- function write_dynamic_functions_load(){
- foreach(k,v in dynamic_functions){
- putsnl("dl" + v[1] + " = (" + v[1] + "_t) dynamicLib.dlsym(\"" + v[1] + "\");");
- putsnl("if(!dl" + v[1] + ") return false;");
- }
- }
- SquiLu*/
- static DynamicLibrary dynamicLib;
- //@write_dynamic_functions_declaration();
- // generated-code:begin
- typedef CXIndex (*clang_createIndex_t)(int excludeDeclarationsFromPCH, int displayDiagnostics);
- static clang_createIndex_t dlclang_createIndex = 0;
- typedef void (*clang_disposeIndex_t)(CXIndex index);
- static clang_disposeIndex_t dlclang_disposeIndex = 0;
- typedef CXTranslationUnit (*clang_parseTranslationUnit_t)(CXIndex CIdx,
- const char *source_filename,
- const char *const *command_line_args,
- int num_command_line_args,
- struct CXUnsavedFile *unsaved_files,
- unsigned num_unsaved_files,
- unsigned options);
- static clang_parseTranslationUnit_t dlclang_parseTranslationUnit = 0;
- typedef CXCursor (*clang_getTranslationUnitCursor_t)(CXTranslationUnit);
- static clang_getTranslationUnitCursor_t dlclang_getTranslationUnitCursor = 0;
- typedef void (*clang_disposeTranslationUnit_t)(CXTranslationUnit);
- static clang_disposeTranslationUnit_t dlclang_disposeTranslationUnit = 0;
- typedef unsigned (*clang_visitChildren_t)(CXCursor parent,
- CXCursorVisitor visitor,
- CXClientData client_data);
- static clang_visitChildren_t dlclang_visitChildren = 0;
- typedef enum CXCursorKind (*clang_getCursorKind_t)(CXCursor);
- static clang_getCursorKind_t dlclang_getCursorKind = 0;
- typedef CXType (*clang_getCursorType_t)(CXCursor);
- static clang_getCursorType_t dlclang_getCursorType = 0;
- typedef CXString (*clang_getCursorSpelling_t)(CXCursor);
- static clang_getCursorSpelling_t dlclang_getCursorSpelling = 0;
- typedef CXString (*clang_getTypeSpelling_t)(CXType CT);
- static clang_getTypeSpelling_t dlclang_getTypeSpelling = 0;
- typedef CXString (*clang_getCursorKindSpelling_t)(enum CXCursorKind);
- static clang_getCursorKindSpelling_t dlclang_getCursorKindSpelling = 0;
- typedef const char * (*clang_getCString_t)(CXString string);
- static clang_getCString_t dlclang_getCString = 0;
- typedef void (*clang_disposeString_t)(CXString str);
- static clang_disposeString_t dlclang_disposeString = 0;
- typedef CXSourceLocation (*clang_getCursorLocation_t)(CXCursor);
- static clang_getCursorLocation_t dlclang_getCursorLocation = 0;
- typedef void (*clang_getPresumedLocation_t)(CXSourceLocation location,
- CXString *filename,
- unsigned *line,
- unsigned *column);
- static clang_getPresumedLocation_t dlclang_getPresumedLocation = 0;
- typedef enum CXLinkageKind (*clang_getCursorLinkage_t)(CXCursor);
- static clang_getCursorLinkage_t dlclang_getCursorLinkage = 0;
- typedef CXType (*clang_getResultType_t)(CXType);
- static clang_getResultType_t dlclang_getResultType = 0;
- // generated-code:end
- static const char *dynamicLibName = DYNLIB_FOR_OS(libclang);
- static bool load_dynamicLib()
- {
- if(dlclang_createIndex) return true;
- if(dynamicLib.open(dynamicLibName))
- {
- //@write_dynamic_functions_load();
- // generated-code:begin
- dlclang_createIndex = (clang_createIndex_t) dynamicLib.dlsym("clang_createIndex");
- if(!dlclang_createIndex) return false;
- dlclang_disposeIndex = (clang_disposeIndex_t) dynamicLib.dlsym("clang_disposeIndex");
- if(!dlclang_disposeIndex) return false;
- dlclang_parseTranslationUnit = (clang_parseTranslationUnit_t) dynamicLib.dlsym("clang_parseTranslationUnit");
- if(!dlclang_parseTranslationUnit) return false;
- dlclang_getTranslationUnitCursor = (clang_getTranslationUnitCursor_t) dynamicLib.dlsym("clang_getTranslationUnitCursor");
- if(!dlclang_getTranslationUnitCursor) return false;
- dlclang_disposeTranslationUnit = (clang_disposeTranslationUnit_t) dynamicLib.dlsym("clang_disposeTranslationUnit");
- if(!dlclang_disposeTranslationUnit) return false;
- dlclang_visitChildren = (clang_visitChildren_t) dynamicLib.dlsym("clang_visitChildren");
- if(!dlclang_visitChildren) return false;
- dlclang_getCursorKind = (clang_getCursorKind_t) dynamicLib.dlsym("clang_getCursorKind");
- if(!dlclang_getCursorKind) return false;
- dlclang_getCursorType = (clang_getCursorType_t) dynamicLib.dlsym("clang_getCursorType");
- if(!dlclang_getCursorType) return false;
- dlclang_getCursorSpelling = (clang_getCursorSpelling_t) dynamicLib.dlsym("clang_getCursorSpelling");
- if(!dlclang_getCursorSpelling) return false;
- dlclang_getTypeSpelling = (clang_getTypeSpelling_t) dynamicLib.dlsym("clang_getTypeSpelling");
- if(!dlclang_getTypeSpelling) return false;
- dlclang_getCursorKindSpelling = (clang_getCursorKindSpelling_t) dynamicLib.dlsym("clang_getCursorKindSpelling");
- if(!dlclang_getCursorKindSpelling) return false;
- dlclang_getCString = (clang_getCString_t) dynamicLib.dlsym("clang_getCString");
- if(!dlclang_getCString) return false;
- dlclang_disposeString = (clang_disposeString_t) dynamicLib.dlsym("clang_disposeString");
- if(!dlclang_disposeString) return false;
- dlclang_getCursorLocation = (clang_getCursorLocation_t) dynamicLib.dlsym("clang_getCursorLocation");
- if(!dlclang_getCursorLocation) return false;
- dlclang_getPresumedLocation = (clang_getPresumedLocation_t) dynamicLib.dlsym("clang_getPresumedLocation");
- if(!dlclang_getPresumedLocation) return false;
- dlclang_getCursorLinkage = (clang_getCursorLinkage_t) dynamicLib.dlsym("clang_getCursorLinkage");
- if(!dlclang_getCursorLinkage) return false;
- dlclang_getResultType = (clang_getResultType_t) dynamicLib.dlsym("clang_getResultType");
- if(!dlclang_getResultType) return false;
- // generated-code:end
- return true;
- }
- return false;
- }
- ////////////////////////////////////////////////////////////////////////////////
- static const SQChar *LibClang_TAG = _SC("LibClang");
- struct MyLibClang {
- CXIndex index;
- int depth;
- const char *file_name;
- char *function_name;
- HSQUIRRELVM v;
- HSQOBJECT visitor_cb;
- HSQOBJECT visitor_udata;
- };
- static SQRESULT get_libclang_instance(HSQUIRRELVM v, SQInteger idx, MyLibClang **self){
- SQRESULT _rc_;
- if((_rc_ = sq_getinstanceup(v,idx,(SQUserPointer*)self,(void*)LibClang_TAG)) < 0) return _rc_;
- if(!*self) return sq_throwerror(v, _SC("libclang is closed"));
- return _rc_;
- }
- #define GET_libclang_INSTANCE_AT(idx) \
- MyLibClang *self=NULL; \
- if((_rc_ = get_libclang_instance(v,idx,&self)) < 0) return _rc_;
- #define GET_libclang_INSTANCE() GET_libclang_INSTANCE_AT(1)
- static void release_visitor_cb(MyLibClang *self)
- {
- sq_release(self->v, &self->visitor_cb);
- sq_resetobject(&self->visitor_cb);
- }
- static SQRESULT sq_libclang_releasehook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
- {
- MyLibClang *self = ((MyLibClang *)p);
- if (self)
- {
- if(self->index)
- {
- dlclang_disposeIndex(self->index);
- }
- release_visitor_cb(self);
- sq_free(self, sizeof(MyLibClang));
- }
- return 0;
- }
- static SQRESULT sq_libclang_constructor(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS_NO_TOP(v);
- if(!load_dynamicLib()) return sq_throwerror(v, _SC("Failed to load libclang !"));
- MyLibClang *self = (MyLibClang *)sq_malloc(sizeof(MyLibClang));
- memset(self, 0, sizeof(MyLibClang));
- self->v = v;
- self->index = dlclang_createIndex(0, 0);
- sq_setinstanceup(v, 1, self);
- sq_setreleasehook(v,1, sq_libclang_releasehook);
- return 1;
- }
- static SQRESULT sq_libclang_close(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_libclang_INSTANCE();
- sq_libclang_releasehook(self, sizeof(MyLibClang), v);
- sq_setinstanceup(v, 1, 0); //next calls will fail with "libclang is closed"
- return 0;
- }
- static void call_visitor_cb(MyLibClang *self, const SQChar *sig, ...)
- {
- HSQUIRRELVM v = self->v;
- int top = sq_gettop(v);
- sq_pushobject(v, self->visitor_cb);
- //sq_pushroottable(v);
- //sq_pushobject(v, self->busy_udata);
- va_list vl;
- va_start(vl, sig);
- SQRESULT rc = sq_call_va_vl(v, SQFalse, -1, NULL, 0, sig, vl);
- va_end(vl);
- sq_settop(v, top);
- }
- static enum CXChildVisitResult
- functionDeclVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
- {
- MyLibClang *cvu = (MyLibClang*) client_data;
- enum CXCursorKind kind = dlclang_getCursorKind(cursor);
- CXType type = dlclang_getCursorType(cursor);
- CXString type_spelling;
- CXString type_kind_spelling;
- CXString name;
- if (kind == CXCursor_ParmDecl){
- name = dlclang_getCursorSpelling(cursor);
- type_spelling = dlclang_getTypeSpelling(type);
- //db_add_funcparam(cvu->db, cvu->function_name, dlclang_getCString(name), dlclang_getCString(type_spelling), type.kind);
- call_visitor_cb(cvu, "sssssi",
- "FuncParam",
- cvu->file_name,
- cvu->function_name,
- dlclang_getCString(name),
- dlclang_getCString(type_spelling),
- type.kind);
- dlclang_disposeString(name);
- dlclang_disposeString(type_spelling);
- }
- return CXChildVisit_Continue;
- }
- static enum CXChildVisitResult
- cursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
- {
- MyLibClang *cvu = (MyLibClang*) client_data;
- enum CXCursorKind kind = dlclang_getCursorKind(cursor);
- CXString name = dlclang_getCursorSpelling(cursor);
- enum CXChildVisitResult ret = CXChildVisit_Recurse;
- CXString filename;
- unsigned int line, column;
- CXSourceLocation location = dlclang_getCursorLocation(cursor);
- dlclang_getPresumedLocation(location, &filename, &line, &column);
- cvu->file_name = dlclang_getCString(filename);
- //sqlite_int64 file_id = db_add_funcfile(cvu->db, dlclang_getCString(filename));
- //call_visitor_cb(cvu, "ss", "FuncFile", dlclang_getCString(filename));
- if (kind == CXCursor_FunctionDecl) {
- enum CXLinkageKind lk = dlclang_getCursorLinkage(cursor);
- CXType type = dlclang_getCursorType(cursor);
- CXString type_spelling = dlclang_getTypeSpelling(type);
- CXType rtype = dlclang_getResultType(type);
- CXString rtype_spelling = dlclang_getTypeSpelling(rtype);
- free(cvu->function_name);
- cvu->function_name = strdup(dlclang_getCString(name));
- //db_add_funcdecl(cvu->db, cvu->function_name, dlclang_getCString(type_spelling),
- // dlclang_getCString(rtype_spelling), lk, file_id, line, column);
- call_visitor_cb(cvu, "ssiissi",
- "FuncDecl",
- cvu->file_name,
- line,
- column,
- cvu->function_name,
- dlclang_getCString(type_spelling),
- dlclang_getCString(rtype_spelling),
- lk);
- dlclang_visitChildren(cursor, *functionDeclVisitor, cvu);
- } else if (kind == CXCursor_CallExpr) {
- //CXType type = clang_getCursorType(cursor);
- //CXString type_spelling = clang_getTypeSpelling(type);
- //printf("%s\n", type_spelling);
- //db_add_funccall(cvu->db, cvu->function_name, dlclang_getCString(name), file_id, line, column);
- call_visitor_cb(cvu, "ssiiss",
- "CallExpr",
- cvu->file_name,
- line,
- column,
- cvu->function_name,
- dlclang_getCString(name));
- ret = CXChildVisit_Continue;
- }
- dlclang_disposeString(name);
- return ret;
- }
- static SQRESULT sq_libclang_parseTranslationUnit(HSQUIRRELVM v){
- SQ_FUNC_VARS(v);
- GET_libclang_INSTANCE();
- if(sq_gettype(v, 2) != OT_CLOSURE)
- return sq_throwerror(v, _SC("invalid fisrt parameter expected closure"));
- SQ_GET_STRING(v, 3, fname);
- release_visitor_cb(self);
- sq_getstackobj(v, 2, &self->visitor_cb);
- sq_addref(v, &self->visitor_cb);
- const char *cl_args[] = {"-I."};
- int cl_argNum = 1;
- if(_top_ > 3)
- {
- //create cl_args with extra parameters
- }
- CXTranslationUnit TU;
- TU = dlclang_parseTranslationUnit(self->index, fname,
- cl_args, cl_argNum, 0, 0, CXTranslationUnit_Incomplete);
- if (TU == NULL) {
- return sq_throwerror(v, _SC("clang_parseTranslationUnit for %s failed\n"), fname);
- }
- CXCursor rootCursor = dlclang_getTranslationUnitCursor(TU);
- dlclang_visitChildren(rootCursor, cursorVisitor, self);
- dlclang_disposeTranslationUnit(TU);
- return 0;
- }
- #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name), sq_libclang_##name,nparams,tycheck}
- static SQRegFunction sq_libclang_methods[] =
- {
- _DECL_FUNC(constructor, 1, _SC("x")),
- _DECL_FUNC(close, 1, _SC("x")),
- _DECL_FUNC(parseTranslationUnit, -3, _SC("xcs")),
- {0,0}
- };
- #undef _DECL_FUNC
- #ifdef __cplusplus
- extern "C" {
- #endif
- SQRESULT sqext_register_libclang(HSQUIRRELVM v)
- {
- sq_pushstring(v,LibClang_TAG,-1);
- sq_newclass(v,SQFalse);
- sq_settypetag(v,-1,(void*)LibClang_TAG);
- sq_insert_reg_funcs(v, sq_libclang_methods);
- sq_newslot(v,-3,SQTrue);
- return 0;
- }
- #ifdef __cplusplus
- }
- #endif
- #endif // WITH_LIBCLANG
|