[libclang] Add entry points that take a full command line including argv[0].
This provides both a more uniform interface and makes libclang behave like clang tooling wrt relative paths against argv[0]. This is necessary for finding paths to a c++ standard library relative to a clang binary given in a compilation database. It can also be used to find paths relative to libclang.so if the full path to it is passed in. Differential Revision: http://reviews.llvm.org/D14695 llvm-svn: 253466
This commit is contained in:
parent
4ba4816b97
commit
c02670ed50
|
@ -1288,6 +1288,17 @@ clang_parseTranslationUnit2(CXIndex CIdx,
|
|||
unsigned options,
|
||||
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.
|
||||
*
|
||||
|
@ -5680,6 +5691,18 @@ CINDEX_LINKAGE int clang_indexSourceFile(CXIndexAction,
|
|||
CXTranslationUnit *out_TU,
|
||||
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.
|
||||
|
|
|
@ -39,15 +39,13 @@ clang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList,
|
|||
Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions);
|
||||
}
|
||||
|
||||
SmallVector<const char *, 16> Args;
|
||||
Args.push_back("<clang>"); // FIXME: Remove dummy argument.
|
||||
Args.insert(Args.end(), ArgList.begin(), ArgList.end());
|
||||
SmallVector<const char *, 16> 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.
|
||||
|
|
|
@ -64,9 +64,11 @@ createDiagnostics(unsigned int argc, char **argv) {
|
|||
new DiagnosticsEngine(DiagIDs, new DiagnosticOptions(), DiagsBuffer));
|
||||
|
||||
// Try to build a CompilerInvocation.
|
||||
SmallVector<const char *, 4> Args;
|
||||
Args.push_back("diagtool");
|
||||
Args.append(argv, argv + argc);
|
||||
std::unique_ptr<CompilerInvocation> Invocation(
|
||||
createInvocationFromCommandLine(llvm::makeArrayRef(argv, argc),
|
||||
InterimDiags));
|
||||
createInvocationFromCommandLine(Args, InterimDiags));
|
||||
if (!Invocation)
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -3089,12 +3089,12 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
|
|||
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 @@ clang_parseTranslationUnit(CXIndex CIdx,
|
|||
}
|
||||
|
||||
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<const char *, 4> 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)
|
||||
|
|
|
@ -907,6 +907,22 @@ int clang_indexSourceFile(CXIndexAction idxAction,
|
|||
unsigned num_unsaved_files,
|
||||
CXTranslationUnit *out_TU,
|
||||
unsigned TU_options) {
|
||||
SmallVector<const char *, 4> 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)
|
||||
|
|
|
@ -249,6 +249,7 @@ clang_hashCursor
|
|||
clang_indexLoc_getCXSourceLocation
|
||||
clang_indexLoc_getFileLocation
|
||||
clang_indexSourceFile
|
||||
clang_indexSourceFileFullArgv
|
||||
clang_indexTranslationUnit
|
||||
clang_index_getCXXClassDeclInfo
|
||||
clang_index_getClientContainer
|
||||
|
@ -284,6 +285,7 @@ clang_Location_isInSystemHeader
|
|||
clang_Location_isFromMainFile
|
||||
clang_parseTranslationUnit
|
||||
clang_parseTranslationUnit2
|
||||
clang_parseTranslationUnit2FullArgv
|
||||
clang_remap_dispose
|
||||
clang_remap_getFilenames
|
||||
clang_remap_getNumFiles
|
||||
|
|
|
@ -379,8 +379,10 @@ public:
|
|||
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 @@ TEST_F(LibclangReparseTest, ReparseWithModule) {
|
|||
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 <vector>\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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue