void ast_json::record_tokens( json_t& obj, CXCursor cursor, CXTranslationUnit translation_unit) { // Get source code extent of node CXSourceRange extent = clang_getCursorExtent(cursor); // Tokenize node's contents CXToken *tokens; unsigned int nTokens; clang_tokenize(translation_unit, extent, &tokens, &nTokens); // JSONize every token for (unsigned i = 0; i < nTokens; i++) { const CXToken& token = tokens[i]; json_t jsontoken; record_token(jsontoken, token, translation_unit); obj.add(jsontoken); } // Release tokens clang_disposeTokens(translation_unit, tokens, nTokens); }
void Html_File::write_html(void) { cur_line_ = 1; cur_column_ = 1; CXFile file = clang_getFile(tu_file_->tu(), source_filename_.c_str()); CXSourceRange range = clang_getRange(clang_getLocationForOffset(tu_file_->tu(), file, 0), clang_getLocationForOffset(tu_file_->tu(), file, tu_file_->length())); CXToken *tokens; unsigned num; clang_tokenize(tu_file_->tu(), range, &tokens, &num); FILE* f = fopen(html_filename_.c_str(), "w"); if (f) { write_header(f); for (unsigned i = 0; i < num; ++i) write_comment_split(f, file, tokens[i]); fprintf(f, "</pre></div></div></body></html>"); fclose(f); } else std::cerr << "error: could not create file: " << html_filename_.c_str() << "\n"; clang_disposeTokens(tu_file_->tu(), tokens, num); }
void ClangParser::switchToFile(const char *fileName) { if (p->tu) { delete[] p->cursors; clang_disposeTokens(p->tu,p->tokens,p->numTokens); p->tokens = 0; p->numTokens = 0; p->cursors = 0; QFileInfo fi(fileName); CXFile f = clang_getFile(p->tu, fileName); uint *pIndex=p->fileMapping.find(fileName); if (pIndex && *pIndex<p->numFiles) { uint i=*pIndex; //printf("switchToFile %s: len=%ld\n",fileName,p->ufs[i].Length); CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0); CXSourceLocation fileEnd = clang_getLocationForOffset(p->tu, f, p->ufs[i].Length); CXSourceRange fileRange = clang_getRange(fileBegin, fileEnd); clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens); p->cursors=new CXCursor[p->numTokens]; clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors); p->curLine = 1; p->curToken = 0; } else { err("clang: Failed to find input file %s in mapping\n",fileName); } } }
void ClangParser::finish() { static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); if (!clangAssistedParsing) return; if (p->tu) { //printf("ClangParser::finish()\n"); delete[] p->cursors; clang_disposeTokens(p->tu,p->tokens,p->numTokens); clang_disposeTranslationUnit(p->tu); clang_disposeIndex(p->index); p->fileMapping.clear(); p->tokens = 0; p->numTokens = 0; p->cursors = 0; } for (uint i=0;i<p->numFiles;i++) { free((void *)p->ufs[i].Filename); } delete[] p->ufs; delete[] p->sources; p->ufs = 0; p->sources = 0; p->numFiles = 0; p->tu = 0; }
static CXCursor getCursorUsingTokens(CXTranslationUnit tu, CXCursor cursor, unsigned int desiredOffset) { // The following does not return a more definitive cursor. // For example, if a compound statement is returned, this does not find // any variables in the statement. CXSourceRange range = clang_getCursorExtent(cursor); CXToken *tokens; unsigned numTokens; clang_tokenize(tu, range, &tokens, &numTokens); unsigned int closestOffset = 0; for(unsigned int i=0; i<numTokens; i++) { CXSourceLocation loc = clang_getTokenLocation(tu, tokens[i]); unsigned int offset; CXFile file; clang_getSpellingLocation(loc, &file, nullptr, nullptr, &offset); if(offset < desiredOffset && offset > closestOffset) { closestOffset = offset; cursor = clang_getCursor(tu, loc); } } clang_disposeTokens(tu, tokens, numTokens); return cursor; }
std::string tokenize_as_vimson(char const* const* args, size_t const argc) { CXIndex index = clang_createIndex(/*excludeDeclsFromPCH*/ 1, /*displayDiagnostics*/0); translation_unit = clang_parseTranslationUnit(index, file_name.c_str(), args, argc, NULL, 0, CXTranslationUnit_Incomplete); if (translation_unit == NULL) { clang_disposeIndex(index); return "{}"; } auto file_range = get_range_whole_file(); if (clang_Range_isNull(file_range)) { clang_disposeTranslationUnit(translation_unit); clang_disposeIndex(index); return "{}"; } CXToken *tokens_; unsigned int num_tokens; clang_tokenize(translation_unit, file_range, &tokens_, &num_tokens); std::vector<CXToken> tokens(tokens_, tokens_ + num_tokens); auto result = make_vimson_from_tokens(tokens); clang_disposeTokens(translation_unit, tokens_, num_tokens); clang_disposeTranslationUnit(translation_unit); clang_disposeIndex(index); return result; }
void ClangParser::finish() { if (p->tu) { delete[] p->cursors; clang_disposeTokens(p->tu, p->tokens, p->numTokens); clang_disposeTranslationUnit(p->tu); clang_disposeIndex(p->index); p->fileMapping.clear(); p->tokens = 0; p->numTokens = 0; p->cursors = 0; } for (uint i = 0; i < p->numFiles; i++) { free((void *)p->ufs[i].Filename); } delete[] p->ufs; delete[] p->sources; p->ufs = 0; p->sources = 0; p->numFiles = 0; p->tu = 0; }
/// @todo - this is a duplicate of a function in ParseBase.cpp void appendCursorTokenString(CXCursor cursor, std::string &str) { CXSourceRange range = clang_getCursorExtent(cursor); CXToken *tokens = 0; unsigned int nTokens = 0; CXTranslationUnit tu = clang_Cursor_getTranslationUnit(cursor); clang_tokenize(tu, range, &tokens, &nTokens); for (size_t i = 0; i < nTokens; i++) { CXTokenKind kind = clang_getTokenKind(tokens[i]); if(kind != CXToken_Comment) { if(str.length() != 0) str += " "; CXStringDisposer spelling = clang_getTokenSpelling(tu, tokens[i]); str += spelling; } } clang_disposeTokens(tu, tokens, nTokens); }
std::string getFirstNonCommentToken(CXCursor cursor) { CXSourceRange range = clang_getCursorExtent(cursor); CXToken *tokens = 0; unsigned int nTokens = 0; CXTranslationUnit tu = clang_Cursor_getTranslationUnit(cursor); clang_tokenize(tu, range, &tokens, &nTokens); std::string str; for (size_t i = 0; i < nTokens; i++) { CXTokenKind kind = clang_getTokenKind(tokens[i]); if(kind != CXToken_Comment) { CXStringDisposer spelling = clang_getTokenSpelling(tu, tokens[i]); str += spelling; break; } } clang_disposeTokens(tu, tokens, nTokens); return str; }
void TokenRange::tokenize(CXTranslationUnit transUnit) { CXCursor cursor = clang_getTranslationUnitCursor(transUnit); CXSourceRange range = clang_getCursorExtent(cursor); CXToken *tokens = 0; unsigned int numTokens = 0; clang_tokenize(transUnit, range, &tokens, &numTokens); resize(numTokens); if(numTokens > 0) { for (size_t i = 0; i < numTokens-1; i++) { at(i).setKind(clang_getTokenKind(tokens[i])); CXSourceRange tokRange = clang_getTokenExtent(transUnit, tokens[i]); clang_getExpansionLocation(clang_getRangeStart(tokRange), NULL, NULL, NULL, &at(i).mStartOffset); clang_getExpansionLocation(clang_getRangeEnd(tokRange), NULL, NULL, NULL, &at(i).mEndOffset); } } clang_disposeTokens(transUnit, tokens, numTokens); }
void printTreeRecursive(struct treeNode* node, CXTranslationUnit cxtup) { depth++; if(node->modified == 0) { CXSourceRange range = clang_getCursorExtent(node->cursor); CXSourceLocation rstart = clang_getRangeStart(range); if(clang_Location_isFromMainFile(rstart) != 0) { enum CXCursorKind cursorkind = clang_getCursorKind(node->cursor); if(depth == 1 && cursorkind != CXCursor_MacroExpansion) { nodenum++; if(cursorkind == CXCursor_StructDecl) { CXToken* currTokens; unsigned int numCurrTokens; clang_tokenize(cxtup, range, &currTokens, &numCurrTokens); CXToken token = currTokens[numCurrTokens-1]; CXString tokenstring = clang_getTokenSpelling(cxtup, token); char* tokenstr = clang_getCString(tokenstring); clang_disposeTokens(cxtup, currTokens, numCurrTokens); //printf("\ntoken: %s\n", tokenstr); if(strcmp(tokenstr, ";")) { clang_disposeString(tokenstring); // Print nothing, do nothing. } else { clang_disposeString(tokenstring); goto PRINT; } } else { PRINT: 1+1; CXToken* tokens; unsigned int numTokens; clang_tokenize(cxtup, range, &tokens, &numTokens); CXString tokenstring; CXSourceRange tokenrange; unsigned* startcol = malloc(sizeof(unsigned)); unsigned* startline = malloc(sizeof(unsigned)); unsigned* endcol = malloc(sizeof(unsigned)); unsigned* endline = malloc(sizeof(unsigned)); for(int i = 0; i<numTokens; i++) { tokenrange = clang_getTokenExtent(cxtup, tokens[i]); tokenstring = clang_getTokenSpelling(cxtup, tokens[i]); CXSourceLocation currend = clang_getRangeEnd(tokenrange); clang_getFileLocation(currend, NULL, endline, endcol, NULL); if(prevcol != 0) { CXSourceLocation currstart = clang_getRangeStart(tokenrange); clang_getFileLocation(currstart, NULL, startline, startcol, NULL); //printf("L%u-%u, C%u-%u", *startline, prevline, *startcol, prevcol); int startl = *startline; int startc = *startcol; for(int i = 0; i < startl-prevline; i++) { printf("\n"); //printf("*startline-prevline = %u, i = %u, prevline = %u\n", start-prevline, i, prevline); } if(startc-prevcol >= 0) { for(int i = 0; i < startc-prevcol; i++) { printf(" "); } } else { for(int i = 1; i < startc; i++) { printf(" "); } } } char* tstr = clang_getCString(tokenstring); /*if(i == 0 && !strcmp(tstr, lastPrintedToken)) { // Do nothing, print nothing. } else {*/ printf("%s", tstr); //} prevline = *endline; prevcol = *endcol; char* str = clang_getCString(tokenstring); strcpy(lastPrintedToken, str); clang_disposeString(tokenstring); } //printf("%i\n", lastPrintedToken); //printf("\n"); clang_disposeTokens(cxtup, tokens, numTokens); free(startcol); free(startline); free(endcol); free(endline); } } } } else if(depth == 1) { //printf("Modified node detected."); if(node->validcursor == false) { //Print modified //printf("%s\n", node->newContent); } else { struct treeNode** nodes = malloc((node->modified) * sizeof(struct treeNode)); //printf("%i\n", sizeof(nodes)) nodes[node->modified-1] = NULL; //printf("nodes[node->modified-1]: %i\n", nodes[node->modified-1]); struct treeNode* next = NULL; int nextnode = 0; int smallestcol = INT_MAX; int smallestline = INT_MAX; int cscol = INT_MIN; int csline = INT_MIN; struct treeListNode* currnode = node->modifiedNodes; CXSourceRange srange; CXSourceLocation sloc; bool first = true; while(nodes[(node->modified)-1] == NULL) { while(currnode != NULL) { if(currnode->node->startline == -1) { srange = clang_getCursorExtent(currnode->node->cursor); sloc = clang_getRangeStart(srange); clang_getFileLocation(sloc, NULL, &(currnode->node->startline), &(currnode->node->startcol), NULL); //printf("Calculated node %i: startline: %i, startcol: %i\n", currnode->node, currnode->node->startline, currnode->node->startcol); } //printf("\ncurrnode->node: %i, nextnode: %i\nnstartline: %i, smallestline: %i ,csline: %i\nnstartcol: %i, smallestcol: %i, cscol: %i\n", currnode->node, nextnode, currnode->node->startline, smallestline, csline, currnode->node->startcol, smallestcol, cscol); if(currnode->node->startline < smallestline) { //printf("\n1\, %i < %i", currnode->node->startline, smallestline); if((currnode->node->startline > csline) || (first == true)) { //printf("\n2, %i > %i", currnode->node->startline); smallestline = currnode->node->startline; smallestcol = currnode->node->startcol; csline = currnode->node->startline; cscol = currnode->node->startcol; next = currnode->node; } } else if(currnode->node->startline == smallestline) { //printf("3\n"); if(currnode->node->startcol < smallestcol) { //printf("4\n"); if((currnode->node->startcol > cscol) || (first == true)) { //printf("5\n"); smallestline = currnode->node->startline; smallestcol = currnode->node->startcol; csline = currnode->node->startline; cscol = currnode->node->startcol; next = currnode->node; } } } //printf("\n6\n"); //printf("currnode->node: %i, nextnode: %i\nnstartline: %i, smallestline: %i ,csline: %i\nnstartcol: %i, smallestcol: %i, cscol: %i\n", currnode->node, nextnode, currnode->node->startline, smallestline, csline, currnode->node->startcol, smallestcol, cscol); currnode = currnode->next; } first = false; //printf("%i ", nodes[nextnode]); //printf("%i\n", next); nodes[nextnode] = next; nextnode++; smallestcol = INT_MAX; smallestline = INT_MAX; currnode = node->modifiedNodes; } for(int i = 0; i <= 1; i++) { //printf("nodenum: %i, nstartline: %i, nstartcol: %i\n", i, nodes[i]->startline, nodes[i]->startcol); } CXSourceRange range = clang_getCursorExtent(node->cursor); CXToken* tokens; unsigned int numTokens; int numNodes = nextnode; nextnode = 0; clang_tokenize(cxtup, range, &tokens, &numTokens); for(int i = 0; i<numTokens; i++) { CXSourceRange tokenrange = clang_getTokenExtent(cxtup, tokens[i]); CXString tokenstring = clang_getTokenSpelling(cxtup, tokens[i]); unsigned startline; unsigned startcol; unsigned endline; unsigned endcol; CXSourceLocation currend = clang_getRangeEnd(tokenrange); clang_getFileLocation(currend, NULL, &endline, &endcol, NULL); if(prevcol != 0) { CXSourceLocation currstart = clang_getRangeStart(tokenrange); clang_getFileLocation(currstart, NULL, &startline, &startcol, NULL); //printf("L%u-%u, C%u-%u", *startline, prevline, *startcol, prevcol); int startl = startline; int startc = startcol; for(int i = 0; i < startl-prevline; i++) { printf("\n"); //printf("*startline-prevline = %u, i = %u, prevline = %u\n", start-prevline, i, prevline); } if(startc-prevcol >= 0) { for(int i = 0; i < startc-prevcol; i++) { printf(" "); } } else { for(int i = 0; i < startc; i++) { printf(" "); } } } char* tstr = clang_getCString(tokenstring); if(i == 0 && !strcmp(tstr, lastPrintedToken)) { // Do nothing, print nothing. } else { //printf("nextstartline: %i, startline: %i\n", nodes[nextnode]->startline, startline); if((nextnode < numNodes) && (nodes[nextnode]->startline == startline) && (nodes[nextnode]->startcol == startcol)) { int* nodenext = &(nodes[nextnode]->cursor); if(nodenext == NULL) { printf("%s\n", nodes[nextnode]->newContent); nextnode++; } else { printf("%s", nodes[nextnode]->newContent); prevline = endline; prevcol = endcol; nextnode++; } } else { printf("%s", tstr); prevline = endline; prevcol = endcol; } } //printf("%i\n", sizeof(nodes)); char* str = clang_getCString(tokenstring); strcpy(lastPrintedToken, str); clang_disposeString(tokenstring); } clang_disposeTokens(cxtup, tokens, numTokens); free(nodes); } } if(node->children != NULL) { struct treeListNode* childlist = node->children; while(childlist != NULL) { printTreeRecursive(childlist->node, cxtup); childlist = childlist->next; } } depth--; }
~token_pack() { clang_disposeTokens(tu_.impl, data_, size_); }
token_set::~token_set() { if(tokens) clang_disposeTokens(tu, tokens, size); }
void TokenizeSource(CXTranslationUnit tu) { CXSourceRange range = clang_getCursorExtent( clang_getTranslationUnitCursor(tu) ); CXToken *tokens; unsigned int token_count; clang_tokenize( tu, range, &tokens, &token_count ); //CXCursor cursors[ token_count ]; //clang_annotateTokens( tu, tokens, token_count, cursors ); auto cursors = my_annotateTokens( tu, tokens, token_count ); for ( auto t = 0u; t < token_count; ++t ) { auto tkind = clang_getTokenKind(tokens[t] ); auto tspelling = tkind == CXToken_Identifier ? CursorKindSpelling( cursors[ t ] ) : TokenKindSpelling( tkind ); auto textent = clang_getTokenExtent( tu, tokens[t] ); auto tstartloc = clang_getRangeStart( textent ); auto tendloc = clang_getRangeEnd( textent ); auto tokspell = clang_getTokenSpelling( tu, tokens[ t ] ); std::cout << "TokenSpelling: " << tokspell << "\n"; std::cout << "Cursor: " << cursors[ t ] << "\n"; // if ( !( cursors[t].kind >= CXCursor_FirstInvalid && // cursors[t].kind <= CXCursor_LastInvalid ) ) { // auto rr = clang_getCursorExtent( cursors[ t ] ); // std::cout << "Range: " << rr << "\n"; // } // std::cout << clang_getCursorDisplayName( cursors[ t ] ) << "\n"; // std::cout << "USR: "******"\n"; unsigned int startoffset, endoffset; clang_getSpellingLocation( tstartloc, nullptr, nullptr, nullptr, &startoffset ); clang_getSpellingLocation( tendloc, nullptr, nullptr, nullptr, &endoffset ); // TODO: testing this hack for int -> identifier instead of keyword // but this loses const to an identifier also! fvck! if ( tspelling == "Keyword" ) { auto type = clang_getCursorType( cursors[ t ] ); auto typekind = type.kind; CXString typespelling; if ( cursors[t].kind == CXCursor_FunctionDecl || cursors[t].kind == CXCursor_CXXMethod ) { type = clang_getResultType( type ); typekind = type.kind; typespelling = clang_getTypeSpelling( type ); } else typespelling = clang_getTypeSpelling( type ); // std::cout << "Type = " << type << " kind: " << typekind << "\n"; // std::cout << clang_getCString(typespelling) << " <-> " << clang_getCString(tokspell) << "\n"; // std::cout << " Const? " << clang_isConstQualifiedType( type ) << "\n"; if ( (( typekind >= CXType_FirstBuiltin && typekind <= CXType_LastBuiltin ) && ( std::string(clang_getCString(typespelling)) == std::string(clang_getCString(tokspell) ) )) || // ( cursors[t].kind == CXCursor_VarDecl ) || ( cursors[t].kind == CXCursor_ParmDecl ) ) tspelling = "Identifier"; } //if ( tspelling != "Punctuation" ) std::cout << startoffset << ":" << endoffset << " @ " << tspelling << "\n"; clang_disposeString( tokspell ); } std::cout << "\n" << end_pattern << "\n"; clang_disposeTokens( tu, tokens, token_count ); }
enum CXChildVisitResult visit_program(CXCursor cursor, CXCursor parent, CXClientData data){ json_t* program = (json_t*)data; json_t* js = NULL; enum CXChildVisitResult ret = CXChildVisit_Continue; switch (clang_getCursorKind(cursor)) { case CXCursor_FunctionDecl: case CXCursor_VarDecl: js = json_object(); json_object_set_new(js, "name", render_string(clang_getCursorSpelling(cursor))); json_object_set_new(js, "display_name", render_string(clang_getCursorDisplayName(cursor))); json_object_set_new(js, "type", render_type(clang_getCursorType(cursor))); if (clang_getCursorKind(cursor) == CXCursor_FunctionDecl) { json_object_set_new(js, "argument_names", json_array()); json_object_set_new(js, "kind", json_string("function")); } else { json_object_set_new(js, "kind", json_string("variable")); } switch (clang_getCursorLinkage(cursor)) { case CXLinkage_Internal: json_object_set_new(js, "linkage", json_string("static")); break; case CXLinkage_UniqueExternal: json_object_set_new(js, "linkage", json_string("anonymous")); break; case CXLinkage_External: break; default: json_object_set_new(js, "linkage", json_string("unknown")); } clang_visitChildren(cursor, visit_object, (CXClientData)js); break; case CXCursor_StructDecl: case CXCursor_UnionDecl: js = json_object(); json_object_set_new(js, "kind", json_string(clang_getCursorKind(cursor) == CXCursor_UnionDecl ? "union" : "struct")); json_object_set_new(js, "name", render_string(clang_getCursorSpelling(cursor))); json_object_set_new(js, "fields", json_array()); clang_visitChildren(cursor, visit_structure, (CXClientData)js); ret = CXChildVisit_Recurse; break; case CXCursor_EnumDecl: js = json_object(); json_object_set_new(js, "kind", json_string("enum")); json_object_set_new(js, "name", render_string(clang_getCursorSpelling(cursor))); json_object_set_new(js, "values", json_array()); clang_visitChildren(cursor, visit_enum, (CXClientData)js); break; case CXCursor_TypedefDecl: js = json_object(); json_object_set_new(js, "kind", json_string("typedef")); json_object_set_new(js, "name", render_string(clang_getCursorSpelling(cursor))); json_object_set_new(js, "type", render_type(clang_getTypedefDeclUnderlyingType(cursor))); ret = CXChildVisit_Recurse; break; case CXCursor_FieldDecl: break; case CXCursor_MacroDefinition: js = json_object(); json_object_set_new(js, "kind", json_string("macro")); { CXToken* tokens; unsigned ntokens, i; CXString name = clang_getCursorSpelling(cursor); char value_buf[1024] = ""; json_object_set_new(js, "name", render_string(clang_getCursorSpelling(cursor))); clang_tokenize(TU, clang_getCursorExtent(cursor), &tokens, &ntokens); for (i=0; i<ntokens; i++) { CXString str = clang_getTokenSpelling(TU, tokens[i]); CXTokenKind tkind = clang_getTokenKind(tokens[i]); if (i == 0 && !strcmp(clang_getCString(name), clang_getCString(str))) { // macro name } else if (i == ntokens - 1 && tkind == CXToken_Punctuation && !strcmp("#", clang_getCString(str))) { // weird clang terminator thingy } else if (tkind == CXToken_Comment) { // comment } else { if (strlen(value_buf) > 0) { strncat(value_buf, " ", sizeof(value_buf) - strlen(value_buf) - 1); } strncat(value_buf, clang_getCString(str), sizeof(value_buf) - strlen(value_buf) - 1); } clang_disposeString(str); } clang_disposeTokens(TU, tokens, ntokens); if (strlen(value_buf) > 0) { long int intval; double dblval; char* endptr_int; char* endptr_dbl; intval = strtol(value_buf, &endptr_int, 0); dblval = strtod(value_buf, &endptr_dbl); if (endptr_int[0] == 0 || (endptr_int[1] == 0 && strchr("UuLl", endptr_int[0]) != NULL)) { json_object_set_new(js, "value", json_integer(intval)); } else if (endptr_dbl[0] == 0 || (endptr_dbl[1] == 0 && strchr("fF", endptr_dbl[0]) != NULL)) { json_object_set_new(js, "value", json_real(dblval)); } else { json_object_set_new(js, "value", json_string(value_buf)); } } } break; /* case CXCursor_PreprocessingDirective: case CXCursor_MacroExpansion: js = json_object(); json_object_set_new(js, "kind", json_string("macro")); json_object_set_new(js, "name", render_string(clang_getCursorSpelling(cursor))); putstring(clang_getCursorSpelling(cursor)); putstring(clang_getCursorDisplayName(cursor)); printf("%d\n", clang_getEnumConstantDeclValue(cursor)); ret = CXChildVisit_Recurse; */ default: js = json_object(); json_object_set_new(js, "name", render_string(clang_getCursorSpelling(cursor))); json_object_set_new(js, "type", render_type(clang_getCursorType(cursor))); json_object_set_new(js, "kind", json_string("wtf")); json_object_set_new(js, "wtf", render_string(clang_getCursorKindSpelling(clang_getCursorKind(cursor)))); } if (js) { json_t* str; if (!json_object_get(program, "")) json_object_set_new(program, "", json_array()); str = render_string(clang_getCursorUSR(cursor)); if (strlen(json_string_value(str)) == 0) { json_decref(str); json_array_append_new(json_object_get(program, ""), js); } else { json_object_set_with_key_new(program, render_string(clang_getCursorUSR(cursor)), js); } } return ret; }
HighlightingInformations::~HighlightingInformations() { clang_disposeTokens(cxTranslationUnit, cxToken, cxTokenCount); }