diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp b/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp index 0603d3b..93ff77a 100644 --- a/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp +++ b/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp @@ -31,11 +31,12 @@ class MicrosoftNumberingContext : public MangleNumberingContext { llvm::DenseMap<const Type *, unsigned> ManglingNumbers; unsigned LambdaManglingNumber; unsigned StaticLocalNumber; + unsigned StaticThreadlocalNumber; public: MicrosoftNumberingContext() : MangleNumberingContext(), LambdaManglingNumber(0), - StaticLocalNumber(0) {} + StaticLocalNumber(0), StaticThreadlocalNumber(0) {} unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override { return ++LambdaManglingNumber; @@ -47,6 +48,8 @@ public: } unsigned getStaticLocalNumber(const VarDecl *VD) override { + if (VD->getTLSKind()) + return ++StaticThreadlocalNumber; return ++StaticLocalNumber; } @@ -63,6 +66,10 @@ public: class MicrosoftCXXABI : public CXXABI { ASTContext &Context; + llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor; + llvm::SmallDenseMap<std::pair<const CXXConstructorDecl *, unsigned>, Expr *> + CtorToDefaultArgExpr; + public: MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { } @@ -82,13 +89,36 @@ public: return false; const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); - + // In the Microsoft ABI, classes can have one or two vtable pointers. - CharUnits PointerSize = - Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); + CharUnits PointerSize = + Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); return Layout.getNonVirtualSize() == PointerSize || Layout.getNonVirtualSize() == PointerSize * 2; - } + } + + void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD, + unsigned ParmIdx, Expr *DAE) override { + CtorToDefaultArgExpr[std::make_pair(CD, ParmIdx)] = DAE; + } + + Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD, + unsigned ParmIdx) override { + return CtorToDefaultArgExpr[std::make_pair(CD, ParmIdx)]; + } + + const CXXConstructorDecl * + getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override { + return RecordToCopyCtor[RD]; + } + + void + addCopyConstructorForExceptionObject(CXXRecordDecl *RD, + CXXConstructorDecl *CD) override { + assert(CD != nullptr); + assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD); + RecordToCopyCtor[RD] = CD; + } MangleNumberingContext *createMangleNumberingContext() const override { return new MicrosoftNumberingContext(); @@ -186,29 +216,28 @@ getMSMemberPointerSlots(const MemberPointerType *MPT) { std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign( const MemberPointerType *MPT) const { - const TargetInfo &Target = Context.getTargetInfo(); - assert(Target.getTriple().getArch() == llvm::Triple::x86 || - Target.getTriple().getArch() == llvm::Triple::x86_64); - unsigned Ptrs, Ints; - std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT); // The nominal struct is laid out with pointers followed by ints and aligned // to a pointer width if any are present and an int width otherwise. + const TargetInfo &Target = Context.getTargetInfo(); unsigned PtrSize = Target.getPointerWidth(0); unsigned IntSize = Target.getIntWidth(); + + unsigned Ptrs, Ints; + std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT); uint64_t Width = Ptrs * PtrSize + Ints * IntSize; unsigned Align; // When MSVC does x86_32 record layout, it aligns aggregate member pointers to // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for // function memptrs. - if (Ptrs + Ints > 1 && Target.getTriple().getArch() == llvm::Triple::x86) - Align = 8 * 8; + if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit()) + Align = 64; else if (Ptrs) Align = Target.getPointerAlign(0); else Align = Target.getIntAlign(); - if (Target.getTriple().getArch() == llvm::Triple::x86_64) + if (Target.getTriple().isArch64Bit()) Width = llvm::RoundUpToAlignment(Width, Align); return std::make_pair(Width, Align); } |