Index: cfe/trunk/include/clang-c/Index.h =================================================================== --- cfe/trunk/include/clang-c/Index.h +++ cfe/trunk/include/clang-c/Index.h @@ -1289,6 +1289,17 @@ CXTranslationUnit *out_TU); /** + * \brief Same as clang_parseTranslationUnit2 but requires a full command line + * for \c command_line_args including argv[0]. This is useful if the standard + * library paths are relative to the binary. + */ +CINDEX_LINKAGE enum CXErrorCode clang_parseTranslationUnit2FullArgv( + 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, CXTranslationUnit *out_TU); + +/** * \brief Flags that control how translation units are saved. * * The enumerators in this enumeration type are meant to be bitwise @@ -5681,6 +5692,18 @@ unsigned TU_options); /** + * \brief Same as clang_indexSourceFile but requires a full command line + * for \c command_line_args including argv[0]. This is useful if the standard + * library paths are relative to the binary. + */ +CINDEX_LINKAGE int clang_indexSourceFileFullArgv( + CXIndexAction, CXClientData client_data, IndexerCallbacks *index_callbacks, + unsigned index_callbacks_size, unsigned index_options, + const char *source_filename, const char *const *command_line_args, + int num_command_line_args, struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, CXTranslationUnit *out_TU, unsigned TU_options); + +/** * \brief Index the given translation unit via callbacks implemented through * #IndexerCallbacks. * Index: cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp =================================================================== --- cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -39,15 +39,13 @@ Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions); } - SmallVector Args; - Args.push_back(""); // FIXME: Remove dummy argument. - Args.insert(Args.end(), ArgList.begin(), ArgList.end()); + SmallVector Args(ArgList.begin(), ArgList.end()); // FIXME: Find a cleaner way to force the driver into restricted modes. Args.push_back("-fsyntax-only"); // FIXME: We shouldn't have to pass in the path info. - driver::Driver TheDriver("clang", llvm::sys::getDefaultTargetTriple(), + driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(), *Diags); // Don't check that inputs exist, they may have been remapped. Index: cfe/trunk/tools/diagtool/ShowEnabledWarnings.cpp =================================================================== --- cfe/trunk/tools/diagtool/ShowEnabledWarnings.cpp +++ cfe/trunk/tools/diagtool/ShowEnabledWarnings.cpp @@ -64,9 +64,11 @@ new DiagnosticsEngine(DiagIDs, new DiagnosticOptions(), DiagsBuffer)); // Try to build a CompilerInvocation. + SmallVector Args; + Args.push_back("diagtool"); + Args.append(argv, argv + argc); std::unique_ptr Invocation( - createInvocationFromCommandLine(llvm::makeArrayRef(argv, argc), - InterimDiags)); + createInvocationFromCommandLine(Args, InterimDiags)); if (!Invocation) return nullptr; Index: cfe/trunk/tools/libclang/CIndex.cpp =================================================================== --- cfe/trunk/tools/libclang/CIndex.cpp +++ cfe/trunk/tools/libclang/CIndex.cpp @@ -3089,12 +3089,12 @@ break; } } - if (!FoundSpellCheckingArgument) - Args->push_back("-fno-spell-checking"); - Args->insert(Args->end(), command_line_args, command_line_args + num_command_line_args); + if (!FoundSpellCheckingArgument) + Args->insert(Args->begin() + 1, "-fno-spell-checking"); + // The 'source_filename' argument is optional. If the caller does not // specify it then it is assumed that the source file is specified // in the actual argument list. @@ -3157,14 +3157,23 @@ } enum CXErrorCode clang_parseTranslationUnit2( - 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, - CXTranslationUnit *out_TU) { + 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, CXTranslationUnit *out_TU) { + SmallVector Args; + Args.push_back("clang"); + Args.append(command_line_args, command_line_args + num_command_line_args); + return clang_parseTranslationUnit2FullArgv( + CIdx, source_filename, Args.data(), Args.size(), unsaved_files, + num_unsaved_files, options, out_TU); +} + +enum CXErrorCode clang_parseTranslationUnit2FullArgv( + 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, CXTranslationUnit *out_TU) { LOG_FUNC_SECTION { *Log << source_filename << ": "; for (int i = 0; i != num_command_line_args; ++i) Index: cfe/trunk/tools/libclang/Indexing.cpp =================================================================== --- cfe/trunk/tools/libclang/Indexing.cpp +++ cfe/trunk/tools/libclang/Indexing.cpp @@ -907,6 +907,22 @@ unsigned num_unsaved_files, CXTranslationUnit *out_TU, unsigned TU_options) { + SmallVector Args; + Args.push_back("clang"); + Args.append(command_line_args, command_line_args + num_command_line_args); + return clang_indexSourceFileFullArgv( + idxAction, client_data, index_callbacks, index_callbacks_size, + index_options, source_filename, Args.data(), Args.size(), unsaved_files, + num_unsaved_files, out_TU, TU_options); +} + +int clang_indexSourceFileFullArgv( + CXIndexAction idxAction, CXClientData client_data, + IndexerCallbacks *index_callbacks, unsigned index_callbacks_size, + unsigned index_options, const char *source_filename, + const char *const *command_line_args, int num_command_line_args, + struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files, + CXTranslationUnit *out_TU, unsigned TU_options) { LOG_FUNC_SECTION { *Log << source_filename << ": "; for (int i = 0; i != num_command_line_args; ++i) Index: cfe/trunk/tools/libclang/libclang.exports =================================================================== --- cfe/trunk/tools/libclang/libclang.exports +++ cfe/trunk/tools/libclang/libclang.exports @@ -249,6 +249,7 @@ clang_indexLoc_getCXSourceLocation clang_indexLoc_getFileLocation clang_indexSourceFile +clang_indexSourceFileFullArgv clang_indexTranslationUnit clang_index_getCXXClassDeclInfo clang_index_getClientContainer @@ -284,6 +285,7 @@ clang_Location_isFromMainFile clang_parseTranslationUnit clang_parseTranslationUnit2 +clang_parseTranslationUnit2FullArgv clang_remap_dispose clang_remap_getFilenames clang_remap_getNumFiles Index: cfe/trunk/unittests/libclang/LibclangTest.cpp =================================================================== --- cfe/trunk/unittests/libclang/LibclangTest.cpp +++ cfe/trunk/unittests/libclang/LibclangTest.cpp @@ -379,8 +379,10 @@ Filename = Path.str(); Files.insert(Filename); } + llvm::sys::fs::create_directories(llvm::sys::path::parent_path(Filename)); std::ofstream OS(Filename); OS << Contents; + assert(OS.good()); } void DisplayDiagnostics() { unsigned NumDiagnostics = clang_getNumDiagnostics(ClangTU); @@ -465,3 +467,27 @@ ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */)); EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU)); } + +TEST_F(LibclangReparseTest, clang_parseTranslationUnit2FullArgv) { + std::string EmptyFiles[] = {"lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o", + "include/arm-linux-gnueabi/.keep", + "include/c++/4.6.1/vector"}; + + for (auto &Name : EmptyFiles) + WriteFile(Name, "\n"); + + std::string Filename = "test.cc"; + WriteFile(Filename, "#include \n"); + + std::string Clang = "bin/clang"; + WriteFile(Clang, ""); + + const char *Argv[] = {Clang.c_str(), "-target", "arm-linux-gnueabi"}; + + EXPECT_EQ(CXError_Success, + clang_parseTranslationUnit2FullArgv(Index, Filename.c_str(), Argv, + sizeof(Argv) / sizeof(Argv[0]), + nullptr, 0, TUFlags, &ClangTU)); + EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU)); + DisplayDiagnostics(); +}