Skip to content

Commit 725d57c

Browse files
pcctstellar
authored andcommitted
AST: Make getEffectiveDeclContext() a member function of ItaniumMangleContextImpl. NFCI.
In an upcoming change we are going to need to access mangler state from the getEffectiveDeclContext() function. Therefore, make it a member function of ItaniumMangleContextImpl. Any callers that are not currently members of ItaniumMangleContextImpl or CXXNameMangler are made members of one or the other depending on where they are called from. Differential Revision: https://reviews.llvm.org/D116773
1 parent 0009cdb commit 725d57c

File tree

1 file changed

+94
-78
lines changed

1 file changed

+94
-78
lines changed

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 94 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -40,65 +40,10 @@ using namespace clang;
4040

4141
namespace {
4242

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-
8743
static bool isLocalContainerContext(const DeclContext *DC) {
8844
return isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC) || isa<BlockDecl>(DC);
8945
}
9046

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-
10247
static const FunctionDecl *getStructor(const FunctionDecl *fn) {
10348
if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate())
10449
return ftd->getTemplatedDecl();
@@ -249,6 +194,14 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
249194
return DiscriminatorOverride;
250195
}
251196

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+
252205
/// @}
253206
};
254207

@@ -427,6 +380,15 @@ class CXXNameMangler {
427380

428381
ASTContext &getASTContext() const { return Context.getASTContext(); }
429382

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+
430392
public:
431393
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
432394
const NamedDecl *D = nullptr, bool NullOut_ = false)
@@ -628,7 +590,48 @@ class CXXNameMangler {
628590

629591
}
630592

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) {
632635
if (ND && ND->getFormalLinkage() == InternalLinkage &&
633636
!ND->isExternallyVisible() &&
634637
getEffectiveDeclContext(ND)->isFileContext() &&
@@ -863,8 +866,8 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
863866
}
864867

865868
/// 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())
868871
return false;
869872

870873
const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier();
@@ -873,7 +876,7 @@ static bool isStd(const NamespaceDecl *NS) {
873876

874877
// isStdNamespace - Return whether a given decl context is a toplevel 'std'
875878
// namespace.
876-
static bool isStdNamespace(const DeclContext *DC) {
879+
bool CXXNameMangler::isStdNamespace(const DeclContext *DC) {
877880
if (!DC->isNamespace())
878881
return false;
879882

@@ -947,6 +950,17 @@ void CXXNameMangler::mangleName(GlobalDecl GD) {
947950
}
948951
}
949952

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+
950964
void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
951965
const AbiTagList *AdditionalAbiTags) {
952966
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
@@ -955,15 +969,15 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
955969
// ::= [<module-name>] <unscoped-template-name> <template-args>
956970
// ::= <local-name>
957971
//
958-
const DeclContext *DC = getEffectiveDeclContext(ND);
972+
const DeclContext *DC = Context.getEffectiveDeclContext(ND);
959973

960974
// If this is an extern variable declared locally, the relevant DeclContext
961975
// is that of the containing namespace, or the translation unit.
962976
// FIXME: This is a hack; extern variables declared locally should have
963977
// a proper semantic declaration context!
964978
if (isLocalContainerContext(DC) && ND->hasLinkage() && !isLambda(ND))
965979
while (!DC->isNamespace() && !DC->isTranslationUnit())
966-
DC = getEffectiveParentContext(DC);
980+
DC = Context.getEffectiveParentContext(DC);
967981
else if (GetLocalClassDecl(ND)) {
968982
mangleLocalName(GD, AdditionalAbiTags);
969983
return;
@@ -1045,7 +1059,7 @@ void CXXNameMangler::mangleModuleNamePrefix(StringRef Name) {
10451059
void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD,
10461060
const TemplateArgument *TemplateArgs,
10471061
unsigned NumTemplateArgs) {
1048-
const DeclContext *DC = getEffectiveDeclContext(TD);
1062+
const DeclContext *DC = Context.getEffectiveDeclContext(TD);
10491063

10501064
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
10511065
mangleUnscopedTemplateName(TD, nullptr);
@@ -1061,7 +1075,7 @@ void CXXNameMangler::mangleUnscopedName(GlobalDecl GD,
10611075
// <unscoped-name> ::= <unqualified-name>
10621076
// ::= St <unqualified-name> # ::std::
10631077

1064-
if (isStdNamespace(getEffectiveDeclContext(ND)))
1078+
if (isStdNamespace(Context.getEffectiveDeclContext(ND)))
10651079
Out << "St";
10661080

10671081
mangleUnqualifiedName(GD, AdditionalAbiTags);
@@ -1421,7 +1435,7 @@ void CXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
14211435
// 12_GLOBAL__N_1 mangling is quite sufficient there, and this better
14221436
// matches GCC anyway, because GCC does not treat anonymous namespaces as
14231437
// implying internal linkage.
1424-
if (isInternalLinkageDecl(ND))
1438+
if (Context.isInternalLinkageDecl(ND))
14251439
Out << 'L';
14261440

14271441
auto *FD = dyn_cast<FunctionDecl>(ND);
@@ -1736,7 +1750,7 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD,
17361750
// <discriminator> := _ <non-negative number>
17371751
assert(isa<NamedDecl>(D) || isa<BlockDecl>(D));
17381752
const RecordDecl *RD = GetLocalClassDecl(D);
1739-
const DeclContext *DC = getEffectiveDeclContext(RD ? RD : D);
1753+
const DeclContext *DC = Context.getEffectiveDeclContext(RD ? RD : D);
17401754

17411755
Out << 'Z';
17421756

@@ -1789,13 +1803,13 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD,
17891803
if (const NamedDecl *PrefixND = getClosurePrefix(BD))
17901804
mangleClosurePrefix(PrefixND, true /*NoFunction*/);
17911805
else
1792-
manglePrefix(getEffectiveDeclContext(BD), true /*NoFunction*/);
1806+
manglePrefix(Context.getEffectiveDeclContext(BD), true /*NoFunction*/);
17931807
assert(!AdditionalAbiTags && "Block cannot have additional abi tags");
17941808
mangleUnqualifiedBlock(BD);
17951809
} else {
17961810
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*/);
17991813
}
18001814
} else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
18011815
// Mangle a block in a default parameter; see above explanation for
@@ -1834,7 +1848,7 @@ void CXXNameMangler::mangleBlockForPrefix(const BlockDecl *Block) {
18341848
mangleLocalName(Block, /* AdditionalAbiTags */ nullptr);
18351849
return;
18361850
}
1837-
const DeclContext *DC = getEffectiveDeclContext(Block);
1851+
const DeclContext *DC = Context.getEffectiveDeclContext(Block);
18381852
if (isLocalContainerContext(DC)) {
18391853
mangleLocalName(Block, /* AdditionalAbiTags */ nullptr);
18401854
return;
@@ -2044,7 +2058,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
20442058
mangleClosurePrefix(PrefixND, NoFunction);
20452059
mangleUnqualifiedName(ND, nullptr);
20462060
} else {
2047-
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
2061+
manglePrefix(Context.getEffectiveDeclContext(ND), NoFunction);
20482062
mangleUnqualifiedName(ND, nullptr);
20492063
}
20502064

@@ -2098,7 +2112,7 @@ void CXXNameMangler::mangleTemplatePrefix(GlobalDecl GD,
20982112
if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) {
20992113
mangleTemplateParameter(TTP->getDepth(), TTP->getIndex());
21002114
} else {
2101-
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
2115+
manglePrefix(Context.getEffectiveDeclContext(ND), NoFunction);
21022116
if (isa<BuiltinTemplateDecl>(ND) || isa<ConceptDecl>(ND))
21032117
mangleUnqualifiedName(GD, nullptr);
21042118
else
@@ -2143,7 +2157,7 @@ void CXXNameMangler::mangleClosurePrefix(const NamedDecl *ND, bool NoFunction) {
21432157
mangleTemplatePrefix(TD, NoFunction);
21442158
mangleTemplateArgs(asTemplateName(TD), *TemplateArgs);
21452159
} else {
2146-
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
2160+
manglePrefix(Context.getEffectiveDeclContext(ND), NoFunction);
21472161
mangleUnqualifiedName(ND, nullptr);
21482162
}
21492163

@@ -5962,7 +5976,8 @@ bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {
59625976

59635977
/// Returns whether S is a template specialization of std::Name with a single
59645978
/// 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) {
59665981
if (S.isNull())
59675982
return false;
59685983

@@ -5975,7 +5990,7 @@ static bool isSpecializedAs(QualType S, llvm::StringRef Name, QualType A) {
59755990
if (!SD || !SD->getIdentifier()->isStr(Name))
59765991
return false;
59775992

5978-
if (!isStdNamespace(getEffectiveDeclContext(SD)))
5993+
if (!isStdNamespace(Context.getEffectiveDeclContext(SD)))
59795994
return false;
59805995

59815996
const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
@@ -5991,8 +6006,9 @@ static bool isSpecializedAs(QualType S, llvm::StringRef Name, QualType A) {
59916006
/// Returns whether SD is a template specialization std::Name<char,
59926007
/// std::char_traits<char> [, std::allocator<char>]>
59936008
/// 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) {
59966012
if (!SD->getIdentifier()->isStr(Name))
59976013
return false;
59986014

@@ -6029,7 +6045,7 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
60296045
}
60306046

60316047
if (const ClassTemplateDecl *TD = dyn_cast<ClassTemplateDecl>(ND)) {
6032-
if (!isStdNamespace(getEffectiveDeclContext(TD)))
6048+
if (!isStdNamespace(Context.getEffectiveDeclContext(TD)))
60336049
return false;
60346050

60356051
// <substitution> ::= Sa # ::std::allocator
@@ -6048,7 +6064,7 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
60486064

60496065
if (const ClassTemplateSpecializationDecl *SD =
60506066
dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
6051-
if (!isStdNamespace(getEffectiveDeclContext(SD)))
6067+
if (!isStdNamespace(Context.getEffectiveDeclContext(SD)))
60526068
return false;
60536069

60546070
// <substitution> ::= Ss # ::std::basic_string<char,

0 commit comments

Comments
 (0)