/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix /// and the specified name as the global variable name. GVName must not be /// empty. void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName, ManglerPrefixTy PrefixTy) { SmallString<256> TmpData; StringRef Name = GVName.toStringRef(TmpData); assert(!Name.empty() && "getNameWithPrefix requires non-empty name"); // If the global name is not led with \1, add the appropriate prefixes. if (Name[0] == '\1') { Name = Name.substr(1); } else { if (PrefixTy == Mangler::Private) { const char *Prefix = DL->getPrivateGlobalPrefix(); OutName.append(Prefix, Prefix+strlen(Prefix)); } else if (PrefixTy == Mangler::LinkerPrivate) { const char *Prefix = DL->getLinkerPrivateGlobalPrefix(); OutName.append(Prefix, Prefix+strlen(Prefix)); } char Prefix = DL->getGlobalPrefix(); if (Prefix != '\0') OutName.push_back(Prefix); } // If this is a simple string that doesn't need escaping, just append it. OutName.append(Name.begin(), Name.end()); }
static std::error_code getHostID(SmallVectorImpl<char> &HostID) { HostID.clear(); #if USE_OSX_GETHOSTUUID // On OS X, use the more stable hardware UUID instead of hostname. struct timespec wait = {1, 0}; // 1 second. uuid_t uuid; if (gethostuuid(uuid, &wait) != 0) return std::error_code(errno, std::system_category()); uuid_string_t UUIDStr; uuid_unparse(uuid, UUIDStr); StringRef UUIDRef(UUIDStr); HostID.append(UUIDRef.begin(), UUIDRef.end()); #elif LLVM_ON_UNIX char HostName[256]; HostName[255] = 0; HostName[0] = 0; gethostname(HostName, 255); StringRef HostNameRef(HostName); HostID.append(HostNameRef.begin(), HostNameRef.end()); #else StringRef Dummy("localhost"); HostID.append(Dummy.begin(), Dummy.end()); #endif return std::error_code(); }
static void getWitnessMethodSubstitutions(ApplySite AI, SILFunction *F, ArrayRef<Substitution> Subs, SmallVectorImpl<Substitution> &NewSubs) { auto &Module = AI.getModule(); auto CalleeCanType = F->getLoweredFunctionType(); ProtocolDecl *proto = nullptr; if (CalleeCanType->getRepresentation() == SILFunctionTypeRepresentation::WitnessMethod) { proto = CalleeCanType->getDefaultWitnessMethodProtocol( *Module.getSwiftModule()); } ArrayRef<Substitution> origSubs = AI.getSubstitutions(); if (proto != nullptr) { // If the callee is a default witness method thunk, preserve substitutions // from the call site. NewSubs.append(origSubs.begin(), origSubs.end()); return; } // If the callee is a concrete witness method thunk, apply substitutions // from the conformance, and drop any substitutions derived from the Self // type. NewSubs.append(Subs.begin(), Subs.end()); if (auto generics = AI.getOrigCalleeType()->getGenericSignature()) { for (auto genericParam : generics->getAllDependentTypes()) { auto origSub = origSubs.front(); origSubs = origSubs.slice(1); // If the callee is a concrete witness method thunk, we ignore // generic parameters derived from 'self', the generic parameter at // depth 0, index 0. auto type = genericParam->getCanonicalType(); while (auto memberType = dyn_cast<DependentMemberType>(type)) { type = memberType.getBase(); } auto paramType = cast<GenericTypeParamType>(type); if (paramType->getDepth() == 0) { // There shouldn't be any other parameters at this depth. assert(paramType->getIndex() == 0); continue; } // Okay, remember this substitution. NewSubs.push_back(origSub); } } assert(origSubs.empty() && "subs not parallel to dependent types"); }
static void constexprToEdges(CFLAAResult &Analysis, ConstantExpr &CExprToCollapse, SmallVectorImpl<Edge> &Results, const TargetLibraryInfo &TLI) { SmallVector<ConstantExpr *, 4> Worklist; Worklist.push_back(&CExprToCollapse); SmallVector<Edge, 8> ConstexprEdges; SmallPtrSet<ConstantExpr *, 4> Visited; while (!Worklist.empty()) { auto *CExpr = Worklist.pop_back_val(); if (!hasUsefulEdges(CExpr)) continue; ConstexprEdges.clear(); argsToEdges(Analysis, CExpr, ConstexprEdges, TLI); for (auto &Edge : ConstexprEdges) { if (auto *Nested = dyn_cast<ConstantExpr>(Edge.From)) if (Visited.insert(Nested).second) Worklist.push_back(Nested); if (auto *Nested = dyn_cast<ConstantExpr>(Edge.To)) if (Visited.insert(Nested).second) Worklist.push_back(Nested); } Results.append(ConstexprEdges.begin(), ConstexprEdges.end()); } }
StringRef HeaderMap::lookupFilename(StringRef Filename, SmallVectorImpl<char> &DestPath) const { const HMapHeader &Hdr = getHeader(); unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets); // If the number of buckets is not a power of two, the headermap is corrupt. // Don't probe infinitely. if (NumBuckets & (NumBuckets-1)) return StringRef(); // Linearly probe the hash table. for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) { HMapBucket B = getBucket(Bucket & (NumBuckets-1)); if (B.Key == HMAP_EmptyBucketKey) return StringRef(); // Hash miss. // See if the key matches. If not, probe on. if (!Filename.equals_lower(getString(B.Key))) continue; // If so, we have a match in the hash table. Construct the destination // path. StringRef Prefix = getString(B.Prefix); StringRef Suffix = getString(B.Suffix); DestPath.clear(); DestPath.append(Prefix.begin(), Prefix.end()); DestPath.append(Suffix.begin(), Suffix.end()); return StringRef(DestPath.begin(), DestPath.size()); } }
StringRef HeaderMapImpl::lookupFilename(StringRef Filename, SmallVectorImpl<char> &DestPath) const { const HMapHeader &Hdr = getHeader(); unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets); // Don't probe infinitely. This should be checked before constructing. assert(llvm::isPowerOf2_32(NumBuckets) && "Expected power of 2"); // Linearly probe the hash table. for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) { HMapBucket B = getBucket(Bucket & (NumBuckets-1)); if (B.Key == HMAP_EmptyBucketKey) return StringRef(); // Hash miss. // See if the key matches. If not, probe on. Optional<StringRef> Key = getString(B.Key); if (LLVM_UNLIKELY(!Key)) continue; if (!Filename.equals_lower(*Key)) continue; // If so, we have a match in the hash table. Construct the destination // path. Optional<StringRef> Prefix = getString(B.Prefix); Optional<StringRef> Suffix = getString(B.Suffix); DestPath.clear(); if (LLVM_LIKELY(Prefix && Suffix)) { DestPath.append(Prefix->begin(), Prefix->end()); DestPath.append(Suffix->begin(), Suffix->end()); } return StringRef(DestPath.begin(), DestPath.size()); } }
// following functions are shamelessly copied from LLVM. bool isPotentiallyReachableFromMany(SmallVectorImpl<BasicBlock *> &Worklist, BasicBlock *StopBB) { // Limit the number of blocks we visit. The goal is to avoid run-away compile // times on large CFGs without hampering sensible code. Arbitrarily chosen. unsigned Limit = 32; SmallSet<const BasicBlock*, 64> Visited; do { BasicBlock *BB = Worklist.pop_back_val(); if (!Visited.insert(BB).second) continue; if (BB == StopBB) return true; if (!--Limit) { // We haven't been able to prove it one way or the other. Conservatively // answer true -- that there is potentially a path. return true; } Worklist.append(succ_begin(BB), succ_end(BB)); } while (!Worklist.empty()); // We have exhausted all possible paths and are certain that 'To' can not be // reached from 'From'. return false; }
error_code llvmutil_createtemporaryfile(const Twine &Prefix, StringRef Suffix, SmallVectorImpl<char> &ResultPath) { llvm::sys::Path P("/tmp"); P.appendComponent(Prefix.str()); P.appendSuffix(Suffix); P.makeUnique(false,NULL); StringRef str = P.str(); ResultPath.append(str.begin(),str.end()); return error_code(); }
static void getPath(SmallVectorImpl<char> &Path, const MDNode *MD) { if(MD==NULL) return; StringRef Filename = DIScope(MD).getFilename(); if (sys::path::is_absolute(Filename)) Path.append(Filename.begin(), Filename.end()); else sys::path::append(Path, DIScope(MD).getDirectory(), Filename); }
static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, StringRef Modifier, StringRef Argument, ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, SmallVectorImpl<char> &Output, void *Cookie, ArrayRef<intptr_t> QualTypeVals) { StringRef Str = "<can't format argument>"; Output.append(Str.begin(), Str.end()); }
static std::error_code getRelocationValueString(const COFFObjectFile *Obj, const RelocationRef &Rel, SmallVectorImpl<char> &Result) { symbol_iterator SymI = Rel.getSymbol(); StringRef SymName; if (std::error_code EC = SymI->getName(SymName)) return EC; Result.append(SymName.begin(), SymName.end()); return std::error_code(); }
/// Get the runtime library link path, which is platform-specific and found /// relative to the compiler. static void getRuntimeLibraryPath(SmallVectorImpl<char> &runtimeLibPath, const llvm::opt::ArgList &args, const ToolChain &TC) { // FIXME: Duplicated from CompilerInvocation, but in theory the runtime // library link path and the standard library module import path don't // need to be the same. if (const Arg *A = args.getLastArg(options::OPT_resource_dir)) { StringRef value = A->getValue(); runtimeLibPath.append(value.begin(), value.end()); } else { auto programPath = TC.getDriver().getSwiftProgramPath(); runtimeLibPath.append(programPath.begin(), programPath.end()); llvm::sys::path::remove_filename(runtimeLibPath); // remove /swift llvm::sys::path::remove_filename(runtimeLibPath); // remove /bin llvm::sys::path::append(runtimeLibPath, "lib", "swift"); } llvm::sys::path::append(runtimeLibPath, getPlatformNameForTriple(TC.getTriple())); }
static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, const char *Modifier, unsigned ML, const char *Argument, unsigned ArgLen, const DiagnosticsEngine::ArgumentValue *PrevArgs, unsigned NumPrevArgs, SmallVectorImpl<char> &Output, void *Cookie, ArrayRef<intptr_t> QualTypeVals) { const char *Str = "<can't format argument>"; Output.append(Str, Str+strlen(Str)); }
StringRef camel_case::appendSentenceCase(SmallVectorImpl<char> &buffer, StringRef string) { // Trivial case: empty string. if (string.empty()) return StringRef(buffer.data(), buffer.size()); // Uppercase the first letter, append the rest. buffer.push_back(clang::toUppercase(string[0])); buffer.append(string.begin() + 1, string.end()); return StringRef(buffer.data(), buffer.size()); }
/// FormatDiagnostic - Format this diagnostic into a string, substituting the /// formal arguments into the %0 slots. The result is appended onto the Str /// array. void Diagnostic:: FormatDiagnostic(SmallVectorImpl<char> &OutStr) const { if (!StoredDiagMessage.empty()) { OutStr.append(StoredDiagMessage.begin(), StoredDiagMessage.end()); return; } StringRef Diag = getDiags()->getDiagnosticIDs()->getDescription(getID()); FormatDiagnostic(Diag.begin(), Diag.end(), OutStr); }
StringRef EnumInfoCache::getEnumInfoKey(const clang::EnumDecl *decl, SmallVectorImpl<char> &scratch) { StringRef moduleName; if (auto moduleOpt = getClangSubmoduleForDecl(decl)) { if (*moduleOpt) moduleName = (*moduleOpt)->getTopLevelModuleName(); } if (moduleName.empty()) moduleName = decl->getASTContext().getLangOpts().CurrentModule; StringRef enumName = decl->getDeclName() ? decl->getName() : decl->getTypedefNameForAnonDecl()->getName(); if (moduleName.empty()) return enumName; scratch.append(moduleName.begin(), moduleName.end()); scratch.push_back('.'); scratch.append(enumName.begin(), enumName.end()); return StringRef(scratch.data(), scratch.size()); }
void append(SmallVectorImpl<char> &path, Style style, const Twine &a, const Twine &b, const Twine &c, const Twine &d) { SmallString<32> a_storage; SmallString<32> b_storage; SmallString<32> c_storage; SmallString<32> d_storage; SmallVector<StringRef, 4> components; if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage)); if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage)); if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage)); if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage)); for (auto &component : components) { bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1], style); bool component_has_sep = !component.empty() && is_separator(component[0], style); bool is_root_name = has_root_name(component, style); if (path_has_sep) { // Strip separators from beginning of component. size_t loc = component.find_first_not_of(separators(style)); StringRef c = component.substr(loc); // Append it. path.append(c.begin(), c.end()); continue; } if (!component_has_sep && !(path.empty() || is_root_name)) { // Add a separator. path.push_back(preferred_separator(style)); } path.append(component.begin(), component.end()); } }
StringRef camel_case::toSentencecase(StringRef string, SmallVectorImpl<char> &scratch) { if (string.empty()) return string; // Can't be uppercased. if (!clang::isLowercase(string[0])) return string; // Uppercase the first letter, append the rest. scratch.clear(); scratch.push_back(clang::toUppercase(string[0])); scratch.append(string.begin() + 1, string.end()); return StringRef(scratch.data(), scratch.size()); }
void Instruction::getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned, MDNode*> > &Result)const { assert(hasMetadata() && getContext().pImpl->MetadataStore.count(this) && "Shouldn't have called this"); const LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore.find(this)->second; assert(!Info.empty() && "Shouldn't have called this"); Result.clear(); Result.append(Info.begin(), Info.end()); // Sort the resulting array so it is stable. if (Result.size() > 1) array_pod_sort(Result.begin(), Result.end()); }
/// \brief Escape diagnostic texts to avoid problems when they are fed into the /// diagnostic formatter a second time. static StringRef escapeDiag(StringRef Str, SmallVectorImpl<char> &Buf) { size_t Pos = Str.find('%'); if (Pos == StringRef::npos) return Str; // We found a '%'. Replace this and all following '%' with '%%'. Buf.clear(); Buf.append(Str.data(), Str.data() + Pos); for (size_t I = Pos, E = Str.size(); I != E; ++I) { if (Str[I] == '%') Buf.push_back('%'); Buf.push_back(Str[I]); } return StringRef(Buf.data(), Buf.size()); }
bool ReplacementHandling::generateReplacementsFileName( StringRef DestinationDir, StringRef MainSourceFile, SmallVectorImpl<char> &Result, SmallVectorImpl<char> &Error) { Error.clear(); SmallString<128> Prefix = DestinationDir; path::append(Prefix, path::filename(MainSourceFile)); if (std::error_code EC = fs::createUniqueFile(Prefix + "_%%_%%_%%_%%_%%_%%.yaml", Result)) { const std::string &Msg = EC.message(); Error.append(Msg.begin(), Msg.end()); return false; } return true; }
/// Collect all of the generic parameter types at every level in the generic /// parameter list. static void collectGenericParamTypes( GenericParamList *genericParams, GenericSignature *parentSig, SmallVectorImpl<GenericTypeParamType *> &allParams) { // If the parent context has a generic signature, add its generic parameters. if (parentSig) { allParams.append(parentSig->getGenericParams().begin(), parentSig->getGenericParams().end()); } if (genericParams) { // Add our parameters. for (auto param : *genericParams) { allParams.push_back(param->getDeclaredType() ->castTo<GenericTypeParamType>()); } } }
void replace_extension(SmallVectorImpl<char> &path, const Twine &extension, Style style) { StringRef p(path.begin(), path.size()); SmallString<32> ext_storage; StringRef ext = extension.toStringRef(ext_storage); // Erase existing extension. size_t pos = p.find_last_of('.'); if (pos != StringRef::npos && pos >= filename_pos(p, style)) path.set_size(pos); // Append '.' if needed. if (ext.size() > 0 && ext[0] != '.') path.push_back('.'); // Append extension. path.append(ext.begin(), ext.end()); }
void WasmObjectFile::getRelocationTypeName( DataRefImpl Ref, SmallVectorImpl<char> &Result) const { const wasm::WasmRelocation& Rel = getWasmRelocation(Ref); StringRef Res = "Unknown"; #define WASM_RELOC(name, value) \ case wasm::name: \ Res = #name; \ break; switch (Rel.Type) { #include "llvm/BinaryFormat/WasmRelocs/WebAssembly.def" } #undef WASM_RELOC Result.append(Res.begin(), Res.end()); }
static bool isPotentiallyReachableInner(SmallVectorImpl<BasicBlock *> &Worklist, BasicBlock *StopBB, const DominatorTree *DT, const LoopInfo *LI) { // When the stop block is unreachable, it's dominated from everywhere, // regardless of whether there's a path between the two blocks. if (DT && !DT->isReachableFromEntry(StopBB)) DT = 0; // Limit the number of blocks we visit. The goal is to avoid run-away compile // times on large CFGs without hampering sensible code. Arbitrarily chosen. unsigned Limit = 128; SmallSet<const BasicBlock*, 64> Visited; do { BasicBlock *BB = Worklist.pop_back_val(); if (!Visited.insert(BB)) continue; if (BB == StopBB) return true; if (DT && DT->dominates(BB, StopBB)) return true; if (LI && loopContainsBoth(LI, BB, StopBB)) return true; if (!--Limit) { // We haven't been able to prove it one way or the other. Conservatively // answer true -- that there is potentially a path. return true; } if (const Loop *Outer = LI ? getOutermostLoop(LI, BB) : 0) { // All blocks in a single loop are reachable from all other blocks. From // any of these blocks, we can skip directly to the exits of the loop, // ignoring any other blocks inside the loop body. Outer->getExitBlocks(Worklist); } else { Worklist.append(succ_begin(BB), succ_end(BB)); } } while (!Worklist.empty()); // We have exhausted all possible paths and are certain that 'To' can not be // reached from 'From'. return false; }
StringRef camel_case::toLowercaseWord(StringRef string, SmallVectorImpl<char> &scratch) { if (string.empty()) return string; // Already lowercase. if (!clang::isUppercase(string[0])) return string; // Acronym doesn't get lowercased. if (string.size() > 1 && clang::isUppercase(string[1])) return string; // Lowercase the first letter, append the rest. scratch.clear(); scratch.push_back(clang::toLowercase(string[0])); scratch.append(string.begin() + 1, string.end()); return StringRef(scratch.data(), scratch.size()); }
static ResolutionKind recordImportDecls(LazyResolver *typeResolver, SmallVectorImpl<ValueDecl *> &results, ArrayRef<ValueDecl *> newDecls, OverloadSetTy &overloads, ResolutionKind resolutionKind) { switch (resolutionKind) { case ResolutionKind::Overloadable: { // Add new decls if they provide a new overload. Note that the new decls // may be ambiguous with respect to each other, just not any existing decls. std::copy_if(newDecls.begin(), newDecls.end(), std::back_inserter(results), [&](ValueDecl *result) -> bool { if (!result->hasInterfaceType()) { if (typeResolver) { typeResolver->resolveDeclSignature(result); if (result->isInvalid()) return true; } else { return true; } } return isValidOverload(overloads, result); }); // Update the overload set. bool stillOverloadable = updateOverloadSet(overloads, newDecls); return stillOverloadable ? ResolutionKind::Overloadable : ResolutionKind::Exact; } case ResolutionKind::Exact: // Add all decls. If they're ambiguous, they're ambiguous. results.append(newDecls.begin(), newDecls.end()); return ResolutionKind::Exact; case ResolutionKind::TypesOnly: // Add type decls only. If they're ambiguous, they're ambiguous. std::copy_if(newDecls.begin(), newDecls.end(), std::back_inserter(results), [](const ValueDecl *VD) { return isa<TypeDecl>(VD); }); return ResolutionKind::TypesOnly; } llvm_unreachable("bad ResolutionKind"); }
/// Compute substitutions for making a direct call to a SIL function with /// @convention(witness_method) convention. /// /// Such functions have a substituted generic signature where the /// abstract `Self` parameter from the original type of the protocol /// requirement is replaced by a concrete type. /// /// Thus, the original substitutions of the apply instruction that /// are written in terms of the requirement's generic signature need /// to be remapped to substitutions suitable for the witness signature. /// /// \param conformanceRef The (possibly-specialized) conformance /// \param requirementSig The generic signature of the requirement /// \param witnessThunkSig The generic signature of the witness method /// \param origSubs The substitutions from the call instruction /// \param newSubs New substitutions are stored here static void getWitnessMethodSubstitutions( SILModule &M, ProtocolConformanceRef conformanceRef, GenericSignature *requirementSig, GenericSignature *witnessThunkSig, SubstitutionList origSubs, bool isDefaultWitness, SmallVectorImpl<Substitution> &newSubs) { if (witnessThunkSig == nullptr) return; if (isDefaultWitness) { newSubs.append(origSubs.begin(), origSubs.end()); return; } assert(!conformanceRef.isAbstract()); auto conformance = conformanceRef.getConcrete(); // If `Self` maps to a bound generic type, this gives us the // substitutions for the concrete type's generic parameters. auto baseSubMap = getSubstitutionsForProtocolConformance(conformanceRef); unsigned baseDepth = 0; auto *rootConformance = conformance->getRootNormalConformance(); if (auto *witnessSig = rootConformance->getGenericSignature()) baseDepth = witnessSig->getGenericParams().back()->getDepth() + 1; auto origDepth = 1; auto origSubMap = requirementSig->getSubstitutionMap(origSubs); auto subMap = SubstitutionMap::combineSubstitutionMaps(baseSubMap, origSubMap, CombineSubstitutionMaps::AtDepth, baseDepth, origDepth, witnessThunkSig); witnessThunkSig->getSubstitutions(subMap, newSubs); }
/// Collect all of the generic parameter types at every level in the generic /// parameter list. static void collectGenericParamTypes( GenericParamList *genericParams, DeclContext *parentDC, SmallVectorImpl<GenericTypeParamType *> &allParams) { // If the parent context is a generic type (or nested type thereof), // add its generic parameters. if (parentDC->isTypeContext()) { if (auto parentSig = parentDC->getGenericSignatureOfContext()) { allParams.append(parentSig->getGenericParams().begin(), parentSig->getGenericParams().end()); } } if (genericParams) { // Add our parameters. for (auto param : *genericParams) { allParams.push_back(param->getDeclaredType() ->castTo<GenericTypeParamType>()); } } }
/// fixupSubprogramName - Replace contains special characters used /// in a typical Objective-C names with '.' in a given string. static void fixupSubprogramName(DISubprogram Fn, SmallVectorImpl<char> &Out) { StringRef FName = Fn.getFunction() ? Fn.getFunction()->getName() : Fn.getName(); FName = Function::getRealLinkageName(FName); StringRef Prefix("llvm.dbg.lv."); Out.reserve(FName.size() + Prefix.size()); Out.append(Prefix.begin(), Prefix.end()); bool isObjCLike = false; for (size_t i = 0, e = FName.size(); i < e; ++i) { char C = FName[i]; if (C == '[') isObjCLike = true; if (isObjCLike && (C == '[' || C == ']' || C == ' ' || C == ':' || C == '+' || C == '(' || C == ')')) Out.push_back('.'); else Out.push_back(C); } }