[llvm] r338068 - [MS Demangler] Print calling convention inside parentheses.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 26 13:33:49 PDT 2018


Author: zturner
Date: Thu Jul 26 13:33:48 2018
New Revision: 338068

URL: http://llvm.org/viewvc/llvm-project?rev=338068&view=rev
Log:
[MS Demangler] Print calling convention inside parentheses.

For function pointers, we would print something like

int __cdecl (*)(int)

We need to move the calling convention inside, and print

int (__cdecl *)(int)

This patch implements this change for regular function pointers as
well as member function pointers.

Modified:
    llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp
    llvm/trunk/test/Demangle/ms-arg-qualifiers.test
    llvm/trunk/test/Demangle/ms-basic.test
    llvm/trunk/test/Demangle/ms-mangle.test

Modified: llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp?rev=338068&r1=338067&r2=338068&view=diff
==============================================================================
--- llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp (original)
+++ llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp Thu Jul 26 13:33:48 2018
@@ -265,6 +265,10 @@ struct FunctionType : public Type {
   void outputPre(OutputStream &OS) override;
   void outputPost(OutputStream &OS) override;
 
+  // True if this FunctionType instance is the Pointee of a PointerType or
+  // MemberPointerType.
+  bool IsFunctionPointer = false;
+
   Type *ReturnType = nullptr;
   // If this is a reference, the type of reference.
   ReferenceKind RefKind;
@@ -556,25 +560,46 @@ Type *PointerType::clone(ArenaAllocator
   return Arena.alloc<PointerType>(*this);
 }
 
-void PointerType::outputPre(OutputStream &OS) {
-  Type::outputPre(OS, *Pointee);
-
-  outputSpaceIfNecessary(OS);
-
-  if (Quals & Q_Unaligned)
-    OS << "__unaligned ";
-
+static void outputPointerIndicator(OutputStream &OS, PointerAffinity Affinity,
+                                   const Name *MemberName,
+                                   const Type *Pointee) {
   // "[]" and "()" (for function parameters) take precedence over "*",
   // so "int *x(int)" means "x is a function returning int *". We need
   // parentheses to supercede the default precedence. (e.g. we want to
   // emit something like "int (*x)(int)".)
-  if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
+  if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array) {
     OS << "(";
+    if (Pointee->Prim == PrimTy::Function) {
+      const FunctionType *FTy = static_cast<const FunctionType *>(Pointee);
+      assert(FTy->IsFunctionPointer);
+      outputCallingConvention(OS, FTy->CallConvention);
+      OS << " ";
+    }
+  }
 
-  if (Prim == PrimTy::Ptr)
+  if (MemberName) {
+    outputName(OS, MemberName);
+    OS << "::";
+  }
+
+  if (Affinity == PointerAffinity::Pointer)
     OS << "*";
   else
     OS << "&";
+}
+
+void PointerType::outputPre(OutputStream &OS) {
+  Type::outputPre(OS, *Pointee);
+
+  outputSpaceIfNecessary(OS);
+
+  if (Quals & Q_Unaligned)
+    OS << "__unaligned ";
+
+  PointerAffinity Affinity = (Prim == PrimTy::Ptr) ? PointerAffinity::Pointer
+                                                   : PointerAffinity::Reference;
+
+  outputPointerIndicator(OS, Affinity, nullptr, Pointee);
 
   // FIXME: We should output this, but it requires updating lots of tests.
   // if (Ty.Quals & Q_Pointer64)
@@ -597,15 +622,7 @@ void MemberPointerType::outputPre(Output
 
   outputSpaceIfNecessary(OS);
 
-  // "[]" and "()" (for function parameters) take precedence over "*",
-  // so "int *x(int)" means "x is a function returning int *". We need
-  // parentheses to supercede the default precedence. (e.g. we want to
-  // emit something like "int (*x)(int)".)
-  if (Pointee->Prim == PrimTy::Function || Pointee->Prim == PrimTy::Array)
-    OS << "(";
-
-  outputName(OS, MemberName);
-  OS << "::*";
+  outputPointerIndicator(OS, PointerAffinity::Pointer, MemberName, Pointee);
 
   // FIXME: We should output this, but it requires updating lots of tests.
   // if (Ty.Quals & Q_Pointer64)
@@ -636,7 +653,11 @@ void FunctionType::outputPre(OutputStrea
     OS << " ";
   }
 
-  outputCallingConvention(OS, CallConvention);
+  // Function pointers print the calling convention as void (__cdecl *)(params)
+  // rather than void __cdecl (*)(params).  So we need to let the PointerType
+  // class handle this.
+  if (!IsFunctionPointer)
+    outputCallingConvention(OS, CallConvention);
 }
 
 void FunctionType::outputPost(OutputStream &OS) {
@@ -726,7 +747,7 @@ private:
   UdtType *demangleClassType();
   PointerType *demanglePointerType();
   MemberPointerType *demangleMemberPointerType();
-  FunctionType *demangleFunctionType(bool HasThisQuals);
+  FunctionType *demangleFunctionType(bool HasThisQuals, bool IsFunctionPointer);
 
   ArrayType *demangleArrayType();
 
@@ -1269,9 +1290,11 @@ void Demangler::demangleThrowSpecificati
   Error = true;
 }
 
-FunctionType *Demangler::demangleFunctionType(bool HasThisQuals) {
+FunctionType *Demangler::demangleFunctionType(bool HasThisQuals,
+                                              bool IsFunctionPointer) {
   FunctionType *FTy = Arena.alloc<FunctionType>();
   FTy->Prim = PrimTy::Function;
+  FTy->IsFunctionPointer = IsFunctionPointer;
 
   if (HasThisQuals) {
     FTy->Quals = demanglePointerExtQualifiers();
@@ -1299,7 +1322,7 @@ Type *Demangler::demangleFunctionEncodin
   FuncClass FC = demangleFunctionClass();
 
   bool HasThisQuals = !(FC & (Global | Static));
-  FunctionType *FTy = demangleFunctionType(HasThisQuals);
+  FunctionType *FTy = demangleFunctionType(HasThisQuals, false);
   FTy->FunctionClass = FC;
 
   return FTy;
@@ -1435,17 +1458,7 @@ PointerType *Demangler::demanglePointerT
   Pointer->Prim =
       (Affinity == PointerAffinity::Pointer) ? PrimTy::Ptr : PrimTy::Ref;
   if (MangledName.consumeFront("6")) {
-    FunctionType *FTy = Arena.alloc<FunctionType>();
-    FTy->Prim = PrimTy::Function;
-    FTy->CallConvention = demangleCallingConvention();
-
-    FTy->ReturnType = demangleType(QualifierMangleMode::Drop);
-    FTy->Params = demangleParameterList();
-
-    if (!MangledName.consumeFront("@Z"))
-      MangledName.consumeFront("Z");
-
-    Pointer->Pointee = FTy;
+    Pointer->Pointee = demangleFunctionType(false, true);
     return Pointer;
   }
 
@@ -1469,7 +1482,7 @@ MemberPointerType *Demangler::demangleMe
 
   if (MangledName.consumeFront("8")) {
     Pointer->MemberName = demangleName();
-    Pointer->Pointee = demangleFunctionType(true);
+    Pointer->Pointee = demangleFunctionType(true, true);
   } else {
     Qualifiers PointeeQuals = Q_None;
     bool IsMember = false;

Modified: llvm/trunk/test/Demangle/ms-arg-qualifiers.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Demangle/ms-arg-qualifiers.test?rev=338068&r1=338067&r2=338068&view=diff
==============================================================================
--- llvm/trunk/test/Demangle/ms-arg-qualifiers.test (original)
+++ llvm/trunk/test/Demangle/ms-arg-qualifiers.test Thu Jul 26 13:33:48 2018
@@ -137,16 +137,16 @@
 
 ?foo_p6ahxz@@YAXP6AHXZ at Z
 ?foo_p6ahxz@@YAXP6AHXZ at Z
-; CHECK: void __cdecl foo_p6ahxz(int __cdecl (*)(void))
+; CHECK: void __cdecl foo_p6ahxz(int (__cdecl *)(void))
 
 ?foo_a6ahxz@@YAXA6AHXZ at Z
 ?foo_a6ahxz@@YAXA6AHXZ at Z
-; CHECK: void __cdecl foo_a6ahxz(int __cdecl (&)(void))
+; CHECK: void __cdecl foo_a6ahxz(int (__cdecl &)(void))
 
 ; FIXME: We don't support rvalue references yet
 ; ?foo_q6ahxz@@YAX$$Q6AHXZ at Z
 ; ?foo_q6ahxz@@YAX$$Q6AHXZ at Z
-; FIXME: void __cdecl foo_q6ahxz(int __cdecl (&&)(void))
+; FIXME: void __cdecl foo_q6ahxz(int (__cdecl &&)(void))
 
 ?foo_qay04h@@YAXQAY04H at Z
 ?foo_qay04h@@YAXQEAY04H at Z
@@ -178,19 +178,19 @@
 
 ?foo_fnptrconst@@YAXP6AXQAH at Z@Z
 ?foo_fnptrconst@@YAXP6AXQEAH at Z@Z
-; CHECK: void __cdecl foo_fnptrconst(void __cdecl (*)(int *const))
+; CHECK: void __cdecl foo_fnptrconst(void (__cdecl *)(int *const))
 
 ?foo_fnptrarray@@YAXP6AXQAH at Z@Z
 ?foo_fnptrarray@@YAXP6AXQEAH at Z@Z
-; CHECK: void __cdecl foo_fnptrarray(void __cdecl (*)(int *const))
+; CHECK: void __cdecl foo_fnptrarray(void (__cdecl *)(int *const))
 
 ; ?foo_fnptrbackref1@@YAXP6AXQAH at Z1@Z
 ; ?foo_fnptrbackref1@@YAXP6AXQEAH at Z1@Z
-; FIXME: void __cdecl foo_fnptrbackref1(void __cdecl (*)(int *const), void __cdecl (*)(int *const))
+; FIXME: void __cdecl foo_fnptrbackref1(void (__cdecl *)(int *const), void (__cdecl *)(int *const))
 
 ; ?foo_fnptrbackref2@@YAXP6AXQAH at Z1@Z
 ; ?foo_fnptrbackref2@@YAXP6AXQEAH at Z1@Z
-; FIXME: void __cdecl foo_fnptrbackref2(void __cdecl (*)(int *const), void __cdecl (*)(int *const))
+; FIXME: void __cdecl foo_fnptrbackref2(void (__cdecl *)(int *const), void (__cdecl *)(int *const))
 
 ; ?foo_fnptrbackref3@@YAXP6AXQAH at Z1@Z
 ; ?foo_fnptrbackref3@@YAXP6AXQEAH at Z1@Z
@@ -202,7 +202,7 @@
 
 ?ret_fnptrarray@@YAP6AXQAH at ZXZ
 ?ret_fnptrarray@@YAP6AXQEAH at ZXZ
-; CHECK: void __cdecl (* __cdecl ret_fnptrarray(void))(int *const)
+; CHECK: void (__cdecl * __cdecl ret_fnptrarray(void))(int *const)
 
 ; The first argument gets mangled as-if it were written int *const
 ; The second arg should not form a backref because it isn't qualified
@@ -217,7 +217,7 @@
 ; Pointer to function types don't backref with function types
 ?mangle_no_backref2@@YAXP6AXXZP6AXXZ at Z
 ?mangle_no_backref2@@YAXP6AXXZP6AXXZ at Z
-; CHECK: void __cdecl mangle_no_backref2(void __cdecl (*)(void), void __cdecl (*)(void))
+; CHECK: void __cdecl mangle_no_backref2(void (__cdecl *)(void), void (__cdecl *)(void))
 
 ?mangle_yes_backref0@@YAXQAH0 at Z
 ?mangle_yes_backref0@@YAXQEAH0 at Z
@@ -229,11 +229,11 @@
 
 ?mangle_yes_backref2@@YAXQBQ6AXXZ0 at Z
 ?mangle_yes_backref2@@YAXQEBQ6AXXZ0 at Z
-; CHECK: void __cdecl mangle_yes_backref2(void __cdecl (*const *const)(void), void __cdecl (*const *const)(void))
+; CHECK: void __cdecl mangle_yes_backref2(void (__cdecl *const *const)(void), void (__cdecl *const *const)(void))
 
 ?mangle_yes_backref3@@YAXQAP6AXXZ0 at Z
 ?mangle_yes_backref3@@YAXQEAP6AXXZ0 at Z
-; CHECK: void __cdecl mangle_yes_backref3(void __cdecl (**const)(void), void __cdecl (**const)(void))
+; CHECK: void __cdecl mangle_yes_backref3(void (__cdecl **const)(void), void (__cdecl **const)(void))
 
 ?mangle_yes_backref4@@YAXQIAH0 at Z
 ?mangle_yes_backref4@@YAXQEIAH0 at Z

Modified: llvm/trunk/test/Demangle/ms-basic.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Demangle/ms-basic.test?rev=338068&r1=338067&r2=338068&view=diff
==============================================================================
--- llvm/trunk/test/Demangle/ms-basic.test (original)
+++ llvm/trunk/test/Demangle/ms-basic.test Thu Jul 26 13:33:48 2018
@@ -30,13 +30,13 @@
 ; CHECK: void __cdecl x(float, int)
 
 ?x@@3P6AHMNH at ZEA
-; CHECK: int __cdecl (*x)(float, double, int)
+; CHECK: int (__cdecl *x)(float, double, int)
 
 ?x@@3P6AHP6AHM at ZN@ZEA
-; CHECK: int __cdecl (*x)(int __cdecl (*)(float), double)
+; CHECK: int (__cdecl *x)(int (__cdecl *)(float), double)
 
 ?x@@3P6AHP6AHM at Z0@ZEA
-; CHECK: int __cdecl (*x)(int __cdecl (*)(float), int __cdecl (*)(float))
+; CHECK: int (__cdecl *x)(int (__cdecl *)(float), int (__cdecl *)(float))
 
 ?x at ns@@3HA
 ; CHECK: int ns::x
@@ -87,7 +87,7 @@
 ; CHECK: class klass instance
 
 ?instance$initializer$@@3P6AXXZEA
-; CHECK: void __cdecl (*instance$initializer$)(void)
+; CHECK: void (__cdecl *instance$initializer$)(void)
 
 ??0klass@@QEAA at XZ
 ; CHECK: __cdecl klass::klass(void)

Modified: llvm/trunk/test/Demangle/ms-mangle.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Demangle/ms-mangle.test?rev=338068&r1=338067&r2=338068&view=diff
==============================================================================
--- llvm/trunk/test/Demangle/ms-mangle.test (original)
+++ llvm/trunk/test/Demangle/ms-mangle.test Thu Jul 26 13:33:48 2018
@@ -91,13 +91,13 @@
 ; CHECK: int (*i)[20]
 
 ?FunArr@@3PAY0BE at P6AHHH@ZA
-; CHECK: int __cdecl (*(*FunArr)[20])(int, int)
+; CHECK: int (__cdecl *(*FunArr)[20])(int, int)
 
 ?j@@3P6GHCE at ZA
-; CHECK: int __stdcall (*j)(signed char, unsigned char)
+; CHECK: int (__stdcall *j)(signed char, unsigned char)
 
 ?funptr@@YAP6AHXZXZ
-; CHECK: int __cdecl (* __cdecl funptr(void))(void)
+; CHECK: int (__cdecl * __cdecl funptr(void))(void)
 
 ?k@@3PTfoo@@DT1@
 ; CHECK: char const volatile foo::*k
@@ -106,7 +106,7 @@
 ; CHECK: char const volatile foo::*k
 
 ?l@@3P8foo@@AEHH at ZQ1@
-; CHECK: int __thiscall (foo::*l)(int)
+; CHECK: int (__thiscall foo::*l)(int)
 
 ?g_cInt@@3HB
 ; CHECK: int const g_cInt
@@ -148,10 +148,10 @@
 ; CHECK: void __cdecl epsilon(int (*const)[10][20])
 
 ?zeta@@YAXP6AHHH at Z@Z
-; CHECK: void __cdecl zeta(int __cdecl (*)(int, int))
+; CHECK: void __cdecl zeta(int (__cdecl *)(int, int))
 
 ?zeta@@YAXP6AHHH at Z@Z
-; CHECK: void __cdecl zeta(int __cdecl (*)(int, int))
+; CHECK: void __cdecl zeta(int (__cdecl *)(int, int))
 
 ; FIXME: We don't support blocks yet.
 
@@ -195,40 +195,40 @@
 ; CHECK: int B::*volatile memptr3
 
 ?funmemptr1@@3RESB@@R6AHXZES1@
-; CHECK: int __cdecl (*volatile B::*volatile funmemptr1)(void)
+; CHECK: int (__cdecl *volatile B::*volatile funmemptr1)(void)
 
 ?funmemptr2@@3PESB@@R6AHXZES1@
-; CHECK: int __cdecl (*volatile B::*funmemptr2)(void)
+; CHECK: int (__cdecl *volatile B::*funmemptr2)(void)
 
 ?funmemptr3@@3REQB@@P6AHXZEQ1@
-; CHECK: int __cdecl (*B::*volatile funmemptr3)(void)
+; CHECK: int (__cdecl *B::*volatile funmemptr3)(void)
 
 ?memptrtofun1@@3R8B@@EAAXXZEQ1@
-; CHECK: void __cdecl (B::*volatile memptrtofun1)(void)
+; CHECK: void (__cdecl B::*volatile memptrtofun1)(void)
 
 ?memptrtofun2@@3P8B@@EAAXXZEQ1@
-; CHECK: void __cdecl (B::*memptrtofun2)(void)
+; CHECK: void (__cdecl B::*memptrtofun2)(void)
 
 ?memptrtofun3@@3P8B@@EAAXXZEQ1@
-; CHECK: void __cdecl (B::*memptrtofun3)(void)
+; CHECK: void (__cdecl B::*memptrtofun3)(void)
 
 ?memptrtofun4@@3R8B@@EAAHXZEQ1@
-; CHECK: int __cdecl (B::*volatile memptrtofun4)(void)
+; CHECK: int (__cdecl B::*volatile memptrtofun4)(void)
 
 ?memptrtofun5@@3P8B@@EAA?CHXZEQ1@
-; CHECK: int volatile __cdecl (B::*memptrtofun5)(void)
+; CHECK: int volatile (__cdecl B::*memptrtofun5)(void)
 
 ?memptrtofun6@@3P8B@@EAA?BHXZEQ1@
-; CHECK: int const __cdecl (B::*memptrtofun6)(void)
+; CHECK: int const (__cdecl B::*memptrtofun6)(void)
 
 ?memptrtofun7@@3R8B@@EAAP6AHXZXZEQ1@
-; CHECK: int __cdecl (* __cdecl (B::*volatile memptrtofun7)(void))(void)
+; CHECK: int (__cdecl * (__cdecl B::*volatile memptrtofun7)(void))(void)
 
 ?memptrtofun8@@3P8B@@EAAR6AHXZXZEQ1@
-; CHECK: int __cdecl (*volatile __cdecl (B::*memptrtofun8)(void))(void)
+; CHECK: int (__cdecl *volatile (__cdecl B::*memptrtofun8)(void))(void)
 
 ?memptrtofun9@@3P8B@@EAAQ6AHXZXZEQ1@
-; CHECK: int __cdecl (*const __cdecl (B::*memptrtofun9)(void))(void)
+; CHECK: int (__cdecl *const (__cdecl B::*memptrtofun9)(void))(void)
 
 
 ?fooE@@YA?AW4E@@XZ




More information about the llvm-commits mailing list