xref: /llvm-project/flang/include/flang/Lower/Mangler.h (revision fac349a169976f822fb27f03e623fa0d28aec1f3)
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