1 //===-- Lower/Mangler.h -- name mangling ------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef FORTRAN_LOWER_MANGLER_H
14 #define FORTRAN_LOWER_MANGLER_H
15
16 #include "flang/Evaluate/expression.h"
17 #include "flang/Optimizer/Dialect/FIRType.h"
18 #include "mlir/IR/BuiltinTypes.h"
19 #include "llvm/ADT/StringRef.h"
20 #include <string>
21
22 namespace Fortran {
23 namespace common {
24 template <typename>
25 class Reference;
26 }
27
28 namespace semantics {
29 class Scope;
30 class Symbol;
31 class DerivedTypeSpec;
32 } // namespace semantics
33
34 namespace lower::mangle {
35
36 using ScopeBlockIdMap =
37 llvm::DenseMap<Fortran::semantics::Scope *, std::int64_t>;
38
39 /// Convert a front-end symbol to a unique internal name.
40 /// A symbol that could be in a block scope must provide a ScopeBlockIdMap.
41 /// If \p keepExternalInScope is true, mangling an external symbol retains
42 /// the scope of the symbol. This is useful when setting the attributes of
43 /// a symbol where all the Fortran context is needed. Otherwise, external
44 /// symbols are mangled outside of any scope.
45 std::string mangleName(const semantics::Symbol &, ScopeBlockIdMap &,
46 bool keepExternalInScope = false,
47 bool underscoring = true);
48 std::string mangleName(const semantics::Symbol &,
49 bool keepExternalInScope = false,
50 bool underscoring = true);
51
52 /// Convert a derived type instance to an internal name.
53 std::string mangleName(const semantics::DerivedTypeSpec &, ScopeBlockIdMap &);
54
55 /// Add a scope specific mangling prefix to a compiler generated name.
56 std::string mangleName(std::string &, const Fortran::semantics::Scope &,
57 ScopeBlockIdMap &);
58
59 /// Recover the bare name of the original symbol from an internal name.
60 std::string demangleName(llvm::StringRef name);
61
62 std::string
63 mangleArrayLiteral(size_t size,
64 const Fortran::evaluate::ConstantSubscripts &shape,
65 Fortran::common::TypeCategory cat, int kind = 0,
66 Fortran::common::ConstantSubscript charLen = -1,
67 llvm::StringRef derivedName = {});
68
69 template <Fortran::common::TypeCategory TC, int KIND>
mangleArrayLiteral(mlir::Type,const Fortran::evaluate::Constant<Fortran::evaluate::Type<TC,KIND>> & x)70 std::string mangleArrayLiteral(
71 mlir::Type,
72 const Fortran::evaluate::Constant<Fortran::evaluate::Type<TC, KIND>> &x) {
73 return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
74 x.shape(), TC, KIND);
75 }
76
77 template <int KIND>
78 std::string
mangleArrayLiteral(mlir::Type,const Fortran::evaluate::Constant<Fortran::evaluate::Type<Fortran::common::TypeCategory::Character,KIND>> & x)79 mangleArrayLiteral(mlir::Type,
80 const Fortran::evaluate::Constant<Fortran::evaluate::Type<
81 Fortran::common::TypeCategory::Character, KIND>> &x) {
82 return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
83 x.shape(), Fortran::common::TypeCategory::Character,
84 KIND, x.LEN());
85 }
86
mangleArrayLiteral(mlir::Type eleTy,const Fortran::evaluate::Constant<Fortran::evaluate::SomeDerived> & x)87 inline std::string mangleArrayLiteral(
88 mlir::Type eleTy,
89 const Fortran::evaluate::Constant<Fortran::evaluate::SomeDerived> &x) {
90 return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
91 x.shape(), Fortran::common::TypeCategory::Derived,
92 /*kind=*/0, /*charLen=*/-1,
93 mlir::cast<fir::RecordType>(eleTy).getName());
94 }
95
96 /// Return the compiler-generated name of a static namelist variable descriptor.
97 std::string globalNamelistDescriptorName(const Fortran::semantics::Symbol &sym);
98
99 /// Return the field name for a derived type component inside a fir.record type.
100 /// It is the component name if the component is not private. Otherwise it is
101 /// mangled with the component parent type to avoid any name clashes in type
102 /// extensions.
103 std::string getRecordTypeFieldName(const Fortran::semantics::Symbol &component,
104 ScopeBlockIdMap &);
105
106 } // namespace lower::mangle
107 } // namespace Fortran
108
109 #endif // FORTRAN_LOWER_MANGLER_H
110