Beispiel #1
0
std::string ExecutionEngine::getMangledName(const GlobalValue *GV) {
  MutexGuard locked(lock);
  Mangler Mang;
  SmallString<128> FullName;
  Mang.getNameWithPrefix(FullName, GV, false);
  return FullName.str();
}
void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
    raw_ostream &OS, const GlobalValue *GV, const Mangler &Mang) const {
  if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
    return;

  const Triple &TT = getTargetTriple();

  if (TT.isKnownWindowsMSVCEnvironment())
    OS << " /EXPORT:";
  else
    OS << " -export:";

  if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
    std::string Flag;
    raw_string_ostream FlagOS(Flag);
    Mang.getNameWithPrefix(FlagOS, GV, false);
    FlagOS.flush();
    if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
      OS << Flag.substr(1);
    else
      OS << Flag;
  } else {
    Mang.getNameWithPrefix(OS, GV, false);
  }

  if (!GV->getValueType()->isFunctionTy()) {
    if (TT.isKnownWindowsMSVCEnvironment())
      OS << ",DATA";
    else
      OS << ",data";
  }
}
/// Get or create SILGlobalVariable for a given global VarDecl.
SILGlobalVariable *SILGenModule::getSILGlobalVariable(VarDecl *gDecl,
                                                      ForDefinition_t forDef) {
  // First, get a mangled name for the declaration.
  std::string mangledName;

  if (auto SILGenName = gDecl->getAttrs().getAttribute<SILGenNameAttr>()) {
    mangledName = SILGenName->Name;
  } else {
    Mangler mangler;
    mangler.mangleGlobalVariableFull(gDecl);
    mangledName = mangler.finalize();
  }

  // Check if it is already created, and update linkage if necessary.
  if (auto gv = M.lookUpGlobalVariable(mangledName)) {
    // Update the SILLinkage here if this is a definition.
    if (forDef == ForDefinition) {
      gv->setLinkage(getSILLinkage(getDeclLinkage(gDecl), ForDefinition));
      gv->setDeclaration(false);
    }
    return gv;
  }

  // Get the linkage for SILGlobalVariable.
  SILLinkage link = getSILLinkage(getDeclLinkage(gDecl), forDef);
  SILType silTy = M.Types.getLoweredTypeOfGlobal(gDecl);

  auto *silGlobal = SILGlobalVariable::create(M, link,
                                              makeModuleFragile ? IsFragile : IsNotFragile,
                                              mangledName, silTy,
                                              None, gDecl);
  silGlobal->setDeclaration(!forDef);

  return silGlobal;
}
Beispiel #4
0
static void mangleSubstitution(Mangler &M, Substitution Sub) {
  M.mangleType(Sub.getReplacement()->getCanonicalType(), 0);
  for (auto C : Sub.getConformances()) {
    if (C.isAbstract())
      return;
    M.mangleProtocolConformance(C.getConcrete());
  }
}
Beispiel #5
0
static void mangleSubstitution(Mangler &M, Substitution Sub) {
  M.mangleType(Sub.getReplacement()->getCanonicalType(),
               ResilienceExpansion::Minimal, 0);
  for (auto C : Sub.getConformances()) {
    if (!C)
      return;
    M.mangleProtocolConformance(C);
  }
}
Beispiel #6
0
static SILValue getBehaviorInitStorageFn(SILGenFunction &gen,
                                         VarDecl *behaviorVar) {
  std::string behaviorInitName;
  {
    Mangler m;
    m.mangleBehaviorInitThunk(behaviorVar);
    std::string Old = m.finalize();
    NewMangling::ASTMangler NewMangler;
    std::string New = NewMangler.mangleBehaviorInitThunk(behaviorVar);
    behaviorInitName = NewMangling::selectMangling(Old, New);
  }
  
  SILFunction *thunkFn;
  // Skip out early if we already emitted this thunk.
  if (auto existing = gen.SGM.M.lookUpFunction(behaviorInitName)) {
    thunkFn = existing;
  } else {
    auto init = behaviorVar->getBehavior()->InitStorageDecl.getDecl();
    auto initFn = gen.SGM.getFunction(SILDeclRef(init), NotForDefinition);
    
    // Emit a thunk to inject the `self` metatype and implode tuples.
    auto storageVar = behaviorVar->getBehavior()->StorageDecl;
    auto selfTy = behaviorVar->getDeclContext()->getDeclaredInterfaceType();
    auto initTy = gen.getLoweredType(selfTy).getFieldType(behaviorVar,
                                                          gen.SGM.M);
    auto storageTy = gen.getLoweredType(selfTy).getFieldType(storageVar,
                                                             gen.SGM.M);
    
    auto initConstantTy = initFn->getLoweredType().castTo<SILFunctionType>();
    
    auto param = SILParameterInfo(initTy.getSwiftRValueType(),
                        initTy.isAddress() ? ParameterConvention::Indirect_In
                                           : ParameterConvention::Direct_Owned);
    auto result = SILResultInfo(storageTy.getSwiftRValueType(),
                              storageTy.isAddress() ? ResultConvention::Indirect
                                                    : ResultConvention::Owned);
    
    initConstantTy = SILFunctionType::get(initConstantTy->getGenericSignature(),
                                          initConstantTy->getExtInfo(),
                                          ParameterConvention::Direct_Unowned,
                                          param,
                                          result,
                                          // TODO: throwing initializer?
                                          None,
                                          gen.getASTContext());
    
    // TODO: Generate the body of the thunk.
    thunkFn = gen.SGM.M.getOrCreateFunction(SILLocation(behaviorVar),
                                            behaviorInitName,
                                            SILLinkage::PrivateExternal,
                                            initConstantTy,
                                            IsBare, IsTransparent, IsFragile);
    
    
  }
  return gen.B.createFunctionRef(behaviorVar, thunkFn);
}
Beispiel #7
0
	std::string mangle(const GlobalValue *GV) {
		std::string MangledName;
		{
			Mangler Mang;

			raw_string_ostream MangledNameStream(MangledName);
			Mang.getNameWithPrefix(MangledNameStream, GV, false);
		}
		return MangledName;
	}
