Example #1
0
void Remangler::mangleSILBoxTypeWithLayout(Node *node) {
  assert(node->getKind() == Node::Kind::SILBoxTypeWithLayout);
  assert(node->getNumChildren() == 1 || node->getNumChildren() == 3);
  Out << "XB";
  auto layout = node->getChild(0);
  assert(layout->getKind() == Node::Kind::SILBoxLayout);
  NodePointer genericArgs = nullptr;
  if (node->getNumChildren() == 3) {
    NodePointer signature = node->getChild(1);
    assert(signature->getKind() == Node::Kind::DependentGenericSignature);
    genericArgs = node->getChild(2);
    assert(genericArgs->getKind() == Node::Kind::TypeList);
    
    Out << 'G';
    mangleDependentGenericSignature(signature);
  }
  mangleSILBoxLayout(layout);
  if (genericArgs) {
    for (unsigned i = 0; i < genericArgs->getNumChildren(); ++i) {
      auto type = genericArgs->getChild(i);
      assert(genericArgs->getKind() == Node::Kind::Type);
      mangleType(type);
    }
    Out << '_';  
  }
}
Example #2
0
bool Context::isThunkSymbol(llvm::StringRef MangledName) {
  if (isMangledName(MangledName)) {
    // First do a quick check
    if (MangledName.endswith("TA") ||  // partial application forwarder
        MangledName.endswith("Ta") ||  // ObjC partial application forwarder
        MangledName.endswith("To") ||  // swift-as-ObjC thunk
        MangledName.endswith("TO") ||  // ObjC-as-swift thunk
        MangledName.endswith("TR") ||  // reabstraction thunk helper function
        MangledName.endswith("Tr") ||  // reabstraction thunk
        MangledName.endswith("TW") ||  // protocol witness thunk
        MangledName.endswith("fC")) {  // allocating constructor

      // To avoid false positives, we need to fully demangle the symbol.
      NodePointer Nd = D->demangleSymbol(MangledName);
      if (!Nd || Nd->getKind() != Node::Kind::Global ||
          Nd->getNumChildren() == 0)
        return false;

      switch (Nd->getFirstChild()->getKind()) {
        case Node::Kind::ObjCAttribute:
        case Node::Kind::NonObjCAttribute:
        case Node::Kind::PartialApplyObjCForwarder:
        case Node::Kind::PartialApplyForwarder:
        case Node::Kind::ReabstractionThunkHelper:
        case Node::Kind::ReabstractionThunk:
        case Node::Kind::ProtocolWitness:
        case Node::Kind::Allocator:
          return true;
        default:
          break;
      }
    }
    return false;
  }

  if (MangledName.startswith("_T")) {
    // Old mangling.
    StringRef Remaining = MangledName.substr(2);
    if (Remaining.startswith("To") ||   // swift-as-ObjC thunk
        Remaining.startswith("TO") ||   // ObjC-as-swift thunk
        Remaining.startswith("PA_") ||  // partial application forwarder
        Remaining.startswith("PAo_")) { // ObjC partial application forwarder
      return true;
    }
  }
  return false;
}
Example #3
0
NodePointer Demangle::stripGenericArgsFromContextNode(NodePointer node,
                                                      NodeFactory &factory) {
  switch (node->getKind()) {
  case Demangle::Node::Kind::BoundGenericClass:
  case Demangle::Node::Kind::BoundGenericEnum:
  case Demangle::Node::Kind::BoundGenericStructure:
  case Demangle::Node::Kind::BoundGenericOtherNominalType:
    // Bound generic types have a 'Type' node under them, whose child is
    // the non-generic reference. If we don't see that structure, do nothing.
    if (node->getNumChildren() < 2 ||
        node->getChild(0)->getKind() != Demangle::Node::Kind::Type ||
        node->getChild(0)->getNumChildren() < 1)
      return node;

    // Strip generic arguments from that child, then return it.
    return stripGenericArgsFromContextNode(node->getChild(0)->getChild(0),
                                          factory);

  case Demangle::Node::Kind::Class:
  case Demangle::Node::Kind::Enum:
  case Demangle::Node::Kind::Structure:
  case Demangle::Node::Kind::OtherNominalType: {
    if (node->getNumChildren() < 2)
      return node;

    auto newContext = stripGenericArgsFromContextNode(node->getChild(0),
                                                      factory);
    if (newContext == node->getChild(0)) return node;

    auto newNode = factory.createNode(node->getKind());
    newNode->addChild(newContext, factory);
    for (unsigned i = 1, n = node->getNumChildren(); i != n; ++i)
      newNode->addChild(node->getChild(i), factory);
    return newNode;
  }
      
  case Demangle::Node::Kind::Extension: {
    // Strip generic arguments from the extended type.
    if (node->getNumChildren() < 2)
      return node;
    
    auto newExtended = stripGenericArgsFromContextNode(node->getChild(1),
                                                       factory);
    if (newExtended == node->getChild(1)) return node;
    
    auto newNode = factory.createNode(Node::Kind::Extension);
    newNode->addChild(node->getChild(0), factory);
    newNode->addChild(newExtended, factory);
    if (node->getNumChildren() == 3)
      newNode->addChild(node->getChild(2), factory);
    return newNode;
  }

  case Demangle::Node::Kind::Module:
    // Modules terminate the recursion.
    return node;

  default:
    // FIXME: Handle local contexts.
    return node;
  }
}