|
8 | 8 |
|
9 | 9 | #include "flang/Lower/Mangler.h"
|
10 | 10 | #include "flang/Common/reference.h"
|
| 11 | +#include "flang/Lower/Todo.h" |
11 | 12 | #include "flang/Lower/Utils.h"
|
12 | 13 | #include "flang/Optimizer/Dialect/FIRType.h"
|
13 | 14 | #include "flang/Optimizer/Support/InternalNames.h"
|
@@ -65,57 +66,93 @@ findInterfaceIfSeperateMP(const Fortran::semantics::Symbol &symbol) {
|
65 | 66 | // Mangle the name of `symbol` to make it unique within FIR's symbol table using
|
66 | 67 | // the FIR name mangler, `mangler`
|
67 | 68 | std::string
|
68 |
| -Fortran::lower::mangle::mangleName(fir::NameUniquer &uniquer, |
69 |
| - const Fortran::semantics::Symbol &symbol) { |
| 69 | +Fortran::lower::mangle::mangleName(const Fortran::semantics::Symbol &symbol, |
| 70 | + bool keepExternalInScope) { |
70 | 71 | // Resolve host and module association before mangling
|
71 | 72 | const auto &ultimateSymbol = symbol.GetUltimate();
|
72 | 73 | auto symbolName = toStringRef(ultimateSymbol.name());
|
73 | 74 |
|
74 | 75 | return std::visit(
|
75 | 76 | Fortran::common::visitors{
|
76 | 77 | [&](const Fortran::semantics::MainProgramDetails &) {
|
77 |
| - return uniquer.doProgramEntry().str(); |
| 78 | + return fir::NameUniquer::doProgramEntry().str(); |
78 | 79 | },
|
79 | 80 | [&](const Fortran::semantics::SubprogramDetails &) {
|
80 | 81 | // Mangle external procedure without any scope prefix.
|
81 |
| - if (Fortran::semantics::IsExternal(ultimateSymbol)) |
82 |
| - return uniquer.doProcedure(llvm::None, llvm::None, symbolName); |
| 82 | + if (!keepExternalInScope && |
| 83 | + Fortran::semantics::IsExternal(ultimateSymbol)) |
| 84 | + return fir::NameUniquer::doProcedure(llvm::None, llvm::None, |
| 85 | + symbolName); |
83 | 86 | // Separate module subprograms must be mangled according to the
|
84 | 87 | // scope where they were declared (the symbol we have is the
|
85 | 88 | // definition).
|
86 | 89 | const auto *interface = &ultimateSymbol;
|
87 | 90 | if (const auto *mpIface = findInterfaceIfSeperateMP(ultimateSymbol))
|
88 | 91 | interface = mpIface;
|
89 | 92 | auto modNames = moduleNames(*interface);
|
90 |
| - return uniquer.doProcedure(modNames, hostName(*interface), |
91 |
| - symbolName); |
| 93 | + return fir::NameUniquer::doProcedure(modNames, hostName(*interface), |
| 94 | + symbolName); |
92 | 95 | },
|
93 | 96 | [&](const Fortran::semantics::ProcEntityDetails &) {
|
94 | 97 | // Mangle procedure pointers and dummy procedures as variables
|
95 | 98 | if (Fortran::semantics::IsPointer(ultimateSymbol) ||
|
96 | 99 | Fortran::semantics::IsDummy(ultimateSymbol))
|
97 |
| - return uniquer.doVariable(moduleNames(ultimateSymbol), |
98 |
| - hostName(ultimateSymbol), symbolName); |
| 100 | + return fir::NameUniquer::doVariable(moduleNames(ultimateSymbol), |
| 101 | + hostName(ultimateSymbol), |
| 102 | + symbolName); |
99 | 103 | // Otherwise, this is an external procedure, even if it does not
|
100 | 104 | // have an explicit EXTERNAL attribute. Mangle it without any
|
101 | 105 | // prefix.
|
102 |
| - return uniquer.doProcedure(llvm::None, llvm::None, symbolName); |
| 106 | + return fir::NameUniquer::doProcedure(llvm::None, llvm::None, |
| 107 | + symbolName); |
103 | 108 | },
|
104 | 109 | [&](const Fortran::semantics::ObjectEntityDetails &) {
|
105 | 110 | auto modNames = moduleNames(ultimateSymbol);
|
106 | 111 | auto optHost = hostName(ultimateSymbol);
|
107 | 112 | if (Fortran::semantics::IsNamedConstant(ultimateSymbol))
|
108 |
| - return uniquer.doConstant(modNames, optHost, symbolName); |
109 |
| - return uniquer.doVariable(modNames, optHost, symbolName); |
| 113 | + return fir::NameUniquer::doConstant(modNames, optHost, |
| 114 | + symbolName); |
| 115 | + return fir::NameUniquer::doVariable(modNames, optHost, symbolName); |
110 | 116 | },
|
111 |
| - [](const auto &) -> std::string { |
112 |
| - assert(false); |
113 |
| - return {}; |
| 117 | + [&](const Fortran::semantics::CommonBlockDetails &) { |
| 118 | + return fir::NameUniquer::doCommonBlock(symbolName); |
114 | 119 | },
|
| 120 | + [&](const Fortran::semantics::DerivedTypeDetails &) -> std::string { |
| 121 | + // Derived type mangling must used mangleName(DerivedTypeSpec&) so |
| 122 | + // that kind type parameter values can be mangled. |
| 123 | + llvm::report_fatal_error( |
| 124 | + "only derived type instances can be mangled"); |
| 125 | + }, |
| 126 | + [](const auto &) -> std::string { TODO_NOLOC("symbol mangling"); }, |
115 | 127 | },
|
116 | 128 | ultimateSymbol.details());
|
117 | 129 | }
|
118 | 130 |
|
| 131 | +std::string Fortran::lower::mangle::mangleName( |
| 132 | + const Fortran::semantics::DerivedTypeSpec &derivedType) { |
| 133 | + // Resolve host and module association before mangling |
| 134 | + const auto &ultimateSymbol = derivedType.typeSymbol().GetUltimate(); |
| 135 | + auto symbolName = toStringRef(ultimateSymbol.name()); |
| 136 | + auto modNames = moduleNames(ultimateSymbol); |
| 137 | + auto optHost = hostName(ultimateSymbol); |
| 138 | + llvm::SmallVector<std::int64_t> kinds; |
| 139 | + for (const auto ¶m : |
| 140 | + Fortran::semantics::OrderParameterDeclarations(ultimateSymbol)) { |
| 141 | + const auto ¶mDetails = |
| 142 | + param->get<Fortran::semantics::TypeParamDetails>(); |
| 143 | + if (paramDetails.attr() == Fortran::common::TypeParamAttr::Kind) { |
| 144 | + const auto *paramValue = derivedType.FindParameter(param->name()); |
| 145 | + assert(paramValue && "derived type kind parameter value not found"); |
| 146 | + auto paramExpr = paramValue->GetExplicit(); |
| 147 | + assert(paramExpr && "derived type kind param not explicit"); |
| 148 | + auto init = Fortran::evaluate::ToInt64(paramValue->GetExplicit()); |
| 149 | + assert(init && "derived type kind param is not constant"); |
| 150 | + kinds.emplace_back(*init); |
| 151 | + } |
| 152 | + } |
| 153 | + return fir::NameUniquer::doType(modNames, optHost, symbolName, kinds); |
| 154 | +} |
| 155 | + |
119 | 156 | std::string Fortran::lower::mangle::demangleName(llvm::StringRef name) {
|
120 | 157 | auto result = fir::NameUniquer::deconstruct(name);
|
121 | 158 | return result.second.name;
|
|
0 commit comments