[Driver] Add unit tests for GnuLdDriver.

llvm-svn: 182980
This commit is contained in:
Rui Ueyama 2013-05-31 02:12:34 +00:00
parent fc3d80bda1
commit 7eb1d49a58
4 changed files with 144 additions and 65 deletions

View File

@ -1,5 +1,6 @@
add_lld_unittest(DriverTests
UniversalDriverTest.cpp
GnuLdDriverTest.cpp
WinLinkDriverTest.cpp
)

View File

@ -0,0 +1,59 @@
//===- lld/unittest/DriverTest.h ------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdarg.h>
#include "gtest/gtest.h"
#include "lld/Driver/Driver.h"
#include "lld/Driver/LinkerInput.h"
#include "llvm/Support/raw_ostream.h"
namespace {
using namespace llvm;
using namespace lld;
template<typename Driver, typename TargetInfo>
class ParserTest : public testing::Test {
protected:
void SetUp() {
os.reset(new raw_string_ostream(diags));
}
virtual TargetInfo *doParse(int argc, const char **argv,
raw_ostream &diag) = 0;
void parse(const char *args, ...) {
// Construct command line options from varargs.
std::vector<const char *> vec;
vec.push_back(args);
va_list ap;
va_start(ap, args);
while (const char *arg = va_arg(ap, const char *))
vec.push_back(arg);
va_end(ap);
// Call the parser.
info.reset(doParse(vec.size(), &vec[0], *os));
// Copy the output file name for the sake of convenience.
if (info)
for (const LinkerInput &input : info->inputFiles())
inputFiles.push_back(input.getPath().str());
}
std::unique_ptr<TargetInfo> info;
std::string diags;
std::unique_ptr<raw_string_ostream> os;
std::vector<std::string> inputFiles;
};
}

View File

@ -0,0 +1,51 @@
//===- lld/unittest/WinLinkDriverTest.cpp ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Windows link.exe driver tests.
///
//===----------------------------------------------------------------------===//
#include "DriverTest.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
using namespace llvm;
using namespace lld;
namespace {
class GnuLdParserTest : public ParserTest<GnuLdDriver, ELFTargetInfo> {
protected:
virtual ELFTargetInfo* doParse(int argc, const char **argv,
raw_ostream &diag) {
std::unique_ptr<ELFTargetInfo> info(GnuLdDriver::parse(argc, argv, diag));
return info.release();
}
};
TEST_F(GnuLdParserTest, Basic) {
parse("ld", "infile.o", nullptr);
ASSERT_TRUE(!!info);
EXPECT_EQ("a.out", info->outputPath());
EXPECT_EQ(1, (int)inputFiles.size());
EXPECT_EQ("infile.o", inputFiles[0]);
EXPECT_FALSE(info->outputYAML());
}
TEST_F(GnuLdParserTest, ManyOptions) {
parse("ld", "-entry", "_start", "-o", "outfile",
"-emit-yaml", "infile.o", nullptr);
ASSERT_TRUE(!!info);
EXPECT_EQ("outfile", info->outputPath());
EXPECT_EQ("_start", info->entrySymbolName());
EXPECT_TRUE(info->outputYAML());
}
} // end anonymous namespace

View File