Beispiel #8
0
static std::string mangleConstant(NormalProtocolConformance *C) {
  using namespace Mangle;
  Mangler mangler;

  //   mangled-name ::= '_T' global
  //   global ::= 'WP' protocol-conformance
  mangler.append("_TWP");
  mangler.mangleProtocolConformance(C);
  return mangler.finalize();

}
Beispiel #9
0
void LTOCodeGenerator::applyScopeRestrictions() {
  if (ScopeRestrictionsDone)
    return;

  // Declare a callback for the internalize pass that will ask for every
  // candidate GlobalValue if it can be internalized or not.
  Mangler Mang;
  SmallString<64> MangledName;
  auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
    // Unnamed globals can't be mangled, but they can't be preserved either.
    if (!GV.hasName())
      return false;

    // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
    // with the linker supplied name, which on Darwin includes a leading
    // underscore.
    MangledName.clear();
    MangledName.reserve(GV.getName().size() + 1);
    Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
    return MustPreserveSymbols.count(MangledName);
  };

  // Preserve linkonce value on linker request
  preserveDiscardableGVs(*MergedModule, mustPreserveGV);

  if (!ShouldInternalize)
    return;

  if (ShouldRestoreGlobalsLinkage) {
    // Record the linkage type of non-local symbols so they can be restored
    // prior
    // to module splitting.
    auto RecordLinkage = [&](const GlobalValue &GV) {
      if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
          GV.hasName())
        ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
    };
    for (auto &GV : *MergedModule)
      RecordLinkage(GV);
    for (auto &GV : MergedModule->globals())
      RecordLinkage(GV);
    for (auto &GV : MergedModule->aliases())
      RecordLinkage(GV);
  }

  // Update the llvm.compiler_used globals to force preserving libcalls and
  // symbols referenced from asm
  updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);

  internalizeModule(*MergedModule, mustPreserveGV);

  ScopeRestrictionsDone = true;
}
bool ide::printDeclUSR(const ValueDecl *D, raw_ostream &OS) {
  using namespace Mangle;

  if (!isa<FuncDecl>(D) && !D->hasName())
    return true; // Ignore.
  if (D->getModuleContext()->isBuiltinModule())
    return true; // Ignore.

  ValueDecl *VD = const_cast<ValueDecl *>(D);

  if (ClangNode ClangN = VD->getClangNode()) {
    llvm::SmallString<128> Buf;
    if (auto ClangD = ClangN.getAsDecl()) {
      bool Ignore = clang::index::generateUSRForDecl(ClangD, Buf);
      if (!Ignore)
        OS << Buf.str();
      return Ignore;
    }

    auto &Importer = *D->getASTContext().getClangModuleLoader();

    auto ClangMacroInfo = ClangN.getAsMacro();
    auto PPRecord = Importer.getClangPreprocessor().getPreprocessingRecord();
    assert(PPRecord && "Clang importer should be created with "
                       "-detailed-preprocessing-record option");
    auto ClangMacroDef = PPRecord->findMacroDefinition(ClangMacroInfo);

    bool Ignore = clang::index::generateUSRForMacro(
        ClangMacroDef, Importer.getClangASTContext().getSourceManager(), Buf);
    if (!Ignore)
      OS << Buf.str();
    return Ignore;
  }

  if (!D->hasType())
    return true;

  // FIXME: mangling 'self' in destructors crashes in mangler.
  if (isa<ParamDecl>(VD) && isa<DestructorDecl>(VD->getDeclContext()))
    return true;

  OS << getUSRSpacePrefix();
  Mangler Mangler;
  if (auto Ctor = dyn_cast<ConstructorDecl>(VD)) {
    Mangler.mangleConstructorEntity(Ctor, /*isAllocating=*/false,
                                    /*uncurryingLevel=*/0);
  } else if (auto Dtor = dyn_cast<DestructorDecl>(VD)) {
    Mangler.mangleDestructorEntity(Dtor, /*isDeallocating=*/false);
  } else if (auto NTD = dyn_cast<NominalTypeDecl>(VD)) {
    Mangler.mangleNominalType(NTD, Mangler::BindGenerics::None);
  } else if (isa<TypeAliasDecl>(VD) || isa<AssociatedTypeDecl>(VD)) {
    Mangler.mangleContextOf(VD, Mangler::BindGenerics::None);
    Mangler.mangleDeclName(VD);
  } else {
    Mangler.mangleEntity(VD, /*uncurryingLevel=*/0);
  }

  Mangler.finalize(OS);
  return false;
}
Beispiel #11
0
static std::string mangleConstant(NormalProtocolConformance *C) {
  using namespace Mangle;
  Mangler mangler;

  //   mangled-name ::= '_T' global
  //   global ::= 'WP' protocol-conformance
  mangler.append("_TWP");
  mangler.mangleProtocolConformance(C);
  std::string Old = mangler.finalize();

  NewMangling::ASTMangler NewMangler;
  std::string New = NewMangler.mangleWitnessTable(C);

  return NewMangling::selectMangling(Old, New);
}
Beispiel #12
0
void LTOCodeGenerator::
applyRestriction(GlobalValue &GV,
                 const ArrayRef<StringRef> &Libcalls,
                 std::vector<const char*> &MustPreserveList,
                 SmallPtrSet<GlobalValue*, 8> &AsmUsed,
                 Mangler &Mangler) {
  SmallString<64> Buffer;
  Mangler.getNameWithPrefix(Buffer, &GV);

  if (GV.isDeclaration())
    return;
  if (MustPreserveSymbols.count(Buffer))
    MustPreserveList.push_back(GV.getName().data());
  if (AsmUndefinedRefs.count(Buffer))
    AsmUsed.insert(&GV);

  // Conservatively append user-supplied runtime library functions to
  // llvm.compiler.used.  These could be internalized and deleted by
  // optimizations like -globalopt, causing problems when later optimizations
  // add new library calls (e.g., llvm.memset => memset and printf => puts).
  // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
  if (isa<Function>(GV) &&
      std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName()))
    AsmUsed.insert(&GV);
}
Beispiel #13
0
void LTOModule::addPotentialUndefinedSymbol(GlobalValue* decl, Mangler &mangler)
{   
   const char* name = mangler.getValueName(decl).c_str();
    // ignore all llvm.* symbols
    if ( strncmp(name, "llvm.", 5) != 0 ) {
        _undefines[name] = 1;
    }
}
Beispiel #14
0
void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
                                      const Triple &T, Mangler &M) {
  if (!T.isKnownWindowsMSVCEnvironment())
    return;

  OS << " /INCLUDE:";
  M.getNameWithPrefix(OS, GV, false);
}
void TargetLoweringObjectFileMachO::getNameWithPrefix(
    SmallVectorImpl<char> &OutName, const GlobalValue *GV, Mangler &Mang,
    const TargetMachine &TM) const {
  SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
  const MCSection *TheSection = SectionForGlobal(GV, GVKind, Mang, TM);
  bool CannotUsePrivateLabel =
      !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection);
  Mang.getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);
}
void TargetLoweringObjectFileCOFF::getNameWithPrefix(
    SmallVectorImpl<char> &OutName, const GlobalValue *GV,
    bool CannotUsePrivateLabel, Mangler &Mang, const TargetMachine &TM) const {
  if (GV->hasPrivateLinkage() &&
      ((isa<Function>(GV) && TM.getFunctionSections()) ||
       (isa<GlobalVariable>(GV) && TM.getDataSections())))
    CannotUsePrivateLabel = true;

  Mang.getNameWithPrefix(OutName, GV, CannotUsePrivateLabel);
}
Beispiel #17
0
void LTOModule::addDefinedSymbol(GlobalValue* def, Mangler &mangler, 
                                bool isFunction)
{    
    // string is owned by _defines
    const char* symbolName = ::strdup(mangler.getValueName(def).c_str());
    
    // set alignment part log2() can have rounding errors
    uint32_t align = def->getAlignment();
    uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0;
    
    // set permissions part
    if ( isFunction )
        attr |= LTO_SYMBOL_PERMISSIONS_CODE;
    else {
        GlobalVariable* gv = dyn_cast<GlobalVariable>(def);
        if ( (gv != NULL) && gv->isConstant() )
            attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
        else
            attr |= LTO_SYMBOL_PERMISSIONS_DATA;
    }
    
    // set definition part 
    if ( def->hasWeakLinkage() || def->hasLinkOnceLinkage() ) {
        // lvm bitcode does not differenciate between weak def data 
        // and tentative definitions!
        // HACK HACK HACK
        // C++ does not use tentative definitions, but does use weak symbols
        // so guess that anything that looks like a C++ symbol is weak and others
        // are tentative definitions
        if ( (strncmp(symbolName, "__Z", 3) == 0) )
            attr |= LTO_SYMBOL_DEFINITION_WEAK;
        else {
            attr |= LTO_SYMBOL_DEFINITION_TENTATIVE;
        }
    }
    else { 
        attr |= LTO_SYMBOL_DEFINITION_REGULAR;
    }
    
    // set scope part
    if ( def->hasHiddenVisibility() )
        attr |= LTO_SYMBOL_SCOPE_HIDDEN;
    else if ( def->hasExternalLinkage() || def->hasWeakLinkage() )
        attr |= LTO_SYMBOL_SCOPE_DEFAULT;
    else
        attr |= LTO_SYMBOL_SCOPE_INTERNAL;

    // add to table of symbols
    NameAndAttributes info;
    info.name = symbolName;
    info.attributes = (lto_symbol_attributes)attr;
    _symbols.push_back(info);
    _defines[info.name] = 1;
}
Beispiel #18
0
void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,
                                      const GlobalValue *GV, Mangler &Mang,
                                      bool MayAlwaysUsePrivate) const {
  if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {
    // Simple case: If GV is not private, it is not important to find out if
    // private labels are legal in this case or not.
    Mang.getNameWithPrefix(Name, GV, false);
    return;
  }
  const TargetLoweringObjectFile *TLOF = getObjFileLowering();
  TLOF->getNameWithPrefix(Name, GV, Mang, *this);
}
/// Emit a global initialization.
void SILGenModule::emitGlobalInitialization(PatternBindingDecl *pd,
                                            unsigned pbdEntry) {
  // Generic and dynamic static properties require lazy initialization, which
  // isn't implemented yet.
  if (pd->isStatic()) {
    auto theType = pd->getDeclContext()->getDeclaredTypeInContext();
    assert(!theType->is<BoundGenericType>()
           && "generic static properties not implemented");
    (void)theType;
  }

  // Emit the lazy initialization token for the initialization expression.
  auto counter = anonymousSymbolCounter++;

  // Pick one variable of the pattern. Usually it's only one variable, but it
  // can also be something like: var (a, b) = ...
  Pattern *pattern = pd->getPattern(pbdEntry);
  VarDecl *varDecl = nullptr;
  pattern->forEachVariable([&](VarDecl *D) {
    varDecl = D;
  });
  assert(varDecl);

  std::string onceTokenBuffer;
  {
    Mangler tokenMangler;
    tokenMangler.mangleGlobalInit(varDecl, counter, false);
    onceTokenBuffer = tokenMangler.finalize();
  }

  auto onceTy = BuiltinIntegerType::getWordType(M.getASTContext());
  auto onceSILTy
    = SILType::getPrimitiveObjectType(onceTy->getCanonicalType());

  // TODO: include the module in the onceToken's name mangling.
  // Then we can make it fragile.
  auto onceToken = SILGlobalVariable::create(M, SILLinkage::Private,
                                             makeModuleFragile,
                                             onceTokenBuffer, onceSILTy);
  onceToken->setDeclaration(false);

  // Emit the initialization code into a function.
  std::string onceFuncBuffer;
  {
    Mangler funcMangler;
    funcMangler.mangleGlobalInit(varDecl, counter, true);
    onceFuncBuffer = funcMangler.finalize();
  }

  SILFunction *onceFunc = emitLazyGlobalInitializer(onceFuncBuffer, pd,
                                                    pbdEntry);

  // Generate accessor functions for all of the declared variables, which
  // Builtin.once the lazy global initializer we just generated then return
  // the address of the individual variable.
  GenGlobalAccessors(*this, onceToken, onceFunc)
    .visit(pd->getPattern(pbdEntry));
}
Beispiel #20
0
bool ide::printAccessorUSR(const AbstractStorageDecl *D, AccessorKind AccKind,
                           llvm::raw_ostream &OS) {
  using namespace Mangle;

  // AccKind should always be either IsGetter or IsSetter here, based
  // on whether a reference is a mutating or non-mutating use.  USRs
  // aren't supposed to reflect implementation differences like stored
  // vs. addressed vs. observing.
  //
  // On the other side, the implementation indexer should be
  // registering the getter/setter USRs independently of how they're
  // actually implemented.  So a stored variable should still have
  // getter/setter USRs (pointing to the variable declaration), and an
  // addressed variable should have its "getter" point at the
  // addressor.

  AbstractStorageDecl *SD = const_cast<AbstractStorageDecl*>(D);
  OS << getUSRSpacePrefix();
  Mangler Mangler;
  Mangler.mangleAccessorEntity(AccKind, AddressorKind::NotAddressor, SD);
  Mangler.finalize(OS);
  return false;
}
Beispiel #21
0
void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,
                                      const GlobalValue *GV, Mangler &Mang,
                                      bool MayAlwaysUsePrivate) const {
  if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {
    // Simple case: If GV is not private, it is not important to find out if
    // private labels are legal in this case or not.
    Mang.getNameWithPrefix(Name, GV, false);
    return;
  }
  SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, *this);
  const TargetLoweringObjectFile *TLOF = getObjFileLowering();
  const MCSection *TheSection = TLOF->SectionForGlobal(GV, GVKind, Mang, *this);
  bool CannotUsePrivateLabel = !canUsePrivateLabel(*AsmInfo, *TheSection);
  TLOF->getNameWithPrefix(Name, GV, CannotUsePrivateLabel, Mang, *this);
}
Beispiel #22
0
void LTOCodeGenerator::
applyRestriction(GlobalValue &GV,
                 std::vector<const char*> &mustPreserveList,
                 SmallPtrSet<GlobalValue*, 8> &asmUsed,
                 Mangler &mangler) {
  SmallString<64> Buffer;
  mangler.getNameWithPrefix(Buffer, &GV, false);

  if (GV.isDeclaration())
    return;
  if (_mustPreserveSymbols.count(Buffer))
    mustPreserveList.push_back(GV.getName().data());
  if (_asmUndefinedRefs.count(Buffer))
    asmUsed.insert(&GV);
}
Beispiel #23
0
// Find exeternal symbols referenced by VALUE. This is a recursive function.
static void
findExternalRefs(Value *value, std::set<std::string> &references, 
                 Mangler &mangler) {

  if (GlobalValue *gv = dyn_cast<GlobalValue>(value)) {
    LTOLinkageTypes lt = getLTOLinkageType(gv);
    if (lt != LTOInternalLinkage && strncmp (gv->getName().c_str(), "llvm.", 5))
      references.insert(mangler.getValueName(gv));
  }

  // GlobalValue, even with InternalLinkage type, may have operands with 
  // ExternalLinkage type. Do not ignore these operands.
  if (Constant *c = dyn_cast<Constant>(value))
    // Handle ConstantExpr, ConstantStruct, ConstantArry etc..
    for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i)
      findExternalRefs(c->getOperand(i), references, mangler);
}
Beispiel #24
0
static std::string mangleConstant(SILDeclRef c, SILDeclRef::ManglingKind Kind) {
  using namespace Mangle;
  Mangler mangler;

  // Almost everything below gets one of the common prefixes:
  //   mangled-name ::= '_T' global     // Native symbol
  //   mangled-name ::= '_TTo' global   // ObjC interop thunk
  //   mangled-name ::= '_TTO' global   // Foreign function thunk
  //   mangled-name ::= '_TTd' global   // Direct
  StringRef introducer = "_T";
  switch (Kind) {
    case SILDeclRef::ManglingKind::Default:
      if (c.isForeign) {
        introducer = "_TTo";
      } else if (c.isDirectReference) {
        introducer = "_TTd";
      } else if (c.isForeignToNativeThunk()) {
        introducer = "_TTO";
      }
      break;
    case SILDeclRef::ManglingKind::VTableMethod:
      introducer = "_TTV";
      break;
    case SILDeclRef::ManglingKind::DynamicThunk:
      introducer = "_TTD";
      break;
  }
  
  // As a special case, Clang functions and globals don't get mangled at all.
  if (c.hasDecl()) {
    if (auto clangDecl = c.getDecl()->getClangDecl()) {
      if (!c.isForeignToNativeThunk() && !c.isNativeToForeignThunk()
          && !c.isCurried) {
        if (auto namedClangDecl = dyn_cast<clang::DeclaratorDecl>(clangDecl)) {
          if (auto asmLabel = namedClangDecl->getAttr<clang::AsmLabelAttr>()) {
            mangler.append('\01');
            mangler.append(asmLabel->getLabel());
          } else if (namedClangDecl->hasAttr<clang::OverloadableAttr>()) {
            std::string storage;
            llvm::raw_string_ostream SS(storage);
            // FIXME: When we can import C++, use Clang's mangler all the time.
            mangleClangDecl(SS, namedClangDecl,
                            c.getDecl()->getASTContext());
            mangler.append(SS.str());
          } else {
            mangler.append(namedClangDecl->getName());
          }
          return mangler.finalize();
        }
      }
    }
  }
  
  switch (c.kind) {
  //   entity ::= declaration                     // other declaration
  case SILDeclRef::Kind::Func:
    if (!c.hasDecl()) {
      mangler.append(introducer);
      mangler.mangleClosureEntity(c.getAbstractClosureExpr(),
                                  c.uncurryLevel);
      return mangler.finalize();
    }

    // As a special case, functions can have manually mangled names.
    // Use the SILGen name only for the original non-thunked, non-curried entry
    // point.
    if (auto NameA = c.getDecl()->getAttrs().getAttribute<SILGenNameAttr>())
      if (!c.isForeignToNativeThunk() && !c.isNativeToForeignThunk()
          && !c.isCurried) {
        mangler.append(NameA->Name);
        return mangler.finalize();
      }
      
    // Use a given cdecl name for native-to-foreign thunks.
    if (auto CDeclA = c.getDecl()->getAttrs().getAttribute<CDeclAttr>())
      if (c.isNativeToForeignThunk()) {
        mangler.append(CDeclA->Name);
        return mangler.finalize();
      }

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

  case SILDeclRef::Kind::EnumElement:
    mangler.append(introducer);
    mangler.mangleEntity(c.getDecl(), c.uncurryLevel);
    return mangler.finalize();

  //   entity ::= context 'D'                     // deallocating destructor
  case SILDeclRef::Kind::Deallocator:
    mangler.append(introducer);
    mangler.mangleDestructorEntity(cast<DestructorDecl>(c.getDecl()),
                                   /*isDeallocating*/ true);
    return mangler.finalize();

  //   entity ::= context 'd'                     // destroying destructor
  case SILDeclRef::Kind::Destroyer:
    mangler.append(introducer);
    mangler.mangleDestructorEntity(cast<DestructorDecl>(c.getDecl()),
                                   /*isDeallocating*/ false);
    return mangler.finalize();

  //   entity ::= context 'C' type                // allocating constructor
  case SILDeclRef::Kind::Allocator:
    mangler.append(introducer);
    mangler.mangleConstructorEntity(cast<ConstructorDecl>(c.getDecl()),
                                    /*allocating*/ true,
                                    c.uncurryLevel);
    return mangler.finalize();

  //   entity ::= context 'c' type                // initializing constructor
  case SILDeclRef::Kind::Initializer:
    mangler.append(introducer);
    mangler.mangleConstructorEntity(cast<ConstructorDecl>(c.getDecl()),
                                    /*allocating*/ false,
                                    c.uncurryLevel);
    return mangler.finalize();

  //   entity ::= declaration 'e'                 // ivar initializer
  //   entity ::= declaration 'E'                 // ivar destroyer
  case SILDeclRef::Kind::IVarInitializer:
  case SILDeclRef::Kind::IVarDestroyer:
    mangler.append(introducer);
    mangler.mangleIVarInitDestroyEntity(
      cast<ClassDecl>(c.getDecl()),
      c.kind == SILDeclRef::Kind::IVarDestroyer);
    return mangler.finalize();

  //   entity ::= declaration 'a'                 // addressor
  case SILDeclRef::Kind::GlobalAccessor:
    mangler.append(introducer);
    mangler.mangleAddressorEntity(c.getDecl());
    return mangler.finalize();

  //   entity ::= declaration 'G'                 // getter
  case SILDeclRef::Kind::GlobalGetter:
    mangler.append(introducer);
    mangler.mangleGlobalGetterEntity(c.getDecl());
    return mangler.finalize();

  //   entity ::= context 'e' index               // default arg generator
  case SILDeclRef::Kind::DefaultArgGenerator:
    mangler.append(introducer);
    mangler.mangleDefaultArgumentEntity(cast<AbstractFunctionDecl>(c.getDecl()),
                                        c.defaultArgIndex);
    return mangler.finalize();

  //   entity ::= 'I' declaration 'i'             // stored property initializer
  case SILDeclRef::Kind::StoredPropertyInitializer:
    mangler.append(introducer);
    mangler.mangleInitializerEntity(cast<VarDecl>(c.getDecl()));
    return mangler.finalize();
  }

  llvm_unreachable("bad entity kind!");
}
Beispiel #25
0
int main(int argc, char* argv[])
{
	printf("main()\n");

#if WIN32
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/ncrt0.o"));
	//linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/main.o"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/OBJ/Browser/Browser.o"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/OBJ/Browser/BrowserFrame.o"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/libui.a"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/libdraw.a"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/libxmlparse.a"));
	linker.m_files.push_back(new StringA("C:/MMStudio/Amiga68k/liblfc.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/usr/local/amiga/lib/gcc/m68k-amigaos/3.4.0/libgcc.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libstdc++.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libm.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnix.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnixmain.a"));
//	linker.m_files.push_back(new StringA("C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libamiga.a"));
	linker.m_files.push_back(new StringA("C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libstubs.a"));
#else


	if (true)
	{
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/ncrt0.o"));
	//	linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/main.o"));

		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/LDebugger.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/mainfrm.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/SourceEdit.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/SourceEditFrame.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/DisassemblyWnd.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/WatchWnd.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/CallStackWnd.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/FileDialog.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/LDebugger/DebugSession.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libui.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libdraw.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libxmlparse.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libcode.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/liblfc.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/lib/gcc/m68k-amigaos/3.4.0/libgcc.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libstdc++.a"));

		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libm.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnix.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnixmain.a"));
	//	linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libamiga.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libstubs.a"));
	}
	else
	{
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/ncrt0.o"));
	//	linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/main.o"));

		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/Browser/Browser.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/OBJ/Browser/BrowserFrame.o"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libui.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libdraw.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libxmlparse.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/libcode.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/liblfc.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/lib/gcc/m68k-amigaos/3.4.0/libgcc.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libstdc++.a"));

		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libm.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnix.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libnixmain.a"));
	//	linker.m_files.push_back(new StringA("WinHD_C:/cygwin/usr/local/amiga/m68k-amigaos/lib/libamiga.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libm020/libnix/libstubs.a"));

		/*
		linker.m_files.push_back(new StringA("WinHD_C:/MMStudio/Amiga68k/ncrt0.o"));
		linker.m_files.push_back(new StringA("WINHD_C:/MMStudio/Amiga68k/main.o"));
		linker.m_files.push_back(new StringA("WINHD_C:/cygwin/home/Sigurd Lerstad/lib/libnix/libnix.a"));
		linker.m_files.push_back(new StringA("WINHD_C:/cygwin/home/Sigurd Lerstad/lib/libnix/libnixmain.a"));
		linker.m_files.push_back(new StringA("WinHD_C:/cygwin/home/Sigurd Lerstad/lib/libnix/libstubs.a"));
		*/
	}
