blob: fa98cc2a8e490caeb4da33feef163166e6a9e5b2 [file] [log] [blame]
//===-- Optimizer/Support/InternalNames.h -----------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef FORTRAN_OPTIMIZER_SUPPORT_INTERNALNAMES_H
#define FORTRAN_OPTIMIZER_SUPPORT_INTERNALNAMES_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include <cstdint>
namespace fir {
/// Internal name mangling of identifiers
///
/// In order to generate symbolically referencable artifacts in a ModuleOp,
/// it is required that those symbols be uniqued. This is a simple interface
/// for converting Fortran symbols into unique names.
///
/// This is intentionally bijective. Given a symbol's parse name, type, and
/// scope-like information, we can generate a uniqued (mangled) name. Given a
/// uniqued name, we can return the symbol parse name, type of the symbol, and
/// any scope-like information for that symbol.
struct NameUniquer {
enum class IntrinsicType { CHARACTER, COMPLEX, INTEGER, LOGICAL, REAL };
/// The sort of the unique name
enum class NameKind {
NOT_UNIQUED,
BLOCK_DATA_NAME,
COMMON,
CONSTANT,
DERIVED_TYPE,
DISPATCH_TABLE,
GENERATED,
INTRINSIC_TYPE_DESC,
PROCEDURE,
TYPE_DESC,
VARIABLE
};
/// Components of an unparsed unique name
struct DeconstructedName {
DeconstructedName(llvm::StringRef name) : name{name} {}
DeconstructedName(llvm::ArrayRef<std::string> modules,
llvm::Optional<std::string> host, llvm::StringRef name,
llvm::ArrayRef<std::int64_t> kinds)
: modules{modules.begin(), modules.end()}, host{host}, name{name},
kinds{kinds.begin(), kinds.end()} {}
llvm::SmallVector<std::string, 2> modules;
llvm::Optional<std::string> host;
std::string name;
llvm::SmallVector<std::int64_t, 4> kinds;
};
/// Unique a common block name
static std::string doCommonBlock(llvm::StringRef name);
/// Unique a block data unit name
static std::string doBlockData(llvm::StringRef name);
/// Unique a (global) constant name
static std::string doConstant(llvm::ArrayRef<llvm::StringRef> modules,
llvm::Optional<llvm::StringRef> host,
llvm::StringRef name);
/// Unique a dispatch table name
static std::string doDispatchTable(llvm::ArrayRef<llvm::StringRef> modules,
llvm::Optional<llvm::StringRef> host,
llvm::StringRef name,
llvm::ArrayRef<std::int64_t> kinds);
/// Unique a compiler generated name
static std::string doGenerated(llvm::StringRef name);
/// Unique an intrinsic type descriptor
static std::string
doIntrinsicTypeDescriptor(llvm::ArrayRef<llvm::StringRef> modules,
llvm::Optional<llvm::StringRef> host,
IntrinsicType type, std::int64_t kind);
/// Unique a procedure name
static std::string doProcedure(llvm::ArrayRef<llvm::StringRef> modules,
llvm::Optional<llvm::StringRef> host,
llvm::StringRef name);
/// Unique a derived type name
static std::string doType(llvm::ArrayRef<llvm::StringRef> modules,
llvm::Optional<llvm::StringRef> host,
llvm::StringRef name,
llvm::ArrayRef<std::int64_t> kinds);
/// Unique a (derived) type descriptor name
static std::string doTypeDescriptor(llvm::ArrayRef<llvm::StringRef> modules,
llvm::Optional<llvm::StringRef> host,
llvm::StringRef name,
llvm::ArrayRef<std::int64_t> kinds);
static std::string doTypeDescriptor(llvm::ArrayRef<std::string> modules,
llvm::Optional<std::string> host,
llvm::StringRef name,
llvm::ArrayRef<std::int64_t> kinds);
/// Unique a (global) variable name. A variable with save attribute
/// defined inside a subprogram also needs to be handled here
static std::string doVariable(llvm::ArrayRef<llvm::StringRef> modules,
llvm::Optional<llvm::StringRef> host,
llvm::StringRef name);
/// Entry point for the PROGRAM (called by the runtime)
/// Can be overridden with the `--main-entry-name=<name>` option.
static llvm::StringRef doProgramEntry();
/// Decompose `uniquedName` into the parse name, symbol type, and scope info
static std::pair<NameKind, DeconstructedName>
deconstruct(llvm::StringRef uniquedName);
private:
static std::string intAsString(std::int64_t i);
static std::string doKind(std::int64_t kind);
static std::string doKinds(llvm::ArrayRef<std::int64_t> kinds);
static std::string toLower(llvm::StringRef name);
NameUniquer() = delete;
NameUniquer(const NameUniquer &) = delete;
NameUniquer(NameUniquer &&) = delete;
NameUniquer &operator=(const NameUniquer &) = delete;
};
} // namespace fir
#endif // FORTRAN_OPTIMIZER_SUPPORT_INTERNALNAMES_H