llvm::Function *CGObjCJit::GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD) { assert(CD && "Missing container decl in GetNameForMethod"); llvm::SmallString<256> Name; llvm::raw_svector_ostream OS(Name); OS << '\01' << (OMD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName(); if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { OS << '(' << CID << ')'; } OS << ' ' << OMD->getSelector().getAsString() << ']'; CodeGenTypes &Types = CGM.getTypes(); llvm::FunctionType *MethodTy = Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD)); llvm::Function *Method = llvm::Function::Create(MethodTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule()); MethodDefinitions.insert(std::make_pair(OMD, Method)); return Method; }
bool isDeclCandidate(FunctionDecl * FDecl) { if (m_NonNullArgIndexs.count(FDecl)) return true; if (llvm::isa<CXXRecordDecl>(FDecl)) return true; std::bitset<32> ArgIndexs; for (specific_attr_iterator<NonNullAttr> I = FDecl->specific_attr_begin<NonNullAttr>(), E = FDecl->specific_attr_end<NonNullAttr>(); I != E; ++I) { NonNullAttr *NonNull = *I; for (NonNullAttr::args_iterator i = NonNull->args_begin(), e = NonNull->args_end(); i != e; ++i) { ArgIndexs.set(*i); } } if (ArgIndexs.any()) { m_NonNullArgIndexs.insert(std::make_pair(FDecl, ArgIndexs)); return true; } return false; }
ModuleDecl *loadModule(SourceLoc importLoc, ArrayRef<std::pair<Identifier, SourceLoc>> path) { // FIXME: Implement submodule support! Identifier name = path[0].first; auto it = ModuleWrappers.find(name); if (it != ModuleWrappers.end()) return it->second->getParentModule(); auto *decl = ModuleDecl::create(name, SwiftContext); // Silence error messages about testably importing a Clang module. decl->setTestingEnabled(); decl->setHasResolvedImports(); auto wrapperUnit = new (SwiftContext) DWARFModuleUnit(*decl); ModuleWrappers.insert({name, wrapperUnit}); decl->addFile(*wrapperUnit); // Force load adapter modules for all imported modules. decl->forAllVisibleModules({}, [](ModuleDecl::ImportedModule import) {}); return decl; }
/// Returns true on success. bool PartialApplyCombiner::allocateTemporaries() { // Copy the original arguments of the partial_apply into // newly created temporaries and use these temporaries instead of // the original arguments afterwards. // This is done to "extend" the life-time of original partial_apply // arguments, as they may be destroyed/deallocated before the last // use by one of the apply instructions. // TODO: // Copy arguments of the partial_apply into new temporaries // only if the lifetime of arguments ends before their uses // by apply instructions. bool needsReleases = false; CanSILFunctionType PAITy = dyn_cast<SILFunctionType>(PAI->getCallee()->getType().getSwiftType()); // Emit a destroy value for each captured closure argument. ArrayRef<SILParameterInfo> Params = PAITy->getParameters(); auto Args = PAI->getArguments(); unsigned Delta = Params.size() - Args.size(); llvm::SmallVector<std::pair<SILValue, unsigned>, 8> ArgsToHandle; for (unsigned AI = 0, AE = Args.size(); AI != AE; ++AI) { SILValue Arg = Args[AI]; SILParameterInfo Param = Params[AI + Delta]; if (Param.isIndirectMutating()) continue; // Create a temporary and copy the argument into it, if: // - the argument stems from an alloc_stack // - the argument is consumed by the callee and is indirect // (e.g. it is an @in argument) if (isa<AllocStackInst>(Arg) || (Param.isConsumed() && Param.isIndirect())) { // If the temporary is non-trivial, we need to release it later. if (!Arg->getType().isTrivial(PAI->getModule())) needsReleases = true; ArgsToHandle.push_back(std::make_pair(Arg, AI)); } } if (needsReleases) { // Compute the set of endpoints, which will be used to insert releases of // temporaries. This may fail if the frontier is located on a critical edge // which we may not split (no CFG changes in SILCombine). ValueLifetimeAnalysis VLA(PAI); if (!VLA.computeFrontier(PAFrontier, ValueLifetimeAnalysis::DontModifyCFG)) return false; } for (auto ArgWithIdx : ArgsToHandle) { SILValue Arg = ArgWithIdx.first; Builder.setInsertionPoint(PAI->getFunction()->begin()->begin()); // Create a new temporary at the beginning of a function. auto *Tmp = Builder.createAllocStack(PAI->getLoc(), Arg->getType(), {/*Constant*/ true, ArgWithIdx.second}); Builder.setInsertionPoint(PAI); // Copy argument into this temporary. Builder.createCopyAddr(PAI->getLoc(), Arg, Tmp, IsTake_t::IsNotTake, IsInitialization_t::IsInitialization); Tmps.push_back(Tmp); ArgToTmp.insert(std::make_pair(Arg, Tmp)); } return true; }
bool insertAsUnhandled(SILBasicBlock *Pred) { return Block2StackDepth.insert({Pred, -2}).second; }