From b8fed00b8166815141d639989082a8bf18c94ddb Mon Sep 17 00:00:00 2001 From: Jaime Gonzalez Date: Fri, 10 Jan 2025 10:59:35 +0100 Subject: [PATCH 1/3] Extract common Tool functions to a separate header --- source/citnames/CMakeLists.txt | 1 + source/citnames/source/semantic/Common.cc | 124 +++++++++++++++++++++ source/citnames/source/semantic/Common.h | 31 ++++++ source/citnames/source/semantic/ToolGcc.cc | 98 +--------------- 4 files changed, 160 insertions(+), 94 deletions(-) create mode 100644 source/citnames/source/semantic/Common.cc create mode 100644 source/citnames/source/semantic/Common.h diff --git a/source/citnames/CMakeLists.txt b/source/citnames/CMakeLists.txt index 18c42133f..54545749a 100644 --- a/source/citnames/CMakeLists.txt +++ b/source/citnames/CMakeLists.txt @@ -23,6 +23,7 @@ target_sources(citnames_a PRIVATE source/Citnames.cc source/semantic/Build.cc + source/semantic/Common.cc source/semantic/Parsers.cc source/semantic/Semantic.cc source/semantic/ToolAny.cc diff --git a/source/citnames/source/semantic/Common.cc b/source/citnames/source/semantic/Common.cc new file mode 100644 index 000000000..d24ac5d4a --- /dev/null +++ b/source/citnames/source/semantic/Common.cc @@ -0,0 +1,124 @@ +/* Copyright (C) 2012-2024 by László Nagy + This file is part of Bear. + + Bear is a tool to generate compilation database for clang tooling. + + Bear is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bear is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Common.h" + +#include +#include + +using namespace cs::semantic; + +namespace { + + std::tuple< + Arguments, + std::vector, + std::optional> + split(const CompilerFlags& flags) + { + Arguments arguments; + std::vector sources; + std::optional output; + + for (const auto& flag : flags) { + switch (flag.type) { + case CompilerFlagType::SOURCE: { + auto candidate = fs::path(flag.arguments.front()); + sources.emplace_back(std::move(candidate)); + break; + } + case CompilerFlagType::KIND_OF_OUTPUT_OUTPUT: { + auto candidate = fs::path(flag.arguments.back()); + output = std::make_optional(std::move(candidate)); + break; + } + case CompilerFlagType::LINKER: + case CompilerFlagType::PREPROCESSOR_MAKE: + case CompilerFlagType::DIRECTORY_SEARCH_LINKER: + break; + default: { + std::copy(flag.arguments.begin(), flag.arguments.end(), std::back_inserter(arguments)); + break; + } + } + } + return std::make_tuple(arguments, sources, output); + } + + bool is_compiler_query(const CompilerFlags& flags) + { + // no flag is a no compilation + if (flags.empty()) { + return true; + } + // otherwise check if this was a version query of a help + return std::any_of(flags.begin(), flags.end(), [](const auto& flag) { + return (flag.type == CompilerFlagType::KIND_OF_OUTPUT_INFO); + }); + } + + bool linking(const CompilerFlags& flags) + { + return std::none_of(flags.begin(), flags.end(), [](auto flag) { + return (flag.type == CompilerFlagType::KIND_OF_OUTPUT_NO_LINKING); + }); + } +} + +rust::Result cs::semantic::compilation_impl(const FlagsByName& flags, const Execution& execution, + std::function create_argument_list_func, + std::function is_preprocessor_func) +{ + const auto& parser = Repeat( + OneOf( + FlagParser(flags), + SourceMatcher(), + EverythingElseFlagMatcher())); + + const Arguments& input_arguments = create_argument_list_func(execution); + return parse(parser, input_arguments) + .and_then([&execution, is_preprocessor_func](auto flags) -> rust::Result { + if (is_compiler_query(flags)) { + SemanticPtr result = std::make_shared(); + return rust::Ok(std::move(result)); + } + if (is_preprocessor_func(flags)) { + SemanticPtr result = std::make_shared(); + return rust::Ok(std::move(result)); + } + + auto [arguments, sources, output] = split(flags); + // Validate: must have source files. + if (sources.empty()) { + return rust::Err(std::runtime_error("Source files not found for compilation.")); + } + // TODO: introduce semantic type for linking + if (linking(flags)) { + arguments.insert(arguments.begin(), "-c"); + } + + SemanticPtr result = std::make_shared( + execution.working_dir, + execution.executable, + std::move(arguments), + std::move(sources), + std::move(output)); + return rust::Ok(std::move(result)); + }); +} diff --git a/source/citnames/source/semantic/Common.h b/source/citnames/source/semantic/Common.h new file mode 100644 index 000000000..dd531a7f2 --- /dev/null +++ b/source/citnames/source/semantic/Common.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2012-2024 by László Nagy + This file is part of Bear. + + Bear is a tool to generate compilation database for clang tooling. + + Bear is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bear is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "Semantic.h" +#include "Parsers.h" + +#include "libresult/Result.h" + +namespace cs::semantic { + rust::Result compilation_impl(const FlagsByName& flags, const Execution& execution, + std::function create_argument_list_func, + std::function is_preprocessor_func); +} diff --git a/source/citnames/source/semantic/ToolGcc.cc b/source/citnames/source/semantic/ToolGcc.cc index 42311f405..448b19254 100644 --- a/source/citnames/source/semantic/ToolGcc.cc +++ b/source/citnames/source/semantic/ToolGcc.cc @@ -19,6 +19,7 @@ #include "ToolGcc.h" #include "Parsers.h" +#include "Common.h" #include "libsys/Path.h" @@ -68,18 +69,6 @@ namespace { return input_arguments; } - bool is_compiler_query(const CompilerFlags& flags) - { - // no flag is a no compilation - if (flags.empty()) { - return true; - } - // otherwise check if this was a version query of a help - return std::any_of(flags.begin(), flags.end(), [](const auto& flag) { - return (flag.type == CompilerFlagType::KIND_OF_OUTPUT_INFO); - }); - } - bool is_prerpocessor(const CompilerFlags& flags) { // one of those make dependency generation also not count as compilation. @@ -93,47 +82,6 @@ namespace { || ((flag.type == CompilerFlagType::PREPROCESSOR_MAKE) && (NO_COMPILATION_FLAG.find(candidate) != NO_COMPILATION_FLAG.end())); }); } - - bool linking(const CompilerFlags& flags) - { - return std::none_of(flags.begin(), flags.end(), [](auto flag) { - return (flag.type == CompilerFlagType::KIND_OF_OUTPUT_NO_LINKING); - }); - } - - std::tuple< - Arguments, - std::vector, - std::optional - > split(const CompilerFlags &flags) { - Arguments arguments; - std::vector sources; - std::optional output; - - for (const auto &flag : flags) { - switch (flag.type) { - case CompilerFlagType::SOURCE: { - auto candidate = fs::path(flag.arguments.front()); - sources.emplace_back(std::move(candidate)); - break; - } - case CompilerFlagType::KIND_OF_OUTPUT_OUTPUT: { - auto candidate = fs::path(flag.arguments.back()); - output = std::make_optional(std::move(candidate)); - break; - } - case CompilerFlagType::LINKER: - case CompilerFlagType::PREPROCESSOR_MAKE: - case CompilerFlagType::DIRECTORY_SEARCH_LINKER: - break; - default: { - std::copy(flag.arguments.begin(), flag.arguments.end(), std::back_inserter(arguments)); - break; - } - } - } - return std::make_tuple(arguments, sources, output); - } } namespace cs::semantic { @@ -268,46 +216,8 @@ namespace cs::semantic { return compilation(FLAG_DEFINITION, execution); } - rust::Result ToolGcc::compilation(const FlagsByName &flags, const Execution &execution) { - const auto &parser = - Repeat( - OneOf( - FlagParser(flags), - SourceMatcher(), - EverythingElseFlagMatcher() - ) - ); - - const Arguments &input_arguments = create_argument_list(execution); - return parse(parser, input_arguments) - .and_then([&execution](auto flags) -> rust::Result { - if (is_compiler_query(flags)) { - SemanticPtr result = std::make_shared(); - return rust::Ok(std::move(result)); - } - if (is_prerpocessor(flags)) { - SemanticPtr result = std::make_shared(); - return rust::Ok(std::move(result)); - } - - auto[arguments, sources, output] = split(flags); - // Validate: must have source files. - if (sources.empty()) { - return rust::Err(std::runtime_error("Source files not found for compilation.")); - } - // TODO: introduce semantic type for linking - if (linking(flags)) { - arguments.insert(arguments.begin(), "-c"); - } - - SemanticPtr result = std::make_shared( - execution.working_dir, - execution.executable, - std::move(arguments), - std::move(sources), - std::move(output) - ); - return rust::Ok(std::move(result)); - }); + rust::Result ToolGcc::compilation(const FlagsByName& flags, const Execution& execution) + { + return compilation_impl(flags, execution, create_argument_list, is_prerpocessor); } } From d54d35e235325ba2832456b7f1a5b7680cc32fb9 Mon Sep 17 00:00:00 2001 From: Jaime Gonzalez Date: Fri, 10 Jan 2025 10:59:58 +0100 Subject: [PATCH 2/3] Add ifort and ifx support to citnames --- source/citnames/CMakeLists.txt | 2 + source/citnames/source/semantic/Build.cc | 2 + .../source/semantic/ToolIntelFortran.cc | 143 ++++++++++++++++++ .../source/semantic/ToolIntelFortran.h | 37 +++++ source/citnames/test/ToolIntelFortranTest.cc | 118 +++++++++++++++ 5 files changed, 302 insertions(+) create mode 100644 source/citnames/source/semantic/ToolIntelFortran.cc create mode 100644 source/citnames/source/semantic/ToolIntelFortran.h create mode 100644 source/citnames/test/ToolIntelFortranTest.cc diff --git a/source/citnames/CMakeLists.txt b/source/citnames/CMakeLists.txt index 54545749a..789ca508b 100644 --- a/source/citnames/CMakeLists.txt +++ b/source/citnames/CMakeLists.txt @@ -30,6 +30,7 @@ target_sources(citnames_a source/semantic/ToolClang.cc source/semantic/ToolCuda.cc source/semantic/ToolGcc.cc + source/semantic/ToolIntelFortran.cc source/semantic/ToolWrapper.cc source/semantic/ToolExtendingWrapper.cc INTERFACE @@ -67,6 +68,7 @@ if (ENABLE_UNIT_TESTS) test/ParserTest.cc test/ToolClangTest.cc test/ToolGccTest.cc + test/ToolIntelFortranTest.cc test/ToolWrapperTest.cc ) diff --git a/source/citnames/source/semantic/Build.cc b/source/citnames/source/semantic/Build.cc index 1213a8ccb..e8ef21ad4 100644 --- a/source/citnames/source/semantic/Build.cc +++ b/source/citnames/source/semantic/Build.cc @@ -22,6 +22,7 @@ #include "ToolGcc.h" #include "ToolClang.h" #include "ToolCuda.h" +#include "ToolIntelFortran.h" #include "ToolWrapper.h" #include "ToolExtendingWrapper.h" #include "Convert.h" @@ -44,6 +45,7 @@ namespace { std::make_shared(), std::make_shared(), std::make_shared(), + std::make_shared(), }; for (auto && compiler : cfg.compilers_to_recognize) { tools.emplace_front(std::make_shared(std::move(compiler))); diff --git a/source/citnames/source/semantic/ToolIntelFortran.cc b/source/citnames/source/semantic/ToolIntelFortran.cc new file mode 100644 index 000000000..b1aa8db62 --- /dev/null +++ b/source/citnames/source/semantic/ToolIntelFortran.cc @@ -0,0 +1,143 @@ +/* Copyright (C) 2012-2024 by László Nagy + This file is part of Bear. + + Bear is a tool to generate compilation database for clang tooling. + + Bear is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bear is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "ToolIntelFortran.h" +#include "Common.h" +#include "Parsers.h" +#include "libsys/Path.h" + +#include +#include +#include +#include +#include + +using namespace cs::semantic; + +namespace { + Arguments create_argument_list(const Execution& execution) + { + Arguments input_arguments; + std::copy(execution.arguments.begin(), execution.arguments.end(), std::back_inserter(input_arguments)); + return input_arguments; + } + + bool is_preprocessor(const CompilerFlags& flags) + { + return std::any_of(flags.begin(), flags.end(), [](const auto& flag) { + const std::string& candidate = flag.arguments.front(); + + static const std::set NO_COMPILATION_FLAG = { "-preprocess-only", "-P", "-E", "-Ep" }; + + return ((flag.type == CompilerFlagType::KIND_OF_OUTPUT_NO_LINKING) && (NO_COMPILATION_FLAG.find(candidate) != NO_COMPILATION_FLAG.end())) + || ((flag.type == CompilerFlagType::PREPROCESSOR_MAKE)); + }); + } +} + +namespace cs::semantic { + + const FlagsByName ToolIntelFortran::FLAG_DEFINITION = { + {"-c", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT_NO_LINKING}}, + {"-S", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT_NO_LINKING}}, + {"-E", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT_NO_LINKING}}, + {"-Ep", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT_NO_LINKING}}, + {"-preprocess-only", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT_NO_LINKING}}, + {"-P", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT_NO_LINKING}}, + {"-o", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::KIND_OF_OUTPUT_OUTPUT}}, + {"-debug", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::KIND_OF_OUTPUT}}, + {"-debug-parameters", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::KIND_OF_OUTPUT}}, + {"@", {MatchInstruction::PREFIX, CompilerFlagType::KIND_OF_OUTPUT}}, + {"-Fa", {MatchInstruction::PREFIX, CompilerFlagType::KIND_OF_OUTPUT}}, + {"-FA", {MatchInstruction::PREFIX, CompilerFlagType::KIND_OF_OUTPUT}}, + {"-shared", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT}}, + {"-dryrun", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT_INFO}}, + {"-dumpmachine", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT_INFO}}, + {"-v", {MatchInstruction::PREFIX, CompilerFlagType::KIND_OF_OUTPUT_INFO}}, + {"-V", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT_INFO}}, + {"--help", {MatchInstruction::PREFIX, CompilerFlagType::KIND_OF_OUTPUT_INFO}}, + {"--version", {MatchInstruction::EXACTLY, CompilerFlagType::KIND_OF_OUTPUT_INFO}}, + {"-D", {MatchInstruction::EXACTLY_WITH_1_OPT_GLUED_OR_SEP, CompilerFlagType::PREPROCESSOR}}, + {"-U", {MatchInstruction::EXACTLY_WITH_1_OPT_GLUED_OR_SEP, CompilerFlagType::PREPROCESSOR}}, + {"-include", {MatchInstruction::EXACTLY_WITH_1_OPT_GLUED_OR_SEP, CompilerFlagType::PREPROCESSOR}}, + {"-undef", {MatchInstruction::EXACTLY, CompilerFlagType::PREPROCESSOR}}, + {"-pthread", {MatchInstruction::EXACTLY, CompilerFlagType::PREPROCESSOR}}, + {"-MD", {MatchInstruction::EXACTLY, CompilerFlagType::PREPROCESSOR_MAKE}}, + {"-MMD", {MatchInstruction::EXACTLY, CompilerFlagType::PREPROCESSOR_MAKE}}, + {"-MF", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::PREPROCESSOR_MAKE}}, + {"-gen-dep", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::PREPROCESSOR_MAKE}}, + {"-C", {MatchInstruction::EXACTLY, CompilerFlagType::PREPROCESSOR}}, + {"-Xoption,cpp", {MatchInstruction::PREFIX, CompilerFlagType::PREPROCESSOR}}, + {"-Xoption,fpp", {MatchInstruction::PREFIX, CompilerFlagType::PREPROCESSOR}}, + {"-fpp", {MatchInstruction::EXACTLY, CompilerFlagType::PREPROCESSOR}}, + {"-nofpp", {MatchInstruction::EXACTLY, CompilerFlagType::PREPROCESSOR}}, + {"-Wp", {MatchInstruction::PREFIX, CompilerFlagType::PREPROCESSOR}}, + {"-I", {MatchInstruction::EXACTLY_WITH_1_OPT_GLUED_OR_SEP, CompilerFlagType::DIRECTORY_SEARCH}}, + {"-iquote", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::DIRECTORY_SEARCH}}, + {"-isystem", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::DIRECTORY_SEARCH}}, + {"-isysroot", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::DIRECTORY_SEARCH}}, + {"-L", {MatchInstruction::EXACTLY_WITH_1_OPT_GLUED_OR_SEP, CompilerFlagType::DIRECTORY_SEARCH_LINKER}}, + {"--sysroot", {MatchInstruction::EXACTLY_WITH_1_OPT_GLUED_WITH_EQ, CompilerFlagType::DIRECTORY_SEARCH}}, + {"-X", {MatchInstruction::EXACTLY, CompilerFlagType::DIRECTORY_SEARCH}}, + {"-l", {MatchInstruction::EXACTLY_WITH_1_OPT_GLUED_OR_SEP, CompilerFlagType::LINKER}}, + {"-nostartfiles", {MatchInstruction::EXACTLY, CompilerFlagType::LINKER}}, + {"-nodefaultlibs", {MatchInstruction::EXACTLY, CompilerFlagType::LINKER}}, + {"-nostdlib", {MatchInstruction::EXACTLY, CompilerFlagType::LINKER}}, + {"-r", {MatchInstruction::EXACTLY, CompilerFlagType::LINKER}}, + {"-s", {MatchInstruction::EXACTLY, CompilerFlagType::LINKER}}, + {"-shared-intel", {MatchInstruction::EXACTLY, CompilerFlagType::LINKER}}, + {"shared-libgcc", {MatchInstruction::EXACTLY, CompilerFlagType::LINKER}}, + {"-static", {MatchInstruction::EXACTLY, CompilerFlagType::LINKER}}, + {"-static-intel", {MatchInstruction::EXACTLY, CompilerFlagType::LINKER}}, + {"-static-libgcc", {MatchInstruction::EXACTLY, CompilerFlagType::LINKER}}, + {"-T", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::LINKER}}, + {"-Xlinker", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::LINKER}}, + {"-Xoption,link", {MatchInstruction::PREFIX, CompilerFlagType::LINKER}}, + {"-u", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::LINKER}}, + {"-Wl", {MatchInstruction::PREFIX, CompilerFlagType::LINKER}}, + {"-Xoption,asm", {MatchInstruction::PREFIX, CompilerFlagType::OTHER}}, + {"-std", {MatchInstruction::EXACTLY_WITH_1_OPT_GLUED_WITH_EQ, CompilerFlagType::OTHER}}, + {"-O", {MatchInstruction::PREFIX, CompilerFlagType::OTHER}}, + {"-g", {MatchInstruction::PREFIX, CompilerFlagType::OTHER}}, + {"-f", {MatchInstruction::PREFIX, CompilerFlagType::OTHER}}, + {"-m", {MatchInstruction::PREFIX, CompilerFlagType::OTHER}}, + {"-x", {MatchInstruction::PREFIX, CompilerFlagType::OTHER}}, + {"-diag-", {MatchInstruction::PREFIX, CompilerFlagType::OTHER}}, + {"-no", {MatchInstruction::PREFIX, CompilerFlagType::OTHER}}, + {"-gen-interfaces", {MatchInstruction::EXACTLY_WITH_1_OPT_SEP, CompilerFlagType::OTHER}}, + {"-nogen-interfaces", {MatchInstruction::EXACTLY, CompilerFlagType::OTHER}}, + {"--", {MatchInstruction::PREFIX, CompilerFlagType::OTHER}}, + }; + + rust::Result ToolIntelFortran::recognize(const Execution& execution) const + { + if (is_compiler_call(execution.executable)) { + return compilation_impl(FLAG_DEFINITION, execution, create_argument_list, is_preprocessor); + } + return rust::Ok(SemanticPtr()); + } + + bool ToolIntelFortran::is_compiler_call(const fs::path& program) const + { + static const auto pattern = std::regex(R"(^([^-]*-)*(ifx|ifort)(-?\w+(\.\d+){0,2})?$)"); + + std::cmatch m; + return std::regex_match(program.filename().c_str(), m, pattern); + } +} diff --git a/source/citnames/source/semantic/ToolIntelFortran.h b/source/citnames/source/semantic/ToolIntelFortran.h new file mode 100644 index 000000000..f34fc30c6 --- /dev/null +++ b/source/citnames/source/semantic/ToolIntelFortran.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2012-2024 by László Nagy + This file is part of Bear. + + Bear is a tool to generate compilation database for clang tooling. + + Bear is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bear is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "Tool.h" +#include "Parsers.h" + +namespace cs::semantic { + + struct ToolIntelFortran : public Tool { + + [[nodiscard]] + rust::Result recognize(const Execution &execution) const override; + + protected: + [[nodiscard]] bool is_compiler_call(const fs::path& program) const; + + static const FlagsByName FLAG_DEFINITION; + }; +} diff --git a/source/citnames/test/ToolIntelFortranTest.cc b/source/citnames/test/ToolIntelFortranTest.cc new file mode 100644 index 000000000..f17019853 --- /dev/null +++ b/source/citnames/test/ToolIntelFortranTest.cc @@ -0,0 +1,118 @@ +/* Copyright (C) 2012-2024 by László Nagy + This file is part of Bear. + + Bear is a tool to generate compilation database for clang tooling. + + Bear is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bear is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "gtest/gtest.h" + +#include "semantic/Tool.h" +#include "semantic/ToolIntelFortran.h" + +using namespace cs::semantic; + +namespace { + + TEST(ToolIntelFortran, is_compiler_call) { + struct Expose : public ToolIntelFortran { + using ToolIntelFortran::is_compiler_call; + }; + Expose sut; + + EXPECT_TRUE(sut.is_compiler_call("ifx")); + EXPECT_TRUE(sut.is_compiler_call("/usr/bin/ifx")); + EXPECT_TRUE(sut.is_compiler_call("ifort")); + EXPECT_TRUE(sut.is_compiler_call("/usr/bin/ifort")); + EXPECT_TRUE(sut.is_compiler_call("/opt/intel/oneapi/compiler/2025.0/bin/ifx")); + EXPECT_TRUE(sut.is_compiler_call("ifx2023")); + EXPECT_TRUE(sut.is_compiler_call("ifx2025.0")); + EXPECT_TRUE(sut.is_compiler_call("ifx-avx2")); + + EXPECT_FALSE(sut.is_compiler_call("gfortran")); + EXPECT_FALSE(sut.is_compiler_call("gcc")); + } + + TEST(ToolIntelFortran, fails_on_empty) { + Execution input = {}; + + ToolIntelFortran sut; + + EXPECT_TRUE(Tool::not_recognized(sut.recognize(input))); + } + + TEST(ToolIntelFortran, simple) { + Execution input = { + "/opt/intel/oneapi/compiler/2025.0/bin/ifx", + {"ifx", "-c", "-o", "source.o", "source.c"}, + "/home/user/project", + {}, + }; + SemanticPtr expected = SemanticPtr( + new Compile( + input.working_dir, + input.executable, + {"-c"}, + {fs::path("source.c")}, + {fs::path("source.o")}) + ); + + ToolIntelFortran sut({}); + + auto result = sut.recognize(input); + EXPECT_TRUE(Tool::recognized_ok(result)); + EXPECT_PRED2([](auto lhs, auto rhs) { return lhs->operator==(*rhs); }, expected, result.unwrap()); + } + + TEST(ToolIntelFortran, linker_flag_filtered) { + Execution input = { + "/opt/intel/oneapi/compiler/2025.0/bin/ifx", + {"ifx", "-L.", "-lthing", "-o", "exe", "source.c"}, + "/home/user/project", + {}, + }; + SemanticPtr expected = SemanticPtr( + new Compile( + input.working_dir, + input.executable, + {"-c"}, + {fs::path("source.c")}, + {fs::path("exe")} + ) + ); + + ToolIntelFortran sut({}); + + auto result = sut.recognize(input); + EXPECT_TRUE(Tool::recognized_ok(result)); + EXPECT_PRED2([](auto lhs, auto rhs) { return lhs->operator==(*rhs); }, expected, result.unwrap()); + } + + TEST(ToolIntelFortran, pass_on_help) { + Execution input = { + "/opt/intel/oneapi/compiler/2025.0/bin/ifx", + {"ifx", "--version"}, + "/home/user/project", + {}, + }; + SemanticPtr expected = SemanticPtr(new QueryCompiler()); + + ToolIntelFortran sut({}); + + auto result = sut.recognize(input); + EXPECT_TRUE(result.is_ok()); + EXPECT_PRED2([](auto lhs, auto rhs) { return lhs->operator==(*rhs); }, expected, result.unwrap()); + } +} From 8d0d8a6cbf3cb34b802a0654d14ebb72c3d3bf3c Mon Sep 17 00:00:00 2001 From: Jaime Gonzalez Date: Fri, 10 Jan 2025 11:04:56 +0100 Subject: [PATCH 3/3] Add `ifx` and `ifort` as compiler wrappers --- source/intercept/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/intercept/CMakeLists.txt b/source/intercept/CMakeLists.txt index 368ca73c5..99a897ef6 100644 --- a/source/intercept/CMakeLists.txt +++ b/source/intercept/CMakeLists.txt @@ -110,6 +110,8 @@ install(CODE " COMMAND ln -sf ../wrapper clang++ COMMAND ln -sf ../wrapper f77 COMMAND ln -sf ../wrapper gfortran + COMMAND ln -sf ../wrapper ifx + COMMAND ln -sf ../wrapper ifort COMMAND ln -sf ../wrapper m2c COMMAND ln -sf ../wrapper pc COMMAND ln -sf ../wrapper lex