|
42 | 42 | #include "swift/../../lib/ClangImporter/ClangAdapter.h"
|
43 | 43 | #include "swift/ClangImporter/ClangImporter.h"
|
44 | 44 | #include "swift/Demangling/Demangle.h"
|
| 45 | +#include "swift/Demangling/Demangler.h" |
45 | 46 | #include "swift/Demangling/ManglingFlavor.h"
|
46 | 47 | #include "swift/Frontend/Frontend.h"
|
47 | 48 |
|
@@ -157,6 +158,179 @@ TypeSystemSwiftTypeRef::CanonicalizeSugar(swift::Demangle::Demangler &dem,
|
157 | 158 | });
|
158 | 159 | }
|
159 | 160 |
|
| 161 | +NodePointer TypeSystemSwiftTypeRef::FindTypeWithModuleAndIdentifierNode( |
| 162 | + swift::Demangle::NodePointer node) { |
| 163 | + if (!node || node->getKind() != Node::Kind::Type) |
| 164 | + return nullptr; |
| 165 | + |
| 166 | + NodePointer current = node; |
| 167 | + while (current && current->hasChildren() && |
| 168 | + current->getFirstChild()->getKind() != Node::Kind::Module) { |
| 169 | + current = current->getFirstChild(); |
| 170 | + } |
| 171 | + switch (current->getKind()) { |
| 172 | + case Node::Kind::Structure: |
| 173 | + case Node::Kind::Class: |
| 174 | + case Node::Kind::Enum: |
| 175 | + case Node::Kind::BoundGenericStructure: |
| 176 | + case Node::Kind::BoundGenericClass: |
| 177 | + case Node::Kind::BoundGenericEnum: |
| 178 | + return current; |
| 179 | + default: |
| 180 | + return nullptr; |
| 181 | + } |
| 182 | +} |
| 183 | + |
| 184 | +std::string TypeSystemSwiftTypeRef::AdjustTypeForOriginallyDefinedInModule( |
| 185 | + llvm::StringRef mangled_typename) { |
| 186 | + if (mangled_typename.empty()) |
| 187 | + return {}; |
| 188 | + |
| 189 | + auto flavor = SwiftLanguageRuntime::GetManglingFlavor(mangled_typename); |
| 190 | + swift::Demangle::Demangler dem; |
| 191 | + auto *type_node = |
| 192 | + swift_demangle::GetDemangledTypeMangling(dem, mangled_typename); |
| 193 | + if (!type_node) |
| 194 | + return {}; |
| 195 | + |
| 196 | + TargetSP target_sp(GetTargetWP().lock()); |
| 197 | + if (!target_sp) |
| 198 | + return {}; |
| 199 | + |
| 200 | + ModuleList &module_list = target_sp->GetImages(); |
| 201 | + |
| 202 | + // A map from the node containing the module and identifier of a specific type |
| 203 | + // to a node with the modified module and identifier of that type. For |
| 204 | + // example, given the following type: |
| 205 | + // |
| 206 | + // Module "a": |
| 207 | + // |
| 208 | + // @available(...) |
| 209 | + // @_originallyDefinedIn(module: "Other", ...) |
| 210 | + // public struct A { ... } |
| 211 | + // The demangle tree of the mangled name stored in DWARF will be: |
| 212 | + // |
| 213 | + // kind=Global |
| 214 | + // kind=TypeMangling |
| 215 | + // kind=Type |
| 216 | + // kind=Structure |
| 217 | + // kind=Module, text="Other" |
| 218 | + // kind=Identifier, text="A" |
| 219 | + // |
| 220 | + // This functions needs to construct the following tree: |
| 221 | + // |
| 222 | + // kind=Global |
| 223 | + // kind=TypeMangling |
| 224 | + // kind=Type |
| 225 | + // kind=Structure |
| 226 | + // kind=Module, text="a" |
| 227 | + // kind=Identifier, text="A" |
| 228 | + // |
| 229 | + // type_to_renamed_type_nodes is populated with the nodes in the original tree |
| 230 | + // node that need to be replaced mapping to their replacements. In this |
| 231 | + // example that would be: |
| 232 | + // |
| 233 | + // kind=Structure |
| 234 | + // kind=Module, text="Other" |
| 235 | + // kind=Identifier, text="A" |
| 236 | + // |
| 237 | + // mapping to: |
| 238 | + // |
| 239 | + // kind=Structure |
| 240 | + // kind=Module, text="a" |
| 241 | + // kind=Identifier, text="A" |
| 242 | + // |
| 243 | + // We can't have a map from module nodes to renamed module nodes because those |
| 244 | + // nodes might be reused elsewhere in the tree. |
| 245 | + llvm::DenseMap<NodePointer, NodePointer> type_to_renamed_type_nodes; |
| 246 | + |
| 247 | + // Visit the demangle tree and populate type_to_renamed_type_nodes. |
| 248 | + PreOrderTraversal(type_node, [&](NodePointer node) { |
| 249 | + // We're visiting the entire tree, but we only need to examine "Type" nodes. |
| 250 | + if (node->getKind() != Node::Kind::Type) |
| 251 | + return true; |
| 252 | + |
| 253 | + auto compiler_type = RemangleAsType(dem, node, flavor); |
| 254 | + if (!compiler_type) |
| 255 | + return true; |
| 256 | + |
| 257 | + // Find the node that contains the module and identifier nodes. |
| 258 | + NodePointer node_with_module_and_name = |
| 259 | + FindTypeWithModuleAndIdentifierNode(node); |
| 260 | + if (!node_with_module_and_name) |
| 261 | + return true; |
| 262 | + |
| 263 | + auto module_name = node_with_module_and_name->getFirstChild()->getText(); |
| 264 | + // Clang types couldn't have been renamed. |
| 265 | + if (module_name == swift::MANGLING_MODULE_OBJC) |
| 266 | + return true; |
| 267 | + |
| 268 | + // If we already processed this node there's nothing to do (this can happen |
| 269 | + // because nodes are shared in the tree). |
| 270 | + if (type_to_renamed_type_nodes.contains(node_with_module_and_name)) |
| 271 | + return true; |
| 272 | + |
| 273 | + // Look for the imported declarations that indicate the type has moved |
| 274 | + // modules. |
| 275 | + std::vector<ImportedDeclaration> decls; |
| 276 | + module_list.FindImportedDeclarations(GetModule(), |
| 277 | + compiler_type.GetMangledTypeName(), |
| 278 | + decls, /*find_one=*/true); |
| 279 | + // If there are none there's nothing to do. |
| 280 | + if (decls.empty()) |
| 281 | + return true; |
| 282 | + |
| 283 | + std::vector<lldb_private::CompilerContext> declContext = |
| 284 | + decls[0].GetDeclContext(); |
| 285 | + |
| 286 | + lldbassert(!declContext.empty() && |
| 287 | + "Unexpected decl context for imported declaration!"); |
| 288 | + if (declContext.empty()) |
| 289 | + return true; |
| 290 | + |
| 291 | + auto module_context = declContext[0]; |
| 292 | + |
| 293 | + // If the mangled name's module and module context module match then |
| 294 | + // there's nothing to do. |
| 295 | + if (module_name == module_context.name) |
| 296 | + return true; |
| 297 | + |
| 298 | + // Construct the node tree that will substituted in. |
| 299 | + NodePointer new_node = dem.createNode(node_with_module_and_name->getKind()); |
| 300 | + NodePointer new_module_node = dem.createNodeWithAllocatedText( |
| 301 | + Node::Kind::Module, module_context.name); |
| 302 | + new_node->addChild(new_module_node, dem); |
| 303 | + new_node->addChild(node_with_module_and_name->getLastChild(), dem); |
| 304 | + |
| 305 | + type_to_renamed_type_nodes[node_with_module_and_name] = new_node; |
| 306 | + return true; |
| 307 | + }); |
| 308 | + |
| 309 | + // If there are no renamed modules, there's nothing to do. |
| 310 | + if (type_to_renamed_type_nodes.empty()) |
| 311 | + return mangled_typename.str(); |
| 312 | + |
| 313 | + NodePointer transformed = Transform(dem, type_node, [&](NodePointer node) { |
| 314 | + return type_to_renamed_type_nodes.contains(node) |
| 315 | + ? type_to_renamed_type_nodes[node] |
| 316 | + : node; |
| 317 | + }); |
| 318 | + |
| 319 | + auto mangling = mangleNode(swift_demangle::mangleType(dem, transformed)); |
| 320 | + assert(mangling.isSuccess()); |
| 321 | + if (!mangling.isSuccess()) { |
| 322 | + LLDB_LOG(GetLog(LLDBLog::Types), |
| 323 | + "[AdjustTypeForOriginallyDefinedInModule] Unexpected mangling " |
| 324 | + "error when mangling adjusted node for type with mangled name {0}", |
| 325 | + mangled_typename); |
| 326 | + |
| 327 | + return {}; |
| 328 | + } |
| 329 | + |
| 330 | + auto str = mangling.result(); |
| 331 | + return str; |
| 332 | +} |
| 333 | + |
160 | 334 | llvm::StringRef
|
161 | 335 | TypeSystemSwiftTypeRef::GetBaseName(swift::Demangle::NodePointer node) {
|
162 | 336 | if (!node)
|
@@ -238,7 +412,7 @@ TypeSP TypeSystemSwiftTypeRefForExpressions::LookupClangType(
|
238 | 412 | ConstString name(name_ref);
|
239 | 413 | if (m_clang_type_cache.Lookup(name.AsCString(), result))
|
240 | 414 | return result;
|
241 |
| - |
| 415 | + |
242 | 416 | TargetSP target_sp = GetTargetWP().lock();
|
243 | 417 | if (!target_sp)
|
244 | 418 | return {};
|
@@ -456,7 +630,7 @@ TypeSystemSwiftTypeRef::GetClangTypeNode(CompilerType clang_type,
|
456 | 630 | if (!is_vector)
|
457 | 631 | break;
|
458 | 632 |
|
459 |
| - auto qual_type = ClangUtil::GetQualType(clang_type); |
| 633 | + auto qual_type = ClangUtil::GetQualType(clang_type); |
460 | 634 | const auto *ptr = qual_type.getTypePtrOrNull();
|
461 | 635 | if (!ptr)
|
462 | 636 | break;
|
|
0 commit comments