Skip to content

Commit 5de0a39

Browse files
committed
[Mangler] Verify USR manglings as well.
1 parent 6c2e1b9 commit 5de0a39

File tree

4 files changed

+32
-14
lines changed

4 files changed

+32
-14
lines changed

include/swift/Basic/Mangler.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,13 @@
1414
#define SWIFT_BASIC_MANGLER_H
1515

1616
#include "swift/Demangling/ManglingUtils.h"
17+
#include "swift/Basic/LLVM.h"
1718
#include "llvm/ADT/DenseMap.h"
19+
#include "llvm/ADT/SmallString.h"
1820
#include "llvm/ADT/StringRef.h"
1921
#include "llvm/ADT/StringMap.h"
2022
#include "llvm/Support/raw_ostream.h"
2123

22-
using llvm::StringRef;
23-
using llvm::ArrayRef;
24-
2524
namespace swift {
2625
namespace Mangle {
2726

@@ -39,7 +38,7 @@ class Mangler {
3938
friend class SubstitutionMerging;
4039

4140
/// The storage for the mangled symbol.
42-
llvm::SmallVector<char, 128> Storage;
41+
llvm::SmallString<128> Storage;
4342

4443
/// The output stream for the mangled symbol.
4544
llvm::raw_svector_ostream Buffer;
@@ -106,7 +105,7 @@ class Mangler {
106105
void finalize(llvm::raw_ostream &stream);
107106

108107
/// Verify that demangling and remangling works.
109-
void verify(const std::string &mangledName);
108+
static void verify(StringRef mangledName);
110109

111110
/// Appends a mangled identifier string.
112111
void appendIdentifier(StringRef ident);

lib/AST/ASTMangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,9 @@ std::string ASTMangler::mangleDeclAsUSR(const ValueDecl *Decl,
350350
} else {
351351
appendEntity(Decl);
352352
}
353+
354+
// We have a custom prefix, so finalize() won't verify for us. Do it manually.
355+
verify(Storage.str().drop_front(USRPrefix.size()));
353356
return finalize();
354357
}
355358

@@ -360,6 +363,8 @@ std::string ASTMangler::mangleAccessorEntityAsUSR(AccessorKind kind,
360363
llvm::SaveAndRestore<bool> allowUnnamedRAII(AllowNamelessEntities, true);
361364
Buffer << USRPrefix;
362365
appendAccessorEntity(kind, addressorKind, decl, /*isStatic*/ false);
366+
// We have a custom prefix, so finalize() won't verify for us. Do it manually.
367+
verify(Storage.str().drop_front(USRPrefix.size()));
363368
return finalize();
364369
}
365370

lib/Basic/Mangler.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,14 @@ void Mangler::beginMangling() {
122122
/// Finish the mangling of the symbol and return the mangled name.
123123
std::string Mangler::finalize() {
124124
assert(Storage.size() && "Mangling an empty name");
125-
std::string result = std::string(Storage.data(), Storage.size());
125+
std::string result = Storage.str().str();
126126
Storage.clear();
127-
verify(result);
127+
128+
#ifndef NDEBUG
129+
if (StringRef(result).startswith(MANGLING_PREFIX_STR))
130+
verify(result);
131+
#endif
132+
128133
return result;
129134
}
130135

@@ -147,11 +152,19 @@ static bool treeContains(Demangle::NodePointer Nd, Demangle::Node::Kind Kind) {
147152
return false;
148153
}
149154

150-
void Mangler::verify(const std::string &mangledName) {
155+
void Mangler::verify(StringRef nameStr) {
151156
#ifndef NDEBUG
152-
StringRef nameStr = mangledName;
153-
if (!nameStr.startswith(MANGLING_PREFIX_STR))
154-
return;
157+
SmallString<128> buffer;
158+
if (!nameStr.startswith(MANGLING_PREFIX_STR) &&
159+
!nameStr.startswith("_Tt") &&
160+
!nameStr.startswith("_S")) {
161+
// This list is the set of prefixes recognized by Demangler::demangleSymbol.
162+
// It should be kept in sync.
163+
assert(StringRef(MANGLING_PREFIX_STR) != "_S" && "redundant check");
164+
buffer += MANGLING_PREFIX_STR;
165+
buffer += nameStr;
166+
nameStr = buffer.str();
167+
}
155168

156169
Demangler Dem;
157170
NodePointer Root = Dem.demangleSymbol(nameStr);
@@ -160,15 +173,14 @@ void Mangler::verify(const std::string &mangledName) {
160173
abort();
161174
}
162175
std::string Remangled = mangleNode(Root);
163-
if (Remangled == mangledName)
176+
if (Remangled == nameStr)
164177
return;
165178

166179
// There are cases (e.g. with dependent associated types) which results in
167180
// different remangled names. See ASTMangler::appendAssociatedTypeName.
168181
// This is no problem for the compiler, but we have to be more tolerant for
169182
// those cases. Instead we try to re-de-mangle the remangled name.
170-
nameStr = Remangled;
171-
NodePointer RootOfRemangled = Dem.demangleSymbol(nameStr);
183+
NodePointer RootOfRemangled = Dem.demangleSymbol(Remangled);
172184
std::string ReDemangled = mangleNode(RootOfRemangled);
173185
if (Remangled == ReDemangled)
174186
return;

lib/Demangling/Demangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ NodePointer Demangler::demangleSymbol(StringRef MangledName) {
237237
&& !nextIf("_S"))
238238
return nullptr;
239239

240+
// If any other prefixes are accepted, please update Mangler::verify.
241+
240242
NodePointer topLevel = createNode(Node::Kind::Global);
241243

242244
parseAndPushNodes();

0 commit comments

Comments
 (0)