@ -12,90 +12,58 @@
///
//===----------------------------------------------------------------------===//
#include <stdarg.h>
#include "DriverTest.h"
#include "gtest/gtest.h"
#include "lld/Driver/Driver.h"
#include "lld/Driver/LinkerInput.h"
#include "lld/ReaderWriter/PECOFFTargetInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace lld;
namespace {
class ParserTest : public testing::Test {
class WinLinkParserTest : public ParserTest<WinLinkDriver, PECOFFTargetInfo> {
protected:
void SetUp() {
os.reset(new raw_string_ostream(diags));
virtual PECOFFTargetInfo *doParse(int argc, const char **argv,
raw_ostream &diag) {
PECOFFTargetInfo *info = new PECOFFTargetInfo();
EXPECT_FALSE(WinLinkDriver::parse(argc, argv, *info, diag));
return info;
}
void parse(const char *args, ...) {
std::vector<const char *> vec;
vec.push_back("link.exe");
vec.push_back(args);
va_list ap;
va_start(ap, args);
while (const char *arg = va_arg(ap, const char *))
vec.push_back(arg);
va_end(ap);
EXPECT_FALSE(WinLinkDriver::parse(vec.size(), &vec[0], info, *os));
}
PECOFFTargetInfo info;
std::string diags;
std::unique_ptr<raw_string_ostream> os;
};
TEST_F(ParserTest, Basic) {
parse("-subsystem", "console", "-out", "a.exe", "a.obj", "b.obj", "c.obj",
nullptr);
EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, info.getSubsystem());
EXPECT_EQ("a.exe", info.outputPath());
const std::vector<LinkerInput> &inputFiles = info.inputFiles();
EXPECT_EQ((size_t)3, inputFiles.size());
EXPECT_EQ("a.obj", inputFiles[0].getPath());
EXPECT_EQ("b.obj", inputFiles[1].getPath());
EXPECT_EQ("c.obj", inputFiles[2].getPath());
TEST_F(WinLinkParserTest, Basic) {
parse("link.exe", "-subsystem", "console", "-out", "a.exe",
"a.obj", "b.obj", "c.obj", nullptr);
EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, info->getSubsystem());
EXPECT_EQ("a.exe", info->outputPath());
EXPECT_EQ(3, (int)inputFiles.size());
EXPECT_EQ("a.obj", inputFiles[0]);
EXPECT_EQ("b.obj", inputFiles[1]);
EXPECT_EQ("c.obj", inputFiles[2]);
}
TEST_F(ParserTest, WindowsStyleOption) {
parse("/subsystem:console", "/out:a.exe", "a.obj", nullptr);
EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, info.getSubsystem());
EXPECT_EQ("a.exe", info.outputPath());
const std::vector<LinkerInput> &inputFiles = info.inputFiles();
EXPECT_EQ((size_t)1, inputFiles.size());
EXPECT_EQ("a.obj", inputFiles[0].getPath());
TEST_F(WinLinkParserTest, WindowsStyleOption) {
parse("link.exe", "/subsystem:console", "/out:a.exe", "a.obj", nullptr);
EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, info->getSubsystem());
EXPECT_EQ("a.exe", info->outputPath());
EXPECT_EQ(1, (int)inputFiles.size());
EXPECT_EQ("a.obj", inputFiles[0]);
}
TEST_F(ParserTest, NoFileExtension) {
parse("foo", "bar", nullptr);
EXPECT_EQ("foo.exe", info.outputPath());
const std::vector<LinkerInput> &inputFiles = info.inputFiles();
EXPECT_EQ((size_t)2, inputFiles.size());
EXPECT_EQ("foo.obj", inputFiles[0].getPath());
EXPECT_EQ("bar.obj", inputFiles[1].getPath());
TEST_F(WinLinkParserTest, NoFileExtension) {
parse("link.exe", "foo", "bar", nullptr);
EXPECT_EQ("foo.exe", info->outputPath());
EXPECT_EQ(2, (int)inputFiles.size());
EXPECT_EQ("foo.obj", inputFiles[0]);
EXPECT_EQ("bar.obj", inputFiles[1]);
}
TEST_F(ParserTest, NonStandardFileExtension) {
parse("foo.o", nullptr);
EXPECT_EQ("foo.exe", info.outputPath());
const std::vector<LinkerInput> &inputFiles = info.inputFiles();
EXPECT_EQ((size_t)1, inputFiles.size());
EXPECT_EQ("foo.o", inputFiles[0].getPath());
TEST_F(WinLinkParserTest, NonStandardFileExtension) {
parse("link.exe", "foo.o", nullptr);
EXPECT_EQ("foo.exe", info->outputPath());
EXPECT_EQ(1, (int)inputFiles.size());
EXPECT_EQ("foo.o", inputFiles[0]);
}
} // end anonymous namespace