Exemple #1
0
llvm::Constant *IRGenModule::getOrCreateOutlinedDestroyFunction(
                              SILType T, const TypeInfo &ti,
                              const OutliningMetadataCollector &collector) {
  IRGenMangler mangler;
  auto manglingBits = getTypeAndGenericSignatureForManglingOutlineFunction(T);
  auto funcName = mangler.mangleOutlinedDestroyFunction(manglingBits.first,
                                                        manglingBits.second);

  auto ptrTy = ti.getStorageType()->getPointerTo();
  llvm::SmallVector<llvm::Type *, 4> paramTys;
  paramTys.push_back(ptrTy);
  collector.addMetadataParameterTypes(paramTys);

  return getOrCreateHelperFunction(funcName, ptrTy, paramTys,
      [&](IRGenFunction &IGF) {
        Explosion params = IGF.collectParameters();
        Address addr = ti.getAddressForPointer(params.claimNext());
        collector.bindMetadataParameters(IGF, params);

        ti.destroy(IGF, addr, T, true);
        
        IGF.Builder.CreateRet(addr.getAddress());
      },
      true /*setIsNoInline*/);
}
Exemple #2
0
 /// Add a 32-bit relative offset to a mangled nominal type string
 /// in the typeref reflection section.
 void addNominalRef(const NominalTypeDecl *nominal) {
   if (auto proto = dyn_cast<ProtocolDecl>(nominal)) {
     IRGenMangler mangler;
     SymbolicMangling mangledStr;
     mangledStr.String = mangler.mangleBareProtocol(proto);
     auto mangledName = IGM.getAddrOfStringForTypeRef(mangledStr);
     B.addRelativeAddress(mangledName);
   } else {
     CanType type = nominal->getDeclaredType()->getCanonicalType();
     B.addRelativeAddress(IGM.getTypeRef(type));
   }
 }
Exemple #3
0
llvm::Constant *
IRGenModule::getOrCreateReleaseFunction(const TypeInfo &ti,
                                        SILType t,
                                        llvm::Type *llvmType) {
  auto *loadableTI = cast<LoadableTypeInfo>(&ti);
  IRGenMangler mangler;
  auto manglingBits =
    getTypeAndGenericSignatureForManglingOutlineFunction(t);
  auto funcName = mangler.mangleOutlinedReleaseFunction(manglingBits.first,
                                                        manglingBits.second);
  llvm::Type *argTys[] = {llvmType};
  return getOrCreateHelperFunction(
      funcName, llvmType, argTys,
      [&](IRGenFunction &IGF) {
        auto it = IGF.CurFn->arg_begin();
        Address addr(&*it++, loadableTI->getFixedAlignment());
        Explosion loaded;
        loadableTI->loadAsTake(IGF, addr, loaded);
        loadableTI->consume(IGF, loaded, irgen::Atomicity::Atomic);
        IGF.Builder.CreateRet(addr.getAddress());
      },
      true /*setIsNoInline*/);
}
Exemple #4
0
  /// Add a 32-bit relative offset to a mangled typeref string
  /// in the typeref reflection section.
  void addTypeRef(ModuleDecl *ModuleContext, CanType type,
                  CanGenericSignature Context = {}) {
    assert(type);

    // Generic parameters should be written in terms of interface types
    // for the purposes of reflection metadata
    assert(!type->hasArchetype() && "Forgot to map typeref out of context");

    // TODO: As a compatibility hack, mangle single-field boxes with the legacy
    // mangling in reflection metadata.
    bool isSingleFieldOfBox = false;
    auto boxTy = dyn_cast<SILBoxType>(type);
    if (boxTy && boxTy->getLayout()->getFields().size() == 1) {
      GenericContextScope scope(IGM, Context);
      type = boxTy->getFieldLoweredType(IGM.getSILModule(), 0);
      isSingleFieldOfBox = true;
    }
    IRGenMangler mangler;
    std::string MangledStr = mangler.mangleTypeForReflection(type,
                                            ModuleContext, isSingleFieldOfBox);
    auto mangledName = IGM.getAddrOfStringForTypeRef(MangledStr);
    addRelativeAddress(mangledName);
  }
