summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangle.cpp83
-rw-r--r--llvm/test/Demangle/ms-arg-qualifiers.test22
-rw-r--r--llvm/test/Demangle/ms-basic.test8
-rw-r--r--llvm/test/Demangle/ms-mangle.test36
4 files changed, 81 insertions, 68 deletions
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index 86a95892edb..7d95dedafaa 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -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 &Arena) const {
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(OutputStream &OS) {
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(OutputStream &OS) {
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::demangleThrowSpecification() {
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::demangleFunctionEncoding() {
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::demanglePointerType() {
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::demangleMemberPointerType() {
if (MangledName.consumeFront("8")) {
Pointer->MemberName = demangleName();
- Pointer->Pointee = demangleFunctionType(true);
+ Pointer->Pointee = demangleFunctionType(true, true);
} else {
Qualifiers PointeeQuals = Q_None;
bool IsMember = false;
diff --git a/llvm/test/Demangle/ms-arg-qualifiers.test b/llvm/test/Demangle/ms-arg-qualifiers.test
index cf83ab02119..bbbca387fb3 100644
--- a/llvm/test/Demangle/ms-arg-qualifiers.test
+++ b/llvm/test/Demangle/ms-arg-qualifiers.test
@@ -137,16 +137,16 @@
?foo_p6ahxz@@YAXP6AHXZ@Z
?foo_p6ahxz@@YAXP6AHXZ@Z
-; CHECK: void __cdecl foo_p6ahxz(int __cdecl (*)(void))
+; CHECK: void __cdecl foo_p6ahxz(int (__cdecl *)(void))
?foo_a6ahxz@@YAXA6AHXZ@Z
?foo_a6ahxz@@YAXA6AHXZ@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@Z
; ?foo_q6ahxz@@YAX$$Q6AHXZ@Z
-; FIXME: void __cdecl foo_q6ahxz(int __cdecl (&&)(void))
+; FIXME: void __cdecl foo_q6ahxz(int (__cdecl &&)(void))
?foo_qay04h@@YAXQAY04H@Z
?foo_qay04h@@YAXQEAY04H@Z
@@ -178,19 +178,19 @@
?foo_fnptrconst@@YAXP6AXQAH@Z@Z
?foo_fnptrconst@@YAXP6AXQEAH@Z@Z
-; CHECK: void __cdecl foo_fnptrconst(void __cdecl (*)(int *const))
+; CHECK: void __cdecl foo_fnptrconst(void (__cdecl *)(int *const))
?foo_fnptrarray@@YAXP6AXQAH@Z@Z
?foo_fnptrarray@@YAXP6AXQEAH@Z@Z
-; CHECK: void __cdecl foo_fnptrarray(void __cdecl (*)(int *const))
+; CHECK: void __cdecl foo_fnptrarray(void (__cdecl *)(int *const))
; ?foo_fnptrbackref1@@YAXP6AXQAH@Z1@Z
; ?foo_fnptrbackref1@@YAXP6AXQEAH@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@Z1@Z
; ?foo_fnptrbackref2@@YAXP6AXQEAH@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@Z1@Z
; ?foo_fnptrbackref3@@YAXP6AXQEAH@Z1@Z
@@ -202,7 +202,7 @@
?ret_fnptrarray@@YAP6AXQAH@ZXZ
?ret_fnptrarray@@YAP6AXQEAH@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@Z
?mangle_no_backref2@@YAXP6AXXZP6AXXZ@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@Z
?mangle_yes_backref0@@YAXQEAH0@Z
@@ -229,11 +229,11 @@
?mangle_yes_backref2@@YAXQBQ6AXXZ0@Z
?mangle_yes_backref2@@YAXQEBQ6AXXZ0@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@Z
?mangle_yes_backref3@@YAXQEAP6AXXZ0@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@Z
?mangle_yes_backref4@@YAXQEIAH0@Z
diff --git a/llvm/test/Demangle/ms-basic.test b/llvm/test/Demangle/ms-basic.test
index 2811017a88e..972a8b7749a 100644
--- a/llvm/test/Demangle/ms-basic.test
+++ b/llvm/test/Demangle/ms-basic.test
@@ -30,13 +30,13 @@
; CHECK: void __cdecl x(float, int)
?x@@3P6AHMNH@ZEA
-; CHECK: int __cdecl (*x)(float, double, int)
+; CHECK: int (__cdecl *x)(float, double, int)
?x@@3P6AHP6AHM@ZN@ZEA
-; CHECK: int __cdecl (*x)(int __cdecl (*)(float), double)
+; CHECK: int (__cdecl *x)(int (__cdecl *)(float), double)
?x@@3P6AHP6AHM@Z0@ZEA
-; CHECK: int __cdecl (*x)(int __cdecl (*)(float), int __cdecl (*)(float))
+; CHECK: int (__cdecl *x)(int (__cdecl *)(float), int (__cdecl *)(float))
?x@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@XZ
; CHECK: __cdecl klass::klass(void)
diff --git a/llvm/test/Demangle/ms-mangle.test b/llvm/test/Demangle/ms-mangle.test
index ae251d0952b..a5d0c70ee31 100644
--- a/llvm/test/Demangle/ms-mangle.test
+++ b/llvm/test/Demangle/ms-mangle.test
@@ -91,13 +91,13 @@
; CHECK: int (*i)[20]
?FunArr@@3PAY0BE@P6AHHH@ZA
-; CHECK: int __cdecl (*(*FunArr)[20])(int, int)
+; CHECK: int (__cdecl *(*FunArr)[20])(int, int)
?j@@3P6GHCE@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@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@Z@Z
-; CHECK: void __cdecl zeta(int __cdecl (*)(int, int))
+; CHECK: void __cdecl zeta(int (__cdecl *)(int, int))
?zeta@@YAXP6AHHH@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
OpenPOWER on IntegriCloud