//===- Strings.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "lld/Common/Strings.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/LLVM.h" #include "llvm/Demangle/Demangle.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/GlobPattern.h" #include #include #include using namespace llvm; using namespace lld; // Returns the demangled C++ symbol name for name. std::string lld::demangleItanium(StringRef name) { // demangleItanium() can be called for all symbols. Only demangle C++ symbols, // to avoid getting unexpected result for a C symbol that happens to match a // mangled type name such as "Pi" (which would demangle to "int*"). if (!name.startswith("_Z") && !name.startswith("__Z") && !name.startswith("___Z") && !name.startswith("____Z")) return std::string(name); return demangle(std::string(name)); } SingleStringMatcher::SingleStringMatcher(StringRef Pattern) { if (Pattern.size() > 2 && Pattern.startswith("\"") && Pattern.endswith("\"")) { ExactMatch = true; ExactPattern = Pattern.substr(1, Pattern.size() - 2); } else { Expected Glob = GlobPattern::create(Pattern); if (!Glob) { error(toString(Glob.takeError())); return; } ExactMatch = false; GlobPatternMatcher = *Glob; } } bool SingleStringMatcher::match(StringRef s) const { return ExactMatch ? (ExactPattern == s) : GlobPatternMatcher.match(s); } bool StringMatcher::match(StringRef s) const { for (const SingleStringMatcher &pat : patterns) if (pat.match(s)) return true; return false; } // Converts a hex string (e.g. "deadbeef") to a vector. std::vector lld::parseHex(StringRef s) { std::vector hex; while (!s.empty()) { StringRef b = s.substr(0, 2); s = s.substr(2); uint8_t h; if (!to_integer(b, h, 16)) { error("not a hexadecimal value: " + b); return {}; } hex.push_back(h); } return hex; } // Returns true if S is valid as a C language identifier. bool lld::isValidCIdentifier(StringRef s) { return !s.empty() && (isAlpha(s[0]) || s[0] == '_') && std::all_of(s.begin() + 1, s.end(), [](char c) { return c == '_' || isAlnum(c); }); } // Write the contents of the a buffer to a file void lld::saveBuffer(StringRef buffer, const Twine &path) { std::error_code ec; raw_fd_ostream os(path.str(), ec, sys::fs::OpenFlags::OF_None); if (ec) error("cannot create " + path + ": " + ec.message()); os << buffer; }