blob: cd19612acc65c753eda5703d1bfc750764238d80 [file] [log] [blame]
Rui Ueyama93c9af42016-06-29 08:01:32 +00001//===- Strings.cpp -------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Strings.h"
11#include "Error.h"
George Rimarc91930a2016-09-02 21:17:20 +000012#include "llvm/ADT/ArrayRef.h"
Rui Ueyama93c9af42016-06-29 08:01:32 +000013#include "llvm/ADT/StringRef.h"
14#include "llvm/ADT/Twine.h"
Rui Ueyamaf4d93382016-07-07 23:04:15 +000015#include "llvm/Config/config.h"
Rafael Espindolad1942132016-09-06 19:17:14 +000016#include "llvm/Demangle/Demangle.h"
Rui Ueyamafbbde542016-06-29 09:08:02 +000017#include <algorithm>
Rui Ueyama93c9af42016-06-29 08:01:32 +000018
19using namespace llvm;
20using namespace lld;
21using namespace lld::elf;
22
George Rimarc91930a2016-09-02 21:17:20 +000023bool elf::hasWildcard(StringRef S) {
George Rimar51da9c72016-09-07 10:19:44 +000024 return S.find_first_of("?*[") != StringRef::npos;
George Rimarc91930a2016-09-02 21:17:20 +000025}
26
George Rimarcd574a52016-09-09 14:35:36 +000027StringRef elf::unquote(StringRef S) {
28 if (!S.startswith("\""))
29 return S;
30 return S.substr(1, S.size() - 2);
31}
32
Rui Ueyamadad2b882016-09-02 22:15:08 +000033// Converts a glob pattern to a regular expression.
George Rimarc91930a2016-09-02 21:17:20 +000034static std::string toRegex(StringRef S) {
George Rimarc91930a2016-09-02 21:17:20 +000035 std::string T;
George Rimar51da9c72016-09-07 10:19:44 +000036 bool InBracket = false;
George Rimarc91930a2016-09-02 21:17:20 +000037 while (!S.empty()) {
38 char C = S.front();
George Rimar51da9c72016-09-07 10:19:44 +000039 if (InBracket) {
40 InBracket = C != ']';
41 T += C;
42 S = S.drop_front();
43 continue;
44 }
45
George Rimarc91930a2016-09-02 21:17:20 +000046 if (C == '*')
47 T += ".*";
48 else if (C == '?')
49 T += '.';
George Rimar51da9c72016-09-07 10:19:44 +000050 else if (StringRef(".+^${}()|/\\").find_first_of(C) != StringRef::npos)
George Rimarc91930a2016-09-02 21:17:20 +000051 T += std::string("\\") + C;
52 else
53 T += C;
George Rimar51da9c72016-09-07 10:19:44 +000054
55 InBracket = C == '[';
Rui Ueyama93c9af42016-06-29 08:01:32 +000056 S = S.substr(1);
Rui Ueyama93c9af42016-06-29 08:01:32 +000057 }
George Rimarc91930a2016-09-02 21:17:20 +000058 return T;
59}
60
Rui Ueyamadad2b882016-09-02 22:15:08 +000061// Converts multiple glob patterns to a regular expression.
George Rimarc91930a2016-09-02 21:17:20 +000062Regex elf::compileGlobPatterns(ArrayRef<StringRef> V) {
63 std::string T = "^(" + toRegex(V[0]);
64 for (StringRef S : V.slice(1))
65 T += "|" + toRegex(S);
66 return Regex(T + ")$");
Rui Ueyama93c9af42016-06-29 08:01:32 +000067}
68
69// Converts a hex string (e.g. "deadbeef") to a vector.
70std::vector<uint8_t> elf::parseHex(StringRef S) {
71 std::vector<uint8_t> Hex;
72 while (!S.empty()) {
73 StringRef B = S.substr(0, 2);
74 S = S.substr(2);
75 uint8_t H;
76 if (B.getAsInteger(16, H)) {
77 error("not a hexadecimal value: " + B);
78 return {};
79 }
80 Hex.push_back(H);
81 }
82 return Hex;
83}
Rui Ueyamafbbde542016-06-29 09:08:02 +000084
85static bool isAlpha(char C) {
86 return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z') || C == '_';
87}
88
89static bool isAlnum(char C) { return isAlpha(C) || ('0' <= C && C <= '9'); }
90
91// Returns true if S is valid as a C language identifier.
92bool elf::isValidCIdentifier(StringRef S) {
93 return !S.empty() && isAlpha(S[0]) &&
94 std::all_of(S.begin() + 1, S.end(), isAlnum);
95}
Rui Ueyamaf4d93382016-07-07 23:04:15 +000096
97// Returns the demangled C++ symbol name for Name.
98std::string elf::demangle(StringRef Name) {
Rui Ueyamaf4d93382016-07-07 23:04:15 +000099 // __cxa_demangle can be used to demangle strings other than symbol
100 // names which do not necessarily start with "_Z". Name can be
101 // either a C or C++ symbol. Don't call __cxa_demangle if the name
102 // does not look like a C++ symbol name to avoid getting unexpected
103 // result for a C symbol that happens to match a mangled type name.
104 if (!Name.startswith("_Z"))
105 return Name;
106
Rafael Espindolad1942132016-09-06 19:17:14 +0000107 char *Buf = itaniumDemangle(Name.str().c_str(), nullptr, nullptr, nullptr);
Rui Ueyamaf4d93382016-07-07 23:04:15 +0000108 if (!Buf)
109 return Name;
110 std::string S(Buf);
111 free(Buf);
112 return S;
Rui Ueyamaf4d93382016-07-07 23:04:15 +0000113}