|
34 | 34 | #include "lldb/Utility/RegularExpression.h"
|
35 | 35 | #include "lldb/Utility/Timer.h"
|
36 | 36 |
|
37 |
| -#include "swift/ClangImporter/ClangImporter.h" |
38 | 37 | #include "swift/../../lib/ClangImporter/ClangAdapter.h"
|
| 38 | +#include "swift/ClangImporter/ClangImporter.h" |
| 39 | +#include "swift/Demangling/Demangler.h" |
39 | 40 | #include "swift/Frontend/Frontend.h"
|
40 | 41 |
|
41 | 42 | #include "clang/APINotes/APINotesManager.h"
|
@@ -150,6 +151,234 @@ TypeSystemSwiftTypeRef::CanonicalizeSugar(swift::Demangle::Demangler &dem,
|
150 | 151 | });
|
151 | 152 | }
|
152 | 153 |
|
| 154 | +swift::Demangle::ManglingErrorOr<std::string> |
| 155 | +TypeSystemSwiftTypeRef::TransformModuleName( |
| 156 | + llvm::StringRef mangled_name, |
| 157 | + const llvm::StringMap<llvm::StringRef> &module_name_map) { |
| 158 | + swift::Demangle::Demangler dem; |
| 159 | + auto *node = dem.demangleSymbol(mangled_name); |
| 160 | + auto *adjusted_node = TypeSystemSwiftTypeRef::Transform( |
| 161 | + dem, node, [&](swift::Demangle::NodePointer node) { |
| 162 | + if (node->getKind() == Node::Kind::Module) { |
| 163 | + auto module_name = node->getText(); |
| 164 | + if (module_name_map.contains(module_name)) { |
| 165 | + auto real_name = module_name_map.lookup(module_name); |
| 166 | + auto *adjusted_module_node = |
| 167 | + dem.createNodeWithAllocatedText(Node::Kind::Module, real_name); |
| 168 | + return adjusted_module_node; |
| 169 | + } |
| 170 | + } |
| 171 | + |
| 172 | + return node; |
| 173 | + }); |
| 174 | + |
| 175 | + auto mangling = mangleNode(adjusted_node); |
| 176 | + return mangling; |
| 177 | +} |
| 178 | + |
| 179 | +static NodePointer CloneNode(Demangler &dem, NodePointer node, |
| 180 | + bool set_children = true) { |
| 181 | + NodePointer clone; |
| 182 | + auto kind = node->getKind(); |
| 183 | + if (node->hasText()) |
| 184 | + clone = dem.createNodeWithAllocatedText(kind, node->getText()); |
| 185 | + else if (node->hasIndex()) |
| 186 | + clone = dem.createNode(kind, node->getIndex()); |
| 187 | + else |
| 188 | + clone = dem.createNode(kind); |
| 189 | + if (set_children) |
| 190 | + for (NodePointer transformed_child : *node) |
| 191 | + clone->addChild(transformed_child, dem); |
| 192 | + return clone; |
| 193 | +} |
| 194 | + |
| 195 | +NodePointer TypeSystemSwiftTypeRef::TransformModuleName( |
| 196 | + NodePointer node, Demangler &dem, |
| 197 | + std::function<NodePointer(NodePointer)> module_transformer) { |
| 198 | + assert(node->getKind() == Node::Kind::Type); |
| 199 | + if (node->getKind() != Node::Kind::Type) { |
| 200 | + LLDB_LOGF(GetLog(LLDBLog::Types), |
| 201 | + "[TransformModuleName] Unexpected node kind %hu", |
| 202 | + static_cast<uint16_t>(node->getKind())); |
| 203 | + return nullptr; |
| 204 | + } |
| 205 | + |
| 206 | + bool failed = false; |
| 207 | + std::function<NodePointer(NodePointer)> recurse_to_module_node = |
| 208 | + [&](NodePointer node) -> NodePointer { |
| 209 | + if (failed) |
| 210 | + return nullptr; |
| 211 | + // If the node has children this is not the module node yet, so recursively |
| 212 | + // examine the first child. |
| 213 | + if (node->hasChildren()) { |
| 214 | + NodePointer transformed = recurse_to_module_node(node->getFirstChild()); |
| 215 | + // Clone the node because demangle trees share subtrees if they're the |
| 216 | + // same, and we don't want to accidentally mutate some other part of the |
| 217 | + // tree. |
| 218 | + NodePointer clone = CloneNode(dem, node); |
| 219 | + clone->replaceChild(0, transformed); |
| 220 | + return clone; |
| 221 | + } |
| 222 | + if (node->getKind() == Node::Kind::Module) |
| 223 | + return module_transformer(node); |
| 224 | + failed = true; |
| 225 | + return nullptr; |
| 226 | + }; |
| 227 | + |
| 228 | + NodePointer transformed = recurse_to_module_node(node); |
| 229 | + if (failed) |
| 230 | + LLDB_LOGF(GetLog(LLDBLog::Types), |
| 231 | + "[TransformModuleName] Failed to transform node %hu", |
| 232 | + static_cast<uint16_t>(node->getKind())); |
| 233 | + |
| 234 | + return transformed; |
| 235 | +} |
| 236 | + |
| 237 | +NodePointer TypeSystemSwiftTypeRef::TransformBoundGenericTypes( |
| 238 | + swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, |
| 239 | + std::function<swift::Demangle::NodePointer(swift::Demangle::NodePointer)> |
| 240 | + type_transformer) { |
| 241 | + if (node->getKind() != Node::Kind::Type || !node->hasChildren()) |
| 242 | + return node; |
| 243 | + |
| 244 | + NodePointer bound_generic_node = node->getFirstChild(); |
| 245 | + if (bound_generic_node->getNumChildren() != 2) |
| 246 | + return node; |
| 247 | + |
| 248 | + NodePointer type_list_node = nullptr; |
| 249 | + switch (bound_generic_node->getKind()) { |
| 250 | + case Node::Kind::BoundGenericClass: |
| 251 | + case Node::Kind::BoundGenericEnum: |
| 252 | + case Node::Kind::BoundGenericStructure: |
| 253 | + case Node::Kind::BoundGenericProtocol: |
| 254 | + case Node::Kind::BoundGenericOtherNominalType: |
| 255 | + case Node::Kind::BoundGenericTypeAlias: |
| 256 | + type_list_node = bound_generic_node->getChild(1); |
| 257 | + break; |
| 258 | + default: |
| 259 | + return node; |
| 260 | + } |
| 261 | + assert(type_list_node && "No type list node!"); |
| 262 | + |
| 263 | + // Transform the bound generic types by applying type_transformer to all the |
| 264 | + // children of the type_list. |
| 265 | + NodePointer transformed_type_list = |
| 266 | + CloneNode(dem, type_list_node, /*set_children=*/false); |
| 267 | + for (NodePointer child : *type_list_node) |
| 268 | + transformed_type_list->addChild(type_transformer(child), dem); |
| 269 | + |
| 270 | + bound_generic_node = CloneNode(dem, bound_generic_node); |
| 271 | + bound_generic_node->replaceChild(1, transformed_type_list); |
| 272 | + node = CloneNode(dem, node); |
| 273 | + node->replaceChild(0, bound_generic_node); |
| 274 | + return node; |
| 275 | +} |
| 276 | + |
| 277 | +std::string TypeSystemSwiftTypeRef::AdjustTypeForOriginallyDefinedInModule( |
| 278 | + llvm::StringRef mangled_typename) { |
| 279 | + if (mangled_typename.empty()) |
| 280 | + return {}; |
| 281 | + |
| 282 | + swift::Demangle::Demangler dem; |
| 283 | + auto *type_node = |
| 284 | + swift_demangle::GetDemangledTypeMangling(dem, mangled_typename); |
| 285 | + assert(type_node); |
| 286 | + if (!type_node) |
| 287 | + return {}; |
| 288 | + |
| 289 | + bool did_transform = false; |
| 290 | + std::function<NodePointer(NodePointer)> transform_all_module_nodes = |
| 291 | + [&](NodePointer node) -> NodePointer { |
| 292 | + auto compiler_type = RemangleAsType(dem, node); |
| 293 | + if (!compiler_type) { |
| 294 | + LLDB_LOG(GetLog(LLDBLog::Types), |
| 295 | + "[AdjustTypeForOriginallyDefinedInModule] Unexpected mangling " |
| 296 | + "error when mangling adjusted node for type with mangled name " |
| 297 | + "{0}", |
| 298 | + mangled_typename); |
| 299 | + |
| 300 | + return node; |
| 301 | + } |
| 302 | + |
| 303 | + // If this type has an @_originallyDefinedIn attribute, the compiler will |
| 304 | + // emit a typealias whose name is prefixed by $ODI followed by the mangled |
| 305 | + // name. |
| 306 | + TargetSP target_sp(GetTargetWP().lock()); |
| 307 | + if (!target_sp) |
| 308 | + return node; |
| 309 | + ModuleList &module_list = target_sp->GetImages(); |
| 310 | + std::vector<ImportedDeclaration> decls; |
| 311 | + module_list.FindImportedDeclarations(GetModule(), |
| 312 | + compiler_type.GetMangledTypeName(), |
| 313 | + decls, /*find_one=*/true); |
| 314 | + if (decls.empty()) |
| 315 | + return node; |
| 316 | + |
| 317 | + std::vector<lldb_private::CompilerContext> declContext = |
| 318 | + decls[0].GetDeclContext(); |
| 319 | + |
| 320 | + lldbassert(!declContext.empty() && |
| 321 | + "Unexpected decl context for $ODI$ typealiased type"); |
| 322 | + if (declContext.empty()) |
| 323 | + return node; |
| 324 | + |
| 325 | + auto module_context = declContext[0]; |
| 326 | + |
| 327 | + auto module_tranformer = |
| 328 | + [&](NodePointer module_node, |
| 329 | + CompilerContext module_context) -> NodePointer { |
| 330 | + if (module_node->getText() == swift::MANGLING_MODULE_OBJC) |
| 331 | + return module_node; |
| 332 | + |
| 333 | + // If the mangled name's module and module context module match then |
| 334 | + // there's nothing to do. |
| 335 | + if (module_node->getText() == module_context.name) |
| 336 | + return module_node; |
| 337 | + |
| 338 | + // Otherwise this is a type who is originally defined in a separate |
| 339 | + // module. Adjust the module name. |
| 340 | + auto *adjusted_module_node = dem.createNodeWithAllocatedText( |
| 341 | + Node::Kind::Module, module_context.name); |
| 342 | + did_transform = true; |
| 343 | + return adjusted_module_node; |
| 344 | + }; |
| 345 | + |
| 346 | + NodePointer transformed_module = |
| 347 | + TypeSystemSwiftTypeRef::TransformModuleName( |
| 348 | + node, dem, [&](NodePointer module_node) { |
| 349 | + return module_tranformer(module_node, module_context); |
| 350 | + }); |
| 351 | + |
| 352 | + if (!transformed_module) { |
| 353 | + return node; |
| 354 | + } |
| 355 | + |
| 356 | + NodePointer transformed_generic_types = |
| 357 | + TypeSystemSwiftTypeRef::TransformBoundGenericTypes( |
| 358 | + dem, transformed_module, transform_all_module_nodes); |
| 359 | + return transformed_generic_types; |
| 360 | + }; |
| 361 | + |
| 362 | + auto transformed_type_node = transform_all_module_nodes(type_node); |
| 363 | + if (!did_transform) |
| 364 | + return {}; |
| 365 | + |
| 366 | + auto mangling = |
| 367 | + mangleNode(swift_demangle::mangleType(dem, transformed_type_node)); |
| 368 | + assert(mangling.isSuccess()); |
| 369 | + if (!mangling.isSuccess()) { |
| 370 | + LLDB_LOG(GetLog(LLDBLog::Types), |
| 371 | + "[AdjustTypeForOriginallyDefinedInModule] Unexpected mangling " |
| 372 | + "error when mangling adjusted node for type with mangled name {0}", |
| 373 | + mangled_typename); |
| 374 | + |
| 375 | + return {}; |
| 376 | + } |
| 377 | + |
| 378 | + auto str = mangling.result(); |
| 379 | + return str; |
| 380 | +} |
| 381 | + |
153 | 382 | llvm::StringRef
|
154 | 383 | TypeSystemSwiftTypeRef::GetBaseName(swift::Demangle::NodePointer node) {
|
155 | 384 | if (!node)
|
@@ -935,13 +1164,7 @@ swift::Demangle::NodePointer TypeSystemSwiftTypeRef::Transform(
|
935 | 1164 | }
|
936 | 1165 | if (changed) {
|
937 | 1166 | // Create a new node with the transformed children.
|
938 |
| - auto kind = node->getKind(); |
939 |
| - if (node->hasText()) |
940 |
| - node = dem.createNodeWithAllocatedText(kind, node->getText()); |
941 |
| - else if (node->hasIndex()) |
942 |
| - node = dem.createNode(kind, node->getIndex()); |
943 |
| - else |
944 |
| - node = dem.createNode(kind); |
| 1167 | + node = CloneNode(dem, node, /*set_children=*/false); |
945 | 1168 | for (NodePointer transformed_child : children)
|
946 | 1169 | node->addChild(transformed_child, dem);
|
947 | 1170 | }
|
@@ -4830,6 +5053,7 @@ TypeSystemSwiftTypeRef::GetDependentGenericParamListForType(
|
4830 | 5053 |
|
4831 | 5054 | #ifndef NDEBUG
|
4832 | 5055 | bool TypeSystemSwiftTypeRef::ShouldSkipValidation(opaque_compiler_type_t type) {
|
| 5056 | + return true; |
4833 | 5057 | auto mangled_name = GetMangledTypeName(type);
|
4834 | 5058 | // NSNotificationName is a typedef to a NSString in clang type, but it's a
|
4835 | 5059 | // struct in SwiftASTContext. Skip validation in this case.
|
|
0 commit comments