diff options
-rw-r--r-- | clang/include/clang/AST/MangleNumberingContext.h | 13 | ||||
-rw-r--r-- | clang/lib/AST/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumCXXABI.cpp | 26 | ||||
-rw-r--r-- | clang/lib/AST/MangleNumberingContext.cpp | 45 | ||||
-rw-r--r-- | clang/lib/AST/MicrosoftCXXABI.cpp | 21 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/pr20719.cpp | 35 |
6 files changed, 85 insertions, 56 deletions
diff --git a/clang/include/clang/AST/MangleNumberingContext.h b/clang/include/clang/AST/MangleNumberingContext.h index 56aec73f245..7a818557fdb 100644 --- a/clang/include/clang/AST/MangleNumberingContext.h +++ b/clang/include/clang/AST/MangleNumberingContext.h @@ -30,23 +30,20 @@ class VarDecl; /// \brief Keeps track of the mangled names of lambda expressions and block /// literals within a particular context. -class MangleNumberingContext - : public RefCountedBase<MangleNumberingContext> { - llvm::DenseMap<const Type *, unsigned> ManglingNumbers; - +class MangleNumberingContext : public RefCountedBase<MangleNumberingContext> { public: virtual ~MangleNumberingContext() {} /// \brief Retrieve the mangling number of a new lambda expression with the /// given call operator within this context. - unsigned getManglingNumber(const CXXMethodDecl *CallOperator); + virtual unsigned getManglingNumber(const CXXMethodDecl *CallOperator) = 0; /// \brief Retrieve the mangling number of a new block literal within this /// context. - unsigned getManglingNumber(const BlockDecl *BD); + virtual unsigned getManglingNumber(const BlockDecl *BD) = 0; /// Static locals are numbered by source order. - unsigned getStaticLocalNumber(const VarDecl *VD); + virtual unsigned getStaticLocalNumber(const VarDecl *VD) = 0; /// \brief Retrieve the mangling number of a static local variable within /// this context. @@ -58,6 +55,6 @@ public: virtual unsigned getManglingNumber(const TagDecl *TD, unsigned MSLocalManglingNumber) = 0; }; - + } // end namespace clang #endif diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index 9006be64f73..6ce347b4a31 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -35,7 +35,6 @@ add_clang_library(clangAST ItaniumCXXABI.cpp ItaniumMangle.cpp Mangle.cpp - MangleNumberingContext.cpp MicrosoftCXXABI.cpp MicrosoftMangle.cpp NestedNameSpecifier.cpp diff --git a/clang/lib/AST/ItaniumCXXABI.cpp b/clang/lib/AST/ItaniumCXXABI.cpp index b5f8c0f4bc8..03428bfa79b 100644 --- a/clang/lib/AST/ItaniumCXXABI.cpp +++ b/clang/lib/AST/ItaniumCXXABI.cpp @@ -32,10 +32,32 @@ namespace { /// \brief Keeps track of the mangled names of lambda expressions and block /// literals within a particular context. class ItaniumNumberingContext : public MangleNumberingContext { - llvm::DenseMap<IdentifierInfo*, unsigned> VarManglingNumbers; - llvm::DenseMap<IdentifierInfo*, unsigned> TagManglingNumbers; + llvm::DenseMap<const Type *, unsigned> ManglingNumbers; + llvm::DenseMap<IdentifierInfo *, unsigned> VarManglingNumbers; + llvm::DenseMap<IdentifierInfo *, unsigned> TagManglingNumbers; public: + unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { + const FunctionProtoType *Proto = + CallOperator->getType()->getAs<FunctionProtoType>(); + ASTContext &Context = CallOperator->getASTContext(); + + QualType Key = + Context.getFunctionType(Context.VoidTy, Proto->getParamTypes(), + FunctionProtoType::ExtProtoInfo()); + Key = Context.getCanonicalType(Key); + return ++ManglingNumbers[Key->castAs<FunctionProtoType>()]; + } + + unsigned getManglingNumber(const BlockDecl *BD) { + const Type *Ty = nullptr; + return ++ManglingNumbers[Ty]; + } + + unsigned getStaticLocalNumber(const VarDecl *VD) override { + return 0; + } + /// Variable decls are numbered by identifier. unsigned getManglingNumber(const VarDecl *VD, unsigned) override { return ++VarManglingNumbers[VD->getIdentifier()]; diff --git a/clang/lib/AST/MangleNumberingContext.cpp b/clang/lib/AST/MangleNumberingContext.cpp deleted file mode 100644 index 5f40f0347d0..00000000000 --- a/clang/lib/AST/MangleNumberingContext.cpp +++ /dev/null @@ -1,45 +0,0 @@ -//===--- MangleNumberingContext.cpp - Context for mangling numbers --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the LambdaMangleContext class, which keeps track of -// the Itanium C++ ABI mangling numbers for lambda expressions. -// -//===----------------------------------------------------------------------===// - -#include "clang/AST/MangleNumberingContext.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/DeclCXX.h" - -using namespace clang; - -unsigned -MangleNumberingContext::getManglingNumber(const CXXMethodDecl *CallOperator) { - const FunctionProtoType *Proto - = CallOperator->getType()->getAs<FunctionProtoType>(); - ASTContext &Context = CallOperator->getASTContext(); - - QualType Key = Context.getFunctionType(Context.VoidTy, Proto->getParamTypes(), - FunctionProtoType::ExtProtoInfo()); - Key = Context.getCanonicalType(Key); - return ++ManglingNumbers[Key->castAs<FunctionProtoType>()]; -} - -unsigned -MangleNumberingContext::getManglingNumber(const BlockDecl *BD) { - // FIXME: Compute a BlockPointerType? Not obvious how. - const Type *Ty = nullptr; - return ++ManglingNumbers[Ty]; -} - -unsigned -MangleNumberingContext::getStaticLocalNumber(const VarDecl *VD) { - // FIXME: Compute a BlockPointerType? Not obvious how. - const Type *Ty = nullptr; - return ++ManglingNumbers[Ty]; -} diff --git a/clang/lib/AST/MicrosoftCXXABI.cpp b/clang/lib/AST/MicrosoftCXXABI.cpp index 6870315b216..64b3c1f152e 100644 --- a/clang/lib/AST/MicrosoftCXXABI.cpp +++ b/clang/lib/AST/MicrosoftCXXABI.cpp @@ -28,7 +28,28 @@ namespace { /// \brief Numbers things which need to correspond across multiple TUs. /// Typically these are things like static locals, lambdas, or blocks. class MicrosoftNumberingContext : public MangleNumberingContext { + llvm::DenseMap<const Type *, unsigned> ManglingNumbers; + unsigned LambdaManglingNumber; + unsigned StaticLocalNumber; + public: + MicrosoftNumberingContext() + : MangleNumberingContext(), LambdaManglingNumber(0), + StaticLocalNumber(0) {} + + unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { + return ++LambdaManglingNumber; + } + + unsigned getManglingNumber(const BlockDecl *BD) { + const Type *Ty = nullptr; + return ++ManglingNumbers[Ty]; + } + + unsigned getStaticLocalNumber(const VarDecl *VD) override { + return ++StaticLocalNumber; + } + unsigned getManglingNumber(const VarDecl *VD, unsigned MSLocalManglingNumber) override { return MSLocalManglingNumber; diff --git a/clang/test/CodeGenCXX/pr20719.cpp b/clang/test/CodeGenCXX/pr20719.cpp new file mode 100644 index 00000000000..208d1113584 --- /dev/null +++ b/clang/test/CodeGenCXX/pr20719.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++11 -o - %s | FileCheck %s + +// Make sure that we emit H's constructor twice: once with the first lambda +// inside of 'lep' and again with the second lambda inside of 'lep'. +// CHECK-DAG: @"\01??0?$H@V<lambda_1>@??$lep@X@@YAXXZ@@@QAE@XZ" +// CHECK-DAG: @"\01??0?$H@V<lambda_2>@??$lep@X@@YAXXZ@@@QAE@XZ" + +template <typename> +struct H { + H() {} +}; + +template <typename Fx> +int K_void(const Fx &) { + H<Fx> callee; + return 0; +} +template <typename Fx> +int K_int(const Fx &) { + H<Fx> callee; + return 0; +} + +struct pair { + pair(int, int); +}; + +struct E1; + +template <typename> +void lep() { + pair x(K_void([] {}), K_int([] {})); +} + +auto z = lep<void>; |