int main(int argc, char *argv[]) { CXIndex Index = clang_createIndex(0, 0); CXTranslationUnit TU; TU = clang_parseTranslationUnit(Index, 0, (const char**)argv, argc, 0, 0, CXTranslationUnit_None); CXCodeCompleteResults *results = clang_codeCompleteAt(TU, argv[1], 20, 7, NULL, 0, clang_defaultCodeCompleteOptions()); unsigned i; for(i =0; i<results->NumResults; i++) { printf("%s",results->Results[i].CompletionString); } // clang_disposeString(String); clang_disposeCodeCompleteResults(results); clang_disposeTranslationUnit(TU); clang_disposeIndex(Index); return 0; }
const char* libclang_vim::at_specific_location( const location_tuple& location_tuple, const std::function<std::string(CXCursor const&)>& predicate) { static std::string vimson; char const* file_name = location_tuple.file.c_str(); auto const args_ptrs = get_args_ptrs(location_tuple.args); cxindex_ptr index = clang_createIndex(/*excludeDeclsFromPCH*/ 1, /*displayDiagnostics*/ 0); std::vector<CXUnsavedFile> unsaved_files = create_unsaved_files(location_tuple); cxtranslation_unit_ptr translation_unit(clang_parseTranslationUnit( index, file_name, args_ptrs.data(), args_ptrs.size(), unsaved_files.data(), unsaved_files.size(), CXTranslationUnit_Incomplete)); if (!translation_unit) return "{}"; CXFile file = clang_getFile(translation_unit, file_name); auto const location = clang_getLocation( translation_unit, file, location_tuple.line, location_tuple.col); CXCursor const cursor = clang_getCursor(translation_unit, location); vimson = predicate(cursor); return vimson.c_str(); }
TranslationUnit::TranslationUnit( CXIndex index , const KUrl& filename_url , const clang::compiler_options& options , const unsigned parse_options , const clang::unsaved_files_list& unsaved_files ) : m_filename(filename_url.toLocalFile().toUtf8()) { kDebug(DEBUG_AREA) << "Parsing a translation unit: " << filename_url.toLocalFile(); kDebug(DEBUG_AREA) << "w/ the following compiler options:" << options; auto files = unsaved_files.get(); auto clang_options = options.get(); // Ok, ready to parse m_unit = clang_parseTranslationUnit( index , m_filename.constData() , clang_options.data() , clang_options.size() , files.data() , files.size() , parse_options ); if (!m_unit) throw Exception::ParseFailure( i18nc("@item:intext", "Failure to parse C++ code").toAscii().constData() ); updateDiagnostic(); }
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; }
CXTranslationUnit CodeFile::ParseTranslationUnit() { /* if (translationUnit) { clang_disposeTranslationUnit(translationUnit); } */ std::vector<const char*> arguments; arguments.push_back("c++"); arguments.push_back("-std=c++11"); arguments.push_back("-stdlib=libc++"); arguments.push_back("-I/Users/Jeppe/Downloads/clang+llvm-3.7.0-x86_64-apple-darwin/include/c++/v1"); arguments.push_back("-I/Users/Jeppe/Downloads/clang+llvm-3.7.0-x86_64-apple-darwin/lib/clang/3.7.0/include"); //arguments.push_back("-I/usr/include"); //arguments.push_back("-I/usr/include/c++/4.2.1/"); arguments.push_back("-I/Projects/PocketEngine/Pocket/Data/"); arguments.push_back("-I/Projects/PocketEngine/Pocket/ComponentSystem/"); arguments.push_back("-I/Projects/PocketEngine/Pocket/ComponentSystem/Meta/"); CXIndex index = clang_createIndex(0,1); CXTranslationUnit tu = clang_parseTranslationUnit(index, path.c_str(), &arguments[0], (int)arguments.size(), NULL, 0, 0); return tu; }
/** * Параметр CXTranslationUnit_SkipFunctionBodies позволяет ускорить разбор * за счёт игнорирования парсером тел функций * Внутри функций обычно нет глобальных переменных */ void fileAction(const std::string &path) { CXTranslationUnit unit = clang_parseTranslationUnit( g_index, path.c_str(), nullptr, /* argv */ 0, /* argc */ nullptr, /* unsaved files */ 0, /* num unsaved files */ CXTranslationUnit_SkipFunctionBodies | CXTranslationUnit_DetailedPreprocessingRecord ); if (unit == nullptr) { std::cout << "Cannot parse: " << path << std::endl; return; } // Получаем курсор для всей единицы трансляции CXCursor cursorTU = clang_getTranslationUnitCursor(unit); clang_visitChildren(cursorTU, globalsFinder, NULL); clang_disposeTranslationUnit(unit); }
TEST_F(LibclangReparseTest, ReparseWithModule) { const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;"; const char *HeaderBottom = "\n};\n#endif\n"; const char *MFile = "#include \"HeaderFile.h\"\nint main() {" " struct Foo foo; foo.bar = 7; foo.baz = 8; }\n"; const char *ModFile = "module A { header \"HeaderFile.h\" }\n"; std::string HeaderName = "HeaderFile.h"; std::string MName = "MFile.m"; std::string ModName = "module.modulemap"; WriteFile(MName, MFile); WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom); WriteFile(ModName, ModFile); std::string ModulesCache = std::string("-fmodules-cache-path=") + TestDir; const char *Args[] = { "-fmodules", ModulesCache.c_str(), "-I", TestDir.c_str() }; int NumArgs = sizeof(Args) / sizeof(Args[0]); ClangTU = clang_parseTranslationUnit(Index, MName.c_str(), Args, NumArgs, nullptr, 0, TUFlags); EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU)); DisplayDiagnostics(); // Immedaitely reparse. ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */)); EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU)); std::string NewHeaderContents = std::string(HeaderTop) + "int baz;" + HeaderBottom; WriteFile(HeaderName, NewHeaderContents); // Reparse after fix. ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */)); EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU)); }
TEST_F(LibclangReparseTest, Reparse) { const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;"; const char *HeaderBottom = "\n};\n#endif\n"; const char *CppFile = "#include \"HeaderFile.h\"\nint main() {" " Foo foo; foo.bar = 7; foo.baz = 8; }\n"; std::string HeaderName = "HeaderFile.h"; std::string CppName = "CppFile.cpp"; WriteFile(CppName, CppFile); WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom); ClangTU = clang_parseTranslationUnit(Index, CppName.c_str(), nullptr, 0, nullptr, 0, TUFlags); EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU)); DisplayDiagnostics(); // Immedaitely reparse. ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */)); EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU)); std::string NewHeaderContents = std::string(HeaderTop) + "int baz;" + HeaderBottom; WriteFile(HeaderName, NewHeaderContents); // Reparse after fix. ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */)); EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU)); }
int main(int argc, const char* argv[]) { if (argc < 4) { std::cerr << "Usage:\n" << " " << argv[0] << " <dbFilename> <indexFilename> [<options>] <sourceFilename>\n"; return 1; } const char* dbFilename = argv[1]; const char* indexFilename = argv[2]; const char* sourceFilename = argv[argc-1]; // Set up the clang translation unit CXIndex cxindex = clang_createIndex(0, 0); CXTranslationUnit tu = clang_parseTranslationUnit( cxindex, 0, argv + 3, argc - 3, // Skip over dbFilename and indexFilename 0, 0, CXTranslationUnit_None); // Print any errors or warnings int n = clang_getNumDiagnostics(tu); if (n > 0) { int nErrors = 0; for (unsigned i = 0; i != n; ++i) { CXDiagnostic diag = clang_getDiagnostic(tu, i); CXString string = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions()); fprintf(stderr, "%s\n", clang_getCString(string)); if (clang_getDiagnosticSeverity(diag) == CXDiagnostic_Error || clang_getDiagnosticSeverity(diag) == CXDiagnostic_Fatal) nErrors++; } } // Create the index EverythingIndexer visitor(sourceFilename); clang_visitChildren( clang_getTranslationUnitCursor(tu), &visitorFunction, &visitor); ClicIndex& index = visitor.usrToReferences; // OK, now write the index to a compressed file std::ofstream fout(indexFilename); boost::iostreams::filtering_stream<boost::iostreams::output> zout; zout.push(boost::iostreams::gzip_compressor()); zout.push(fout); printIndex(zout, index); // Now open the database and add the index to it ClicDb db(dbFilename); BOOST_FOREACH(const ClicIndex::value_type& it, index) { const std::string& usr = it.first; db.addMultiple(usr, it.second); } return 0; }
int main(int argc, char *argv[]) { auto index = clang_createIndex(0, 0); auto options = clang_defaultEditingTranslationUnitOptions(); char const *args[] = { "-x", "c++", "-std=c++11" }; auto arg_count = sizeof( args ) / sizeof( *args ); filename = argv[1]; CXUnsavedFile *unsaved_files = NULL; auto unsaved_file_count = 0; tu = clang_parseTranslationUnit(index, filename.c_str(), args, arg_count, unsaved_files, unsaved_file_count, options ); if ( !tu ) { std::cout << "Translation Unit Parse Failed!\n"; return -1; } std::stringstream ss( argv[2] ); int line, col; ss >> line; ss.get(); ss >> col; std::cout << "Hello " << line << ":" << col << "\n"; auto file = clang_getFile( tu, filename.c_str() ); auto location = clang_getLocation( tu, file, line, col ); clang_visitChildren( clang_getTranslationUnitCursor( tu ), visitor, reinterpret_cast<CXClientData>(0) ); auto cursor = clang_getCursor( tu, location ); auto refcursor = clang_getCursorReferenced( cursor ); auto rrefcursor = clang_getCursorReferenced( refcursor ); auto arf = clang_getTypeKindSpelling( clang_getCursorType( cursor ).kind ); auto foo = clang_getCanonicalCursor( cursor ); auto semparent = clang_getCursorSemanticParent( cursor ); auto lexparent = clang_getCursorLexicalParent( cursor ); std::cout << cursor << "\n"; std::cout << refcursor << "\n"; std::cout << rrefcursor << "\n"; std::cout << clang_getCString(arf) << "\n"; std::cout << foo << "\n"; std::cout << "Parent: " << semparent << "\n"; std::cout << "LexParent: " << lexparent << "\n"; //clang_visitChildren( semparent, visitor, reinterpret_cast<CXClientData>(0) ); clang_disposeString( arf ); return 0; }
static inline CXTranslationUnit CLANG_PARSE(const CXIndex &idx, const char *filename, char **args, int args_size, CXUnsavedFile *unsaved_file) { int unsaved_file_num = 0; if (unsaved_file) unsaved_file_num = 1; return clang_parseTranslationUnit(idx, filename, args, args_size, unsaved_file, unsaved_file_num, clang_defaultEditingTranslationUnitOptions()| CXTranslationUnit_PrecompiledPreamble| CXTranslationUnit_CXXPrecompiledPreamble| CXTranslationUnit_CacheCompletionResults); }
CXTranslationUnit ClangWorkerThread::DoCreateTU(CXIndex index, ClangThreadRequest* task, bool reparse) { wxFileName fn(task->GetFileName()); DoSetStatusMsg(wxString::Format(wxT("clang: parsing file %s..."), fn.GetFullName().c_str())); FileExtManager::FileType type = FileExtManager::GetType(task->GetFileName()); int argc(0); char** argv = MakeCommandLine(task, argc, type); for(int i = 0; i < argc; i++) { CL_DEBUG(wxT("Command Line Argument: %s"), wxString(argv[i], wxConvUTF8).c_str()); } std::string c_filename = task->GetFileName().mb_str(wxConvUTF8).data(); CL_DEBUG(wxT("Calling clang_parseTranslationUnit...")); // First time, need to create it unsigned flags; if(reparse) { flags = CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_Incomplete | CXTranslationUnit_DetailedPreprocessingRecord | CXTranslationUnit_CXXChainedPCH; } else { flags = CXTranslationUnit_Incomplete | #if HAS_LIBCLANG_BRIEFCOMMENTS CXTranslationUnit_SkipFunctionBodies | #endif CXTranslationUnit_DetailedPreprocessingRecord; } CXTranslationUnit TU = clang_parseTranslationUnit(index, c_filename.c_str(), argv, argc, NULL, 0, flags); CL_DEBUG(wxT("Calling clang_parseTranslationUnit... done")); ClangUtils::FreeArgv(argv, argc); DoSetStatusMsg(wxString::Format(wxT("clang: parsing file %s...done"), fn.GetFullName().c_str())); if(TU && reparse) { CL_DEBUG(wxT("Calling clang_reparseTranslationUnit...")); if(clang_reparseTranslationUnit(TU, 0, NULL, clang_defaultReparseOptions(TU)) == 0) { CL_DEBUG(wxT("Calling clang_reparseTranslationUnit... done")); return TU; } else { CL_DEBUG(wxT("An error occured during reparsing of the TU for file %s. TU: %p"), task->GetFileName().c_str(), (void*)TU); // The only thing that left to be done here, is to dispose the TU clang_disposeTranslationUnit(TU); PostEvent(wxEVT_CLANG_TU_CREATE_ERROR, task->GetFileName()); return NULL; } } return TU; }
int main(int argc, char * argv[]) { CXIndex index = clang_createIndex(0, 0); CXTranslationUnit txUnit = clang_parseTranslationUnit(index, 0, (const char * const *) argv, argc, 0, 0, CXTranslationUnit_None); CXCursor cur = clang_getTranslationUnitCursor(txUnit); clang_visitChildren(cur, visitor, NULL); clang_disposeTranslationUnit(txUnit); clang_disposeIndex(index); return 0; }
CXTranslationUnit completion_parseTranslationUnit(completion_Session *session) { struct CXUnsavedFile unsaved_files = __get_CXUnsavedFile(session); session->cx_tu = clang_parseTranslationUnit( session->cx_index, session->src_filename, (const char * const *) session->cmdline_args, session->num_args, &unsaved_files, 1, session->ParseOptions); return session->cx_tu; }
int main(int argc, const char* const argv[]){ if (argc < 2) { printf("Usage: %s header.h\n", argv[0]); printf("Standard clang arguments (-I, -D, etc.) may be used\n"); exit(1); } unsigned i; char filename[] = "ffigen.tmp.XXXXXX"; int fd = mkstemp(filename); FILE* file = fdopen(fd, "w"); fprintf(file, "#define _SIZE_T\n"); fprintf(file, "#define _PTRDIFF_T\n"); fprintf(file, "typedef __SIZE_TYPE__ size_t;\n"); fprintf(file, "typedef __PTRDIFF_TYPE__ ptrdiff_t;\n"); fprintf(file, "#include <%s>\n", argv[1]); fclose(file); int clang_argc = argc + 1; const char** clang_argv = malloc(sizeof(char*) * clang_argc); clang_argv[0] = "-x"; clang_argv[1] = "c"; clang_argv[2] = filename; for (i=3; i < clang_argc; i++) { clang_argv[i] = argv[i-1]; } CXIndex Index = clang_createIndex(0, 0); TU = clang_parseTranslationUnit(Index, 0, clang_argv, clang_argc, 0, 0, CXTranslationUnit_DetailedPreprocessingRecord); json_t* json = json_object(); clang_visitChildren(clang_getTranslationUnitCursor(TU), visit_program, (CXClientData)json); json_dumpf(json, stdout, JSON_INDENT(2) | JSON_PRESERVE_ORDER); printf("\n"); json_decref(json); for (i=0; i<clang_getNumDiagnostics(TU); i++) { putstring(clang_formatDiagnostic(clang_getDiagnostic(TU, i), clang_defaultDiagnosticDisplayOptions())); } clang_disposeTranslationUnit(TU); clang_disposeIndex(Index); free(clang_argv); unlink(filename); return 0; }
void TestCases::ClangTest() { #ifdef ENABLE_CLANG_COMPLETION std::cout << "checking to see if libclang/libclang.dll works" << std::endl; int argc = 1; char* argv[] = {"--version"}; CXIndex index = clang_createIndex(0, 0); CXTranslationUnit tu = clang_parseTranslationUnit(index, 0, argv, argc, 0, 0, CXTranslationUnit_None); clang_disposeTranslationUnit(tu); clang_disposeIndex(index); #endif }
int main(int argc, char *argv[]) { CXIndex Index = clang_createIndex(0, 0); CXTranslationUnit TU = clang_parseTranslationUnit(Index, 0, (const char**)argv, argc, 0, 0, CXTranslationUnit_None); struct self whole; whole. clang_disposeTranslationUnit(TU); clang_disposeIndex(Index); return 0; }
void parseTranslationUnit(const Path &sourceFile, const List<String> &args, CXTranslationUnit &unit, CXIndex index, String &clangLine, uint32_t fileId, DependencyMap *dependencies, CXUnsavedFile *unsaved, int unsavedCount) { clangLine = "clang "; int idx = 0; const List<String> &defaultArguments = Server::instance()->options().defaultArguments; List<const char*> clangArgs(args.size() + defaultArguments.size(), 0); const List<String> *lists[] = { &args, &defaultArguments }; for (int i=0; i<2; ++i) { const int count = lists[i]->size(); for (int j=0; j<count; ++j) { String arg = lists[i]->at(j); if (arg.isEmpty()) continue; if (dependencies && arg == "-include" && j + 1 < count) { const uint32_t fileId = Location::fileId(lists[i]->at(j + 1)); if (fileId) { (*dependencies)[fileId].insert(fileId); } } clangArgs[idx++] = lists[i]->at(j).constData(); arg.replace("\"", "\\\""); clangLine += arg; clangLine += ' '; } } clangLine += sourceFile; StopWatch sw; unsigned int flags = CXTranslationUnit_DetailedPreprocessingRecord; if (Server::instance()->options().completionCacheSize) flags |= CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults; unit = clang_parseTranslationUnit(index, sourceFile.constData(), clangArgs.data(), idx, unsaved, unsavedCount, flags); // error() << sourceFile << sw.elapsed(); }
bool parse( int argc, const char **argv, CXUnsavedFile *unsaved_files = nullptr, unsigned int unsaved_file_count = 0 ) { orig_argc = argc; orig_argv = argv; for ( auto i = 0; i < argc; ++i ) std::cout << argv[i] << " "; std::cout << "\n"; unit = clang_parseTranslationUnit( index, filename.c_str(), argv, argc, unsaved_files, unsaved_file_count, options ); return valid = (unit != NULL); }
void Tokenizer::parse(OovStringRef fileName, OovStringRef buffer, size_t bufLen, char const * const clang_args[], size_t num_clang_args) { CLangAutoLock lock(mCLangLock, __LINE__, this); try { if(!mSourceFile) { // The clang_defaultCodeCompleteOptions() options are not for the parse // function, they are for the clang_codeCompleteAt func. unsigned options = clang_defaultEditingTranslationUnitOptions(); // This is required to allow go to definition to work with #include. options |= CXTranslationUnit_DetailedPreprocessingRecord; mSourceFilename = fileName; mContextIndex = clang_createIndex(1, 1); mTransUnit = clang_parseTranslationUnit(mContextIndex, fileName, clang_args, static_cast<int>(num_clang_args), 0, 0, options); } else { static CXUnsavedFile file; file.Filename = mSourceFilename.c_str(); file.Contents = buffer; file.Length = bufLen; unsigned options = clang_defaultReparseOptions(mTransUnit); int stat = clang_reparseTranslationUnit(mTransUnit, 1, &file, options); if(stat != 0) { clang_disposeTranslationUnit(mTransUnit); mTransUnit = nullptr; } } mSourceFile = clang_getFile(mTransUnit, fileName); } catch(...) { DUMP_PARSE_INT("Tokenizer::parse - CRASHED", 0); } }
translation_unit& index::parse_translation_unit(const std::vector<std::string>& args, const std::vector<unsaved_file>& unsaved) { auto argv = convert_args(args); auto unsaved_files = convert_unsaved_files(unsaved); unsigned options = CXTranslationUnit_DetailedPreprocessingRecord | CXTranslationUnit_CacheCompletionResults; auto tu = clang_parseTranslationUnit(idx, nullptr, argv.data(), argv.size(), unsaved_files.data(), unsaved_files.size(), options); if(!tu) throw error("unable to parse tu"); // Have to reparse to cache completion results. int err = clang_reparseTranslationUnit(tu, unsaved_files.size(), unsaved_files.data(), clang_defaultReparseOptions(tu)); if(err) { clang_disposeTranslationUnit(tu); throw error("unable to reparse tu"); } tus.emplace_back(tu); return tus.back(); }
int main(int argc, char *argv[]) { CXIndex index = clang_createIndex(0, 1); CXTranslationUnit tu = clang_parseTranslationUnit(index, "ast_clang.m", NULL, 0, NULL, 0, CXTranslationUnit_None); clang_visitChildrenWithBlock(clang_getTranslationUnitCursor(tu), ^enum CXChildVisitResult (CXCursor cursor, CXCursor parent) { enum CXCursorKind cursor_kind = clang_getCursorKind(cursor); switch(cursor_kind) { case CXCursor_ObjCInterfaceDecl:{ CXString cxname = clang_getCursorSpelling(cursor); printf("class: %s\n", clang_getCString(cxname)); clang_disposeString(cxname); } break; case CXCursor_ObjCPropertyDecl:{ CXString cxname = clang_getCursorSpelling(cursor); printf(" -> %s\n", clang_getCString(cxname)); clang_disposeString(cxname); } break; default:{}break; } return CXChildVisit_Recurse; });
int main(int argc, char **argv) { if (argc < 2) return 1; CXIndex index = clang_createIndex(1, 1); const char * const *args = 0; if (argc > 2) args = (const char *const *)&argv[2]; CXTranslationUnit unit = clang_parseTranslationUnit(index, argv[1], args, argc - 2, 0, 0, clang_defaultEditingTranslationUnitOptions()); if (unit) { int indent = 0; clang_visitChildren(clang_getTranslationUnitCursor(unit), visit, &indent); const unsigned int diagnosticCount = clang_getNumDiagnostics(unit); unsigned int i; for (i=0; i<diagnosticCount; ++i) { CXDiagnostic diagnostic = clang_getDiagnostic(unit, i); const unsigned int diagnosticOptions = (CXDiagnostic_DisplaySourceLocation| CXDiagnostic_DisplayColumn| CXDiagnostic_DisplaySourceRanges| CXDiagnostic_DisplayOption| CXDiagnostic_DisplayCategoryId| CXDiagnostic_DisplayCategoryName); CXString diagnosticText = clang_formatDiagnostic(diagnostic, diagnosticOptions); const char *cstr = clang_getCString(diagnosticText); if (cstr) printf("%s\n", cstr); clang_disposeString(diagnosticText); } clang_disposeTranslationUnit(unit); } clang_disposeIndex(index); return 0; }
bool IndexerJob::parse(int build) { CXIndex &index = mUnits[build].first; if (!index) index = clang_createIndex(0, 1); if (!index) { abort(); return false; } const List<String> args = mSourceInformation.builds.at(build).args; const List<String> &defaultArguments = Server::instance()->options().defaultArguments; CXTranslationUnit &unit = mUnits[build].second; assert(!unit); mClangLines.append(String()); String &clangLine = mClangLines[build]; clangLine = Server::instance()->clangPath(); clangLine += ' '; int idx = 0; List<const char*> clangArgs(args.size() + defaultArguments.size(), 0); const List<String> *lists[] = { &args, &defaultArguments }; for (int i=0; i<2; ++i) { const int count = lists[i]->size(); for (int j=0; j<count; ++j) { String arg = lists[i]->at(j); if (arg.isEmpty()) continue; if (arg == "-include" && j + 1 < count) { const uint32_t fileId = Location::fileId(lists[i]->at(j + 1)); if (fileId) { mData->dependencies[fileId].insert(mFileId); } } clangArgs[idx++] = lists[i]->at(j).constData(); arg.replace("\"", "\\\""); clangLine += arg; clangLine += ' '; } } clangLine += mSourceInformation.sourceFile; unit = clang_parseTranslationUnit(index, mSourceInformation.sourceFile.constData(), clangArgs.data(), idx, 0, 0, CXTranslationUnit_Incomplete | CXTranslationUnit_DetailedPreprocessingRecord); warning() << "loading unit " << clangLine << " " << (unit != 0); if (unit) { return !isAborted(); } error() << "got failure" << clangLine; const String preprocessorOnly = RTags::filterPreprocessor(mSourceInformation.sourceFile); if (!preprocessorOnly.isEmpty()) { CXUnsavedFile unsaved = { mSourceInformation.sourceFile.constData(), preprocessorOnly.constData(), static_cast<unsigned long>(preprocessorOnly.size()) }; unit = clang_parseTranslationUnit(index, mSourceInformation.sourceFile.constData(), clangArgs.data(), idx, &unsaved, 1, CXTranslationUnit_Incomplete | CXTranslationUnit_DetailedPreprocessingRecord); } if (unit) { clang_getInclusions(unit, IndexerJob::inclusionVisitor, this); clang_disposeTranslationUnit(unit); unit = 0; } else { mData->dependencies[mFileId].insert(mFileId); } return !isAborted(); }
TextEdit::TextEdit(QWidget *parent): QTextEdit(parent) { this->setFont(QFont("Monaco", 10)); this->setTabStopWidth(fontMetrics().width("\t")/2); connect(this,SIGNAL(cursorPositionChanged()),this,SLOT(slotCursorPositionChanged())); QFile file("/tmp/a.m"); file.open(QIODevice::ReadOnly|QIODevice::Text); QByteArray data = file.readAll(); QTextStream in(&data); QString decodedStr = in.readAll(); setPlainText(decodedStr); file.close(); cx_index = clang_createIndex(0,0); struct CXUnsavedFile unsaved_file; unsaved_file.Filename = "/tmp/a.m"; unsaved_file.Contents = (char*)calloc(sizeof(char), 4096); unsaved_file.Length = this->toPlainText().length(); char **cmd_args = (char**)calloc(sizeof(char*), 6); int i = 0; for(i ; i <6; i++) { cmd_args[i] = (char*)calloc(sizeof(char), 1000 + 1); strcpy(cmd_args[i], "-cc1"); strcpy(cmd_args[i], "-fsyntax-only"); strcpy(cmd_args[i], "-code-completion-macros"); strcpy(cmd_args[i], "-code-completion-patterns"); strcpy(cmd_args[i], "-x objective-c"); strcpy(cmd_args[i], "-I/usr/share/iPhoneOS5.0.sdk/usr/include"); } cx_tu = clang_parseTranslationUnit(cx_index, "/tmp/a.m" , cmd_args, 6, &unsaved_file, 1, CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_Incomplete); if(!cx_tu) qDebug()<<"cx_tu"; //connect(this,SIGNAL(textChanged()), this,SLOT(slotReparse())); completionList = new QListWidget(this); completionList->setSelectionMode( QAbstractItemView::SingleSelection ); completionList->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded ); completionList->hide(); completionList->setSortingEnabled( true ); completionList->setSelectionMode( QAbstractItemView::SingleSelection ); QPalette palette; palette.setBrush(QPalette::Active, QPalette::Base, Qt::white); completionList->setPalette(palette); m_formatFunction.setForeground(Qt::black); m_formatSingleLineComment.setForeground(Qt::red); m_formatKeyword.setForeground(Qt::blue); m_formatUserKeyword.setForeground(Qt::darkBlue); m_formatOperator.setForeground(Qt::black); m_formatNumber.setForeground(Qt::darkMagenta); m_formatEscapeChar.setForeground(Qt::darkBlue); m_formatMacro.setForeground(Qt::darkGreen); m_formatMultiLineComment.setForeground(Qt::red); m_formatString.setForeground(Qt::darkCyan); //connect(m_completionList, SIGNAL(itemActivated(QListWidgetItem *)), this, SLOT(slotWordCompletion(QListWidgetItem *)) ); }
CXTranslationUnit TUManager::parse(const std::string & filename, const std::vector<std::string> & flags) { CXTranslationUnit tu = translationUnits_[filename]; if (! tu) { // FIXME: needed ? // Note: the -cc1 argument indicates the compiler front-end, and // not the driver, should be run. The compiler front-end has // several additional Clang specific features which are not // exposed through the GCC compatible driver interface. // from: http://clang.llvm.org/get_started.html // const_cast<std::vector<std::string> &>(flags).push_back("-cc1"); std::size_t nbArgs = flags.size(); const char **argv = 0; if (nbArgs > 0) { argv = new const char *[nbArgs + 1]; argv[nbArgs] = 0; for (std::size_t i = 0; i < nbArgs; ++i) argv[i] = flags[i].c_str(); } tu = clang_parseTranslationUnit(index_, filename.c_str(), argv, nbArgs, 0, 0, clang_defaultEditingTranslationUnitOptions() | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_CacheCompletionResults); delete [] argv; translationUnits_[filename] = tu; } if (! tu) { std::clog << "parsing \"" << filename << "\" failed." << std::endl; return 0; } // NOTE: Even at the first time the translation unit is reparsed, // because without this the completion is erroneous. // From the clang mailing list: // From: Douglas Gregor <*****@*****.**> // Subject: Re: Clang indexing library performance // Newsgroups: gmane.comp.compilers.clang.devel // ... // You want to use the "default editing options" when parsing the // translation unit // clang_defaultEditingTranslationUnitOptions() // and then reparse at least once. That will enable the various // code-completion optimizations that should bring this time down // significantly. if (clang_reparseTranslationUnit(tu, 0, 0, clang_defaultReparseOptions(tu))) { // a 'fatal' error occur (even a diagnostic is impossible) clang_disposeTranslationUnit(tu); translationUnits_[filename] = 0; } return tu; }
void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) { static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); static QStrList &includePath = Config_getList(INCLUDE_PATH); static QStrList clangOptions = Config_getList(CLANG_OPTIONS); static QCString clangCompileDatabase = Config_getList(CLANG_COMPILATION_DATABASE_PATH); if (!clangAssistedParsing) return; //printf("ClangParser::start(%s)\n",fileName); p->fileName = fileName; p->index = clang_createIndex(0, 0); p->curLine = 1; p->curToken = 0; QDictIterator<void> di(Doxygen::inputPaths); int argc=0; std::string error; // load a clang compilation database (https://clang.llvm.org/docs/JSONCompilationDatabase.html) // this only needs to be loaded once, and could be refactored to a higher level function static std::unique_ptr<clang::tooling::CompilationDatabase> db = clang::tooling::CompilationDatabase::loadFromDirectory(clangCompileDatabase.data(), error); int clang_option_len = 0; std::vector<clang::tooling::CompileCommand> command; if (strcmp(clangCompileDatabase, "0") != 0) { if (db == nullptr) { // user specified a path, but DB file was not found err("%s using clang compilation database path of: \"%s\"\n", error.c_str(), clangCompileDatabase.data()); } else { // check if the file we are parsing is in the DB command = db->getCompileCommands(fileName); if (!command.empty() ) { // it's possible to have multiple entries for the same file, so use the last entry clang_option_len = command[command.size()-1].CommandLine.size(); } } } char **argv = (char**)malloc(sizeof(char*)*(4+Doxygen::inputPaths.count()+includePath.count()+clangOptions.count()+clang_option_len)); if (!command.empty() ) { std::vector<std::string> options = command[command.size()-1].CommandLine; // copy each compiler option used from the database. Skip the first which is compiler exe. for (auto option = options.begin()+1; option != options.end(); option++) { argv[argc++] = strdup(option->c_str()); } // this extra addition to argv is accounted for as we are skipping the first entry in argv[argc++]=strdup("-w"); // finally, turn off warnings. } else { // add include paths for input files for (di.toFirst();di.current();++di,++argc) { QCString inc = QCString("-I")+di.currentKey(); argv[argc]=strdup(inc.data()); //printf("argv[%d]=%s\n",argc,argv[argc]); } // add external include paths for (uint i=0;i<includePath.count();i++) { QCString inc = QCString("-I")+includePath.at(i); argv[argc++]=strdup(inc.data()); } // user specified options for (uint i=0;i<clangOptions.count();i++) { argv[argc++]=strdup(clangOptions.at(i)); } // extra options argv[argc++]=strdup("-ferror-limit=0"); argv[argc++]=strdup("-x"); // Since we can be presented with a .h file that can contain C/C++ or // Objective C code and we need to configure the parser before knowing this, // we use the source file to detected the language. Detection will fail if you // pass a bunch of .h files containing ObjC code, and no sources :-( SrcLangExt lang = getLanguageFromFileName(fileName); if (lang==SrcLangExt_ObjC || p->detectedLang!=ClangParser::Private::Detected_Cpp) { QCString fn = fileName; if (p->detectedLang==ClangParser::Private::Detected_Cpp && (fn.right(4).lower()==".cpp" || fn.right(4).lower()==".cxx" || fn.right(3).lower()==".cc" || fn.right(2).lower()==".c")) { // fall back to C/C++ once we see an extension that indicates this p->detectedLang = ClangParser::Private::Detected_Cpp; } else if (fn.right(3).lower()==".mm") // switch to Objective C++ { p->detectedLang = ClangParser::Private::Detected_ObjCpp; } else if (fn.right(2).lower()==".m") // switch to Objective C { p->detectedLang = ClangParser::Private::Detected_ObjC; } } switch(p->detectedLang) { case ClangParser::Private::Detected_Cpp: argv[argc++]=strdup("c++"); break; case ClangParser::Private::Detected_ObjC: argv[argc++]=strdup("objective-c"); break; case ClangParser::Private::Detected_ObjCpp: argv[argc++]=strdup("objective-c++"); break; } // provide the input and and its dependencies as unsaved files so we can // pass the filtered versions argv[argc++]=strdup(fileName); } static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); //printf("source %s ----------\n%s\n-------------\n\n", // fileName,p->source.data()); uint numUnsavedFiles = filesInTranslationUnit.count()+1; p->numFiles = numUnsavedFiles; p->sources = new QCString[numUnsavedFiles]; p->ufs = new CXUnsavedFile[numUnsavedFiles]; p->sources[0] = detab(fileToString(fileName,filterSourceFiles,TRUE)); p->ufs[0].Filename = strdup(fileName); p->ufs[0].Contents = p->sources[0].data(); p->ufs[0].Length = p->sources[0].length(); QStrListIterator it(filesInTranslationUnit); uint i=1; for (it.toFirst();it.current() && i<numUnsavedFiles;++it,i++) { p->fileMapping.insert(it.current(),new uint(i)); p->sources[i] = detab(fileToString(it.current(),filterSourceFiles,TRUE)); p->ufs[i].Filename = strdup(it.current()); p->ufs[i].Contents = p->sources[i].data(); p->ufs[i].Length = p->sources[i].length(); } // let libclang do the actual parsing p->tu = clang_parseTranslationUnit(p->index, 0, argv, argc, p->ufs, numUnsavedFiles, CXTranslationUnit_DetailedPreprocessingRecord); // free arguments for (int i=0;i<argc;++i) { free(argv[i]); } free(argv); if (p->tu) { // filter out any includes not found by the clang parser determineInputFilesInSameTu(filesInTranslationUnit); // show any warnings that the compiler produced for (uint i=0, n=clang_getNumDiagnostics(p->tu); i!=n; ++i) { CXDiagnostic diag = clang_getDiagnostic(p->tu, i); CXString string = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions()); err("%s [clang]\n",clang_getCString(string)); clang_disposeString(string); clang_disposeDiagnostic(diag); } // create a source range for the given file QFileInfo fi(fileName); CXFile f = clang_getFile(p->tu, fileName); CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0); CXSourceLocation fileEnd = clang_getLocationForOffset(p->tu, f, p->ufs[0].Length); CXSourceRange fileRange = clang_getRange(fileBegin, fileEnd); // produce a token stream for the file clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens); // produce cursors for each token in the stream p->cursors=new CXCursor[p->numTokens]; clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors); } else { p->tokens = 0; p->numTokens = 0; p->cursors = 0; err("clang: Failed to parse translation unit %s\n",fileName); } }
void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit) { static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING"); static QStrList &includePath = Config_getList("INCLUDE_PATH"); static QStrList clangOptions = Config_getList("CLANG_OPTIONS"); if (!clangAssistedParsing) return; //printf("ClangParser::start(%s)\n",fileName); p->fileName = fileName; p->index = clang_createIndex(0, 0); p->curLine = 1; p->curToken = 0; char **argv = (char**)malloc(sizeof(char*)*(4+Doxygen::inputPaths.count()+includePath.count()+clangOptions.count())); QDictIterator<void> di(Doxygen::inputPaths); int argc=0; // add include paths for input files for (di.toFirst();di.current();++di,++argc) { QCString inc = QCString("-I")+di.currentKey(); argv[argc]=strdup(inc.data()); //printf("argv[%d]=%s\n",argc,argv[argc]); } // add external include paths for (uint i=0;i<includePath.count();i++) { QCString inc = QCString("-I")+includePath.at(i); argv[argc++]=strdup(inc.data()); } // user specified options for (uint i=0;i<clangOptions.count();i++) { argv[argc++]=strdup(clangOptions.at(i)); } // extra options argv[argc++]=strdup("-ferror-limit=0"); argv[argc++]=strdup("-x"); // Since we can be presented with a .h file that can contain C/C++ or // Objective C code and we need to configure the parser before knowing this, // we use the source file to detected the language. Detection will fail if you // pass a bunch of .h files containing ObjC code, and no sources :-( SrcLangExt lang = getLanguageFromFileName(fileName); if (lang==SrcLangExt_ObjC || p->detectedLang!=ClangParser::Private::Detected_Cpp) { QCString fn = fileName; if (p->detectedLang==ClangParser::Private::Detected_Cpp && (fn.right(4).lower()==".cpp" || fn.right(4).lower()==".cxx" || fn.right(3).lower()==".cc" || fn.right(2).lower()==".c")) { // fall back to C/C++ once we see an extension that indicates this p->detectedLang = ClangParser::Private::Detected_Cpp; } else if (fn.right(3).lower()==".mm") // switch to Objective C++ { p->detectedLang = ClangParser::Private::Detected_ObjCpp; } else if (fn.right(2).lower()==".m") // switch to Objective C { p->detectedLang = ClangParser::Private::Detected_ObjC; } } switch(p->detectedLang) { case ClangParser::Private::Detected_Cpp: argv[argc++]=strdup("c++"); break; case ClangParser::Private::Detected_ObjC: argv[argc++]=strdup("objective-c"); break; case ClangParser::Private::Detected_ObjCpp: argv[argc++]=strdup("objective-c++"); break; } // provide the input and and its dependencies as unsaved files so we can // pass the filtered versions argv[argc++]=strdup(fileName); static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES"); //printf("source %s ----------\n%s\n-------------\n\n", // fileName,p->source.data()); uint numUnsavedFiles = filesInTranslationUnit.count()+1; p->numFiles = numUnsavedFiles; p->sources = new QCString[numUnsavedFiles]; p->ufs = new CXUnsavedFile[numUnsavedFiles]; p->sources[0] = detab(fileToString(fileName,filterSourceFiles,TRUE)); p->ufs[0].Filename = strdup(fileName); p->ufs[0].Contents = p->sources[0].data(); p->ufs[0].Length = p->sources[0].length(); QStrListIterator it(filesInTranslationUnit); uint i=1; for (it.toFirst();it.current() && i<numUnsavedFiles;++it,i++) { p->fileMapping.insert(it.current(),new uint(i)); p->sources[i] = detab(fileToString(it.current(),filterSourceFiles,TRUE)); p->ufs[i].Filename = strdup(it.current()); p->ufs[i].Contents = p->sources[i].data(); p->ufs[i].Length = p->sources[i].length(); } // let libclang do the actual parsing p->tu = clang_parseTranslationUnit(p->index, 0, argv, argc, p->ufs, numUnsavedFiles, CXTranslationUnit_DetailedPreprocessingRecord); // free arguments for (int i=0;i<argc;++i) { free(argv[i]); } free(argv); if (p->tu) { // filter out any includes not found by the clang parser determineInputFilesInSameTu(filesInTranslationUnit); // show any warnings that the compiler produced for (uint i=0, n=clang_getNumDiagnostics(p->tu); i!=n; ++i) { CXDiagnostic diag = clang_getDiagnostic(p->tu, i); CXString string = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions()); err("%s [clang]\n",clang_getCString(string)); clang_disposeString(string); clang_disposeDiagnostic(diag); } // create a source range for the given file QFileInfo fi(fileName); CXFile f = clang_getFile(p->tu, fileName); CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0); CXSourceLocation fileEnd = clang_getLocationForOffset(p->tu, f, p->ufs[0].Length); CXSourceRange fileRange = clang_getRange(fileBegin, fileEnd); // produce a token stream for the file clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens); // produce cursors for each token in the stream p->cursors=new CXCursor[p->numTokens]; clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors); } else { p->tokens = 0; p->numTokens = 0; p->cursors = 0; err("clang: Failed to parse translation unit %s\n",fileName); } }
static void process_ac(int sock) { tpl_node *tn; struct msg_ac msg; wordexp_t flags; tn = msg_ac_node(&msg); tpl_load(tn, TPL_FD, sock); tpl_unpack(tn, 0); tpl_free(tn); struct CXUnsavedFile unsaved = { msg.filename, msg.buffer.addr, msg.buffer.sz }; change_dir(msg.filename); try_load_dotccode(&flags); str_t *partial = extract_partial(&msg); if (partial) msg.col -= partial->len; if (needs_reparsing(&flags, msg.filename)) { if (clang_tu) clang_disposeTranslationUnit(clang_tu); clang_tu = clang_parseTranslationUnit(clang_index, msg.filename, (char const * const *)flags.we_wordv, flags.we_wordc, &unsaved, 1, clang_defaultEditingTranslationUnitOptions()); if (last_filename) free(last_filename); if (last_wordexp.we_wordv) wordfree(&last_wordexp); last_filename = strdup(msg.filename); last_wordexp = flags; } // diag /* for (int i = 0, n = clang_getNumDiagnostics(clang_tu); i != n; ++i) { CXDiagnostic diag = clang_getDiagnostic(clang_tu, i); CXString string = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions()); fprintf(stderr, "%s\n", clang_getCString(string)); clang_disposeString(string); clang_disposeDiagnostic(diag); } */ CXCodeCompleteResults *results; results = clang_codeCompleteAt(clang_tu, msg.filename, msg.line, msg.col, &unsaved, 1, CXCodeComplete_IncludeMacros); free_msg_ac(&msg); // diag /* for (int i = 0, n = clang_codeCompleteGetNumDiagnostics(results); i != n; ++i) { CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i); CXString string = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions()); fprintf(stderr, "%s\n", clang_getCString(string)); clang_disposeString(string); clang_disposeDiagnostic(diag); } */ struct msg_ac_response msg_r = { (partial) ? partial->len : 0, 0, 0 }; if (results) { struct make_ac_ctx ctx; str_t *fmt; init_make_ac_ctx(&ctx); msg_r.proposals_n = filter_out_cc_results(results->Results, results->NumResults, partial, &fmt); sort_cc_results(results->Results, msg_r.proposals_n); if (msg_r.proposals_n > MAX_AC_RESULTS) msg_r.proposals_n = MAX_AC_RESULTS; msg_r.proposals = malloc(sizeof(struct ac_proposal) * msg_r.proposals_n); int cur = 0; for (int i = 0; i < msg_r.proposals_n; ++i) { int added; added = make_ac_proposal(&ctx, &msg_r.proposals[cur], &results->Results[i], fmt); if (added) cur++; } msg_r.proposals_n = cur; free_make_ac_ctx(&ctx); str_free(fmt); } if (partial) str_free(partial); clang_disposeCodeCompleteResults(results); msg_ac_response_send(&msg_r, sock); free_msg_ac_response(&msg_r); }