vladimir.plyashkun created this revision.
vladimir.plyashkun added a project: clang.
Herald added a subscriber: mgorny.

Due to command line length restrictions, arguments can be passed through 
response files. 
Before trying to load compilation database from command line, response files 
should be expanded first.


Repository:
  rL LLVM

https://reviews.llvm.org/D34440

Files:
  lib/Tooling/CommonOptionsParser.cpp
  unittests/Tooling/CMakeLists.txt
  unittests/Tooling/CommonOptionsParserTest.cpp

Index: unittests/Tooling/CMakeLists.txt
===================================================================
--- unittests/Tooling/CMakeLists.txt
+++ unittests/Tooling/CMakeLists.txt
@@ -12,6 +12,7 @@
 
 add_clang_unittest(ToolingTests
   CommentHandlerTest.cpp
+  CommonOptionsParserTest.cpp
   CompilationDatabaseTest.cpp
   FixItTest.cpp
   LookupTest.cpp
Index: unittests/Tooling/CommonOptionsParserTest.cpp
===================================================================
--- /dev/null
+++ unittests/Tooling/CommonOptionsParserTest.cpp
@@ -0,0 +1,68 @@
+//===- unittests/Tooling/CommonOptionsParserTest.cpp
+//----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "gtest/gtest.h"
+#include <fstream>
+
+using namespace llvm;
+using namespace clang::tooling;
+
+class CommonOptionsParserTest : public testing::Test {
+public:
+  SmallString<128> TestDir;
+  SmallString<128> ResponseFileName;
+
+  CommonOptionsParserTest() {
+    std::error_code EC = sys::fs::createUniqueDirectory("unittest", TestDir);
+    EXPECT_TRUE(!EC);
+    sys::path::append(ResponseFileName, TestDir, "resp");
+  }
+  void setResponseFileContent(const std::string &content) {
+    std::ofstream File(ResponseFileName.c_str());
+    EXPECT_TRUE(File.is_open());
+    File << content;
+    File.close();
+  }
+  ~CommonOptionsParserTest() override {
+    sys::fs::remove(ResponseFileName);
+    sys::fs::remove(TestDir);
+  }
+};
+
+TEST_F(CommonOptionsParserTest,
+       ExpandResponseFileBeforeLoadingCompilationDatabase) {
+  setResponseFileContent("-option_1 -- -option_2=true -option_3");
+  SmallString<128> ResponseRef;
+  ResponseRef.append(1, '@');
+  ResponseRef.append(ResponseFileName.c_str());
+  int Argc = 3;
+  const char *Argv[] = {"pos_1", "pos_2", ResponseRef.c_str()};
+  cl::OptionCategory Category("options");
+  cl::opt<bool> option1("option_1", cl::desc(""), cl::init(false),
+                        cl::cat(Category));
+  cl::opt<bool> option2("option_2", cl::desc(""), cl::init(false),
+                        cl::cat(Category));
+  cl::opt<bool> option3("option_3", cl::desc(""), cl::init(false),
+                        cl::cat(Category));
+  CommonOptionsParser Parser(Argc, Argv, Category);
+  CompilationDatabase &Database = Parser.getCompilations();
+  std::vector<CompileCommand> ActualCC = Database.getCompileCommands("source");
+  ASSERT_EQ(1u, ActualCC.size());
+  std::vector<std::string> ExpectedCmd;
+  ExpectedCmd.push_back("clang-tool");
+  ExpectedCmd.push_back("-option_2=true");
+  ExpectedCmd.push_back("-option_3");
+  ExpectedCmd.push_back("source");
+
+  ASSERT_EQ(ExpectedCmd, ActualCC[0].CommandLine);
+}
\ No newline at end of file
Index: lib/Tooling/CommonOptionsParser.cpp
===================================================================
--- lib/Tooling/CommonOptionsParser.cpp
+++ lib/Tooling/CommonOptionsParser.cpp
@@ -25,6 +25,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/StringSaver.h"
 #include "clang/Tooling/ArgumentsAdjusters.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Tooling.h"
@@ -115,7 +116,13 @@
       cl::cat(Category));
 
   cl::HideUnrelatedOptions(Category);
-
+  //Expand response files before loading compilation database from command line
+  SmallVector<const char *, 20> newArgv(argv, argv + argc);
+  BumpPtrAllocator A;
+  StringSaver Saver(A);
+  cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, newArgv);
+  argv = &newArgv[0];
+  argc = static_cast<int>(newArgv.size());
   std::string ErrorMessage;
   Compilations =
       FixedCompilationDatabase::loadFromCommandLine(argc, argv, ErrorMessage);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to