#endif

	printf("pass1\n");
	linker.pass1();

/*
	GlobalSymbol* pSymbol = linker.m_globsyms[new StringA("_main")];
	pSymbol->m_defined = true;
	pSymbol->ResolvedValue = (DWORD)MyMain;
*/
//	linker.AddSymbol(new StringA("_main"), (DWORD)MyMain);

	printf("loading first object file\n");
#if 1
	linker.LoadObjectFile(linker.m_objectFiles[0]);
	if (true)
	{
		for (int i = 1; i < linker.m_objectFiles.size(); i++)
		{
			printf("loading %d object file\n", i);
			linker.LoadObjectFile(linker.m_objectFiles[i]);
		}
	}

	printf("Here\n");
	TRACE("\n\n");

	{
		for (int i = 0; i < linker.m_loadedObjectFiles.size(); i++)
		{
			OFile2* ofile = linker.m_loadedObjectFiles[i];

			if (ofile->m_afilename)
				TRACE("%s:%s\n", ofile->m_afilename->c_str(), ofile->m_ofilename->c_str());
			else
				TRACE("%s\n", ofile->m_ofilename->c_str());
		}
	}
#endif

	printf("before sets\n");

	linker.sets();

	printf("LoadObjectfile2\n");

	OFile* pOFile = linker.LoadObjectFile2(linker.m_objectFiles[0]);

	if (true)
	{
		for (int i = 1; i < linker.m_objectFiles.size(); i++)
		{
			linker.LoadObjectFile2(linker.m_objectFiles[i]);
		}
	}

