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