Index: llvm/trunk/include/llvm/Demangle/Utility.h =================================================================== --- llvm/trunk/include/llvm/Demangle/Utility.h +++ llvm/trunk/include/llvm/Demangle/Utility.h @@ -70,22 +70,6 @@ BufferCapacity = BufferCapacity_; } - /// Create an OutputStream from a buffer and a size. If either of these are - /// null a buffer is allocated. - static OutputStream create(char *StartBuf, size_t *Size, size_t AllocSize) { - OutputStream Result; - - if (!StartBuf || !Size) { - StartBuf = static_cast(std::malloc(AllocSize)); - if (StartBuf == nullptr) - std::terminate(); - Size = &AllocSize; - } - - Result.reset(StartBuf, *Size); - return Result; - } - /// If a ParameterPackExpansion (or similar type) is encountered, the offset /// into the pack that we're currently printing. unsigned CurrentPackIndex = std::numeric_limits::max(); @@ -185,4 +169,19 @@ SwapAndRestore &operator=(const SwapAndRestore &) = delete; }; +inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S, + size_t InitSize) { + size_t BufferSize; + if (Buf == nullptr) { + Buf = static_cast(std::malloc(InitSize)); + if (Buf == nullptr) + return true; + BufferSize = InitSize; + } else + BufferSize = *N; + + S.reset(Buf, BufferSize); + return false; +} + #endif Index: llvm/trunk/lib/Demangle/ItaniumDemangle.cpp =================================================================== --- llvm/trunk/lib/Demangle/ItaniumDemangle.cpp +++ llvm/trunk/lib/Demangle/ItaniumDemangle.cpp @@ -310,21 +310,6 @@ return Alloc.allocate(sizeof(Node *) * sz); } }; - -bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S, - size_t InitSize) { - size_t BufferSize; - if (Buf == nullptr) { - Buf = static_cast(std::malloc(InitSize)); - if (Buf == nullptr) - return true; - BufferSize = InitSize; - } else - BufferSize = *N; - - S.reset(Buf, BufferSize); - return false; -} } // unnamed namespace //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp =================================================================== --- llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp +++ llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp @@ -1016,7 +1016,10 @@ void Demangler::memorizeIdentifier(IdentifierNode *Identifier) { // Render this class template name into a string buffer so that we can // memorize it for the purpose of back-referencing. - OutputStream OS = OutputStream::create(nullptr, nullptr, 1024); + OutputStream OS; + if (initializeOutputStream(nullptr, nullptr, OS, 1024)) + // FIXME: Propagate out-of-memory as an error? + std::terminate(); Identifier->output(OS, OF_Default); OS << '\0'; char *Name = OS.getBuffer(); @@ -1346,7 +1349,9 @@ if (MangledName.empty()) goto StringLiteralError; - OS = OutputStream::create(nullptr, nullptr, 1024); + if (initializeOutputStream(nullptr, nullptr, OS, 1024)) + // FIXME: Propagate out-of-memory as an error? + std::terminate(); if (IsWcharT) { Result->Char = CharKind::Wchar; if (StringByteSize > 64) @@ -1466,7 +1471,10 @@ return nullptr; // Render the parent symbol's name into a buffer. - OutputStream OS = OutputStream::create(nullptr, nullptr, 1024); + OutputStream OS; + if (initializeOutputStream(nullptr, nullptr, OS, 1024)) + // FIXME: Propagate out-of-memory as an error? + std::terminate(); OS << '`'; Scope->output(OS, OF_Default); OS << '\''; @@ -2289,7 +2297,9 @@ (int)Backrefs.FunctionParamCount); // Create an output stream so we can render each type. - OutputStream OS = OutputStream::create(nullptr, 0, 1024); + OutputStream OS; + if (initializeOutputStream(nullptr, nullptr, OS, 1024)) + std::terminate(); for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) { OS.setCurrentPosition(0); @@ -2314,21 +2324,29 @@ char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N, int *Status, MSDemangleFlags Flags) { + int InternalStatus = demangle_success; Demangler D; + OutputStream S; + StringView Name{MangledName}; - SymbolNode *S = D.parse(Name); + SymbolNode *AST = D.parse(Name); if (Flags & MSDF_DumpBackrefs) D.dumpBackReferences(); - OutputStream OS = OutputStream::create(Buf, N, 1024); - if (D.Error) { - OS << MangledName; - *Status = llvm::demangle_invalid_mangled_name; - } else { - S->output(OS, OF_Default); - *Status = llvm::demangle_success; + + if (D.Error) + InternalStatus = demangle_invalid_mangled_name; + else if (initializeOutputStream(Buf, N, S, 1024)) + InternalStatus = demangle_memory_alloc_failure; + else { + AST->output(S, OF_Default); + S += '\0'; + if (N != nullptr) + *N = S.getCurrentPosition(); + Buf = S.getBuffer(); } - OS << '\0'; - return OS.getBuffer(); + if (Status) + *Status = InternalStatus; + return InternalStatus == demangle_success ? Buf : nullptr; }