/*
	{
		GlobalSymbol* psym = linker.m_globsyms[new StringA("_DOSBase")];
		int x = *(long*)psym->ResolvedValue;
	}
*/
	printf("done\n");

	if (linker.m_undefinedReferenceCount)
	{
		printf("undefined reference count: %d\n", linker.m_undefinedReferenceCount);
		TRACE("undefined reference count: %d\n", linker.m_undefinedReferenceCount);
	}
	else
	{
#if AMIGA
		GlobalSymbol* sym = linker.m_globsyms[new StringA("_plinker")];
		ASSERT(sym);
		ASSERT(sym->m_syms.size());

		*(Linker**)sym->m_syms[0]->ResolvedValue = &linker;
#endif

#if WIN32
		/*
		{
			gsymmap_t::iterator it2 = linker.m_globsyms.begin();
			while (it2 != linker.m_globsyms.end())
			{
// "__ZTI14red_black_nodeIPN6System7StringAEPNS0_9NamespaceEE"

				GlobalSymbol* sym = (*it2).second;
				if (strstr(sym->m_name->c_str(), "TI") && strstr(sym->m_name->c_str(), "red_black_node") && strstr(sym->m_name->c_str(), "StringA"))
				{
					MessageBeep(-1);
				}

				++it2;
			}
		}
		*/

		TypeArchive* ar = new TypeArchive(TypeArchive::Mode_Load, new FileByteStream(new StringA("C:/test.typeinfo"), FileMode_Read));

		int ntypes;
		*ar >> ntypes;

		printf("%d\n", ntypes);

		for (int i = 0; i < ntypes; i++)
		{
			NamedType* pType;
			*ar >> pType;

			BufferImp<char> buffer;
			StringBuilderA strbuilder(&buffer);
			pType->Write(strbuilder);
			pType->m_qname = buffer.DetachToString();

			if (*pType->m_qname == "second_argument_type")
			{
				MessageBeep(-1);
			}

			//if (pType->m_qname)
			{
				StringBuilderA strbuilder(&buffer);
				strbuilder << "__ZTI";	// type info

				Mangler mangler;
				mangler.MangleType(pType, strbuilder);

				StringA* name = buffer.DetachToString();

				gsymmap_t::iterator it2 = linker.m_globsyms.find(name);
				//map<StringA*, DWORD, Ref_Less<StringA> >::iterator it2 = symbols.find(name);
				if (it2 != linker.m_globsyms.end())
				{
					GlobalSymbol* globsym = (*it2).second;

					//TRACE("%s\n", name->c_str());

					if (!strcmp(globsym->m_name->c_str(), "__ZTI9IAddChild"))
					{
						MessageBeep(-1);

					}

					for (int j = 0; j < globsym->m_syms.size(); j++)
					{
						Symbol* sym = globsym->m_syms[j];

					}

#if AMIGA
					__type_info2* ti = (__type_info2*)sym->ResolvedValue;
					printf("%s\n", ti->__type_name);

				//	int len = strlen(ti->__type_name);
						/*
						char* newname = malloc(len+1+4);
						strcpy(newname+4, ti->__type_name);
						ti->__type_name = newname+4;
						*(Type**)newname = pType;
						*/
#endif
#if 0
					TypeDescriptor* typedesc = (TypeDescriptor*)(*it2).second;

					//VERIFY(typedesc->_m_data == NULL);

					if (pType->GetKind() == type_class)
					{
						((ClassType*)pType)->m_typedesc = (Type_Info*)typedesc;
					}
					else if (pType->GetKind() == type_enum)
					{
						((EnumType*)pType)->m_typedesc = (Type_Info*)typedesc;
					}

					typedesc->_m_data = pType2;

					AddPersistentLiveRoot((Object**)&typedesc->_m_data);
#endif
				}
				else
				{
					TRACE("-----%s\n", name->c_str());
				}
			}
		}
#endif

	{
#if 1
		ULONG heapsize = heap->m_next - (heap->m_data);
#else
		ULONG heapsize = heap->m_next - (heap->m_data+heap->m_size);
#endif

		printf("heapsize: %f MB\n", heapsize / (1024.0*1024));
	}

	#if AMIGA

		printf("Calling");

		char* line = strdup("programname parameter0 parameter1");
		entrypoint_hook(pOFile->m_textdata, line, strlen(line));
	#endif
	}

