summaryrefslogtreecommitdiff
path: root/flang/include/flang/Lower/Mangler.h
blob: 1f3109b3541918d647124cb2924993d4199fc7fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//===-- Lower/Mangler.h -- name mangling ------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
//
//===----------------------------------------------------------------------===//

#ifndef FORTRAN_LOWER_MANGLER_H
#define FORTRAN_LOWER_MANGLER_H

#include "flang/Evaluate/expression.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "mlir/IR/BuiltinTypes.h"
#include "llvm/ADT/StringRef.h"
#include <string>

namespace Fortran {
namespace common {
template <typename>
class Reference;
}

namespace semantics {
class Scope;
class Symbol;
class DerivedTypeSpec;
} // namespace semantics

namespace lower::mangle {

using ScopeBlockIdMap =
    llvm::DenseMap<Fortran::semantics::Scope *, std::int64_t>;

/// Convert a front-end symbol to a unique internal name.
/// A symbol that could be in a block scope must provide a ScopeBlockIdMap.
/// If \p keepExternalInScope is true, mangling an external symbol retains
/// the scope of the symbol. This is useful when setting the attributes of
/// a symbol where all the Fortran context is needed. Otherwise, external
/// symbols are mangled outside of any scope.
std::string mangleName(const semantics::Symbol &, ScopeBlockIdMap &,
                       bool keepExternalInScope = false);
std::string mangleName(const semantics::Symbol &,
                       bool keepExternalInScope = false);

/// Convert a derived type instance to an internal name.
std::string mangleName(const semantics::DerivedTypeSpec &, ScopeBlockIdMap &);

/// Add a scope specific mangling prefix to a compiler generated name.
std::string mangleName(std::string &, const Fortran::semantics::Scope &,
                       ScopeBlockIdMap &);

/// Recover the bare name of the original symbol from an internal name.
std::string demangleName(llvm::StringRef name);

std::string
mangleArrayLiteral(size_t size,
                   const Fortran::evaluate::ConstantSubscripts &shape,
                   Fortran::common::TypeCategory cat, int kind = 0,
                   Fortran::common::ConstantSubscript charLen = -1,
                   llvm::StringRef derivedName = {});

template <Fortran::common::TypeCategory TC, int KIND>
std::string mangleArrayLiteral(
    mlir::Type,
    const Fortran::evaluate::Constant<Fortran::evaluate::Type<TC, KIND>> &x) {
  return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
                            x.shape(), TC, KIND);
}

template <int KIND>
std::string
mangleArrayLiteral(mlir::Type,
                   const Fortran::evaluate::Constant<Fortran::evaluate::Type<
                       Fortran::common::TypeCategory::Character, KIND>> &x) {
  return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
                            x.shape(), Fortran::common::TypeCategory::Character,
                            KIND, x.LEN());
}

inline std::string mangleArrayLiteral(
    mlir::Type eleTy,
    const Fortran::evaluate::Constant<Fortran::evaluate::SomeDerived> &x) {
  return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
                            x.shape(), Fortran::common::TypeCategory::Derived,
                            /*kind=*/0, /*charLen=*/-1,
                            eleTy.cast<fir::RecordType>().getName());
}

/// Return the compiler-generated name of a static namelist variable descriptor.
std::string globalNamelistDescriptorName(const Fortran::semantics::Symbol &sym);

} // namespace lower::mangle
} // namespace Fortran

#endif // FORTRAN_LOWER_MANGLER_H