[llvm] r339436 - [MS Demangler] Properly demangle conversion operators.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 10 08:04:56 PDT 2018


Author: zturner
Date: Fri Aug 10 08:04:56 2018
New Revision: 339436

URL: http://llvm.org/viewvc/llvm-project?rev=339436&view=rev
Log:
[MS Demangler] Properly demangle conversion operators.

These were completely broken before.  We need to handle
the 'B' operator tag.

Added:
    llvm/trunk/test/Demangle/ms-conversion-operators.test
Modified:
    llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp

Modified: llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp?rev=339436&r1=339435&r2=339436&view=diff
==============================================================================
--- llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp (original)
+++ llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp Fri Aug 10 08:04:56 2018
@@ -285,12 +285,13 @@ struct Type {
 
 // Represents an identifier which may be a template.
 struct Name {
-  // Name read from an MangledName string.
-  StringView Str;
-
   bool IsTemplateInstantiation = false;
   bool IsOperator = false;
   bool IsBackReference = false;
+  bool IsConversionOperator = false;
+
+  // Name read from an MangledName string.
+  StringView Str;
 
   // Template parameters. Only valid if Flags contains NF_TemplateInstantiation.
   TemplateParams *TParams = nullptr;
@@ -518,7 +519,7 @@ static void outputParameterList(OutputSt
   }
 }
 
-static void outputName(OutputStream &OS, const Name *TheName,
+static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty,
                        NameResolver &Resolver);
 
 static void outputParameterList(OutputStream &OS, const TemplateParams &Params,
@@ -542,7 +543,7 @@ static void outputParameterList(OutputSt
       if (Head->PointerToSymbol)
         OS << "&";
       Type::outputPre(OS, *Head->ParamType, Resolver);
-      outputName(OS, Head->ParamName, Resolver);
+      outputName(OS, Head->ParamName, Head->ParamType, Resolver);
       Type::outputPost(OS, *Head->ParamType, Resolver);
     } else if (Head->ParamType) {
       // simple type.
@@ -550,7 +551,7 @@ static void outputParameterList(OutputSt
       Type::outputPost(OS, *Head->ParamType, Resolver);
     } else {
       // Template alias.
-      outputName(OS, Head->ParamName, Resolver);
+      outputName(OS, Head->ParamName, Head->ParamType, Resolver);
     }
 
     Head = Head->Next;
@@ -563,17 +564,21 @@ static void outputParameterList(OutputSt
 
 static void outputNameComponent(OutputStream &OS, const Name &N,
                                 NameResolver &Resolver) {
-  StringView S = N.Str;
+  if (N.IsConversionOperator) {
+    OS << " conv";
+  } else {
+    StringView S = N.Str;
 
-  if (N.IsBackReference)
-    S = Resolver.resolve(N.Str);
-  OS << S;
+    if (N.IsBackReference)
+      S = Resolver.resolve(N.Str);
+    OS << S;
+  }
 
-  if (N.IsTemplateInstantiation)
+  if (N.IsTemplateInstantiation && N.TParams)
     outputParameterList(OS, *N.TParams, Resolver);
 }
 
-static void outputName(OutputStream &OS, const Name *TheName,
+static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty,
                        NameResolver &Resolver) {
   if (!TheName)
     return;
@@ -603,9 +608,23 @@ static void outputName(OutputStream &OS,
     return;
   }
 
-  // Print out an overloaded operator.
-  OS << "operator";
-  outputNameComponent(OS, *TheName, Resolver);
+  if (TheName->IsConversionOperator) {
+    OS << "operator";
+    if (TheName->IsTemplateInstantiation && TheName->TParams)
+      outputParameterList(OS, *TheName->TParams, Resolver);
+    OS << " ";
+    if (Ty) {
+      const FunctionType *FTy = static_cast<const FunctionType *>(Ty);
+      Type::outputPre(OS, *FTy->ReturnType, Resolver);
+      Type::outputPost(OS, *FTy->ReturnType, Resolver);
+    } else {
+      OS << "<conversion>";
+    }
+  } else {
+    // Print out an overloaded operator.
+    OS << "operator";
+    outputNameComponent(OS, *TheName, Resolver);
+  }
 }
 
 namespace {
@@ -745,7 +764,7 @@ static void outputPointerIndicator(Outpu
   }
 
   if (MemberName) {
-    outputName(OS, MemberName, Resolver);
+    outputName(OS, MemberName, Pointee, Resolver);
     OS << "::";
   }
 
@@ -872,7 +891,7 @@ void UdtType::outputPre(OutputStream &OS
     assert(false && "Not a udt type!");
   }
 
-  outputName(OS, UdtName, Resolver);
+  outputName(OS, UdtName, this, Resolver);
 }
 
 Type *ArrayType::clone(ArenaAllocator &Arena) const {
@@ -1181,7 +1200,7 @@ Name *Demangler::demangleTemplateInstant
     // 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);
-    outputName(OS, Node, *this);
+    outputName(OS, Node, nullptr, *this);
     OS << '\0';
     char *Name = OS.getBuffer();
 
@@ -1316,7 +1335,12 @@ Name *Demangler::demangleOperatorName(St
   };
 
   Name *Node = Arena.alloc<Name>();
-  Node->Str = NameString();
+  if (MangledName.consumeFront('B')) {
+    // Handle conversion operator specially.
+    Node->IsConversionOperator = true;
+  } else {
+    Node->Str = NameString();
+  }
   Node->IsOperator = true;
   return Node;
 }
@@ -2148,7 +2172,7 @@ void Demangler::output(const Symbol *S,
   // "second half". For example, outputPre() writes a return type for a
   // function and outputPost() writes an parameter list.
   Type::outputPre(OS, *S->SymbolType, *this);
-  outputName(OS, S->SymbolName, *this);
+  outputName(OS, S->SymbolName, S->SymbolType, *this);
   Type::outputPost(OS, *S->SymbolType, *this);
 }
 

Added: llvm/trunk/test/Demangle/ms-conversion-operators.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Demangle/ms-conversion-operators.test?rev=339436&view=auto
==============================================================================
--- llvm/trunk/test/Demangle/ms-conversion-operators.test (added)
+++ llvm/trunk/test/Demangle/ms-conversion-operators.test Fri Aug 10 08:04:56 2018
@@ -0,0 +1,21 @@
+; RUN: llvm-undname < %s | FileCheck %s
+
+; CHECK-NOT: Invalid mangled name
+
+??$?BH at TemplateOps@@QAEHXZ
+??BOps@@QAEHXZ
+??BConstOps@@QAE?BHXZ
+??BVolatileOps@@QAE?CHXZ
+??BConstVolatileOps@@QAE?DHXZ
+??$?BN at TemplateOps@@QAENXZ
+??BOps@@QAENXZ
+??BConstOps@@QAE?BNXZ
+??BVolatileOps@@QAE?CNXZ
+??BConstVolatileOps@@QAE?DNXZ
+??BCompoundTypeOps@@QAEPAHXZ
+??BCompoundTypeOps@@QAEPBHXZ
+??BCompoundTypeOps@@QAE$$QAHXZ
+??BCompoundTypeOps@@QAE?AU?$Foo at H@@XZ
+??$?BH at CompoundTypeOps@@QAE?AU?$Bar at U?$Foo at H@@@@XZ
+??$?BPAH at TemplateOps@@QAEPAHXZ
+




More information about the llvm-commits mailing list