#if 0
	if (argc <= 1)
	{
		printf("Usage:\n");
		printf("loader objectfile\n");
		return -10;
	}

	Linker linker;

	for (int i = 1; i < argc; i++)
	{
		linker.m_files.Add(new StringA(argv[i]));
	}

	printf("pass1...");
	linker.pass1();
//	linker.pass2();

	/*
	GlobalSymbol* globsym = linker.globsyms["_main2"];

	FileByteStream file(globsym->m_filename);
	linker.LoadObjectFile(file);

	printf("Calling...");
	((dllentrypoint)globsym->Value)();
	printf("done\n");
	*/

	printf("done\n");

	printf("loading...");
	fflush(stdout);

//	FileByteStream* file = new FileByteStream(linker.m_files[0]);
//	printf("sdfsdf\n");
//	fflush(stdout);
	linker.LoadObjectFile(linker.m_objectFiles[0]);

	linker.sets();

	OFile* pOFile = linker.LoadObjectFile2(linker.m_objectFiles[0]);

	printf("done\n");

	if (linker.m_undefinedReferenceCount)
	{
		printf("undefined reference count: %d\n", linker.m_undefinedReferenceCount);
		TRACE("undefined reference count: %d\n", linker.m_undefinedReferenceCount);
	}
	else
	{
	#if AMIGA
		char* line = strdup("programname parameter0 parameter1");
		entrypoint_hook(pOFile->m_textdata, line, strlen(line));
	#endif
	}
