diff options
| author | Zachary Turner <zturner@google.com> | 2018-08-10 15:04:56 +0000 |
|---|---|---|
| committer | Zachary Turner <zturner@google.com> | 2018-08-10 15:04:56 +0000 |
| commit | a17721cf5d6951662801b6cf218d63bc481fa245 (patch) | |
| tree | 1e731d71ebef577c95600dfdb8e05793ac580370 /llvm | |
| parent | e89f2fa65703f1a497d7e9b20dc470467cee66ed (diff) | |
| download | bcm5719-llvm-a17721cf5d6951662801b6cf218d63bc481fa245.tar.gz bcm5719-llvm-a17721cf5d6951662801b6cf218d63bc481fa245.zip | |
[MS Demangler] Properly demangle conversion operators.
These were completely broken before. We need to handle
the 'B' operator tag.
llvm-svn: 339436
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Demangle/MicrosoftDemangle.cpp | 64 | ||||
| -rw-r--r-- | llvm/test/Demangle/ms-conversion-operators.test | 21 |
2 files changed, 65 insertions, 20 deletions
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp index fd64edbb9e0..13f2a2c02e1 100644 --- a/llvm/lib/Demangle/MicrosoftDemangle.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp @@ -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(OutputStream &OS, const FunctionParams &Params, } } -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(OutputStream &OS, const TemplateParams &Params, 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(OutputStream &OS, const TemplateParams &Params, 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(OutputStream &OS, const TemplateParams &Params, 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, const Name *TheName, 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(OutputStream &OS, PointerAffinity Affinity, } if (MemberName) { - outputName(OS, MemberName, Resolver); + outputName(OS, MemberName, Pointee, Resolver); OS << "::"; } @@ -872,7 +891,7 @@ void UdtType::outputPre(OutputStream &OS, NameResolver &Resolver) { 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::demangleTemplateInstantiationName(StringView &MangledName, // 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(StringView &MangledName) { }; 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, OutputStream &OS) { // "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); } diff --git a/llvm/test/Demangle/ms-conversion-operators.test b/llvm/test/Demangle/ms-conversion-operators.test new file mode 100644 index 00000000000..afc34aab4fa --- /dev/null +++ b/llvm/test/Demangle/ms-conversion-operators.test @@ -0,0 +1,21 @@ +; RUN: llvm-undname < %s | FileCheck %s + +; CHECK-NOT: Invalid mangled name + +??$?BH@TemplateOps@@QAEHXZ +??BOps@@QAEHXZ +??BConstOps@@QAE?BHXZ +??BVolatileOps@@QAE?CHXZ +??BConstVolatileOps@@QAE?DHXZ +??$?BN@TemplateOps@@QAENXZ +??BOps@@QAENXZ +??BConstOps@@QAE?BNXZ +??BVolatileOps@@QAE?CNXZ +??BConstVolatileOps@@QAE?DNXZ +??BCompoundTypeOps@@QAEPAHXZ +??BCompoundTypeOps@@QAEPBHXZ +??BCompoundTypeOps@@QAE$$QAHXZ +??BCompoundTypeOps@@QAE?AU?$Foo@H@@XZ +??$?BH@CompoundTypeOps@@QAE?AU?$Bar@U?$Foo@H@@@@XZ +??$?BPAH@TemplateOps@@QAEPAHXZ + |

