r231499 - MS ABI: Insert copy-constructors into the CatchableType

Nico Weber thakis at chromium.org
Fri Mar 6 11:15:45 PST 2015


On Fri, Mar 6, 2015 at 10:53 AM, David Majnemer <david.majnemer at gmail.com>
wrote:

> Author: majnemer
> Date: Fri Mar  6 12:53:55 2015
> New Revision: 231499
>
> URL: http://llvm.org/viewvc/llvm-project?rev=231499&view=rev
> Log:
> MS ABI: Insert copy-constructors into the CatchableType
>
> Find all unambiguous public classes of the exception object's class type
> and reference all of their copy constructors.  Yes, this is not
> conforming but it is necessary in order to implement their ABI.  This is
> because the copy constructor is actually referenced by the metadata
> describing which catch handlers are eligible to handle the exception
> object.
>
> N.B.  This doesn't yet handle the copy constructor closure case yet,
> that work is ongoing.
>
> Differential Revision: http://reviews.llvm.org/D8101
>
> Modified:
>     cfe/trunk/include/clang/AST/ASTContext.h
>     cfe/trunk/include/clang/AST/Mangle.h
>     cfe/trunk/lib/AST/ASTContext.cpp
>     cfe/trunk/lib/AST/CXXABI.h
>     cfe/trunk/lib/AST/ItaniumCXXABI.cpp
>     cfe/trunk/lib/AST/MicrosoftCXXABI.cpp
>     cfe/trunk/lib/AST/MicrosoftMangle.cpp
>     cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
>     cfe/trunk/lib/Sema/SemaExprCXX.cpp
>     cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp
>
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=231499&r1=231498&r2=231499&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Fri Mar  6 12:53:55 2015
> @@ -2193,6 +2193,12 @@ public:
>    /// it is not used.
>    bool DeclMustBeEmitted(const Decl *D);
>
> +  const CXXConstructorDecl *
> +  getCopyConstructorForExceptionObject(CXXRecordDecl *RD);
> +
> +  void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
> +                                            CXXConstructorDecl *CD);
> +
>    void setManglingNumber(const NamedDecl *ND, unsigned Number);
>    unsigned getManglingNumber(const NamedDecl *ND) const;
>
>
> Modified: cfe/trunk/include/clang/AST/Mangle.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Mangle.h?rev=231499&r1=231498&r2=231499&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Mangle.h (original)
> +++ cfe/trunk/include/clang/AST/Mangle.h Fri Mar  6 12:53:55 2015
> @@ -203,8 +203,8 @@ public:
>    virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t
> NumEntries,
>                                             raw_ostream &Out) = 0;
>
> -  virtual void mangleCXXCatchableType(QualType T, uint32_t Size,
> -                                      raw_ostream &Out) = 0;
> +  virtual void mangleCXXCatchableType(QualType T, const
> CXXConstructorDecl *CD,
> +                                      uint32_t Size, raw_ostream &Out) =
> 0;
>
>    virtual void mangleCXXRTTIBaseClassDescriptor(
>        const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t
> VBPtrOffset,
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=231499&r1=231498&r2=231499&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Fri Mar  6 12:53:55 2015
> @@ -8189,6 +8189,19 @@ MangleNumberingContext *ASTContext::crea
>    return ABI->createMangleNumberingContext();
>  }
>
> +const CXXConstructorDecl *
> +ASTContext::getCopyConstructorForExceptionObject(CXXRecordDecl *RD) {
> +  return ABI->getCopyConstructorForExceptionObject(
> +      cast<CXXRecordDecl>(RD->getFirstDecl()));
> +}
> +
> +void ASTContext::addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
> +                                                      CXXConstructorDecl
> *CD) {
> +  return ABI->addCopyConstructorForExceptionObject(
> +      cast<CXXRecordDecl>(RD->getFirstDecl()),
> +      cast<CXXConstructorDecl>(CD->getFirstDecl()));
> +}
> +
>  void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int
> index) {
>    ParamIndices[D] = index;
>  }
>
> Modified: cfe/trunk/lib/AST/CXXABI.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CXXABI.h?rev=231499&r1=231498&r2=231499&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/CXXABI.h (original)
> +++ cfe/trunk/lib/AST/CXXABI.h Fri Mar  6 12:53:55 2015
> @@ -20,6 +20,7 @@
>  namespace clang {
>
>  class ASTContext;
> +class CXXConstructorDecl;
>  class MemberPointerType;
>  class MangleNumberingContext;
>
> @@ -41,6 +42,14 @@ public:
>
>    /// Returns a new mangling number context for this C++ ABI.
>    virtual MangleNumberingContext *createMangleNumberingContext() const =
> 0;
> +
> +  /// Adds a mapping from class to copy constructor for this C++ ABI.
> +  virtual void addCopyConstructorForExceptionObject(CXXRecordDecl *,
> +                                                    CXXConstructorDecl *)
> = 0;
> +
> +  /// Retrieves the mapping from class to copy constructor for this C++
> ABI.
> +  virtual const CXXConstructorDecl *
> +  getCopyConstructorForExceptionObject(CXXRecordDecl *) = 0;
>  };
>
>  /// Creates an instance of a C++ ABI class.
>
> Modified: cfe/trunk/lib/AST/ItaniumCXXABI.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumCXXABI.cpp?rev=231499&r1=231498&r2=231499&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ItaniumCXXABI.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumCXXABI.cpp Fri Mar  6 12:53:55 2015
> @@ -133,6 +133,14 @@ public:
>      return Layout.getNonVirtualSize() == PointerSize;
>    }
>
> +  const CXXConstructorDecl *
> +  getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
> +    return nullptr;
> +  }
> +
> +  void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
> +                                            CXXConstructorDecl *CD)
> override {}
> +
>    MangleNumberingContext *createMangleNumberingContext() const override {
>      return new ItaniumNumberingContext();
>    }
>
> Modified: cfe/trunk/lib/AST/MicrosoftCXXABI.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftCXXABI.cpp?rev=231499&r1=231498&r2=231499&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/MicrosoftCXXABI.cpp (original)
> +++ cfe/trunk/lib/AST/MicrosoftCXXABI.cpp Fri Mar  6 12:53:55 2015
> @@ -63,6 +63,8 @@ public:
>
>  class MicrosoftCXXABI : public CXXABI {
>    ASTContext &Context;
> +  llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *>
> RecordToCopyCtor;
> +
>  public:
>    MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
>
> @@ -82,13 +84,26 @@ 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;
> -  }
> +  }
> +
> +  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();
>
> Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=231499&r1=231498&r2=231499&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
> +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Fri Mar  6 12:53:55 2015
> @@ -114,8 +114,8 @@ public:
>                            uint32_t NumEntries, raw_ostream &Out) override;
>    void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
>                                     raw_ostream &Out) override;
> -  void mangleCXXCatchableType(QualType T, uint32_t Size,
> -                              raw_ostream &Out) override;
> +  void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
> +                              uint32_t Size, raw_ostream &Out) override;
>    void mangleCXXRTTI(QualType T, raw_ostream &Out) override;
>    void mangleCXXRTTIName(QualType T, raw_ostream &Out) override;
>    void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived,
> @@ -2307,13 +2307,25 @@ void MicrosoftMangleContextImpl::mangleC
>    Mangler.mangleType(T, SourceRange(),
> MicrosoftCXXNameMangler::QMM_Result);
>  }
>
> -void MicrosoftMangleContextImpl::mangleCXXCatchableType(QualType T,
> -                                                        uint32_t Size,
> -                                                        raw_ostream &Out)
> {
> +void MicrosoftMangleContextImpl::mangleCXXCatchableType(
> +    QualType T, const CXXConstructorDecl *CD, uint32_t Size, raw_ostream
> &Out) {
>    MicrosoftCXXNameMangler Mangler(*this, Out);
> -  Mangler.getStream() << "_CT??_R0";
> -  Mangler.mangleType(T, SourceRange(),
> MicrosoftCXXNameMangler::QMM_Result);
> -  Mangler.getStream() << "@8";
> +  Mangler.getStream() << "_CT";
> +
> +  llvm::SmallString<64> RTTIMangling;
> +  {
> +    llvm::raw_svector_ostream Stream(RTTIMangling);
> +    mangleCXXRTTI(T, Stream);
> +  }
> +  Mangler.getStream() << RTTIMangling.substr(1);
> +
> +  llvm::SmallString<64> CopyCtorMangling;
> +  if (CD) {
> +    llvm::raw_svector_ostream Stream(CopyCtorMangling);
> +    mangleCXXCtor(CD, Ctor_Complete, Stream);
> +  }
> +  Mangler.getStream() << CopyCtorMangling.substr(1);
> +
>    Mangler.getStream() << Size;
>  }
>
>
> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=231499&r1=231498&r2=231499&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Fri Mar  6 12:53:55 2015
> @@ -17,6 +17,7 @@
>  #include "CGCXXABI.h"
>  #include "CGVTables.h"
>  #include "CodeGenModule.h"
> +#include "CodeGenTypes.h"
>  #include "TargetInfo.h"
>  #include "clang/AST/Decl.h"
>  #include "clang/AST/DeclCXX.h"
> @@ -3225,11 +3226,14 @@ llvm::Constant *MicrosoftCXXABI::getCatc
>                                                    uint32_t VBIndex) {
>    assert(!T->isReferenceType());
>
> +  CXXRecordDecl *RD = T->getAsCXXRecordDecl();
> +  const CXXConstructorDecl *CD =
> +      RD ? CGM.getContext().getCopyConstructorForExceptionObject(RD) :
> nullptr;
>    uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
>    SmallString<256> MangledName;
>    {
>      llvm::raw_svector_ostream Out(MangledName);
> -    getMangleContext().mangleCXXCatchableType(T, Size, Out);
> +    getMangleContext().mangleCXXCatchableType(T, CD, Size, Out);
>    }
>    if (llvm::GlobalVariable *GV =
> CGM.getModule().getNamedGlobal(MangledName))
>      return getImageRelativeConstant(GV);
> @@ -3241,16 +3245,15 @@ llvm::Constant *MicrosoftCXXABI::getCatc
>    // The runtime is responsible for calling the copy constructor if the
>    // exception is caught by value.
>    llvm::Constant *CopyCtor =
> -
> getImageRelativeConstant(llvm::Constant::getNullValue(CGM.Int8PtrTy));
> +      CD ? llvm::ConstantExpr::getBitCast(
> +               CGM.getAddrOfCXXStructor(CD, StructorType::Complete),
> +               CGM.Int8PtrTy)
> +         : llvm::Constant::getNullValue(CGM.Int8PtrTy);
> +  CopyCtor = getImageRelativeConstant(CopyCtor);
>
> -  bool IsScalar = true;
> +  bool IsScalar = !RD;
>    bool HasVirtualBases = false;
>    bool IsStdBadAlloc = false; // std::bad_alloc is special for some
> reason.
> -  if (T->getAsCXXRecordDecl()) {
> -    IsScalar = false;
> -    // TODO: Fill in the CopyCtor here!  This is not trivial due to
> -    // copy-constructors possessing things like default arguments.
> -  }
>    QualType PointeeType = T;
>    if (T->isPointerType())
>      PointeeType = T->getPointeeType();
>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=231499&r1=231498&r2=231499&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Mar  6 12:53:55 2015
> @@ -657,6 +657,55 @@ ExprResult Sema::BuildCXXThrow(SourceLoc
>        CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope);
>  }
>
> +static void
> +collectPublicBases(CXXRecordDecl *RD,
> +                   llvm::DenseMap<CXXRecordDecl *, unsigned>
> &SubobjectsSeen,
> +                   llvm::SmallPtrSetImpl<CXXRecordDecl *> &VBases,
> +                   llvm::SetVector<CXXRecordDecl *> &PublicSubobjectsSeen,
> +                   bool ParentIsPublic) {
> +  for (const CXXBaseSpecifier &BS : RD->bases()) {
> +    CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl();
> +    bool NewSubobject;
> +    // Virtual bases constitute the same subobject.  Non-virtual bases are
> +    // always distinct subobjects.
> +    if (BS.isVirtual())
> +      NewSubobject = VBases.insert(BaseDecl).second;
> +    else
> +      NewSubobject = true;
> +
> +    if (NewSubobject)
> +      ++SubobjectsSeen[BaseDecl];
> +
> +    // Only add subobjects which have public access throughout the entire
> chain.
> +    bool PublicPath = ParentIsPublic && BS.getAccessSpecifier() ==
> AS_public;
> +    if (PublicPath)
> +      PublicSubobjectsSeen.insert(BaseDecl);
> +
> +    // Recurse on to each base subobject.
> +    collectPublicBases(BaseDecl, SubobjectsSeen, VBases,
> PublicSubobjectsSeen,
> +                       PublicPath);
> +  }
> +}
> +
> +static void getUnambiguousPublicSubobjects(
> +    CXXRecordDecl *RD, llvm::SmallVectorImpl<CXXRecordDecl *> &Objects) {
> +  llvm::DenseMap<CXXRecordDecl *, unsigned> SubobjectsSeen;
> +  llvm::SmallSet<CXXRecordDecl *, 2> VBases;
> +  llvm::SetVector<CXXRecordDecl *> PublicSubobjectsSeen;
> +  SubobjectsSeen[RD] = 1;
> +  PublicSubobjectsSeen.insert(RD);
> +  collectPublicBases(RD, SubobjectsSeen, VBases, PublicSubobjectsSeen,
> +                     /*ParentIsPublic=*/true);
> +
> +  for (CXXRecordDecl *PublicSubobject : PublicSubobjectsSeen) {
> +    // Skip ambiguous objects.
> +    if (SubobjectsSeen[PublicSubobject] > 1)
> +      continue;
> +
> +    Objects.push_back(PublicSubobject);
> +  }
> +}
> +
>  /// CheckCXXThrowOperand - Validate the operand of a throw.
>  ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E,
>                                        bool IsThrownVarInScope) {
> @@ -723,18 +772,29 @@ ExprResult Sema::CheckCXXThrowOperand(So
>      return E;
>
>    // If the class has a destructor, we must be able to call it.
> -  if (RD->hasIrrelevantDestructor())
> -    return E;
> +  if (!RD->hasIrrelevantDestructor()) {
> +    if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) {
> +      MarkFunctionReferenced(E->getExprLoc(), Destructor);
> +      CheckDestructorAccess(E->getExprLoc(), Destructor,
> +                            PDiag(diag::err_access_dtor_exception) << Ty);
> +      if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
> +        return ExprError();
> +    }
> +  }
>
> -  CXXDestructorDecl *Destructor = LookupDestructor(RD);
> -  if (!Destructor)
> -    return E;
> +  if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
> +    llvm::SmallVector<CXXRecordDecl *, 2> UnambiguousPublicSubobjects;
> +    getUnambiguousPublicSubobjects(RD, UnambiguousPublicSubobjects);
> +    for (CXXRecordDecl *Subobject : UnambiguousPublicSubobjects) {
> +      if (CXXConstructorDecl *CD = LookupCopyingConstructor(Subobject,
> 0)) {
> +        if (CD->isTrivial())
> +          continue;
>

Is this necessary? MarkFunctionReferenced checks this for constructors
already. If it is necessary, do yo need to check for ||
hasAttr<DLLExportAttr> here? Same question for destructors above (think of
an explicit defaulted protected dtor, which is trivial but not irrelevant.)


> +        MarkFunctionReferenced(E->getExprLoc(), CD);
> +        Context.addCopyConstructorForExceptionObject(Subobject, CD);
> +      }
> +    }
> +  }
>
> -  MarkFunctionReferenced(E->getExprLoc(), Destructor);
> -  CheckDestructorAccess(E->getExprLoc(), Destructor,
> -                        PDiag(diag::err_access_dtor_exception) << Ty);
> -  if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
> -    return ExprError();
>    return E;
>  }
>
>
> Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp?rev=231499&r1=231498&r2=231499&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp Fri Mar  6 12:53:55
> 2015
> @@ -1,16 +1,16 @@
>  // RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 %s
> -fcxx-exceptions | FileCheck %s
>
>  // CHECK-DAG: @"\01??_R0?AUY@@@8" = linkonce_odr global
> %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8]
> c".?AUY@@\00" }, comdat
> -// CHECK-DAG: @"_CT??_R0?AUY@@@88" = linkonce_odr unnamed_addr constant
> %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7*
> @"\01??_R0?AUY@@@8" to i8*), i32 0, i32 -1, i32 0, i32 8, i8* null },
> comdat
> +// CHECK-DAG: @"_CT??_R0?AUY@@@8??0Y@@QAE at ABU0@@Z8" = linkonce_odr
> unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast
> (%rtti.TypeDescriptor7* @"\01??_R0?AUY@@@8" to i8*), i32 0, i32 -1, i32
> 0, i32 8, i8* bitcast (%struct.Y* (%struct.Y*, %struct.Y*, i32)* @"\01??0Y@
> @QAE at ABU0@@Z" to i8*) }, comdat
>  // CHECK-DAG: @"\01??_R0?AUZ@@@8" = linkonce_odr global
> %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8]
> c".?AUZ@@\00" }, comdat
>  // CHECK-DAG: @"_CT??_R0?AUZ@@@81" = linkonce_odr unnamed_addr constant
> %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7*
> @"\01??_R0?AUZ@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* null },
> comdat
>  // CHECK-DAG: @"\01??_R0?AUW@@@8" = linkonce_odr global
> %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8]
> c".?AUW@@\00" }, comdat
> -// CHECK-DAG: @"_CT??_R0?AUW@@@84" = linkonce_odr unnamed_addr constant
> %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7*
> @"\01??_R0?AUW@@@8" to i8*), i32 4, i32 -1, i32 0, i32 4, i8* null },
> comdat
> +// CHECK-DAG: @"_CT??_R0?AUW@@@8??0W@@QAE at ABU0@@Z4" = linkonce_odr
> unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast
> (%rtti.TypeDescriptor7* @"\01??_R0?AUW@@@8" to i8*), i32 4, i32 -1, i32
> 0, i32 4, i8* bitcast (%struct.W* (%struct.W*, %struct.W*, i32)* @"\01??0W@
> @QAE at ABU0@@Z" to i8*) }, comdat
>  // CHECK-DAG: @"\01??_R0?AUM@@@8" = linkonce_odr global
> %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8]
> c".?AUM@@\00" }, comdat
>  // CHECK-DAG: @"_CT??_R0?AUM@@@81" = linkonce_odr unnamed_addr constant
> %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7*
> @"\01??_R0?AUM@@@8" to i8*), i32 8, i32 -1, i32 0, i32 1, i8* null },
> comdat
>  // CHECK-DAG: @"\01??_R0?AUV@@@8" = linkonce_odr global
> %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8]
> c".?AUV@@\00" }, comdat
>  // CHECK-DAG: @"_CT??_R0?AUV@@@81" = linkonce_odr unnamed_addr constant
> %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7*
> @"\01??_R0?AUV@@@8" to i8*), i32 0, i32 4, i32 4, i32 1, i8* null },
> comdat
> -// CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant
> %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*]
> [%eh.CatchableType* @"_CT??_R0?AUY@@@88", %eh.CatchableType*
> @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@84",
> %eh.CatchableType* @"_CT??_R0?AUM@@@81", %eh.CatchableType*
> @"_CT??_R0?AUV@@@81"] }, comdat
> +// CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant
> %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*]
> [%eh.CatchableType* @"_CT??_R0?AUY@@@8??0Y@@QAE at ABU0@@Z8",
> %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType*
> @"_CT??_R0?AUW@@@8??0W@@QAE at ABU0@@Z4", %eh.CatchableType* @"_CT??_R0?AUM@@@81",
> %eh.CatchableType* @"_CT??_R0?AUV@@@81"] }, comdat
>  // CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant
> %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"\01??_DY@@QAE at XZ"
> to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@"
> to i8*) }, comdat
>
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150306/c9876154/attachment.html>


More information about the cfe-commits mailing list