diff --git a/flang/include/flang/Common/Version.h b/flang/include/flang/Common/Version.h new file mode 100644 --- /dev/null +++ b/flang/include/flang/Common/Version.h @@ -0,0 +1,57 @@ +//===- Version.h - Flang Version Number ---------------------*- Fortran -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Defines version macros and version-related utility functions +/// for Flang. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_FLANG_COMMON_VERSION_H +#define LLVM_FLANG_COMMON_VERSION_H + +#include "flang/Version.inc" +#include "llvm/ADT/StringRef.h" + +namespace Fortran::common { + /// Retrieves the repository path (e.g., Subversion path) that + /// identifies the particular Flang branch, tag, or trunk from which this + /// Flang was built. + std::string getFlangRepositoryPath(); + + /// Retrieves the repository path from which LLVM was built. + /// + /// This supports LLVM residing in a separate repository from flang. + std::string getLLVMRepositoryPath(); + + /// Retrieves the repository revision number (or identifier) from which + /// this Flang was built. + std::string getFlangRevision(); + + /// Retrieves the repository revision number (or identifier) from which + /// LLVM was built. + /// + /// If Flang and LLVM are in the same repository, this returns the same + /// string as getFlangRevision. + std::string getLLVMRevision(); + + /// Retrieves the full repository version that is an amalgamation of + /// the information in getFlangRepositoryPath() and getFlangRevision(). + std::string getFlangFullRepositoryVersion(); + + /// Retrieves a string representing the complete flang version, + /// which includes the flang version number, the repository version, + /// and the vendor tag. + std::string getFlangFullVersion(); + + /// Like getFlangFullVersion(), but with a custom tool name. + std::string getFlangToolFullVersion(llvm::StringRef ToolName); +} + +#endif // LLVM_FLANG_COMMON_VERSION_H + diff --git a/flang/lib/Common/CMakeLists.txt b/flang/lib/Common/CMakeLists.txt --- a/flang/lib/Common/CMakeLists.txt +++ b/flang/lib/Common/CMakeLists.txt @@ -1,9 +1,45 @@ +find_first_existing_vc_file("${LLVM_MAIN_SRC_DIR}" llvm_vc) +find_first_existing_vc_file("${FLANG_SOURCE_DIR}" flang_vc) + +# The VC revision include that we want to generate. +set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSVersion.inc") + +set(generate_vcs_version_script "${LLVM_CMAKE_DIR}/GenerateVersionFromVCS.cmake") + +if(llvm_vc AND LLVM_APPEND_VC_REV) + set(llvm_source_dir ${LLVM_MAIN_SRC_DIR}) +endif() +if(flang_vc AND LLVM_APPEND_VC_REV) + set(flang_source_dir ${FLANG_SOURCE_DIR}) +endif() + +# Create custom target to generate the VC revision include. +add_custom_command(OUTPUT "${version_inc}" + DEPENDS "${llvm_vc}" "${flang_vc}" "${generate_vcs_version_script}" + COMMAND ${CMAKE_COMMAND} "-DNAMES=\"LLVM;FLANG\"" + "-DLLVM_SOURCE_DIR=${llvm_source_dir}" + "-DFLANG_SOURCE_DIR=${flang_source_dir}" + "-DHEADER_FILE=${version_inc}" + -P "${generate_vcs_version_script}") + +# Mark the generated header as being generated. +set_source_files_properties("${version_inc}" + PROPERTIES GENERATED TRUE + HEADER_FILE_ONLY TRUE) + +if(FLANG_VENDOR) + set_source_files_properties(Version.cpp + PROPERTIES COMPILE_DEFINITIONS "FLANG_VENDOR=\"${FLANG_VENDOR} \"") +endif() + add_flang_library(FortranCommon Fortran.cpp Fortran-features.cpp default-kinds.cpp idioms.cpp + Version.cpp + ${version_inc} LINK_COMPONENTS Support diff --git a/flang/lib/Common/Version.cpp b/flang/lib/Common/Version.cpp new file mode 100644 --- /dev/null +++ b/flang/lib/Common/Version.cpp @@ -0,0 +1,107 @@ +//===- Version.cpp - Flang Version Number -------------------*- Fortran -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines several version-related utility functions for Flang. +// +//===----------------------------------------------------------------------===// + +#include "flang/Common/Version.h" +#include "llvm/Support/raw_ostream.h" +#include +#include + +#include "VCSVersion.inc" + +namespace Fortran::common { + +std::string getFlangRepositoryPath() { +#if defined(FLANG_REPOSITORY_STRING) + return FLANG_REPOSITORY_STRING; +#else +#ifdef FLANG_REPOSITORY + return FLANG_REPOSITORY; +#else + return ""; +#endif +#endif +} + +std::string getLLVMRepositoryPath() { +#ifdef LLVM_REPOSITORY + return LLVM_REPOSITORY; +#else + return ""; +#endif +} + +std::string getFlangRevision() { +#ifdef FLANG_REVISION + return FLANG_REVISION; +#else + return ""; +#endif +} + +std::string getLLVMRevision() { +#ifdef LLVM_REVISION + return LLVM_REVISION; +#else + return ""; +#endif +} + +std::string getFlangFullRepositoryVersion() { + std::string buf; + llvm::raw_string_ostream OS(buf); + std::string Path = getFlangRepositoryPath(); + std::string Revision = getFlangRevision(); + if (!Path.empty() || !Revision.empty()) { + OS << '('; + if (!Path.empty()) + OS << Path; + if (!Revision.empty()) { + if (!Path.empty()) + OS << ' '; + OS << Revision; + } + OS << ')'; + } + // Support LLVM in a separate repository. + std::string LLVMRev = getLLVMRevision(); + if (!LLVMRev.empty() && LLVMRev != Revision) { + OS << " ("; + std::string LLVMRepo = getLLVMRepositoryPath(); + if (!LLVMRepo.empty()) + OS << LLVMRepo << ' '; + OS << LLVMRev << ')'; + } + return buf; +} + +std::string getFlangFullVersion() { + return getFlangToolFullVersion("flang"); +} + +std::string getFlangToolFullVersion(llvm::StringRef ToolName) { + std::string buf; + llvm::raw_string_ostream OS(buf); +#ifdef FLANG_VENDOR + OS << FLANG_VENDOR; +#endif + OS << ToolName << " version " FLANG_VERSION_STRING; + + std::string repo = getFlangFullRepositoryVersion(); + if (!repo.empty()) { + OS << " " << repo; + } + + return buf; +} + + +} // end namespace Fortran::common diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -15,6 +15,7 @@ #include "flang/Lower/IntrinsicCall.h" #include "flang/Common/static-multimap-view.h" +#include "flang/Common/Version.h" #include "flang/Lower/Mangler.h" #include "flang/Lower/Runtime.h" #include "flang/Lower/StatementContext.h" @@ -34,6 +35,7 @@ #include "flang/Optimizer/Builder/Todo.h" #include "flang/Optimizer/Dialect/FIROpsSupport.h" #include "flang/Optimizer/Support/FatalError.h" +#include "flang/Version.inc" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/Math/IR/Math.h" #include "llvm/Support/CommandLine.h" @@ -483,6 +485,7 @@ void genCFPointer(llvm::ArrayRef); fir::ExtendedValue genCFunLoc(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genCLoc(mlir::Type, llvm::ArrayRef); + fir::ExtendedValue genCompilerVersion(mlir::Type, llvm::ArrayRef); void genDateAndTime(llvm::ArrayRef); mlir::Value genDim(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genDotProduct(mlir::Type, @@ -741,6 +744,7 @@ &I::genCmplx, {{{"x", asValue}, {"y", asValue, handleDynamicOptional}}}}, {"command_argument_count", &I::genCommandArgumentCount}, + {"compiler_version", &I::genCompilerVersion}, {"conjg", &I::genConjg}, {"count", &I::genCount, @@ -2626,6 +2630,14 @@ ; } +// COMPILER_VERSION +fir::ExtendedValue IntrinsicLibrary::genCompilerVersion( + mlir::Type resultType, llvm::ArrayRef args) { + assert(args.size() == 0); + return fir::factory::createStringLiteral(builder, loc, Fortran::common::getFlangFullVersion()); +} + + // CONJG mlir::Value IntrinsicLibrary::genConjg(mlir::Type resultType, llvm::ArrayRef args) {