From b5500b9ca0102f1ccaf32f0e77e96d0739aded9b Mon Sep 17 00:00:00 2001 From: pascal Date: Sat, 3 Sep 2016 22:46:54 +0000 Subject: Use the space freed up by sparc and zaurus to import LLVM. ok hackroom@ --- gnu/llvm/unittests/Support/CommandLineTest.cpp | 268 +++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 gnu/llvm/unittests/Support/CommandLineTest.cpp (limited to 'gnu/llvm/unittests/Support/CommandLineTest.cpp') diff --git a/gnu/llvm/unittests/Support/CommandLineTest.cpp b/gnu/llvm/unittests/Support/CommandLineTest.cpp new file mode 100644 index 00000000000..eac669f467b --- /dev/null +++ b/gnu/llvm/unittests/Support/CommandLineTest.cpp @@ -0,0 +1,268 @@ +//===- llvm/unittest/Support/CommandLineTest.cpp - CommandLine tests ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/STLExtras.h" +#include "llvm/Config/config.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/StringSaver.h" +#include "gtest/gtest.h" +#include +#include + +using namespace llvm; + +namespace { + +class TempEnvVar { + public: + TempEnvVar(const char *name, const char *value) + : name(name) { + const char *old_value = getenv(name); + EXPECT_EQ(nullptr, old_value) << old_value; +#if HAVE_SETENV + setenv(name, value, true); +#else +# define SKIP_ENVIRONMENT_TESTS +#endif + } + + ~TempEnvVar() { +#if HAVE_SETENV + // Assume setenv and unsetenv come together. + unsetenv(name); +#else + (void)name; // Suppress -Wunused-private-field. +#endif + } + + private: + const char *const name; +}; + +template +class StackOption : public cl::opt { + typedef cl::opt Base; +public: + // One option... + template + explicit StackOption(const M0t &M0) : Base(M0) {} + + // Two options... + template + StackOption(const M0t &M0, const M1t &M1) : Base(M0, M1) {} + + // Three options... + template + StackOption(const M0t &M0, const M1t &M1, const M2t &M2) : Base(M0, M1, M2) {} + + // Four options... + template + StackOption(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) + : Base(M0, M1, M2, M3) {} + + ~StackOption() override { this->removeArgument(); } +}; + + +cl::OptionCategory TestCategory("Test Options", "Description"); +TEST(CommandLineTest, ModifyExisitingOption) { + StackOption TestOption("test-option", cl::desc("old description")); + + const char Description[] = "New description"; + const char ArgString[] = "new-test-option"; + const char ValueString[] = "Integer"; + + StringMap &Map = cl::getRegisteredOptions(); + + ASSERT_TRUE(Map.count("test-option") == 1) << + "Could not find option in map."; + + cl::Option *Retrieved = Map["test-option"]; + ASSERT_EQ(&TestOption, Retrieved) << "Retrieved wrong option."; + + ASSERT_EQ(&cl::GeneralCategory,Retrieved->Category) << + "Incorrect default option category."; + + Retrieved->setCategory(TestCategory); + ASSERT_EQ(&TestCategory,Retrieved->Category) << + "Failed to modify option's option category."; + + Retrieved->setDescription(Description); + ASSERT_STREQ(Retrieved->HelpStr.data(), Description) + << "Changing option description failed."; + + Retrieved->setArgStr(ArgString); + ASSERT_STREQ(ArgString, Retrieved->ArgStr.data()) + << "Failed to modify option's Argument string."; + + Retrieved->setValueStr(ValueString); + ASSERT_STREQ(Retrieved->ValueStr.data(), ValueString) + << "Failed to modify option's Value string."; + + Retrieved->setHiddenFlag(cl::Hidden); + ASSERT_EQ(cl::Hidden, TestOption.getOptionHiddenFlag()) << + "Failed to modify option's hidden flag."; +} +#ifndef SKIP_ENVIRONMENT_TESTS + +const char test_env_var[] = "LLVM_TEST_COMMAND_LINE_FLAGS"; + +cl::opt EnvironmentTestOption("env-test-opt"); +TEST(CommandLineTest, ParseEnvironment) { + TempEnvVar TEV(test_env_var, "-env-test-opt=hello"); + EXPECT_EQ("", EnvironmentTestOption); + cl::ParseEnvironmentOptions("CommandLineTest", test_env_var); + EXPECT_EQ("hello", EnvironmentTestOption); +} + +// This test used to make valgrind complain +// ("Conditional jump or move depends on uninitialised value(s)") +// +// Warning: Do not run any tests after this one that try to gain access to +// registered command line options because this will likely result in a +// SEGFAULT. This can occur because the cl::opt in the test below is declared +// on the stack which will be destroyed after the test completes but the +// command line system will still hold a pointer to a deallocated cl::Option. +TEST(CommandLineTest, ParseEnvironmentToLocalVar) { + // Put cl::opt on stack to check for proper initialization of fields. + StackOption EnvironmentTestOptionLocal("env-test-opt-local"); + TempEnvVar TEV(test_env_var, "-env-test-opt-local=hello-local"); + EXPECT_EQ("", EnvironmentTestOptionLocal); + cl::ParseEnvironmentOptions("CommandLineTest", test_env_var); + EXPECT_EQ("hello-local", EnvironmentTestOptionLocal); +} + +#endif // SKIP_ENVIRONMENT_TESTS + +TEST(CommandLineTest, UseOptionCategory) { + StackOption TestOption2("test-option", cl::cat(TestCategory)); + + ASSERT_EQ(&TestCategory,TestOption2.Category) << "Failed to assign Option " + "Category."; +} + +typedef void ParserFunction(StringRef Source, StringSaver &Saver, + SmallVectorImpl &NewArgv, + bool MarkEOLs); + +void testCommandLineTokenizer(ParserFunction *parse, const char *Input, + const char *const Output[], size_t OutputSize) { + SmallVector Actual; + BumpPtrAllocator A; + StringSaver Saver(A); + parse(Input, Saver, Actual, /*MarkEOLs=*/false); + EXPECT_EQ(OutputSize, Actual.size()); + for (unsigned I = 0, E = Actual.size(); I != E; ++I) { + if (I < OutputSize) + EXPECT_STREQ(Output[I], Actual[I]); + } +} + +TEST(CommandLineTest, TokenizeGNUCommandLine) { + const char *Input = "foo\\ bar \"foo bar\" \'foo bar\' 'foo\\\\bar' " + "foo\"bar\"baz C:\\src\\foo.cpp \"C:\\src\\foo.cpp\""; + const char *const Output[] = { "foo bar", "foo bar", "foo bar", "foo\\bar", + "foobarbaz", "C:\\src\\foo.cpp", + "C:\\src\\foo.cpp" }; + testCommandLineTokenizer(cl::TokenizeGNUCommandLine, Input, Output, + array_lengthof(Output)); +} + +TEST(CommandLineTest, TokenizeWindowsCommandLine) { + const char *Input = "a\\b c\\\\d e\\\\\"f g\" h\\\"i j\\\\\\\"k \"lmn\" o pqr " + "\"st \\\"u\" \\v"; + const char *const Output[] = { "a\\b", "c\\\\d", "e\\f g", "h\"i", "j\\\"k", + "lmn", "o", "pqr", "st \"u", "\\v" }; + testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input, Output, + array_lengthof(Output)); +} + +TEST(CommandLineTest, AliasesWithArguments) { + static const size_t ARGC = 3; + const char *const Inputs[][ARGC] = { + { "-tool", "-actual=x", "-extra" }, + { "-tool", "-actual", "x" }, + { "-tool", "-alias=x", "-extra" }, + { "-tool", "-alias", "x" } + }; + + for (size_t i = 0, e = array_lengthof(Inputs); i < e; ++i) { + StackOption Actual("actual"); + StackOption Extra("extra"); + StackOption Input(cl::Positional); + + cl::alias Alias("alias", llvm::cl::aliasopt(Actual)); + + cl::ParseCommandLineOptions(ARGC, Inputs[i]); + EXPECT_EQ("x", Actual); + EXPECT_EQ(0, Input.getNumOccurrences()); + + Alias.removeArgument(); + } +} + +void testAliasRequired(int argc, const char *const *argv) { + StackOption Option("option", cl::Required); + cl::alias Alias("o", llvm::cl::aliasopt(Option)); + + cl::ParseCommandLineOptions(argc, argv); + EXPECT_EQ("x", Option); + EXPECT_EQ(1, Option.getNumOccurrences()); + + Alias.removeArgument(); +} + +TEST(CommandLineTest, AliasRequired) { + const char *opts1[] = { "-tool", "-option=x" }; + const char *opts2[] = { "-tool", "-o", "x" }; + testAliasRequired(array_lengthof(opts1), opts1); + testAliasRequired(array_lengthof(opts2), opts2); +} + +TEST(CommandLineTest, HideUnrelatedOptions) { + StackOption TestOption1("hide-option-1"); + StackOption TestOption2("hide-option-2", cl::cat(TestCategory)); + + cl::HideUnrelatedOptions(TestCategory); + + ASSERT_EQ(cl::ReallyHidden, TestOption1.getOptionHiddenFlag()) + << "Failed to hide extra option."; + ASSERT_EQ(cl::NotHidden, TestOption2.getOptionHiddenFlag()) + << "Hid extra option that should be visable."; + + StringMap &Map = cl::getRegisteredOptions(); + ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag()) + << "Hid default option that should be visable."; +} + +cl::OptionCategory TestCategory2("Test Options set 2", "Description"); + +TEST(CommandLineTest, HideUnrelatedOptionsMulti) { + StackOption TestOption1("multi-hide-option-1"); + StackOption TestOption2("multi-hide-option-2", cl::cat(TestCategory)); + StackOption TestOption3("multi-hide-option-3", cl::cat(TestCategory2)); + + const cl::OptionCategory *VisibleCategories[] = {&TestCategory, + &TestCategory2}; + + cl::HideUnrelatedOptions(makeArrayRef(VisibleCategories)); + + ASSERT_EQ(cl::ReallyHidden, TestOption1.getOptionHiddenFlag()) + << "Failed to hide extra option."; + ASSERT_EQ(cl::NotHidden, TestOption2.getOptionHiddenFlag()) + << "Hid extra option that should be visable."; + ASSERT_EQ(cl::NotHidden, TestOption3.getOptionHiddenFlag()) + << "Hid extra option that should be visable."; + + StringMap &Map = cl::getRegisteredOptions(); + ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag()) + << "Hid default option that should be visable."; +} + +} // anonymous namespace -- cgit v1.2.3-59-g8ed1b