From a43ff964c4520f4515d7c04ae99bf51b7ae4ee09 Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Sat, 5 Mar 2022 13:31:36 +0300 Subject: [PATCH 01/24] [utils][cl] Use reference_wrapper in Options registration It allows to set Category directly without the pointer to the Category. Like this: cl::Option cat1Opt1({"--c1opt1"}, "", {testCategory1}); Instead of: cl::Option cat1Opt1({"--c1opt1"}, "", {&testCategory1}); To implement this, reference_wrapper is used. --- src/mapleall/maple_util/include/cl_option.h | 5 +++-- src/mapleall/maple_util/src/cl_option.cpp | 4 ++-- src/mapleall/test/cl_ut_test.cpp | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/mapleall/maple_util/include/cl_option.h b/src/mapleall/maple_util/include/cl_option.h index ba7365b8d6..4de5824140 100644 --- a/src/mapleall/maple_util/include/cl_option.h +++ b/src/mapleall/maple_util/include/cl_option.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -76,7 +77,7 @@ class OptionInterface { void FinalizeInitialization(const std::vector &optnames, const std::string &descr, - const std::vector &optionCategories); + const std::vector> &optionCategories); bool IsEnabledByUser() const { return isEnabledByUser; @@ -131,7 +132,7 @@ class Option : public OptionInterface { template explicit Option(const std::vector &optnames, const std::string &descr, - const std::vector &optionCategories, + const std::vector> &optionCategories, const ArgsT &... args) { /* It's needed to avoid empty Apply() */ if constexpr (sizeof...(ArgsT) > 0) { diff --git a/src/mapleall/maple_util/src/cl_option.cpp b/src/mapleall/maple_util/src/cl_option.cpp index 477891bc28..fa9510aedb 100644 --- a/src/mapleall/maple_util/src/cl_option.cpp +++ b/src/mapleall/maple_util/src/cl_option.cpp @@ -21,7 +21,7 @@ using namespace cl; void OptionInterface::FinalizeInitialization(const std::vector &optnames, const std::string &descr, - const std::vector &optionCategories) { + const std::vector> &optionCategories) { optDescription = descr; auto &cl = CommandLine::GetCommandLine(); @@ -31,7 +31,7 @@ void OptionInterface::FinalizeInitialization(const std::vector &opt cl.Register(optnames, *this, cl.defaultCategory); } else { for (auto &cat : optionCategories) { - cl.Register(optnames, *this, *cat); + cl.Register(optnames, *this, cat.get()); } } } diff --git a/src/mapleall/test/cl_ut_test.cpp b/src/mapleall/test/cl_ut_test.cpp index 7505200ee5..ade9738702 100644 --- a/src/mapleall/test/cl_ut_test.cpp +++ b/src/mapleall/test/cl_ut_test.cpp @@ -111,8 +111,8 @@ namespace testopts { cl::Option optVal({"--optval"}, "", cl::optionalValue, cl::Init(-42)); cl::Option woVal({"--woval"}, "", cl::disallowedValue, cl::Init(-42)); - cl::Option cat1Opt1({"--c1opt1"}, "", {&testCategory1}); - cl::Option cat12Opt({"--c12opt"}, "", {&testCategory1, &testCategory2}); + cl::Option cat1Opt1({"--c1opt1"}, "", {testCategory1}); + cl::Option cat12Opt({"--c12opt"}, "", {testCategory1, testCategory2}); cl::Option uttype({"--uttype"}, ""); -- Gitee From 3ecae8ada831b6eddc95edf54ebadc778e60d779 Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Wed, 9 Mar 2022 15:32:41 +0300 Subject: [PATCH 02/24] [utils][cl] Set Option in all categories where the option is registered If the option is detected, it must be added to all categories where the option is registered. Then these categories are used to check whether the option was set in command line. --- src/mapleall/maple_util/include/cl_option.h | 1 + src/mapleall/maple_util/src/cl_parser.cpp | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_util/include/cl_option.h b/src/mapleall/maple_util/include/cl_option.h index 4de5824140..767d4f54eb 100644 --- a/src/mapleall/maple_util/include/cl_option.h +++ b/src/mapleall/maple_util/include/cl_option.h @@ -100,6 +100,7 @@ class OptionInterface { } std::vector rawValues; // Value not converted to template T type + std::vector optCategories; // The option is registred in these categories protected: std::vector names; // names of the option diff --git a/src/mapleall/maple_util/src/cl_parser.cpp b/src/mapleall/maple_util/src/cl_parser.cpp index 4631bdd51f..c4e0080770 100644 --- a/src/mapleall/maple_util/src/cl_parser.cpp +++ b/src/mapleall/maple_util/src/cl_parser.cpp @@ -56,7 +56,11 @@ RetCode CommandLine::ParseJoinedOption(ssize_t &argsIndex, if (err != RetCode::noError) { return err; } - optCategory.enabledOptions.push_back(option); + + /* Set Option in all categories registering for this option */ + for (auto &category : option->optCategories) { + category->enabledOptions.push_back(option); + } } else { return RetCode::notRegistered; } @@ -72,7 +76,11 @@ RetCode CommandLine::ParseOption(ssize_t &argsIndex, if (err != RetCode::noError) { return err; } - optCategory.enabledOptions.push_back(opt); + + /* Set Option in all categories registering for this option */ + for (auto &category : opt->optCategories) { + category->enabledOptions.push_back(opt); + } return RetCode::noError; } @@ -211,4 +219,6 @@ void CommandLine::Register(const std::vector &optNames, ASSERT(optCategory.options.count(disabledWith) == 0, "Duplicated options name"); optCategory.options.emplace(disabledWith, &opt); } + + opt.optCategories.push_back(&optCategory); } -- Gitee From de1ec1e60005b036ae5122f419269669c65305b7 Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Sat, 5 Mar 2022 15:32:43 +0300 Subject: [PATCH 03/24] [utils][cl] Add HelpPrinter in CL BashCompletionPrinter and HelpPrinter are used to print the options for the help and bash completion. --- src/mapleall/maple_util/include/cl_option.h | 19 +++++++++++++++++++ src/mapleall/maple_util/include/cl_parser.h | 11 +++++++++++ src/mapleall/maple_util/src/cl_parser.cpp | 15 +++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/src/mapleall/maple_util/include/cl_option.h b/src/mapleall/maple_util/include/cl_option.h index 767d4f54eb..a1ff48b4e2 100644 --- a/src/mapleall/maple_util/include/cl_option.h +++ b/src/mapleall/maple_util/include/cl_option.h @@ -41,6 +41,12 @@ enum class ValueJoinedType { kValueJoined, /* joined option (like -DMACRO) is allowed */ }; +/* is option visible from Help ? */ +enum class OptionVisibilityType { + kVisibleOption, /* an Option will be visible in Help */ + kHidedOption /* an Option will be NOT visible in Help */ +}; + /* These constexpr are needed to use short name in option description, like this: * cl::Option option({"--option"}, "Description", optionalValue); * instead of: @@ -51,6 +57,8 @@ constexpr ValueExpectedType requiredValue = ValueExpectedType::kValueRequired; constexpr ValueExpectedType disallowedValue = ValueExpectedType::kValueDisallowed; constexpr ValueJoinedType joinedValue = ValueJoinedType::kValueJoined; constexpr ValueJoinedType separatedValue = ValueJoinedType::kValueSeparated; +constexpr OptionVisibilityType visible = OptionVisibilityType::kVisibleOption; +constexpr OptionVisibilityType hide = OptionVisibilityType::kHidedOption; /* Initializer is used to set default value for an option */ template struct Init { @@ -91,6 +99,10 @@ class OptionInterface { return (valueJoined == ValueJoinedType::kValueJoined); } + bool IsVisibleOption() const { + return (visibleOption == OptionVisibilityType::kVisibleOption); + } + const std::string &GetDisabledName() const { return disableWith; } @@ -111,6 +123,7 @@ class OptionInterface { ValueExpectedType valueExpected = ValueExpectedType::kValueRequired; // whether the value is expected ValueJoinedType valueJoined = ValueJoinedType::kValueSeparated; // Joined option like -DMACRO + OptionVisibilityType visibleOption = OptionVisibilityType::kVisibleOption; // Visible in Help }; /* Option class describes command line option */ @@ -193,6 +206,8 @@ class Option : public OptionInterface { SetExpectingAttribute(arg); } else if constexpr (std::is_same_v) { SetJoinAttribute(arg); + } else if constexpr (std::is_same_v) { + SetVisibilityAttribute(arg); } else if constexpr (std::is_same_v) { SetDisablingAttribute(arg); } else { @@ -222,6 +237,10 @@ class Option : public OptionInterface { valueJoined = value; } + void SetVisibilityAttribute(OptionVisibilityType value) { + visibleOption = value; + } + void SetDisablingAttribute(const DisableWith &value) { disableWith = value.disableWith; } diff --git a/src/mapleall/maple_util/include/cl_parser.h b/src/mapleall/maple_util/include/cl_parser.h index f0b41d733b..4f80dd0138 100644 --- a/src/mapleall/maple_util/include/cl_parser.h +++ b/src/mapleall/maple_util/include/cl_parser.h @@ -53,6 +53,7 @@ struct OptionCategory { OptionsMapType options; OptionsMapType joinedOptions; std::vector enabledOptions; + std::vector registredOptions; }; class CommandLine { @@ -74,6 +75,16 @@ class CommandLine { void Register(const std::vector &optNames, OptionInterface &opt, OptionCategory &optCategory); + void BashCompletionPrinter(const OptionCategory &optCategory) const; + void BashCompletionPrinter() const { + return BashCompletionPrinter(defaultCategory); + } + + void HelpPrinter(const OptionCategory &optCategory) const; + void HelpPrinter() const { + return HelpPrinter(defaultCategory); + } + std::vector> badCLArgs; OptionCategory defaultCategory; diff --git a/src/mapleall/maple_util/src/cl_parser.cpp b/src/mapleall/maple_util/src/cl_parser.cpp index c4e0080770..14a2926ee7 100644 --- a/src/mapleall/maple_util/src/cl_parser.cpp +++ b/src/mapleall/maple_util/src/cl_parser.cpp @@ -220,5 +220,20 @@ void CommandLine::Register(const std::vector &optNames, optCategory.options.emplace(disabledWith, &opt); } + optCategory.registredOptions.push_back(&opt); opt.optCategories.push_back(&optCategory); } + +void CommandLine::BashCompletionPrinter(const OptionCategory &optCategory) const { + for (auto &opt : optCategory.options) { + maple::LogInfo::MapleLogger() << opt.first << '\n'; + } +} + +void CommandLine::HelpPrinter(const OptionCategory &optCategory) const { + for (auto &opt : optCategory.registredOptions) { + if (opt->IsVisibleOption()) { + maple::LogInfo::MapleLogger() << opt->GetDescription() << '\n'; + } + } +} -- Gitee From ba4abbb01f3720ff149754a7a1fa2e3f0c81cda8 Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Mon, 7 Mar 2022 15:30:05 +0300 Subject: [PATCH 04/24] [utils][cl] Add option name in error message It's more clear, if it prints the name of duplicated option. --- src/mapleall/maple_util/src/cl_parser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_util/src/cl_parser.cpp b/src/mapleall/maple_util/src/cl_parser.cpp index 14a2926ee7..29e8caba5d 100644 --- a/src/mapleall/maple_util/src/cl_parser.cpp +++ b/src/mapleall/maple_util/src/cl_parser.cpp @@ -206,7 +206,7 @@ void CommandLine::Register(const std::vector &optNames, continue; } - ASSERT(optCategory.options.count(optName) == 0, "Duplicated options name"); + ASSERT(optCategory.options.count(optName) == 0, "Duplicated options name %s", optName.data()); optCategory.options.emplace(optName, &opt); if (opt.IsJoinedValPermitted()) { @@ -216,7 +216,7 @@ void CommandLine::Register(const std::vector &optNames, auto disabledWith = opt.GetDisabledName(); if (!disabledWith.empty()) { - ASSERT(optCategory.options.count(disabledWith) == 0, "Duplicated options name"); + ASSERT(optCategory.options.count(disabledWith) == 0, "Duplicated options name", disabledWith.data()); optCategory.options.emplace(disabledWith, &opt); } -- Gitee From 434b7acb1b58fe8dfc68cb71ba31747c1af6be6f Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Tue, 8 Mar 2022 12:39:49 +0300 Subject: [PATCH 05/24] [utils][cl] Add option clean to reset the option value This logic is needed for unit tests. It's used to clear the options between tests run. --- src/mapleall/maple_util/include/cl_option.h | 30 +++++++++++++++++++++ src/mapleall/maple_util/include/cl_parser.h | 5 ++++ src/mapleall/maple_util/src/cl_parser.cpp | 6 +++++ src/mapleall/test/cl_ut_test.cpp | 5 ++++ 4 files changed, 46 insertions(+) diff --git a/src/mapleall/maple_util/include/cl_option.h b/src/mapleall/maple_util/include/cl_option.h index a1ff48b4e2..a5556be441 100644 --- a/src/mapleall/maple_util/include/cl_option.h +++ b/src/mapleall/maple_util/include/cl_option.h @@ -82,6 +82,7 @@ class OptionInterface { virtual RetCode Parse(ssize_t &argsIndex, const std::vector &args, KeyArg &keyArg) = 0; + virtual void Clear() = 0; void FinalizeInitialization(const std::vector &optnames, const std::string &descr, @@ -190,6 +191,28 @@ class Option : public OptionInterface { return err; } + void Clear() override { + if (defaultValue.isSet) { + value = defaultValue.defaultValue; + } else { + if constexpr(std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v) { + value = 0; + } else if constexpr(std::is_same_v) { + value = ""; + } else if constexpr(std::is_same_v) { + value = false; + } else { + /* Type dependent static_assert. Simple static_assert(false") does not work */ + static_assert(false && sizeof(T), "T not supported"); + } + } + + isEnabledByUser = false; + } + const T &GetValue() const { return value; } @@ -227,6 +250,8 @@ class Option : public OptionInterface { template void SetDefaultAttribute(const Init &initializer) { value = initializer.defaultVal; + defaultValue.isSet = true; + defaultValue.defaultValue = value; } void SetExpectingAttribute(ValueExpectedType value) { @@ -245,6 +270,11 @@ class Option : public OptionInterface { disableWith = value.disableWith; } + struct DefaultValue { + T defaultValue; + bool isSet = false; + } defaultValue; + T value; }; diff --git a/src/mapleall/maple_util/include/cl_parser.h b/src/mapleall/maple_util/include/cl_parser.h index 4f80dd0138..4321fa7f76 100644 --- a/src/mapleall/maple_util/include/cl_parser.h +++ b/src/mapleall/maple_util/include/cl_parser.h @@ -75,6 +75,11 @@ class CommandLine { void Register(const std::vector &optNames, OptionInterface &opt, OptionCategory &optCategory); + void Clear(OptionCategory &optCategory); + void Clear() { + return Clear(defaultCategory); + } + void BashCompletionPrinter(const OptionCategory &optCategory) const; void BashCompletionPrinter() const { return BashCompletionPrinter(defaultCategory); diff --git a/src/mapleall/maple_util/src/cl_parser.cpp b/src/mapleall/maple_util/src/cl_parser.cpp index 29e8caba5d..c311e3cc9f 100644 --- a/src/mapleall/maple_util/src/cl_parser.cpp +++ b/src/mapleall/maple_util/src/cl_parser.cpp @@ -224,6 +224,12 @@ void CommandLine::Register(const std::vector &optNames, opt.optCategories.push_back(&optCategory); } +void CommandLine::Clear(OptionCategory &optCategory) { + for (auto &opt : optCategory.registredOptions) { + opt->Clear(); + } +} + void CommandLine::BashCompletionPrinter(const OptionCategory &optCategory) const { for (auto &opt : optCategory.options) { maple::LogInfo::MapleLogger() << opt.first << '\n'; diff --git a/src/mapleall/test/cl_ut_test.cpp b/src/mapleall/test/cl_ut_test.cpp index ade9738702..56f2add346 100644 --- a/src/mapleall/test/cl_ut_test.cpp +++ b/src/mapleall/test/cl_ut_test.cpp @@ -44,6 +44,11 @@ bool operator==(const std::string &str, const UTCLType &opt) { return ret; } +template <> +void cl::Option::Clear() { + value.data = ""; +} + template <> cl::RetCode cl::Option::Parse(ssize_t &argsIndex, const std::vector &args, -- Gitee From 5d7474e54f86d27c174c98d4b9c5b1e814eb1e5f Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Mon, 7 Mar 2022 23:08:51 +0300 Subject: [PATCH 06/24] [utils][cl] Fix "String options" parser If String option contains a value like: --opt="-opt1 -opt2 -opt3" it must correct parse it. --key --val must be parsed for kValueRequired. --- src/mapleall/maple_util/src/cl_option_parser.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_util/src/cl_option_parser.cpp b/src/mapleall/maple_util/src/cl_option_parser.cpp index adaecd48d8..302a75b198 100644 --- a/src/mapleall/maple_util/src/cl_option_parser.cpp +++ b/src/mapleall/maple_util/src/cl_option_parser.cpp @@ -121,10 +121,9 @@ template <> RetCode Option::ParseString(ssize_t &argsIndex, return RetCode::unnecessaryValue; } - if (IsPrefixDetected(keyArg.val)) { - if (ExpectedVal() == ValueExpectedType::kValueRequired) { - return RetCode::valueEmpty; - } + /* --key --value is allowed only for kValueRequired case */ + if (IsPrefixDetected(keyArg.val) && !keyArg.isEqualOpt && + ExpectedVal() == ValueExpectedType::kValueOptional) { ++argsIndex; return RetCode::noError; } -- Gitee From 146110021c628dd3f2305f29935ee57a257d1c3e Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Sat, 26 Mar 2022 18:00:18 +0300 Subject: [PATCH 07/24] [utils][cl] Add expanded options in CL Library CL Library must be able to handle the options with several values, like this: -LLib1 -LLib2 -LLib3. In this case we have the same option -L, but this option has several values: Lib1, Lib2 and Lib3. CL Library must accumulate (not overwrite) values for this option. To handle this, new cl::List class was implemented. So options must be described by cl::List class, like this: cl::List("-L", "Option Descriptor"); And then you can use GetValues interface to get access to all accumulated values of this option. NOTE: Also this commit: * add GetName interface to print the options in MplDriver. * replace RawValues with GetRawValues interface. * add UT for cl::List --- src/mapleall/maple_util/include/cl_option.h | 117 ++++++++++++++++-- src/mapleall/maple_util/include/cl_parser.h | 17 ++- .../maple_util/src/cl_option_parser.cpp | 2 - src/mapleall/maple_util/src/cl_parser.cpp | 6 +- src/mapleall/test/cl_ut_test.cpp | 97 ++++++++++++++- 5 files changed, 219 insertions(+), 20 deletions(-) diff --git a/src/mapleall/maple_util/include/cl_option.h b/src/mapleall/maple_util/include/cl_option.h index a5556be441..693080f4d9 100644 --- a/src/mapleall/maple_util/include/cl_option.h +++ b/src/mapleall/maple_util/include/cl_option.h @@ -83,6 +83,7 @@ class OptionInterface { virtual RetCode Parse(ssize_t &argsIndex, const std::vector &args, KeyArg &keyArg) = 0; virtual void Clear() = 0; + virtual std::vector GetRawValues() = 0; void FinalizeInitialization(const std::vector &optnames, const std::string &descr, @@ -108,11 +109,16 @@ class OptionInterface { return disableWith; } + virtual std::string GetName() const { + assert(names.size() > 0); + return names[0]; + } + const std::string &GetDescription() const { return optDescription; } - std::vector rawValues; // Value not converted to template T type + std::string rawKey; std::vector optCategories; // The option is registred in these categories protected: @@ -171,6 +177,7 @@ class Option : public OptionInterface { RetCode Parse(ssize_t &argsIndex, const std::vector &args, KeyArg &keyArg) override { RetCode err = RetCode::noError; + auto &key = args[argsIndex]; if constexpr(std::is_same_v || std::is_same_v || std::is_same_v || @@ -187,6 +194,7 @@ class Option : public OptionInterface { if (err == RetCode::noError) { isEnabledByUser = true; + rawKey = key; } return err; } @@ -213,14 +221,55 @@ class Option : public OptionInterface { isEnabledByUser = false; } + std::vector GetRawValues() override { + std::vector rawVals; + FillVal(value, rawVals); + return rawVals; + } + + std::string GetName() const override { + if constexpr (std::is_same_v) { + assert(names.size() > 0); + return ((value == true) ? names[0] : this->GetDisabledName()); + } else { + return OptionInterface::GetName(); + } + } + const T &GetValue() const { return value; } - void SetValue(const T &val) { + virtual void SetValue(const T &val) { value = val; } + protected: + RetCode ParseDigit(ssize_t &argsIndex, const std::vector &args, KeyArg &keyArg); + RetCode ParseString(ssize_t &argsIndex, const std::vector &args, KeyArg &keyArg); + RetCode ParseBool(ssize_t &argsIndex, const std::vector &args); + + void FillVal(const T &val, std::vector &vals) { + if constexpr(std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v) { + vals.emplace_back(std::to_string(val)); + } else if constexpr (std::is_same_v) { + vals.emplace_back(val); + } else if constexpr (std::is_same_v) { + vals.emplace_back(""); + } else { + /* Type dependent static_assert. Simple static_assert(false") does not work */ + static_assert(false && sizeof(T), "T not supported"); + } + } + + struct DefaultValue { + T defaultValue; + bool isSet = false; + } defaultValue; + private: /* To apply input arguments in any order */ template @@ -243,13 +292,9 @@ class Option : public OptionInterface { } } - RetCode ParseDigit(ssize_t &argsIndex, const std::vector &args, KeyArg &keyArg); - RetCode ParseString(ssize_t &argsIndex, const std::vector &args, KeyArg &keyArg); - RetCode ParseBool(ssize_t &argsIndex, const std::vector &args); - template void SetDefaultAttribute(const Init &initializer) { - value = initializer.defaultVal; + SetValue(initializer.defaultVal); defaultValue.isSet = true; defaultValue.defaultValue = value; } @@ -270,11 +315,6 @@ class Option : public OptionInterface { disableWith = value.disableWith; } - struct DefaultValue { - T defaultValue; - bool isSet = false; - } defaultValue; - T value; }; @@ -300,6 +340,59 @@ bool operator==(const char *arg, Option& opt) { return opt == arg; } +template +class List : public Option { +public: + // options must not be copyable and assignment + List(const List &) = delete; + List &operator=(const List &) = delete; + + /* variadic template is used to apply any number of options parameters in any order */ + template + explicit List(const std::vector &optnames, + const std::string &descr, + const ArgsT &... args) : Option(optnames, descr, args...) {}; + + template + explicit List(const std::vector &optnames, + const std::string &descr, + const std::vector> &optionCategories, + const ArgsT &... args) : Option(optnames, descr, optionCategories, args...) {}; + + void Clear() override { + values.clear(); + if (this->defaultValue.isSet) { + SetValue(this->defaultValue.defaultValue); + } + this->isEnabledByUser = false; + } + + void SetValue(const T &val) override { + values.push_back(val); + } + + const T &GetValue() const { + static_assert(false && sizeof(T), "GetValue must be not used for List"); + return T(); + } + + const std::vector &GetValues() const { + return values; + } + + std::vector GetRawValues() override { + std::vector rawVals; + for (const auto &val : values) { + this->FillVal(val, rawVals); + } + + return rawVals; + } + +private: + std::vector values; +}; + } #endif /* MAPLE_UTIL_INCLUDE_OPTION_H */ diff --git a/src/mapleall/maple_util/include/cl_parser.h b/src/mapleall/maple_util/include/cl_parser.h index 4321fa7f76..356dbdf7ae 100644 --- a/src/mapleall/maple_util/include/cl_parser.h +++ b/src/mapleall/maple_util/include/cl_parser.h @@ -19,6 +19,7 @@ #include #include #include +#include #include namespace cl { @@ -52,8 +53,22 @@ struct KeyArg { struct OptionCategory { OptionsMapType options; OptionsMapType joinedOptions; - std::vector enabledOptions; std::vector registredOptions; + + void AddEnabledOption(OptionInterface *opt) { + if (enabledOptionsSet.find(opt) == enabledOptionsSet.end()) { + enabledOptionsSet.insert(opt); + enabledOptions.push_back(opt); + } + } + + const std::vector &GetEnabledOptions() { + return enabledOptions; + } + + private: + std::unordered_set enabledOptionsSet; + std::vector enabledOptions; }; class CommandLine { diff --git a/src/mapleall/maple_util/src/cl_option_parser.cpp b/src/mapleall/maple_util/src/cl_option_parser.cpp index 302a75b198..3b2b0104d8 100644 --- a/src/mapleall/maple_util/src/cl_option_parser.cpp +++ b/src/mapleall/maple_util/src/cl_option_parser.cpp @@ -128,7 +128,6 @@ template <> RetCode Option::ParseString(ssize_t &argsIndex, return RetCode::noError; } - rawValues.emplace_back(keyArg.val); SetValue(std::string(keyArg.val)); argsIndex += 1 + indexIncCnt; // 1 for key, indexIncCnt for Key Value from ExtractValue @@ -176,7 +175,6 @@ RetCode Option::ParseDigit(ssize_t &argsIndex, return RetCode::incorrectValue; } - rawValues.emplace_back(keyArg.val); SetValue(dig); argsIndex += 1 + indexIncCnt; // 1 for key, indexIncCnt for Key Value from ExtractValue diff --git a/src/mapleall/maple_util/src/cl_parser.cpp b/src/mapleall/maple_util/src/cl_parser.cpp index c311e3cc9f..efebb0835f 100644 --- a/src/mapleall/maple_util/src/cl_parser.cpp +++ b/src/mapleall/maple_util/src/cl_parser.cpp @@ -59,7 +59,7 @@ RetCode CommandLine::ParseJoinedOption(ssize_t &argsIndex, /* Set Option in all categories registering for this option */ for (auto &category : option->optCategories) { - category->enabledOptions.push_back(option); + category->AddEnabledOption(option); } } else { return RetCode::notRegistered; @@ -79,7 +79,7 @@ RetCode CommandLine::ParseOption(ssize_t &argsIndex, /* Set Option in all categories registering for this option */ for (auto &category : opt->optCategories) { - category->enabledOptions.push_back(opt); + category->AddEnabledOption(opt); } return RetCode::noError; @@ -216,7 +216,7 @@ void CommandLine::Register(const std::vector &optNames, auto disabledWith = opt.GetDisabledName(); if (!disabledWith.empty()) { - ASSERT(optCategory.options.count(disabledWith) == 0, "Duplicated options name", disabledWith.data()); + ASSERT(optCategory.options.count(disabledWith) == 0, "Duplicated options name %s", disabledWith.data()); optCategory.options.emplace(disabledWith, &opt); } diff --git a/src/mapleall/test/cl_ut_test.cpp b/src/mapleall/test/cl_ut_test.cpp index 56f2add346..5dd898f1b1 100644 --- a/src/mapleall/test/cl_ut_test.cpp +++ b/src/mapleall/test/cl_ut_test.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "cl_option.h" #include "cl_parser.h" @@ -49,6 +50,11 @@ void cl::Option::Clear() { value.data = ""; } +template <> +std::vector cl::Option::GetRawValues() { + return std::vector(); +} + template <> cl::RetCode cl::Option::Parse(ssize_t &argsIndex, const std::vector &args, @@ -122,6 +128,16 @@ namespace testopts { cl::Option uttype({"--uttype"}, ""); cl::Option desc({"--desc"}, "It's test description"); + + cl::Option dup({"--dup"}, ""); + + cl::List vecString({"--vecstr"}, ""); + cl::List vecDig({"--vecdig"}, ""); + cl::List vecBool({"--vecbool"}, "", cl::DisableWith("--no-vecbool")); + + cl::List vecStringDef({"--vecstrdef"}, "", cl::Init("Default")); + cl::List vecDigDef({"--vecdigdef"}, "", cl::Init(100)); + cl::List vecBoolDef({"--vecbooldef"}, "", cl::DisableWith("--no-vecbooldef"), cl::Init(true)); } // namespace testopts /* ################# "Enable/Disable Boolean Options" Test ############### @@ -859,8 +875,6 @@ TEST(clOptions, ownOptionType3) { * ####################################################################### */ TEST(clOptions, duplicatedOptions) { - - cl::Option dup({"--dup"}, ""); EXPECT_DEATH(cl::Option dup2({"--dup"}, ""), ""); } @@ -870,3 +884,82 @@ TEST(clOptions, duplicatedOptions) { TEST(clOptions, description) { ASSERT_EQ(testopts::desc.GetDescription(), "It's test description"); } + +/* ##################### Check cl::list ################################## + * ####################################################################### */ + +TEST(clOptions, optList1) { + // create command line + const char *argv[] = { + "CLTest", // program name + "--vecstr", "data1", + "--vecstr", "data2", + "--vecstr", "data3", + "--vecdig", "10", + "--vecdig", "20", + "--vecbool", "--no-vecbool", "--vecbool", + nullptr}; + int argc = (sizeof(argv) / sizeof(argv[0])) - 1; + + auto err = cl::CommandLine::GetCommandLine().Parse(argc, (char **)argv); + ASSERT_EQ(err, cl::RetCode::noError); + + auto strVals = testopts::vecString.GetValues(); + ASSERT_EQ(strVals.size(), 3); + ASSERT_EQ(strVals[0], "data1"); + ASSERT_EQ(strVals[1], "data2"); + ASSERT_EQ(strVals[2], "data3"); + + auto digVals = testopts::vecDig.GetValues(); + ASSERT_EQ(digVals.size(), 2); + ASSERT_EQ(digVals[0], 10); + ASSERT_EQ(digVals[1], 20); + + auto boolVals = testopts::vecBool.GetValues(); + ASSERT_EQ(boolVals.size(), 3); + ASSERT_EQ(boolVals[0], true); + ASSERT_EQ(boolVals[1], false); + ASSERT_EQ(boolVals[2], true); + + cl::CommandLine::GetCommandLine().Clear(); // to clear previous test data + + ASSERT_EQ(testopts::vecBool.GetValues().size(), 0); + ASSERT_EQ(testopts::vecDig.GetValues().size(), 0); + ASSERT_EQ(testopts::vecString.GetValues().size(), 0); +} + +TEST(clOptions, optList2) { + // create command line + const char *argv[] = { + "CLTest", // program name + "--vecstrdef", "data1", + "--vecdigdef", "10", + "--vecbooldef", "--no-vecbooldef", + nullptr }; + int argc = (sizeof(argv) / sizeof(argv[0])) - 1; + + ASSERT_EQ(testopts::vecBoolDef.GetValues().size(), 1); + ASSERT_EQ(testopts::vecDigDef.GetValues().size(), 1); + ASSERT_EQ(testopts::vecStringDef.GetValues().size(), 1); + + ASSERT_EQ(testopts::vecDigDef.GetValues()[0], 100); + ASSERT_EQ(testopts::vecBoolDef.GetValues()[0], true); + ASSERT_EQ(testopts::vecStringDef.GetValues()[0], "Default"); + + auto err = cl::CommandLine::GetCommandLine().Parse(argc, (char **)argv); + ASSERT_EQ(err, cl::RetCode::noError); + + ASSERT_EQ(testopts::vecStringDef.GetValues().size(), 2); + ASSERT_EQ(testopts::vecDigDef.GetValues().size(), 2); + ASSERT_EQ(testopts::vecBoolDef.GetValues().size(), 3); + + ASSERT_EQ(testopts::vecStringDef.GetValues()[1], "data1"); + ASSERT_EQ(testopts::vecDigDef.GetValues()[1], 10); + ASSERT_EQ(testopts::vecBoolDef.GetValues()[1], true); + ASSERT_EQ(testopts::vecBoolDef.GetValues()[2], false); + + cl::CommandLine::GetCommandLine().Clear(); // to clear previous test data + ASSERT_EQ(testopts::vecStringDef.GetValues().size(), 1); + ASSERT_EQ(testopts::vecDigDef.GetValues().size(), 1); + ASSERT_EQ(testopts::vecBoolDef.GetValues().size(), 1); +} -- Gitee From 31db50aab7f8ceda7115e9047214940fbd05933a Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Sun, 27 Mar 2022 11:31:09 +0300 Subject: [PATCH 08/24] [utils][cl] Add helper functions to copy enabled options --- src/mapleall/maple_util/include/cl_option.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mapleall/maple_util/include/cl_option.h b/src/mapleall/maple_util/include/cl_option.h index 693080f4d9..659b42ef58 100644 --- a/src/mapleall/maple_util/include/cl_option.h +++ b/src/mapleall/maple_util/include/cl_option.h @@ -340,6 +340,20 @@ bool operator==(const char *arg, Option& opt) { return opt == arg; } +template +void CopyIfEnabled(T &dst, cl::Option &src) { + if (src.IsEnabledByUser()) { + dst = src; + } +} + +template +void CopyIfEnabled(T &dst, const T &src, cl::Option &opt) { + if (opt.IsEnabledByUser()) { + dst = src; + } +} + template class List : public Option { public: -- Gitee From 89a39073cecee24e588714386f12de6bc4d8c76e Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Mon, 28 Mar 2022 14:13:09 +0300 Subject: [PATCH 09/24] [utils][cl] Add (u)int8(16) types in CL library --- src/mapleall/maple_util/include/cl_option.h | 25 ++++++++++--------- .../maple_util/src/cl_option_parser.cpp | 10 ++++---- src/mapleall/test/cl_ut_test.cpp | 23 ++++++++++++++++- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/mapleall/maple_util/include/cl_option.h b/src/mapleall/maple_util/include/cl_option.h index 659b42ef58..62c8713948 100644 --- a/src/mapleall/maple_util/include/cl_option.h +++ b/src/mapleall/maple_util/include/cl_option.h @@ -28,6 +28,16 @@ namespace cl { +template +constexpr inline bool digitalCheck = (std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v); + /* is key VALUE needed ? */ enum class ValueExpectedType { kValueOptional, /* "--key VALUE" and "--key" are allowed */ @@ -178,10 +188,7 @@ class Option : public OptionInterface { KeyArg &keyArg) override { RetCode err = RetCode::noError; auto &key = args[argsIndex]; - if constexpr(std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v) { + if constexpr(digitalCheck) { err = ParseDigit(argsIndex, args, keyArg); } else if constexpr(std::is_same_v) { err = ParseString(argsIndex, args, keyArg); @@ -203,10 +210,7 @@ class Option : public OptionInterface { if (defaultValue.isSet) { value = defaultValue.defaultValue; } else { - if constexpr(std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v) { + if constexpr(digitalCheck) { value = 0; } else if constexpr(std::is_same_v) { value = ""; @@ -250,10 +254,7 @@ class Option : public OptionInterface { RetCode ParseBool(ssize_t &argsIndex, const std::vector &args); void FillVal(const T &val, std::vector &vals) { - if constexpr(std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v) { + if constexpr(digitalCheck) { vals.emplace_back(std::to_string(val)); } else if constexpr (std::is_same_v) { vals.emplace_back(val); diff --git a/src/mapleall/maple_util/src/cl_option_parser.cpp b/src/mapleall/maple_util/src/cl_option_parser.cpp index 3b2b0104d8..8770c98b34 100644 --- a/src/mapleall/maple_util/src/cl_option_parser.cpp +++ b/src/mapleall/maple_util/src/cl_option_parser.cpp @@ -139,11 +139,7 @@ template RetCode Option::ParseDigit(ssize_t &argsIndex, const std::vector &args, KeyArg &keyArg) { - constexpr bool u64Type = std::is_same::value; - constexpr bool u32Type = std::is_same::value; - constexpr bool i64Type = std::is_same::value; - constexpr bool i32Type = std::is_same::value; - static_assert(u64Type || u32Type || i64Type || i32Type, "Expected (u)intXX types"); + static_assert(digitalCheck, "Expected (u)intXX types"); RetCode err = RetCode::noError; ssize_t indexIncCnt = 0; @@ -182,7 +178,11 @@ RetCode Option::ParseDigit(ssize_t &argsIndex, } /* Needed to describe OptionType<>::Parse template in this .cpp file */ +template class cl::Option; +template class cl::Option; template class cl::Option; template class cl::Option; +template class cl::Option; +template class cl::Option; template class cl::Option; template class cl::Option; diff --git a/src/mapleall/test/cl_ut_test.cpp b/src/mapleall/test/cl_ut_test.cpp index 5dd898f1b1..1fdd7b92b8 100644 --- a/src/mapleall/test/cl_ut_test.cpp +++ b/src/mapleall/test/cl_ut_test.cpp @@ -98,6 +98,9 @@ namespace testopts { cl::Option testStr({"--str"}, ""); + cl::Option testUint8({"--uint8"}, ""); + cl::Option testUint16({"--uint16"}, ""); + cl::Option testInt32({"--int32"}, ""); cl::Option testUint32({"--uint32"}, ""); @@ -232,6 +235,8 @@ TEST(clOptions, digitTestMaxVal) { // create command line const char *argv[] = { "CLTest", // program name + "--uint8", "255", + "--uint16", "65535", "--int32", "2147483647", "--uint32", "4294967295", "--int64", "9223372036854775807", @@ -242,6 +247,12 @@ TEST(clOptions, digitTestMaxVal) { auto err = cl::CommandLine::GetCommandLine().Parse(argc, (char **)argv); ASSERT_EQ(err, cl::RetCode::noError); + uint8_t uint8Dig = testopts::testUint8; + ASSERT_EQ(uint8Dig, (1 << 8) - 1); + + uint16_t uint16Dig = testopts::testUint16; + ASSERT_EQ(uint16Dig, (1 << 16) - 1); + int32_t int32Dig = testopts::testInt32; ASSERT_EQ(int32Dig, INT_MAX); @@ -381,6 +392,8 @@ TEST(clOptions, digitTestOutOfRange2) { const char *argv[] = { "CLTest", // program name "--uint32", "4294967296", + "--uint16", "65536", + "--uint8", "256", nullptr}; int argc = (sizeof(argv) / sizeof(argv[0])) - 1; @@ -388,11 +401,19 @@ TEST(clOptions, digitTestOutOfRange2) { ASSERT_EQ(err, cl::RetCode::parsingErr); auto &badArgs = cl::CommandLine::GetCommandLine().badCLArgs; - ASSERT_EQ(badArgs.size(), 2); + ASSERT_EQ(badArgs.size(), 6); ASSERT_EQ(badArgs[0].first, "--uint32"); ASSERT_EQ(badArgs[1].first, "4294967296"); + ASSERT_EQ(badArgs[2].first, "--uint16"); + ASSERT_EQ(badArgs[3].first, "65536"); + ASSERT_EQ(badArgs[4].first, "--uint8"); + ASSERT_EQ(badArgs[5].first, "256"); ASSERT_EQ(badArgs[0].second, cl::RetCode::outOfRange); ASSERT_EQ(badArgs[1].second, cl::RetCode::notRegistered); + ASSERT_EQ(badArgs[2].second, cl::RetCode::outOfRange); + ASSERT_EQ(badArgs[3].second, cl::RetCode::notRegistered); + ASSERT_EQ(badArgs[4].second, cl::RetCode::outOfRange); + ASSERT_EQ(badArgs[5].second, cl::RetCode::notRegistered); } TEST(clOptions, digitTestOutOfRange3) { -- Gitee From 15bc2a250d2ccabe88ec3fdab3e5bc2135232758 Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Fri, 1 Apr 2022 13:23:18 +0300 Subject: [PATCH 10/24] [utils][cl] Add GetCommonValue to get value from abstract OptionInterface --- src/mapleall/maple_util/include/cl_option.h | 21 +++++++++++++++++++++ src/mapleall/test/cl_ut_test.cpp | 20 ++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/mapleall/maple_util/include/cl_option.h b/src/mapleall/maple_util/include/cl_option.h index 62c8713948..6e2a2ba562 100644 --- a/src/mapleall/maple_util/include/cl_option.h +++ b/src/mapleall/maple_util/include/cl_option.h @@ -17,6 +17,7 @@ #include "cl_parser.h" +#include #include #include #include @@ -85,6 +86,21 @@ struct DisableWith { explicit DisableWith(const std::string &val) : disableWith(val) {} }; +class OptionWrp { +public: + template + /* implicit */ OptionWrp(T v) : val(v) {} + + template + operator T() { + T *pval = std::any_cast(&val); + assert(pval); + return *pval; + } + + std::any val; +}; + /* Interface for templated Option class */ class OptionInterface { public: @@ -94,6 +110,7 @@ class OptionInterface { const std::vector &args, KeyArg &keyArg) = 0; virtual void Clear() = 0; virtual std::vector GetRawValues() = 0; + virtual OptionWrp GetCommonValue() const = 0; void FinalizeInitialization(const std::vector &optnames, const std::string &descr, @@ -244,6 +261,10 @@ class Option : public OptionInterface { return value; } + OptionWrp GetCommonValue() const override { + return value; + } + virtual void SetValue(const T &val) { value = val; } diff --git a/src/mapleall/test/cl_ut_test.cpp b/src/mapleall/test/cl_ut_test.cpp index 1fdd7b92b8..59513844a8 100644 --- a/src/mapleall/test/cl_ut_test.cpp +++ b/src/mapleall/test/cl_ut_test.cpp @@ -141,6 +141,8 @@ namespace testopts { cl::List vecStringDef({"--vecstrdef"}, "", cl::Init("Default")); cl::List vecDigDef({"--vecdigdef"}, "", cl::Init(100)); cl::List vecBoolDef({"--vecbooldef"}, "", cl::DisableWith("--no-vecbooldef"), cl::Init(true)); + + cl::Option common({"--common"}, ""); } // namespace testopts /* ################# "Enable/Disable Boolean Options" Test ############### @@ -984,3 +986,21 @@ TEST(clOptions, optList2) { ASSERT_EQ(testopts::vecDigDef.GetValues().size(), 1); ASSERT_EQ(testopts::vecBoolDef.GetValues().size(), 1); } + +/* ##################### "GetCommonValue from interface" check ########### + * ####################################################################### */ +TEST(clOptions, common) { + // create command line + const char *argv[] = { + "CLTest", // program name + "--common", "datacommon", + nullptr }; + int argc = (sizeof(argv) / sizeof(argv[0])) - 1; + + auto err = cl::CommandLine::GetCommandLine().Parse(argc, (char **)argv); + ASSERT_EQ(err, cl::RetCode::noError); + + cl::OptionInterface *commonOpt = &testopts::common; + std::string val = commonOpt->GetCommonValue(); + ASSERT_EQ(val, "datacommon"); +} -- Gitee From d1815220daa721f4c8598498706b9235ce08fe0e Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Tue, 22 Mar 2022 16:01:36 +0300 Subject: [PATCH 11/24] [utils][cl] Use deque instead of vector in CL library --- src/mapleall/maple_util/include/cl_option.h | 11 ++++++----- src/mapleall/maple_util/include/cl_parser.h | 11 ++++++----- src/mapleall/maple_util/src/cl_option_parser.cpp | 8 ++++---- src/mapleall/maple_util/src/cl_parser.cpp | 13 +++++++------ src/mapleall/test/cl_ut_test.cpp | 2 +- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/mapleall/maple_util/include/cl_option.h b/src/mapleall/maple_util/include/cl_option.h index 6e2a2ba562..d9b50b4f9e 100644 --- a/src/mapleall/maple_util/include/cl_option.h +++ b/src/mapleall/maple_util/include/cl_option.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -107,7 +108,7 @@ class OptionInterface { virtual ~OptionInterface() = default; virtual RetCode Parse(ssize_t &argsIndex, - const std::vector &args, KeyArg &keyArg) = 0; + const std::deque &args, KeyArg &keyArg) = 0; virtual void Clear() = 0; virtual std::vector GetRawValues() = 0; virtual OptionWrp GetCommonValue() const = 0; @@ -201,7 +202,7 @@ class Option : public OptionInterface { return GetValue(); } - RetCode Parse(ssize_t &argsIndex, const std::vector &args, + RetCode Parse(ssize_t &argsIndex, const std::deque &args, KeyArg &keyArg) override { RetCode err = RetCode::noError; auto &key = args[argsIndex]; @@ -270,9 +271,9 @@ class Option : public OptionInterface { } protected: - RetCode ParseDigit(ssize_t &argsIndex, const std::vector &args, KeyArg &keyArg); - RetCode ParseString(ssize_t &argsIndex, const std::vector &args, KeyArg &keyArg); - RetCode ParseBool(ssize_t &argsIndex, const std::vector &args); + RetCode ParseDigit(ssize_t &argsIndex, const std::deque &args, KeyArg &keyArg); + RetCode ParseString(ssize_t &argsIndex, const std::deque &args, KeyArg &keyArg); + RetCode ParseBool(ssize_t &argsIndex, const std::deque &args); void FillVal(const T &val, std::vector &vals) { if constexpr(digitalCheck) { diff --git a/src/mapleall/maple_util/include/cl_parser.h b/src/mapleall/maple_util/include/cl_parser.h index 356dbdf7ae..24412bc3f0 100644 --- a/src/mapleall/maple_util/include/cl_parser.h +++ b/src/mapleall/maple_util/include/cl_parser.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace cl { @@ -85,7 +86,7 @@ class CommandLine { return Parse(argc, argv, defaultCategory); } - RetCode HandleInputArgs(const std::vector &args, + RetCode HandleInputArgs(const std::deque &args, OptionCategory &optCategory); void Register(const std::vector &optNames, OptionInterface &opt, OptionCategory &optCategory); @@ -113,18 +114,18 @@ class CommandLine { OptionInterface *CheckJoinedOption(KeyArg &keyArg, OptionCategory &optCategory); RetCode ParseJoinedOption(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg, OptionCategory &optCategory); RetCode ParseOption(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg, OptionCategory &optCategory, OptionInterface *opt); RetCode ParseEqualOption(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg, OptionCategory &optCategory, const OptionsMapType &optMap, ssize_t pos); RetCode ParseSimpleOption(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg, OptionCategory &optCategory, const OptionsMapType &optMap); }; diff --git a/src/mapleall/maple_util/src/cl_option_parser.cpp b/src/mapleall/maple_util/src/cl_option_parser.cpp index 8770c98b34..8db521b497 100644 --- a/src/mapleall/maple_util/src/cl_option_parser.cpp +++ b/src/mapleall/maple_util/src/cl_option_parser.cpp @@ -44,7 +44,7 @@ bool IsPrefixDetected(std::string_view opt) { /* NOTE: Returning ssize_t parameter is used to show how many command line arguments * handled with this key. argsIndex must be incremented with this parameter outside of ExtractValue. */ std::pair ExtractValue(ssize_t argsIndex, - const std::vector &args, + const std::deque &args, const OptionInterface &opt, KeyArg &keyArg) { /* The option like "--key= " does not contain a value after equal symbol */ if (keyArg.isEqualOpt == true && keyArg.val.empty()) { @@ -89,7 +89,7 @@ std::pair ExtractValue(ssize_t argsIndex, * ################################################################ */ template <> RetCode Option::ParseBool(ssize_t &argsIndex, - const std::vector &args) { + const std::deque &args) { /* DisabledName should set it to false, like --fno-omit-framepointer vs --fomit-framepointer */ SetValue(GetDisabledName() != args[argsIndex]); @@ -99,7 +99,7 @@ template <> RetCode Option::ParseBool(ssize_t &argsIndex, /* NOTE: argsIndex must be incremented only if option is handled successfully */ template <> RetCode Option::ParseString(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg) { RetCode err = RetCode::noError; ssize_t indexIncCnt = 0; @@ -137,7 +137,7 @@ template <> RetCode Option::ParseString(ssize_t &argsIndex, /* NOTE: argsIndex must be incremented only if option is handled successfully */ template RetCode Option::ParseDigit(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg) { static_assert(digitalCheck, "Expected (u)intXX types"); diff --git a/src/mapleall/maple_util/src/cl_parser.cpp b/src/mapleall/maple_util/src/cl_parser.cpp index efebb0835f..34efc883d1 100644 --- a/src/mapleall/maple_util/src/cl_parser.cpp +++ b/src/mapleall/maple_util/src/cl_parser.cpp @@ -18,6 +18,7 @@ #include "mpl_logging.h" #include +#include #include #include #include @@ -48,7 +49,7 @@ OptionInterface *CommandLine::CheckJoinedOption(KeyArg &keyArg, OptionCategory & } RetCode CommandLine::ParseJoinedOption(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg, OptionCategory &optCategory) { OptionInterface *option = CheckJoinedOption(keyArg, optCategory); if (option != nullptr) { @@ -69,7 +70,7 @@ RetCode CommandLine::ParseJoinedOption(ssize_t &argsIndex, } RetCode CommandLine::ParseOption(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg, OptionCategory &optCategory, OptionInterface *opt) { RetCode err = opt->Parse(argsIndex, args, keyArg); @@ -86,7 +87,7 @@ RetCode CommandLine::ParseOption(ssize_t &argsIndex, } RetCode CommandLine::ParseEqualOption(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg, OptionCategory &optCategory, const OptionsMapType &optMap, ssize_t pos) { keyArg.isEqualOpt = true; @@ -110,7 +111,7 @@ RetCode CommandLine::ParseEqualOption(ssize_t &argsIndex, } RetCode CommandLine::ParseSimpleOption(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg, OptionCategory &optCategory, const OptionsMapType &optMap) { keyArg.isEqualOpt = false; @@ -126,7 +127,7 @@ RetCode CommandLine::ParseSimpleOption(ssize_t &argsIndex, } } -RetCode CommandLine::HandleInputArgs(const std::vector &args, +RetCode CommandLine::HandleInputArgs(const std::deque &args, OptionCategory &optCategory) { RetCode err = RetCode::noError; @@ -189,7 +190,7 @@ RetCode CommandLine::Parse(int argc, char **argv, OptionCategory &optCategory) { return RetCode::noError; } - std::vector args; + std::deque args; while (argc != 0 && *argv != nullptr) { args.emplace_back(*argv); ++argv; diff --git a/src/mapleall/test/cl_ut_test.cpp b/src/mapleall/test/cl_ut_test.cpp index 59513844a8..7b652f861b 100644 --- a/src/mapleall/test/cl_ut_test.cpp +++ b/src/mapleall/test/cl_ut_test.cpp @@ -57,7 +57,7 @@ std::vector cl::Option::GetRawValues() { template <> cl::RetCode cl::Option::Parse(ssize_t &argsIndex, - const std::vector &args, + const std::deque &args, KeyArg &keyArg) { utCLTypeChecker = true; RetCode err = cl::RetCode::noError; -- Gitee From c8d3b94edb8bf3b79e1a35e95a22beb397a662b8 Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Fri, 4 Mar 2022 15:38:11 +0300 Subject: [PATCH 12/24] [mapleall][driver] Add driver options descriptions by new CL library These options will be used in the driver in next commits. --- src/mapleall/maple_driver/BUILD.gn | 9 +- .../maple_driver/include/driver_options.h | 112 +++++++ .../maple_driver/src/driver_options.cpp | 309 ++++++++++++++++++ src/mapleall/maple_util/include/cl_parser.h | 15 + 4 files changed, 443 insertions(+), 2 deletions(-) create mode 100644 src/mapleall/maple_driver/include/driver_options.h create mode 100644 src/mapleall/maple_driver/src/driver_options.cpp diff --git a/src/mapleall/maple_driver/BUILD.gn b/src/mapleall/maple_driver/BUILD.gn index 4cdb42df47..67a56eb81d 100644 --- a/src/mapleall/maple_driver/BUILD.gn +++ b/src/mapleall/maple_driver/BUILD.gn @@ -74,6 +74,7 @@ executable("maple") { "${MAPLEALL_ROOT}/maple_phase:libmplphase", "${MAPLEALL_ROOT}/maple_phase:libmplphase", "${MAPLEALL_ROOT}/maple_util:libmplutil", + "${MAPLEALL_ROOT}/maple_util:libcommandline", "${MAPLEALL_ROOT}/mempool:libmempool", "${MAPLEALL_ROOT}/mpl2mpl:libmpl2mpl", "${THIRD_PARTY_ROOT}/bounds_checking_function:libHWSecureC", @@ -81,9 +82,13 @@ executable("maple") { } static_library("libdriver_option") { - sources = [ "src/driver_option_common.cpp" ] + sources = [ "src/driver_option_common.cpp", + "src/driver_options.cpp" + ] - include_dirs = [ "${MAPLEALL_ROOT}/maple_driver/include" ] + include_dirs = [ "${MAPLEALL_ROOT}/maple_driver/include", + "${MAPLEALL_ROOT}/maple_util/include" + ] output_dir = "${root_out_dir}/lib/${HOST_ARCH}" } diff --git a/src/mapleall/maple_driver/include/driver_options.h b/src/mapleall/maple_driver/include/driver_options.h new file mode 100644 index 0000000000..3ea9f488ef --- /dev/null +++ b/src/mapleall/maple_driver/include/driver_options.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) [2022] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef MAPLE_DRIVER_INCLUDE_DRIVER_OPTIONS_H +#define MAPLE_DRIVER_INCLUDE_DRIVER_OPTIONS_H + +#include "cl_option.h" +#include "cl_parser.h" + +#include + +static cl::OptionCategory &driverCategory = cl::CommandLine::GetCommandLine().defaultCategory; + +static cl::OptionCategory &clangCategory = cl::CommandLine::GetCommandLine().clangCategory; +static cl::OptionCategory &hir2mplCategory = cl::CommandLine::GetCommandLine().hir2mplCategory; +static cl::OptionCategory &mpl2mplCategory = cl::CommandLine::GetCommandLine().mpl2mplCategory; +static cl::OptionCategory &meCategory = cl::CommandLine::GetCommandLine().meCategory; +static cl::OptionCategory &cgCategory = cl::CommandLine::GetCommandLine().cgCategory; +static cl::OptionCategory &asCategory = cl::CommandLine::GetCommandLine().asCategory; +static cl::OptionCategory &ldCategory = cl::CommandLine::GetCommandLine().ldCategory; + +static cl::OptionCategory &dex2mplCategory = cl::CommandLine::GetCommandLine().dex2mplCategory; +static cl::OptionCategory &jbc2mplCategory = cl::CommandLine::GetCommandLine().jbc2mplCategory; +static cl::OptionCategory &ipaCategory = cl::CommandLine::GetCommandLine().ipaCategory; + +namespace opts { + +/* ##################### BOOL Options ############################################################### */ + +extern cl::Option version; +extern cl::Option o0; +extern cl::Option o1; +extern cl::Option o2; +extern cl::Option os; +extern cl::Option verify; +extern cl::Option decoupleStatic; +extern cl::Option bigendian; +extern cl::Option gconly; +extern cl::Option timePhase; +extern cl::Option genMeMpl; +extern cl::Option compileWOLink; +extern cl::Option genVtable; +extern cl::Option verbose; +extern cl::Option debug; +extern cl::Option withDwarf; +extern cl::Option npeNoCheck; +extern cl::Option npeStaticCheck; +extern cl::Option npeDynamicCheck; +extern cl::Option npeDynamicCheckSilent; +extern cl::Option npeDynamicCheckAll; +extern cl::Option boundaryNoCheck; +extern cl::Option boundaryStaticCheck; +extern cl::Option boundaryDynamicCheck; +extern cl::Option boundaryDynamicCheckSilent; +extern cl::Option safeRegionOption; +extern cl::Option printDriverPhases; +extern cl::Option ldStatic; +extern cl::Option maplePhase; +extern cl::Option genMapleBC; +extern cl::Option genLMBC; +extern cl::Option profileGen; +extern cl::Option profileUse; + +/* ##################### STRING Options ############################################################### */ + +extern cl::Option help; +extern cl::Option infile; +extern cl::Option mplt; +extern cl::Option partO2; +extern cl::List jbc2mplOpt; +extern cl::List hir2mplOpt; +extern cl::List clangOpt; +extern cl::List asOpt; +extern cl::List ldOpt; +extern cl::List dex2mplOpt; +extern cl::List mplipaOpt; +extern cl::List mplcgOpt; +extern cl::List meOpt; +extern cl::List mpl2mplOpt; +extern cl::Option profile; +extern cl::Option run; +extern cl::Option optionOpt; +extern cl::List ldLib; +extern cl::List ldLibPath; +extern cl::List enableMacro; +extern cl::List disableMacro; +extern cl::List includeDir; +extern cl::List includeSystem; +extern cl::Option output; +extern cl::Option saveTempOpt; + +/* ##################### DIGITAL Options ############################################################### */ + +extern cl::Option helpLevel; + +/* #################################################################################################### */ + +} /* opts */ + +#endif /* MAPLE_DRIVER_INCLUDE_DRIVER_OPTIONS_H */ diff --git a/src/mapleall/maple_driver/src/driver_options.cpp b/src/mapleall/maple_driver/src/driver_options.cpp new file mode 100644 index 0000000000..3f31d007a1 --- /dev/null +++ b/src/mapleall/maple_driver/src/driver_options.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (c) [2022] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "driver_options.h" +#include "cl_option.h" + +#include +#include + +namespace opts { + +/* ##################### BOOL Options ############################################################### */ + +cl::Option version({"--version", "-v"}, + "--version [command] \tPrint version and exit.\n", + {driverCategory}); + +cl::Option o0({"--O0", "-O0"}, + " -O0 \tNo optimization.\n", + {driverCategory}); + +cl::Option o1({"--O1", "-O1"}, + " -O1 \tDo some optimization.\n", + {driverCategory}); + +cl::Option o2({"--O2", "-O2"}, + " -O2 \tDo more optimization. (Default)\n", + {driverCategory}); + +cl::Option os({"--Os", "-Os"}, + " -Os \tOptimize for size, based on O2.\n", + {driverCategory, hir2mplCategory}); + +cl::Option verify({"--verify"}, + " --verify \tVerify mpl file\n", + {driverCategory, dex2mplCategory, mpl2mplCategory}); + +cl::Option decoupleStatic({"--decouple-static", "-decouple-static"}, + " --decouple-static \tdecouple the static method and field\n" + " --no-decouple-static \tDon't decouple the static method and field\n", + {driverCategory, dex2mplCategory, meCategory, mpl2mplCategory}, + cl::DisableWith("--no-decouple-static")); + +cl::Option bigendian({"-Be", "--BigEndian"}, + " --BigEndian/--Be \tUsing BigEndian\n" + " --no-BigEndian/ --no-Be \tUsing LittleEndian\n", + {driverCategory, meCategory, mpl2mplCategory, cgCategory}, + cl::DisableWith("--no-BigEndian")); + +cl::Option gconly({"--gconly", "-gconly"}, + " --gconly \tMake gconly is enable\n" + " --no-gconly \tDon't make gconly is enable\n", + {driverCategory, dex2mplCategory, meCategory, + mpl2mplCategory, cgCategory}, + cl::DisableWith("--no-gconly")); + +cl::Option timePhase({"-time-phases"}, + " -time-phases \tTiming phases and print percentages\n", + {driverCategory}); + +cl::Option genMeMpl({"--genmempl"}, + " --genmempl \tGenerate me.mpl file\n", + {driverCategory}); + +cl::Option compileWOLink({"-c"}, + " -c \tCompile the source files without linking\n", + {driverCategory}); + +cl::Option genVtable({"--genVtableImpl"}, + " --genVtableImpl \tGenerate VtableImpl.mpl file\n", + {driverCategory}); + +cl::Option verbose({"-verbose"}, + " -verbose \t: print informations\n", + {driverCategory, jbc2mplCategory, hir2mplCategory, + meCategory, mpl2mplCategory, cgCategory}); + +cl::Option debug({"--debug"}, + " --debug \tPrint debug info.\n", + {driverCategory}); + +cl::Option withDwarf({"-g"}, + " --debug \tPrint debug info.\n", + {driverCategory}); + +cl::Option npeNoCheck({"--no-npe-check"}, + " --no-npe-check \tDisable null pointer check (Default)\n", + {driverCategory}); + +cl::Option npeStaticCheck({"--npe-check-static"}, + " --npe-check-static \tEnable null pointer static check only\n", + {driverCategory}); + +cl::Option npeDynamicCheck({"--npe-check-dynamic"}, + " --npe-check-dynamic \tEnable null pointer dynamic check with static warning\n", + {driverCategory}); + +cl::Option npeDynamicCheckSilent({"--npe-check-dynamic-silent"}, + " --npe-check-dynamic-silent \tEnable null pointer dynamic without static warning\n", + {driverCategory}); + +cl::Option npeDynamicCheckAll({"--npe-check-dynamic-all"}, + " --npe-check-dynamic-all \tKeep dynamic check before dereference, used with --npe-check-dynamic* options\n", + {driverCategory}); + +cl::Option boundaryNoCheck({"--no-boundary-check"}, + " --no-boundary-check \tDisable boundary check (Default)\n", + {driverCategory}); + +cl::Option boundaryStaticCheck({"--boundary-check-static"}, + " --boundary-check-static \tEnable boundary static check\n", + {driverCategory}); + +cl::Option boundaryDynamicCheck({"--boundary-check-dynamic"}, + " --boundary-check-dynamic \tEnable boundary dynamic check with static warning\n", + {driverCategory}); + +cl::Option boundaryDynamicCheckSilent({"--boundary-check-dynamic-silent"}, + " --boundary-check-dynamic-silent \tEnable boundary dynamic check without static warning\n", + {driverCategory}); + +cl::Option safeRegionOption({"--safe-region"}, + " --safe-region \tEnable safe region\n", + {driverCategory}); + +cl::Option printDriverPhases({"--print-driver-phases"}, + " --print-driver-phases \tPrint Driver Phases\n", + {driverCategory}); + +cl::Option ldStatic({"-static"}, + " -static \tForce the linker to link a program statically\n", + {driverCategory, ldCategory}); + +cl::Option maplePhase({"--maple-phase"}, + " --maple-phase \tRun maple phase only\n --no-maple-phase\n", + {driverCategory}, + cl::DisableWith("--no-maple-phase"), + cl::Init(true)); + +cl::Option genMapleBC({"--genmaplebc"}, + " --genmaplebc \tGenerate .mbc file\n", + {driverCategory}); + +cl::Option genLMBC({"--genlmbc"}, + " --genlmbc \tGenerate .lmbc file\n", + {driverCategory}); + +cl::Option profileGen({"--profileGen"}, + " --profileGen \tGenerate profile data for static languages\n", + {driverCategory, meCategory, mpl2mplCategory, cgCategory}); + +cl::Option profileUse({"--profileUse"}, + " --profileUse \tOptimize static languages with profile data\n", + {driverCategory, meCategory, mpl2mplCategory, cgCategory}); + +/* ##################### STRING Options ############################################################### */ + +cl::Option help({"--help", "-h"}, + "USAGE: maple [options]\n\n" + " Example 1: /maple --run=me:mpl2mpl:mplcg " + "--option=\"[MEOPT]:[MPL2MPLOPT]:[MPLCGOPT]\"\n" + " --mplt=MPLTPATH inputFile.mpl\n" + " Example 2: /maple -O2 --mplt=mpltPath inputFile.dex\n\n" + "==============================\n" + " Options:\n", + {driverCategory}, + cl::optionalValue); + +cl::Option infile({"--infile"}, + " --infile file1,file2,file3 \tInput files.\n", + {driverCategory}); + +cl::Option mplt({"--mplt", "-mplt"}, + " --mplt=file1,file2,file3 \tImport mplt files.\n", + {driverCategory, dex2mplCategory, jbc2mplCategory}); + +cl::Option partO2({"--partO2"}, + " --partO2 \tSet func list for O2\n", + {driverCategory}); + +cl::List jbc2mplOpt({"--jbc2mpl-opt"}, + " --jbc2mpl-opt \tSet options for jbc2mpl\n", + {driverCategory}); + +cl::List hir2mplOpt({"--hir2mpl-opt"}, + " --hir2mpl-opt \tSet options for hir2mpl\n", + {driverCategory}); + +cl::List clangOpt({"--clang-opt"}, + " --clang-opt \tSet options for clang as AST generator\n", + {driverCategory}); + +cl::List asOpt({"--as-opt"}, + "--as-opt \tSet options for as\n", + {driverCategory}); + +cl::List ldOpt({"--ld-opt"}, + "--ld-opt \tSet options for ld\n", + {driverCategory}); + +cl::List dex2mplOpt({"--dex2mpl-opt"}, + "--dex2mpl-opt \tSet options for dex2mpl\n", + {driverCategory}); + +cl::List mplipaOpt({"--mplipa-opt"}, + "--mplipa-opt \tSet options for mplipa\n", + {driverCategory}); + +cl::List mplcgOpt({"--mplcg-opt"}, + "--mplcg-opt \tSet options for mplcg\n", + {driverCategory}); + +cl::List meOpt({"--me-opt"}, + "--me-opt \tSet options for me\n", + {driverCategory}); + +cl::List mpl2mplOpt({"--mpl2mpl-opt"}, + "--mpl2mpl-opt \tSet options for mpl2mpl\n", + {driverCategory}); + +cl::Option profile({"--profile"}, + " --profile \tFor PGO optimization\n" + " \t--profile=list_file\n", + {driverCategory, dex2mplCategory, mpl2mplCategory, cgCategory}); + +cl::Option run({"--run"}, + " --run=cmd1:cmd2 \tThe name of executables that are going\n" + " \tto execute. IN SEQUENCE.\n" + " \tSeparated by \":\".Available exe names:\n" + " \tjbc2mpl, me, mpl2mpl, mplcg\n" + " \tInput file must match the tool can\n" + " \thandle\n", + {driverCategory}); + +cl::Option optionOpt({"--option"}, + " --option=\"opt1:opt2\" \tOptions for each executable,\n" + " \tseparated by \":\".\n" + " \tThe sequence must match the sequence in\n" + " \t--run.\n", + {driverCategory}); + +cl::List ldLib({"-l"}, + " -l \tLinks with a library file\n", + {driverCategory, ldCategory}, + cl::joinedValue); + +cl::List ldLibPath({"-L"}, + " -L \tAdd directory to library search path\n", + {driverCategory, ldCategory}, + cl::joinedValue); + +cl::List enableMacro({"-D"}, + " -D = \tDefine to (or 1 if omitted)\n", + {driverCategory, clangCategory}, + cl::joinedValue); + +cl::List disableMacro({"-U"}, + " -U \tUndefine macro \n", + {driverCategory, clangCategory}, + cl::joinedValue); + +cl::List includeDir({"-I"}, + " -I \tAdd directory to include search path\n", + {driverCategory, clangCategory}, + cl::joinedValue); + +cl::List includeSystem({"--isystem"}, + " -isystem \tAdd directory to SYSTEM include search path\n", + {driverCategory, clangCategory}, + cl::joinedValue); + +cl::Option output({"-o"}, + " -o \tPlace the output into \n", + {driverCategory}, + cl::Init("a.out")); + +cl::Option saveTempOpt({"--save-temps"}, + " --save-temps \tDo not delete intermediate files.\n" + " \t--save-temps Save all intermediate files.\n" + " \t--save-temps=file1,file2,file3 Save the\n" + " \ttarget files.\n", + {driverCategory}, + cl::optionalValue); + +/* ##################### DIGITAL Options ############################################################### */ + +cl::Option helpLevel({"--level"}, + " --level=NUM \tPrint the help info of specified level.\n" + " \tNUM=0: All options (Default)\n" + " \tNUM=1: Product options\n" + " \tNUM=2: Experimental options\n" + " \tNUM=3: Debug options\n", + {driverCategory}); + +/* #################################################################################################### */ + +} /* namespace opts */ diff --git a/src/mapleall/maple_util/include/cl_parser.h b/src/mapleall/maple_util/include/cl_parser.h index 24412bc3f0..bc419494ac 100644 --- a/src/mapleall/maple_util/include/cl_parser.h +++ b/src/mapleall/maple_util/include/cl_parser.h @@ -109,6 +109,21 @@ class CommandLine { std::vector> badCLArgs; OptionCategory defaultCategory; + /* NOTE: categories must be constructed before options. + * It's the reason why they are inside CommandLine. + * Looks like ugly architecture, but we need it */ + cl::OptionCategory clangCategory; + cl::OptionCategory hir2mplCategory; + cl::OptionCategory mpl2mplCategory; + cl::OptionCategory meCategory; + cl::OptionCategory cgCategory; + cl::OptionCategory asCategory; + cl::OptionCategory ldCategory; + + cl::OptionCategory dex2mplCategory; + cl::OptionCategory jbc2mplCategory; + cl::OptionCategory ipaCategory; + private: CommandLine() = default; -- Gitee From 7bb22032ed512c7ad3586346cc7dd5aaa794d30f Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Sat, 5 Mar 2022 11:57:34 +0300 Subject: [PATCH 13/24] [mapleall][driver] Introduce MplDriver class This class will be used to handle all driver actions instead of mplOptions class. --- src/mapleall/maple_driver/BUILD.gn | 1 + src/mapleall/maple_driver/include/compiler.h | 24 +- .../maple_driver/include/maple_driver.h | 134 ++++ src/mapleall/maple_driver/src/maple.cpp | 8 +- .../maple_driver/src/maple_driver.cpp | 606 ++++++++++++++++++ 5 files changed, 744 insertions(+), 29 deletions(-) create mode 100644 src/mapleall/maple_driver/include/maple_driver.h create mode 100644 src/mapleall/maple_driver/src/maple_driver.cpp diff --git a/src/mapleall/maple_driver/BUILD.gn b/src/mapleall/maple_driver/BUILD.gn index 67a56eb81d..b3a63ee5c2 100644 --- a/src/mapleall/maple_driver/BUILD.gn +++ b/src/mapleall/maple_driver/BUILD.gn @@ -53,6 +53,7 @@ executable("maple") { "src/clang_compiler.cpp", "src/ld_compiler.cpp", "src/maple.cpp", + "src/maple_driver.cpp", "src/maple_comb_compiler_wrapper.cpp", "src/maple_comb_compiler.cpp", "src/mpl_options.cpp", diff --git a/src/mapleall/maple_driver/include/compiler.h b/src/mapleall/maple_driver/include/compiler.h index 0284f63559..599a486d2f 100644 --- a/src/mapleall/maple_driver/include/compiler.h +++ b/src/mapleall/maple_driver/include/compiler.h @@ -28,31 +28,9 @@ #ifdef INTERGRATE_DRIVER #include "dex2mpl_options.h" #endif +#include "maple_driver.h" namespace maple { -const std::string kBinNameNone = ""; -const std::string kBinNameJbc2mpl = "jbc2mpl"; -const std::string kBinNameCpp2mpl = "hir2mpl"; -const std::string kBinNameClang = "clang"; -const std::string kBinNameDex2mpl = "dex2mpl"; -const std::string kBinNameMplipa = "mplipa"; -const std::string kBinNameMe = "me"; -const std::string kBinNameMpl2mpl = "mpl2mpl"; -const std::string kBinNameMplcg = "mplcg"; -const std::string kBinNameMapleComb = "maplecomb"; -const std::string kBinNameMapleCombWrp = "maplecombwrp"; -const std::string kMachine = "aarch64-"; -const std::string kVendor = "unknown-"; -const std::string kOperatingSystem = "linux-gnu-"; -const std::string kLdFlag = "ld"; -const std::string kGccFlag = "gcc"; -const std::string kGppFlag = "g++"; -const std::string kAsFlag = "as"; -const std::string kInputPhase = "input"; -const std::string kBinNameLd = kMachine + kOperatingSystem + kLdFlag; -const std::string kBinNameAs = kMachine + kOperatingSystem + kAsFlag; -const std::string kBinNameGcc = kMachine + kOperatingSystem + kGccFlag; -const std::string kBinNameGpp = kMachine + kOperatingSystem + kGppFlag; class Compiler { public: diff --git a/src/mapleall/maple_driver/include/maple_driver.h b/src/mapleall/maple_driver/include/maple_driver.h new file mode 100644 index 0000000000..8306c0c3fe --- /dev/null +++ b/src/mapleall/maple_driver/include/maple_driver.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) [2022] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MAPLE_DRIVER_INCLUDE_MAPLE_DRIVER_H +#define MAPLE_DRIVER_INCLUDE_MAPLE_DRIVER_H + +#include "cl_parser.h" +#include "error_code.h" +#include "mpl_options.h" +#include "version.h" + +#include +#include + +namespace maple { + +extern const std::string kBinNameNone; +extern const std::string kBinNameJbc2mpl; +extern const std::string kBinNameCpp2mpl; +extern const std::string kBinNameClang; +extern const std::string kBinNameDex2mpl; +extern const std::string kBinNameMplipa; +extern const std::string kBinNameMe; +extern const std::string kBinNameMpl2mpl; +extern const std::string kBinNameMplcg; +extern const std::string kBinNameMapleComb; +extern const std::string kBinNameMapleCombWrp; +extern const std::string kMachine; +extern const std::string kVendor; +extern const std::string kOperatingSystem; +extern const std::string kLdFlag; +extern const std::string kGccFlag; +extern const std::string kGppFlag; +extern const std::string kAsFlag; +extern const std::string kInputPhase; +extern const std::string kBinNameLd; +extern const std::string kBinNameAs; +extern const std::string kBinNameGcc; +extern const std::string kBinNameGpp; + +struct DrvOptions { + SafetyCheckMode npeCheckMode = SafetyCheckMode::kNoCheck; + SafetyCheckMode boundaryCheckMode = SafetyCheckMode::kNoCheck; +}; + +class MplDriver { +using ExeOptMapType = std::unordered_map>; + + public: + /* singleton */ + static MplDriver &GetMplDriver(); + + // must not be copyable + MplDriver(const MplDriver &) = delete; + MplDriver &operator=(const MplDriver &) = delete; + + ErrorCode Processing(); + + std::string GetVersion() { +#ifdef ANDROID + const std::string version = "MapleDriver " + + std::to_string(Version::GetMajorVersion()) + "." + + std::to_string(Version::GetMinorVersion()) + " 20190929"; +#else + const std::string version = "Maple Version : " + Version::GetVersionStr(); +#endif + return version; + } + + ExeOptMapType &GetExeOptions() { + return exeOptions; + } + + DrvOptions drvOptions; + + private: + MplDriver() = default; + + ErrorCode HandleEarlyOptions(); + void HandleExtraOptions(); + ErrorCode HandleOptions(); + ErrorCode CheckInputFiles(); + ErrorCode DecideRunningPhases(); + ErrorCode DecideRunningPhases(const std::vector &runExes); + std::unique_ptr DecideRunningPhasesByType(const InputInfo *const inputInfo, + bool isMultipleFiles); + ErrorCode MFCreateActionByExe(const std::string &exe, std::unique_ptr ¤tAction, + const InputInfo *const inputInfo, bool &wasWrpCombCompilerCreated); + ErrorCode SFCreateActionByExe(const std::string &exe, std::unique_ptr ¤tAction, + const InputInfo *const inputInfo, bool &isCombCompiler); + void DumpActionTree(const Action &action, int indents) const; + void DumpActionTree() const; + void UpdateTools(const std::string &args); + void UpdateExeOptions(const std::string &options, const std::string &tool); + ErrorCode UpdateExeOptions(const std::string &args); + InputInfo *AllocateInputInfo(const std::string &inputFile); + + RunMode runMode = RunMode::kAutoRun; + + std::vector inputFiles; + std::string exeFolder; + + /* exeOptions is used to forward options to necessary tool. + * As example: --ld-opt="opt1 opt2" will be forwarded to linker */ + ExeOptMapType exeOptions; + + /* It contains compilation steps for current compiler run. + * If user sets the tools with --run=tool1:tool2:etc, it containts these tools. + * Or it can be automatically filled in DecideRunningPhasesByType */ + std::vector tools; + + /* Do not remove temporary files that are set in saveFiles */ + std::vector saveFiles; + + std::vector> inputInfos; + std::vector> rootActions; +}; + +int DriverProcessing(int argc, char **argv); + +} // namespace maple + +#endif // MAPLE_DRIVER_INCLUDE_MPL_OPTIONS_H diff --git a/src/mapleall/maple_driver/src/maple.cpp b/src/mapleall/maple_driver/src/maple.cpp index 5cd1655cc4..86afd59290 100644 --- a/src/mapleall/maple_driver/src/maple.cpp +++ b/src/mapleall/maple_driver/src/maple.cpp @@ -14,17 +14,13 @@ */ #include "compiler_factory.h" #include "error_code.h" +#include "maple_driver.h" #include "mpl_options.h" #include "mpl_logging.h" using namespace maple; int main(int argc, char **argv) { - MplOptions mplOptions; - int ret = mplOptions.Parse(argc, argv); - if (ret == kErrorNoError) { - ret = CompilerFactory::GetInstance().Compile(mplOptions); - } - PrintErrorMessage(ret); + int ret = DriverProcessing(argc, argv); return ret; } diff --git a/src/mapleall/maple_driver/src/maple_driver.cpp b/src/mapleall/maple_driver/src/maple_driver.cpp new file mode 100644 index 0000000000..aaf752bafd --- /dev/null +++ b/src/mapleall/maple_driver/src/maple_driver.cpp @@ -0,0 +1,606 @@ +/* + * Copyright (c) [2022] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "compiler.h" +#include "driver_options.h" +#include "error_code.h" +#include "maple_driver.h" +#include "mpl_options.h" +#include +#include + +namespace maple { + +const std::string kBinNameNone = ""; +const std::string kBinNameJbc2mpl = "jbc2mpl"; +const std::string kBinNameCpp2mpl = "hir2mpl"; +const std::string kBinNameClang = "clang"; +const std::string kBinNameDex2mpl = "dex2mpl"; +const std::string kBinNameMplipa = "mplipa"; +const std::string kBinNameMe = "me"; +const std::string kBinNameMpl2mpl = "mpl2mpl"; +const std::string kBinNameMplcg = "mplcg"; +const std::string kBinNameMapleComb = "maplecomb"; +const std::string kBinNameMapleCombWrp = "maplecombwrp"; +const std::string kMachine = "aarch64-"; +const std::string kVendor = "unknown-"; +const std::string kOperatingSystem = "linux-gnu-"; +const std::string kLdFlag = "ld"; +const std::string kGccFlag = "gcc"; +const std::string kGppFlag = "g++"; +const std::string kAsFlag = "as"; +const std::string kInputPhase = "input"; +const std::string kBinNameLd = kMachine + kOperatingSystem + kLdFlag; +const std::string kBinNameAs = kMachine + kOperatingSystem + kAsFlag; +const std::string kBinNameGcc = kMachine + kOperatingSystem + kGccFlag; +const std::string kBinNameGpp = kMachine + kOperatingSystem + kGppFlag; + +/* tool -> OptionCategory map: ld -> ldCategory, me -> meCategory and etc... */ +static std::unordered_map exeCategories = + { + {"driver", &driverCategory}, + {maple::kBinNameClang, &clangCategory}, + {maple::kBinNameCpp2mpl, &hir2mplCategory}, + {maple::kBinNameMpl2mpl, &mpl2mplCategory}, + {maple::kBinNameMe, &meCategory}, + {maple::kBinNameMplcg, &cgCategory}, + {maple::kAsFlag, &asCategory}, + {maple::kLdFlag, &ldCategory}, + {maple::kBinNameDex2mpl, &dex2mplCategory}, + {maple::kBinNameJbc2mpl, &jbc2mplCategory}, + {maple::kBinNameMplipa, &ipaCategory} + }; + +/* Debug option */ +static cl::Option woinput({"--woinput"}, "", cl::hide); + +MplDriver &MplDriver::GetMplDriver() { + static MplDriver mplDriver; + return mplDriver; +} + +void MplDriver::DumpActionTree(const Action &action, int indents) const { + for (const std::unique_ptr &a : action.GetInputActions()) { + DumpActionTree(*a, indents + 1); + } + + if (indents != 0) { + LogInfo::MapleLogger() << "|"; + /* print indents */ + for (int i = 0; i < indents; ++i) { + LogInfo::MapleLogger() << "-"; + } + } + + if (action.GetTool() == kInputPhase) { + LogInfo::MapleLogger() << action.GetTool() << " " << action.GetInputFile() << '\n'; + } else { + LogInfo::MapleLogger() << action.GetTool() << '\n'; + } +} + +void MplDriver::DumpActionTree() const { + for (auto &rNode : rootActions) { + DumpActionTree(*rNode, 0); + } +} + +void MplDriver::UpdateTools(const std::string &args) { + std::vector argTools; + StringUtils::Split(args, argTools, ':'); + for (auto &tool : argTools) { + if (!tool.empty()) { + tools.push_back(tool); + } + } +} + +void MplDriver::UpdateExeOptions(const std::string &options, const std::string &tool) { + std::vector splittedOptions; + StringUtils::Split(options, splittedOptions, ' '); + + for (auto &opt : splittedOptions) { + if (!opt.empty()) { + exeOptions[tool].push_back(opt); + } + } +} + +ErrorCode MplDriver::UpdateExeOptions(const std::string &args) { + std::vector options; + StringUtils::Split(args, options, ':'); + + /* The number of a tools and options for them must be the same */ + if (options.size() != tools.size()) { + LogInfo::MapleLogger(kLlErr) << "The --run and --option are not matched, please check them." + << "(Too many or too few)\n"; + return kErrorInvalidParameter; + } + + auto tool = tools.begin(); + for (auto &opt : options) { + UpdateExeOptions(opt, *tool); + ++tool; + } + + return kErrorNoError; +} + +ErrorCode MplDriver::CheckInputFiles() { + auto &badArgs = cl::CommandLine::GetCommandLine().badCLArgs; + auto isInputFile = [](const auto &fileName) { + bool isInputFile = true; + std::ifstream infile; + infile.open(fileName); + if (infile.fail()) { + isInputFile = false; + infile.close(); + } + infile.close(); + return isInputFile; + }; + + /* Set input files with --infile="file1 file2" option */ + if (driver::opts::infile.IsEnabledByUser()) { + if (StringUtils::Trim(driver::opts::infile).empty()) { + return kErrorFileNotFound; + } + + std::vector splitsInputFiles; + StringUtils::Split(driver::opts::infile, splitsInputFiles, ','); + + /* inputInfo describes each input file for driver */ + for (auto &inFile : splitsInputFiles) { + if (isInputFile(inFile)) { + inputFiles.push_back(inFile); + inputInfos.push_back(std::make_unique(inFile)); + } + } + } + + /* Set input files directly: maple file1 file2 */ + else { + for (auto &arg : badArgs) { + if (isInputFile(arg.first)) { + inputFiles.push_back(arg.first); + inputInfos.push_back(std::make_unique(arg.first)); + } + } + } + + if (inputFiles.empty()) { + return kErrorFileNotFound; + } + + return kErrorNoError; +} + +std::unique_ptr MplDriver::DecideRunningPhasesByType(const InputInfo *const inputInfo, + bool isMultipleFiles) { + InputFileType inputFileType = inputInfo->GetInputFileType(); + std::unique_ptr currentAction = std::make_unique(kInputPhase, inputInfo); + std::unique_ptr newAction; + + bool isNeedMapleComb = true; + bool isNeedMplcg = true; + bool isNeedAs = true; + switch (inputFileType) { + case InputFileType::kFileTypeC: + case InputFileType::kFileTypeCpp: + newAction = std::make_unique(kBinNameClang, inputInfo, currentAction); + currentAction = std::move(newAction); + [[clang::fallthrough]]; + case InputFileType::kFileTypeAst: + tools.push_back(kBinNameCpp2mpl); + newAction = std::make_unique(kBinNameCpp2mpl, inputInfo, currentAction); + currentAction = std::move(newAction); + break; + case InputFileType::kFileTypeJar: + // fall-through + case InputFileType::kFileTypeClass: + tools.push_back(kBinNameJbc2mpl); + newAction = std::make_unique(kBinNameJbc2mpl, inputInfo, currentAction); + currentAction = std::move(newAction); + isNeedAs = false; + break; + case InputFileType::kFileTypeDex: + tools.push_back(kBinNameDex2mpl); + newAction = std::make_unique(kBinNameDex2mpl, inputInfo, currentAction); + currentAction = std::move(newAction); + isNeedAs = false; + break; + case InputFileType::kFileTypeMpl: + break; + case InputFileType::kFileTypeMeMpl: + case InputFileType::kFileTypeVtableImplMpl: + isNeedMapleComb = false; + break; + case InputFileType::kFileTypeS: + isNeedMplcg = false; + isNeedMapleComb = false; + break; + case InputFileType::kFileTypeBpl: + break; + case InputFileType::kFileTypeObj: + isNeedMplcg = false; + isNeedMapleComb = false; + isNeedAs = false; + break; + case InputFileType::kFileTypeNone: + return nullptr; + break; + default: + return nullptr; + break; + } + + if (driver::opts::maplePhase) { + isNeedAs = false; + } + + if (isNeedMapleComb) { + if (isMultipleFiles) { + newAction = std::make_unique(kBinNameMapleCombWrp, inputInfo, currentAction); + currentAction = std::move(newAction); + } else { + newAction = std::make_unique(kBinNameMapleComb, inputInfo, currentAction); + currentAction = std::move(newAction); + } + + tools.push_back(kBinNameMe); + tools.push_back(kBinNameMpl2mpl); + } + if (isNeedMplcg && !isMultipleFiles) { + tools.push_back(kBinNameMplcg); + newAction = std::make_unique(kBinNameMplcg, inputInfo, currentAction); + currentAction = std::move(newAction); + } + + if (isNeedAs == true) { + tools.push_back(kAsFlag); + newAction = std::make_unique(kAsFlag, inputInfo, currentAction); + currentAction = std::move(newAction); + } + + if (!driver::opts::compileWOLink) { + tools.push_back(kLdFlag); + /* "Linking step" Action can have several inputActions. + * Each inputAction links to previous Actions to create the action tree. + * For linking step, inputActions are all assembly actions. + * Linking step Action is created outside this function because + * we must create all assembly actions (for all input files) before. + */ + } + + return currentAction; +} + +InputInfo *MplDriver::AllocateInputInfo(const std::string &inputFile) { + auto inputInfo = std::make_unique(inputFile); + InputInfo *ret = inputInfo.get(); + + inputInfos.push_back(std::move(inputInfo)); + + /* inputInfo continue to exist in inputInfos vector of unique_ptr so we can return raw pointer */ + return ret; +} + +ErrorCode MplDriver::DecideRunningPhases() { + ErrorCode ret = kErrorNoError; + std::vector> linkActions; + std::unique_ptr lastAction; + + bool isMultipleFiles = (inputInfos.size() > 1); + + for (auto &inputInfo : inputInfos) { + CHECK_FATAL(inputInfo != nullptr, "InputInfo must be created!!"); + + lastAction = DecideRunningPhasesByType(inputInfo.get(), isMultipleFiles); + + /* TODO: Add a message interface for correct exit with compilation error. And use it here + * instead of CHECK_FATAL. + */ + CHECK_FATAL(lastAction != nullptr, "Incorrect input file type: %s", + inputInfo->GetInputFile().c_str()); + + if ((lastAction->GetTool() == kAsFlag && !driver::opts::compileWOLink) || + lastAction->GetTool() == kInputPhase) { + /* 1. For linking step, inputActions are all assembly actions; + * 2. If we try to link with maple driver, inputActions are all kInputPhase objects; + */ + linkActions.push_back(std::move(lastAction)); + } else { + rootActions.push_back(std::move(lastAction)); + } + } + + if (!linkActions.empty()) { + /* "a.out" is the default output file name - fix if it's needed */ + auto currentAction = std::make_unique(kLdFlag, linkActions, AllocateInputInfo("a.out")); + rootActions.push_back(std::move(currentAction)); + } + + return ret; +} + +ErrorCode MplDriver::MFCreateActionByExe(const std::string &exe, std::unique_ptr ¤tAction, + const InputInfo *const inputInfo, bool &wasWrpCombCompilerCreated) { + ErrorCode ret = kErrorNoError; + + if (exe == kBinNameMe || exe == kBinNameMpl2mpl || exe == kBinNameMplcg) { + if (wasWrpCombCompilerCreated == false) { + auto newAction = std::make_unique(kBinNameMapleCombWrp, inputInfo, currentAction); + currentAction = std::move(newAction); + wasWrpCombCompilerCreated = true; + } else { + return ret; + } + } + + else { + auto newAction = std::make_unique(exe, inputInfo, currentAction); + currentAction = std::move(newAction); + } + + return ret; +} + +ErrorCode MplDriver::SFCreateActionByExe(const std::string &exe, std::unique_ptr ¤tAction, + const InputInfo *const inputInfo, bool &isCombCompiler) { + ErrorCode ret = kErrorNoError; + + if (exe == kBinNameMe || exe == kBinNameMpl2mpl) { + if (isCombCompiler == false) { + auto newAction = std::make_unique(kBinNameMapleComb, inputInfo, currentAction); + currentAction = std::move(newAction); + isCombCompiler = true; + } else { + return ret; + } + } + + else { + auto newAction = std::make_unique(exe, inputInfo, currentAction); + currentAction = std::move(newAction); + } + + return ret; +} + +ErrorCode MplDriver::DecideRunningPhases(const std::vector &runExes) { + ErrorCode ret = kErrorNoError; + + bool isMultipleFiles = (inputInfos.size() > 1); + + for (auto &inputInfo : inputInfos) { + CHECK_FATAL(inputInfo != nullptr, "InputInfo must be created!!"); + /* MplOption is owner of all InputInfos. MplOption is alive during compilation, + * so we can use raw pointer inside an Action. + */ + const InputInfo *const rawInputInfo = inputInfo.get(); + + bool isCombCompiler = false; + bool wasWrpCombCompilerCreated = false; + + auto currentAction = std::make_unique(kInputPhase, inputInfo.get()); + + for (const auto &exe : runExes) { + if (isMultipleFiles == true) { + ret = MFCreateActionByExe(exe, currentAction, rawInputInfo, wasWrpCombCompilerCreated); + if (ret != kErrorNoError) { + return ret; + } + } else { + ret = SFCreateActionByExe(exe, currentAction, rawInputInfo, isCombCompiler); + if (ret != kErrorNoError) { + return ret; + } + } + } + + rootActions.push_back(std::move(currentAction)); + } + + return ret; +} + +ErrorCode MplDriver::HandleEarlyOptions() { + if (driver::opts::version) { + LogInfo::MapleLogger() << GetVersion() << "\n"; + return kErrorExitHelp; + } + + if (driver::opts::printDriverPhases) { + DumpActionTree(); + return kErrorExitHelp; + } + + if (driver::opts::help.IsEnabledByUser()) { + if (auto it = exeCategories.find(driver::opts::help.GetValue()); it != exeCategories.end()) { + cl::CommandLine::GetCommandLine().HelpPrinter(*it->second); + } else { + cl::CommandLine::GetCommandLine().HelpPrinter(); + } + return kErrorExitHelp; + } + + /* On and run should not appear at the same time */ + if (driver::opts::run.IsEnabledByUser() && + (driver::opts::o0.IsEnabledByUser() || + driver::opts::o1.IsEnabledByUser() || driver::opts::o2.IsEnabledByUser())) { + LogInfo::MapleLogger(kLlErr) << "Cannot set auto mode and run mode at the same time!\n"; + return kErrorInvalidParameter; + } + + if (driver::opts::run.IsEnabledByUser()) { + runMode = RunMode::kCustomRun; + UpdateTools(driver::opts::run); + } + + if (driver::opts::o0.IsEnabledByUser() || + driver::opts::o1.IsEnabledByUser() || + driver::opts::o2.IsEnabledByUser()) { + runMode = RunMode::kAutoRun; + } + + if (!driver::opts::optionOpt.GetValue().empty()) { + if (UpdateExeOptions(driver::opts::optionOpt) != kErrorNoError) { + return kErrorInvalidParameter; + } + } + + return kErrorNoError; +} + +void MplDriver::HandleExtraOptions() { + if (!driver::opts::clangOpt.GetValue().empty()) { + UpdateExeOptions(driver::opts::clangOpt, kBinNameClang); + } + + if (!driver::opts::hir2mplOpt.GetValue().empty()) { + UpdateExeOptions(driver::opts::hir2mplOpt, kBinNameCpp2mpl); + } + + if (!driver::opts::mpl2mplOpt.GetValue().empty()) { + UpdateExeOptions(driver::opts::mpl2mplOpt, kBinNameMpl2mpl); + } + + if (!driver::opts::meOpt.GetValue().empty()) { + UpdateExeOptions(driver::opts::meOpt, kBinNameMe); + } + + if (!driver::opts::mplcgOpt.GetValue().empty()) { + UpdateExeOptions(driver::opts::mplcgOpt, kBinNameMplcg); + } + + if (!driver::opts::asOpt.GetValue().empty()) { + UpdateExeOptions(driver::opts::asOpt, kAsFlag); + } + + if (!driver::opts::ldOpt.GetValue().empty()) { + UpdateExeOptions(driver::opts::ldOpt, kLdFlag); + } + + if (!driver::opts::dex2mplOpt.GetValue().empty()) { + UpdateExeOptions(driver::opts::dex2mplOpt, kBinNameDex2mpl); + } + + if (!driver::opts::jbc2mplOpt.GetValue().empty()) { + UpdateExeOptions(driver::opts::jbc2mplOpt, kBinNameJbc2mpl); + } + + if (!driver::opts::mplipaOpt.GetValue().empty()) { + UpdateExeOptions(driver::opts::mplipaOpt, kBinNameMplipa); + } +} + +ErrorCode MplDriver::HandleOptions() { + if (driver::opts::saveTempOpt.IsEnabledByUser()) { + driver::opts::genMeMpl.SetValue(true); + driver::opts::genVtable.SetValue(true); + StringUtils::Split(driver::opts::saveTempOpt, saveFiles, ','); + } + + if (!driver::opts::safeRegionOption) { + if (driver::opts::npeNoCheck) { + drvOptions.npeCheckMode = SafetyCheckMode::kNoCheck; + } + + if (driver::opts::npeStaticCheck) { + drvOptions.npeCheckMode = SafetyCheckMode::kStaticCheck; + } + + if (driver::opts::boundaryNoCheck) { + drvOptions.npeCheckMode = SafetyCheckMode::kNoCheck; + } + + if (driver::opts::boundaryStaticCheck) { + drvOptions.npeCheckMode = SafetyCheckMode::kStaticCheck; + } + } else { /* safeRegionOption is eanbled */ + drvOptions.npeCheckMode = SafetyCheckMode::kDynamicCheck; + drvOptions.boundaryCheckMode = SafetyCheckMode::kDynamicCheck; + } + + + if (driver::opts::npeDynamicCheck) { + drvOptions.npeCheckMode = SafetyCheckMode::kDynamicCheck; + } + + if (driver::opts::npeDynamicCheckSilent) { + drvOptions.npeCheckMode = SafetyCheckMode::kDynamicCheckSilent; + } + + if (driver::opts::boundaryDynamicCheck) { + drvOptions.boundaryCheckMode = SafetyCheckMode::kDynamicCheck; + } + + if (driver::opts::boundaryDynamicCheckSilent) { + drvOptions.boundaryCheckMode = SafetyCheckMode::kDynamicCheckSilent; + } + + HandleExtraOptions(); + + return kErrorNoError; +} + +ErrorCode MplDriver::Processing() { + ErrorCode ret = HandleEarlyOptions(); + if (ret != kErrorNoError) { + return ret; + } + + /* Check whether the input files were valid */ + if (!woinput) { + ret = CheckInputFiles(); + if (ret != kErrorNoError) { + return ret; + } + } + + // Decide runningExes for default options(O0, O2) by input files + if (runMode != RunMode::kCustomRun) { + ret = DecideRunningPhases(); + if (ret != kErrorNoError) { + return ret; + } + } else { // kCustomRun + /* kCustomRun run mode is set if --run=tool1:tool2 option is used. + * This Option is parsed on DecideRunType step. DecideRunType fills runningExes vector. + * DecideRunningPhases(runningExes) creates ActionsTree in kCustomRun mode. + * Maybe we can create Actions tree in DecideRunType in order to not use runningExes? + */ + ret = DecideRunningPhases(tools); + if (ret != kErrorNoError) { + return ret; + } + } + + ret = HandleOptions(); + if (ret != kErrorNoError) { + return ret; + } + + return kErrorNoError; +} + +int DriverProcessing(int argc, char **argv) { + cl::CommandLine::GetCommandLine().Parse(argc, argv); + MplDriver::GetMplDriver().Processing(); + + return 0; +} + +} // namespace maple -- Gitee From c0a774c2dbd5760a0fac16d4998ea4238c06089b Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Tue, 8 Mar 2022 11:56:19 +0300 Subject: [PATCH 14/24] [mapleall][driver] Implement unit tests for maple driver To compile unit tests: make mapleallUT To run unit tests: UTDriver --- BUILD.gn | 3 +- src/mapleall/maple_driver/BUILD.gn | 46 +++++---- src/mapleall/test/BUILD.gn | 43 ++++++-- src/mapleall/test/mpl_driver_ut_test.cpp | 126 +++++++++++++++++++++++ 4 files changed, 190 insertions(+), 28 deletions(-) create mode 100644 src/mapleall/test/mpl_driver_ut_test.cpp diff --git a/BUILD.gn b/BUILD.gn index 40e691379f..03ee5f1e10 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -41,7 +41,8 @@ group("ast2mpl") { group("mapleallUT") { deps = [ - "${MAPLEALL_ROOT}/test:mapleallUT", + "${MAPLEALL_ROOT}/test:UTDriver", + "${MAPLEALL_ROOT}/test:UTCL", ] } diff --git a/src/mapleall/maple_driver/BUILD.gn b/src/mapleall/maple_driver/BUILD.gn index b3a63ee5c2..fcace65d2b 100644 --- a/src/mapleall/maple_driver/BUILD.gn +++ b/src/mapleall/maple_driver/BUILD.gn @@ -39,6 +39,32 @@ include_directories = [ ] executable("maple") { + sources = [ "src/maple.cpp" ] + + include_dirs = include_directories + + deps = [ + ":libdriver", + ":libdriver_option", + ":liboption_parser", + "${MAPLEALL_ROOT}/maple_be:libcg", + "${MAPLEALL_ROOT}/maple_be:libmplad", + "${MAPLEALL_ROOT}/maple_be:libmplbe", + "${MAPLEALL_ROOT}/maple_ipa:libmplipa", + "${MAPLEALL_ROOT}/maple_ir:libmplir", + "${MAPLEALL_ROOT}/maple_me:libmplme", + "${MAPLEALL_ROOT}/maple_me:libmplmewpo", + "${MAPLEALL_ROOT}/maple_phase:libmplphase", + "${MAPLEALL_ROOT}/maple_phase:libmplphase", + "${MAPLEALL_ROOT}/maple_util:libmplutil", + "${MAPLEALL_ROOT}/maple_util:libcommandline", + "${MAPLEALL_ROOT}/mempool:libmempool", + "${MAPLEALL_ROOT}/mpl2mpl:libmpl2mpl", + "${THIRD_PARTY_ROOT}/bounds_checking_function:libHWSecureC", + ] +} + +static_library("libdriver") { sources = [ "src/as_compiler.cpp", "src/compiler.cpp", @@ -52,7 +78,6 @@ executable("maple") { "src/cpp2mpl_compiler.cpp", "src/clang_compiler.cpp", "src/ld_compiler.cpp", - "src/maple.cpp", "src/maple_driver.cpp", "src/maple_comb_compiler_wrapper.cpp", "src/maple_comb_compiler.cpp", @@ -62,24 +87,7 @@ executable("maple") { include_dirs = include_directories - deps = [ - ":libdriver_option", - ":liboption_parser", - "${MAPLEALL_ROOT}/maple_be:libcg", - "${MAPLEALL_ROOT}/maple_be:libmplad", - "${MAPLEALL_ROOT}/maple_be:libmplbe", - "${MAPLEALL_ROOT}/maple_ipa:libmplipa", - "${MAPLEALL_ROOT}/maple_ir:libmplir", - "${MAPLEALL_ROOT}/maple_me:libmplme", - "${MAPLEALL_ROOT}/maple_me:libmplmewpo", - "${MAPLEALL_ROOT}/maple_phase:libmplphase", - "${MAPLEALL_ROOT}/maple_phase:libmplphase", - "${MAPLEALL_ROOT}/maple_util:libmplutil", - "${MAPLEALL_ROOT}/maple_util:libcommandline", - "${MAPLEALL_ROOT}/mempool:libmempool", - "${MAPLEALL_ROOT}/mpl2mpl:libmpl2mpl", - "${THIRD_PARTY_ROOT}/bounds_checking_function:libHWSecureC", - ] + output_dir = "${root_out_dir}/lib/${HOST_ARCH}" } static_library("libdriver_option") { diff --git a/src/mapleall/test/BUILD.gn b/src/mapleall/test/BUILD.gn index 5552b9fc28..c76eca762b 100644 --- a/src/mapleall/test/BUILD.gn +++ b/src/mapleall/test/BUILD.gn @@ -18,15 +18,13 @@ cflags_cc -= [ "-Werror", ] -include_directories = [ - "${MAPLE_ROOT}/tools/gtest_lib/include", - "${MAPLEALL_ROOT}/maple_util/include", -] -src_mapleallUT = [ "cl_ut_test.cpp" ] +executable("UTCL") { + sources = [ "cl_ut_test.cpp" ] + include_dirs = [ + "${MAPLE_ROOT}/tools/gtest_lib/include", + "${MAPLEALL_ROOT}/maple_util/include", + ] -executable("mapleallUT") { - sources = src_mapleallUT - include_dirs = include_directories output_dir = "${root_out_dir}/lib/${HOST_ARCH}" deps = [ @@ -44,3 +42,32 @@ executable("mapleallUT") { ] } +executable("UTDriver") { + sources = [ "mpl_driver_ut_test.cpp" ] + include_dirs = [ + "${MAPLE_ROOT}/tools/gtest_lib/include", + "${MAPLEALL_ROOT}/maple_util/include", + "${MAPLEALL_ROOT}/maple_driver/include", + "${MAPLEALL_ROOT}/maple_ir/include", + "${MAPLEALL_ROOT}/mempool/include", + "${THIRD_PARTY_ROOT}/bounds_checking_function/include" + ] + + output_dir = "${root_out_dir}/lib/${HOST_ARCH}" + + deps = [ + "${MAPLEALL_ROOT}/maple_util:libmplutil", + "${MAPLEALL_ROOT}/maple_util:libcommandline", + "${MAPLEALL_ROOT}/maple_driver:libdriver", + "${MAPLEALL_ROOT}/maple_driver:libdriver_option", + "${THIRD_PARTY_ROOT}/bounds_checking_function:libHWSecureC", + ] + + libs = [ + "${MAPLE_ROOT}/tools/gtest_lib/lib/libgmock.a", + "${MAPLE_ROOT}/tools/gtest_lib/lib/libgmock_main.a", + "${MAPLE_ROOT}/tools/gtest_lib/lib/libgtest.a", + "${MAPLE_ROOT}/tools/gtest_lib/lib/libgtest_main.a", + "pthread", + ] +} diff --git a/src/mapleall/test/mpl_driver_ut_test.cpp b/src/mapleall/test/mpl_driver_ut_test.cpp new file mode 100644 index 0000000000..5b226b76f9 --- /dev/null +++ b/src/mapleall/test/mpl_driver_ut_test.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) [2022] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "error_code.h" +#include "maple_driver.h" +#include "driver_options.h" + +#include "gtest/gtest.h" + +TEST(MplDriver, OptForwarding1) { + // create command line + const char *argv[] = { + "maple", // program name + "--woinput", + "--clang-opt=-opt1 -opt2 -opt3", + "--hir2mpl-opt=-hir2mpl", + "--mpl2mpl-opt=-mpl2mpl", + "--me-opt=-me", + "--mplcg-opt=-mplcg", + "--as-opt=-as", + "--ld-opt=-ld", + "--dex2mpl-opt=-dex", + "--jbc2mpl-opt=-jbc", + "--mplipa-opt=-ipa", + nullptr}; + int argc = (sizeof(argv) / sizeof(argv[0])) - 1; + + auto err = cl::CommandLine::GetCommandLine().Parse(argc, (char **)argv); + ASSERT_EQ(err, cl::RetCode::noError); + + auto &drv = maple::MplDriver::GetMplDriver(); + auto drvErr = drv.Processing(); + ASSERT_EQ(drvErr, maple::kErrorNoError); + + auto &exeOptions = drv.GetExeOptions(); + ASSERT_EQ(1, exeOptions.count(maple::kBinNameClang)); + ASSERT_EQ(3, exeOptions[maple::kBinNameClang].size()); + ASSERT_EQ("-opt1", exeOptions[maple::kBinNameClang][0]); + ASSERT_EQ("-opt2", exeOptions[maple::kBinNameClang][1]); + ASSERT_EQ("-opt3", exeOptions[maple::kBinNameClang][2]); + + ASSERT_EQ(1, exeOptions.count(maple::kBinNameCpp2mpl)); + ASSERT_EQ(1, exeOptions[maple::kBinNameCpp2mpl].size()); + ASSERT_EQ("-hir2mpl", exeOptions[maple::kBinNameCpp2mpl][0]); + + ASSERT_EQ(1, exeOptions.count(maple::kBinNameMpl2mpl)); + ASSERT_EQ(1, exeOptions[maple::kBinNameMpl2mpl].size()); + ASSERT_EQ("-mpl2mpl", exeOptions[maple::kBinNameMpl2mpl][0]); + + ASSERT_EQ(1, exeOptions.count(maple::kBinNameMe)); + ASSERT_EQ(1, exeOptions[maple::kBinNameMe].size()); + ASSERT_EQ("-me", exeOptions[maple::kBinNameMe][0]); + + ASSERT_EQ(1, exeOptions.count(maple::kBinNameMplcg)); + ASSERT_EQ(1, exeOptions[maple::kBinNameMplcg].size()); + ASSERT_EQ("-mplcg", exeOptions[maple::kBinNameMplcg][0]); + + ASSERT_EQ(1, exeOptions.count(maple::kAsFlag)); + ASSERT_EQ(1, exeOptions[maple::kAsFlag].size()); + ASSERT_EQ("-as", exeOptions[maple::kAsFlag][0]); + + ASSERT_EQ(1, exeOptions.count(maple::kLdFlag)); + ASSERT_EQ(1, exeOptions[maple::kLdFlag].size()); + ASSERT_EQ("-ld", exeOptions[maple::kLdFlag][0]); + + ASSERT_EQ(1, exeOptions.count(maple::kBinNameDex2mpl)); + ASSERT_EQ(1, exeOptions[maple::kBinNameDex2mpl].size()); + ASSERT_EQ("-dex", exeOptions[maple::kBinNameDex2mpl][0]); + + ASSERT_EQ(1, exeOptions.count(maple::kBinNameJbc2mpl)); + ASSERT_EQ(1, exeOptions[maple::kBinNameJbc2mpl].size()); + ASSERT_EQ("-jbc", exeOptions[maple::kBinNameJbc2mpl][0]); + + ASSERT_EQ(1, exeOptions.count(maple::kBinNameMplipa)); + ASSERT_EQ(1, exeOptions[maple::kBinNameMplipa].size()); + ASSERT_EQ("-ipa", exeOptions[maple::kBinNameMplipa][0]); +} + +TEST(MplDriver, OptForwarding2) { + // create command line + const char *argv[] = { + "maple", // program name + "--woinput", + "--run=clang:hir2mpl:me", + "--option=-opt1 -opt2 -opt3:-opt4 -opt5 : -opt6", + nullptr}; + int argc = (sizeof(argv) / sizeof(argv[0])) - 1; + + cl::CommandLine::GetCommandLine().Clear(); // to clear previous test data + auto err = cl::CommandLine::GetCommandLine().Parse(argc, (char **)argv); + ASSERT_EQ(err, cl::RetCode::noError); + + auto &drv = maple::MplDriver::GetMplDriver(); + auto &exeOptions = drv.GetExeOptions(); + exeOptions.clear(); // to clear previous test data + + auto drvErr = drv.Processing(); + ASSERT_EQ(drvErr, maple::kErrorNoError); + + ASSERT_EQ(1, exeOptions.count(maple::kBinNameClang)); + ASSERT_EQ(3, exeOptions[maple::kBinNameClang].size()); + ASSERT_EQ("-opt1", exeOptions[maple::kBinNameClang][0]); + ASSERT_EQ("-opt2", exeOptions[maple::kBinNameClang][1]); + ASSERT_EQ("-opt3", exeOptions[maple::kBinNameClang][2]); + + ASSERT_EQ(1, exeOptions.count(maple::kBinNameCpp2mpl)); + ASSERT_EQ(2, exeOptions[maple::kBinNameCpp2mpl].size()); + ASSERT_EQ("-opt4", exeOptions[maple::kBinNameCpp2mpl][0]); + ASSERT_EQ("-opt5", exeOptions[maple::kBinNameCpp2mpl][1]); + + ASSERT_EQ(1, exeOptions.count(maple::kBinNameMe)); + ASSERT_EQ(1, exeOptions[maple::kBinNameMe].size()); + ASSERT_EQ("-opt6", exeOptions[maple::kBinNameMe][0]); +} -- Gitee From 93f87aa68b3c340b1109e76e10fea628f11c0181 Mon Sep 17 00:00:00 2001 From: Alex Antonov Date: Sat, 26 Mar 2022 18:12:55 +0300 Subject: [PATCH 15/24] [mapleall] Refactor driver to use MplDriver instead of MplOptions --- src/mapleall/maple_driver/BUILD.gn | 1 - src/mapleall/maple_driver/include/compiler.h | 144 +++--- .../maple_driver/include/compiler_factory.h | 9 +- .../maple_driver/include/compiler_selector.h | 8 +- .../maple_driver/include/driver_runner.h | 15 +- .../maple_driver/include/maple_driver.h | 247 +++++++++- .../maple_driver/include/mpl_options.h | 424 +----------------- src/mapleall/maple_driver/src/as_compiler.cpp | 19 +- .../maple_driver/src/clang_compiler.cpp | 18 +- src/mapleall/maple_driver/src/compiler.cpp | 105 +++-- .../maple_driver/src/compiler_factory.cpp | 43 +- .../maple_driver/src/compiler_selector.cpp | 25 +- .../maple_driver/src/cpp2mpl_compiler.cpp | 20 +- .../maple_driver/src/dex2mpl_compiler.cpp | 205 +-------- .../maple_driver/src/ipa_compiler.cpp | 9 +- .../maple_driver/src/jbc2mpl_compiler.cpp | 7 +- src/mapleall/maple_driver/src/ld_compiler.cpp | 15 +- src/mapleall/maple_driver/src/maple.cpp | 141 ++++++ .../maple_driver/src/maple_comb_compiler.cpp | 278 ++++++++---- .../src/maple_comb_compiler_wrapper.cpp | 62 +-- .../maple_driver/src/maple_driver.cpp | 188 +++++--- .../maple_driver/src/mplcg_compiler.cpp | 169 ++++--- 22 files changed, 1044 insertions(+), 1108 deletions(-) diff --git a/src/mapleall/maple_driver/BUILD.gn b/src/mapleall/maple_driver/BUILD.gn index fcace65d2b..28b9e6d113 100644 --- a/src/mapleall/maple_driver/BUILD.gn +++ b/src/mapleall/maple_driver/BUILD.gn @@ -81,7 +81,6 @@ static_library("libdriver") { "src/maple_driver.cpp", "src/maple_comb_compiler_wrapper.cpp", "src/maple_comb_compiler.cpp", - "src/mpl_options.cpp", "src/mplcg_compiler.cpp", ] diff --git a/src/mapleall/maple_driver/include/compiler.h b/src/mapleall/maple_driver/include/compiler.h index 599a486d2f..28ceda66c6 100644 --- a/src/mapleall/maple_driver/include/compiler.h +++ b/src/mapleall/maple_driver/include/compiler.h @@ -15,6 +15,7 @@ #ifndef MAPLE_DRIVER_INCLUDE_COMPILER_H #define MAPLE_DRIVER_INCLUDE_COMPILER_H #include +#include #include #include "error_code.h" #include "mpl_options.h" @@ -38,20 +39,20 @@ class Compiler { virtual ~Compiler() = default; - virtual ErrorCode Compile(MplOptions &options, const Action &action, + virtual ErrorCode Compile(const Action &action, std::unique_ptr &theModule); - virtual void GetTmpFilesToDelete(const MplOptions&, const Action&, + virtual void GetTmpFilesToDelete(const Action&, std::vector&) const {} - virtual std::unordered_set GetFinalOutputs(const MplOptions&, const Action&) const { + virtual std::unordered_set GetFinalOutputs(const Action&) const { return std::unordered_set(); } - virtual void PrintCommand(const MplOptions&, const Action&) const {} + virtual void PrintCommand(const Action&) const {} protected: - virtual std::string GetBinPath(const MplOptions &mplOptions) const; + virtual std::string GetBinPath() const; virtual const std::string &GetBinName() const { return kBinNameNone; } @@ -63,30 +64,32 @@ class Compiler { return GetBinName(); } - virtual std::string GetInputFileName(const MplOptions&, const Action &action) const { + virtual std::string GetInputFileName(const Action &action) const { return action.GetInputFile(); } - virtual DefaultOption GetDefaultOptions(const MplOptions&, const Action&) const { + virtual DefaultOption GetDefaultOptions(const Action&) const { return DefaultOption(); } + virtual void AppendOutputOption(std::vector &, const std::string &) const { + return; + } + private: const std::string name; - std::vector MakeOption(const MplOptions &options, - const Action &action) const; + std::vector MakeOption(const Action &action) const; void AppendDefaultOptions(std::vector &finalOptions, const std::vector &defaultOptions, bool isDebug) const; void AppendExtraOptions(std::vector &finalOptions, - const MplOptions &options, bool isDebug) const; + bool isDebug, const Action &action) const; void AppendInputsAsOptions(std::vector &finalOptions, - const MplOptions &mplOptions, const Action &action) const; + const Action &action) const; void ReplaceOrInsertOption(std::vector &finalOptions, const std::string &key, const std::string &value) const; - std::vector MakeDefaultOptions(const MplOptions &options, - const Action &action) const; - int Exe(const MplOptions &mplOptions, const std::vector &options) const; + std::vector MakeDefaultOptions(const Action &action) const; + int Exe(const std::vector &options) const; const std::string &GetName() const { return name; } @@ -100,11 +103,10 @@ class Jbc2MplCompiler : public Compiler { private: const std::string &GetBinName() const override; - DefaultOption GetDefaultOptions(const MplOptions &options, const Action &action) const override; - void GetTmpFilesToDelete(const MplOptions &mplOptions, const Action &action, + DefaultOption GetDefaultOptions(const Action &action) const override; + void GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const override; - std::unordered_set GetFinalOutputs(const MplOptions &mplOptions, - const Action &action) const override; + std::unordered_set GetFinalOutputs(const Action &action) const override; }; class ClangCompiler : public Compiler { @@ -115,12 +117,12 @@ class ClangCompiler : public Compiler { private: const std::string &GetBinName() const override; - std::string GetBinPath(const MplOptions &options) const override; - DefaultOption GetDefaultOptions(const MplOptions &options, const Action &action) const override; - void GetTmpFilesToDelete(const MplOptions &mplOptions, const Action &action, + std::string GetBinPath() const override; + DefaultOption GetDefaultOptions(const Action &action) const override; + void GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const override; - std::unordered_set GetFinalOutputs(const MplOptions &mplOptions, - const Action &action) const override ; + std::unordered_set GetFinalOutputs(const Action &action) const override; + void AppendOutputOption(std::vector &finalOptions, const std::string &name) const override; }; class Cpp2MplCompiler : public Compiler { @@ -130,14 +132,14 @@ class Cpp2MplCompiler : public Compiler { ~Cpp2MplCompiler() = default; private: - std::string GetBinPath(const MplOptions &options) const override; + std::string GetBinPath() const override; const std::string &GetBinName() const override; - std::string GetInputFileName(const MplOptions &options, const Action &action) const override; - DefaultOption GetDefaultOptions(const MplOptions &options, const Action &action) const override; - void GetTmpFilesToDelete(const MplOptions &mplOptions, const Action &action, + std::string GetInputFileName(const Action &action) const override; + DefaultOption GetDefaultOptions(const Action &action) const override; + void GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const override; - std::unordered_set GetFinalOutputs(const MplOptions &mplOptions, - const Action &action) const override; + std::unordered_set GetFinalOutputs(const Action &action) const override; + void AppendOutputOption(std::vector &finalOptions, const std::string &name) const override; }; class Dex2MplCompiler : public Compiler { @@ -145,24 +147,14 @@ class Dex2MplCompiler : public Compiler { explicit Dex2MplCompiler(const std::string &name) : Compiler(name) {} ~Dex2MplCompiler() = default; -#ifdef INTERGRATE_DRIVER - ErrorCode Compile(MplOptions &options, const Action &action, - std::unique_ptr &theModule) override; -#endif - - void PrintCommand(const MplOptions &options, const Action &action) const override; + void PrintCommand(const Action &action) const override; private: const std::string &GetBinName() const override; - DefaultOption GetDefaultOptions(const MplOptions &options, const Action &action) const override; - void GetTmpFilesToDelete(const MplOptions &mplOptions, const Action &action, + DefaultOption GetDefaultOptions(const Action &action) const override; + void GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const override; - std::unordered_set GetFinalOutputs(const MplOptions &mplOptions, - const Action &action) const override; -#ifdef INTERGRATE_DRIVER - void PostDex2Mpl(std::unique_ptr &theModule) const; - bool MakeDex2mplOptions(const MplOptions &options); -#endif + std::unordered_set GetFinalOutputs(const Action &action) const override; }; class IpaCompiler : public Compiler { @@ -173,8 +165,8 @@ class IpaCompiler : public Compiler { private: const std::string &GetBinName() const override; - DefaultOption GetDefaultOptions(const MplOptions &options, const Action &action) const override; - std::string GetInputFileName(const MplOptions &options, const Action &action) const override; + DefaultOption GetDefaultOptions(const Action &action) const override; + std::string GetInputFileName(const Action &action) const override; }; class MapleCombCompiler : public Compiler { @@ -183,19 +175,19 @@ class MapleCombCompiler : public Compiler { ~MapleCombCompiler() = default; - ErrorCode Compile(MplOptions &options, const Action &action, + ErrorCode Compile(const Action &action, std::unique_ptr &theModule) override; - void PrintCommand(const MplOptions &options, const Action &action) const override; - std::string GetInputFileName(const MplOptions &options, const Action &action) const override; + void PrintCommand(const Action &action) const override; + std::string GetInputFileName(const Action &action) const override; private: - std::unordered_set GetFinalOutputs(const MplOptions &mplOptions, - const Action &action) const override; - void GetTmpFilesToDelete(const MplOptions &mplOptions, const Action &action, + std::unordered_set GetFinalOutputs(const Action &action) const override; + void GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const override; - ErrorCode MakeMeOptions(const MplOptions &options, DriverRunner &runner); - ErrorCode MakeMpl2MplOptions(const MplOptions &options, DriverRunner &runner); - std::string DecideOutExe(const MplOptions &options); + const std::string &DecideOutExe() const; + ErrorCode AppendCombOptions(MIRSrcLang srcLang); + ErrorCode MakeMeOptions(DriverRunner &runner); + ErrorCode MakeMpl2MplOptions(DriverRunner &runner); }; class MplcgCompiler : public Compiler { @@ -203,15 +195,15 @@ class MplcgCompiler : public Compiler { explicit MplcgCompiler(const std::string &name) : Compiler(name) {} ~MplcgCompiler() = default; - ErrorCode Compile(MplOptions &options, const Action &action, + ErrorCode Compile(const Action &action, std::unique_ptr &theModule) override; - void PrintMplcgCommand(const MplOptions &options, const Action &action, const MIRModule &md) const; - void SetOutputFileName(const MplOptions &options, const Action &action, const MIRModule &md); - std::string GetInputFile(const MplOptions &options, const Action &action, const MIRModule *md) const; + void PrintMplcgCommand(const Action &action, const MIRModule &md) const; + void SetOutputFileName(const Action &action, const MIRModule &md); + std::string GetInputFile(const Action &action, const MIRModule *md) const; private: - DefaultOption GetDefaultOptions(const MplOptions &options, const Action &action) const override; - ErrorCode GetMplcgOptions(MplOptions &options, const Action &action, const MIRModule *theModule); - ErrorCode MakeCGOptions(const MplOptions &options); + ErrorCode GetMplcgOptions(const Action &action, const MIRModule *theModule); + ErrorCode AppendMplcgOptions(MIRSrcLang srcLang); + ErrorCode MakeCGOptions(); const std::string &GetBinName() const override; std::string baseName; std::string outputFile; @@ -222,16 +214,15 @@ class MapleCombCompilerWrp : public Compiler { explicit MapleCombCompilerWrp(const std::string &name) : Compiler(name) {} ~MapleCombCompilerWrp() = default; - std::string GetInputFileName(const MplOptions &options, const Action &action) const override; + std::string GetInputFileName(const Action &action) const override; private: - std::string GetBinPath(const MplOptions &options) const override; + std::string GetBinPath() const override; const std::string &GetBinName() const override; - DefaultOption GetDefaultOptions(const MplOptions &options, const Action &action) const override; - void GetTmpFilesToDelete(const MplOptions &mplOptions, const Action &action, + DefaultOption GetDefaultOptions(const Action &action) const override; + void GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const override; - std::unordered_set GetFinalOutputs(const MplOptions &mplOptions, - const Action &action) const override; + std::unordered_set GetFinalOutputs(const Action &action) const override; }; // Build .s to .o @@ -242,15 +233,15 @@ class AsCompiler : public Compiler { ~AsCompiler() = default; private: - std::string GetBinPath(const MplOptions &options) const override; + std::string GetBinPath() const override; const std::string &GetBinName() const override; const std::string &GetTool() const override; - DefaultOption GetDefaultOptions(const MplOptions &options, const Action &action) const override; - std::string GetInputFileName(const MplOptions &options, const Action &action) const override; - void GetTmpFilesToDelete(const MplOptions &mplOptions, const Action &action, + DefaultOption GetDefaultOptions(const Action &action) const override; + std::string GetInputFileName(const Action &action) const override; + void GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const override; - std::unordered_set GetFinalOutputs(const MplOptions &mplOptions, - const Action &action) const override; + std::unordered_set GetFinalOutputs(const Action &action) const override; + void AppendOutputOption(std::vector &finalOptions, const std::string &name) const override; }; // Build .o to .so @@ -261,11 +252,12 @@ class LdCompiler : public Compiler { ~LdCompiler() = default; private: - std::string GetBinPath(const MplOptions &options) const override; + std::string GetBinPath() const override; const std::string &GetBinName() const override; const std::string &GetTool() const override; - DefaultOption GetDefaultOptions(const MplOptions &options, const Action &action) const override; - std::string GetInputFileName(const MplOptions &options, const Action &action) const override; + DefaultOption GetDefaultOptions(const Action &action) const override; + std::string GetInputFileName(const Action &action) const override; + void AppendOutputOption(std::vector &finalOptions, const std::string &name) const override; }; } // namespace maple #endif // MAPLE_DRIVER_INCLUDE_COMPILER_H diff --git a/src/mapleall/maple_driver/include/compiler_factory.h b/src/mapleall/maple_driver/include/compiler_factory.h index 1b5118ff5d..85eb4c80b5 100644 --- a/src/mapleall/maple_driver/include/compiler_factory.h +++ b/src/mapleall/maple_driver/include/compiler_factory.h @@ -30,14 +30,17 @@ class CompilerFactory { CompilerFactory &operator=(const CompilerFactory&) = delete; CompilerFactory &operator=(CompilerFactory&&) = delete; ~CompilerFactory(); - ErrorCode Compile(MplOptions &mplOptions); + + ErrorCode Compile(const MplDriver::RootActionsType &rootActions); + ErrorCode DeleteTmpFiles(const std::vector &tempFiles, + const std::vector &saveFiles, + const std::vector &inputFiles, + const MplDriver::RootActionsType &actions) const; private: bool compileFinished = false; CompilerFactory(); void Insert(const std::string &name, Compiler *value); - ErrorCode DeleteTmpFiles(const MplOptions &mplOptions, - const std::vector &tempFiles) const; SupportedCompilers supportedCompilers; CompilerSelector *compilerSelector; std::unique_ptr theModule; diff --git a/src/mapleall/maple_driver/include/compiler_selector.h b/src/mapleall/maple_driver/include/compiler_selector.h index fa599313f3..d35348dd79 100644 --- a/src/mapleall/maple_driver/include/compiler_selector.h +++ b/src/mapleall/maple_driver/include/compiler_selector.h @@ -27,7 +27,7 @@ class CompilerSelector { virtual ~CompilerSelector() = default; - virtual ErrorCode Select(const SupportedCompilers&, const MplOptions&, + virtual ErrorCode Select(const SupportedCompilers&, const MplDriver::RootActionsType&, std::vector&) const { return kErrorToolNotFound; } @@ -39,14 +39,12 @@ class CompilerSelectorImpl : public CompilerSelector { ~CompilerSelectorImpl() = default; - ErrorCode Select(const SupportedCompilers &supportedCompilers, const MplOptions &mplOptions, + ErrorCode Select(const SupportedCompilers &supportedCompilers, const MplDriver::RootActionsType&, std::vector &selectedActions) const override; private: Compiler *FindCompiler(const SupportedCompilers &compilers, const std::string &name) const; - ErrorCode InsertCompilerIfNeeded(std::vector &selected, const SupportedCompilers &compilers, - const std::string &name) const; - ErrorCode Select(const SupportedCompilers &supportedCompilers, const MplOptions &mplOptions, + ErrorCode Select(const SupportedCompilers &supportedCompilers, Action &action, std::vector &selectedActions) const; }; } // namespace maple diff --git a/src/mapleall/maple_driver/include/driver_runner.h b/src/mapleall/maple_driver/include/driver_runner.h index ca245d1e22..5412891765 100644 --- a/src/mapleall/maple_driver/include/driver_runner.h +++ b/src/mapleall/maple_driver/include/driver_runner.h @@ -15,16 +15,19 @@ #ifndef MAPLE_DRIVER_INCLUDE_DRIVER_RUNNER_H #define MAPLE_DRIVER_INCLUDE_DRIVER_RUNNER_H -#include -#include -#include -#include "me_option.h" -#include "module_phase_manager.h" -#include "error_code.h" #include "cg.h" #include "cg_option.h" #include "cg_phasemanager.h" +#include "error_code.h" +#include "maple_driver.h" #include "maple_phase_manager.h" +#include "me_option.h" +#include "module_phase_manager.h" + +#include +#include +#include + namespace maple { using namespace maplebe; diff --git a/src/mapleall/maple_driver/include/maple_driver.h b/src/mapleall/maple_driver/include/maple_driver.h index 8306c0c3fe..659a68ae63 100644 --- a/src/mapleall/maple_driver/include/maple_driver.h +++ b/src/mapleall/maple_driver/include/maple_driver.h @@ -17,12 +17,17 @@ #include "cl_parser.h" #include "error_code.h" +#include "file_utils.h" #include "mpl_options.h" #include "version.h" #include #include +std::string GetCommonOptionsStr(const std::vector &exclude); +extern const std::vector extraExclude; +extern const std::vector printExclude; + namespace maple { extern const std::string kBinNameNone; @@ -49,15 +54,220 @@ extern const std::string kBinNameAs; extern const std::string kBinNameGcc; extern const std::string kBinNameGpp; +enum InputFileType { + kFileTypeNone, + kFileTypeClass, + kFileTypeJar, + kFileTypeAst, + kFileTypeCpp, + kFileTypeC, + kFileTypeDex, + kFileTypeMpl, + kFileTypeVtableImplMpl, + kFileTypeS, + kFileTypeObj, + kFileTypeBpl, + kFileTypeMeMpl, + kFileTypeMbc, + kFileTypeLmbc, +}; + +enum RunMode { + kAutoRun, + kCustomRun, + kUnkownRun +}; + struct DrvOptions { SafetyCheckMode npeCheckMode = SafetyCheckMode::kNoCheck; SafetyCheckMode boundaryCheckMode = SafetyCheckMode::kNoCheck; + bool generalRegOnly = false; }; -class MplDriver { -using ExeOptMapType = std::unordered_map>; +class Compiler; + +class InputInfo { +public: + explicit InputInfo(const std::string &inputFile) + : inputFile(inputFile) { + inputFileType = GetInputFileType(inputFile); + + inputName = FileUtils::GetFileName(inputFile, true); + inputFolder = FileUtils::GetFileFolder(inputFile); + outputFolder = inputFolder; + outputName = FileUtils::GetFileName(inputFile, false); + fullOutput = outputFolder + outputName; + } + + ~InputInfo() = default; + static InputFileType GetInputFileType(const std::string &inputFile) { + InputFileType fileType = InputFileType::kFileTypeNone; + std::string extensionName = FileUtils::GetFileExtension(inputFile); + if (extensionName == "class") { + fileType = InputFileType::kFileTypeClass; + } + else if (extensionName == "dex") { + fileType = InputFileType::kFileTypeDex; + } + else if (extensionName == "c") { + fileType = InputFileType::kFileTypeC; + } + else if (extensionName == "cpp") { + fileType = InputFileType::kFileTypeCpp; + } + else if (extensionName == "ast") { + fileType = InputFileType::kFileTypeAst; + } + else if (extensionName == "jar") { + fileType = InputFileType::kFileTypeJar; + } + else if (extensionName == "mpl" || extensionName == "bpl") { + if (inputFile.find("VtableImpl") == std::string::npos) { + if (inputFile.find(".me.mpl") != std::string::npos) { + fileType = InputFileType::kFileTypeMeMpl; + } else { + fileType = extensionName == "mpl" ? InputFileType::kFileTypeMpl : InputFileType::kFileTypeBpl; + } + } else { + fileType = InputFileType::kFileTypeVtableImplMpl; + } + } else if (extensionName == "s") { + fileType = InputFileType::kFileTypeS; + } else if (extensionName == "o") { + fileType = InputFileType::kFileTypeObj; + } else if (extensionName == "mbc") { + fileType = InputFileType::kFileTypeMbc; + } else if (extensionName == "lmbc") { + fileType = InputFileType::kFileTypeLmbc; + } + + return fileType; + } + + InputFileType GetInputFileType() const { + return inputFileType; + } + + const std::string &GetInputFile() const { + return inputFile; + } + + const std::string &GetOutputFolder() const { + return outputFolder; + } + + const std::string &GetOutputName() const { + return outputName; + } + + const std::string &GetFullOutputName() const { + return fullOutput; + } + +private: + std::string inputFile = ""; + InputFileType inputFileType = InputFileType::kFileTypeNone; + + std::string inputName = ""; + std::string inputFolder = ""; + std::string outputName = ""; + std::string outputFolder = ""; + std::string fullOutput = ""; +}; + +class Action { +public: + Action(const std::string &tool, const InputInfo *const inputInfo) + : inputInfo(inputInfo), tool(tool) {} + + Action(const std::string &tool, const InputInfo *const inputInfo, + std::unique_ptr &inAction) + : inputInfo(inputInfo), tool(tool) { + inputActions.push_back(std::move(inAction)); + } + + Action(const std::string &tool, std::vector> &inActions, + const InputInfo *const inputInfo) + : inputInfo(inputInfo), tool(tool) { + for (auto &inAction : inActions) { + linkInputFiles.push_back(inAction->GetInputFile()); + } + + std::move(begin(inActions), end(inActions), std::back_inserter(inputActions)); + } + + ~Action() = default; + + const std::string &GetTool() const { + return tool; + } + + const std::string &GetInputFile() const { + return inputInfo->GetInputFile(); + } + + const std::string &GetOutputFolder() const { + return inputInfo->GetOutputFolder(); + } + const std::string &GetOutputName() const { + return inputInfo->GetOutputName(); + } + + const std::string &GetFullOutputName() const { + return inputInfo->GetFullOutputName(); + } + + InputFileType GetInputFileType() const { + return inputInfo->GetInputFileType(); + } + + const std::vector &GetLinkFiles() const { + return linkInputFiles; + } + + const std::vector> &GetInputActions() const { + return inputActions; + } + + Compiler *GetCompiler() const { + return compilerTool; + } + + void SetCompiler(Compiler *compiler) { + compilerTool = compiler; + } + + bool IsItFirstRealAction() const { + /* First action is always "Input". + * But first real action will be a tool from kMapleCompilers. + */ + if (inputActions.size() > 0 && inputActions[0]->tool == "input") { + return true; + } + return false; + } + + std::vector internalTools; + +private: + const InputInfo *inputInfo; + + std::string tool = ""; + std::string exeFolder = ""; + std::vector linkInputFiles; + + Compiler *compilerTool = nullptr; + + /* This vector contains a links to previous actions in Action tree */ + std::vector> inputActions; +}; + +class MplDriver { public: + using ExeOptMapType = std::unordered_map>; + using RootActionsType = std::vector>; + /* singleton */ static MplDriver &GetMplDriver(); @@ -66,6 +276,9 @@ using ExeOptMapType = std::unordered_map>; MplDriver &operator=(const MplDriver &) = delete; ErrorCode Processing(); + cl::OptionCategory *GetCategory(const std::string &tool) const; + ErrorCode UpdateExeOptions(const std::string &exeName, + MplOption mplOptions[], unsigned int length); std::string GetVersion() { #ifdef ANDROID @@ -82,6 +295,30 @@ using ExeOptMapType = std::unordered_map>; return exeOptions; } + const std::string &GetExeFolder() const { + return exeFolder; + } + + const RootActionsType &GetActions() const { + return rootActions; + } + + RunMode GetRunMode() const { + return runMode; + } + + const std::vector &GetTools() const { + return tools; + } + + const std::vector &GetInputFiles() const { + return inputFiles; + } + + const std::vector &GetSaveFiles() const { + return saveFiles; + } + DrvOptions drvOptions; private: @@ -106,7 +343,7 @@ using ExeOptMapType = std::unordered_map>; ErrorCode UpdateExeOptions(const std::string &args); InputInfo *AllocateInputInfo(const std::string &inputFile); - RunMode runMode = RunMode::kAutoRun; + RunMode runMode = RunMode::kUnkownRun; std::vector inputFiles; std::string exeFolder; @@ -124,11 +361,9 @@ using ExeOptMapType = std::unordered_map>; std::vector saveFiles; std::vector> inputInfos; - std::vector> rootActions; + RootActionsType rootActions; }; -int DriverProcessing(int argc, char **argv); - } // namespace maple #endif // MAPLE_DRIVER_INCLUDE_MPL_OPTIONS_H diff --git a/src/mapleall/maple_driver/include/mpl_options.h b/src/mapleall/maple_driver/include/mpl_options.h index e0bcb3cf62..8a8dbbc4f4 100644 --- a/src/mapleall/maple_driver/include/mpl_options.h +++ b/src/mapleall/maple_driver/include/mpl_options.h @@ -14,53 +14,12 @@ */ #ifndef MAPLE_DRIVER_INCLUDE_MPL_OPTIONS_H #define MAPLE_DRIVER_INCLUDE_MPL_OPTIONS_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "file_utils.h" -#include "option_parser.h" #include "mpl_logging.h" -#include "mir_module.h" - -namespace maple { -enum InputFileType { - kFileTypeNone, - kFileTypeClass, - kFileTypeJar, - kFileTypeAst, - kFileTypeCpp, - kFileTypeC, - kFileTypeDex, - kFileTypeMpl, - kFileTypeVtableImplMpl, - kFileTypeS, - kFileTypeObj, - kFileTypeBpl, - kFileTypeMeMpl, - kFileTypeMbc, - kFileTypeLmbc, -}; -enum OptimizationLevel { - kO0, - kO1, - kO2, - kCLangO0, - kCLangO2, -}; +#include +#include -enum RunMode { - kAutoRun, - kCustomRun, - kUnkownRun -}; +namespace maple { enum SafetyCheckMode { kNoCheck, @@ -69,183 +28,6 @@ enum SafetyCheckMode { kDynamicCheckSilent }; -class Compiler; - -class InputInfo { -public: - explicit InputInfo(const std::string &inputFile) - : inputFile(inputFile) { - inputFileType = GetInputFileType(inputFile); - - inputName = FileUtils::GetFileName(inputFile, true); - inputFolder = FileUtils::GetFileFolder(inputFile); - outputFolder = inputFolder; - outputName = FileUtils::GetFileName(inputFile, false); - fullOutput = outputFolder + outputName; - } - - ~InputInfo() = default; - static InputFileType GetInputFileType(const std::string &inputFile) { - InputFileType fileType = InputFileType::kFileTypeNone; - std::string extensionName = FileUtils::GetFileExtension(inputFile); - if (extensionName == "class") { - fileType = InputFileType::kFileTypeClass; - } - else if (extensionName == "dex") { - fileType = InputFileType::kFileTypeDex; - } - else if (extensionName == "c") { - fileType = InputFileType::kFileTypeC; - } - else if (extensionName == "cpp") { - fileType = InputFileType::kFileTypeCpp; - } - else if (extensionName == "ast") { - fileType = InputFileType::kFileTypeAst; - } - else if (extensionName == "jar") { - fileType = InputFileType::kFileTypeJar; - } - else if (extensionName == "mpl" || extensionName == "bpl") { - if (inputFile.find("VtableImpl") == std::string::npos) { - if (inputFile.find(".me.mpl") != std::string::npos) { - fileType = InputFileType::kFileTypeMeMpl; - } else { - fileType = extensionName == "mpl" ? InputFileType::kFileTypeMpl : InputFileType::kFileTypeBpl; - } - } else { - fileType = InputFileType::kFileTypeVtableImplMpl; - } - } else if (extensionName == "s") { - fileType = InputFileType::kFileTypeS; - } else if (extensionName == "o") { - fileType = InputFileType::kFileTypeObj; - } else if (extensionName == "mbc") { - fileType = InputFileType::kFileTypeMbc; - } else if (extensionName == "lmbc") { - fileType = InputFileType::kFileTypeLmbc; - } - - return fileType; - } - - InputFileType GetInputFileType() const { - return inputFileType; - } - - const std::string &GetInputFile() const { - return inputFile; - } - - const std::string &GetOutputFolder() const { - return outputFolder; - } - - const std::string &GetOutputName() const { - return outputName; - } - - const std::string &GetFullOutputName() const { - return fullOutput; - } - -private: - std::string inputFile = ""; - InputFileType inputFileType = InputFileType::kFileTypeNone; - - std::string inputName = ""; - std::string inputFolder = ""; - std::string outputName = ""; - std::string outputFolder = ""; - std::string fullOutput = ""; -}; - -class Action { -public: - Action(const std::string &tool, const InputInfo *const inputInfo) - : inputInfo(inputInfo), tool(tool) {} - - Action(const std::string &tool, const InputInfo *const inputInfo, - std::unique_ptr &inAction) - : inputInfo(inputInfo), tool(tool) { - inputActions.push_back(std::move(inAction)); - } - - Action(const std::string &tool, std::vector> &inActions, - const InputInfo *const inputInfo) - : inputInfo(inputInfo), tool(tool) { - for (auto &inAction : inActions) { - linkInputFiles.push_back(inAction->GetInputFile()); - } - - std::move(begin(inActions), end(inActions), std::back_inserter(inputActions)); - } - - ~Action() = default; - - const std::string &GetTool() const { - return tool; - } - - const std::string &GetInputFile() const { - return inputInfo->GetInputFile(); - } - - const std::string &GetOutputFolder() const { - return inputInfo->GetOutputFolder(); - } - - const std::string &GetOutputName() const { - return inputInfo->GetOutputName(); - } - - const std::string &GetFullOutputName() const { - return inputInfo->GetFullOutputName(); - } - - InputFileType GetInputFileType() const { - return inputInfo->GetInputFileType(); - } - - const std::vector &GetLinkFiles() const { - return linkInputFiles; - } - - const std::vector> &GetInputActions() const { - return inputActions; - } - - Compiler *GetCompiler() const { - return compilerTool; - } - - void SetCompiler(Compiler *compiler) { - compilerTool = compiler; - } - - bool IsItFirstRealAction() const { - /* First action is always "Input". - * But first real action will be a tool from kMapleCompilers. - */ - if (inputActions.size() > 0 && inputActions[0]->tool == "input") { - return true; - } - return false; - } - -private: - const InputInfo *inputInfo; - - std::string tool = ""; - std::string exeFolder = ""; - std::vector linkInputFiles; - - Compiler *compilerTool = nullptr; - - /* This vector contains a links to previous actions in Action tree */ - std::vector> inputActions; -}; - class MplOption { public: MplOption(){needRootPath = false;} @@ -291,205 +73,5 @@ struct DefaultOption { uint32_t length = 0; }; -class MplOptions { - public: - MplOptions() = default; - MplOptions(const MplOptions &options) = delete; - MplOptions &operator=(const MplOptions &options) = delete; - ~MplOptions() = default; - - int Parse(int argc, char **argv); - - const std::map> &GetExeOptions() const { - return exeOptions; - } - - const std::string &GetInputFiles() const { - return inputFiles; - } - - const std::string &GetExeFolder() const { - return exeFolder; - } - - const OptimizationLevel &GetOptimizationLevel() const { - return optimizationLevel; - } - - const std::string &GetMpltFile() const { - return mpltFile; - } - - const std::string &GetPartO2List() const { - return partO2List; - } - - const RunMode &GetRunMode() const { - return runMode; - } - - bool HasSetDefaultLevel() const { - return setDefaultLevel; - } - - bool HasSetSaveTmps() const { - return isSaveTmps; - } - - const std::vector &GetSaveFiles() const { - return saveFiles; - } - - const std::vector &GetSplitsInputFiles() const { - return splitsInputFiles; - } - - const std::vector &GetRunningExes() const { - return runningExes; - } - - const std::vector &GetSelectedExes() const { - return selectedExes; - } - - bool HasSetDebugFlag() const { - return debugFlag; - } - - bool WithDwarf() const { - return withDwarf; - } - - bool HasSetTimePhases() const { - return timePhases; - } - - bool HasSetGenMeMpl() const { - return genMeMpl; - } - - bool HasSetGenMapleBC() const { - return genMapleBC; - } - - bool HasSetGenLMBC() const { - return genLMBC; - } - - bool HasSetGenOnlyObj() const { - return genObj; - } - - bool HasSetRunMaplePhase() const { - return runMaplePhaseOnly; - } - - bool HasSetGenVtableImpl() const { - return genVtableImpl; - } - - bool HasSetGeneralRegOnly() const { - return generalRegOnly; - } - - SafetyCheckMode GetNpeCheckMode() const { - return npeCheckMode; - } - - bool IsNpeCheckAll() const { - return isNpeCheckAll; - } - - SafetyCheckMode GetBoundaryCheckMode() const { - return boundaryCheckMode; - } - - const std::vector> &GetActions() const { - return rootActions; - } - - const std::deque &GetOptions() const { - return optionParser->GetOptions(); - } - - bool IsSafeRegion() const { - return safeRegion; - } - - ErrorCode AppendCombOptions(MIRSrcLang srcLang); - ErrorCode AppendMplcgOptions(MIRSrcLang srcLang); - std::string GetInputFileNameForPrint(const Action * const action) const; - void PrintCommand(const Action * const action); - void connectOptStr(std::string &optionStr, const std::string &exeName, bool &firstComb, std::string &runStr); - std::string GetCommonOptionsStr() const; - void PrintDetailCommand(const Action * const action, bool isBeforeParse); - inline void PrintDetailCommand(bool isBeforeParse) { - PrintDetailCommand(nullptr, isBeforeParse); - } - private: - bool Init(const std::string &inputFile); - ErrorCode HandleGeneralOptions(); - ErrorCode DecideRunType(); - ErrorCode DecideRunningPhases(); - ErrorCode DecideRunningPhases(const std::vector &runExes); - std::unique_ptr DecideRunningPhasesByType(const InputInfo *const inputInfo, bool isMultipleFiles); - ErrorCode MFCreateActionByExe(const std::string &exe, std::unique_ptr ¤tAction, - const InputInfo *const inputInfo, bool &wasWrpCombCompilerCreated); - ErrorCode SFCreateActionByExe(const std::string &exe, std::unique_ptr ¤tAction, - const InputInfo *const inputInfo, bool &isCombCompiler); - ErrorCode CheckInputFileValidity(); - ErrorCode CheckFileExits(); - ErrorCode AddOption(const mapleOption::Option &option); - InputInfo *AllocateInputInfo(const std::string &inputFile); - ErrorCode UpdatePhaseOption(const std::string &args, const std::string &exeName); - ErrorCode UpdateExtraOptionOpt(const std::string &args); - ErrorCode AppendDefaultOptions(const std::string &exeName, MplOption mplOptions[], unsigned int length); - void DumpAppendedOptions(const std::string &exeName, const MplOption mplOptions[], - unsigned int length) const; - void UpdateRunningExe(const std::string &args); - void DumpActionTree(const Action &action, int idents) const; - void DumpActionTree() const; - std::unique_ptr optionParser = nullptr; - std::map> options = {}; - std::map> exeOptions = {}; - std::string inputFiles = ""; - std::string exeFolder = ""; - std::string mpltFile = ""; - std::string meOptArgs = ""; - std::string mpl2mplOptArgs = ""; - std::string mplcgOptArgs = ""; - OptimizationLevel optimizationLevel = OptimizationLevel::kO0; - RunMode runMode = RunMode::kUnkownRun; - bool setDefaultLevel = false; - bool isSaveTmps = false; - std::vector saveFiles = {}; - std::vector splitsInputFiles = {}; - std::vector runningExes = {}; - std::vector selectedExes = {}; - bool optForSize = false; - bool isWithIpa = false; - std::ostringstream printExtraOptStr; - bool debugFlag = false; - bool withDwarf = false; - bool timePhases = false; - bool genObj = false; - bool genMeMpl = false; - bool genMapleBC = false; - bool genLMBC = false; - bool runMaplePhaseOnly = true; - bool genVtableImpl = false; - bool hasPrinted = false; - bool generalRegOnly = false; - bool isDriverPhasesDumpCmd = false; - unsigned int helpLevel = mapleOption::kBuildTypeDefault; - std::string partO2List = ""; - SafetyCheckMode npeCheckMode = SafetyCheckMode::kNoCheck; - bool isNpeCheckAll = false; - SafetyCheckMode boundaryCheckMode = SafetyCheckMode::kNoCheck; - bool safeRegion = false; - - std::vector> inputInfos; - std::vector> rootActions; -}; } // namespace maple #endif // MAPLE_DRIVER_INCLUDE_MPL_OPTIONS_H diff --git a/src/mapleall/maple_driver/src/as_compiler.cpp b/src/mapleall/maple_driver/src/as_compiler.cpp index b057f8ac2e..99a379a71a 100644 --- a/src/mapleall/maple_driver/src/as_compiler.cpp +++ b/src/mapleall/maple_driver/src/as_compiler.cpp @@ -17,7 +17,7 @@ #include "default_options.def" namespace maple { -std::string AsCompiler::GetBinPath(const MplOptions&) const { +std::string AsCompiler::GetBinPath() const { #ifdef ANDROID return "prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/"; #else @@ -34,7 +34,7 @@ const std::string &AsCompiler::GetTool() const { return kAsFlag; } -DefaultOption AsCompiler::GetDefaultOptions(const MplOptions &options, const Action &action) const { +DefaultOption AsCompiler::GetDefaultOptions(const Action &action) const { uint32_t len = sizeof(kAsDefaultOptions) / sizeof(MplOption); DefaultOption defaultOptions = { std::make_unique(len), len }; @@ -49,24 +49,29 @@ DefaultOption AsCompiler::GetDefaultOptions(const MplOptions &options, const Act defaultOptions.mplOptions[i].SetValue( FileUtils::AppendMapleRootIfNeeded(defaultOptions.mplOptions[i].GetNeedRootPath(), defaultOptions.mplOptions[i].GetValue(), - options.GetExeFolder())); + MplDriver::GetMplDriver().GetExeFolder())); } return defaultOptions; } -std::string AsCompiler::GetInputFileName(const MplOptions&, const Action &action) const { +std::string AsCompiler::GetInputFileName(const Action &action) const { return action.GetFullOutputName() + ".s"; } -void AsCompiler::GetTmpFilesToDelete(const MplOptions&, const Action &action, +void AsCompiler::GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const { tempFiles.push_back(action.GetFullOutputName() + ".o"); } -std::unordered_set AsCompiler::GetFinalOutputs(const MplOptions&, - const Action &action) const { +std::unordered_set AsCompiler::GetFinalOutputs(const Action &action) const { auto finalOutputs = std::unordered_set(); (void)finalOutputs.insert(action.GetFullOutputName() + ".o"); return finalOutputs; } + +void AsCompiler::AppendOutputOption(std::vector &finalOptions, + const std::string &name) const { + finalOptions.emplace_back("-o", name); +} + } // namespace maple diff --git a/src/mapleall/maple_driver/src/clang_compiler.cpp b/src/mapleall/maple_driver/src/clang_compiler.cpp index e5924a388c..7cbfdd800a 100644 --- a/src/mapleall/maple_driver/src/clang_compiler.cpp +++ b/src/mapleall/maple_driver/src/clang_compiler.cpp @@ -17,11 +17,12 @@ #include #include "compiler.h" #include "file_utils.h" +#include "maple_driver.h" #include "mpl_timer.h" #include "default_options.def" namespace maple { -std::string ClangCompiler::GetBinPath(const MplOptions&) const{ +std::string ClangCompiler::GetBinPath() const{ return FileUtils::SafeGetenv(kMapleRoot) + "/tools/bin/"; } @@ -61,7 +62,7 @@ static uint32_t FillSpecialDefaulOpt(std::unique_ptr &opt, return additionalLen; } -DefaultOption ClangCompiler::GetDefaultOptions(const MplOptions &options, const Action &action) const { +DefaultOption ClangCompiler::GetDefaultOptions(const Action &action) const { DefaultOption defaultOptions; uint32_t fullLen = 0; uint32_t defaultLen = 0; @@ -86,20 +87,25 @@ DefaultOption ClangCompiler::GetDefaultOptions(const MplOptions &options, const defaultOptions.mplOptions[i].SetValue( FileUtils::AppendMapleRootIfNeeded(defaultOptions.mplOptions[i].GetNeedRootPath(), defaultOptions.mplOptions[i].GetValue(), - options.GetExeFolder())); + MplDriver::GetMplDriver().GetExeFolder())); } return defaultOptions; } -void ClangCompiler::GetTmpFilesToDelete(const MplOptions&, const Action &action, +void ClangCompiler::GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const { tempFiles.push_back(action.GetFullOutputName() + ".ast"); } -std::unordered_set ClangCompiler::GetFinalOutputs(const MplOptions&, - const Action &action) const { +std::unordered_set ClangCompiler::GetFinalOutputs(const Action &action) const { std::unordered_set finalOutputs; (void)finalOutputs.insert(action.GetFullOutputName() + ".ast"); return finalOutputs; } + +void ClangCompiler::AppendOutputOption(std::vector &finalOptions, + const std::string &name) const { + finalOptions.emplace_back("-o", name); +} + } diff --git a/src/mapleall/maple_driver/src/compiler.cpp b/src/mapleall/maple_driver/src/compiler.cpp index 9936680598..8f55c89c8f 100644 --- a/src/mapleall/maple_driver/src/compiler.cpp +++ b/src/mapleall/maple_driver/src/compiler.cpp @@ -13,23 +13,27 @@ * See the Mulan PSL v2 for more details. */ #include "compiler.h" -#include +#include "driver_options.h" #include "file_utils.h" +#include "maple_driver.h" #include "safe_exe.h" #include "mpl_timer.h" +#include +#include +#include + namespace maple { using namespace mapleOption; -int Compiler::Exe(const MplOptions &mplOptions, - const std::vector &options) const { +int Compiler::Exe(const std::vector &options) const { std::ostringstream ostrStream; - ostrStream << GetBinPath(mplOptions) << GetBinName(); + ostrStream << GetBinPath() << GetBinName(); std::string binPath = ostrStream.str(); return SafeExe::Exe(binPath, options); } -std::string Compiler::GetBinPath(const MplOptions &mplOptions) const { +std::string Compiler::GetBinPath() const { #ifdef MAPLE_PRODUCT_EXECUTABLE // build flag -DMAPLE_PRODUCT_EXECUTABLE std::string binPath = std::string(MAPLE_PRODUCT_EXECUTABLE); if (binPath.empty()) { @@ -38,22 +42,22 @@ std::string Compiler::GetBinPath(const MplOptions &mplOptions) const { binPath = binPath + kFileSeperatorChar; } #else - std::string binPath = mplOptions.GetExeFolder(); + std::string binPath = MplDriver::GetMplDriver().GetExeFolder(); #endif return binPath; } -ErrorCode Compiler::Compile(MplOptions &options, const Action &action, +ErrorCode Compiler::Compile(const Action &action, std::unique_ptr&) { MPLTimer timer = MPLTimer(); LogInfo::MapleLogger() << "Starting " << GetName() << '\n'; timer.Start(); - std::vector generatedOptions = MakeOption(options, action); + std::vector generatedOptions = MakeOption(action); if (generatedOptions.empty()) { return kErrorInvalidParameter; } - if (Exe(options, generatedOptions) != 0) { + if (Exe(generatedOptions) != 0) { return kErrorCompileFail; } timer.Stop(); @@ -61,14 +65,13 @@ ErrorCode Compiler::Compile(MplOptions &options, const Action &action, return kErrorNoError; } -std::vector Compiler::MakeOption(const MplOptions &options, - const Action &action) const { +std::vector Compiler::MakeOption(const Action &action) const { std::vector finalOptions; - std::vector defaultOptions = MakeDefaultOptions(options, action); + std::vector defaultOptions = MakeDefaultOptions(action); - AppendInputsAsOptions(finalOptions, options, action); - AppendDefaultOptions(finalOptions, defaultOptions, options.HasSetDebugFlag()); - AppendExtraOptions(finalOptions, options, options.HasSetDebugFlag()); + AppendInputsAsOptions(finalOptions, action); + AppendDefaultOptions(finalOptions, defaultOptions, opts::debug); + AppendExtraOptions(finalOptions, opts::debug, action); return finalOptions; } @@ -91,38 +94,51 @@ void Compiler::AppendDefaultOptions(std::vector &finalOptions, } void Compiler::AppendExtraOptions(std::vector &finalOptions, - const MplOptions &options, bool isDebug) const { + bool isDebug, const Action &action) const { const std::string &binName = GetTool(); - auto exeOption = options.GetExeOptions().find(binName); - if (exeOption == options.GetExeOptions().end()) { - return; + auto &drv = MplDriver::GetMplDriver(); + + if (isDebug) { + LogInfo::MapleLogger() << Compiler::GetName() << " Extra Options: "; } - for (const Option &opt : exeOption->second) { - std::string prefix = opt.GetPrefix(); - const std::string &baseKey = opt.OptionKey(); - const std::string key = prefix + baseKey; - const std::string &value = opt.Args(); - - /* Default behaviour: extra options do not replace default options, - * because it can be some additional option with the same key. - * For example: we can have some default -isystem SYSTEM pathes option. - * And if some additional -isystem SYSTEM pathes is added, it's not correct - * to replace them (SYSTEM pathes msut be extended (not replaced)). - * If you need to replace some special option, check and replace it here */ - if (baseKey == "o") { - ReplaceOrInsertOption(finalOptions, key, value); - } else { - (void)finalOptions.emplace_back(MplOption(key, value)); + /* Append options setting by: --run=binName --option="-opt1 -opt2" */ + auto &exeOptions = drv.GetExeOptions(); + auto it = exeOptions.find(binName); + if (it != exeOptions.end()) { + for (auto &opt : it->second) { + finalOptions.emplace_back(opt, ""); + if (isDebug) { + LogInfo::MapleLogger() << opt << " "; + } } } - if (isDebug) { - LogInfo::MapleLogger() << Compiler::GetName() << " Extra Options: "; - for (const Option &opt : exeOption->second) { - LogInfo::MapleLogger() << opt.OptionKey() << " " - << opt.Args(); + cl::OptionCategory *category = drv.GetCategory(binName); + ASSERT(category != nullptr, "Undefined tool: %s", binName.data()); + + /* Append options setting directly for special category. Example: --verbose */ + for (const auto &opt : category->GetEnabledOptions()) { + for (const auto &val : opt->GetRawValues()) { + finalOptions.emplace_back(opt->GetName(), val); + if (isDebug) { + LogInfo::MapleLogger() << opt->GetName() << " " << val << " "; + } + } + } + + /* output file can not be specified for several last actions. As exaple: + * If last actions are assembly tool for 2 files (to get file1.o, file2.o), + * we can not have one output name for them. */ + if (opts::output.IsEnabledByUser() && drv.GetActions().size() == 1) { + /* Set output file for last compilation tool */ + if (&action == drv.GetActions()[0].get()) { + /* the tool may not support "-o" for output option */ + AppendOutputOption(finalOptions, opts::output.GetValue()); } + } + + if (isDebug) { LogInfo::MapleLogger() << '\n'; } } @@ -143,9 +159,9 @@ void Compiler::ReplaceOrInsertOption(std::vector &finalOptions, } void Compiler::AppendInputsAsOptions(std::vector &finalOptions, - const MplOptions &mplOptions, const Action &action) const { + const Action &action) const { std::vector splittedInputFileNames; - std::string inputFileNames = GetInputFileName(mplOptions, action); + std::string inputFileNames = GetInputFileName(action); StringUtils::Split(inputFileNames, splittedInputFileNames, ' '); for (auto &inputFileName : splittedInputFileNames) { @@ -153,9 +169,8 @@ void Compiler::AppendInputsAsOptions(std::vector &finalOptions, } } -std::vector Compiler::MakeDefaultOptions(const MplOptions &options, - const Action &action) const { - DefaultOption rawDefaultOptions = GetDefaultOptions(options, action); +std::vector Compiler::MakeDefaultOptions(const Action &action) const { + DefaultOption rawDefaultOptions = GetDefaultOptions(action); std::vector defaultOptions; if (rawDefaultOptions.mplOptions != nullptr) { for (uint32_t i = 0; i < rawDefaultOptions.length; ++i) { diff --git a/src/mapleall/maple_driver/src/compiler_factory.cpp b/src/mapleall/maple_driver/src/compiler_factory.cpp index 94eb281629..d4063f9d58 100644 --- a/src/mapleall/maple_driver/src/compiler_factory.cpp +++ b/src/mapleall/maple_driver/src/compiler_factory.cpp @@ -15,6 +15,7 @@ #include "compiler_factory.h" #include #include "file_utils.h" +#include "maple_driver.h" #include "string_utils.h" #include "mpl_logging.h" @@ -67,24 +68,34 @@ void CompilerFactory::Insert(const std::string &name, Compiler *value) { (void)supportedCompilers.insert(make_pair(name, value)); } -ErrorCode CompilerFactory::DeleteTmpFiles(const MplOptions &mplOptions, - const std::vector &tempFiles) const { +ErrorCode CompilerFactory::DeleteTmpFiles(const std::vector &tempFiles, + const std::vector &saveFiles, + const std::vector &inputFiles, + const MplDriver::RootActionsType &actions) const { int ret = 0; for (const std::string &tmpFile : tempFiles) { bool isSave = false; - for (auto saveFile : mplOptions.GetSaveFiles()) { + for (auto &saveFile : saveFiles) { if (!saveFile.empty() && std::regex_match(tmpFile, std::regex(StringUtils::Replace(saveFile, "*", ".*?")))) { isSave = true; break; } } - if (!isSave && mplOptions.GetInputFiles().find(tmpFile) == std::string::npos /* not input */) { + + bool isInputFile = false; + for (auto &inFile : inputFiles) { + if (inFile == tmpFile) { + isInputFile = true; + } + } + + if (!isSave && !isInputFile /* not input */) { bool isNeedRemove = true; /* If we compile several files we can have several last Actions, * so we need to NOT remove output files for each last Action. */ - for (auto &lastAction : mplOptions.GetActions()) { - auto finalOutputs = lastAction->GetCompiler()->GetFinalOutputs(mplOptions, *lastAction); + for (auto &lastAction : actions) { + auto finalOutputs = lastAction->GetCompiler()->GetFinalOutputs(*lastAction); /* do not remove output files */ if (finalOutputs.find(tmpFile) != finalOutputs.end()) { isNeedRemove = false; @@ -99,7 +110,7 @@ ErrorCode CompilerFactory::DeleteTmpFiles(const MplOptions &mplOptions, return ret == 0 ? kErrorNoError : kErrorFileNotFound; } -ErrorCode CompilerFactory::Compile(MplOptions &mplOptions) { +ErrorCode CompilerFactory::Compile(const MplDriver::RootActionsType &rootActions) { if (compileFinished) { LogInfo::MapleLogger() << "Failed! Compilation has been completed in previous time and multi-instance compilation is not supported\n"; @@ -112,7 +123,7 @@ ErrorCode CompilerFactory::Compile(MplOptions &mplOptions) { LogInfo::MapleLogger() << "Failed! Compiler is null." << "\n"; return kErrorCompileFail; } - ErrorCode ret = compilerSelector->Select(supportedCompilers, mplOptions, actions); + ErrorCode ret = compilerSelector->Select(supportedCompilers, rootActions, actions); if (ret != kErrorNoError) { return ret; } @@ -128,25 +139,11 @@ ErrorCode CompilerFactory::Compile(MplOptions &mplOptions) { return kErrorToolNotFound; } - ret = compiler->Compile(mplOptions, *action, this->theModule); + ret = compiler->Compile(*action, this->theModule); if (ret != kErrorNoError) { return ret; } } - if (mplOptions.HasSetDebugFlag()) { - mplOptions.PrintDetailCommand(false); - } - // Compiler finished - compileFinished = true; - if (!mplOptions.HasSetSaveTmps() || !mplOptions.GetSaveFiles().empty()) { - std::vector tmpFiles; - - for (auto *action : actions) { - action->GetCompiler()->GetTmpFilesToDelete(mplOptions, *action, tmpFiles); - } - - ret = DeleteTmpFiles(mplOptions, tmpFiles); - } return ret; } diff --git a/src/mapleall/maple_driver/src/compiler_selector.cpp b/src/mapleall/maple_driver/src/compiler_selector.cpp index 87e3fc327e..f49903014c 100644 --- a/src/mapleall/maple_driver/src/compiler_selector.cpp +++ b/src/mapleall/maple_driver/src/compiler_selector.cpp @@ -25,23 +25,7 @@ Compiler *CompilerSelectorImpl::FindCompiler(const SupportedCompilers &compilers return nullptr; } -ErrorCode CompilerSelectorImpl::InsertCompilerIfNeeded(std::vector &selected, - const SupportedCompilers &compilers, - const std::string &name) const { - Compiler *compiler = FindCompiler(compilers, name); - if (compiler != nullptr) { - if (std::find(selected.cbegin(), selected.cend(), compiler) == selected.cend()) { - selected.push_back(compiler); - } - return kErrorNoError; - } - - LogInfo::MapleLogger(kLlErr) << name << " not found!!!" << '\n'; - return kErrorToolNotFound; -} - ErrorCode CompilerSelectorImpl::Select(const SupportedCompilers &supportedCompilers, - const MplOptions &mplOptions, Action &action, std::vector &selectedActions) const { ErrorCode ret = kErrorNoError; @@ -49,7 +33,7 @@ ErrorCode CompilerSelectorImpl::Select(const SupportedCompilers &supportedCompil /* Traverse Action tree recursively and select compilers in * "from leaf(clang) to root(ld)" order */ for (const std::unique_ptr &a : action.GetInputActions()) { - ret = Select(supportedCompilers, mplOptions, *a, selectedActions); + ret = Select(supportedCompilers, *a, selectedActions); if (ret != kErrorNoError) { return ret; } @@ -77,12 +61,11 @@ ErrorCode CompilerSelectorImpl::Select(const SupportedCompilers &supportedCompil } ErrorCode CompilerSelectorImpl::Select(const SupportedCompilers &supportedCompilers, - const MplOptions &mplOptions, + const MplDriver::RootActionsType& actions, std::vector &selectedActions) const { - ErrorCode ret; - for (const std::unique_ptr &action : mplOptions.GetActions()) { - ret = Select(supportedCompilers, mplOptions, *action, selectedActions); + for (const std::unique_ptr &action : actions) { + ErrorCode ret = Select(supportedCompilers, *action, selectedActions); if (ret != kErrorNoError) { return ret; } diff --git a/src/mapleall/maple_driver/src/cpp2mpl_compiler.cpp b/src/mapleall/maple_driver/src/cpp2mpl_compiler.cpp index ffb863baa2..a496108b36 100644 --- a/src/mapleall/maple_driver/src/cpp2mpl_compiler.cpp +++ b/src/mapleall/maple_driver/src/cpp2mpl_compiler.cpp @@ -15,11 +15,12 @@ #include #include "compiler.h" #include "file_utils.h" +#include "maple_driver.h" #include "mpl_logging.h" #include "default_options.def" namespace maple { -std::string Cpp2MplCompiler::GetBinPath(const MplOptions&) const{ +std::string Cpp2MplCompiler::GetBinPath() const{ return FileUtils::SafeGetenv(kMapleRoot) + "/output/" + FileUtils::SafeGetenv("MAPLE_BUILD_TYPE") + "/bin/"; } @@ -28,7 +29,7 @@ const std::string &Cpp2MplCompiler::GetBinName() const { return kBinNameCpp2mpl; } -std::string Cpp2MplCompiler::GetInputFileName(const MplOptions &, const Action &action) const { +std::string Cpp2MplCompiler::GetInputFileName(const Action &action) const { if (action.IsItFirstRealAction()) { return action.GetInputFile(); } @@ -41,7 +42,7 @@ std::string Cpp2MplCompiler::GetInputFileName(const MplOptions &, const Action & return action.GetOutputFolder() + outputName + ".ast"; } -DefaultOption Cpp2MplCompiler::GetDefaultOptions(const MplOptions &options, const Action&) const { +DefaultOption Cpp2MplCompiler::GetDefaultOptions(const Action&) const { uint32_t len = sizeof(kCpp2MplDefaultOptionsForAst) / sizeof(MplOption); DefaultOption defaultOptions = { std::make_unique(len), len }; @@ -53,22 +54,27 @@ DefaultOption Cpp2MplCompiler::GetDefaultOptions(const MplOptions &options, cons defaultOptions.mplOptions[i].SetValue( FileUtils::AppendMapleRootIfNeeded(defaultOptions.mplOptions[i].GetNeedRootPath(), defaultOptions.mplOptions[i].GetValue(), - options.GetExeFolder())); + MplDriver::GetMplDriver().GetExeFolder())); } return defaultOptions; } -void Cpp2MplCompiler::GetTmpFilesToDelete(const MplOptions&, const Action &action, +void Cpp2MplCompiler::GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const { tempFiles.push_back(action.GetFullOutputName() + ".mpl"); tempFiles.push_back(action.GetFullOutputName() + ".mplt"); } -std::unordered_set Cpp2MplCompiler::GetFinalOutputs(const MplOptions&, - const Action &action) const { +std::unordered_set Cpp2MplCompiler::GetFinalOutputs(const Action &action) const { std::unordered_set finalOutputs; (void)finalOutputs.insert(action.GetFullOutputName() + ".mpl"); (void)finalOutputs.insert(action.GetFullOutputName() + ".mplt"); return finalOutputs; } + +void Cpp2MplCompiler::AppendOutputOption(std::vector &finalOptions, + const std::string &name) const { + finalOptions.emplace_back("-o", name); +} + } // namespace maple diff --git a/src/mapleall/maple_driver/src/dex2mpl_compiler.cpp b/src/mapleall/maple_driver/src/dex2mpl_compiler.cpp index 543b5396ae..501a663380 100644 --- a/src/mapleall/maple_driver/src/dex2mpl_compiler.cpp +++ b/src/mapleall/maple_driver/src/dex2mpl_compiler.cpp @@ -14,25 +14,28 @@ */ #include "compiler.h" #include "default_options.def" -#include +#include "driver_options.h" +#include "maple_driver.h" #ifdef INTERGRATE_DRIVER #include "dex2mpl_runner.h" #include "mir_function.h" #endif +#include + namespace maple { const std::string &Dex2MplCompiler::GetBinName() const { return kBinNameDex2mpl; } -DefaultOption Dex2MplCompiler::GetDefaultOptions(const MplOptions &options, const Action&) const { +DefaultOption Dex2MplCompiler::GetDefaultOptions(const Action&) const { uint32_t len = 0; MplOption *kDex2mplDefaultOptions = nullptr; - if (options.GetOptimizationLevel() == kO0 && options.HasSetDefaultLevel()) { + if (opts::o0) { len = sizeof(kDex2mplDefaultOptionsO0) / sizeof(MplOption); kDex2mplDefaultOptions = kDex2mplDefaultOptionsO0; - } else if (options.GetOptimizationLevel() == kO2 && options.HasSetDefaultLevel()) { + } else if (opts::o2) { len = sizeof(kDex2mplDefaultOptionsO2) / sizeof(MplOption); kDex2mplDefaultOptions = kDex2mplDefaultOptionsO2; } @@ -50,214 +53,42 @@ DefaultOption Dex2MplCompiler::GetDefaultOptions(const MplOptions &options, cons defaultOptions.mplOptions[i].SetValue( FileUtils::AppendMapleRootIfNeeded(defaultOptions.mplOptions[i].GetNeedRootPath(), defaultOptions.mplOptions[i].GetValue(), - options.GetExeFolder())); + MplDriver::GetMplDriver().GetExeFolder())); } return defaultOptions; } -void Dex2MplCompiler::GetTmpFilesToDelete(const MplOptions&, const Action &action, +void Dex2MplCompiler::GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const { tempFiles.push_back(action.GetFullOutputName() + ".mpl"); tempFiles.push_back(action.GetFullOutputName() + ".mplt"); } -std::unordered_set Dex2MplCompiler::GetFinalOutputs(const MplOptions&, - const Action &action) const { +std::unordered_set Dex2MplCompiler::GetFinalOutputs(const Action &action) const { auto finalOutputs = std::unordered_set(); (void)finalOutputs.insert(action.GetFullOutputName() + ".mpl"); (void)finalOutputs.insert(action.GetFullOutputName() + ".mplt"); return finalOutputs; } -#ifdef INTERGRATE_DRIVER -void Dex2MplCompiler::PostDex2Mpl(std::unique_ptr &theModule) const { - // for each function - for (auto *func : theModule->GetFunctionList()) { - if (func == nullptr) { - continue; - } - - MIRSymbolTable *symTab = func->GetSymTab(); - // for each symbol - for (size_t i = 0; i != symTab->GetSymbolTableSize(); ++i) { - MIRSymbol *currSymbol = symTab->GetSymbolFromStIdx(i); - if (currSymbol == nullptr) { - continue; - } - // (1) replace void ptr with void ref - if (theModule->IsJavaModule() && currSymbol->GetType() == GlobalTables::GetTypeTable().GetVoidPtr()) { - MIRType *voidRef = GlobalTables::GetTypeTable().GetOrCreatePointerType( - *GlobalTables::GetTypeTable().GetVoid(), PTY_ref); - currSymbol->SetTyIdx(voidRef->GetTypeIndex()); - } - // (2) replace String ref with String ptr if symbol's name starts with "L_STR" - if (currSymbol->GetType()->GetKind() == kTypePointer && currSymbol->GetName().find("L_STR") == 0) { - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(currSymbol->GetTyIdx()); - auto *ptrTy = static_cast(ty->CopyMIRTypeNode()); - ASSERT(ptrTy != nullptr, "null ptr check"); - ptrTy->SetPrimType(PTY_ptr); - TyIdx newTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(ptrTy); - delete ptrTy; - currSymbol->SetTyIdx(newTyIdx); - } - } - - // (3) reset pregIndex of pregTab if function has body - if (func->GetBody() != nullptr) { - uint32 maxPregNo = 0; - for (uint32 i = 0; i < func->GetFormalCount(); ++i) { - MIRSymbol *formalSt = func->GetFormal(i); - if (formalSt->IsPreg()) { - // no special register appears in the formals - uint32 pRegNo = static_cast(formalSt->GetPreg()->GetPregNo()); - if (pRegNo > maxPregNo) { - maxPregNo = pRegNo; - } - } - } - if (func->GetPregTab() == nullptr) { - continue; - } - func->GetPregTab()->SetIndex(maxPregNo + 1); - } - } - - // (4) fix unmatched MIRConst type of global symbols - for (size_t i = 0; i != GlobalTables::GetGsymTable().GetSymbolTableSize(); ++i) { - MIRSymbol *symbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(i); - if (symbol == nullptr || !symbol->IsConst()) { - continue; - } - TyIdx stTyIdx = symbol->GetTyIdx(); - if (stTyIdx == 0) { - continue; - } - MIRType *stType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(stTyIdx); - MIRConst *mirConst = symbol->GetKonst(); - - if (mirConst == nullptr || mirConst->GetKind() != kConstInt) { - continue; - } - if (static_cast(mirConst)->GetValue() != 0) { - continue; - } - MIRType &valueType = mirConst->GetType(); - if (valueType.GetTypeIndex() != stTyIdx) { - auto *newIntConst = theModule->GetMemPool()->New(0, *stType); - symbol->SetValue({newIntConst}); - } - } - - // (5) remove type attr `rcunowned` of local symbol in rclocalunowned function specified by dex2mpl - for (auto *func : theModule->GetFunctionList()) { - if (func == nullptr || !func->GetAttr(FUNCATTR_rclocalunowned)) { - continue; - } - MIRSymbolTable *symTab = func->GetSymTab(); - for (size_t i = 0; i != symTab->GetSymbolTableSize(); ++i) { - MIRSymbol *symbol = symTab->GetSymbolFromStIdx(i); - if (symbol == nullptr) { - continue; - } - if (symbol->GetAttr(ATTR_rcunowned)) { - symbol->ResetAttr(ATTR_rcunowned); - } - } - } - - // 1: MIRStructType::isImported has different meaning for dex2mpl and binary mplt importer. - // for dex2mpl, `isImported` means whether a type is imported from mplt file instead of dex file, so all types from - // mplt are marked imported. But for binary mplt importer, `isImported` means whether a type is loaded successfully, - // so only complete types are marked imported. - // The workaround is to reset `isImported` according to the completeness of a type. - for (MIRType *type : GlobalTables::GetTypeTable().GetTypeTable()) { - if (type == nullptr) { - continue; - } - MIRTypeKind typeKind = type->GetKind(); - if (typeKind == kTypeStructIncomplete || typeKind == kTypeClassIncomplete || typeKind == kTypeInterfaceIncomplete) { - auto *structType = static_cast(type); - structType->SetIsImported(false); - } else if (typeKind == kTypeClass || typeKind == kTypeInterface) { - auto *structType = static_cast(type); - structType->SetIsImported(true); - } - } -} -#endif +void Dex2MplCompiler::PrintCommand(const Action &action) const { + auto &drv = MplDriver::GetMplDriver(); -void Dex2MplCompiler::PrintCommand(const MplOptions &options, const Action &action) const { std::string runStr = "--run="; std::string optionStr = "--option=\""; std::string connectSym = ""; - if (options.GetExeOptions().find(kBinNameDex2mpl) != options.GetExeOptions().end()) { + if (drv.GetExeOptions().find(kBinNameDex2mpl) != drv.GetExeOptions().end()) { runStr += "dex2mpl"; - auto inputDex2mplOptions = options.GetExeOptions().find(kBinNameDex2mpl); + auto inputDex2mplOptions = drv.GetExeOptions().find(kBinNameDex2mpl); for (auto &opt : inputDex2mplOptions->second) { - connectSym = opt.Args() != "" ? "=" : ""; - optionStr += " --" + opt.OptionKey() + connectSym + opt.Args(); + optionStr += " --" + opt; } } optionStr += "\""; - LogInfo::MapleLogger() << "Starting:" << options.GetExeFolder() << "maple " << runStr << " " << optionStr - << " --infile " << GetInputFileName(options, action) << '\n'; -} -#ifdef INTERGRATE_DRIVER -bool Dex2MplCompiler::MakeDex2mplOptions(const MplOptions &options) { - Dex2mplOptions &dex2mplOptions = Dex2mplOptions::GetInstance(); - dex2mplOptions.LoadDefault(); - auto it = options.GetExeOptions().find(kBinNameDex2mpl); - if (it == options.GetExeOptions().end()) { - LogInfo::MapleLogger() << "no dex2mpl input options\n"; - return false; - } - bool result = dex2mplOptions.SolveOptions(it->second, options.HasSetDebugFlag()); - if (result == false) { - LogInfo::MapleLogger() << "Meet error dex2mpl options\n"; - return false; - } - return true; + LogInfo::MapleLogger() << "Starting:" << drv.GetExeFolder() << "maple " + << runStr << " " << optionStr + << " --infile " << GetInputFileName(action) << '\n'; } -ErrorCode Dex2MplCompiler::Compile(MplOptions &options, const Action &action, - std::unique_ptr &theModule) { - Dex2mplOptions &dex2mplOptions = Dex2mplOptions::GetInstance(); - bool result = MakeDex2mplOptions(options); - if (!result) { - return ErrorCode::kErrorCompileFail; - } - // .dex - std::string dexFileName = action.GetInputFile(); - theModule = std::make_unique(dexFileName); - - const auto &runningExes = options.GetRunningExes(); - bool isDex2mplFinalExe = (runningExes[runningExes.size() - 1] == kBinNameDex2mpl); - std::unique_ptr dex2mpl = std::make_unique(dexFileName, dex2mplOptions, - std::move(theModule), options.HasSetSaveTmps(), isDex2mplFinalExe); - if (dex2mpl == nullptr) { - ERR(kLncErr, "new Dex2mplRunner failed."); - return ErrorCode::kErrorCompileFail; - } - LogInfo::MapleLogger() << "Starting dex2mpl" << '\n'; - int ret = dex2mpl->Init(); - if (ret != 0) { - return ErrorCode::kErrorCompileFail; - } - ret = dex2mpl->Run(); - if (ret != 0) { - ERR(kLncErr, "(ToIDEUser)dex2mpl failed."); - return ErrorCode::kErrorCompileFail; - } - // Check that whether the kBinNameDex2mpl is the final compiler - // If not, we need to call PostDex2Mpl() to deal with some differences in theModule to - // adapt to the needs of maplecomb - if (runningExes[runningExes.size() - 1] != kBinNameDex2mpl) { - dex2mpl->MoveMirModule(theModule); - PostDex2Mpl(theModule); - } - PrintCommand(options, action); - return ErrorCode::kErrorNoError; -} -#endif } // namespace maple diff --git a/src/mapleall/maple_driver/src/ipa_compiler.cpp b/src/mapleall/maple_driver/src/ipa_compiler.cpp index 939facc8e2..d56fe107f3 100644 --- a/src/mapleall/maple_driver/src/ipa_compiler.cpp +++ b/src/mapleall/maple_driver/src/ipa_compiler.cpp @@ -14,17 +14,18 @@ */ #include "compiler.h" #include "default_options.def" +#include "driver_options.h" namespace maple { const std::string &IpaCompiler::GetBinName() const { return kBinNameMplipa; } -DefaultOption IpaCompiler::GetDefaultOptions(const MplOptions &options, const Action&) const { +DefaultOption IpaCompiler::GetDefaultOptions(const Action&) const { uint32_t len = 0; MplOption *kMplipaDefaultOptions = nullptr; - if (options.GetOptimizationLevel() == kO2 && options.HasSetDefaultLevel()) { + if (opts::o2) { len = sizeof(kMplipaDefaultOptionsO2) / sizeof(MplOption); kMplipaDefaultOptions = kMplipaDefaultOptionsO2; } @@ -42,12 +43,12 @@ DefaultOption IpaCompiler::GetDefaultOptions(const MplOptions &options, const Ac defaultOptions.mplOptions[i].SetValue( FileUtils::AppendMapleRootIfNeeded(defaultOptions.mplOptions[i].GetNeedRootPath(), defaultOptions.mplOptions[i].GetValue(), - options.GetExeFolder())); + MplDriver::GetMplDriver().GetExeFolder())); } return defaultOptions; } -std::string IpaCompiler::GetInputFileName(const MplOptions&, const Action &action) const { +std::string IpaCompiler::GetInputFileName(const Action &action) const { return action.GetFullOutputName() + ".mpl"; } } // namespace maple diff --git a/src/mapleall/maple_driver/src/jbc2mpl_compiler.cpp b/src/mapleall/maple_driver/src/jbc2mpl_compiler.cpp index 0eb1272827..17f512fb51 100644 --- a/src/mapleall/maple_driver/src/jbc2mpl_compiler.cpp +++ b/src/mapleall/maple_driver/src/jbc2mpl_compiler.cpp @@ -21,18 +21,17 @@ const std::string &Jbc2MplCompiler::GetBinName() const { return kBinNameJbc2mpl; } -DefaultOption Jbc2MplCompiler::GetDefaultOptions(const MplOptions&, const Action&) const { +DefaultOption Jbc2MplCompiler::GetDefaultOptions(const Action&) const { return DefaultOption(); } -void Jbc2MplCompiler::GetTmpFilesToDelete(const MplOptions&, const Action &action, +void Jbc2MplCompiler::GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const { tempFiles.push_back(action.GetFullOutputName() + ".mpl"); tempFiles.push_back(action.GetFullOutputName() + ".mplt"); } -std::unordered_set Jbc2MplCompiler::GetFinalOutputs(const MplOptions&, - const Action &action) const { +std::unordered_set Jbc2MplCompiler::GetFinalOutputs(const Action &action) const { std::unordered_set finalOutputs; (void)finalOutputs.insert(action.GetFullOutputName() + ".mpl"); (void)finalOutputs.insert(action.GetFullOutputName() + ".mplt"); diff --git a/src/mapleall/maple_driver/src/ld_compiler.cpp b/src/mapleall/maple_driver/src/ld_compiler.cpp index 2b54bf739f..bbc0968745 100644 --- a/src/mapleall/maple_driver/src/ld_compiler.cpp +++ b/src/mapleall/maple_driver/src/ld_compiler.cpp @@ -15,9 +15,10 @@ #include "compiler.h" #include "file_utils.h" #include "default_options.def" +#include "maple_driver.h" namespace maple { -std::string LdCompiler::GetBinPath(const MplOptions&) const { +std::string LdCompiler::GetBinPath() const { #ifdef ANDROID return "prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/"; #else @@ -35,7 +36,7 @@ const std::string &LdCompiler::GetTool() const { return kLdFlag; } -DefaultOption LdCompiler::GetDefaultOptions(const MplOptions &options, const Action&) const { +DefaultOption LdCompiler::GetDefaultOptions(const Action&) const { uint32_t len = sizeof(kLdDefaultOptions) / sizeof(MplOption); DefaultOption defaultOptions = { std::make_unique(len), len }; @@ -47,12 +48,12 @@ DefaultOption LdCompiler::GetDefaultOptions(const MplOptions &options, const Act defaultOptions.mplOptions[i].SetValue( FileUtils::AppendMapleRootIfNeeded(defaultOptions.mplOptions[i].GetNeedRootPath(), defaultOptions.mplOptions[i].GetValue(), - options.GetExeFolder())); + MplDriver::GetMplDriver().GetExeFolder())); } return defaultOptions; } -std::string LdCompiler::GetInputFileName(const MplOptions&, const Action &action) const { +std::string LdCompiler::GetInputFileName(const Action &action) const { std::string files; bool isFirstEntry = true; @@ -68,4 +69,10 @@ std::string LdCompiler::GetInputFileName(const MplOptions&, const Action &action } return files; } + +void LdCompiler::AppendOutputOption(std::vector &finalOptions, + const std::string &name) const { + finalOptions.emplace_back("-o", name); +} + } // namespace maple diff --git a/src/mapleall/maple_driver/src/maple.cpp b/src/mapleall/maple_driver/src/maple.cpp index 86afd59290..714a9d0116 100644 --- a/src/mapleall/maple_driver/src/maple.cpp +++ b/src/mapleall/maple_driver/src/maple.cpp @@ -13,13 +13,154 @@ * See the Mulan PSL v2 for more details. */ #include "compiler_factory.h" +#include "driver_options.h" #include "error_code.h" #include "maple_driver.h" #include "mpl_options.h" #include "mpl_logging.h" +#include +#include using namespace maple; +const std::vector extraExclude = { &opts::run, + &opts::optionOpt, + &opts::infile, + &opts::mpl2mplOpt, + &opts::meOpt, + &opts::mplcgOpt }; + +const std::vector printExclude = { &opts::run, + &opts::optionOpt, + &opts::infile }; + +std::string GetCommonOptionsStr(const std::vector &exclude) { + std::string driverOptions; + for (auto const &opt : driverCategory.GetEnabledOptions()) { + if (!(std::find(std::begin(exclude), std::end(exclude), opt) != std::end(exclude))) { + for (const auto &val : opt->GetRawValues()) { + driverOptions += opt->GetName() + " " + val + " "; + } + } + } + + return driverOptions; +} + +void ConnectOptStr(std::string &optionStr, const std::string &exeName, + bool &firstComb, std::string &runStr) { + std::string connectSym = ""; + auto &drv = MplDriver::GetMplDriver(); + + if (drv.GetExeOptions().find(exeName) != drv.GetExeOptions().end()) { + if (!firstComb) { + runStr += (":" + exeName); + optionStr += ":"; + } else { + runStr += exeName; + firstComb = false; + } + auto it = drv.GetExeOptions().find(exeName); + for (auto &opt : it->second) { + optionStr += (" " + opt); + } + } +} + +void PrintMpl2mplMeCgCommand(const std::string *inputFile, bool isBeforeParse) { + auto &drv = MplDriver::GetMplDriver(); + if (drv.GetExeOptions().find(kBinNameMe) == drv.GetExeOptions().end() && + drv.GetExeOptions().find(kBinNameMpl2mpl) == drv.GetExeOptions().end() && + drv.GetExeOptions().find(kBinNameMplcg) == drv.GetExeOptions().end()) { + return; + } + std::string runStr = "--run="; + std::string optionStr; + optionStr += "--option=\""; + bool firstComb = true; + + ConnectOptStr(optionStr, kBinNameMe, firstComb, runStr); + ConnectOptStr(optionStr, kBinNameMpl2mpl, firstComb, runStr); + ConnectOptStr(optionStr, kBinNameMplcg, firstComb, runStr); + optionStr += "\""; + + std::string driverOptions = GetCommonOptionsStr(extraExclude); + std::string inputs; + if (inputFile == nullptr) { + for (const auto &in : MplDriver::GetMplDriver().GetInputFiles()) { + inputs += " " + in; + } + inputFile = &inputs; + } + + std::string state = (isBeforeParse == true) ? "Starting: " : "Finihsed: "; + LogInfo::MapleLogger() << state << drv.GetExeFolder() << "maple " + << runStr << " " << optionStr << " " + << driverOptions << " " << *inputFile << '\n'; +} + +void PrintCombCompilerCommand(const std::string &input) { + auto &drv = MplDriver::GetMplDriver(); + + std::string optionStr; + std::string runStr = "--run="; + + if (drv.GetRunMode() == kCustomRun) { + PrintMpl2mplMeCgCommand(&input, true); + return; + } + + /* For kAutoRun */ + if (opts::o0) { + optionStr = " -O0"; + } else if (opts::o1) { + optionStr = " -O1"; + } else if (opts::o2) { + optionStr = " -O0"; + } else if (opts::os) { + optionStr = " -Os"; + } + + LogInfo::MapleLogger() << "Starting: " << drv.GetExeFolder() << "maple " + << optionStr << " " << GetCommonOptionsStr(printExclude) + << " " << input << '\n'; +} + +int DriverProcessing(int argc, char **argv) { + cl::CommandLine::GetCommandLine().Parse(argc, argv); + auto &drv = MplDriver::GetMplDriver(); + + auto ret = drv.Processing(); + if (ret != kErrorNoError) { + PrintErrorMessage(ret); + return 0; + } + + auto &compilerFactory = CompilerFactory::GetInstance(); + ret = compilerFactory.Compile(drv.GetActions()); + if (ret != kErrorNoError) { + PrintErrorMessage(ret); + return 0; + } + + if (opts::debug) { + PrintMpl2mplMeCgCommand(nullptr, false); + } + + if (!opts::saveTempOpt.IsEnabledByUser()) { + std::vector tmpFiles; + + for (auto &action : drv.GetActions()) { + action->GetCompiler()->GetTmpFilesToDelete(*action, tmpFiles); + } + + ret = compilerFactory.DeleteTmpFiles(tmpFiles, drv.GetSaveFiles(), + drv.GetInputFiles(), drv.GetActions()); + } + + return 0; +} + int main(int argc, char **argv) { int ret = DriverProcessing(argc, argv); return ret; diff --git a/src/mapleall/maple_driver/src/maple_comb_compiler.cpp b/src/mapleall/maple_driver/src/maple_comb_compiler.cpp index 64623f455f..b93bdac0f1 100644 --- a/src/mapleall/maple_driver/src/maple_comb_compiler.cpp +++ b/src/mapleall/maple_driver/src/maple_comb_compiler.cpp @@ -12,20 +12,38 @@ * FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ -#include -#include + #include "compiler.h" +#include "error_code.h" +#include "maple_driver.h" +#include "mpl_options.h" #include "string_utils.h" #include "mpl_logging.h" +#include "driver_options.h" #include "driver_runner.h" #include "inline.h" #include "me_phase_manager.h" #include "constantfold.h" +#include +#include +#include + +#include "default_options.def" + +namespace { + template + bool Contains(const TContainer &container, const TData &data) { + return (std::find(std::begin(container), std::end(container), data) != container.end()); + }; +} + +void PrintCombCompilerCommand(const std::string &input); + namespace maple { using namespace mapleOption; -std::string MapleCombCompiler::GetInputFileName(const MplOptions &, const Action &action) const { +std::string MapleCombCompiler::GetInputFileName(const Action &action) const { if (action.IsItFirstRealAction()) { return action.GetInputFile(); } @@ -38,7 +56,7 @@ std::string MapleCombCompiler::GetInputFileName(const MplOptions &, const Action return action.GetFullOutputName() + ".mpl"; } -void MapleCombCompiler::GetTmpFilesToDelete(const MplOptions&, const Action &action, +void MapleCombCompiler::GetTmpFilesToDelete(const Action &action, std::vector &tempFiles) const { std::string filePath; filePath = action.GetFullOutputName() + ".data.muid"; @@ -57,157 +75,249 @@ void MapleCombCompiler::GetTmpFilesToDelete(const MplOptions&, const Action &act } } -std::unordered_set MapleCombCompiler::GetFinalOutputs(const MplOptions&, - const Action &action) const { +std::unordered_set MapleCombCompiler::GetFinalOutputs(const Action &action) const { std::unordered_set finalOutputs; (void)finalOutputs.insert(action.GetFullOutputName() + ".VtableImpl.mpl"); return finalOutputs; } -void MapleCombCompiler::PrintCommand(const MplOptions &options, const Action &action) const { +void MapleCombCompiler::PrintCommand(const Action &action) const { + auto &drv = MplDriver::GetMplDriver(); + std::string runStr = "--run="; std::ostringstream optionStr; optionStr << "--option=\""; std::string connectSym = ""; bool firstComb = false; - if (options.GetExeOptions().find(kBinNameMe) != options.GetExeOptions().end()) { + + if (drv.GetExeOptions().find(kBinNameMe) != drv.GetExeOptions().end()) { runStr += "me"; - auto it = options.GetExeOptions().find(kBinNameMe); - for (const mapleOption::Option &opt : it->second) { - connectSym = !opt.Args().empty() ? "=" : ""; - auto prefixStr = opt.GetPrefix(); - optionStr << " " << prefixStr << opt.OptionKey() << connectSym << opt.Args(); + auto it = drv.GetExeOptions().find(kBinNameMe); + + for (auto &opt : it->second) { + optionStr << " " << opt; } + firstComb = true; } - if (options.GetExeOptions().find(kBinNameMpl2mpl) != options.GetExeOptions().end()) { + + if (drv.GetExeOptions().find(kBinNameMpl2mpl) != drv.GetExeOptions().end()) { if (firstComb) { runStr += ":mpl2mpl"; optionStr << ":"; } else { runStr += "mpl2mpl"; } - auto it = options.GetExeOptions().find(kBinNameMpl2mpl); - for (const mapleOption::Option &opt : it->second) { - connectSym = !opt.Args().empty() ? "=" : ""; - auto prefixStr = opt.GetPrefix(); - optionStr << " " << prefixStr << opt.OptionKey() << connectSym << opt.Args(); + auto it = drv.GetExeOptions().find(kBinNameMpl2mpl); + for (auto &opt : it->second) { + optionStr << " " << opt; } } - std::string driverOptions = options.GetCommonOptionsStr(); - + std::string driverOptions = GetCommonOptionsStr(extraExclude); optionStr << "\""; - LogInfo::MapleLogger() << "Starting:" << options.GetExeFolder() << "maple " << runStr << " " << optionStr.str() << " " - << driverOptions << " " << GetInputFileName(options, action) << '\n'; + LogInfo::MapleLogger() << "Starting:" << drv.GetExeFolder() << "maple " + << runStr << " " << optionStr.str() << " " + << driverOptions << " " << GetInputFileName(action) << '\n'; } -ErrorCode MapleCombCompiler::MakeMeOptions(const MplOptions &options, DriverRunner &runner) { - auto it = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMe); - if (it == options.GetRunningExes().end()) { - return kErrorNoError; - } +ErrorCode MapleCombCompiler::MakeMeOptions(DriverRunner &runner) { MeOption &meOption = MeOption::GetInstance(); - auto itOpt = options.GetExeOptions().find(kBinNameMe); - if (itOpt == options.GetExeOptions().end()) { - LogInfo::MapleLogger() << "no me input options\n"; - return kErrorCompileFail; + auto &drv = MplDriver::GetMplDriver(); + + auto itOpt = drv.GetExeOptions().find(kBinNameMe); + if (itOpt != drv.GetExeOptions().end()) { + const auto &meOptions = itOpt->second; + const std::deque strMeOptions(meOptions.begin(), meOptions.end()); + cl::CommandLine::GetCommandLine().HandleInputArgs(strMeOptions, meCategory); + } else { + cl::CommandLine::GetCommandLine().HandleInputArgs({}, meCategory); + } + + for (auto &arg : cl::CommandLine::GetCommandLine().badCLArgs) { + if (!FileUtils::IsFileExists(arg.first)) { + LogInfo::MapleLogger() << "Unknown option for me tool: " << arg.first << "\n"; + return kErrorInvalidParameter; + } } - bool result = meOption.SolveOptions(itOpt->second, options.HasSetDebugFlag()); + + bool result = meOption.SolveOptions(opts::debug); if (result == false) { LogInfo::MapleLogger() << "Meet error me options\n"; return kErrorCompileFail; } - MeOption::generalRegOnly = options.HasSetGeneralRegOnly(); - MeOption::npeCheckMode = options.GetNpeCheckMode(); - MeOption::isNpeCheckAll = options.IsNpeCheckAll(); - MeOption::boundaryCheckMode = options.GetBoundaryCheckMode(); - MeOption::safeRegionMode = options.IsSafeRegion(); + + /* generalRegOnly is set as WA: if generalRegOnly is set for mplcg, it should be set for me too */ + MeOption::generalRegOnly = drv.drvOptions.generalRegOnly; + + /* npeCheckMode and boundaryCheckMode can not be handled by option directly + * because these modes are enums dependent from several options */ + MeOption::npeCheckMode = drv.drvOptions.npeCheckMode; + MeOption::boundaryCheckMode = drv.drvOptions.boundaryCheckMode; + + MeOption::isNpeCheckAll = opts::npeDynamicCheckAll; + MeOption::safeRegionMode = opts::safeRegionOption; + // Set me options for driver runner runner.SetMeOptions(&MeOption::GetInstance()); + return kErrorNoError; } -ErrorCode MapleCombCompiler::MakeMpl2MplOptions(const MplOptions &options, DriverRunner &runner) { - auto it = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMpl2mpl); - if (it == options.GetRunningExes().end()) { - return kErrorNoError; - } +ErrorCode MapleCombCompiler::MakeMpl2MplOptions(DriverRunner &runner) { auto &mpl2mplOption = Options::GetInstance(); - auto itOption = options.GetExeOptions().find(kBinNameMpl2mpl); - if (itOption == options.GetExeOptions().end()) { - LogInfo::MapleLogger() << "no mpl2mpl input options\n"; - return kErrorCompileFail; + auto &drv = MplDriver::GetMplDriver(); + + auto itOpt = drv.GetExeOptions().find(kBinNameMpl2mpl); + if (itOpt != drv.GetExeOptions().end()) { + const auto &mplOptions = itOpt->second; + const std::deque strMplOptions(mplOptions.begin(), mplOptions.end()); + cl::CommandLine::GetCommandLine().HandleInputArgs(strMplOptions, mpl2mplCategory); + } else { + cl::CommandLine::GetCommandLine().HandleInputArgs({}, mpl2mplCategory); + } + + for (auto &arg : cl::CommandLine::GetCommandLine().badCLArgs) { + if (!FileUtils::IsFileExists(arg.first)) { + LogInfo::MapleLogger() << "Unknown option for mpl2mpl tool: " << arg.first << "\n"; + return kErrorInvalidParameter; + } } - bool result = mpl2mplOption.SolveOptions(itOption->second, options.HasSetDebugFlag()); + + bool result = mpl2mplOption.SolveOptions(opts::debug); if (result == false) { LogInfo::MapleLogger() << "Meet error mpl2mpl options\n"; return kErrorCompileFail; } + // Set mpl2mpl options for driver runner runner.SetMpl2mplOptions(&Options::GetInstance()); return kErrorNoError; } -std::string MapleCombCompiler::DecideOutExe(const MplOptions &options) { - std::string printOutExe = ""; - auto &selectExes = options.GetSelectedExes(); - if (selectExes[selectExes.size() - 1] == kBinNameMapleComb) { - auto it = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMpl2mpl); - if (it != options.GetRunningExes().end()) { - printOutExe = kBinNameMpl2mpl; - return printOutExe; +ErrorCode MapleCombCompiler::AppendCombOptions(MIRSrcLang srcLang) { + ErrorCode ret = kErrorNoError; + auto &drv = MplDriver::GetMplDriver(); + + if (opts::o0) { + ret = drv.UpdateExeOptions(kBinNameMe, kMeDefaultOptionsO0, + sizeof(kMeDefaultOptionsO0) / sizeof(MplOption)); + if (ret != kErrorNoError) { + return ret; } - it = std::find(options.GetRunningExes().begin(), options.GetRunningExes().end(), kBinNameMe); - if (it != options.GetRunningExes().end()) { - printOutExe = kBinNameMe; - return printOutExe; + if (srcLang != kSrcLangC) { + ret = drv.UpdateExeOptions(kBinNameMpl2mpl, kMpl2MplDefaultOptionsO0, + sizeof(kMpl2MplDefaultOptionsO0) / sizeof(MplOption)); + } else { + ret = drv.UpdateExeOptions(kBinNameMpl2mpl, kMpl2MplDefaultOptionsO0ForC, + sizeof(kMpl2MplDefaultOptionsO0ForC) / sizeof(MplOption)); + } + + if (ret != kErrorNoError) { + return ret; + } + } else if (opts::o2) { + if (srcLang != kSrcLangC) { + ret = drv.UpdateExeOptions(kBinNameMe, kMeDefaultOptionsO2, + sizeof(kMeDefaultOptionsO2) / sizeof(MplOption)); + if (ret != kErrorNoError) { + return ret; + } + ret = drv.UpdateExeOptions(kBinNameMpl2mpl, kMpl2MplDefaultOptionsO2, + sizeof(kMpl2MplDefaultOptionsO2) / sizeof(MplOption)); + } else { + ret = drv.UpdateExeOptions(kBinNameMe, kMeDefaultOptionsO2ForC, + sizeof(kMeDefaultOptionsO2ForC) / sizeof(MplOption)); + if (ret != kErrorNoError) { + return ret; + } + ret = drv.UpdateExeOptions(kBinNameMpl2mpl, kMpl2MplDefaultOptionsO2ForC, + sizeof(kMpl2MplDefaultOptionsO2ForC) / sizeof(MplOption)); + } + if (ret != kErrorNoError) { + return ret; + } + } else if (opts::os) { + if (srcLang == kSrcLangJava) { + return kErrorNotImplement; + } + + ret = drv.UpdateExeOptions(kBinNameMe, kMeDefaultOptionsOs, + sizeof(kMeDefaultOptionsOs) / sizeof(MplOption)); + if (ret != kErrorNoError) { + return ret; + } + ret = drv.UpdateExeOptions(kBinNameMpl2mpl, kMpl2MplDefaultOptionsOs, + sizeof(kMpl2MplDefaultOptionsOs) / sizeof(MplOption)); + } + + return ret; +} + +const std::string &MapleCombCompiler::DecideOutExe() const { + const auto &tools = MplDriver::GetMplDriver().GetTools(); + + const std::string *lastMplTool = &kBinNameMe; + for (const auto &tool : tools) { + if (tool == kBinNameMpl2mpl) { + lastMplTool = &kBinNameMpl2mpl; + } else if (tool == kBinNameMplcg) { + lastMplTool = &kBinNameMplcg; } } - return selectExes[selectExes.size() - 1]; + + return *lastMplTool; } -ErrorCode MapleCombCompiler::Compile(MplOptions &options, const Action &action, +ErrorCode MapleCombCompiler::Compile(const Action &action, std::unique_ptr &theModule) { - std::string fileName = GetInputFileName(options, action); + std::string fileName = GetInputFileName(action); bool fileParsed = true; if (theModule == nullptr) { theModule = std::make_unique(fileName); fileParsed = false; } - options.PrintCommand(&action); + + PrintCombCompilerCommand(fileName); + LogInfo::MapleLogger() << "Starting maplecomb\n"; - theModule->InitPartO2List(options.GetPartO2List()); - DriverRunner runner(theModule.get(), options.GetSelectedExes(), action.GetInputFileType(), fileName, - fileName, fileName, options.WithDwarf(), fileParsed, - options.HasSetTimePhases(), options.HasSetGenVtableImpl(), - options.HasSetGenMeMpl(), options.HasSetGenMapleBC(), - options.HasSetGenLMBC()); - ErrorCode ret = kErrorNoError; + theModule->InitPartO2List(opts::partO2); + DriverRunner runner(theModule.get(), action.internalTools, action.GetInputFileType(), fileName, + fileName, fileName, opts::withDwarf, fileParsed, + opts::timePhase, opts::genVtable, opts::genMeMpl, + opts::genMapleBC, opts::genLMBC); MIRParser parser(*theModule); MIRSrcLang srcLang = kSrcLangUnknown; - ret = runner.ParseSrcLang(srcLang); + ErrorCode ret = runner.ParseSrcLang(srcLang); if (ret != kErrorNoError) { return ret; } theModule->SetSrcLang(srcLang); // Add running phases and default options according to the srcLang (only for auto mode) - ret = options.AppendCombOptions(theModule->GetSrcLang()); - if (ret != kErrorNoError) { - return ret; + if (MplDriver::GetMplDriver().GetRunMode() != RunMode::kCustomRun) { + ret = AppendCombOptions(theModule->GetSrcLang()); + if (ret != kErrorNoError) { + return ret; + } } - ret = MakeMeOptions(options, runner); - if (ret != kErrorNoError) { - return ret; + if (Contains(action.internalTools, kBinNameMe)) { + ret = MakeMeOptions(runner); + if (ret != kErrorNoError) { + return ret; + } } - ret = MakeMpl2MplOptions(options, runner); - if (ret != kErrorNoError) { - return ret; + + if (Contains(action.internalTools, kBinNameMpl2mpl)) { + ret = MakeMpl2MplOptions(runner); + if (ret != kErrorNoError) { + return ret; + } } - runner.SetPrintOutExe(DecideOutExe(options)); + + runner.SetPrintOutExe(DecideOutExe()); // Parse the input file ret = runner.ParseInput(); @@ -215,8 +325,8 @@ ErrorCode MapleCombCompiler::Compile(MplOptions &options, const Action &action, return ret; } - if (options.HasSetDebugFlag()) { - PrintCommand(options, action); + if (opts::debug) { + PrintCommand(action); } ErrorCode nErr = runner.Run(); return nErr; diff --git a/src/mapleall/maple_driver/src/maple_comb_compiler_wrapper.cpp b/src/mapleall/maple_driver/src/maple_comb_compiler_wrapper.cpp index 92974c8829..184c59cf20 100644 --- a/src/mapleall/maple_driver/src/maple_comb_compiler_wrapper.cpp +++ b/src/mapleall/maple_driver/src/maple_comb_compiler_wrapper.cpp @@ -13,6 +13,7 @@ * See the Mulan PSL v2 for more details. */ #include "compiler.h" +#include "driver_options.h" #include "types_def.h" #include @@ -26,67 +27,21 @@ const std::string &MapleCombCompilerWrp::GetBinName() const { return kTmpBin; } -std::string MapleCombCompilerWrp::GetBinPath(const MplOptions&) const { +std::string MapleCombCompilerWrp::GetBinPath() const { return FileUtils::SafeGetenv(kMapleRoot) + "/output/" + FileUtils::SafeGetenv("MAPLE_BUILD_TYPE") + "/bin/"; } -DefaultOption MapleCombCompilerWrp::GetDefaultOptions(const MplOptions &mplOptions, - const Action&) const { - auto options = mplOptions.GetOptions(); - std::vector