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; }
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()); } }
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); } }
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); }
std::string mangle(const GlobalValue *GV) { std::string MangledName; { Mangler Mang; raw_string_ostream MangledNameStream(MangledName); Mang.getNameWithPrefix(MangledNameStream, GV, false); } return MangledName; }
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(); }
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; }
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); }
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); }
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; } }
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); }
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; }
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)); }
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; }
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); }
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); }
// 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); }
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!"); }
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); }
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; }
/****************************************************************************** * Returns exact mangled name of function. */ const char *mangleExact(FuncDeclaration *fd) { Mangler v; v.mangleExact(fd); return v.result; }
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; }
/// 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!"); }