void PrintTo(const TranslationUnit &translationUnit, ::std::ostream *os) { *os << "TranslationUnit(" << translationUnit.filePath().constData() << ", " << translationUnit.projectPartId().constData() << ", " << translationUnit.documentRevision() << ")"; }
int test_main(int argc, char * argv[]) { try { // setup log initializeStderrLog("coredev", ::core::system::kLogLevelWarning); // ignore sigpipe Error error = ::core::system::ignoreSignal(::core::system::SigPipe); if (error) LOG_ERROR(error); // write a C++ file std::string cpp = "#include <string>\n" "class X { public:\n" " void test(int y, int x = 10);\n" "}\n" "void X::test(int y, int x) {}\n" "void foobar() {\n" " X x;\n" " x." "}"; std::ofstream ostr("foo.cpp"); ostr << cpp; ostr.close(); // load libclang using namespace libclang; std::string diagnostics; clang().load(EmbeddedLibrary(), LibraryVersion(3,4,0), &diagnostics); if (!clang().isLoaded()) { std::cerr << "Failed to load libclang: " << diagnostics << std::endl; return EXIT_FAILURE; } // create a source index and get a translation unit for it SourceIndex sourceIndex; TranslationUnit tu = sourceIndex.getTranslationUnit("foo.cpp"); if (tu.empty()) { std::cerr << "No translation unit foo.cpp" << std::endl; return EXIT_FAILURE; } // code complete CodeCompleteResults results = tu.codeCompleteAt("foo.cpp", 8, 6); for (unsigned i = 0; i<results.getNumResults(); i++) { std::cout << results.getResult(i).getTypedText() << std::endl; std::cout << " " << results.getResult(i).getText() << std::endl; } return EXIT_SUCCESS; } CATCH_UNEXPECTED_EXCEPTION // if we got this far we had an unexpected exception return EXIT_FAILURE ; }
IAsyncJob::AsyncPrepareResult UpdateAnnotationsJob::prepareAsyncRun() { const JobRequest jobRequest = context().jobRequest; QTC_ASSERT(isExpectedJobRequestType(jobRequest), return AsyncPrepareResult()); QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); const TranslationUnit translationUnit = *m_translationUnit; const TranslationUnitUpdateInput updateInput = createUpdateInput(m_pinnedDocument); setRunner([translationUnit, updateInput]() { TIME_SCOPE_DURATION("UpdateAnnotationsJobRunner"); // Update UpdateAnnotationsJob::AsyncResult asyncResult; asyncResult.updateResult = translationUnit.update(updateInput); // Collect translationUnit.extractAnnotations(asyncResult.firstHeaderErrorDiagnostic, asyncResult.diagnostics, asyncResult.tokenInfos, asyncResult.skippedSourceRanges); asyncResult.unresolvedFilePaths.unite( unresolvedFilePaths({asyncResult.firstHeaderErrorDiagnostic})); asyncResult.unresolvedFilePaths.unite(unresolvedFilePaths(asyncResult.diagnostics)); return asyncResult; }); return AsyncPrepareResult{translationUnit.id()}; }
bool JobQueue::isJobRequestOutDated(const JobRequest &jobRequest) const { const JobRequest::Requirements requirements = jobRequest.requirements; const UnsavedFiles unsavedFiles = m_translationUnits.unsavedFiles(); if (requirements.testFlag(JobRequest::CurrentUnsavedFiles)) { if (jobRequest.unsavedFilesChangeTimePoint != unsavedFiles.lastChangeTimePoint()) { qCDebug(jobsLog) << "Removing due to outdated unsaved files:" << jobRequest; return true; } } bool projectCheckedAndItExists = false; if (requirements.testFlag(JobRequest::DocumentValid)) { if (!m_translationUnits.hasTranslationUnit(jobRequest.filePath, jobRequest.projectPartId)) { qCDebug(jobsLog) << "Removing due to already closed document:" << jobRequest; return true; } if (!m_projectParts.hasProjectPart(jobRequest.projectPartId)) { qCDebug(jobsLog) << "Removing due to already closed project:" << jobRequest; return true; } projectCheckedAndItExists = true; const TranslationUnit translationUnit = m_translationUnits.translationUnit(jobRequest.filePath, jobRequest.projectPartId); if (!translationUnit.isIntact()) { qCDebug(jobsLog) << "Removing due to not intact translation unit:" << jobRequest; return true; } if (requirements.testFlag(JobRequest::CurrentDocumentRevision)) { if (translationUnit.documentRevision() != jobRequest.documentRevision) { qCDebug(jobsLog) << "Removing due to changed document revision:" << jobRequest; return true; } } } if (requirements.testFlag(JobRequest::CurrentProject)) { if (!projectCheckedAndItExists && !m_projectParts.hasProjectPart(jobRequest.projectPartId)) { qCDebug(jobsLog) << "Removing due to already closed project:" << jobRequest; return true; } const ProjectPart &project = m_projectParts.project(jobRequest.projectPartId); if (project.lastChangeTimePoint() != jobRequest.projectChangeTimePoint) { qCDebug(jobsLog) << "Removing due to outdated project:" << jobRequest; return true; } } return false; }
void TranslationUnits::sendDocumentAnnotations(const TranslationUnit &translationUnit) { if (sendDocumentAnnotationsCallback) { DocumentAnnotationsChangedMessage message(translationUnit.fileContainer(), translationUnit.mainFileDiagnostics(), translationUnit.highlightingMarks().toHighlightingMarksContainers(), translationUnit.skippedSourceRanges().toSourceRangeContainers()); sendDocumentAnnotationsCallback(std::move(message)); } }
TranslationUnit *parse(const QByteArray &source, TranslationUnit::ParseMode mode, LanguageFeatures features) { const StringLiteral *fileId = control->stringLiteral("<stdin>"); TranslationUnit *unit = new TranslationUnit(control.data(), fileId); unit->setSource(source.constData(), source.length()); unit->setLanguageFeatures(features); unit->parse(mode); return unit; }
TranslationUnitUpdater Document::createUpdater() const { TranslationUnit unit = translationUnit(); const TranslationUnitUpdateInput updateInput = createUpdateInput(); TranslationUnitUpdater updater(unit.id(), unit.cxIndex(), unit.cxTranslationUnit(), updateInput); return updater; }
static int priority(const TranslationUnit &translationUnit) { int thePriority = 0; if (translationUnit.isUsedByCurrentEditor()) thePriority += 1000; if (translationUnit.isVisibleInEditor()) thePriority += 100; return thePriority; }
TranslationUnit *parse(const QByteArray &source, TranslationUnit::ParseMode mode, bool blockErrors = false) { StringLiteral *fileId = control.findOrInsertStringLiteral("<stdin>"); TranslationUnit *unit = new TranslationUnit(&control, fileId); unit->setObjCEnabled(true); unit->setSource(source.constData(), source.length()); unit->blockErrors(blockErrors); unit->parse(mode); return unit; }
void tst_Lookup::base_class_defined_1() { Overview overview; const QByteArray source = "\n" "class base {};\n" "class derived: public base {};\n"; Document::Ptr doc = Document::create("base_class_defined_1"); doc->setSource(source); doc->parse(); doc->check(); QVERIFY(doc->diagnosticMessages().isEmpty()); QCOMPARE(doc->globalSymbolCount(), 2U); Snapshot snapshot; snapshot.insert(doc->fileName(), doc); Document::Ptr emptyDoc = Document::create("<empty>"); Class *baseClass = doc->globalSymbolAt(0)->asClass(); QVERIFY(baseClass); Class *derivedClass = doc->globalSymbolAt(1)->asClass(); QVERIFY(derivedClass); LookupContext ctx(derivedClass, emptyDoc, doc, snapshot); const QList<Symbol *> candidates = ctx.resolveClass(derivedClass->baseClassAt(0)->name()); QCOMPARE(candidates.size(), 1); QCOMPARE(candidates.at(0), baseClass); TranslationUnit *unit = doc->translationUnit(); QVERIFY(unit != 0); TranslationUnitAST *ast = unit->ast()->asTranslationUnit(); QVERIFY(ast != 0); ClassSymbols classSymbols(doc->control()); classSymbols(ast); QCOMPARE(classSymbols.size(), 2); const QMap<Class *, ClassSpecifierAST *> classToAST = invert(classSymbols.asMap()); QVERIFY(classToAST.value(baseClass) != 0); QVERIFY(classToAST.value(derivedClass) != 0); }
IAsyncJob::AsyncPrepareResult UpdateExtraDocumentAnnotationsJob::prepareAsyncRun() { const JobRequest jobRequest = context().jobRequest; QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); const TranslationUnit translationUnit = *m_translationUnit; setRunner([translationUnit]() { TIME_SCOPE_DURATION("UpdateExtraDocumentAnnotationsJobRunner"); return translationUnit.fullTokenInfos().toTokenInfoContainers(); }); return AsyncPrepareResult{translationUnit.id()}; }
TranslationUnit *parse(const QByteArray &source, TranslationUnit::ParseMode mode, bool enableObjc, bool qtMocRun) { const StringLiteral *fileId = control->stringLiteral("<stdin>"); TranslationUnit *unit = new TranslationUnit(control.data(), fileId); unit->setSource(source.constData(), source.length()); unit->setObjCEnabled(enableObjc); unit->setQtMocRunEnabled(qtMocRun); unit->parse(mode); return unit; }
TEST(visit, declTest) { const char* path = "loadsrcs/decl.c"; CyFlowVisitor* visitor = new CyFlowVisitor(); EXPECT_EQ( 0 ,cflowSrcParse(path)); TranslationUnit* unit = TranslationUnit::getInstance(); unit->accept(visitor); visitor->save("dots/decl"); unit->deleteInstance(); delete visitor; }
void tst_Lookup::base_class_defined_1() { Overview overview; const QByteArray source = "\n" "class base {};\n" "class derived: public base {};\n"; Document::Ptr doc = Document::create("base_class_defined_1"); doc->setUtf8Source(source); doc->parse(); doc->check(); QVERIFY(doc->diagnosticMessages().isEmpty()); QCOMPARE(doc->globalSymbolCount(), 2U); Snapshot snapshot; snapshot.insert(doc); Class *baseClass = doc->globalSymbolAt(0)->asClass(); QVERIFY(baseClass); Class *derivedClass = doc->globalSymbolAt(1)->asClass(); QVERIFY(derivedClass); const LookupContext ctx(doc, snapshot); LookupScope *klass = ctx.lookupType(derivedClass->baseClassAt(0)->name(), derivedClass->enclosingScope()); QVERIFY(klass != 0); QCOMPARE(klass->symbols().size(), 1); QCOMPARE(klass->symbols().first(), baseClass); TranslationUnit *unit = doc->translationUnit(); QVERIFY(unit != 0); TranslationUnitAST *ast = unit->ast()->asTranslationUnit(); QVERIFY(ast != 0); ClassSymbols classSymbols(unit); classSymbols(ast); QCOMPARE(classSymbols.size(), 2); const QMap<Class *, ClassSpecifierAST *> classToAST = invert(classSymbols.asMap()); QVERIFY(classToAST.value(baseClass) != 0); QVERIFY(classToAST.value(derivedClass) != 0); }
TEST_F( TranslationUnitTest, InvalidTranslationUnit ) { TranslationUnit unit; EXPECT_TRUE( unit.IsCurrentlyUpdating() ); EXPECT_EQ( std::vector< CompletionData >(), unit.CandidatesForLocation( 1, 1, std::vector< UnsavedFile >() ) ); EXPECT_EQ( Location(), unit.GetDeclarationLocation( 1, 1, std::vector< UnsavedFile >() ) ); EXPECT_EQ( Location(), unit.GetDefinitionLocation( 1, 1, std::vector< UnsavedFile >() ) ); EXPECT_EQ( std::string( "Internal error: no translation unit" ), unit.GetTypeAtLocation( 1, 1, std::vector< UnsavedFile >() ) ); EXPECT_EQ( std::string( "Internal error: no translation unit" ), unit.GetEnclosingFunctionAtLocation( 1, 1, std::vector< UnsavedFile >() ) ); EXPECT_EQ( DocumentationData(), unit.GetDocsForLocationInFile( 1, 1, std::vector< UnsavedFile >(), false ) ); }
void Symbol::setSourceLocation(unsigned sourceLocation) { _sourceLocation = sourceLocation; if (! _sourceLocation) { _isGenerated = false; _sourceOffset = 0; } else { TranslationUnit *unit = translationUnit(); const Token &tk = unit->tokenAt(sourceLocation); _isGenerated = tk.f.generated; _sourceOffset = tk.offset; } }
/// Currently, we return the end of fileName.cpp /// \todo take the definitions of the surrounding declarations into account QList<InsertionLocation> InsertionPointLocator::methodDefinition( Declaration *declaration) const { QList<InsertionLocation> result; if (!declaration) return result; const QString declFileName = QString::fromUtf8(declaration->fileName(), declaration->fileNameLength()); QString target = declFileName; if (!isSourceFile(declFileName)) { Internal::CppToolsPlugin *cpptools = Internal::CppToolsPlugin::instance(); QString candidate = cpptools->correspondingHeaderOrSource(declFileName); if (!candidate.isEmpty()) target = candidate; } Document::Ptr doc = m_refactoringChanges->file(target).cppDocument(); if (doc.isNull()) return result; Snapshot simplified = m_refactoringChanges->snapshot().simplified(doc); if (Symbol *s = simplified.findMatchingDefinition(declaration)) { if (Function *f = s->asFunction()) { if (f->isConst() == declaration->type().isConst() && f->isVolatile() == declaration->type().isVolatile()) return result; } } TranslationUnit *xUnit = doc->translationUnit(); unsigned tokenCount = xUnit->tokenCount(); if (tokenCount < 2) // no tokens available return result; unsigned line = 0, column = 0; xUnit->getTokenEndPosition(xUnit->tokenCount() - 2, &line, &column); const QLatin1String prefix("\n\n"); result.append(InsertionLocation(target, prefix, QString(), line, column)); return result; }
IAsyncJob::AsyncPrepareResult UpdateDocumentAnnotationsJob::prepareAsyncRun() { const JobRequest jobRequest = context().jobRequest; QTC_ASSERT(jobRequest.type == JobRequest::Type::UpdateDocumentAnnotations, return AsyncPrepareResult()); try { m_pinnedDocument = context().documentForJobRequest(); m_pinnedFileContainer = m_pinnedDocument.fileContainer(); const TranslationUnit translationUnit = m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit); const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput(); setRunner([translationUnit, updateInput]() { return runAsyncHelper(translationUnit, updateInput); }); return AsyncPrepareResult{translationUnit.id()}; } catch (const std::exception &exception) { qWarning() << "Error in UpdateDocumentAnnotationsJob::prepareAsyncRun:" << exception.what(); return AsyncPrepareResult(); } }
bool operator==(const TranslationUnit &first, const TranslationUnit &second) { return first.filePath() == second.filePath() && first.projectPartId() == second.projectPartId(); }
/* Walk the codemodel. */ void CodeModelAttributes::createAttributes(TranslationUnit translationUnit) { m_translationUnit = translationUnit; parseScope(const_cast<CodeModel::NamespaceScope *>(translationUnit.codeModel())); }
Error getCppCompletions(const core::json::JsonRpcRequest& request, core::json::JsonRpcResponse* pResponse) { // get params std::string docPath, userText; int line, column; Error error = json::readParams(request.params, &docPath, &line, &column, &userText); if (error) return error; // resolve the docPath if it's aliased FilePath filePath = module_context::resolveAliasedPath(docPath); // get the translation unit and do the code completion std::string filename = filePath.absolutePath(); TranslationUnit tu = rSourceIndex().getTranslationUnit(filename); if (!tu.empty()) { std::string lastTypedText; json::Array completionsJson; boost::shared_ptr<CodeCompleteResults> pResults = tu.codeCompleteAt(filename, line, column); if (!pResults->empty()) { // get results for (unsigned i = 0; i<pResults->getNumResults(); i++) { CodeCompleteResult result = pResults->getResult(i); // filter on user text if we have it if (!userText.empty() && !boost::algorithm::starts_with(result.getTypedText(), userText)) { continue; } // check whether this completion is valid and bail if not if (result.getAvailability() != CXAvailability_Available) { continue; } std::string typedText = result.getTypedText(); // if we have the same typed text then just ammend previous result if ((typedText == lastTypedText) && !completionsJson.empty()) { json::Object& res = completionsJson.back().get_obj(); json::Array& text = res["text"].get_array(); text.push_back(friendlyCompletionText(result)); } else { completionsJson.push_back(toJson(result)); } lastTypedText = typedText; } } json::Object resultJson; resultJson["completions"] = completionsJson; pResponse->setResult(resultJson); } else { // set null result indicating this file doesn't support completions pResponse->setResult(json::Value()); } return Success(); }
Nameables resolve (TranslationUnit& tu, ScopedName const& from, Name const& name) { if (trace) cerr << "resolve: starting resolution process for \'" << name << "\' from \'" << from << "\'" << endl; Nameables r; // Check if name is already scoped. // if (name.scoped ()) { r = tu.lookup (ScopedName (name)); } else { // Obtain all nodes corresponding to this scope name. // for (ScopedName next (from);;) { Nameables scopes (tu.lookup (next)); // Lookup the name in each scope. // for (Nameables::const_iterator i (scopes.begin ()), end (scopes.end ()); i != end; ++i) { if (Scope* s = dynamic_cast<Scope*> (*i)) { s->lookup (name, r); } } if (r.begin () != r.end () || next.simple ()) { // Found something -or- at the root scope. // break; } next = ScopedName (next.begin (), next.end () - 1); } } if (r.begin () == r.end ()) { if (trace) cerr << "resolve: resolution process for \'" << name << "\' from \'" << from << "\' failed." << endl; throw NotFound (); } else { if (trace) cerr << "resolve: resolution process for \'" << name << "\' from \'" << from << "\' succeeded:" << endl; for (Nameables::const_iterator i (r.begin ()), end (r.end ()); i != end; ++i) { if (trace) cerr << "\t\'" << (**i).scoped_name () << "\'" << endl; } } return r; }
int main(int argc, char **argv) { llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa"); std::vector<ASTUnit*> ASTUnits; Program Prog; Indexer Idxer(Prog); if (InputFilenames.empty()) return 0; DiagnosticOptions DiagOpts; llvm::IntrusiveRefCntPtr<Diagnostic> Diags = CompilerInstance::createDiagnostics(DiagOpts, argc, argv); for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) { const std::string &InFile = InputFilenames[i]; llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromASTFile(InFile, Diags)); if (!AST) return 1; ASTUnits.push_back(AST.take()); } if (ViewCallGraph) { llvm::OwningPtr<CallGraph> CG; CG.reset(new CallGraph(Prog)); for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) CG->addTU(ASTUnits[i]->getASTContext()); CG->ViewCallGraph(); return 0; } if (AnalyzeFunction.empty()) return 0; // Feed all ASTUnits to the Indexer. for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) { ASTUnitTU *TU = new ASTUnitTU(ASTUnits[i]); Idxer.IndexAST(TU); } Entity Ent = Entity::get(AnalyzeFunction, Prog); FunctionDecl *FD; TranslationUnit *TU; llvm::tie(FD, TU) = Idxer.getDefinitionFor(Ent); if (!FD) return 0; // Create an analysis engine. Preprocessor &PP = TU->getPreprocessor(); // Hard code options for now. AnalysisManager AMgr(TU->getASTContext(), PP.getDiagnostics(), PP.getLangOptions(), /* PathDiagnostic */ 0, CreateRegionStoreManager, CreateRangeConstraintManager, &Idxer, /* MaxNodes */ 300000, /* MaxLoop */ 3, /* VisualizeEG */ false, /* VisualizeEGUbi */ false, /* PurgeDead */ true, /* EagerlyAssume */ false, /* TrimGraph */ false, /* InlineCall */ true, /* UseUnoptimizedCFG */ false); GRTransferFuncs* TF = MakeCFRefCountTF(AMgr.getASTContext(), /*GC*/false, AMgr.getLangOptions()); GRExprEngine Eng(AMgr, TF); Eng.ExecuteWorkList(AMgr.getStackFrame(FD, TU), AMgr.getMaxNodes()); return 0; }
bool operator==(const FileContainer &fileContainer, const TranslationUnit &translationUnit) { return fileContainer.filePath() == translationUnit.filePath() && fileContainer.projectPartId() == translationUnit.projectPartId(); }
core::Error findReferences(const core::libclang::FileLocation& location, std::string* pSpelling, std::vector<core::libclang::FileRange>* pRefs) { Cursor cursor = rSourceIndex().referencedCursorForFileLocation(location); if (!cursor.isValid() || !cursor.isDeclaration()) return Success(); // get it's USR (bail if it doesn't have one) std::string USR = cursor.getUSR(); if (USR.empty()) return Success(); // determine what translation units to look in -- if this is a package // then we look throughout all the source code in the package. if (rCompilationDatabase().hasTranslationUnit( location.filePath.absolutePath())) { // get all translation units to search std::vector<std::string> files = rCompilationDatabase() .translationUnits(); // get translation units we've already indexed std::map<std::string,TranslationUnit> indexedUnits = rSourceIndex().getIndexedTranslationUnits(); for (const std::string& filename : files) { // first look in already indexed translation units // (this will pickup unsaved files) std::map<std::string,TranslationUnit>::iterator it = indexedUnits.find(filename); if (it != indexedUnits.end()) { findReferences(USR, it->second.getCXTranslationUnit(), pSpelling, pRefs); } else { // get the compilation arguments for this file and use them to // create a temporary translation unit to search std::vector<std::string> compileArgs = rCompilationDatabase().compileArgsForTranslationUnit(filename, true); if (compileArgs.empty()) continue; // create temporary index CXIndex index = libclang::clang().createIndex( 1 /* Exclude PCH */, (rSourceIndex().verbose() > 0) ? 1 : 0); // get args in form clang expects core::system::ProcessArgs argsArray(compileArgs); // parse the translation unit CXTranslationUnit tu = libclang::clang().parseTranslationUnit( index, filename.c_str(), argsArray.args(), gsl::narrow_cast<int>(argsArray.argCount()), nullptr, 0, // no unsaved files CXTranslationUnit_None | CXTranslationUnit_Incomplete); // find references findReferences(USR, tu, pSpelling, pRefs); // dispose translation unit and index libclang::clang().disposeTranslationUnit(tu); libclang::clang().disposeIndex(index); } } } // not a package, just search locally else { TranslationUnit tu = rSourceIndex().getTranslationUnit( location.filePath.absolutePath(), true); if (!tu.empty()) findReferences(USR, tu.getCXTranslationUnit(), pSpelling, pRefs); } return Success(); }