29
29
#include " clang/Basic/FileManager.h"
30
30
#include " clang/Basic/SourceManager.h"
31
31
#include " clang/Basic/TargetInfo.h"
32
+ #include " llvm/ADT/SmallVector.h"
32
33
#include " llvm/ADT/StringExtras.h"
33
34
#include " llvm/Support/CRC.h"
34
35
#include " llvm/Support/MD5.h"
35
36
#include " llvm/Support/MathExtras.h"
36
37
#include " llvm/Support/StringSaver.h"
37
38
#include " llvm/Support/xxhash.h"
39
+ #include < functional>
38
40
#include < optional>
39
41
40
42
using namespace clang ;
@@ -368,9 +370,13 @@ class MicrosoftCXXNameMangler {
368
370
void mangleVariableEncoding (const VarDecl *VD);
369
371
void mangleMemberDataPointer (const CXXRecordDecl *RD, const ValueDecl *VD,
370
372
StringRef Prefix = " $" );
373
+ void mangleMemberDataPointerInClassNTTP (const CXXRecordDecl *,
374
+ const ValueDecl *);
371
375
void mangleMemberFunctionPointer (const CXXRecordDecl *RD,
372
376
const CXXMethodDecl *MD,
373
377
StringRef Prefix = " $" );
378
+ void mangleMemberFunctionPointerInClassNTTP (const CXXRecordDecl *RD,
379
+ const CXXMethodDecl *MD);
374
380
void mangleVirtualMemPtrThunk (const CXXMethodDecl *MD,
375
381
const MethodVFTableLocation &ML);
376
382
void mangleNumber (int64_t Number);
@@ -711,6 +717,28 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD,
711
717
mangleNumber (VBTableOffset);
712
718
}
713
719
720
+ void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP (
721
+ const CXXRecordDecl *RD, const ValueDecl *VD) {
722
+ MSInheritanceModel IM = RD->getMSInheritanceModel ();
723
+ // <nttp-class-member-data-pointer> ::= <member-data-pointer>
724
+ // ::= N
725
+ // ::= 8 <postfix> @ <unqualified-name> @
726
+
727
+ if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
728
+ return mangleMemberDataPointer (RD, VD, " " );
729
+
730
+ if (!VD) {
731
+ Out << ' N' ;
732
+ return ;
733
+ }
734
+
735
+ Out << ' 8' ;
736
+ mangleNestedName (VD);
737
+ Out << ' @' ;
738
+ mangleUnqualifiedName (VD);
739
+ Out << ' @' ;
740
+ }
741
+
714
742
void
715
743
MicrosoftCXXNameMangler::mangleMemberFunctionPointer (const CXXRecordDecl *RD,
716
744
const CXXMethodDecl *MD,
@@ -775,6 +803,34 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
775
803
mangleNumber (VBTableOffset);
776
804
}
777
805
806
+ void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP (
807
+ const CXXRecordDecl *RD, const CXXMethodDecl *MD) {
808
+ // <nttp-class-member-function-pointer> ::= <member-function-pointer>
809
+ // ::= N
810
+ // ::= E? <virtual-mem-ptr-thunk>
811
+ // ::= E? <mangled-name> <type-encoding>
812
+
813
+ if (!MD) {
814
+ if (RD->getMSInheritanceModel () != MSInheritanceModel::Single)
815
+ return mangleMemberFunctionPointer (RD, MD, " " );
816
+
817
+ Out << ' N' ;
818
+ return ;
819
+ }
820
+
821
+ Out << " E?" ;
822
+ if (MD->isVirtual ()) {
823
+ MicrosoftVTableContext *VTContext =
824
+ cast<MicrosoftVTableContext>(getASTContext ().getVTableContext ());
825
+ MethodVFTableLocation ML =
826
+ VTContext->getMethodVFTableLocation (GlobalDecl (MD));
827
+ mangleVirtualMemPtrThunk (MD, ML);
828
+ } else {
829
+ mangleName (MD);
830
+ mangleFunctionEncoding (MD, /* ShouldMangle=*/ true );
831
+ }
832
+ }
833
+
778
834
void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk (
779
835
const CXXMethodDecl *MD, const MethodVFTableLocation &ML) {
780
836
// Get the vftable offset.
@@ -1188,6 +1244,11 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
1188
1244
// ::= <substitution> [<postfix>]
1189
1245
void MicrosoftCXXNameMangler::mangleNestedName (GlobalDecl GD) {
1190
1246
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl ());
1247
+
1248
+ if (const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1249
+ for (unsigned I = 1 , IE = ID->getChainingSize (); I < IE; ++I)
1250
+ mangleSourceName (" <unnamed-tag>" );
1251
+
1191
1252
const DeclContext *DC = getEffectiveDeclContext (ND);
1192
1253
while (!DC->isTranslationUnit ()) {
1193
1254
if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
@@ -1570,7 +1631,6 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
1570
1631
// ::= 8 <class> <unqualified-name> @
1571
1632
// ::= A <type> <non-negative integer> # float
1572
1633
// ::= B <type> <non-negative integer> # double
1573
- // ::= E <mangled-name> # reference to D
1574
1634
// # pointer to member, by component value
1575
1635
// ::= F <number> <number>
1576
1636
// ::= G <number> <number> <number>
@@ -1615,7 +1675,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
1615
1675
mangleTemplateArgValue (TPO->getType ().getUnqualifiedType (),
1616
1676
TPO->getValue ());
1617
1677
} else {
1618
- mangle (ND, TA. getParamTypeForDecl ()-> isReferenceType () ? " $E? " : " $1?" );
1678
+ mangle (ND, " $1?" );
1619
1679
}
1620
1680
break ;
1621
1681
}
@@ -1744,46 +1804,62 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
1744
1804
// FIXME: This can only happen as an extension. Invent a mangling.
1745
1805
break ;
1746
1806
} else if (auto *VD = Base.dyn_cast <const ValueDecl*>()) {
1747
- Out << (T-> isReferenceType () ? " E" : " 1 " ) ;
1807
+ Out << " E" ;
1748
1808
mangle (VD);
1749
1809
} else {
1750
1810
break ;
1751
1811
}
1752
1812
} else {
1753
- unsigned NumAts = 0 ;
1754
- if (T->isPointerType ()) {
1813
+ if (T->isPointerType ())
1755
1814
Out << " 5" ;
1756
- ++NumAts;
1757
- }
1758
1815
1759
- QualType T = Base.getType ();
1816
+ SmallVector<char , 2 > EntryTypes;
1817
+ SmallVector<std::function<void ()>, 2 > EntryManglers;
1818
+ QualType ET = Base.getType ();
1760
1819
for (APValue::LValuePathEntry E : V.getLValuePath ()) {
1761
- // We don't know how to mangle array subscripting yet.
1762
- if (T->isArrayType ())
1763
- goto mangling_unknown;
1820
+ if (auto *AT = ET->getAsArrayTypeUnsafe ()) {
1821
+ EntryTypes.push_back (' C' );
1822
+ EntryManglers.push_back ([this , I = E.getAsArrayIndex ()] {
1823
+ Out << ' 0' ;
1824
+ mangleNumber (I);
1825
+ Out << ' @' ;
1826
+ });
1827
+ ET = AT->getElementType ();
1828
+ continue ;
1829
+ }
1764
1830
1765
1831
const Decl *D = E.getAsBaseOrMember ().getPointer ();
1766
- auto *FD = dyn_cast<FieldDecl>(D);
1767
- // We don't know how to mangle derived-to-base conversions yet.
1768
- if (!FD)
1769
- goto mangling_unknown;
1770
-
1771
- Out << " 6" ;
1772
- ++NumAts;
1773
- T = FD->getType ();
1832
+ if (auto *FD = dyn_cast<FieldDecl>(D)) {
1833
+ ET = FD->getType ();
1834
+ if (const auto *RD = ET->getAsRecordDecl ())
1835
+ if (RD->isAnonymousStructOrUnion ())
1836
+ continue ;
1837
+ } else {
1838
+ ET = getASTContext ().getRecordType (cast<CXXRecordDecl>(D));
1839
+ // Bug in MSVC: fully qualified name of base class should be used for
1840
+ // mangling to prevent collisions e.g. on base classes with same names
1841
+ // in different namespaces.
1842
+ }
1843
+
1844
+ EntryTypes.push_back (' 6' );
1845
+ EntryManglers.push_back ([this , D] {
1846
+ mangleUnqualifiedName (cast<NamedDecl>(D));
1847
+ Out << ' @' ;
1848
+ });
1774
1849
}
1775
1850
1851
+ for (auto I = EntryTypes.rbegin (), E = EntryTypes.rend (); I != E; ++I)
1852
+ Out << *I;
1853
+
1776
1854
auto *VD = Base.dyn_cast <const ValueDecl*>();
1777
1855
if (!VD)
1778
1856
break ;
1779
1857
Out << " E" ;
1780
1858
mangle (VD);
1781
1859
1782
- for (APValue::LValuePathEntry E : V.getLValuePath ()) {
1783
- const Decl *D = E.getAsBaseOrMember ().getPointer ();
1784
- mangleUnqualifiedName (cast<FieldDecl>(D));
1785
- }
1786
- for (unsigned I = 0 ; I != NumAts; ++I)
1860
+ for (const std::function<void ()> &Mangler : EntryManglers)
1861
+ Mangler ();
1862
+ if (T->isPointerType ())
1787
1863
Out << ' @' ;
1788
1864
}
1789
1865
@@ -1794,20 +1870,14 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
1794
1870
if (WithScalarType)
1795
1871
mangleType (T, SourceRange (), QMM_Escape);
1796
1872
1797
- // FIXME: The below manglings don't include a conversion, so bail if there
1798
- // would be one. MSVC mangles the (possibly converted) value of the
1799
- // pointer-to-member object as if it were a struct, leading to collisions
1800
- // in some cases.
1801
- if (!V.getMemberPointerPath ().empty ())
1802
- break ;
1803
-
1804
1873
const CXXRecordDecl *RD =
1805
1874
T->castAs <MemberPointerType>()->getMostRecentCXXRecordDecl ();
1806
1875
const ValueDecl *D = V.getMemberPointerDecl ();
1807
1876
if (T->isMemberDataPointerType ())
1808
- mangleMemberDataPointer (RD, D, " " );
1877
+ mangleMemberDataPointerInClassNTTP (RD, D);
1809
1878
else
1810
- mangleMemberFunctionPointer (RD, cast_or_null<CXXMethodDecl>(D), " " );
1879
+ mangleMemberFunctionPointerInClassNTTP (RD,
1880
+ cast_or_null<CXXMethodDecl>(D));
1811
1881
return ;
1812
1882
}
1813
1883
@@ -1895,7 +1965,6 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
1895
1965
break ;
1896
1966
}
1897
1967
1898
- mangling_unknown:
1899
1968
DiagnosticsEngine &Diags = Context.getDiags ();
1900
1969
unsigned DiagID = Diags.getCustomDiagID (
1901
1970
DiagnosticsEngine::Error, " cannot mangle this template argument yet" );
0 commit comments