18f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===-- arcmt-test.cpp - ARC Migration Tool testbed -----------------------===// 28f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// 38f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// The LLVM Compiler Infrastructure 48f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// 58f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// This file is distributed under the University of Illinois Open Source 68f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// License. See LICENSE.TXT for details. 78f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// 88f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 98f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 108f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/ARCMigrate/ARCMT.h" 118f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Frontend/ASTUnit.h" 128f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Frontend/TextDiagnosticPrinter.h" 138f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Frontend/Utils.h" 14f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "clang/Frontend/VerifyDiagnosticConsumer.h" 158f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "clang/Lex/Preprocessor.h" 1669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis#include "llvm/Support/FileSystem.h" 17f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "llvm/Support/MemoryBuffer.h" 188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall#include "llvm/Support/Signals.h" 1969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis#include "llvm/Support/system_error.h" 208f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 218f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallusing namespace clang; 228f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallusing namespace arcmt; 238f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 248f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic llvm::cl::opt<bool> 258f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallCheckOnly("check-only", 268f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall llvm::cl::desc("Just check for issues that need to be handled manually")); 278f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 288f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//static llvm::cl::opt<bool> 298f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//TestResultForARC("test-result", 308f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//llvm::cl::desc("Test the result of transformations by parsing it in ARC mode")); 318f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 328f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic llvm::cl::opt<bool> 338f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallOutputTransformations("output-transformations", 348f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall llvm::cl::desc("Print the source transformations")); 358f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 368f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic llvm::cl::opt<bool> 378f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallVerifyDiags("verify",llvm::cl::desc("Verify emitted diagnostics and warnings")); 388f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 398f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic llvm::cl::opt<bool> 408f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallVerboseOpt("v", llvm::cl::desc("Enable verbose output")); 418f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 4269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidisstatic llvm::cl::opt<bool> 4369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios KyrtzidisVerifyTransformedFiles("verify-transformed-files", 4469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidisllvm::cl::desc("Read pairs of file mappings (typically the output of " 4569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis "c-arcmt-test) and compare their contents with the filenames " 4669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis "provided in command-line")); 4769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 4869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidisstatic llvm::cl::opt<std::string> 4969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios KyrtzidisRemappingsFile("remappings-file", 5069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis llvm::cl::desc("Pairs of file mappings (typically the output of " 5169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis "c-arcmt-test)")); 5269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 5369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidisstatic llvm::cl::list<std::string> 5469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios KyrtzidisResultFiles(llvm::cl::Positional, llvm::cl::desc("<filename>...")); 5569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 568f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic llvm::cl::extrahelp extraHelp( 578f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall "\nusage with compiler args: arcmt-test [options] --args [compiler flags]\n"); 588f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 598f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// This function isn't referenced outside its translation unit, but it 608f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// can't use the "static" keyword because its address is used for 618f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// GetMainExecutable (since some platforms don't support taking the 628f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// address of main, and some platforms can't implement GetMainExecutable 638f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// without being given the address of a function in the main executable). 64ac1db6b2bde50e9a0f3846243f654f6c13682725Rafael Espindolastd::string GetExecutablePath(const char *Argv0) { 658f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall // This just needs to be some symbol in the binary; C++ doesn't 668f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall // allow taking the address of ::main however. 678f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall void *MainAddr = (void*) (intptr_t) GetExecutablePath; 68ac1db6b2bde50e9a0f3846243f654f6c13682725Rafael Espindola return llvm::sys::fs::getMainExecutable(Argv0, MainAddr); 698f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 708f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 718f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic void printSourceLocation(SourceLocation loc, ASTContext &Ctx, 725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &OS); 738f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic void printSourceRange(CharSourceRange range, ASTContext &Ctx, 745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &OS); 758f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 768f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallnamespace { 778f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 788f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallclass PrintTransforms : public MigrationProcess::RewriteListener { 798f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall ASTContext *Ctx; 805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &OS; 818f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 828f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallpublic: 835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner PrintTransforms(raw_ostream &OS) 848f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall : Ctx(0), OS(OS) { } 858f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 868f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall virtual void start(ASTContext &ctx) { Ctx = &ctx; } 878f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall virtual void finish() { Ctx = 0; } 888f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner virtual void insert(SourceLocation loc, StringRef text) { 908f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall assert(Ctx); 918f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << "Insert: "; 928f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall printSourceLocation(loc, *Ctx, OS); 938f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << " \"" << text << "\"\n"; 948f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 958f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 968f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall virtual void remove(CharSourceRange range) { 978f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall assert(Ctx); 988f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << "Remove: "; 998f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall printSourceRange(range, *Ctx, OS); 1008f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << '\n'; 1018f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1028f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall}; 1038f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1048f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} // anonymous namespace 1058f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic bool checkForMigration(StringRef resourcesPath, 1072d3ba4f5a923a90c3fc290ddfba5e36c2d0a9b46Chris Lattner ArrayRef<const char *> Args) { 10802c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 10978ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer *DiagClient = 11002c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); 111c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 112c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> Diags( 11302c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient)); 1148f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall // Chain in -verify checker, if requested. 115621bc69624599da62abd9bc9e5edd8a63ac99fe6David Blaikie VerifyDiagnosticConsumer *verifyDiag = 0; 1168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (VerifyDiags) { 117621bc69624599da62abd9bc9e5edd8a63ac99fe6David Blaikie verifyDiag = new VerifyDiagnosticConsumer(*Diags); 1188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall Diags->setClient(verifyDiag); 1198f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1208f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 121eaed19e241359fb37da0269a64311e57cd53b83cArgyrios Kyrtzidis CompilerInvocation CI; 1228fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith if (!CompilerInvocation::CreateFromArgs(CI, Args.begin(), Args.end(), *Diags)) 1238fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith return true; 1248f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 125eaed19e241359fb37da0269a64311e57cd53b83cArgyrios Kyrtzidis if (CI.getFrontendOpts().Inputs.empty()) { 1268f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall llvm::errs() << "error: no input files\n"; 1278f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 1288f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1298f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 130d3b74d9ca4f239a7a90ad193378c494306c57352Ted Kremenek if (!CI.getLangOpts()->ObjC1) 1318f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return false; 1328f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1331f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor arcmt::checkForManualIssues(CI, CI.getFrontendOpts().Inputs[0], 134e665d6929e11796620ff799bc0186ebd747bfc76Argyrios Kyrtzidis Diags->getClient()); 135e665d6929e11796620ff799bc0186ebd747bfc76Argyrios Kyrtzidis return Diags->getClient()->getNumErrors() > 0; 1368f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 1378f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1385f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void printResult(FileRemapper &remapper, raw_ostream &OS) { 13930660a898545416f0fea2d717f16f75640001e38Ted Kremenek PreprocessorOptions PPOpts; 14030660a898545416f0fea2d717f16f75640001e38Ted Kremenek remapper.applyMappings(PPOpts); 1418f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall // The changed files will be in memory buffers, print them. 1428f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall for (unsigned i = 0, e = PPOpts.RemappedFileBuffers.size(); i != e; ++i) { 1438f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall const llvm::MemoryBuffer *mem = PPOpts.RemappedFileBuffers[i].second; 1448f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << mem->getBuffer(); 1458f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1468f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 1478f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic bool performTransformations(StringRef resourcesPath, 1492d3ba4f5a923a90c3fc290ddfba5e36c2d0a9b46Chris Lattner ArrayRef<const char *> Args) { 1508f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall // Check first. 1518f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (checkForMigration(resourcesPath, Args)) 1528f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 1538f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 15402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 15578ad0b98848c17a0a11847fa1d456e2dfec8aa2fDavid Blaikie DiagnosticConsumer *DiagClient = 15602c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); 157c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 158c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> TopDiags( 15902c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor new DiagnosticsEngine(DiagID, &*DiagOpts, &*DiagClient)); 1608f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 161eaed19e241359fb37da0269a64311e57cd53b83cArgyrios Kyrtzidis CompilerInvocation origCI; 1628fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith if (!CompilerInvocation::CreateFromArgs(origCI, Args.begin(), Args.end(), 1638fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith *TopDiags)) 1648fdb6dee2da0dee97d64fe12eda46fb318414de9Dylan Noblesmith return true; 1658f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 166eaed19e241359fb37da0269a64311e57cd53b83cArgyrios Kyrtzidis if (origCI.getFrontendOpts().Inputs.empty()) { 1678f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall llvm::errs() << "error: no input files\n"; 1688f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return true; 1698f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1708f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 171d3b74d9ca4f239a7a90ad193378c494306c57352Ted Kremenek if (!origCI.getLangOpts()->ObjC1) 1728f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return false; 1738f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 174eaed19e241359fb37da0269a64311e57cd53b83cArgyrios Kyrtzidis MigrationProcess migration(origCI, DiagClient); 1758f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 176e0ac7454bae910ab3d67a92f6e2e5046d3bb8c1aArgyrios Kyrtzidis std::vector<TransformFn> 177bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian transforms = arcmt::getAllTransformations(origCI.getLangOpts()->getGC(), 178bbdfad581fa300fa0d162d968ec14de3c95fc760Fariborz Jahanian origCI.getMigratorOpts().NoFinalizeRemoval); 1798f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall assert(!transforms.empty()); 1808f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1811e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith OwningPtr<PrintTransforms> transformPrinter; 1828f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (OutputTransformations) 1838f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall transformPrinter.reset(new PrintTransforms(llvm::outs())); 1848f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1858f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall for (unsigned i=0, e = transforms.size(); i != e; ++i) { 1868f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall bool err = migration.applyTransform(transforms[i], transformPrinter.get()); 1878f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (err) return true; 1888f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1898f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (VerboseOpt) { 1908f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (i == e-1) 1918f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall llvm::errs() << "\n##### FINAL RESULT #####\n"; 1928f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall else 1938f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall llvm::errs() << "\n##### OUTPUT AFTER "<< i+1 <<". TRANSFORMATION #####\n"; 1948f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall printResult(migration.getRemapper(), llvm::errs()); 1958f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall llvm::errs() << "\n##########################\n\n"; 1968f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1978f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 1988f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 1998f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (!OutputTransformations) 2008f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall printResult(migration.getRemapper(), llvm::outs()); 2018f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2028f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall // FIXME: TestResultForARC 2038f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2048f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return false; 2058f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 2068f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 2075f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic bool filesCompareEqual(StringRef fname1, StringRef fname2) { 20869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis using namespace llvm; 20969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 21069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis OwningPtr<MemoryBuffer> file1; 21169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis MemoryBuffer::getFile(fname1, file1); 21269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (!file1) 21369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return false; 21469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 21569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis OwningPtr<MemoryBuffer> file2; 21669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis MemoryBuffer::getFile(fname2, file2); 21769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (!file2) 21869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return false; 21969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 22069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return file1->getBuffer() == file2->getBuffer(); 22169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis} 22269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 2232d3ba4f5a923a90c3fc290ddfba5e36c2d0a9b46Chris Lattnerstatic bool verifyTransformedFiles(ArrayRef<std::string> resultFiles) { 22469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis using namespace llvm; 22569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 22669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis assert(!resultFiles.empty()); 22769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 22869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis std::map<StringRef, StringRef> resultMap; 22969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 23069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis for (ArrayRef<std::string>::iterator 23169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis I = resultFiles.begin(), E = resultFiles.end(); I != E; ++I) { 23269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis StringRef fname(*I); 23369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (!fname.endswith(".result")) { 23469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis errs() << "error: filename '" << fname 23569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis << "' does not have '.result' extension\n"; 23669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return true; 23769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 23869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis resultMap[sys::path::stem(fname)] = fname; 23969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 24069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 24169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis OwningPtr<MemoryBuffer> inputBuf; 24269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (RemappingsFile.empty()) 24369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis MemoryBuffer::getSTDIN(inputBuf); 24469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis else 24569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis MemoryBuffer::getFile(RemappingsFile, inputBuf); 24669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (!inputBuf) { 24769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis errs() << "error: could not read remappings input\n"; 24869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return true; 24969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 25069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 25169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis SmallVector<StringRef, 8> strs; 25269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis inputBuf->getBuffer().split(strs, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false); 25369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 25469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (strs.empty()) { 25569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis errs() << "error: no files to verify from stdin\n"; 25669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return true; 25769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 25869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (strs.size() % 2 != 0) { 25969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis errs() << "error: files to verify are not original/result pairs\n"; 26069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return true; 26169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 26269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 26369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis for (unsigned i = 0, e = strs.size(); i != e; i += 2) { 26469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis StringRef inputOrigFname = strs[i]; 26569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis StringRef inputResultFname = strs[i+1]; 26669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 26769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis std::map<StringRef, StringRef>::iterator It; 26869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis It = resultMap.find(sys::path::filename(inputOrigFname)); 26969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (It == resultMap.end()) { 27069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis errs() << "error: '" << inputOrigFname << "' is not in the list of " 27169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis << "transformed files to verify\n"; 27269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return true; 27369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 27469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 27569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis bool exists = false; 27669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis sys::fs::exists(It->second, exists); 27769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (!exists) { 27869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis errs() << "error: '" << It->second << "' does not exist\n"; 27969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return true; 28069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 28169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis sys::fs::exists(inputResultFname, exists); 28269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (!exists) { 28369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis errs() << "error: '" << inputResultFname << "' does not exist\n"; 28469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return true; 28569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 28669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 28769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (!filesCompareEqual(It->second, inputResultFname)) { 28869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis errs() << "error: '" << It->second << "' is different than " 28969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis << "'" << inputResultFname << "'\n"; 29069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return true; 29169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 29269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 29369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis resultMap.erase(It); 29469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 29569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 29669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (!resultMap.empty()) { 29769325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis for (std::map<StringRef, StringRef>::iterator 29869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis I = resultMap.begin(), E = resultMap.end(); I != E; ++I) 29969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis errs() << "error: '" << I->second << "' was not verified!\n"; 30069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return true; 30169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 30269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 30369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return false; 30469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis} 30569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 3068f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 3078f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// Misc. functions. 3088f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 3098f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3108f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic void printSourceLocation(SourceLocation loc, ASTContext &Ctx, 3115f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &OS) { 3128f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall SourceManager &SM = Ctx.getSourceManager(); 3138f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall PresumedLoc PL = SM.getPresumedLoc(loc); 3148f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3158f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << llvm::sys::path::filename(PL.getFilename()); 3168f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << ":" << PL.getLine() << ":" 3178f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall << PL.getColumn(); 3188f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 3198f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3208f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallstatic void printSourceRange(CharSourceRange range, ASTContext &Ctx, 3215f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner raw_ostream &OS) { 3228f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall SourceManager &SM = Ctx.getSourceManager(); 3234e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie const LangOptions &langOpts = Ctx.getLangOpts(); 3248f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3258f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall PresumedLoc PL = SM.getPresumedLoc(range.getBegin()); 3268f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3278f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << llvm::sys::path::filename(PL.getFilename()); 3288f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << " [" << PL.getLine() << ":" 3298f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall << PL.getColumn(); 3308f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << " - "; 3318f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3328f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall SourceLocation end = range.getEnd(); 3338f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall PL = SM.getPresumedLoc(end); 3348f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3358f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall unsigned endCol = PL.getColumn() - 1; 3368f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (!range.isTokenRange()) 3378f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall endCol += Lexer::MeasureTokenLength(end, SM, langOpts); 3388f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall OS << PL.getLine() << ":" << endCol << "]"; 3398f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 3408f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3418f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 3428f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall// Command line processing. 3438f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall//===----------------------------------------------------------------------===// 3448f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3458f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCallint main(int argc, const char **argv) { 3468f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall void *MainAddr = (void*) (intptr_t) GetExecutablePath; 3478f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall llvm::sys::PrintStackTraceOnErrorSignal(); 3488f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3498f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall std::string 3508f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall resourcesPath = CompilerInvocation::GetResourcesPath(argv[0], MainAddr); 3518f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3528f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall int optargc = 0; 3538f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall for (; optargc != argc; ++optargc) { 3548f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (StringRef(argv[optargc]) == "--args") 3558f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall break; 3568f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 3576bd17d2f2e6e498b0ff01e2e755f044de046d138David Blaikie llvm::cl::ParseCommandLineOptions(optargc, argv, "arcmt-test"); 35869325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 35969325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (VerifyTransformedFiles) { 36069325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis if (ResultFiles.empty()) { 36169325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis llvm::cl::PrintHelpMessage(); 36269325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return 1; 36369325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 36469325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis return verifyTransformedFiles(ResultFiles); 36569325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis } 36669325d5b7cfecf1b3128745efc33612aedf1b8b4Argyrios Kyrtzidis 3678f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (optargc == argc) { 3688f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall llvm::cl::PrintHelpMessage(); 3698f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return 1; 3708f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall } 3718f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3722d3ba4f5a923a90c3fc290ddfba5e36c2d0a9b46Chris Lattner ArrayRef<const char*> Args(argv+optargc+1, argc-optargc-1); 3738f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3748f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall if (CheckOnly) 3758f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return checkForMigration(resourcesPath, Args); 3768f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall 3778f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall return performTransformations(resourcesPath, Args); 3788f0e8d22960d56f8390f4971e2c0f2f0a0884602John McCall} 379