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); if (ShouldUseObjCUSR(SD)) { return printObjCUSRForAccessor(SD, AccKind, OS); } NewMangling::ASTMangler NewMangler; std::string Mangled = NewMangler.mangleAccessorEntityAsUSR(AccKind, AddressorKind::NotAddressor, SD, getUSRSpacePrefix()); OS << Mangled; return false; }
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); }
static std::string mangleGetter(VarDecl *varDecl) { Mangle::Mangler getterMangler; getterMangler.append("_T"); getterMangler.mangleGlobalGetterEntity(varDecl); std::string Old = getterMangler.finalize(); NewMangling::ASTMangler NewMangler; std::string New = NewMangler.mangleGlobalGetterEntity(varDecl); return NewMangling::selectMangling(Old, New); }
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); }
static std::string mangleConstant(NormalProtocolConformance *C) { NewMangling::ASTMangler Mangler; return Mangler.mangleWitnessTable(C); }
bool ide::printDeclUSR(const ValueDecl *D, raw_ostream &OS) { using namespace Mangle; if (!D->hasName() && (!isa<FuncDecl>(D) || cast<FuncDecl>(D)->getAccessorKind() == AccessorKind::NotAccessor)) 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(); bool Ignore = clang::index::generateUSRForMacro(D->getNameStr(), ClangMacroInfo->getDefinitionLoc(), Importer.getClangASTContext().getSourceManager(), Buf); if (!Ignore) OS << Buf.str(); return Ignore; } if (ShouldUseObjCUSR(VD)) { return printObjCUSR(VD, OS); } if (!D->hasInterfaceType()) return true; // FIXME: mangling 'self' in destructors crashes in mangler. if (isa<ParamDecl>(VD) && isa<DestructorDecl>(VD->getDeclContext())) return true; NewMangling::ASTMangler NewMangler; std::string Mangled = NewMangler.mangleDeclAsUSR(VD, getUSRSpacePrefix()); OS << Mangled; return false; }