int InternalStatus = demangle_success;
Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
- OutputBuffer O;
-
Node *AST = Parser.parse();
if (AST == nullptr)
InternalStatus = demangle_invalid_mangled_name;
- else if (!initializeOutputBuffer(Buf, N, O, 1024))
- InternalStatus = demangle_memory_alloc_failure;
else {
+ OutputBuffer O(Buf, N);
assert(Parser.ForwardTemplateRefs.empty());
AST->print(O);
O += '\0';
public:
OutputBuffer(char *StartBuf, size_t Size)
- : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
+ : Buffer(StartBuf), BufferCapacity(Size) {}
+ OutputBuffer(char *StartBuf, size_t *SizePtr)
+ : OutputBuffer(StartBuf, StartBuf ? *SizePtr : 0) {}
OutputBuffer() = default;
// Non-copyable
OutputBuffer(const OutputBuffer &) = delete;
operator StringView() const { return StringView(Buffer, CurrentPosition); }
- void reset(char *Buffer_, size_t BufferCapacity_) {
- CurrentPosition = 0;
- Buffer = Buffer_;
- BufferCapacity = BufferCapacity_;
- }
-
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
/// into the pack that we're currently printing.
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
ScopedOverride &operator=(const ScopedOverride &) = delete;
};
-inline bool initializeOutputBuffer(char *Buf, size_t *N, OutputBuffer &OB,
- size_t InitSize) {
- size_t BufferSize;
- if (Buf == nullptr) {
- Buf = static_cast<char *>(std::malloc(InitSize));
- if (Buf == nullptr)
- return false;
- BufferSize = InitSize;
- } else
- BufferSize = *N;
-
- OB.reset(Buf, BufferSize);
- return true;
-}
-
DEMANGLE_NAMESPACE_END
#endif
public:
OutputBuffer(char *StartBuf, size_t Size)
- : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
+ : Buffer(StartBuf), BufferCapacity(Size) {}
+ OutputBuffer(char *StartBuf, size_t *SizePtr)
+ : OutputBuffer(StartBuf, StartBuf ? *SizePtr : 0) {}
OutputBuffer() = default;
// Non-copyable
OutputBuffer(const OutputBuffer &) = delete;
operator StringView() const { return StringView(Buffer, CurrentPosition); }
- void reset(char *Buffer_, size_t BufferCapacity_) {
- CurrentPosition = 0;
- Buffer = Buffer_;
- BufferCapacity = BufferCapacity_;
- }
-
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
/// into the pack that we're currently printing.
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
ScopedOverride &operator=(const ScopedOverride &) = delete;
};
-inline bool initializeOutputBuffer(char *Buf, size_t *N, OutputBuffer &OB,
- size_t InitSize) {
- size_t BufferSize;
- if (Buf == nullptr) {
- Buf = static_cast<char *>(std::malloc(InitSize));
- if (Buf == nullptr)
- return false;
- BufferSize = InitSize;
- } else
- BufferSize = *N;
-
- OB.reset(Buf, BufferSize);
- return true;
-}
-
DEMANGLE_NAMESPACE_END
#endif
return nullptr;
OutputBuffer Demangled;
- if (!initializeOutputBuffer(nullptr, nullptr, Demangled, 1024))
- return nullptr;
-
if (strcmp(MangledName, "_Dmain") == 0) {
Demangled << "D main";
} else {
int InternalStatus = demangle_success;
Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
- OutputBuffer OB;
-
Node *AST = Parser.parse();
if (AST == nullptr)
InternalStatus = demangle_invalid_mangled_name;
- else if (!initializeOutputBuffer(Buf, N, OB, 1024))
- InternalStatus = demangle_memory_alloc_failure;
else {
+ OutputBuffer OB(Buf, N);
assert(Parser.ForwardTemplateRefs.empty());
AST->print(OB);
OB += '\0';
}
static char *printNode(const Node *RootNode, char *Buf, size_t *N) {
- OutputBuffer OB;
- if (!initializeOutputBuffer(Buf, N, OB, 128))
- return nullptr;
+ OutputBuffer OB(Buf, N);
RootNode->print(OB);
OB += '\0';
if (N != nullptr)
return nullptr;
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
- OutputBuffer OB;
- if (!initializeOutputBuffer(Buf, N, OB, 128))
- return nullptr;
+ OutputBuffer OB(Buf, N);
KeepGoingLocalFunction:
while (true) {
return nullptr;
NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
- OutputBuffer OB;
- if (!initializeOutputBuffer(Buf, N, OB, 128))
- return nullptr;
+ OutputBuffer OB(Buf, N);
OB += '(';
Params.printWithComma(OB);
if (!isFunction())
return nullptr;
- OutputBuffer OB;
- if (!initializeOutputBuffer(Buf, N, OB, 128))
- return nullptr;
+ OutputBuffer OB(Buf, N);
if (const Node *Ret =
static_cast<const FunctionEncoding *>(RootNode)->getReturnType())
StringView Demangler::copyString(StringView Borrowed) {
char *Stable = Arena.allocUnalignedBuffer(Borrowed.size());
- std::memcpy(Stable, Borrowed.begin(), Borrowed.size());
+ // This is not a micro-optimization, it avoids UB, should Borrowed be an null
+ // buffer.
+ if (Borrowed.size())
+ std::memcpy(Stable, Borrowed.begin(), Borrowed.size());
return {Stable, Borrowed.size()};
}
// Render this class template name into a string buffer so that we can
// memorize it for the purpose of back-referencing.
OutputBuffer OB;
- if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024))
- // FIXME: Propagate out-of-memory as an error?
- std::terminate();
Identifier->output(OB, OF_Default);
StringView Owned = copyString(OB);
memorizeString(Owned);
EncodedStringLiteralNode *Result = Arena.alloc<EncodedStringLiteralNode>();
- // Must happen before the first `goto StringLiteralError`.
- if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024))
- // FIXME: Propagate out-of-memory as an error?
- std::terminate();
-
// Prefix indicating the beginning of a string literal
if (!MangledName.consumeFront("@_"))
goto StringLiteralError;
// Render the parent symbol's name into a buffer.
OutputBuffer OB;
- if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024))
- // FIXME: Propagate out-of-memory as an error?
- std::terminate();
OB << '`';
Scope->output(OB, OF_Default);
OB << '\'';
// Create an output stream so we can render each type.
OutputBuffer OB;
- if (!initializeOutputBuffer(nullptr, nullptr, OB, 1024))
- std::terminate();
for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) {
OB.setCurrentPosition(0);
char *Buf, size_t *N,
int *Status, MSDemangleFlags Flags) {
Demangler D;
- OutputBuffer OB;
StringView Name{MangledName};
SymbolNode *AST = D.parse(Name);
int InternalStatus = demangle_success;
if (D.Error)
InternalStatus = demangle_invalid_mangled_name;
- else if (!initializeOutputBuffer(Buf, N, OB, 1024))
- InternalStatus = demangle_memory_alloc_failure;
else {
+ OutputBuffer OB(Buf, N);
AST->output(OB, OF);
OB += '\0';
if (N != nullptr)
std::string Node::toString(OutputFlags Flags) const {
OutputBuffer OB;
- initializeOutputBuffer(nullptr, nullptr, OB, 1024);
this->output(OB, Flags);
StringView SV = OB;
std::string Owned(SV.begin(), SV.end());
return nullptr;
Demangler D;
- if (!initializeOutputBuffer(nullptr, nullptr, D.Output, 1024))
- return nullptr;
-
if (!D.demangle(Mangled)) {
std::free(D.Output.getBuffer());
return nullptr;