[demangler] Add StringView conversion operator
authorNathan Sidwell <nathan@acm.org>
Tue, 1 Mar 2022 16:36:24 +0000 (08:36 -0800)
committerNathan Sidwell <nathan@acm.org>
Mon, 28 Mar 2022 18:19:55 +0000 (11:19 -0700)
The OutputBuffer class tries to present a NUL-terminated string API to
consumers.  But several of them would prefer a StringView.  In
particular the Microsoft demangler, juggles between NUL-terminated and
StringView, which is confusing.

This adds a StringView conversion, and adjusts the Demanglers that can
benefit from that.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D120990

libcxxabi/src/demangle/Utility.h
llvm/include/llvm/Demangle/Utility.h
llvm/lib/Demangle/MicrosoftDemangle.cpp
llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
llvm/unittests/Demangle/ItaniumDemangleTest.cpp
llvm/unittests/Demangle/OutputBufferTest.cpp

index 7633085..1390f14 100644 (file)
@@ -75,6 +75,8 @@ public:
   OutputBuffer(const OutputBuffer &) = delete;
   OutputBuffer &operator=(const OutputBuffer &) = delete;
 
+  operator StringView() const { return StringView(Buffer, CurrentPosition); }
+
   void reset(char *Buffer_, size_t BufferCapacity_) {
     CurrentPosition = 0;
     Buffer = Buffer_;
index 844b636..3ea92c9 100644 (file)
@@ -75,6 +75,8 @@ public:
   OutputBuffer(const OutputBuffer &) = delete;
   OutputBuffer &operator=(const OutputBuffer &) = delete;
 
+  operator StringView() const { return StringView(Buffer, CurrentPosition); }
+
   void reset(char *Buffer_, size_t BufferCapacity_) {
     CurrentPosition = 0;
     Buffer = Buffer_;
index a009bef..aca8cf7 100644 (file)
@@ -970,12 +970,9 @@ void Demangler::memorizeIdentifier(IdentifierNode *Identifier) {
     // FIXME: Propagate out-of-memory as an error?
     std::terminate();
   Identifier->output(OB, OF_Default);
-  OB << '\0';
-  char *Name = OB.getBuffer();
-
-  StringView Owned = copyString(Name);
+  StringView Owned = copyString(OB);
   memorizeString(Owned);
-  std::free(Name);
+  std::free(OB.getBuffer());
 }
 
 IdentifierNode *
@@ -1279,7 +1276,6 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
   bool IsWcharT = false;
   bool IsNegative = false;
   size_t CrcEndPos = 0;
-  char *ResultBuffer = nullptr;
 
   EncodedStringLiteralNode *Result = Arena.alloc<EncodedStringLiteralNode>();
 
@@ -1375,10 +1371,8 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
     }
   }
 
-  OB << '\0';
-  ResultBuffer = OB.getBuffer();
-  Result->DecodedString = copyString(ResultBuffer);
-  std::free(ResultBuffer);
+  Result->DecodedString = copyString(OB);
+  std::free(OB.getBuffer());
   return Result;
 
 StringLiteralError:
@@ -1455,10 +1449,9 @@ Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
   Scope->output(OB, OF_Default);
   OB << '\'';
   OB << "::`" << Number << "'";
-  OB << '\0';
-  char *Result = OB.getBuffer();
-  Identifier->Name = copyString(Result);
-  std::free(Result);
+
+  Identifier->Name = copyString(OB);
+  std::free(OB.getBuffer());
   return Identifier;
 }
 
@@ -2322,8 +2315,8 @@ void Demangler::dumpBackReferences() {
     TypeNode *T = Backrefs.FunctionParams[I];
     T->output(OB, OF_Default);
 
-    std::printf("  [%d] - %.*s\n", (int)I, (int)OB.getCurrentPosition(),
-                OB.getBuffer());
+    StringView B = OB;
+    std::printf("  [%d] - %.*s\n", (int)I, (int)B.size(), B.begin());
   }
   std::free(OB.getBuffer());
 
index d07d05a..494cdab 100644 (file)
@@ -121,8 +121,8 @@ std::string Node::toString(OutputFlags Flags) const {
   OutputBuffer OB;
   initializeOutputBuffer(nullptr, nullptr, OB, 1024);
   this->output(OB, Flags);
-  OB << '\0';
-  std::string Owned(OB.getBuffer());
+  StringView SV = OB;
+  std::string Owned(SV.begin(), SV.end());
   std::free(OB.getBuffer());
   return Owned;
 }
index 5a059c0..9d9f683 100644 (file)
@@ -53,7 +53,8 @@ TEST(ItaniumDemangle, MethodOverride) {
 }
 
 static std::string toString(OutputBuffer &OB) {
-  return {OB.getBuffer(), OB.getCurrentPosition()};
+  StringView SV = OB;
+  return {SV.begin(), SV.end()};
 }
 
 TEST(ItaniumDemangle, HalfType) {
index 9fc572b..829169b 100644 (file)
@@ -15,7 +15,8 @@ using namespace llvm;
 using llvm::itanium_demangle::OutputBuffer;
 
 static std::string toString(OutputBuffer &OB) {
-  return {OB.getBuffer(), OB.getCurrentPosition()};
+  StringView SV = OB;
+  return {SV.begin(), SV.end()};
 }
 
 template <typename T> static std::string printToString(const T &Value) {