forked from OSchip/llvm-project
[mangle] Fix mangling where an extra mangle context is required.
Summary: - [Itanium C++ ABI][1], for certain contexts like default parameter and etc., mangling numbering will be local to the particular argument in which it appears. - However, for these cases, the mangle numbering context is allocated per expression evaluation stack entry. That causes, for example, two lambdas defined/used understand the same default parameter are numbered as the same value and, in turn, one of them is not generated at all. - In this patch, an extra mangle numbering context map is maintained in the AST context to map taht extra declaration context to its numbering context. So that, 2 different lambdas defined/used in the same default parameter are numbered differently. [1]: https://itanium-cxx-abi.github.io/cxx-abi/abi.html Reviewers: rsmith, eli.friedman Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D68715 llvm-svn: 374200
This commit is contained in:
parent
bc2350a341
commit
fd18e94697
clang
include/clang
lib
test/CodeGenCXX
|
@ -514,6 +514,8 @@ private:
|
||||||
/// need to be consistently numbered for the mangler).
|
/// need to be consistently numbered for the mangler).
|
||||||
llvm::DenseMap<const DeclContext *, std::unique_ptr<MangleNumberingContext>>
|
llvm::DenseMap<const DeclContext *, std::unique_ptr<MangleNumberingContext>>
|
||||||
MangleNumberingContexts;
|
MangleNumberingContexts;
|
||||||
|
llvm::DenseMap<const Decl *, std::unique_ptr<MangleNumberingContext>>
|
||||||
|
ExtraMangleNumberingContexts;
|
||||||
|
|
||||||
/// Side-table of mangling numbers for declarations which rarely
|
/// Side-table of mangling numbers for declarations which rarely
|
||||||
/// need them (like static local vars).
|
/// need them (like static local vars).
|
||||||
|
@ -2812,6 +2814,9 @@ public:
|
||||||
/// Retrieve the context for computing mangling numbers in the given
|
/// Retrieve the context for computing mangling numbers in the given
|
||||||
/// DeclContext.
|
/// DeclContext.
|
||||||
MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
|
MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
|
||||||
|
enum NeedExtraManglingDecl_t { NeedExtraManglingDecl };
|
||||||
|
MangleNumberingContext &getManglingNumberContext(NeedExtraManglingDecl_t,
|
||||||
|
const Decl *D);
|
||||||
|
|
||||||
std::unique_ptr<MangleNumberingContext> createMangleNumberingContext() const;
|
std::unique_ptr<MangleNumberingContext> createMangleNumberingContext() const;
|
||||||
|
|
||||||
|
|
|
@ -1045,13 +1045,6 @@ public:
|
||||||
/// suffice, e.g., in a default function argument.
|
/// suffice, e.g., in a default function argument.
|
||||||
Decl *ManglingContextDecl;
|
Decl *ManglingContextDecl;
|
||||||
|
|
||||||
/// The context information used to mangle lambda expressions
|
|
||||||
/// and block literals within this context.
|
|
||||||
///
|
|
||||||
/// This mangling information is allocated lazily, since most contexts
|
|
||||||
/// do not have lambda expressions or block literals.
|
|
||||||
std::unique_ptr<MangleNumberingContext> MangleNumbering;
|
|
||||||
|
|
||||||
/// If we are processing a decltype type, a set of call expressions
|
/// If we are processing a decltype type, a set of call expressions
|
||||||
/// for which we have deferred checking the completeness of the return type.
|
/// for which we have deferred checking the completeness of the return type.
|
||||||
SmallVector<CallExpr *, 8> DelayedDecltypeCalls;
|
SmallVector<CallExpr *, 8> DelayedDecltypeCalls;
|
||||||
|
@ -1080,12 +1073,7 @@ public:
|
||||||
ExpressionKind ExprContext)
|
ExpressionKind ExprContext)
|
||||||
: Context(Context), ParentCleanup(ParentCleanup),
|
: Context(Context), ParentCleanup(ParentCleanup),
|
||||||
NumCleanupObjects(NumCleanupObjects), NumTypos(0),
|
NumCleanupObjects(NumCleanupObjects), NumTypos(0),
|
||||||
ManglingContextDecl(ManglingContextDecl), MangleNumbering(),
|
ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext) {}
|
||||||
ExprContext(ExprContext) {}
|
|
||||||
|
|
||||||
/// Retrieve the mangling numbering context, used to consistently
|
|
||||||
/// number constructs like lambdas for mangling.
|
|
||||||
MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx);
|
|
||||||
|
|
||||||
bool isUnevaluated() const {
|
bool isUnevaluated() const {
|
||||||
return Context == ExpressionEvaluationContext::Unevaluated ||
|
return Context == ExpressionEvaluationContext::Unevaluated ||
|
||||||
|
|
|
@ -10261,6 +10261,16 @@ ASTContext::getManglingNumberContext(const DeclContext *DC) {
|
||||||
return *MCtx;
|
return *MCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MangleNumberingContext &
|
||||||
|
ASTContext::getManglingNumberContext(NeedExtraManglingDecl_t, const Decl *D) {
|
||||||
|
assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C.
|
||||||
|
std::unique_ptr<MangleNumberingContext> &MCtx =
|
||||||
|
ExtraMangleNumberingContexts[D];
|
||||||
|
if (!MCtx)
|
||||||
|
MCtx = createMangleNumberingContext();
|
||||||
|
return *MCtx;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<MangleNumberingContext>
|
std::unique_ptr<MangleNumberingContext>
|
||||||
ASTContext::createMangleNumberingContext() const {
|
ASTContext::createMangleNumberingContext() const {
|
||||||
return ABI->createMangleNumberingContext();
|
return ABI->createMangleNumberingContext();
|
||||||
|
|
|
@ -352,21 +352,13 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC,
|
||||||
// -- the initializers of inline variables
|
// -- the initializers of inline variables
|
||||||
case VariableTemplate:
|
case VariableTemplate:
|
||||||
// -- the initializers of templated variables
|
// -- the initializers of templated variables
|
||||||
return &ExprEvalContexts.back().getMangleNumberingContext(Context);
|
return &Context.getManglingNumberContext(ASTContext::NeedExtraManglingDecl,
|
||||||
|
ManglingContextDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm_unreachable("unexpected context");
|
llvm_unreachable("unexpected context");
|
||||||
}
|
}
|
||||||
|
|
||||||
MangleNumberingContext &
|
|
||||||
Sema::ExpressionEvaluationContextRecord::getMangleNumberingContext(
|
|
||||||
ASTContext &Ctx) {
|
|
||||||
assert(ManglingContextDecl && "Need to have a context declaration");
|
|
||||||
if (!MangleNumbering)
|
|
||||||
MangleNumbering = Ctx.createMangleNumberingContext();
|
|
||||||
return *MangleNumbering;
|
|
||||||
}
|
|
||||||
|
|
||||||
CXXMethodDecl *Sema::startLambdaDefinition(
|
CXXMethodDecl *Sema::startLambdaDefinition(
|
||||||
CXXRecordDecl *Class, SourceRange IntroducerRange,
|
CXXRecordDecl *Class, SourceRange IntroducerRange,
|
||||||
TypeSourceInfo *MethodTypeInfo, SourceLocation EndLoc,
|
TypeSourceInfo *MethodTypeInfo, SourceLocation EndLoc,
|
||||||
|
|
|
@ -178,18 +178,24 @@ void use_func_template() {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
struct type_info;
|
struct type_info {
|
||||||
|
bool before(const type_info &) const noexcept;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
namespace PR12123 {
|
namespace PR12123 {
|
||||||
struct A { virtual ~A(); } g;
|
struct A { virtual ~A(); } g;
|
||||||
|
struct C { virtual ~C(); } k;
|
||||||
struct B {
|
struct B {
|
||||||
void f(const std::type_info& x = typeid([]()->A& { return g; }()));
|
void f(const std::type_info& x = typeid([]()->A& { return g; }()));
|
||||||
void h();
|
void h();
|
||||||
|
void j(bool cond = typeid([]() -> A & { return g; }()).before(typeid([]() -> C & { return k; }())));
|
||||||
};
|
};
|
||||||
void B::h() { f(); }
|
void B::h() { f(); j(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv
|
// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv
|
||||||
|
// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %"struct.PR12123::A"* @_ZZN7PR121231B1jEbEd_NKUlvE_clEv
|
||||||
|
// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %"struct.PR12123::C"* @_ZZN7PR121231B1jEbEd_NKUlvE0_clEv
|
||||||
|
|
||||||
// CHECK-LABEL: define {{.*}} @_Z{{[0-9]*}}testVarargsLambdaNumberingv(
|
// CHECK-LABEL: define {{.*}} @_Z{{[0-9]*}}testVarargsLambdaNumberingv(
|
||||||
inline int testVarargsLambdaNumbering() {
|
inline int testVarargsLambdaNumbering() {
|
||||||
|
|
Loading…
Reference in New Issue