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 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(); }