#endif

	return 0;
}
void TargetLoweringObjectFile::getNameWithPrefix(
    SmallVectorImpl<char> &OutName, const GlobalValue *GV, Mangler &Mang,
    const TargetMachine &TM) const {
  Mang.getNameWithPrefix(OutName, GV, /*CannotUsePrivateLabel=*/false);
}
Beispiel #27
0
bool ide::printDeclUSR(const ValueDecl *D, raw_ostream &OS) {
  using namespace Mangle;

  if (!isa<FuncDecl>(D) && !D->hasName())
    return true; // Ignore.
  if (D->getModuleContext()->isBuiltinModule())
    return true; // Ignore.

  ValueDecl *VD = const_cast<ValueDecl *>(D);

  auto interpretAsClangNode = [](const ValueDecl *D)->ClangNode {
    ClangNode ClangN = D->getClangNode();
    if (auto ClangD = ClangN.getAsDecl()) {
      // NSErrorDomain causes the clang enum to be imported like this:
      //
      // struct MyError {
      //     enum Code : Int32 {
      //         case errFirst
      //         case errSecond
      //     }
      //     static var errFirst: MyError.Code { get }
      //     static var errSecond: MyError.Code { get }
      // }
      //
      // The clang enum and enum constants are associated with both the
      // struct/nested enum, and the static vars/enum cases.
      // But we want unique USRs for the above symbols, so use the clang USR
      // for the enum and enum cases, and the Swift USR for the struct and vars.
      //
      if (isa<clang::EnumDecl>(ClangD)) {
        if (ClangD->hasAttr<clang::NSErrorDomainAttr>() && isa<StructDecl>(D))
          return ClangNode();
      } else if (auto *ClangEnumConst = dyn_cast<clang::EnumConstantDecl>(ClangD)) {
        if (auto *ClangEnum = dyn_cast<clang::EnumDecl>(ClangEnumConst->getDeclContext())) {
          if (ClangEnum->hasAttr<clang::NSErrorDomainAttr>() && isa<VarDecl>(D))
            return ClangNode();
        }
      }
    }
    return ClangN;
  };

  if (ClangNode ClangN = interpretAsClangNode(D)) {
    llvm::SmallString<128> Buf;
    if (auto ClangD = ClangN.getAsDecl()) {
      bool Ignore = clang::index::generateUSRForDecl(ClangD, Buf);
      if (!Ignore)
        OS << Buf.str();
      return Ignore;
    }

    auto &Importer = *D->getASTContext().getClangModuleLoader();

    auto ClangMacroInfo = ClangN.getAsMacro();
    auto PPRecord = Importer.getClangPreprocessor().getPreprocessingRecord();
    assert(PPRecord && "Clang importer should be created with "
                       "-detailed-preprocessing-record option");
    auto ClangMacroDef = PPRecord->findMacroDefinition(ClangMacroInfo);

    bool Ignore = clang::index::generateUSRForMacro(
        ClangMacroDef, Importer.getClangASTContext().getSourceManager(), Buf);
    if (!Ignore)
      OS << Buf.str();
    return Ignore;
  }

  if (!D->hasType())
    return true;

  // FIXME: mangling 'self' in destructors crashes in mangler.
  if (isa<ParamDecl>(VD) && isa<DestructorDecl>(VD->getDeclContext()))
    return true;

  OS << getUSRSpacePrefix();
  Mangler Mangler;

  Mangler.bindGenericParameters(VD->getDeclContext());

  if (auto Ctor = dyn_cast<ConstructorDecl>(VD)) {
    Mangler.mangleConstructorEntity(Ctor, /*isAllocating=*/false,
                                    /*uncurryingLevel=*/0);
  } else if (auto Dtor = dyn_cast<DestructorDecl>(VD)) {
    Mangler.mangleDestructorEntity(Dtor, /*isDeallocating=*/false);
  } else if (auto NTD = dyn_cast<NominalTypeDecl>(VD)) {
    Mangler.mangleNominalType(NTD);
  } else if (isa<TypeAliasDecl>(VD) || isa<AssociatedTypeDecl>(VD)) {
    Mangler.mangleContextOf(VD);
    Mangler.mangleDeclName(VD);
  } else {
    Mangler.mangleEntity(VD, /*uncurryingLevel=*/0);
  }

  Mangler.finalize(OS);
  return false;
}
Beispiel #28
0
/******************************************************************************
 * Returns exact mangled name of function.
 */
