summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Liao <michael.hliao@gmail.com>2019-10-09 19:08:52 +0000
committerMichael Liao <michael.hliao@gmail.com>2019-10-09 19:08:52 +0000
commitfd18e94697c987d5f24e25aa4e27adaffff3cce4 (patch)
treef03c7359e09612eb9b193ca1d4a206a7d8176c58
parentbc2350a3412676977ec2ffc801e661aa0cec9de6 (diff)
downloadbcm5719-llvm-fd18e94697c987d5f24e25aa4e27adaffff3cce4.tar.gz
bcm5719-llvm-fd18e94697c987d5f24e25aa4e27adaffff3cce4.zip
[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
-rw-r--r--clang/include/clang/AST/ASTContext.h5
-rw-r--r--clang/include/clang/Sema/Sema.h14
-rw-r--r--clang/lib/AST/ASTContext.cpp10
-rw-r--r--clang/lib/Sema/SemaLambda.cpp12
-rw-r--r--clang/test/CodeGenCXX/mangle-lambdas.cpp10
5 files changed, 26 insertions, 25 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 5105b9c35cd..7547960b092 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -514,6 +514,8 @@ private:
/// need to be consistently numbered for the mangler).
llvm::DenseMap<const DeclContext *, std::unique_ptr<MangleNumberingContext>>
MangleNumberingContexts;
+ llvm::DenseMap<const Decl *, std::unique_ptr<MangleNumberingContext>>
+ ExtraMangleNumberingContexts;
/// Side-table of mangling numbers for declarations which rarely
/// need them (like static local vars).
@@ -2812,6 +2814,9 @@ public:
/// Retrieve the context for computing mangling numbers in the given
/// DeclContext.
MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
+ enum NeedExtraManglingDecl_t { NeedExtraManglingDecl };
+ MangleNumberingContext &getManglingNumberContext(NeedExtraManglingDecl_t,
+ const Decl *D);
std::unique_ptr<MangleNumberingContext> createMangleNumberingContext() const;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index c9211eb7001..2fb3e32e1b3 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1045,13 +1045,6 @@ public:
/// suffice, e.g., in a default function argument.
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
/// for which we have deferred checking the completeness of the return type.
SmallVector<CallExpr *, 8> DelayedDecltypeCalls;
@@ -1080,12 +1073,7 @@ public:
ExpressionKind ExprContext)
: Context(Context), ParentCleanup(ParentCleanup),
NumCleanupObjects(NumCleanupObjects), NumTypos(0),
- ManglingContextDecl(ManglingContextDecl), MangleNumbering(),
- ExprContext(ExprContext) {}
-
- /// Retrieve the mangling numbering context, used to consistently
- /// number constructs like lambdas for mangling.
- MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx);
+ ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext) {}
bool isUnevaluated() const {
return Context == ExpressionEvaluationContext::Unevaluated ||
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a41b64ffcc8..8dd57f2bd28 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -10261,6 +10261,16 @@ ASTContext::getManglingNumberContext(const DeclContext *DC) {
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>
ASTContext::createMangleNumberingContext() const {
return ABI->createMangleNumberingContext();
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index a76a840f26e..b05ed75e879 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -352,21 +352,13 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC,
// -- the initializers of inline variables
case VariableTemplate:
// -- the initializers of templated variables
- return &ExprEvalContexts.back().getMangleNumberingContext(Context);
+ return &Context.getManglingNumberContext(ASTContext::NeedExtraManglingDecl,
+ ManglingContextDecl);
}
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(
CXXRecordDecl *Class, SourceRange IntroducerRange,
TypeSourceInfo *MethodTypeInfo, SourceLocation EndLoc,
diff --git a/clang/test/CodeGenCXX/mangle-lambdas.cpp b/clang/test/CodeGenCXX/mangle-lambdas.cpp
index d49ed4b2a5e..fcca878e387 100644
--- a/clang/test/CodeGenCXX/mangle-lambdas.cpp
+++ b/clang/test/CodeGenCXX/mangle-lambdas.cpp
@@ -178,18 +178,24 @@ void use_func_template() {
}
namespace std {
- struct type_info;
+ struct type_info {
+ bool before(const type_info &) const noexcept;
+ };
}
namespace PR12123 {
struct A { virtual ~A(); } g;
+ struct C { virtual ~C(); } k;
struct B {
void f(const std::type_info& x = typeid([]()->A& { return g; }()));
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"* @_ZZN7PR121231B1jEbEd_NKUlvE_clEv
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %"struct.PR12123::C"* @_ZZN7PR121231B1jEbEd_NKUlvE0_clEv
// CHECK-LABEL: define {{.*}} @_Z{{[0-9]*}}testVarargsLambdaNumberingv(
inline int testVarargsLambdaNumbering() {
OpenPOWER on IntegriCloud