Exemple #5
0
/// Mangle this entity as a std::string.
std::string LinkEntity::mangleAsString() const {
  IRGenMangler mangler;
  switch (getKind()) {
    case Kind::DispatchThunk:
      return mangler.mangleEntity(getDecl(), /*isCurried=*/false,
                                  ASTMangler::SymbolKind::SwiftDispatchThunk);

    case Kind::DispatchThunkInitializer:
      return mangler.mangleConstructorEntity(
          cast<ConstructorDecl>(getDecl()),
          /*isAllocating=*/false,
          /*isCurried=*/false,
          ASTMangler::SymbolKind::SwiftDispatchThunk);

    case Kind::DispatchThunkAllocator:
      return mangler.mangleConstructorEntity(
          cast<ConstructorDecl>(getDecl()),
          /*isAllocating=*/true,
          /*isCurried=*/false,
          ASTMangler::SymbolKind::SwiftDispatchThunk);

    case Kind::ValueWitness:
      return mangler.mangleValueWitness(getType(), getValueWitness());

    case Kind::ValueWitnessTable:
      return mangler.mangleValueWitnessTable(getType());

    case Kind::TypeMetadataAccessFunction:
      return mangler.mangleTypeMetadataAccessFunction(getType());

    case Kind::TypeMetadataLazyCacheVariable:
      return mangler.mangleTypeMetadataLazyCacheVariable(getType());

    case Kind::TypeMetadataInstantiationCache:
      return mangler.mangleTypeMetadataInstantiationCache(
                                              cast<NominalTypeDecl>(getDecl()));

    case Kind::TypeMetadataInstantiationFunction:
      return mangler.mangleTypeMetadataInstantiationFunction(
                                              cast<NominalTypeDecl>(getDecl()));

    case Kind::TypeMetadataInPlaceInitializationCache:
      return mangler.mangleTypeMetadataInPlaceInitializationCache(
                                              cast<NominalTypeDecl>(getDecl()));

    case Kind::TypeMetadataCompletionFunction:
      return mangler.mangleTypeMetadataCompletionFunction(
                                              cast<NominalTypeDecl>(getDecl()));

    case Kind::TypeMetadata:
      switch (getMetadataAddress()) {
        case TypeMetadataAddress::FullMetadata:
          return mangler.mangleTypeFullMetadataFull(getType());
        case TypeMetadataAddress::AddressPoint:
          return mangler.mangleTypeMetadataFull(getType());
      }
      llvm_unreachable("invalid metadata address");

    case Kind::TypeMetadataPattern:
      return mangler.mangleTypeMetadataPattern(
                                          cast<NominalTypeDecl>(getDecl()));

    case Kind::ForeignTypeMetadataCandidate:
      return mangler.mangleTypeMetadataFull(getType());

    case Kind::SwiftMetaclassStub:
      return mangler.mangleClassMetaClass(cast<ClassDecl>(getDecl()));

    case Kind::ClassMetadataBaseOffset:               // class metadata base offset
      return mangler.mangleClassMetadataBaseOffset(cast<ClassDecl>(getDecl()));

    case Kind::NominalTypeDescriptor:
      return mangler.mangleNominalTypeDescriptor(
                                          cast<NominalTypeDecl>(getDecl()));

    case Kind::PropertyDescriptor:
      return mangler.manglePropertyDescriptor(
                                          cast<AbstractStorageDecl>(getDecl()));

    case Kind::ModuleDescriptor:
      return mangler.mangleModuleDescriptor(cast<ModuleDecl>(getDecl()));
  
    case Kind::ExtensionDescriptor:
      return mangler.mangleExtensionDescriptor(getExtension());
    
    case Kind::AnonymousDescriptor:
      return mangler.mangleAnonymousDescriptor(getDeclContext());

    case Kind::ProtocolDescriptor:
      return mangler.mangleProtocolDescriptor(cast<ProtocolDecl>(getDecl()));

    case Kind::ProtocolConformanceDescriptor:
      return mangler.mangleProtocolConformanceDescriptor(
                     cast<NormalProtocolConformance>(getProtocolConformance()));

    case Kind::EnumCase:
      return mangler.mangleEnumCase(getDecl());

    case Kind::FieldOffset:
      return mangler.mangleFieldOffset(getDecl());

    case Kind::DirectProtocolWitnessTable:
      return mangler.mangleDirectProtocolWitnessTable(getProtocolConformance());

    case Kind::GenericProtocolWitnessTableCache:
      return mangler.mangleGenericProtocolWitnessTableCache(
                                                      getProtocolConformance());

    case Kind::GenericProtocolWitnessTableInstantiationFunction:
      return mangler.mangleGenericProtocolWitnessTableInstantiationFunction(
                                                      getProtocolConformance());

    case Kind::ResilientProtocolWitnessTable:
      return mangler.mangleResilientProtocolWitnessTable(getProtocolConformance());

    case Kind::ProtocolWitnessTableAccessFunction:
      return mangler.mangleProtocolWitnessTableAccessFunction(
                                                      getProtocolConformance());

    case Kind::ProtocolWitnessTablePattern:
      return mangler.mangleProtocolWitnessTablePattern(getProtocolConformance());

    case Kind::ProtocolWitnessTableLazyAccessFunction:
      return mangler.mangleProtocolWitnessTableLazyAccessFunction(getType(),
                                                      getProtocolConformance());

    case Kind::ProtocolWitnessTableLazyCacheVariable:
      return mangler.mangleProtocolWitnessTableLazyCacheVariable(getType(),
                                                      getProtocolConformance());

    case Kind::AssociatedTypeMetadataAccessFunction:
      return mangler.mangleAssociatedTypeMetadataAccessFunction(
                  getProtocolConformance(), getAssociatedType()->getNameStr());

    case Kind::AssociatedTypeWitnessTableAccessFunction: {
      auto assocConf = getAssociatedConformance();
      return mangler.mangleAssociatedTypeWitnessTableAccessFunction(
                  getProtocolConformance(), assocConf.first, assocConf.second);
    }

    case Kind::CoroutineContinuationPrototype:
      return mangler.mangleCoroutineContinuationPrototype(
                                              cast<SILFunctionType>(getType()));

      // An Objective-C class reference reference. The symbol is private, so
      // the mangling is unimportant; it should just be readable in LLVM IR.
    case Kind::ObjCClassRef: {
      llvm::SmallString<64> tempBuffer;
      StringRef name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(tempBuffer);
      std::string Result("\01l_OBJC_CLASS_REF_$_");
      Result.append(name.data(), name.size());
      return Result;
    }

      // An Objective-C class reference;  not a swift mangling.
    case Kind::ObjCClass: {
      llvm::SmallString<64> TempBuffer;
      StringRef Name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(TempBuffer);
      std::string Result("OBJC_CLASS_$_");
      Result.append(Name.data(), Name.size());
      return Result;
    }

      // An Objective-C metaclass reference;  not a swift mangling.
    case Kind::ObjCMetaclass: {
      llvm::SmallString<64> TempBuffer;
      StringRef Name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(TempBuffer);
      std::string Result("OBJC_METACLASS_$_");
      Result.append(Name.data(), Name.size());
      return Result;
    }

    case Kind::SILFunction:
      return getSILFunction()->getName();
    case Kind::SILGlobalVariable:
      return getSILGlobalVariable()->getName();

    case Kind::ReflectionBuiltinDescriptor:
      return mangler.mangleReflectionBuiltinDescriptor(getType());
    case Kind::ReflectionFieldDescriptor:
      return mangler.mangleReflectionFieldDescriptor(getType());
    case Kind::ReflectionAssociatedTypeDescriptor:
      return mangler.mangleReflectionAssociatedTypeDescriptor(
                                                      getProtocolConformance());
  }
  llvm_unreachable("bad entity kind!");
}
Exemple #6
0
llvm::Constant *IRGenModule::getTypeRef(CanType type) {
  IRGenMangler Mangler;
  auto SymbolicName = Mangler.mangleTypeForReflection(*this, type);
  return getAddrOfStringForTypeRef(SymbolicName);
}
Exemple #7
0
/// Mangle this entity as a std::string.
std::string LinkEntity::mangleAsString() const {
  IRGenMangler mangler;
  switch (getKind()) {
  case Kind::DispatchThunk: {
    auto *func = cast<FuncDecl>(getDecl());
    return mangler.mangleDispatchThunk(func);
  }

  case Kind::DispatchThunkInitializer: {
    auto *ctor = cast<ConstructorDecl>(getDecl());
    return mangler.mangleConstructorDispatchThunk(ctor,
                                                  /*isAllocating=*/false);
  }

  case Kind::DispatchThunkAllocator: {
    auto *ctor = cast<ConstructorDecl>(getDecl());
    return mangler.mangleConstructorDispatchThunk(ctor,
                                                  /*isAllocating=*/true);
  }

  case Kind::MethodDescriptor: {
    auto *func = cast<FuncDecl>(getDecl());
    return mangler.mangleMethodDescriptor(func);
  }

  case Kind::MethodDescriptorInitializer: {
    auto *ctor = cast<ConstructorDecl>(getDecl());
    return mangler.mangleConstructorMethodDescriptor(ctor,
                                                     /*isAllocating=*/false);
  }

  case Kind::MethodDescriptorAllocator: {
    auto *ctor = cast<ConstructorDecl>(getDecl());
    return mangler.mangleConstructorMethodDescriptor(ctor,
                                                     /*isAllocating=*/true);
  }

  case Kind::MethodLookupFunction: {
    auto *classDecl = cast<ClassDecl>(getDecl());
    return mangler.mangleMethodLookupFunction(classDecl);
  }

  case Kind::ValueWitness:
    return mangler.mangleValueWitness(getType(), getValueWitness());

  case Kind::ValueWitnessTable:
    return mangler.mangleValueWitnessTable(getType());

  case Kind::TypeMetadataAccessFunction:
    return mangler.mangleTypeMetadataAccessFunction(getType());

  case Kind::TypeMetadataLazyCacheVariable:
    return mangler.mangleTypeMetadataLazyCacheVariable(getType());

  case Kind::TypeMetadataInstantiationCache:
    return mangler.mangleTypeMetadataInstantiationCache(
                                            cast<NominalTypeDecl>(getDecl()));

  case Kind::TypeMetadataInstantiationFunction:
    return mangler.mangleTypeMetadataInstantiationFunction(
                                            cast<NominalTypeDecl>(getDecl()));

  case Kind::TypeMetadataSingletonInitializationCache:
    return mangler.mangleTypeMetadataSingletonInitializationCache(
                                            cast<NominalTypeDecl>(getDecl()));

  case Kind::TypeMetadataCompletionFunction:
    return mangler.mangleTypeMetadataCompletionFunction(
                                            cast<NominalTypeDecl>(getDecl()));

  case Kind::TypeMetadata:
    switch (getMetadataAddress()) {
      case TypeMetadataAddress::FullMetadata:
        return mangler.mangleTypeFullMetadataFull(getType());
      case TypeMetadataAddress::AddressPoint:
        return mangler.mangleTypeMetadataFull(getType());
    }
    llvm_unreachable("invalid metadata address");

  case Kind::TypeMetadataPattern:
    return mangler.mangleTypeMetadataPattern(
                                        cast<NominalTypeDecl>(getDecl()));

  case Kind::SwiftMetaclassStub:
    return mangler.mangleClassMetaClass(cast<ClassDecl>(getDecl()));

  case Kind::ObjCMetadataUpdateFunction:
    return mangler.mangleObjCMetadataUpdateFunction(cast<ClassDecl>(getDecl()));

  case Kind::ObjCResilientClassStub:
    switch (getMetadataAddress()) {
    case TypeMetadataAddress::FullMetadata:
      return mangler.mangleFullObjCResilientClassStub(cast<ClassDecl>(getDecl()));
    case TypeMetadataAddress::AddressPoint:
      return mangler.mangleObjCResilientClassStub(cast<ClassDecl>(getDecl()));
    }
    llvm_unreachable("invalid metadata address");

  case Kind::ClassMetadataBaseOffset:               // class metadata base offset
    return mangler.mangleClassMetadataBaseOffset(cast<ClassDecl>(getDecl()));

  case Kind::NominalTypeDescriptor:
    return mangler.mangleNominalTypeDescriptor(
                                        cast<NominalTypeDecl>(getDecl()));

  case Kind::OpaqueTypeDescriptor:
    return mangler.mangleOpaqueTypeDescriptor(cast<OpaqueTypeDecl>(getDecl()));

  case Kind::OpaqueTypeDescriptorAccessor:
    return mangler.mangleOpaqueTypeDescriptorAccessor(
        cast<OpaqueTypeDecl>(getDecl()));

  case Kind::OpaqueTypeDescriptorAccessorImpl:
    return mangler.mangleOpaqueTypeDescriptorAccessorImpl(
        cast<OpaqueTypeDecl>(getDecl()));

  case Kind::OpaqueTypeDescriptorAccessorKey:
    return mangler.mangleOpaqueTypeDescriptorAccessorKey(
        cast<OpaqueTypeDecl>(getDecl()));

  case Kind::OpaqueTypeDescriptorAccessorVar:
    return mangler.mangleOpaqueTypeDescriptorAccessorVar(
        cast<OpaqueTypeDecl>(getDecl()));

  case Kind::PropertyDescriptor:
    return mangler.manglePropertyDescriptor(
                                        cast<AbstractStorageDecl>(getDecl()));

  case Kind::ModuleDescriptor:
    return mangler.mangleModuleDescriptor(cast<ModuleDecl>(getDecl()));
  
  case Kind::ExtensionDescriptor:
    return mangler.mangleExtensionDescriptor(getExtension());

  case Kind::AnonymousDescriptor:
    return mangler.mangleAnonymousDescriptor(getAnonymousDeclContext());

  case Kind::ProtocolDescriptor:
    return mangler.mangleProtocolDescriptor(cast<ProtocolDecl>(getDecl()));

  case Kind::ProtocolRequirementsBaseDescriptor:
    return mangler.mangleProtocolRequirementsBaseDescriptor(
                                                 cast<ProtocolDecl>(getDecl()));

  case Kind::AssociatedTypeDescriptor:
    return mangler.mangleAssociatedTypeDescriptor(
                                          cast<AssociatedTypeDecl>(getDecl()));

  case Kind::AssociatedConformanceDescriptor: {
    auto assocConformance = getAssociatedConformance();
    return mangler.mangleAssociatedConformanceDescriptor(
             cast<ProtocolDecl>(getDecl()),
             assocConformance.first,
             assocConformance.second);
  }

  case Kind::BaseConformanceDescriptor: {
    auto assocConformance = getAssociatedConformance();
    return mangler.mangleBaseConformanceDescriptor(
             cast<ProtocolDecl>(getDecl()),
             assocConformance.second);
  }

  case Kind::DefaultAssociatedConformanceAccessor: {
    auto assocConformance = getAssociatedConformance();
    return mangler.mangleDefaultAssociatedConformanceAccessor(
             cast<ProtocolDecl>(getDecl()),
             assocConformance.first,
             assocConformance.second);
  }

  case Kind::ProtocolConformanceDescriptor:
    return mangler.mangleProtocolConformanceDescriptor(
                                                  getRootProtocolConformance());

  case Kind::EnumCase:
    return mangler.mangleEnumCase(getDecl());

  case Kind::FieldOffset:
    return mangler.mangleFieldOffset(getDecl());

  case Kind::ProtocolWitnessTable:
    return mangler.mangleWitnessTable(getRootProtocolConformance());

  case Kind::GenericProtocolWitnessTableInstantiationFunction:
    return mangler.mangleGenericProtocolWitnessTableInstantiationFunction(
                                                    getProtocolConformance());

  case Kind::ProtocolWitnessTablePattern:
    return mangler.mangleProtocolWitnessTablePattern(getProtocolConformance());

  case Kind::ProtocolWitnessTableLazyAccessFunction:
    return mangler.mangleProtocolWitnessTableLazyAccessFunction(getType(),
                                                    getProtocolConformance());

  case Kind::ProtocolWitnessTableLazyCacheVariable:
    return mangler.mangleProtocolWitnessTableLazyCacheVariable(getType(),
                                                    getProtocolConformance());

  case Kind::AssociatedTypeWitnessTableAccessFunction: {
    auto assocConf = getAssociatedConformance();
    if (isa<GenericTypeParamType>(assocConf.first)) {
      return mangler.mangleBaseWitnessTableAccessFunction(
                  getProtocolConformance(), assocConf.second);
    }
    
    return mangler.mangleAssociatedTypeWitnessTableAccessFunction(
                getProtocolConformance(), assocConf.first, assocConf.second);
  }

  case Kind::CoroutineContinuationPrototype:
    return mangler.mangleCoroutineContinuationPrototype(
                                            cast<SILFunctionType>(getType()));

    // An Objective-C class reference reference. The symbol is private, so
    // the mangling is unimportant; it should just be readable in LLVM IR.
  case Kind::ObjCClassRef: {
    llvm::SmallString<64> tempBuffer;
    StringRef name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(tempBuffer);
    std::string Result("OBJC_CLASS_REF_$_");
    Result.append(name.data(), name.size());
    return Result;
  }

    // An Objective-C class reference;  not a swift mangling.
  case Kind::ObjCClass: {
    llvm::SmallString<64> TempBuffer;
    StringRef Name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(TempBuffer);
    std::string Result("OBJC_CLASS_$_");
    Result.append(Name.data(), Name.size());
    return Result;
  }

    // An Objective-C metaclass reference;  not a swift mangling.
  case Kind::ObjCMetaclass: {
    llvm::SmallString<64> TempBuffer;
    StringRef Name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(TempBuffer);
    std::string Result("OBJC_METACLASS_$_");
    Result.append(Name.data(), Name.size());
    return Result;
  }

  case Kind::SILFunction: {
    std::string Result(getSILFunction()->getName());
    if (isDynamicallyReplaceable()) {
      Result.append("TI");
    }
    return Result;
  }
  case Kind::DynamicallyReplaceableFunctionImpl: {
    assert(isa<AbstractFunctionDecl>(getDecl()));
    std::string Result;
    if (auto *Constructor = dyn_cast<ConstructorDecl>(getDecl())) {
      Result = mangler.mangleConstructorEntity(Constructor, isAllocator(),
                                               /*isCurried=*/false);
    } else  {
      Result = mangler.mangleEntity(getDecl(), /*isCurried=*/false);
    }
    Result.append("TI");
    return Result;
  }

  case Kind::DynamicallyReplaceableFunctionVariable: {
    std::string Result(getSILFunction()->getName());
    Result.append("TX");
    return Result;
  }

  case Kind::DynamicallyReplaceableFunctionKey: {
    std::string Result(getSILFunction()->getName());
    Result.append("Tx");
    return Result;
  }


  case Kind::DynamicallyReplaceableFunctionVariableAST: {
    assert(isa<AbstractFunctionDecl>(getDecl()));
    std::string Result;
    if (auto *Constructor = dyn_cast<ConstructorDecl>(getDecl())) {
      Result =
          mangler.mangleConstructorEntity(Constructor, isAllocator(),
                                          /*isCurried=*/false);
    } else  {
      Result = mangler.mangleEntity(getDecl(), /*isCurried=*/false);
    }
    Result.append("TX");
    return Result;
  }

  case Kind::DynamicallyReplaceableFunctionKeyAST: {
    assert(isa<AbstractFunctionDecl>(getDecl()));
    std::string Result;
    if (auto *Constructor = dyn_cast<ConstructorDecl>(getDecl())) {
      Result =
          mangler.mangleConstructorEntity(Constructor, isAllocator(),
                                          /*isCurried=*/false);
    } else  {
      Result = mangler.mangleEntity(getDecl(), /*isCurried=*/false);
    }
    Result.append("Tx");
    return Result;
  }

  case Kind::SILGlobalVariable:
    return getSILGlobalVariable()->getName();

  case Kind::ReflectionBuiltinDescriptor:
    return mangler.mangleReflectionBuiltinDescriptor(getType());
  case Kind::ReflectionFieldDescriptor:
    return mangler.mangleReflectionFieldDescriptor(getType());
  case Kind::ReflectionAssociatedTypeDescriptor:
    return mangler.mangleReflectionAssociatedTypeDescriptor(
                                                    getProtocolConformance());
  }
  llvm_unreachable("bad entity kind!");
}
Exemple #8
0
/// Mangle this entity into the given stream.
std::string LinkEntity::mangleNew() const {
  // Almost everything below gets the common prefix:
  //   mangled-name ::= '_T' global
  IRGenMangler mangler;
  switch (getKind()) {
      //   global ::= 'w' value-witness-kind          // value witness
    case Kind::ValueWitness:
      return mangler.mangleValueWitness(getType(), getValueWitness());

      //   global ::= 'WV' type                       // value witness
    case Kind::ValueWitnessTable:
      return mangler.mangleValueWitnessTable(getType());

      //   global ::= 'Ma' type               // type metadata access function
    case Kind::TypeMetadataAccessFunction:
      return mangler.mangleTypeMetadataAccessFunction(getType());

      //   global ::= 'ML' type               // type metadata lazy cache variable
    case Kind::TypeMetadataLazyCacheVariable:
      return mangler.mangleTypeMetadataLazyCacheVariable(getType());

      //   global ::= 'Mf' type                       // 'full' type metadata
      //   global ::= 'M' directness type             // type metadata
      //   global ::= 'MP' directness type            // type metadata pattern
    case Kind::TypeMetadata:
      switch (getMetadataAddress()) {
        case TypeMetadataAddress::FullMetadata:
          return mangler.mangleTypeFullMetadataFull(getType());
        case TypeMetadataAddress::AddressPoint:
          return mangler.mangleTypeMetadataFull(getType(), isMetadataPattern());
      }
      llvm_unreachable("invalid metadata address");

      //   global ::= 'M' directness type             // type metadata
    case Kind::ForeignTypeMetadataCandidate:
      return mangler.mangleTypeMetadataFull(getType(), /*isPattern=*/false);

      //   global ::= 'Mm' type                       // class metaclass
    case Kind::SwiftMetaclassStub:
      return mangler.mangleClassMetaClass(cast<ClassDecl>(getDecl()));

      //   global ::= 'Mn' type                       // nominal type descriptor
    case Kind::NominalTypeDescriptor:
      return mangler.mangleNominalTypeDescriptor(
                                          cast<NominalTypeDecl>(getDecl()));

      //   global ::= 'Mp' type                       // protocol descriptor
    case Kind::ProtocolDescriptor:
      return mangler.mangleProtocolDescriptor(cast<ProtocolDecl>(getDecl()));

      //   global ::= 'Wo' entity
    case Kind::WitnessTableOffset:
      return mangler.mangleWitnessTableOffset(getDecl());

      //   global ::= 'Wv' directness entity
    case Kind::FieldOffset:
      return mangler.mangleFieldOffsetFull(getDecl(), isOffsetIndirect());

      //   global ::= 'WP' protocol-conformance
    case Kind::DirectProtocolWitnessTable:
      return mangler.mangleDirectProtocolWitnessTable(getProtocolConformance());

      //   global ::= 'WG' protocol-conformance
    case Kind::GenericProtocolWitnessTableCache:
      return mangler.mangleGenericProtocolWitnessTableCache(
                                                      getProtocolConformance());

      //   global ::= 'WI' protocol-conformance
    case Kind::GenericProtocolWitnessTableInstantiationFunction:
      return mangler.mangleGenericProtocolWitnessTableInstantiationFunction(
                                                      getProtocolConformance());

      //   global ::= 'Wa' protocol-conformance
    case Kind::ProtocolWitnessTableAccessFunction:
      return mangler.mangleProtocolWitnessTableAccessFunction(
                                                      getProtocolConformance());

      //   global ::= 'Wl' type protocol-conformance
    case Kind::ProtocolWitnessTableLazyAccessFunction:
      return mangler.mangleProtocolWitnessTableLazyAccessFunction(getType(),
                                                      getProtocolConformance());

      //   global ::= 'WL' type protocol-conformance
    case Kind::ProtocolWitnessTableLazyCacheVariable:
      return mangler.mangleProtocolWitnessTableLazyCacheVariable(getType(),
                                                      getProtocolConformance());

      //   global ::= 'Wt' protocol-conformance identifier
    case Kind::AssociatedTypeMetadataAccessFunction:
      return mangler.mangleAssociatedTypeMetadataAccessFunction(
                  getProtocolConformance(), getAssociatedType()->getNameStr());

      //   global ::= 'WT' protocol-conformance identifier nominal-type
    case Kind::AssociatedTypeWitnessTableAccessFunction:
      return mangler.mangleAssociatedTypeWitnessTableAccessFunction(
                  getProtocolConformance(), getAssociatedType()->getNameStr(),
                  getAssociatedProtocol());

      // For all the following, this rule was imposed above:
      //   global ::= local-marker? entity            // some identifiable thing

      //   entity ::= declaration                     // other declaration
    case Kind::Function:
      // As a special case, functions can have manually mangled names.
      if (auto AsmA = getDecl()->getAttrs().getAttribute<SILGenNameAttr>()) {
        return AsmA->Name;
      }

      // Otherwise, fall through into the 'other decl' case.
      LLVM_FALLTHROUGH;

    case Kind::Other:
      // As a special case, Clang functions and globals don't get mangled at all.
      if (auto clangDecl = getDecl()->getClangDecl()) {
        if (auto namedClangDecl = dyn_cast<clang::DeclaratorDecl>(clangDecl)) {
          if (auto asmLabel = namedClangDecl->getAttr<clang::AsmLabelAttr>()) {
            std::string Name(1, '\01');
            Name.append(asmLabel->getLabel());
            return Name;
          }
          if (namedClangDecl->hasAttr<clang::OverloadableAttr>()) {
            // FIXME: When we can import C++, use Clang's mangler all the time.
            std::string storage;
            llvm::raw_string_ostream SS(storage);
            mangleClangDecl(SS, namedClangDecl, getDecl()->getASTContext());
            return SS.str();
          }
          return namedClangDecl->getName();
        }
      }

      if (auto type = dyn_cast<NominalTypeDecl>(getDecl())) {
        return mangler.mangleNominalType(type);
      }
      if (auto ctor = dyn_cast<ConstructorDecl>(getDecl())) {
        // FIXME: Hack. LinkInfo should be able to refer to the allocating
        // constructor rather than inferring it here.
        return mangler.mangleConstructorEntity(ctor, /*isAllocating=*/true,
                                               /*isCurried=*/false);
      }
      return mangler.mangleEntity(getDecl(), /*isCurried=*/false);

      // An Objective-C class reference reference. The symbol is private, so
      // the mangling is unimportant; it should just be readable in LLVM IR.
    case Kind::ObjCClassRef: {
      llvm::SmallString<64> tempBuffer;
      StringRef name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(tempBuffer);
      std::string Result("OBJC_CLASS_REF_$_");
      Result.append(name.data(), name.size());
      return Result;
    }

      // An Objective-C class reference;  not a swift mangling.
    case Kind::ObjCClass: {
      llvm::SmallString<64> TempBuffer;
      StringRef Name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(TempBuffer);
      std::string Result("OBJC_CLASS_$_");
      Result.append(Name.data(), Name.size());
      return Result;
    }

      // An Objective-C metaclass reference;  not a swift mangling.
    case Kind::ObjCMetaclass: {
      llvm::SmallString<64> TempBuffer;
      StringRef Name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(TempBuffer);
      std::string Result("OBJC_METACLASS_$_");
      Result.append(Name.data(), Name.size());
      return Result;
    }

    case Kind::SILFunction:
      return getSILFunction()->getName();
    case Kind::SILGlobalVariable:
      return getSILGlobalVariable()->getName();

    case Kind::ReflectionBuiltinDescriptor:
      return mangler.mangleReflectionBuiltinDescriptor(getType());
    case Kind::ReflectionFieldDescriptor:
      return mangler.mangleReflectionFieldDescriptor(getType());
    case Kind::ReflectionAssociatedTypeDescriptor:
      return mangler.mangleReflectionAssociatedTypeDescriptor(
                                                      getProtocolConformance());
    case Kind::ReflectionSuperclassDescriptor:
      return mangler.mangleReflectionSuperclassDescriptor(
                                                    cast<ClassDecl>(getDecl()));
  }
  llvm_unreachable("bad entity kind!");
}