summaryrefslogtreecommitdiff
path: root/tools/arcmt-test
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-07-09 20:00:58 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-07-09 20:00:58 +0000
commit69325d5b7cfecf1b3128745efc33612aedf1b8b4 (patch)
treeddd1627268276e97d9a2394625f3aff4b904f5ec /tools/arcmt-test
parent8dd5cdfc462026648b480adaf774e24bc620f7c3 (diff)
downloadclang-69325d5b7cfecf1b3128745efc33612aedf1b8b4.tar.gz
clang-69325d5b7cfecf1b3128745efc33612aedf1b8b4.tar.bz2
clang-69325d5b7cfecf1b3128745efc33612aedf1b8b4.tar.xz
[arcmt] Introduce new '-ccc-arcmt-migrate <path>' ARC migration driver option.
This is a new mode of migration, where we avoid modifying the original files but we emit temporary files instead. <path> will be used to keep migration process metadata. Currently the temporary files that are produced are put in the system's temp directory but we can put them in the <path> if is necessary. Also introduce new ARC migration functions in libclang whose only purpose, currently, is to accept <path> and provide pairs of original file/transformed file to map from the originals to the files after transformations are applied. Finally introduce the c-arcmt-test utility that exercises the new libclang functions, update arcmt-test, and add tests for the whole process. rdar://9735086. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134844 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/arcmt-test')
-rw-r--r--tools/arcmt-test/arcmt-test.cpp125
1 files changed, 124 insertions, 1 deletions
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
index 702e13a414..eb0f56943f 100644
--- a/tools/arcmt-test/arcmt-test.cpp
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -14,7 +14,9 @@
#include "clang/Frontend/Utils.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
using namespace clang;
using namespace arcmt;
@@ -37,6 +39,20 @@ VerifyDiags("verify",llvm::cl::desc("Verify emitted diagnostics and warnings"));
static llvm::cl::opt<bool>
VerboseOpt("v", llvm::cl::desc("Enable verbose output"));
+static llvm::cl::opt<bool>
+VerifyTransformedFiles("verify-transformed-files",
+llvm::cl::desc("Read pairs of file mappings (typically the output of "
+ "c-arcmt-test) and compare their contents with the filenames "
+ "provided in command-line"));
+
+static llvm::cl::opt<std::string>
+RemappingsFile("remappings-file",
+ llvm::cl::desc("Pairs of file mappings (typically the output of "
+ "c-arcmt-test)"));
+
+static llvm::cl::list<std::string>
+ResultFiles(llvm::cl::Positional, llvm::cl::desc("<filename>..."));
+
static llvm::cl::extrahelp extraHelp(
"\nusage with compiler args: arcmt-test [options] --args [compiler flags]\n");
@@ -183,6 +199,105 @@ static bool performTransformations(llvm::StringRef resourcesPath,
return false;
}
+static bool filesCompareEqual(llvm::StringRef fname1, llvm::StringRef fname2) {
+ using namespace llvm;
+
+ OwningPtr<MemoryBuffer> file1;
+ MemoryBuffer::getFile(fname1, file1);
+ if (!file1)
+ return false;
+
+ OwningPtr<MemoryBuffer> file2;
+ MemoryBuffer::getFile(fname2, file2);
+ if (!file2)
+ return false;
+
+ return file1->getBuffer() == file2->getBuffer();
+}
+
+static bool verifyTransformedFiles(llvm::ArrayRef<std::string> resultFiles) {
+ using namespace llvm;
+
+ assert(!resultFiles.empty());
+
+ std::map<StringRef, StringRef> resultMap;
+
+ for (ArrayRef<std::string>::iterator
+ I = resultFiles.begin(), E = resultFiles.end(); I != E; ++I) {
+ StringRef fname(*I);
+ if (!fname.endswith(".result")) {
+ errs() << "error: filename '" << fname
+ << "' does not have '.result' extension\n";
+ return true;
+ }
+ resultMap[sys::path::stem(fname)] = fname;
+ }
+
+ OwningPtr<MemoryBuffer> inputBuf;
+ if (RemappingsFile.empty())
+ MemoryBuffer::getSTDIN(inputBuf);
+ else
+ MemoryBuffer::getFile(RemappingsFile, inputBuf);
+ if (!inputBuf) {
+ errs() << "error: could not read remappings input\n";
+ return true;
+ }
+
+ SmallVector<StringRef, 8> strs;
+ inputBuf->getBuffer().split(strs, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+
+ if (strs.empty()) {
+ errs() << "error: no files to verify from stdin\n";
+ return true;
+ }
+ if (strs.size() % 2 != 0) {
+ errs() << "error: files to verify are not original/result pairs\n";
+ return true;
+ }
+
+ for (unsigned i = 0, e = strs.size(); i != e; i += 2) {
+ StringRef inputOrigFname = strs[i];
+ StringRef inputResultFname = strs[i+1];
+
+ std::map<StringRef, StringRef>::iterator It;
+ It = resultMap.find(sys::path::filename(inputOrigFname));
+ if (It == resultMap.end()) {
+ errs() << "error: '" << inputOrigFname << "' is not in the list of "
+ << "transformed files to verify\n";
+ return true;
+ }
+
+ bool exists = false;
+ sys::fs::exists(It->second, exists);
+ if (!exists) {
+ errs() << "error: '" << It->second << "' does not exist\n";
+ return true;
+ }
+ sys::fs::exists(inputResultFname, exists);
+ if (!exists) {
+ errs() << "error: '" << inputResultFname << "' does not exist\n";
+ return true;
+ }
+
+ if (!filesCompareEqual(It->second, inputResultFname)) {
+ errs() << "error: '" << It->second << "' is different than "
+ << "'" << inputResultFname << "'\n";
+ return true;
+ }
+
+ resultMap.erase(It);
+ }
+
+ if (!resultMap.empty()) {
+ for (std::map<StringRef, StringRef>::iterator
+ I = resultMap.begin(), E = resultMap.end(); I != E; ++I)
+ errs() << "error: '" << I->second << "' was not verified!\n";
+ return true;
+ }
+
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Misc. functions.
//===----------------------------------------------------------------------===//
@@ -236,7 +351,15 @@ int main(int argc, const char **argv) {
break;
}
llvm::cl::ParseCommandLineOptions(optargc, const_cast<char **>(argv), "arcmt-test");
-
+
+ if (VerifyTransformedFiles) {
+ if (ResultFiles.empty()) {
+ llvm::cl::PrintHelpMessage();
+ return 1;
+ }
+ return verifyTransformedFiles(ResultFiles);
+ }
+
if (optargc == argc) {
llvm::cl::PrintHelpMessage();
return 1;