@@ -40,65 +40,10 @@ using namespace clang;
40
40
41
41
namespace {
42
42
43
- // / Retrieve the declaration context that should be used when mangling the given
44
- // / declaration.
45
- static const DeclContext *getEffectiveDeclContext (const Decl *D) {
46
- // The ABI assumes that lambda closure types that occur within
47
- // default arguments live in the context of the function. However, due to
48
- // the way in which Clang parses and creates function declarations, this is
49
- // not the case: the lambda closure type ends up living in the context
50
- // where the function itself resides, because the function declaration itself
51
- // had not yet been created. Fix the context here.
52
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
53
- if (RD->isLambda ())
54
- if (ParmVarDecl *ContextParam
55
- = dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl ()))
56
- return ContextParam->getDeclContext ();
57
- }
58
-
59
- // Perform the same check for block literals.
60
- if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
61
- if (ParmVarDecl *ContextParam
62
- = dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl ()))
63
- return ContextParam->getDeclContext ();
64
- }
65
-
66
- const DeclContext *DC = D->getDeclContext ();
67
- if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
68
- isa<OMPDeclareMapperDecl>(DC)) {
69
- return getEffectiveDeclContext (cast<Decl>(DC));
70
- }
71
-
72
- if (const auto *VD = dyn_cast<VarDecl>(D))
73
- if (VD->isExternC ())
74
- return VD->getASTContext ().getTranslationUnitDecl ();
75
-
76
- if (const auto *FD = dyn_cast<FunctionDecl>(D))
77
- if (FD->isExternC ())
78
- return FD->getASTContext ().getTranslationUnitDecl ();
79
-
80
- return DC->getRedeclContext ();
81
- }
82
-
83
- static const DeclContext *getEffectiveParentContext (const DeclContext *DC) {
84
- return getEffectiveDeclContext (cast<Decl>(DC));
85
- }
86
-
87
43
static bool isLocalContainerContext (const DeclContext *DC) {
88
44
return isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC) || isa<BlockDecl>(DC);
89
45
}
90
46
91
- static const RecordDecl *GetLocalClassDecl (const Decl *D) {
92
- const DeclContext *DC = getEffectiveDeclContext (D);
93
- while (!DC->isNamespace () && !DC->isTranslationUnit ()) {
94
- if (isLocalContainerContext (DC))
95
- return dyn_cast<RecordDecl>(D);
96
- D = cast<Decl>(DC);
97
- DC = getEffectiveDeclContext (D);
98
- }
99
- return nullptr ;
100
- }
101
-
102
47
static const FunctionDecl *getStructor (const FunctionDecl *fn) {
103
48
if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate ())
104
49
return ftd->getTemplatedDecl ();
@@ -249,6 +194,14 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
249
194
return DiscriminatorOverride;
250
195
}
251
196
197
+ const DeclContext *getEffectiveDeclContext (const Decl *D);
198
+ const DeclContext *getEffectiveParentContext (const DeclContext *DC) {
199
+ return getEffectiveDeclContext (cast<Decl>(DC));
200
+ }
201
+
202
+ bool isInternalLinkageDecl (const NamedDecl *ND);
203
+ const DeclContext *IgnoreLinkageSpecDecls (const DeclContext *DC);
204
+
252
205
// / @}
253
206
};
254
207
@@ -427,6 +380,15 @@ class CXXNameMangler {
427
380
428
381
ASTContext &getASTContext () const { return Context.getASTContext (); }
429
382
383
+ bool isStd (const NamespaceDecl *NS);
384
+ bool isStdNamespace (const DeclContext *DC);
385
+
386
+ const RecordDecl *GetLocalClassDecl (const Decl *D);
387
+ const DeclContext *IgnoreLinkageSpecDecls (const DeclContext *DC);
388
+ bool isSpecializedAs (QualType S, llvm::StringRef Name, QualType A);
389
+ bool isStdCharSpecialization (const ClassTemplateSpecializationDecl *SD,
390
+ llvm::StringRef Name, bool HasAllocator);
391
+
430
392
public:
431
393
CXXNameMangler (ItaniumMangleContextImpl &C, raw_ostream &Out_,
432
394
const NamedDecl *D = nullptr , bool NullOut_ = false )
@@ -628,7 +590,48 @@ class CXXNameMangler {
628
590
629
591
}
630
592
631
- static bool isInternalLinkageDecl (const NamedDecl *ND) {
593
+ // / Retrieve the declaration context that should be used when mangling the given
594
+ // / declaration.
595
+ const DeclContext *
596
+ ItaniumMangleContextImpl::getEffectiveDeclContext (const Decl *D) {
597
+ // The ABI assumes that lambda closure types that occur within
598
+ // default arguments live in the context of the function. However, due to
599
+ // the way in which Clang parses and creates function declarations, this is
600
+ // not the case: the lambda closure type ends up living in the context
601
+ // where the function itself resides, because the function declaration itself
602
+ // had not yet been created. Fix the context here.
603
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
604
+ if (RD->isLambda ())
605
+ if (ParmVarDecl *ContextParam =
606
+ dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl ()))
607
+ return ContextParam->getDeclContext ();
608
+ }
609
+
610
+ // Perform the same check for block literals.
611
+ if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
612
+ if (ParmVarDecl *ContextParam =
613
+ dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl ()))
614
+ return ContextParam->getDeclContext ();
615
+ }
616
+
617
+ const DeclContext *DC = D->getDeclContext ();
618
+ if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
619
+ isa<OMPDeclareMapperDecl>(DC)) {
620
+ return getEffectiveDeclContext (cast<Decl>(DC));
621
+ }
622
+
623
+ if (const auto *VD = dyn_cast<VarDecl>(D))
624
+ if (VD->isExternC ())
625
+ return getASTContext ().getTranslationUnitDecl ();
626
+
627
+ if (const auto *FD = dyn_cast<FunctionDecl>(D))
628
+ if (FD->isExternC ())
629
+ return getASTContext ().getTranslationUnitDecl ();
630
+
631
+ return DC->getRedeclContext ();
632
+ }
633
+
634
+ bool ItaniumMangleContextImpl::isInternalLinkageDecl (const NamedDecl *ND) {
632
635
if (ND && ND->getFormalLinkage () == InternalLinkage &&
633
636
!ND->isExternallyVisible () &&
634
637
getEffectiveDeclContext (ND)->isFileContext () &&
@@ -863,8 +866,8 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
863
866
}
864
867
865
868
// / Return whether a given namespace is the 'std' namespace.
866
- static bool isStd (const NamespaceDecl *NS) {
867
- if (!getEffectiveParentContext (NS)->isTranslationUnit ())
869
+ bool CXXNameMangler:: isStd (const NamespaceDecl *NS) {
870
+ if (!Context. getEffectiveParentContext (NS)->isTranslationUnit ())
868
871
return false ;
869
872
870
873
const IdentifierInfo *II = NS->getOriginalNamespace ()->getIdentifier ();
@@ -873,7 +876,7 @@ static bool isStd(const NamespaceDecl *NS) {
873
876
874
877
// isStdNamespace - Return whether a given decl context is a toplevel 'std'
875
878
// namespace.
876
- static bool isStdNamespace (const DeclContext *DC) {
879
+ bool CXXNameMangler:: isStdNamespace (const DeclContext *DC) {
877
880
if (!DC->isNamespace ())
878
881
return false ;
879
882
@@ -947,6 +950,17 @@ void CXXNameMangler::mangleName(GlobalDecl GD) {
947
950
}
948
951
}
949
952
953
+ const RecordDecl *CXXNameMangler::GetLocalClassDecl (const Decl *D) {
954
+ const DeclContext *DC = Context.getEffectiveDeclContext (D);
955
+ while (!DC->isNamespace () && !DC->isTranslationUnit ()) {
956
+ if (isLocalContainerContext (DC))
957
+ return dyn_cast<RecordDecl>(D);
958
+ D = cast<Decl>(DC);
959
+ DC = Context.getEffectiveDeclContext (D);
960
+ }
961
+ return nullptr ;
962
+ }
963
+
950
964
void CXXNameMangler::mangleNameWithAbiTags (GlobalDecl GD,
951
965
const AbiTagList *AdditionalAbiTags) {
952
966
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl ());
@@ -955,15 +969,15 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
955
969
// ::= [<module-name>] <unscoped-template-name> <template-args>
956
970
// ::= <local-name>
957
971
//
958
- const DeclContext *DC = getEffectiveDeclContext (ND);
972
+ const DeclContext *DC = Context. getEffectiveDeclContext (ND);
959
973
960
974
// If this is an extern variable declared locally, the relevant DeclContext
961
975
// is that of the containing namespace, or the translation unit.
962
976
// FIXME: This is a hack; extern variables declared locally should have
963
977
// a proper semantic declaration context!
964
978
if (isLocalContainerContext (DC) && ND->hasLinkage () && !isLambda (ND))
965
979
while (!DC->isNamespace () && !DC->isTranslationUnit ())
966
- DC = getEffectiveParentContext (DC);
980
+ DC = Context. getEffectiveParentContext (DC);
967
981
else if (GetLocalClassDecl (ND)) {
968
982
mangleLocalName (GD, AdditionalAbiTags);
969
983
return ;
@@ -1045,7 +1059,7 @@ void CXXNameMangler::mangleModuleNamePrefix(StringRef Name) {
1045
1059
void CXXNameMangler::mangleTemplateName (const TemplateDecl *TD,
1046
1060
const TemplateArgument *TemplateArgs,
1047
1061
unsigned NumTemplateArgs) {
1048
- const DeclContext *DC = getEffectiveDeclContext (TD);
1062
+ const DeclContext *DC = Context. getEffectiveDeclContext (TD);
1049
1063
1050
1064
if (DC->isTranslationUnit () || isStdNamespace (DC)) {
1051
1065
mangleUnscopedTemplateName (TD, nullptr );
@@ -1061,7 +1075,7 @@ void CXXNameMangler::mangleUnscopedName(GlobalDecl GD,
1061
1075
// <unscoped-name> ::= <unqualified-name>
1062
1076
// ::= St <unqualified-name> # ::std::
1063
1077
1064
- if (isStdNamespace (getEffectiveDeclContext (ND)))
1078
+ if (isStdNamespace (Context. getEffectiveDeclContext (ND)))
1065
1079
Out << " St" ;
1066
1080
1067
1081
mangleUnqualifiedName (GD, AdditionalAbiTags);
@@ -1421,7 +1435,7 @@ void CXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
1421
1435
// 12_GLOBAL__N_1 mangling is quite sufficient there, and this better
1422
1436
// matches GCC anyway, because GCC does not treat anonymous namespaces as
1423
1437
// implying internal linkage.
1424
- if (isInternalLinkageDecl (ND))
1438
+ if (Context. isInternalLinkageDecl (ND))
1425
1439
Out << ' L' ;
1426
1440
1427
1441
auto *FD = dyn_cast<FunctionDecl>(ND);
@@ -1736,7 +1750,7 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD,
1736
1750
// <discriminator> := _ <non-negative number>
1737
1751
assert (isa<NamedDecl>(D) || isa<BlockDecl>(D));
1738
1752
const RecordDecl *RD = GetLocalClassDecl (D);
1739
- const DeclContext *DC = getEffectiveDeclContext (RD ? RD : D);
1753
+ const DeclContext *DC = Context. getEffectiveDeclContext (RD ? RD : D);
1740
1754
1741
1755
Out << ' Z' ;
1742
1756
@@ -1789,13 +1803,13 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD,
1789
1803
if (const NamedDecl *PrefixND = getClosurePrefix (BD))
1790
1804
mangleClosurePrefix (PrefixND, true /* NoFunction*/ );
1791
1805
else
1792
- manglePrefix (getEffectiveDeclContext (BD), true /* NoFunction*/ );
1806
+ manglePrefix (Context. getEffectiveDeclContext (BD), true /* NoFunction*/ );
1793
1807
assert (!AdditionalAbiTags && " Block cannot have additional abi tags" );
1794
1808
mangleUnqualifiedBlock (BD);
1795
1809
} else {
1796
1810
const NamedDecl *ND = cast<NamedDecl>(D);
1797
- mangleNestedName (GD, getEffectiveDeclContext (ND), AdditionalAbiTags ,
1798
- true /* NoFunction*/ );
1811
+ mangleNestedName (GD, Context. getEffectiveDeclContext (ND),
1812
+ AdditionalAbiTags, true /* NoFunction*/ );
1799
1813
}
1800
1814
} else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
1801
1815
// Mangle a block in a default parameter; see above explanation for
@@ -1834,7 +1848,7 @@ void CXXNameMangler::mangleBlockForPrefix(const BlockDecl *Block) {
1834
1848
mangleLocalName (Block, /* AdditionalAbiTags */ nullptr );
1835
1849
return ;
1836
1850
}
1837
- const DeclContext *DC = getEffectiveDeclContext (Block);
1851
+ const DeclContext *DC = Context. getEffectiveDeclContext (Block);
1838
1852
if (isLocalContainerContext (DC)) {
1839
1853
mangleLocalName (Block, /* AdditionalAbiTags */ nullptr );
1840
1854
return ;
@@ -2044,7 +2058,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
2044
2058
mangleClosurePrefix (PrefixND, NoFunction);
2045
2059
mangleUnqualifiedName (ND, nullptr );
2046
2060
} else {
2047
- manglePrefix (getEffectiveDeclContext (ND), NoFunction);
2061
+ manglePrefix (Context. getEffectiveDeclContext (ND), NoFunction);
2048
2062
mangleUnqualifiedName (ND, nullptr );
2049
2063
}
2050
2064
@@ -2098,7 +2112,7 @@ void CXXNameMangler::mangleTemplatePrefix(GlobalDecl GD,
2098
2112
if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) {
2099
2113
mangleTemplateParameter (TTP->getDepth (), TTP->getIndex ());
2100
2114
} else {
2101
- manglePrefix (getEffectiveDeclContext (ND), NoFunction);
2115
+ manglePrefix (Context. getEffectiveDeclContext (ND), NoFunction);
2102
2116
if (isa<BuiltinTemplateDecl>(ND) || isa<ConceptDecl>(ND))
2103
2117
mangleUnqualifiedName (GD, nullptr );
2104
2118
else
@@ -2143,7 +2157,7 @@ void CXXNameMangler::mangleClosurePrefix(const NamedDecl *ND, bool NoFunction) {
2143
2157
mangleTemplatePrefix (TD, NoFunction);
2144
2158
mangleTemplateArgs (asTemplateName (TD), *TemplateArgs);
2145
2159
} else {
2146
- manglePrefix (getEffectiveDeclContext (ND), NoFunction);
2160
+ manglePrefix (Context. getEffectiveDeclContext (ND), NoFunction);
2147
2161
mangleUnqualifiedName (ND, nullptr );
2148
2162
}
2149
2163
@@ -5962,7 +5976,8 @@ bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {
5962
5976
5963
5977
// / Returns whether S is a template specialization of std::Name with a single
5964
5978
// / argument of type A.
5965
- static bool isSpecializedAs (QualType S, llvm::StringRef Name, QualType A) {
5979
+ bool CXXNameMangler::isSpecializedAs (QualType S, llvm::StringRef Name,
5980
+ QualType A) {
5966
5981
if (S.isNull ())
5967
5982
return false ;
5968
5983
@@ -5975,7 +5990,7 @@ static bool isSpecializedAs(QualType S, llvm::StringRef Name, QualType A) {
5975
5990
if (!SD || !SD->getIdentifier ()->isStr (Name))
5976
5991
return false ;
5977
5992
5978
- if (!isStdNamespace (getEffectiveDeclContext (SD)))
5993
+ if (!isStdNamespace (Context. getEffectiveDeclContext (SD)))
5979
5994
return false ;
5980
5995
5981
5996
const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs ();
@@ -5991,8 +6006,9 @@ static bool isSpecializedAs(QualType S, llvm::StringRef Name, QualType A) {
5991
6006
// / Returns whether SD is a template specialization std::Name<char,
5992
6007
// / std::char_traits<char> [, std::allocator<char>]>
5993
6008
// / HasAllocator controls whether the 3rd template argument is needed.
5994
- static bool isStdCharSpecialization (const ClassTemplateSpecializationDecl *SD,
5995
- llvm::StringRef Name, bool HasAllocator) {
6009
+ bool CXXNameMangler::isStdCharSpecialization (
6010
+ const ClassTemplateSpecializationDecl *SD, llvm::StringRef Name,
6011
+ bool HasAllocator) {
5996
6012
if (!SD->getIdentifier ()->isStr (Name))
5997
6013
return false ;
5998
6014
@@ -6029,7 +6045,7 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
6029
6045
}
6030
6046
6031
6047
if (const ClassTemplateDecl *TD = dyn_cast<ClassTemplateDecl>(ND)) {
6032
- if (!isStdNamespace (getEffectiveDeclContext (TD)))
6048
+ if (!isStdNamespace (Context. getEffectiveDeclContext (TD)))
6033
6049
return false ;
6034
6050
6035
6051
// <substitution> ::= Sa # ::std::allocator
@@ -6048,7 +6064,7 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
6048
6064
6049
6065
if (const ClassTemplateSpecializationDecl *SD =
6050
6066
dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
6051
- if (!isStdNamespace (getEffectiveDeclContext (SD)))
6067
+ if (!isStdNamespace (Context. getEffectiveDeclContext (SD)))
6052
6068
return false ;
6053
6069
6054
6070
// <substitution> ::= Ss # ::std::basic_string<char,
0 commit comments