Home | History | Annotate | Download | only in AST
      1 //===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This provides C++ AST support targeting the Microsoft Visual C++
     11 // ABI.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "CXXABI.h"
     16 #include "clang/AST/ASTContext.h"
     17 #include "clang/AST/Attr.h"
     18 #include "clang/AST/DeclCXX.h"
     19 #include "clang/AST/MangleNumberingContext.h"
     20 #include "clang/AST/RecordLayout.h"
     21 #include "clang/AST/Type.h"
     22 #include "clang/Basic/TargetInfo.h"
     23 
     24 using namespace clang;
     25 
     26 namespace {
     27 
     28 /// \brief Numbers things which need to correspond across multiple TUs.
     29 /// Typically these are things like static locals, lambdas, or blocks.
     30 class MicrosoftNumberingContext : public MangleNumberingContext {
     31   llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
     32   unsigned LambdaManglingNumber;
     33   unsigned StaticLocalNumber;
     34   unsigned StaticThreadlocalNumber;
     35 
     36 public:
     37   MicrosoftNumberingContext()
     38       : MangleNumberingContext(), LambdaManglingNumber(0),
     39         StaticLocalNumber(0), StaticThreadlocalNumber(0) {}
     40 
     41   unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
     42     return ++LambdaManglingNumber;
     43   }
     44 
     45   unsigned getManglingNumber(const BlockDecl *BD) override {
     46     const Type *Ty = nullptr;
     47     return ++ManglingNumbers[Ty];
     48   }
     49 
     50   unsigned getStaticLocalNumber(const VarDecl *VD) override {
     51     if (VD->getTLSKind())
     52       return ++StaticThreadlocalNumber;
     53     return ++StaticLocalNumber;
     54   }
     55 
     56   unsigned getManglingNumber(const VarDecl *VD,
     57                              unsigned MSLocalManglingNumber) override {
     58     return MSLocalManglingNumber;
     59   }
     60 
     61   unsigned getManglingNumber(const TagDecl *TD,
     62                              unsigned MSLocalManglingNumber) override {
     63     return MSLocalManglingNumber;
     64   }
     65 };
     66 
     67 class MicrosoftCXXABI : public CXXABI {
     68   ASTContext &Context;
     69   llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor;
     70   llvm::SmallDenseMap<std::pair<const CXXConstructorDecl *, unsigned>, Expr *>
     71       CtorToDefaultArgExpr;
     72 
     73   llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
     74       UnnamedTagDeclToDeclaratorDecl;
     75   llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
     76       UnnamedTagDeclToTypedefNameDecl;
     77 
     78 public:
     79   MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
     80 
     81   std::pair<uint64_t, unsigned>
     82   getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override;
     83 
     84   CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
     85     if (!isVariadic &&
     86         Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
     87       return CC_X86ThisCall;
     88     return CC_C;
     89   }
     90 
     91   bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
     92     llvm_unreachable("unapplicable to the MS ABI");
     93   }
     94 
     95   void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
     96                                        unsigned ParmIdx, Expr *DAE) override {
     97     CtorToDefaultArgExpr[std::make_pair(CD, ParmIdx)] = DAE;
     98   }
     99 
    100   Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
    101                                         unsigned ParmIdx) override {
    102     return CtorToDefaultArgExpr[std::make_pair(CD, ParmIdx)];
    103   }
    104 
    105   const CXXConstructorDecl *
    106   getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
    107     return RecordToCopyCtor[RD];
    108   }
    109 
    110   void
    111   addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
    112                                        CXXConstructorDecl *CD) override {
    113     assert(CD != nullptr);
    114     assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD);
    115     RecordToCopyCtor[RD] = CD;
    116   }
    117 
    118   void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
    119                                        TypedefNameDecl *DD) override {
    120     TD = TD->getCanonicalDecl();
    121     DD = cast<TypedefNameDecl>(DD->getCanonicalDecl());
    122     TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
    123     if (!I)
    124       I = DD;
    125   }
    126 
    127   TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
    128     return UnnamedTagDeclToTypedefNameDecl.lookup(
    129         const_cast<TagDecl *>(TD->getCanonicalDecl()));
    130   }
    131 
    132   void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
    133                                       DeclaratorDecl *DD) override {
    134     TD = TD->getCanonicalDecl();
    135     DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
    136     DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
    137     if (!I)
    138       I = DD;
    139   }
    140 
    141   DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
    142     return UnnamedTagDeclToDeclaratorDecl.lookup(
    143         const_cast<TagDecl *>(TD->getCanonicalDecl()));
    144   }
    145 
    146   MangleNumberingContext *createMangleNumberingContext() const override {
    147     return new MicrosoftNumberingContext();
    148   }
    149 };
    150 }
    151 
    152 // getNumBases() seems to only give us the number of direct bases, and not the
    153 // total.  This function tells us if we inherit from anybody that uses MI, or if
    154 // we have a non-primary base class, which uses the multiple inheritance model.
    155 static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
    156   while (RD->getNumBases() > 0) {
    157     if (RD->getNumBases() > 1)
    158       return true;
    159     assert(RD->getNumBases() == 1);
    160     const CXXRecordDecl *Base =
    161         RD->bases_begin()->getType()->getAsCXXRecordDecl();
    162     if (RD->isPolymorphic() && !Base->isPolymorphic())
    163       return true;
    164     RD = Base;
    165   }
    166   return false;
    167 }
    168 
    169 MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
    170   if (!hasDefinition() || isParsingBaseSpecifiers())
    171     return MSInheritanceAttr::Keyword_unspecified_inheritance;
    172   if (getNumVBases() > 0)
    173     return MSInheritanceAttr::Keyword_virtual_inheritance;
    174   if (usesMultipleInheritanceModel(this))
    175     return MSInheritanceAttr::Keyword_multiple_inheritance;
    176   return MSInheritanceAttr::Keyword_single_inheritance;
    177 }
    178 
    179 MSInheritanceAttr::Spelling
    180 CXXRecordDecl::getMSInheritanceModel() const {
    181   MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
    182   assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
    183   return IA->getSemanticSpelling();
    184 }
    185 
    186 MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
    187   if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
    188     return VDA->getVtorDispMode();
    189   return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
    190 }
    191 
    192 // Returns the number of pointer and integer slots used to represent a member
    193 // pointer in the MS C++ ABI.
    194 //
    195 // Member function pointers have the following general form;  however, fields
    196 // are dropped as permitted (under the MSVC interpretation) by the inheritance
    197 // model of the actual class.
    198 //
    199 //   struct {
    200 //     // A pointer to the member function to call.  If the member function is
    201 //     // virtual, this will be a thunk that forwards to the appropriate vftable
    202 //     // slot.
    203 //     void *FunctionPointerOrVirtualThunk;
    204 //
    205 //     // An offset to add to the address of the vbtable pointer after
    206 //     // (possibly) selecting the virtual base but before resolving and calling
    207 //     // the function.
    208 //     // Only needed if the class has any virtual bases or bases at a non-zero
    209 //     // offset.
    210 //     int NonVirtualBaseAdjustment;
    211 //
    212 //     // The offset of the vb-table pointer within the object.  Only needed for
    213 //     // incomplete types.
    214 //     int VBPtrOffset;
    215 //
    216 //     // An offset within the vb-table that selects the virtual base containing
    217 //     // the member.  Loading from this offset produces a new offset that is
    218 //     // added to the address of the vb-table pointer to produce the base.
    219 //     int VirtualBaseAdjustmentOffset;
    220 //   };
    221 static std::pair<unsigned, unsigned>
    222 getMSMemberPointerSlots(const MemberPointerType *MPT) {
    223   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
    224   MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
    225   unsigned Ptrs = 0;
    226   unsigned Ints = 0;
    227   if (MPT->isMemberFunctionPointer())
    228     Ptrs = 1;
    229   else
    230     Ints = 1;
    231   if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
    232                                           Inheritance))
    233     Ints++;
    234   if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
    235     Ints++;
    236   if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
    237     Ints++;
    238   return std::make_pair(Ptrs, Ints);
    239 }
    240 
    241 std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
    242     const MemberPointerType *MPT) const {
    243   // The nominal struct is laid out with pointers followed by ints and aligned
    244   // to a pointer width if any are present and an int width otherwise.
    245   const TargetInfo &Target = Context.getTargetInfo();
    246   unsigned PtrSize = Target.getPointerWidth(0);
    247   unsigned IntSize = Target.getIntWidth();
    248 
    249   unsigned Ptrs, Ints;
    250   std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
    251   uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
    252   unsigned Align;
    253 
    254   // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
    255   // 8 bytes.  However, __alignof usually returns 4 for data memptrs and 8 for
    256   // function memptrs.
    257   if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
    258     Align = 64;
    259   else if (Ptrs)
    260     Align = Target.getPointerAlign(0);
    261   else
    262     Align = Target.getIntAlign();
    263 
    264   if (Target.getTriple().isArch64Bit())
    265     Width = llvm::RoundUpToAlignment(Width, Align);
    266   return std::make_pair(Width, Align);
    267 }
    268 
    269 CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
    270   return new MicrosoftCXXABI(Ctx);
    271 }
    272 
    273