const char *mangleExact(FuncDeclaration *fd)
{
    Mangler v;
    v.mangleExact(fd);
    return v.result;
}
Beispiel #29
0
static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){
  const TargetMachine &TM = AP.TM;
  Mangler *Mang = AP.Mang;
  const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout();
  MCContext &Ctx = AP.OutContext;
  bool isDarwin = Triple(TM.getTargetTriple()).isOSDarwin();

  SmallString<128> Name;
  StringRef Suffix;
  if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB) {
    if (isDarwin)
      Suffix = "$stub";
  } else if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG)
    Suffix = "$non_lazy_ptr";

  if (!Suffix.empty())
    Name += DL->getPrivateGlobalPrefix();

  unsigned PrefixLen = Name.size();

  if (!MO.isGlobal()) {
    assert(MO.isSymbol() && "Isn't a symbol reference");
    Mang->getNameWithPrefix(Name, MO.getSymbolName());
  } else {
    const GlobalValue *GV = MO.getGlobal();
    TM.getNameWithPrefix(Name, GV, *Mang);
  }

  unsigned OrigLen = Name.size() - PrefixLen;

  Name += Suffix;
  MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
  StringRef OrigName = StringRef(Name).substr(PrefixLen, OrigLen);

  // If the target flags on the operand changes the name of the symbol, do that
  // before we return the symbol.
  if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && isDarwin) {
    MachineModuleInfoImpl::StubValueTy &StubSym =
      getMachOMMI(AP).getFnStubEntry(Sym);
    if (StubSym.getPointer())
      return Sym;
    
    if (MO.isGlobal()) {
      StubSym =
      MachineModuleInfoImpl::
      StubValueTy(AP.getSymbol(MO.getGlobal()),
                  !MO.getGlobal()->hasInternalLinkage());
    } else {
      StubSym =
      MachineModuleInfoImpl::
      StubValueTy(Ctx.GetOrCreateSymbol(OrigName), false);
    }
    return Sym;
  }

  // If the symbol reference is actually to a non_lazy_ptr, not to the symbol,
  // then add the suffix.
  if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG) {
    MachineModuleInfoMachO &MachO = getMachOMMI(AP);
    
    MachineModuleInfoImpl::StubValueTy &StubSym =
      (MO.getTargetFlags() & PPCII::MO_NLP_HIDDEN_FLAG) ? 
         MachO.getHiddenGVStubEntry(Sym) : MachO.getGVStubEntry(Sym);
    
    if (!StubSym.getPointer()) {
      assert(MO.isGlobal() && "Extern symbol not handled yet");
      StubSym = MachineModuleInfoImpl::
                   StubValueTy(AP.getSymbol(MO.getGlobal()),
                               !MO.getGlobal()->hasInternalLinkage());
    }
    return Sym;
  }
  
  return Sym;
}
Beispiel #30
0
/// Mangle this entity into the given stream.
void LinkEntity::mangle(raw_ostream &buffer) const {
  // Almost everything below gets the common prefix:
  //   mangled-name ::= '_T' global
  Mangler mangler;
  switch (getKind()) {
  //   global ::= 'w' value-witness-kind type     // value witness
  case Kind::ValueWitness:
    mangler.append("_Tw");
    mangler.append(mangleValueWitness(getValueWitness()));
    mangler.mangleType(getType(), 0);
    return mangler.finalize(buffer);

  //   global ::= 'WV' type                       // value witness
  case Kind::ValueWitnessTable:
    mangler.append("_TWV");
    mangler.mangleType(getType(), 0);
    return mangler.finalize(buffer);

  //   global ::= 't' type
  // Abstract type manglings just follow <type>.
  case Kind::TypeMangling:
    mangler.mangleType(getType(), 0);
    return mangler.finalize(buffer);

  //   global ::= 'Ma' type               // type metadata access function
  case Kind::TypeMetadataAccessFunction:
    mangler.append("_TMa");
    mangler.mangleType(getType(), 0);
    return mangler.finalize(buffer);

  //   global ::= 'ML' type               // type metadata lazy cache variable
  case Kind::TypeMetadataLazyCacheVariable:
    mangler.append("_TML");
    mangler.mangleType(getType(), 0);
    return mangler.finalize(buffer);

  //   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:
      mangler.mangleTypeFullMetadataFull(getType());
      break;
    case TypeMetadataAddress::AddressPoint:
      mangler.mangleTypeMetadataFull(getType(), isMetadataPattern());
      break;
    }
    return mangler.finalize(buffer);

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

  //   global ::= 'Mm' type                       // class metaclass
  case Kind::SwiftMetaclassStub:
    mangler.append("_TMm");
    mangler.mangleNominalType(cast<ClassDecl>(getDecl()),
                              Mangler::BindGenerics::None);
    return mangler.finalize(buffer);

  //   global ::= 'Mn' type                       // nominal type descriptor
  case Kind::NominalTypeDescriptor:
    mangler.append("_TMn");
    mangler.mangleNominalType(cast<NominalTypeDecl>(getDecl()),
                              Mangler::BindGenerics::None);
    return mangler.finalize(buffer);

  //   global ::= 'Mp' type                       // protocol descriptor
  case Kind::ProtocolDescriptor:
    mangler.append("_TMp");
    mangler.mangleProtocolName(cast<ProtocolDecl>(getDecl()));
    return mangler.finalize(buffer);

  //   global ::= 'Wo' entity
  case Kind::WitnessTableOffset:
     mangler.append("_TWo");

    // Witness table entries for constructors always refer to the allocating
    // constructor.
    if (auto ctor = dyn_cast<ConstructorDecl>(getDecl()))
      mangler.mangleConstructorEntity(ctor, /*isAllocating=*/true,
                                      getUncurryLevel());
    else
      mangler.mangleEntity(getDecl(), getUncurryLevel());
    return mangler.finalize(buffer);

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

  //   global ::= 'WP' protocol-conformance
  case Kind::DirectProtocolWitnessTable:
    mangler.append("_TWP");
    mangler.mangleProtocolConformance(getProtocolConformance());
    return mangler.finalize(buffer);

  //   global ::= 'WG' protocol-conformance
  case Kind::GenericProtocolWitnessTableCache:
    buffer << "_TWG";
    mangler.mangleProtocolConformance(getProtocolConformance());
    return mangler.finalize(buffer);

  //   global ::= 'WI' protocol-conformance
  case Kind::GenericProtocolWitnessTableInstantiationFunction:
    buffer << "_TWI";
    mangler.mangleProtocolConformance(getProtocolConformance());
    return mangler.finalize(buffer);

  //   global ::= 'Wa' protocol-conformance
  case Kind::ProtocolWitnessTableAccessFunction:
    mangler.append("_TWa");
    mangler.mangleProtocolConformance(getProtocolConformance());
    return mangler.finalize(buffer);

  //   global ::= 'Wl' type protocol-conformance
  case Kind::ProtocolWitnessTableLazyAccessFunction:
    mangler.append("_TWl");
    mangler.mangleType(getType(), 0);
    mangler.mangleProtocolConformance(getProtocolConformance());
    return mangler.finalize(buffer);

  //   global ::= 'WL' type protocol-conformance
  case Kind::ProtocolWitnessTableLazyCacheVariable:
    mangler.append("_TWL");
    mangler.mangleType(getType(), 0);
    mangler.mangleProtocolConformance(getProtocolConformance());
    return mangler.finalize(buffer);
      
  //   global ::= 'Wt' protocol-conformance identifier
  case Kind::AssociatedTypeMetadataAccessFunction:
    mangler.append("_TWt");
    mangler.mangleProtocolConformance(getProtocolConformance());
    mangler.mangleIdentifier(getAssociatedType()->getNameStr());
    return mangler.finalize(buffer);

  //   global ::= 'WT' protocol-conformance identifier nominal-type
  case Kind::AssociatedTypeWitnessTableAccessFunction:
    mangler.append("_TWT");
    mangler.mangleProtocolConformance(getProtocolConformance());
    mangler.mangleIdentifier(getAssociatedType()->getNameStr());
    mangler.mangleProtocolDecl(getAssociatedProtocol());
    return mangler.finalize(buffer);

  // 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>()) {
      mangler.append(AsmA->Name);
      return mangler.finalize(buffer);
    }

    // Otherwise, fall through into the 'other decl' case.
    SWIFT_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>()) {
          mangler.append('\01');
          mangler.append(asmLabel->getLabel());
        } else 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());
          mangler.append(SS.str());
        } else {
          mangler.append(namedClangDecl->getName());
        }
        return mangler.finalize(buffer);
      }
    }

    mangler.append("_T");
    if (auto type = dyn_cast<NominalTypeDecl>(getDecl())) {
      mangler.mangleNominalType(type, Mangler::BindGenerics::None);
    } else if (auto ctor = dyn_cast<ConstructorDecl>(getDecl())) {
      // FIXME: Hack. LinkInfo should be able to refer to the allocating
      // constructor rather than inferring it here.
      mangler.mangleConstructorEntity(ctor, /*isAllocating=*/true,
                                      getUncurryLevel());
    } else {
      mangler.mangleEntity(getDecl(), getUncurryLevel());
    }
      return mangler.finalize(buffer);

  // 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: {
    mangler.append("OBJC_CLASS_REF_$_");
    llvm::SmallString<64> tempBuffer;
    StringRef name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(tempBuffer);
    mangler.append(name);
    return mangler.finalize(buffer);
  }

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

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

  case Kind::SILFunction:
    mangler.appendSymbol(getSILFunction()->getName());
    return mangler.finalize(buffer);
  case Kind::SILGlobalVariable:
    mangler.appendSymbol(getSILGlobalVariable()->getName());
    return mangler.finalize(buffer);
  }
  llvm_unreachable("bad entity kind!");
}