r212435 - CodeGen: Refactor RTTI emission

David Majnemer david.majnemer at gmail.com
Sun Jul 6 23:20:48 PDT 2014


Author: majnemer
Date: Mon Jul  7 01:20:47 2014
New Revision: 212435

URL: http://llvm.org/viewvc/llvm-project?rev=212435&view=rev
Log:
CodeGen: Refactor RTTI emission

Let's not expose ABI specific minutia inside of CodeGenModule and Type.
Instead, let's abstract it through CXXABI.

This gets rid of:
CodeGenModule::getCompleteObjectLocator,
CodeGenModule::EmitFundamentalTypeDescriptor{s,},
CodeGenModule::getMSTypeDescriptor,
CodeGenModule::getMSCompleteObjectLocator,
CGCXXABI::shouldRTTIBeUnique,
CGCXXABI::classifyRTTIUniqueness.

CGRTTI was *almost* entirely centered around providing Itanium-style
RTTI information.  Instead of providing interfaces that only it
consumes, move it to the ItaniumCXXABI implementation file.  This allows
it to have access to Itanium-specific implementation details without
providing useless expansion points for the Microsoft ABI side.

Differential Revision: http://reviews.llvm.org/D4261

Removed:
    cfe/trunk/lib/CodeGen/CGRTTI.cpp
    cfe/trunk/lib/CodeGen/MicrosoftRTTI.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGCXXABI.cpp
    cfe/trunk/lib/CodeGen/CGCXXABI.h
    cfe/trunk/lib/CodeGen/CMakeLists.txt
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.cpp?rev=212435&r1=212434&r2=212435&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.cpp Mon Jul  7 01:20:47 2014
@@ -325,31 +325,3 @@ LValue CGCXXABI::EmitThreadLocalVarDeclL
 bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
   return false;
 }
-
-/// What sort of uniqueness rules should we use for the RTTI for the
-/// given type?
-CGCXXABI::RTTIUniquenessKind
-CGCXXABI::classifyRTTIUniqueness(QualType CanTy,
-                                 llvm::GlobalValue::LinkageTypes Linkage) {
-  if (shouldRTTIBeUnique())
-    return RUK_Unique;
-
-  // It's only necessary for linkonce_odr or weak_odr linkage.
-  if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
-      Linkage != llvm::GlobalValue::WeakODRLinkage)
-    return RUK_Unique;
-
-  // It's only necessary with default visibility.
-  if (CanTy->getVisibility() != DefaultVisibility)
-    return RUK_Unique;
-
-  // If we're not required to publish this symbol, hide it.
-  if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
-    return RUK_NonUniqueHidden;
-
-  // If we're required to publish this symbol, as we might be under an
-  // explicit instantiation, leave it with default visibility but
-  // enable string-comparisons.
-  assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
-  return RUK_NonUniqueVisible;
-}

Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=212435&r1=212434&r2=212435&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Mon Jul  7 01:20:47 2014
@@ -207,6 +207,8 @@ public:
                                               llvm::Value *ptr,
                                               QualType type) = 0;
 
+  virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0;
+
   virtual bool shouldTypeidBeNullChecked(bool IsDeref,
                                          QualType SrcRecordTy) = 0;
   virtual void EmitBadTypeidCall(CodeGenFunction &CGF) = 0;
@@ -516,36 +518,6 @@ public:
   virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
                                               const VarDecl *VD,
                                               QualType LValType);
-
-  /**************************** RTTI Uniqueness ******************************/
-
-protected:
-  /// Returns true if the ABI requires RTTI type_info objects to be unique
-  /// across a program.
-  virtual bool shouldRTTIBeUnique() { return true; }
-
-public:
-  /// What sort of unique-RTTI behavior should we use?
-  enum RTTIUniquenessKind {
-    /// We are guaranteeing, or need to guarantee, that the RTTI string
-    /// is unique.
-    RUK_Unique,
-
-    /// We are not guaranteeing uniqueness for the RTTI string, so we
-    /// can demote to hidden visibility but must use string comparisons.
-    RUK_NonUniqueHidden,
-
-    /// We are not guaranteeing uniqueness for the RTTI string, so we
-    /// have to use string comparisons, but we also have to emit it with
-    /// non-hidden visibility.
-    RUK_NonUniqueVisible
-  };
-
-  /// Return the required visibility status for the given type and linkage in
-  /// the current ABI.
-  RTTIUniquenessKind
-  classifyRTTIUniqueness(QualType CanTy,
-                         llvm::GlobalValue::LinkageTypes Linkage);
 };
 
 // Create an instance of a C++ ABI class:

Removed: cfe/trunk/lib/CodeGen/CGRTTI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRTTI.cpp?rev=212434&view=auto
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRTTI.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRTTI.cpp (removed)
@@ -1,998 +0,0 @@
-//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with C++ code generation of RTTI descriptors.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenModule.h"
-#include "CGCXXABI.h"
-#include "CGObjCRuntime.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/AST/Type.h"
-#include "clang/Frontend/CodeGenOptions.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-namespace {
-class ItaniumRTTIBuilder {
-  CodeGenModule &CGM;  // Per-module state.
-  llvm::LLVMContext &VMContext;
-  
-  /// Fields - The fields of the RTTI descriptor currently being built.
-  SmallVector<llvm::Constant *, 16> Fields;
-
-  /// GetAddrOfTypeName - Returns the mangled type name of the given type.
-  llvm::GlobalVariable *
-  GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
-
-  /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI 
-  /// descriptor of the given type.
-  llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
-  
-  /// BuildVTablePointer - Build the vtable pointer for the given type.
-  void BuildVTablePointer(const Type *Ty);
-  
-  /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
-  /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
-  void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
-  
-  /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
-  /// classes with bases that do not satisfy the abi::__si_class_type_info 
-  /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
-  void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
-  
-  /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
-  /// for pointer types.
-  void BuildPointerTypeInfo(QualType PointeeTy);
-
-  /// BuildObjCObjectTypeInfo - Build the appropriate kind of
-  /// type_info for an object type.
-  void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);
-  
-  /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
-  /// struct, used for member pointer types.
-  void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
-  
-public:
-  ItaniumRTTIBuilder(CodeGenModule &CGM) : CGM(CGM), 
-    VMContext(CGM.getModule().getContext()) { }
-
-  // Pointer type info flags.
-  enum {
-    /// PTI_Const - Type has const qualifier.
-    PTI_Const = 0x1,
-    
-    /// PTI_Volatile - Type has volatile qualifier.
-    PTI_Volatile = 0x2,
-    
-    /// PTI_Restrict - Type has restrict qualifier.
-    PTI_Restrict = 0x4,
-    
-    /// PTI_Incomplete - Type is incomplete.
-    PTI_Incomplete = 0x8,
-    
-    /// PTI_ContainingClassIncomplete - Containing class is incomplete.
-    /// (in pointer to member).
-    PTI_ContainingClassIncomplete = 0x10
-  };
-  
-  // VMI type info flags.
-  enum {
-    /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
-    VMI_NonDiamondRepeat = 0x1,
-    
-    /// VMI_DiamondShaped - Class is diamond shaped.
-    VMI_DiamondShaped = 0x2
-  };
-  
-  // Base class type info flags.
-  enum {
-    /// BCTI_Virtual - Base class is virtual.
-    BCTI_Virtual = 0x1,
-    
-    /// BCTI_Public - Base class is public.
-    BCTI_Public = 0x2
-  };
-  
-  /// BuildTypeInfo - Build the RTTI type info struct for the given type.
-  ///
-  /// \param Force - true to force the creation of this RTTI value
-  llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
-};
-}
-
-llvm::GlobalVariable *
-ItaniumRTTIBuilder::GetAddrOfTypeName(QualType Ty,
-                               llvm::GlobalVariable::LinkageTypes Linkage) {
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  // We know that the mangled name of the type starts at index 4 of the
-  // mangled name of the typename, so we can just index into it in order to
-  // get the mangled name of the type.
-  llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
-                                                            Name.substr(4));
-
-  llvm::GlobalVariable *GV = 
-    CGM.CreateOrReplaceCXXRuntimeVariable(Name, Init->getType(), Linkage);
-
-  GV->setInitializer(Init);
-
-  return GV;
-}
-
-llvm::Constant *
-ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
-  // Mangle the RTTI name.
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  // Look for an existing global.
-  llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
-  
-  if (!GV) {
-    // Create a new global variable.
-    GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
-                                  /*Constant=*/true,
-                                  llvm::GlobalValue::ExternalLinkage, nullptr,
-                                  Name);
-  }
-  
-  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
-}
-
-/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
-/// info for that type is defined in the standard library.
-static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
-  // Itanium C++ ABI 2.9.2:
-  //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
-  //   the run-time support library. Specifically, the run-time support
-  //   library should contain type_info objects for the types X, X* and 
-  //   X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,
-  //   unsigned char, signed char, short, unsigned short, int, unsigned int,
-  //   long, unsigned long, long long, unsigned long long, float, double,
-  //   long double, char16_t, char32_t, and the IEEE 754r decimal and 
-  //   half-precision floating point types.
-  switch (Ty->getKind()) {
-    case BuiltinType::Void:
-    case BuiltinType::NullPtr:
-    case BuiltinType::Bool:
-    case BuiltinType::WChar_S:
-    case BuiltinType::WChar_U:
-    case BuiltinType::Char_U:
-    case BuiltinType::Char_S:
-    case BuiltinType::UChar:
-    case BuiltinType::SChar:
-    case BuiltinType::Short:
-    case BuiltinType::UShort:
-    case BuiltinType::Int:
-    case BuiltinType::UInt:
-    case BuiltinType::Long:
-    case BuiltinType::ULong:
-    case BuiltinType::LongLong:
-    case BuiltinType::ULongLong:
-    case BuiltinType::Half:
-    case BuiltinType::Float:
-    case BuiltinType::Double:
-    case BuiltinType::LongDouble:
-    case BuiltinType::Char16:
-    case BuiltinType::Char32:
-    case BuiltinType::Int128:
-    case BuiltinType::UInt128:
-    case BuiltinType::OCLImage1d:
-    case BuiltinType::OCLImage1dArray:
-    case BuiltinType::OCLImage1dBuffer:
-    case BuiltinType::OCLImage2d:
-    case BuiltinType::OCLImage2dArray:
-    case BuiltinType::OCLImage3d:
-    case BuiltinType::OCLSampler:
-    case BuiltinType::OCLEvent:
-      return true;
-      
-    case BuiltinType::Dependent:
-#define BUILTIN_TYPE(Id, SingletonId)
-#define PLACEHOLDER_TYPE(Id, SingletonId) \
-    case BuiltinType::Id:
-#include "clang/AST/BuiltinTypes.def"
-      llvm_unreachable("asking for RRTI for a placeholder type!");
-      
-    case BuiltinType::ObjCId:
-    case BuiltinType::ObjCClass:
-    case BuiltinType::ObjCSel:
-      llvm_unreachable("FIXME: Objective-C types are unsupported!");
-  }
-
-  llvm_unreachable("Invalid BuiltinType Kind!");
-}
-
-static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
-  QualType PointeeTy = PointerTy->getPointeeType();
-  const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
-  if (!BuiltinTy)
-    return false;
-    
-  // Check the qualifiers.
-  Qualifiers Quals = PointeeTy.getQualifiers();
-  Quals.removeConst();
-    
-  if (!Quals.empty())
-    return false;
-    
-  return TypeInfoIsInStandardLibrary(BuiltinTy);
-}
-
-/// IsStandardLibraryRTTIDescriptor - Returns whether the type
-/// information for the given type exists in the standard library.
-static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
-  // Type info for builtin types is defined in the standard library.
-  if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
-    return TypeInfoIsInStandardLibrary(BuiltinTy);
-  
-  // Type info for some pointer types to builtin types is defined in the
-  // standard library.
-  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
-    return TypeInfoIsInStandardLibrary(PointerTy);
-
-  return false;
-}
-
-/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
-/// the given type exists somewhere else, and that we should not emit the type
-/// information in this translation unit.  Assumes that it is not a
-/// standard-library type.
-static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
-                                            QualType Ty) {
-  ASTContext &Context = CGM.getContext();
-
-  // If RTTI is disabled, assume it might be disabled in the
-  // translation unit that defines any potential key function, too.
-  if (!Context.getLangOpts().RTTI) return false;
-
-  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
-    if (!RD->hasDefinition())
-      return false;
-
-    if (!RD->isDynamicClass())
-      return false;
-
-    // FIXME: this may need to be reconsidered if the key function
-    // changes.
-    return CGM.getVTables().isVTableExternal(RD);
-  }
-  
-  return false;
-}
-
-/// IsIncompleteClassType - Returns whether the given record type is incomplete.
-static bool IsIncompleteClassType(const RecordType *RecordTy) {
-  return !RecordTy->getDecl()->isCompleteDefinition();
-}  
-
-/// ContainsIncompleteClassType - Returns whether the given type contains an
-/// incomplete class type. This is true if
-///
-///   * The given type is an incomplete class type.
-///   * The given type is a pointer type whose pointee type contains an 
-///     incomplete class type.
-///   * The given type is a member pointer type whose class is an incomplete
-///     class type.
-///   * The given type is a member pointer type whoise pointee type contains an
-///     incomplete class type.
-/// is an indirect or direct pointer to an incomplete class type.
-static bool ContainsIncompleteClassType(QualType Ty) {
-  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
-    if (IsIncompleteClassType(RecordTy))
-      return true;
-  }
-  
-  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
-    return ContainsIncompleteClassType(PointerTy->getPointeeType());
-  
-  if (const MemberPointerType *MemberPointerTy = 
-      dyn_cast<MemberPointerType>(Ty)) {
-    // Check if the class type is incomplete.
-    const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
-    if (IsIncompleteClassType(ClassType))
-      return true;
-    
-    return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
-  }
-  
-  return false;
-}
-
-/// getTypeInfoLinkage - Return the linkage that the type info and type info
-/// name constants should have for the given type.
-llvm::GlobalVariable::LinkageTypes 
-CodeGenModule::getTypeInfoLinkage(QualType Ty) {
-  // Itanium C++ ABI 2.9.5p7:
-  //   In addition, it and all of the intermediate abi::__pointer_type_info 
-  //   structs in the chain down to the abi::__class_type_info for the
-  //   incomplete class type must be prevented from resolving to the 
-  //   corresponding type_info structs for the complete class type, possibly
-  //   by making them local static objects. Finally, a dummy class RTTI is
-  //   generated for the incomplete type that will not resolve to the final 
-  //   complete class RTTI (because the latter need not exist), possibly by 
-  //   making it a local static object.
-  if (ContainsIncompleteClassType(Ty))
-    return llvm::GlobalValue::InternalLinkage;
-  
-  switch (Ty->getLinkage()) {
-  case NoLinkage:
-  case InternalLinkage:
-  case UniqueExternalLinkage:
-    return llvm::GlobalValue::InternalLinkage;
-
-  case VisibleNoLinkage:
-  case ExternalLinkage:
-    if (!getLangOpts().RTTI) {
-      // RTTI is not enabled, which means that this type info struct is going
-      // to be used for exception handling. Give it linkonce_odr linkage.
-      return llvm::GlobalValue::LinkOnceODRLinkage;
-    }
-
-    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
-      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
-      if (RD->hasAttr<WeakAttr>())
-        return llvm::GlobalValue::WeakODRLinkage;
-      if (RD->isDynamicClass())
-        return getVTableLinkage(RD);
-    }
-
-    return llvm::GlobalValue::LinkOnceODRLinkage;
-  }
-
-  llvm_unreachable("Invalid linkage!");
-}
-
-// CanUseSingleInheritance - Return whether the given record decl has a "single, 
-// public, non-virtual base at offset zero (i.e. the derived class is dynamic 
-// iff the base is)", according to Itanium C++ ABI, 2.95p6b.
-static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
-  // Check the number of bases.
-  if (RD->getNumBases() != 1)
-    return false;
-  
-  // Get the base.
-  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
-  
-  // Check that the base is not virtual.
-  if (Base->isVirtual())
-    return false;
-  
-  // Check that the base is public.
-  if (Base->getAccessSpecifier() != AS_public)
-    return false;
-  
-  // Check that the class is dynamic iff the base is.
-  const CXXRecordDecl *BaseDecl = 
-    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-  if (!BaseDecl->isEmpty() && 
-      BaseDecl->isDynamicClass() != RD->isDynamicClass())
-    return false;
-  
-  return true;
-}
-
-void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
-  // abi::__class_type_info.
-  static const char * const ClassTypeInfo =
-    "_ZTVN10__cxxabiv117__class_type_infoE";
-  // abi::__si_class_type_info.
-  static const char * const SIClassTypeInfo =
-    "_ZTVN10__cxxabiv120__si_class_type_infoE";
-  // abi::__vmi_class_type_info.
-  static const char * const VMIClassTypeInfo =
-    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
-
-  const char *VTableName = nullptr;
-
-  switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
-
-  case Type::LValueReference:
-  case Type::RValueReference:
-    llvm_unreachable("References shouldn't get here");
-
-  case Type::Auto:
-    llvm_unreachable("Undeduced auto type shouldn't get here");
-
-  case Type::Builtin:
-  // GCC treats vector and complex types as fundamental types.
-  case Type::Vector:
-  case Type::ExtVector:
-  case Type::Complex:
-  case Type::Atomic:
-  // FIXME: GCC treats block pointers as fundamental types?!
-  case Type::BlockPointer:
-    // abi::__fundamental_type_info.
-    VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
-    break;
-
-  case Type::ConstantArray:
-  case Type::IncompleteArray:
-  case Type::VariableArray:
-    // abi::__array_type_info.
-    VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
-    break;
-
-  case Type::FunctionNoProto:
-  case Type::FunctionProto:
-    // abi::__function_type_info.
-    VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
-    break;
-
-  case Type::Enum:
-    // abi::__enum_type_info.
-    VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
-    break;
-
-  case Type::Record: {
-    const CXXRecordDecl *RD = 
-      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
-    
-    if (!RD->hasDefinition() || !RD->getNumBases()) {
-      VTableName = ClassTypeInfo;
-    } else if (CanUseSingleInheritance(RD)) {
-      VTableName = SIClassTypeInfo;
-    } else {
-      VTableName = VMIClassTypeInfo;
-    }
-    
-    break;
-  }
-
-  case Type::ObjCObject:
-    // Ignore protocol qualifiers.
-    Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
-
-    // Handle id and Class.
-    if (isa<BuiltinType>(Ty)) {
-      VTableName = ClassTypeInfo;
-      break;
-    }
-
-    assert(isa<ObjCInterfaceType>(Ty));
-    // Fall through.
-
-  case Type::ObjCInterface:
-    if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
-      VTableName = SIClassTypeInfo;
-    } else {
-      VTableName = ClassTypeInfo;
-    }
-    break;
-
-  case Type::ObjCObjectPointer:
-  case Type::Pointer:
-    // abi::__pointer_type_info.
-    VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
-    break;
-
-  case Type::MemberPointer:
-    // abi::__pointer_to_member_type_info.
-    VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
-    break;
-  }
-
-  llvm::Constant *VTable = 
-    CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);
-    
-  llvm::Type *PtrDiffTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
-
-  // The vtable address point is 2.
-  llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
-  VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);
-  VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
-
-  Fields.push_back(VTable);
-}
-
-llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
-  // We want to operate on the canonical type.
-  Ty = CGM.getContext().getCanonicalType(Ty);
-
-  // Check if we've already emitted an RTTI descriptor for this type.
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
-  if (OldGV && !OldGV->isDeclaration()) {
-    assert(!OldGV->hasAvailableExternallyLinkage() &&
-           "available_externally typeinfos not yet implemented");
-
-    return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);
-  }
-
-  // Check if there is already an external RTTI descriptor for this type.
-  bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
-  if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty)))
-    return GetAddrOfExternalRTTIDescriptor(Ty);
-
-  // Emit the standard library with external linkage.
-  llvm::GlobalVariable::LinkageTypes Linkage;
-  if (IsStdLib)
-    Linkage = llvm::GlobalValue::ExternalLinkage;
-  else
-    Linkage = CGM.getTypeInfoLinkage(Ty);
-
-  // Add the vtable pointer.
-  BuildVTablePointer(cast<Type>(Ty));
-  
-  // And the name.
-  llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
-  llvm::Constant *TypeNameField;
-
-  // If we're supposed to demote the visibility, be sure to set a flag
-  // to use a string comparison for type_info comparisons.
-  CGCXXABI::RTTIUniquenessKind RTTIUniqueness =
-      CGM.getCXXABI().classifyRTTIUniqueness(Ty, Linkage);
-  if (RTTIUniqueness != CGCXXABI::RUK_Unique) {
-    // The flag is the sign bit, which on ARM64 is defined to be clear
-    // for global pointers.  This is very ARM64-specific.
-    TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty);
-    llvm::Constant *flag =
-        llvm::ConstantInt::get(CGM.Int64Ty, ((uint64_t)1) << 63);
-    TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
-    TypeNameField =
-        llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.Int8PtrTy);
-  } else {
-    TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy);
-  }
-  Fields.push_back(TypeNameField);
-
-  switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
-
-  // GCC treats vector types as fundamental types.
-  case Type::Builtin:
-  case Type::Vector:
-  case Type::ExtVector:
-  case Type::Complex:
-  case Type::BlockPointer:
-    // Itanium C++ ABI 2.9.5p4:
-    // abi::__fundamental_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::LValueReference:
-  case Type::RValueReference:
-    llvm_unreachable("References shouldn't get here");
-
-  case Type::Auto:
-    llvm_unreachable("Undeduced auto type shouldn't get here");
-
-  case Type::ConstantArray:
-  case Type::IncompleteArray:
-  case Type::VariableArray:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__array_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::FunctionNoProto:
-  case Type::FunctionProto:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__function_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::Enum:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__enum_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::Record: {
-    const CXXRecordDecl *RD = 
-      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
-    if (!RD->hasDefinition() || !RD->getNumBases()) {
-      // We don't need to emit any fields.
-      break;
-    }
-    
-    if (CanUseSingleInheritance(RD))
-      BuildSIClassTypeInfo(RD);
-    else 
-      BuildVMIClassTypeInfo(RD);
-
-    break;
-  }
-
-  case Type::ObjCObject:
-  case Type::ObjCInterface:
-    BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
-    break;
-
-  case Type::ObjCObjectPointer:
-    BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
-    break; 
-      
-  case Type::Pointer:
-    BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
-    break;
-
-  case Type::MemberPointer:
-    BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
-    break;
-
-  case Type::Atomic:
-    // No fields, at least for the moment.
-    break;
-  }
-
-  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
-
-  llvm::GlobalVariable *GV = 
-    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), 
-                             /*Constant=*/true, Linkage, Init, Name);
-  
-  // If there's already an old global variable, replace it with the new one.
-  if (OldGV) {
-    GV->takeName(OldGV);
-    llvm::Constant *NewPtr = 
-      llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
-    OldGV->replaceAllUsesWith(NewPtr);
-    OldGV->eraseFromParent();
-  }
-
-  // The Itanium ABI specifies that type_info objects must be globally
-  // unique, with one exception: if the type is an incomplete class
-  // type or a (possibly indirect) pointer to one.  That exception
-  // affects the general case of comparing type_info objects produced
-  // by the typeid operator, which is why the comparison operators on
-  // std::type_info generally use the type_info name pointers instead
-  // of the object addresses.  However, the language's built-in uses
-  // of RTTI generally require class types to be complete, even when
-  // manipulating pointers to those class types.  This allows the
-  // implementation of dynamic_cast to rely on address equality tests,
-  // which is much faster.
-
-  // All of this is to say that it's important that both the type_info
-  // object and the type_info name be uniqued when weakly emitted.
-
-  // Give the type_info object and name the formal visibility of the
-  // type itself.
-  llvm::GlobalValue::VisibilityTypes llvmVisibility;
-  if (llvm::GlobalValue::isLocalLinkage(Linkage))
-    // If the linkage is local, only default visibility makes sense.
-    llvmVisibility = llvm::GlobalValue::DefaultVisibility;
-  else if (RTTIUniqueness == CGCXXABI::RUK_NonUniqueHidden)
-    llvmVisibility = llvm::GlobalValue::HiddenVisibility;
-  else
-    llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility());
-  TypeName->setVisibility(llvmVisibility);
-  GV->setVisibility(llvmVisibility);
-
-  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
-}
-
-/// ComputeQualifierFlags - Compute the pointer type info flags from the
-/// given qualifier.
-static unsigned ComputeQualifierFlags(Qualifiers Quals) {
-  unsigned Flags = 0;
-
-  if (Quals.hasConst())
-    Flags |= ItaniumRTTIBuilder::PTI_Const;
-  if (Quals.hasVolatile())
-    Flags |= ItaniumRTTIBuilder::PTI_Volatile;
-  if (Quals.hasRestrict())
-    Flags |= ItaniumRTTIBuilder::PTI_Restrict;
-
-  return Flags;
-}
-
-/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
-/// for the given Objective-C object type.
-void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
-  // Drop qualifiers.
-  const Type *T = OT->getBaseType().getTypePtr();
-  assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
-
-  // The builtin types are abi::__class_type_infos and don't require
-  // extra fields.
-  if (isa<BuiltinType>(T)) return;
-
-  ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();
-  ObjCInterfaceDecl *Super = Class->getSuperClass();
-
-  // Root classes are also __class_type_info.
-  if (!Super) return;
-
-  QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);
-
-  // Everything else is single inheritance.
-  llvm::Constant *BaseTypeInfo = ItaniumRTTIBuilder(CGM).BuildTypeInfo(SuperTy);
-  Fields.push_back(BaseTypeInfo);
-}
-
-/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
-/// inheritance, according to the Itanium C++ ABI, 2.95p6b.
-void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
-  // Itanium C++ ABI 2.9.5p6b:
-  // It adds to abi::__class_type_info a single member pointing to the 
-  // type_info structure for the base type,
-  llvm::Constant *BaseTypeInfo = 
-    ItaniumRTTIBuilder(CGM).BuildTypeInfo(RD->bases_begin()->getType());
-  Fields.push_back(BaseTypeInfo);
-}
-
-namespace {
-  /// SeenBases - Contains virtual and non-virtual bases seen when traversing
-  /// a class hierarchy.
-  struct SeenBases {
-    llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
-    llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
-  };
-}
-
-/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
-/// abi::__vmi_class_type_info.
-///
-static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, 
-                                             SeenBases &Bases) {
-  
-  unsigned Flags = 0;
-  
-  const CXXRecordDecl *BaseDecl = 
-    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-  
-  if (Base->isVirtual()) {
-    // Mark the virtual base as seen.
-    if (!Bases.VirtualBases.insert(BaseDecl)) {
-      // If this virtual base has been seen before, then the class is diamond
-      // shaped.
-      Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
-    } else {
-      if (Bases.NonVirtualBases.count(BaseDecl))
-        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
-    }
-  } else {
-    // Mark the non-virtual base as seen.
-    if (!Bases.NonVirtualBases.insert(BaseDecl)) {
-      // If this non-virtual base has been seen before, then the class has non-
-      // diamond shaped repeated inheritance.
-      Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
-    } else {
-      if (Bases.VirtualBases.count(BaseDecl))
-        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
-    }
-  }
-
-  // Walk all bases.
-  for (const auto &I : BaseDecl->bases()) 
-    Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
-  
-  return Flags;
-}
-
-static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
-  unsigned Flags = 0;
-  SeenBases Bases;
-  
-  // Walk all bases.
-  for (const auto &I : RD->bases()) 
-    Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
-  
-  return Flags;
-}
-
-/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
-/// classes with bases that do not satisfy the abi::__si_class_type_info 
-/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
-void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __flags is a word with flags describing details about the class 
-  //   structure, which may be referenced by using the __flags_masks 
-  //   enumeration. These flags refer to both direct and indirect bases. 
-  unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __base_count is a word with the number of direct proper base class 
-  //   descriptions that follow.
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
-  
-  if (!RD->getNumBases())
-    return;
-  
-  llvm::Type *LongLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().LongTy);
-
-  // Now add the base class descriptions.
-  
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __base_info[] is an array of base class descriptions -- one for every 
-  //   direct proper base. Each description is of the type:
-  //
-  //   struct abi::__base_class_type_info {
-  //   public:
-  //     const __class_type_info *__base_type;
-  //     long __offset_flags;
-  //
-  //     enum __offset_flags_masks {
-  //       __virtual_mask = 0x1,
-  //       __public_mask = 0x2,
-  //       __offset_shift = 8
-  //     };
-  //   };
-  for (const auto &Base : RD->bases()) {
-    // The __base_type member points to the RTTI for the base type.
-    Fields.push_back(ItaniumRTTIBuilder(CGM).BuildTypeInfo(Base.getType()));
-
-    const CXXRecordDecl *BaseDecl = 
-      cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
-
-    int64_t OffsetFlags = 0;
-    
-    // All but the lower 8 bits of __offset_flags are a signed offset. 
-    // For a non-virtual base, this is the offset in the object of the base
-    // subobject. For a virtual base, this is the offset in the virtual table of
-    // the virtual base offset for the virtual base referenced (negative).
-    CharUnits Offset;
-    if (Base.isVirtual())
-      Offset = 
-        CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
-    else {
-      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
-      Offset = Layout.getBaseClassOffset(BaseDecl);
-    };
-    
-    OffsetFlags = uint64_t(Offset.getQuantity()) << 8;
-    
-    // The low-order byte of __offset_flags contains flags, as given by the 
-    // masks from the enumeration __offset_flags_masks.
-    if (Base.isVirtual())
-      OffsetFlags |= BCTI_Virtual;
-    if (Base.getAccessSpecifier() == AS_public)
-      OffsetFlags |= BCTI_Public;
-
-    Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
-  }
-}
-
-/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
-/// used for pointer types.
-void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
-  Qualifiers Quals;
-  QualType UnqualifiedPointeeTy = 
-    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __flags is a flag word describing the cv-qualification and other 
-  //   attributes of the type pointed to
-  unsigned Flags = ComputeQualifierFlags(Quals);
-
-  // Itanium C++ ABI 2.9.5p7:
-  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
-  //   incomplete class type, the incomplete target type flag is set. 
-  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
-    Flags |= PTI_Incomplete;
-
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //  __pointee is a pointer to the std::type_info derivation for the 
-  //  unqualified type being pointed to.
-  llvm::Constant *PointeeTypeInfo = 
-    ItaniumRTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
-  Fields.push_back(PointeeTypeInfo);
-}
-
-/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
-/// struct, used for member pointer types.
-void
-ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
-  QualType PointeeTy = Ty->getPointeeType();
-  
-  Qualifiers Quals;
-  QualType UnqualifiedPointeeTy = 
-    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __flags is a flag word describing the cv-qualification and other 
-  //   attributes of the type pointed to.
-  unsigned Flags = ComputeQualifierFlags(Quals);
-
-  const RecordType *ClassType = cast<RecordType>(Ty->getClass());
-
-  // Itanium C++ ABI 2.9.5p7:
-  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
-  //   incomplete class type, the incomplete target type flag is set. 
-  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
-    Flags |= PTI_Incomplete;
-
-  if (IsIncompleteClassType(ClassType))
-    Flags |= PTI_ContainingClassIncomplete;
-  
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __pointee is a pointer to the std::type_info derivation for the 
-  //   unqualified type being pointed to.
-  llvm::Constant *PointeeTypeInfo = 
-    ItaniumRTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
-  Fields.push_back(PointeeTypeInfo);
-
-  // Itanium C++ ABI 2.9.5p9:
-  //   __context is a pointer to an abi::__class_type_info corresponding to the
-  //   class type containing the member pointed to 
-  //   (e.g., the "A" in "int A::*").
-  Fields.push_back(
-      ItaniumRTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));
-}
-
-llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
-                                                       bool ForEH) {
-  // Return a bogus pointer if RTTI is disabled, unless it's for EH.
-  // FIXME: should we even be calling this method if RTTI is disabled
-  // and it's not for EH?
-  if (!ForEH && !getLangOpts().RTTI)
-    return llvm::Constant::getNullValue(Int8PtrTy);
-  
-  if (ForEH && Ty->isObjCObjectPointerType() &&
-      LangOpts.ObjCRuntime.isGNUFamily())
-    return ObjCRuntime->GetEHType(Ty);
-
-  if (getTarget().getCXXABI().isMicrosoft())
-    return getMSTypeDescriptor(Ty);
-  return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
-}
-
-void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) {
-  QualType PointerType = Context.getPointerType(Type);
-  QualType PointerTypeConst = Context.getPointerType(Type.withConst());
-  ItaniumRTTIBuilder(*this).BuildTypeInfo(Type, true);
-  ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType, true);
-  ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);
-}
-
-void CodeGenModule::EmitFundamentalRTTIDescriptors() {
-  QualType FundamentalTypes[] = { Context.VoidTy, Context.NullPtrTy,
-                                  Context.BoolTy, Context.WCharTy,
-                                  Context.CharTy, Context.UnsignedCharTy,
-                                  Context.SignedCharTy, Context.ShortTy, 
-                                  Context.UnsignedShortTy, Context.IntTy,
-                                  Context.UnsignedIntTy, Context.LongTy, 
-                                  Context.UnsignedLongTy, Context.LongLongTy, 
-                                  Context.UnsignedLongLongTy,
-                                  Context.HalfTy, Context.FloatTy,
-                                  Context.DoubleTy, Context.LongDoubleTy,
-                                  Context.Char16Ty, Context.Char32Ty };
-  for (unsigned i = 0; i < llvm::array_lengthof(FundamentalTypes); ++i)
-    EmitFundamentalRTTIDescriptor(FundamentalTypes[i]);
-}

Modified: cfe/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CMakeLists.txt?rev=212435&r1=212434&r2=212435&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ cfe/trunk/lib/CodeGen/CMakeLists.txt Mon Jul  7 01:20:47 2014
@@ -45,7 +45,6 @@ add_clang_library(clangCodeGen
   CGObjCRuntime.cpp
   CGOpenCLRuntime.cpp
   CGOpenMPRuntime.cpp
-  CGRTTI.cpp
   CGRecordLayoutBuilder.cpp
   CGStmt.cpp
   CGStmtOpenMP.cpp
@@ -60,7 +59,6 @@ add_clang_library(clangCodeGen
   CodeGenTypes.cpp
   ItaniumCXXABI.cpp
   MicrosoftCXXABI.cpp
-  MicrosoftRTTI.cpp
   ModuleBuilder.cpp
   TargetInfo.cpp
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=212435&r1=212434&r2=212435&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Jul  7 01:20:47 2014
@@ -3389,3 +3389,19 @@ llvm::Constant *CodeGenModule::EmitUuido
 
   return llvm::ConstantStruct::getAnon(Fields);
 }
+
+llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
+                                                       bool ForEH) {
+  // Return a bogus pointer if RTTI is disabled, unless it's for EH.
+  // FIXME: should we even be calling this method if RTTI is disabled
+  // and it's not for EH?
+  if (!ForEH && !getLangOpts().RTTI)
+    return llvm::Constant::getNullValue(Int8PtrTy);
+  
+  if (ForEH && Ty->isObjCObjectPointerType() &&
+      LangOpts.ObjCRuntime.isGNUFamily())
+    return ObjCRuntime->GetEHType(Ty);
+
+  return getCXXABI().getAddrOfRTTIDescriptor(Ty);
+}
+

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=212435&r1=212434&r2=212435&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Jul  7 01:20:47 2014
@@ -747,12 +747,6 @@ public:
   /// The type of a generic block literal.
   llvm::Type *getGenericBlockLiteralType();
 
-  /// \brief Gets or a creats a Microsoft TypeDescriptor.
-  llvm::Constant *getMSTypeDescriptor(QualType Ty);
-  /// \brief Gets or a creats a Microsoft CompleteObjectLocator.
-  llvm::Constant *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
-                                             const VPtrInfo *Info);
-
   /// Gets the address of a block which requires no captures.
   llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *);
   
@@ -973,9 +967,6 @@ public:
     F->setLinkage(getFunctionLinkage(GD));
   }
 
-  /// \brief Returns the appropriate linkage for the TypeInfo struct for a type.
-  llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty);
-
   /// Return the appropriate linkage for the vtable, VTT, and type information
   /// of the given class.
   llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD);

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=212435&r1=212434&r2=212435&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Mon Jul  7 01:20:47 2014
@@ -109,6 +109,10 @@ public:
   llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF, llvm::Value *ptr,
                                       QualType type) override;
 
+  void EmitFundamentalRTTIDescriptor(QualType Type);
+  void EmitFundamentalRTTIDescriptors();
+  llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
+
   bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override;
   void EmitBadTypeidCall(CodeGenFunction &CGF) override;
   llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
@@ -238,6 +242,37 @@ public:
                                       QualType LValType) override;
 
   bool NeedsVTTParameter(GlobalDecl GD) override;
+
+  /**************************** RTTI Uniqueness ******************************/
+
+protected:
+  /// Returns true if the ABI requires RTTI type_info objects to be unique
+  /// across a program.
+  virtual bool shouldRTTIBeUnique() const { return true; }
+
+public:
+  /// What sort of unique-RTTI behavior should we use?
+  enum RTTIUniquenessKind {
+    /// We are guaranteeing, or need to guarantee, that the RTTI string
+    /// is unique.
+    RUK_Unique,
+
+    /// We are not guaranteeing uniqueness for the RTTI string, so we
+    /// can demote to hidden visibility but must use string comparisons.
+    RUK_NonUniqueHidden,
+
+    /// We are not guaranteeing uniqueness for the RTTI string, so we
+    /// have to use string comparisons, but we also have to emit it with
+    /// non-hidden visibility.
+    RUK_NonUniqueVisible
+  };
+
+  /// Return the required visibility status for the given type and linkage in
+  /// the current ABI.
+  RTTIUniquenessKind
+  classifyRTTIUniqueness(QualType CanTy,
+                         llvm::GlobalValue::LinkageTypes Linkage) const;
+  friend class ItaniumRTTIBuilder;
 };
 
 class ARMCXXABI : public ItaniumCXXABI {
@@ -270,7 +305,7 @@ public:
   iOS64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {}
 
   // ARM64 libraries are prepared for non-unique RTTI.
-  bool shouldRTTIBeUnique() override { return false; }
+  bool shouldRTTIBeUnique() const override { return false; }
 };
 }
 
@@ -1206,7 +1241,7 @@ void ItaniumCXXABI::emitVTableDefinition
       isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
       cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") &&
       DC->getParent()->isTranslationUnit())
-    CGM.EmitFundamentalRTTIDescriptors();
+    EmitFundamentalRTTIDescriptors();
 }
 
 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
@@ -1944,3 +1979,996 @@ bool ItaniumCXXABI::NeedsVTTParameter(Gl
   
   return false;
 }
+
+namespace {
+class ItaniumRTTIBuilder {
+  CodeGenModule &CGM;  // Per-module state.
+  llvm::LLVMContext &VMContext;
+  const ItaniumCXXABI &CXXABI;  // Per-module state.
+
+  /// Fields - The fields of the RTTI descriptor currently being built.
+  SmallVector<llvm::Constant *, 16> Fields;
+
+  /// GetAddrOfTypeName - Returns the mangled type name of the given type.
+  llvm::GlobalVariable *
+  GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
+
+  /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI
+  /// descriptor of the given type.
+  llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
+
+  /// BuildVTablePointer - Build the vtable pointer for the given type.
+  void BuildVTablePointer(const Type *Ty);
+
+  /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
+  /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
+  void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
+
+  /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
+  /// classes with bases that do not satisfy the abi::__si_class_type_info
+  /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
+  void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
+
+  /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
+  /// for pointer types.
+  void BuildPointerTypeInfo(QualType PointeeTy);
+
+  /// BuildObjCObjectTypeInfo - Build the appropriate kind of
+  /// type_info for an object type.
+  void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);
+
+  /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info
+  /// struct, used for member pointer types.
+  void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
+
+public:
+  ItaniumRTTIBuilder(const ItaniumCXXABI &ABI)
+      : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()), CXXABI(ABI) {}
+
+  // Pointer type info flags.
+  enum {
+    /// PTI_Const - Type has const qualifier.
+    PTI_Const = 0x1,
+
+    /// PTI_Volatile - Type has volatile qualifier.
+    PTI_Volatile = 0x2,
+
+    /// PTI_Restrict - Type has restrict qualifier.
+    PTI_Restrict = 0x4,
+
+    /// PTI_Incomplete - Type is incomplete.
+    PTI_Incomplete = 0x8,
+
+    /// PTI_ContainingClassIncomplete - Containing class is incomplete.
+    /// (in pointer to member).
+    PTI_ContainingClassIncomplete = 0x10
+  };
+
+  // VMI type info flags.
+  enum {
+    /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
+    VMI_NonDiamondRepeat = 0x1,
+
+    /// VMI_DiamondShaped - Class is diamond shaped.
+    VMI_DiamondShaped = 0x2
+  };
+
+  // Base class type info flags.
+  enum {
+    /// BCTI_Virtual - Base class is virtual.
+    BCTI_Virtual = 0x1,
+
+    /// BCTI_Public - Base class is public.
+    BCTI_Public = 0x2
+  };
+
+  /// BuildTypeInfo - Build the RTTI type info struct for the given type.
+  ///
+  /// \param Force - true to force the creation of this RTTI value
+  llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
+};
+}
+
+llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
+    QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) {
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  // We know that the mangled name of the type starts at index 4 of the
+  // mangled name of the typename, so we can just index into it in order to
+  // get the mangled name of the type.
+  llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
+                                                            Name.substr(4));
+
+  llvm::GlobalVariable *GV =
+    CGM.CreateOrReplaceCXXRuntimeVariable(Name, Init->getType(), Linkage);
+
+  GV->setInitializer(Init);
+
+  return GV;
+}
+
+llvm::Constant *
+ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
+  // Mangle the RTTI name.
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  // Look for an existing global.
+  llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
+
+  if (!GV) {
+    // Create a new global variable.
+    GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
+                                  /*Constant=*/true,
+                                  llvm::GlobalValue::ExternalLinkage, nullptr,
+                                  Name);
+  }
+
+  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
+}
+
+/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
+/// info for that type is defined in the standard library.
+static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
+  // Itanium C++ ABI 2.9.2:
+  //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
+  //   the run-time support library. Specifically, the run-time support
+  //   library should contain type_info objects for the types X, X* and
+  //   X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,
+  //   unsigned char, signed char, short, unsigned short, int, unsigned int,
+  //   long, unsigned long, long long, unsigned long long, float, double,
+  //   long double, char16_t, char32_t, and the IEEE 754r decimal and
+  //   half-precision floating point types.
+  switch (Ty->getKind()) {
+    case BuiltinType::Void:
+    case BuiltinType::NullPtr:
+    case BuiltinType::Bool:
+    case BuiltinType::WChar_S:
+    case BuiltinType::WChar_U:
+    case BuiltinType::Char_U:
+    case BuiltinType::Char_S:
+    case BuiltinType::UChar:
+    case BuiltinType::SChar:
+    case BuiltinType::Short:
+    case BuiltinType::UShort:
+    case BuiltinType::Int:
+    case BuiltinType::UInt:
+    case BuiltinType::Long:
+    case BuiltinType::ULong:
+    case BuiltinType::LongLong:
+    case BuiltinType::ULongLong:
+    case BuiltinType::Half:
+    case BuiltinType::Float:
+    case BuiltinType::Double:
+    case BuiltinType::LongDouble:
+    case BuiltinType::Char16:
+    case BuiltinType::Char32:
+    case BuiltinType::Int128:
+    case BuiltinType::UInt128:
+    case BuiltinType::OCLImage1d:
+    case BuiltinType::OCLImage1dArray:
+    case BuiltinType::OCLImage1dBuffer:
+    case BuiltinType::OCLImage2d:
+    case BuiltinType::OCLImage2dArray:
+    case BuiltinType::OCLImage3d:
+    case BuiltinType::OCLSampler:
+    case BuiltinType::OCLEvent:
+      return true;
+
+    case BuiltinType::Dependent:
+#define BUILTIN_TYPE(Id, SingletonId)
+#define PLACEHOLDER_TYPE(Id, SingletonId) \
+    case BuiltinType::Id:
+#include "clang/AST/BuiltinTypes.def"
+      llvm_unreachable("asking for RRTI for a placeholder type!");
+
+    case BuiltinType::ObjCId:
+    case BuiltinType::ObjCClass:
+    case BuiltinType::ObjCSel:
+      llvm_unreachable("FIXME: Objective-C types are unsupported!");
+  }
+
+  llvm_unreachable("Invalid BuiltinType Kind!");
+}
+
+static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
+  QualType PointeeTy = PointerTy->getPointeeType();
+  const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
+  if (!BuiltinTy)
+    return false;
+
+  // Check the qualifiers.
+  Qualifiers Quals = PointeeTy.getQualifiers();
+  Quals.removeConst();
+
+  if (!Quals.empty())
+    return false;
+
+  return TypeInfoIsInStandardLibrary(BuiltinTy);
+}
+
+/// IsStandardLibraryRTTIDescriptor - Returns whether the type
+/// information for the given type exists in the standard library.
+static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
+  // Type info for builtin types is defined in the standard library.
+  if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
+    return TypeInfoIsInStandardLibrary(BuiltinTy);
+
+  // Type info for some pointer types to builtin types is defined in the
+  // standard library.
+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
+    return TypeInfoIsInStandardLibrary(PointerTy);
+
+  return false;
+}
+
+/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
+/// the given type exists somewhere else, and that we should not emit the type
+/// information in this translation unit.  Assumes that it is not a
+/// standard-library type.
+static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
+                                            QualType Ty) {
+  ASTContext &Context = CGM.getContext();
+
+  // If RTTI is disabled, assume it might be disabled in the
+  // translation unit that defines any potential key function, too.
+  if (!Context.getLangOpts().RTTI) return false;
+
+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+    if (!RD->hasDefinition())
+      return false;
+
+    if (!RD->isDynamicClass())
+      return false;
+
+    // FIXME: this may need to be reconsidered if the key function
+    // changes.
+    return CGM.getVTables().isVTableExternal(RD);
+  }
+
+  return false;
+}
+
+/// IsIncompleteClassType - Returns whether the given record type is incomplete.
+static bool IsIncompleteClassType(const RecordType *RecordTy) {
+  return !RecordTy->getDecl()->isCompleteDefinition();
+}
+
+/// ContainsIncompleteClassType - Returns whether the given type contains an
+/// incomplete class type. This is true if
+///
+///   * The given type is an incomplete class type.
+///   * The given type is a pointer type whose pointee type contains an
+///     incomplete class type.
+///   * The given type is a member pointer type whose class is an incomplete
+///     class type.
+///   * The given type is a member pointer type whoise pointee type contains an
+///     incomplete class type.
+/// is an indirect or direct pointer to an incomplete class type.
+static bool ContainsIncompleteClassType(QualType Ty) {
+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+    if (IsIncompleteClassType(RecordTy))
+      return true;
+  }
+
+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
+    return ContainsIncompleteClassType(PointerTy->getPointeeType());
+
+  if (const MemberPointerType *MemberPointerTy =
+      dyn_cast<MemberPointerType>(Ty)) {
+    // Check if the class type is incomplete.
+    const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
+    if (IsIncompleteClassType(ClassType))
+      return true;
+
+    return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
+  }
+
+  return false;
+}
+
+// CanUseSingleInheritance - Return whether the given record decl has a "single,
+// public, non-virtual base at offset zero (i.e. the derived class is dynamic
+// iff the base is)", according to Itanium C++ ABI, 2.95p6b.
+static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
+  // Check the number of bases.
+  if (RD->getNumBases() != 1)
+    return false;
+
+  // Get the base.
+  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
+
+  // Check that the base is not virtual.
+  if (Base->isVirtual())
+    return false;
+
+  // Check that the base is public.
+  if (Base->getAccessSpecifier() != AS_public)
+    return false;
+
+  // Check that the class is dynamic iff the base is.
+  const CXXRecordDecl *BaseDecl =
+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+  if (!BaseDecl->isEmpty() &&
+      BaseDecl->isDynamicClass() != RD->isDynamicClass())
+    return false;
+
+  return true;
+}
+
+void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
+  // abi::__class_type_info.
+  static const char * const ClassTypeInfo =
+    "_ZTVN10__cxxabiv117__class_type_infoE";
+  // abi::__si_class_type_info.
+  static const char * const SIClassTypeInfo =
+    "_ZTVN10__cxxabiv120__si_class_type_infoE";
+  // abi::__vmi_class_type_info.
+  static const char * const VMIClassTypeInfo =
+    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
+
+  const char *VTableName = nullptr;
+
+  switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
+
+  case Type::LValueReference:
+  case Type::RValueReference:
+    llvm_unreachable("References shouldn't get here");
+
+  case Type::Auto:
+    llvm_unreachable("Undeduced auto type shouldn't get here");
+
+  case Type::Builtin:
+  // GCC treats vector and complex types as fundamental types.
+  case Type::Vector:
+  case Type::ExtVector:
+  case Type::Complex:
+  case Type::Atomic:
+  // FIXME: GCC treats block pointers as fundamental types?!
+  case Type::BlockPointer:
+    // abi::__fundamental_type_info.
+    VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
+    break;
+
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+    // abi::__array_type_info.
+    VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
+    break;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto:
+    // abi::__function_type_info.
+    VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
+    break;
+
+  case Type::Enum:
+    // abi::__enum_type_info.
+    VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
+    break;
+
+  case Type::Record: {
+    const CXXRecordDecl *RD =
+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+
+    if (!RD->hasDefinition() || !RD->getNumBases()) {
+      VTableName = ClassTypeInfo;
+    } else if (CanUseSingleInheritance(RD)) {
+      VTableName = SIClassTypeInfo;
+    } else {
+      VTableName = VMIClassTypeInfo;
+    }
+
+    break;
+  }
+
+  case Type::ObjCObject:
+    // Ignore protocol qualifiers.
+    Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
+
+    // Handle id and Class.
+    if (isa<BuiltinType>(Ty)) {
+      VTableName = ClassTypeInfo;
+      break;
+    }
+
+    assert(isa<ObjCInterfaceType>(Ty));
+    // Fall through.
+
+  case Type::ObjCInterface:
+    if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
+      VTableName = SIClassTypeInfo;
+    } else {
+      VTableName = ClassTypeInfo;
+    }
+    break;
+
+  case Type::ObjCObjectPointer:
+  case Type::Pointer:
+    // abi::__pointer_type_info.
+    VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
+    break;
+
+  case Type::MemberPointer:
+    // abi::__pointer_to_member_type_info.
+    VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
+    break;
+  }
+
+  llvm::Constant *VTable =
+    CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);
+
+  llvm::Type *PtrDiffTy =
+    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
+
+  // The vtable address point is 2.
+  llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
+  VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);
+  VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
+
+  Fields.push_back(VTable);
+}
+
+/// \brief Return the linkage that the type info and type info name constants
+/// should have for the given type.
+static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
+                                                             QualType Ty) {
+  // Itanium C++ ABI 2.9.5p7:
+  //   In addition, it and all of the intermediate abi::__pointer_type_info
+  //   structs in the chain down to the abi::__class_type_info for the
+  //   incomplete class type must be prevented from resolving to the
+  //   corresponding type_info structs for the complete class type, possibly
+  //   by making them local static objects. Finally, a dummy class RTTI is
+  //   generated for the incomplete type that will not resolve to the final
+  //   complete class RTTI (because the latter need not exist), possibly by
+  //   making it a local static object.
+  if (ContainsIncompleteClassType(Ty))
+    return llvm::GlobalValue::InternalLinkage;
+
+  switch (Ty->getLinkage()) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return llvm::GlobalValue::InternalLinkage;
+
+  case VisibleNoLinkage:
+  case ExternalLinkage:
+    if (!CGM.getLangOpts().RTTI) {
+      // RTTI is not enabled, which means that this type info struct is going
+      // to be used for exception handling. Give it linkonce_odr linkage.
+      return llvm::GlobalValue::LinkOnceODRLinkage;
+    }
+
+    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
+      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
+      if (RD->hasAttr<WeakAttr>())
+        return llvm::GlobalValue::WeakODRLinkage;
+      if (RD->isDynamicClass())
+        return CGM.getVTableLinkage(RD);
+    }
+
+    return llvm::GlobalValue::LinkOnceODRLinkage;
+  }
+
+  llvm_unreachable("Invalid linkage!");
+}
+
+llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
+  // We want to operate on the canonical type.
+  Ty = CGM.getContext().getCanonicalType(Ty);
+
+  // Check if we've already emitted an RTTI descriptor for this type.
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
+  if (OldGV && !OldGV->isDeclaration()) {
+    assert(!OldGV->hasAvailableExternallyLinkage() &&
+           "available_externally typeinfos not yet implemented");
+
+    return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);
+  }
+
+  // Check if there is already an external RTTI descriptor for this type.
+  bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
+  if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty)))
+    return GetAddrOfExternalRTTIDescriptor(Ty);
+
+  // Emit the standard library with external linkage.
+  llvm::GlobalVariable::LinkageTypes Linkage;
+  if (IsStdLib)
+    Linkage = llvm::GlobalValue::ExternalLinkage;
+  else
+    Linkage = getTypeInfoLinkage(CGM, Ty);
+
+  // Add the vtable pointer.
+  BuildVTablePointer(cast<Type>(Ty));
+
+  // And the name.
+  llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
+  llvm::Constant *TypeNameField;
+
+  // If we're supposed to demote the visibility, be sure to set a flag
+  // to use a string comparison for type_info comparisons.
+  ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
+      CXXABI.classifyRTTIUniqueness(Ty, Linkage);
+  if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
+    // The flag is the sign bit, which on ARM64 is defined to be clear
+    // for global pointers.  This is very ARM64-specific.
+    TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty);
+    llvm::Constant *flag =
+        llvm::ConstantInt::get(CGM.Int64Ty, ((uint64_t)1) << 63);
+    TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
+    TypeNameField =
+        llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.Int8PtrTy);
+  } else {
+    TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy);
+  }
+  Fields.push_back(TypeNameField);
+
+  switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
+
+  // GCC treats vector types as fundamental types.
+  case Type::Builtin:
+  case Type::Vector:
+  case Type::ExtVector:
+  case Type::Complex:
+  case Type::BlockPointer:
+    // Itanium C++ ABI 2.9.5p4:
+    // abi::__fundamental_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::LValueReference:
+  case Type::RValueReference:
+    llvm_unreachable("References shouldn't get here");
+
+  case Type::Auto:
+    llvm_unreachable("Undeduced auto type shouldn't get here");
+
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__array_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__function_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::Enum:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__enum_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::Record: {
+    const CXXRecordDecl *RD =
+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+    if (!RD->hasDefinition() || !RD->getNumBases()) {
+      // We don't need to emit any fields.
+      break;
+    }
+
+    if (CanUseSingleInheritance(RD))
+      BuildSIClassTypeInfo(RD);
+    else
+      BuildVMIClassTypeInfo(RD);
+
+    break;
+  }
+
+  case Type::ObjCObject:
+  case Type::ObjCInterface:
+    BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
+    break;
+
+  case Type::ObjCObjectPointer:
+    BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
+    break;
+
+  case Type::Pointer:
+    BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
+    break;
+
+  case Type::MemberPointer:
+    BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
+    break;
+
+  case Type::Atomic:
+    // No fields, at least for the moment.
+    break;
+  }
+
+  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
+
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
+                             /*Constant=*/true, Linkage, Init, Name);
+
+  // If there's already an old global variable, replace it with the new one.
+  if (OldGV) {
+    GV->takeName(OldGV);
+    llvm::Constant *NewPtr =
+      llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+    OldGV->replaceAllUsesWith(NewPtr);
+    OldGV->eraseFromParent();
+  }
+
+  // The Itanium ABI specifies that type_info objects must be globally
+  // unique, with one exception: if the type is an incomplete class
+  // type or a (possibly indirect) pointer to one.  That exception
+  // affects the general case of comparing type_info objects produced
+  // by the typeid operator, which is why the comparison operators on
+  // std::type_info generally use the type_info name pointers instead
+  // of the object addresses.  However, the language's built-in uses
+  // of RTTI generally require class types to be complete, even when
+  // manipulating pointers to those class types.  This allows the
+  // implementation of dynamic_cast to rely on address equality tests,
+  // which is much faster.
+
+  // All of this is to say that it's important that both the type_info
+  // object and the type_info name be uniqued when weakly emitted.
+
+  // Give the type_info object and name the formal visibility of the
+  // type itself.
+  llvm::GlobalValue::VisibilityTypes llvmVisibility;
+  if (llvm::GlobalValue::isLocalLinkage(Linkage))
+    // If the linkage is local, only default visibility makes sense.
+    llvmVisibility = llvm::GlobalValue::DefaultVisibility;
+  else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden)
+    llvmVisibility = llvm::GlobalValue::HiddenVisibility;
+  else
+    llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility());
+  TypeName->setVisibility(llvmVisibility);
+  GV->setVisibility(llvmVisibility);
+
+  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
+}
+
+/// ComputeQualifierFlags - Compute the pointer type info flags from the
+/// given qualifier.
+static unsigned ComputeQualifierFlags(Qualifiers Quals) {
+  unsigned Flags = 0;
+
+  if (Quals.hasConst())
+    Flags |= ItaniumRTTIBuilder::PTI_Const;
+  if (Quals.hasVolatile())
+    Flags |= ItaniumRTTIBuilder::PTI_Volatile;
+  if (Quals.hasRestrict())
+    Flags |= ItaniumRTTIBuilder::PTI_Restrict;
+
+  return Flags;
+}
+
+/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
+/// for the given Objective-C object type.
+void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
+  // Drop qualifiers.
+  const Type *T = OT->getBaseType().getTypePtr();
+  assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
+
+  // The builtin types are abi::__class_type_infos and don't require
+  // extra fields.
+  if (isa<BuiltinType>(T)) return;
+
+  ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();
+  ObjCInterfaceDecl *Super = Class->getSuperClass();
+
+  // Root classes are also __class_type_info.
+  if (!Super) return;
+
+  QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);
+
+  // Everything else is single inheritance.
+  llvm::Constant *BaseTypeInfo =
+      ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(SuperTy);
+  Fields.push_back(BaseTypeInfo);
+}
+
+/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
+/// inheritance, according to the Itanium C++ ABI, 2.95p6b.
+void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
+  // Itanium C++ ABI 2.9.5p6b:
+  // It adds to abi::__class_type_info a single member pointing to the
+  // type_info structure for the base type,
+  llvm::Constant *BaseTypeInfo =
+    ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(RD->bases_begin()->getType());
+  Fields.push_back(BaseTypeInfo);
+}
+
+namespace {
+  /// SeenBases - Contains virtual and non-virtual bases seen when traversing
+  /// a class hierarchy.
+  struct SeenBases {
+    llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
+    llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
+  };
+}
+
+/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
+/// abi::__vmi_class_type_info.
+///
+static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base,
+                                             SeenBases &Bases) {
+
+  unsigned Flags = 0;
+
+  const CXXRecordDecl *BaseDecl =
+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+
+  if (Base->isVirtual()) {
+    // Mark the virtual base as seen.
+    if (!Bases.VirtualBases.insert(BaseDecl)) {
+      // If this virtual base has been seen before, then the class is diamond
+      // shaped.
+      Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
+    } else {
+      if (Bases.NonVirtualBases.count(BaseDecl))
+        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
+    }
+  } else {
+    // Mark the non-virtual base as seen.
+    if (!Bases.NonVirtualBases.insert(BaseDecl)) {
+      // If this non-virtual base has been seen before, then the class has non-
+      // diamond shaped repeated inheritance.
+      Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
+    } else {
+      if (Bases.VirtualBases.count(BaseDecl))
+        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
+    }
+  }
+
+  // Walk all bases.
+  for (const auto &I : BaseDecl->bases())
+    Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
+
+  return Flags;
+}
+
+static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
+  unsigned Flags = 0;
+  SeenBases Bases;
+
+  // Walk all bases.
+  for (const auto &I : RD->bases())
+    Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
+
+  return Flags;
+}
+
+/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
+/// classes with bases that do not satisfy the abi::__si_class_type_info
+/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
+void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
+  llvm::Type *UnsignedIntLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __flags is a word with flags describing details about the class
+  //   structure, which may be referenced by using the __flags_masks
+  //   enumeration. These flags refer to both direct and indirect bases.
+  unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __base_count is a word with the number of direct proper base class
+  //   descriptions that follow.
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
+
+  if (!RD->getNumBases())
+    return;
+
+  llvm::Type *LongLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().LongTy);
+
+  // Now add the base class descriptions.
+
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __base_info[] is an array of base class descriptions -- one for every
+  //   direct proper base. Each description is of the type:
+  //
+  //   struct abi::__base_class_type_info {
+  //   public:
+  //     const __class_type_info *__base_type;
+  //     long __offset_flags;
+  //
+  //     enum __offset_flags_masks {
+  //       __virtual_mask = 0x1,
+  //       __public_mask = 0x2,
+  //       __offset_shift = 8
+  //     };
+  //   };
+  for (const auto &Base : RD->bases()) {
+    // The __base_type member points to the RTTI for the base type.
+    Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType()));
+
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
+
+    int64_t OffsetFlags = 0;
+
+    // All but the lower 8 bits of __offset_flags are a signed offset.
+    // For a non-virtual base, this is the offset in the object of the base
+    // subobject. For a virtual base, this is the offset in the virtual table of
+    // the virtual base offset for the virtual base referenced (negative).
+    CharUnits Offset;
+    if (Base.isVirtual())
+      Offset =
+        CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
+    else {
+      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+      Offset = Layout.getBaseClassOffset(BaseDecl);
+    };
+
+    OffsetFlags = uint64_t(Offset.getQuantity()) << 8;
+
+    // The low-order byte of __offset_flags contains flags, as given by the
+    // masks from the enumeration __offset_flags_masks.
+    if (Base.isVirtual())
+      OffsetFlags |= BCTI_Virtual;
+    if (Base.getAccessSpecifier() == AS_public)
+      OffsetFlags |= BCTI_Public;
+
+    Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
+  }
+}
+
+/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
+/// used for pointer types.
+void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
+  Qualifiers Quals;
+  QualType UnqualifiedPointeeTy =
+    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   __flags is a flag word describing the cv-qualification and other
+  //   attributes of the type pointed to
+  unsigned Flags = ComputeQualifierFlags(Quals);
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
+  //   incomplete class type, the incomplete target type flag is set.
+  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
+    Flags |= PTI_Incomplete;
+
+  llvm::Type *UnsignedIntLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+
+  // Itanium C++ ABI 2.9.5p7:
+  //  __pointee is a pointer to the std::type_info derivation for the
+  //  unqualified type being pointed to.
+  llvm::Constant *PointeeTypeInfo =
+    ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
+  Fields.push_back(PointeeTypeInfo);
+}
+
+/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info
+/// struct, used for member pointer types.
+void
+ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
+  QualType PointeeTy = Ty->getPointeeType();
+
+  Qualifiers Quals;
+  QualType UnqualifiedPointeeTy =
+    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   __flags is a flag word describing the cv-qualification and other
+  //   attributes of the type pointed to.
+  unsigned Flags = ComputeQualifierFlags(Quals);
+
+  const RecordType *ClassType = cast<RecordType>(Ty->getClass());
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
+  //   incomplete class type, the incomplete target type flag is set.
+  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
+    Flags |= PTI_Incomplete;
+
+  if (IsIncompleteClassType(ClassType))
+    Flags |= PTI_ContainingClassIncomplete;
+
+  llvm::Type *UnsignedIntLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   __pointee is a pointer to the std::type_info derivation for the
+  //   unqualified type being pointed to.
+  llvm::Constant *PointeeTypeInfo =
+    ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
+  Fields.push_back(PointeeTypeInfo);
+
+  // Itanium C++ ABI 2.9.5p9:
+  //   __context is a pointer to an abi::__class_type_info corresponding to the
+  //   class type containing the member pointed to
+  //   (e.g., the "A" in "int A::*").
+  Fields.push_back(
+      ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(QualType(ClassType, 0)));
+}
+
+llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
+  return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
+}
+
+void ItaniumCXXABI::EmitFundamentalRTTIDescriptor(QualType Type) {
+  QualType PointerType = getContext().getPointerType(Type);
+  QualType PointerTypeConst = getContext().getPointerType(Type.withConst());
+  ItaniumRTTIBuilder(*this).BuildTypeInfo(Type, true);
+  ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType, true);
+  ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);
+}
+
+void ItaniumCXXABI::EmitFundamentalRTTIDescriptors() {
+  QualType FundamentalTypes[] = {
+      getContext().VoidTy,             getContext().NullPtrTy,
+      getContext().BoolTy,             getContext().WCharTy,
+      getContext().CharTy,             getContext().UnsignedCharTy,
+      getContext().SignedCharTy,       getContext().ShortTy,
+      getContext().UnsignedShortTy,    getContext().IntTy,
+      getContext().UnsignedIntTy,      getContext().LongTy,
+      getContext().UnsignedLongTy,     getContext().LongLongTy,
+      getContext().UnsignedLongLongTy, getContext().HalfTy,
+      getContext().FloatTy,            getContext().DoubleTy,
+      getContext().LongDoubleTy,       getContext().Char16Ty,
+      getContext().Char32Ty,
+  };
+  for (const QualType &FundamentalType : FundamentalTypes)
+    EmitFundamentalRTTIDescriptor(FundamentalType);
+}
+
+/// What sort of uniqueness rules should we use for the RTTI for the
+/// given type?
+ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
+    QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage) const {
+  if (shouldRTTIBeUnique())
+    return RUK_Unique;
+
+  // It's only necessary for linkonce_odr or weak_odr linkage.
+  if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
+      Linkage != llvm::GlobalValue::WeakODRLinkage)
+    return RUK_Unique;
+
+  // It's only necessary with default visibility.
+  if (CanTy->getVisibility() != DefaultVisibility)
+    return RUK_Unique;
+
+  // If we're not required to publish this symbol, hide it.
+  if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
+    return RUK_NonUniqueHidden;
+
+  // If we're required to publish this symbol, as we might be under an
+  // explicit instantiation, leave it with default visibility but
+  // enable string-comparisons.
+  assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
+  return RUK_NonUniqueVisible;
+}

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=212435&r1=212434&r2=212435&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Mon Jul  7 01:20:47 2014
@@ -57,6 +57,11 @@ public:
                                       llvm::Value *ptr,
                                       QualType type) override;
 
+  llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
+                                                   const VPtrInfo *Info);
+
+  llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
+
   bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override;
   void EmitBadTypeidCall(CodeGenFunction &CGF) override;
   llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
@@ -1059,7 +1064,7 @@ void MicrosoftCXXABI::emitVTableDefiniti
     if (VTable->hasInitializer())
       continue;
 
-    llvm::Constant *RTTI = CGM.getMSCompleteObjectLocator(RD, Info);
+    llvm::Constant *RTTI = getMSCompleteObjectLocator(RD, Info);
 
     const VTableLayout &VTLayout =
       VFTContext.getVFTableLayout(RD, Info->FullOffsetInMDC);
@@ -2364,3 +2369,509 @@ llvm::Value *MicrosoftCXXABI::EmitLoadOf
 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
   return new MicrosoftCXXABI(CGM);
 }
+
+// MS RTTI Overview:
+// The run time type information emitted by cl.exe contains 5 distinct types of
+// structures.  Many of them reference each other.
+//
+// TypeInfo:  Static classes that are returned by typeid.
+//
+// CompleteObjectLocator:  Referenced by vftables.  They contain information
+//   required for dynamic casting, including OffsetFromTop.  They also contain
+//   a reference to the TypeInfo for the type and a reference to the
+//   CompleteHierarchyDescriptor for the type.
+//
+// ClassHieararchyDescriptor: Contains information about a class hierarchy.
+//   Used during dynamic_cast to walk a class hierarchy.  References a base
+//   class array and the size of said array.
+//
+// BaseClassArray: Contains a list of classes in a hierarchy.  BaseClassArray is
+//   somewhat of a misnomer because the most derived class is also in the list
+//   as well as multiple copies of virtual bases (if they occur multiple times
+//   in the hiearchy.)  The BaseClassArray contains one BaseClassDescriptor for
+//   every path in the hierarchy, in pre-order depth first order.  Note, we do
+//   not declare a specific llvm type for BaseClassArray, it's merely an array
+//   of BaseClassDescriptor pointers.
+//
+// BaseClassDescriptor: Contains information about a class in a class hierarchy.
+//   BaseClassDescriptor is also somewhat of a misnomer for the same reason that
+//   BaseClassArray is.  It contains information about a class within a
+//   hierarchy such as: is this base is ambiguous and what is its offset in the
+//   vbtable.  The names of the BaseClassDescriptors have all of their fields
+//   mangled into them so they can be aggressively deduplicated by the linker.
+
+static bool isImageRelative(CodeGenModule &CGM) {
+  return CGM.getTarget().getPointerWidth(/*AddressSpace=*/0) == 64;
+}
+
+static llvm::Type *getImageRelativeType(CodeGenModule &CGM,
+                                        llvm::Type *PtrType) {
+  if (!isImageRelative(CGM))
+    return PtrType;
+  return CGM.IntTy;
+}
+
+static llvm::GlobalVariable *getImageBase(CodeGenModule &CGM) {
+  StringRef Name = "__ImageBase";
+  if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
+    return GV;
+
+  return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
+                                  /*isConstant=*/true,
+                                  llvm::GlobalValue::ExternalLinkage,
+                                  /*Initializer=*/nullptr, Name);
+}
+
+static llvm::Constant *getImageRelativeConstant(CodeGenModule &CGM,
+                                                llvm::Constant *PtrVal) {
+  if (!isImageRelative(CGM))
+    return PtrVal;
+
+  llvm::Constant *ImageBaseAsInt =
+      llvm::ConstantExpr::getPtrToInt(getImageBase(CGM), CGM.IntPtrTy);
+  llvm::Constant *PtrValAsInt =
+      llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
+  llvm::Constant *Diff =
+      llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
+                                 /*HasNUW=*/true, /*HasNSW=*/true);
+  return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
+}
+
+// 5 routines for constructing the llvm types for MS RTTI structs.
+static llvm::StructType *getClassHierarchyDescriptorType(CodeGenModule &CGM);
+
+static llvm::StructType *getTypeDescriptorType(CodeGenModule &CGM,
+                                               StringRef TypeInfoString) {
+  llvm::SmallString<32> TDTypeName("MSRTTITypeDescriptor");
+  TDTypeName += TypeInfoString.size();
+  if (auto Type = CGM.getModule().getTypeByName(TDTypeName))
+    return Type;
+  llvm::Type *FieldTypes[] = {
+      CGM.Int8PtrPtrTy,
+      CGM.Int8PtrTy,
+      llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
+  return llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, TDTypeName);
+}
+
+static llvm::StructType *getBaseClassDescriptorType(CodeGenModule &CGM) {
+  static const char Name[] = "MSRTTIBaseClassDescriptor";
+  if (auto Type = CGM.getModule().getTypeByName(Name))
+    return Type;
+  llvm::Type *FieldTypes[] = {
+      getImageRelativeType(CGM, CGM.Int8PtrTy),
+      CGM.IntTy,
+      CGM.IntTy,
+      CGM.IntTy,
+      CGM.IntTy,
+      CGM.IntTy,
+      getImageRelativeType(
+          CGM, getClassHierarchyDescriptorType(CGM)->getPointerTo()),
+  };
+  return llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, Name);
+}
+
+static llvm::StructType *getClassHierarchyDescriptorType(CodeGenModule &CGM) {
+  static const char Name[] = "MSRTTIClassHierarchyDescriptor";
+  if (auto Type = CGM.getModule().getTypeByName(Name))
+    return Type;
+  // Forward-declare RTTIClassHierarchyDescriptor to break a cycle.
+  llvm::StructType *Type = llvm::StructType::create(CGM.getLLVMContext(), Name);
+  llvm::Type *FieldTypes[] = {
+    CGM.IntTy,
+    CGM.IntTy,
+    CGM.IntTy,
+    getImageRelativeType(
+        CGM,
+        getBaseClassDescriptorType(CGM)->getPointerTo()->getPointerTo()),
+  };
+  Type->setBody(FieldTypes);
+  return Type;
+}
+
+static llvm::StructType *getCompleteObjectLocatorType(CodeGenModule &CGM) {
+  static const char Name[] = "MSRTTICompleteObjectLocator";
+  if (auto Type = CGM.getModule().getTypeByName(Name))
+    return Type;
+  llvm::StructType *Type = llvm::StructType::create(CGM.getLLVMContext(), Name);
+  llvm::Type *FieldTypes[] = {
+    CGM.IntTy,
+    CGM.IntTy,
+    CGM.IntTy,
+    getImageRelativeType(CGM, CGM.Int8PtrTy),
+    getImageRelativeType(
+        CGM, getClassHierarchyDescriptorType(CGM)->getPointerTo()),
+    getImageRelativeType(CGM, Type),
+  };
+  llvm::ArrayRef<llvm::Type *> FieldTypesRef(
+      std::begin(FieldTypes),
+      isImageRelative(CGM) ? std::end(FieldTypes) : std::end(FieldTypes) - 1);
+  Type->setBody(FieldTypesRef);
+  return Type;
+}
+
+static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) {
+  StringRef MangledName("\01??_7type_info@@6B@");
+  if (auto VTable = CGM.getModule().getNamedGlobal(MangledName))
+    return VTable;
+  return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
+                                  /*Constant=*/true,
+                                  llvm::GlobalVariable::ExternalLinkage,
+                                  /*Initializer=*/nullptr, MangledName);
+}
+
+namespace {
+
+/// \brief A Helper struct that stores information about a class in a class
+/// hierarchy.  The information stored in these structs struct is used during
+/// the generation of ClassHierarchyDescriptors and BaseClassDescriptors.
+// During RTTI creation, MSRTTIClasses are stored in a contiguous array with
+// implicit depth first pre-order tree connectivity.  getFirstChild and
+// getNextSibling allow us to walk the tree efficiently.
+struct MSRTTIClass {
+  enum {
+    IsPrivateOnPath = 1 | 8,
+    IsAmbiguous = 2,
+    IsPrivate = 4,
+    IsVirtual = 16,
+    HasHierarchyDescriptor = 64
+  };
+  MSRTTIClass(const CXXRecordDecl *RD) : RD(RD) {}
+  uint32_t initialize(const MSRTTIClass *Parent,
+                      const CXXBaseSpecifier *Specifier);
+
+  MSRTTIClass *getFirstChild() { return this + 1; }
+  static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
+    return Child + 1 + Child->NumBases;
+  }
+
+  const CXXRecordDecl *RD, *VirtualRoot;
+  uint32_t Flags, NumBases, OffsetInVBase;
+};
+
+/// \brief Recursively initialize the base class array.
+uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent,
+                                 const CXXBaseSpecifier *Specifier) {
+  Flags = HasHierarchyDescriptor;
+  if (!Parent) {
+    VirtualRoot = nullptr;
+    OffsetInVBase = 0;
+  } else {
+    if (Specifier->getAccessSpecifier() != AS_public)
+      Flags |= IsPrivate | IsPrivateOnPath;
+    if (Specifier->isVirtual()) {
+      Flags |= IsVirtual;
+      VirtualRoot = RD;
+      OffsetInVBase = 0;
+    } else {
+      if (Parent->Flags & IsPrivateOnPath)
+        Flags |= IsPrivateOnPath;
+      VirtualRoot = Parent->VirtualRoot;
+      OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
+          .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
+    }
+  }
+  NumBases = 0;
+  MSRTTIClass *Child = getFirstChild();
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    NumBases += Child->initialize(this, &Base) + 1;
+    Child = getNextChild(Child);
+  }
+  return NumBases;
+}
+
+static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
+  switch (Ty->getLinkage()) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return llvm::GlobalValue::InternalLinkage;
+
+  case VisibleNoLinkage:
+  case ExternalLinkage:
+    return llvm::GlobalValue::LinkOnceODRLinkage;
+  }
+  llvm_unreachable("Invalid linkage!");
+}
+
+/// \brief An ephemeral helper class for building MS RTTI types.  It caches some
+/// calls to the module and information about the most derived class in a
+/// hierarchy.
+struct MSRTTIBuilder {
+  enum {
+    HasBranchingHierarchy = 1,
+    HasVirtualBranchingHierarchy = 2,
+    HasAmbiguousBases = 4
+  };
+
+  MSRTTIBuilder(CodeGenModule &CGM, const CXXRecordDecl *RD)
+      : CGM(CGM), Context(CGM.getContext()), VMContext(CGM.getLLVMContext()),
+        Module(CGM.getModule()), RD(RD),
+        Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
+        Mangler(
+            cast<MicrosoftMangleContext>(CGM.getCXXABI().getMangleContext())) {}
+
+  llvm::GlobalVariable *getBaseClassDescriptor(const MSRTTIClass &Classes);
+  llvm::GlobalVariable *
+  getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
+  llvm::GlobalVariable *getClassHierarchyDescriptor();
+  llvm::GlobalVariable *getCompleteObjectLocator(const VPtrInfo *Info);
+
+  CodeGenModule &CGM;
+  ASTContext &Context;
+  llvm::LLVMContext &VMContext;
+  llvm::Module &Module;
+  const CXXRecordDecl *RD;
+  llvm::GlobalVariable::LinkageTypes Linkage;
+  MicrosoftMangleContext &Mangler;
+};
+
+} // namespace
+
+/// \brief Recursively serializes a class hierarchy in pre-order depth first
+/// order.
+static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes,
+                                    const CXXRecordDecl *RD) {
+  Classes.push_back(MSRTTIClass(RD));
+  for (const CXXBaseSpecifier &Base : RD->bases())
+    serializeClassHierarchy(Classes, Base.getType()->getAsCXXRecordDecl());
+}
+
+/// \brief Find ambiguity among base classes.
+static void
+detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> &Classes) {
+  llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
+  llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
+  llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
+  for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
+    if ((Class->Flags & MSRTTIClass::IsVirtual) &&
+        !VirtualBases.insert(Class->RD)) {
+      Class = MSRTTIClass::getNextChild(Class);
+      continue;
+    }
+    if (!UniqueBases.insert(Class->RD))
+      AmbiguousBases.insert(Class->RD);
+    Class++;
+  }
+  if (AmbiguousBases.empty())
+    return;
+  for (MSRTTIClass &Class : Classes)
+    if (AmbiguousBases.count(Class.RD))
+      Class.Flags |= MSRTTIClass::IsAmbiguous;
+}
+
+llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    Mangler.mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
+  }
+
+  // Check to see if we've already declared this ClassHierarchyDescriptor.
+  if (auto CHD = Module.getNamedGlobal(MangledName))
+    return CHD;
+
+  // Serialize the class hierarchy and initialize the CHD Fields.
+  SmallVector<MSRTTIClass, 8> Classes;
+  serializeClassHierarchy(Classes, RD);
+  Classes.front().initialize(/*Parent=*/nullptr, /*Specifier=*/nullptr);
+  detectAmbiguousBases(Classes);
+  int Flags = 0;
+  for (auto Class : Classes) {
+    if (Class.RD->getNumBases() > 1)
+      Flags |= HasBranchingHierarchy;
+    // Note: cl.exe does not calculate "HasAmbiguousBases" correctly.  We
+    // believe the field isn't actually used.
+    if (Class.Flags & MSRTTIClass::IsAmbiguous)
+      Flags |= HasAmbiguousBases;
+  }
+  if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
+    Flags |= HasVirtualBranchingHierarchy;
+  // These gep indices are used to get the address of the first element of the
+  // base class array.
+  llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
+                               llvm::ConstantInt::get(CGM.IntTy, 0)};
+
+  // Forward-declare the class hierarchy descriptor
+  auto Type = getClassHierarchyDescriptorType(CGM);
+  auto CHD = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
+                                      /*Initializer=*/nullptr,
+                                      MangledName.c_str());
+
+  // Initialize the base class ClassHierarchyDescriptor.
+  llvm::Constant *Fields[] = {
+    llvm::ConstantInt::get(CGM.IntTy, 0), // Unknown
+    llvm::ConstantInt::get(CGM.IntTy, Flags),
+    llvm::ConstantInt::get(CGM.IntTy, Classes.size()),
+    getImageRelativeConstant(CGM,
+                             llvm::ConstantExpr::getInBoundsGetElementPtr(
+                                 getBaseClassArray(Classes),
+                                 llvm::ArrayRef<llvm::Value *>(GEPIndices))),
+  };
+  CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
+  return CHD;
+}
+
+llvm::GlobalVariable *
+MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    Mangler.mangleCXXRTTIBaseClassArray(RD, Out);
+  }
+
+  // Forward-declare the base class array.
+  // cl.exe pads the base class array with 1 (in 32 bit mode) or 4 (in 64 bit
+  // mode) bytes of padding.  We provide a pointer sized amount of padding by
+  // adding +1 to Classes.size().  The sections have pointer alignment and are
+  // marked pick-any so it shouldn't matter.
+  auto PtrType = getImageRelativeType(
+      CGM, getBaseClassDescriptorType(CGM)->getPointerTo());
+  auto ArrayType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
+  auto BCA = new llvm::GlobalVariable(Module, ArrayType,
+      /*Constant=*/true, Linkage, /*Initializer=*/nullptr, MangledName.c_str());
+
+  // Initialize the BaseClassArray.
+  SmallVector<llvm::Constant *, 8> BaseClassArrayData;
+  for (MSRTTIClass &Class : Classes)
+    BaseClassArrayData.push_back(
+        getImageRelativeConstant(CGM, getBaseClassDescriptor(Class)));
+  BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
+  BCA->setInitializer(llvm::ConstantArray::get(ArrayType, BaseClassArrayData));
+  return BCA;
+}
+
+llvm::GlobalVariable *
+MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) {
+  // Compute the fields for the BaseClassDescriptor.  They are computed up front
+  // because they are mangled into the name of the object.
+  uint32_t OffsetInVBTable = 0;
+  int32_t VBPtrOffset = -1;
+  if (Class.VirtualRoot) {
+    auto &VTableContext = CGM.getMicrosoftVTableContext();
+    OffsetInVBTable = VTableContext.getVBTableIndex(RD, Class.VirtualRoot) * 4;
+    VBPtrOffset = Context.getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
+  }
+
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    Mangler.mangleCXXRTTIBaseClassDescriptor(Class.RD, Class.OffsetInVBase,
+                                             VBPtrOffset, OffsetInVBTable,
+                                             Class.Flags, Out);
+  }
+
+  // Check to see if we've already declared declared this object.
+  if (auto BCD = Module.getNamedGlobal(MangledName))
+    return BCD;
+
+  // Forward-declare the base class descriptor.
+  auto Type = getBaseClassDescriptorType(CGM);
+  auto BCD = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
+                                      /*Initializer=*/nullptr,
+                                      MangledName.c_str());
+
+  // Initialize the BaseClassDescriptor.
+  llvm::Constant *Fields[] = {
+    getImageRelativeConstant(
+        CGM, CGM.GetAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD))),
+    llvm::ConstantInt::get(CGM.IntTy, Class.NumBases),
+    llvm::ConstantInt::get(CGM.IntTy, Class.OffsetInVBase),
+    llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
+    llvm::ConstantInt::get(CGM.IntTy, OffsetInVBTable),
+    llvm::ConstantInt::get(CGM.IntTy, Class.Flags),
+    getImageRelativeConstant(
+        CGM, MSRTTIBuilder(CGM, Class.RD).getClassHierarchyDescriptor()),
+  };
+  BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
+  return BCD;
+}
+
+llvm::GlobalVariable *
+MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo *Info) {
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    Mangler.mangleCXXRTTICompleteObjectLocator(RD, Info->MangledPath, Out);
+  }
+
+  // Check to see if we've already computed this complete object locator.
+  if (auto COL = Module.getNamedGlobal(MangledName))
+    return COL;
+
+  // Compute the fields of the complete object locator.
+  int OffsetToTop = Info->FullOffsetInMDC.getQuantity();
+  int VFPtrOffset = 0;
+  // The offset includes the vtordisp if one exists.
+  if (const CXXRecordDecl *VBase = Info->getVBaseWithVPtr())
+    if (Context.getASTRecordLayout(RD)
+      .getVBaseOffsetsMap()
+      .find(VBase)
+      ->second.hasVtorDisp())
+      VFPtrOffset = Info->NonVirtualOffset.getQuantity() + 4;
+
+  // Forward-declare the complete object locator.
+  llvm::StructType *Type = getCompleteObjectLocatorType(CGM);
+  auto COL = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
+    /*Initializer=*/nullptr, MangledName.c_str());
+
+  // Initialize the CompleteObjectLocator.
+  llvm::Constant *Fields[] = {
+    llvm::ConstantInt::get(CGM.IntTy, isImageRelative(CGM)),
+    llvm::ConstantInt::get(CGM.IntTy, OffsetToTop),
+    llvm::ConstantInt::get(CGM.IntTy, VFPtrOffset),
+    getImageRelativeConstant(
+        CGM, CGM.GetAddrOfRTTIDescriptor(Context.getTypeDeclType(RD))),
+    getImageRelativeConstant(CGM, getClassHierarchyDescriptor()),
+    getImageRelativeConstant(CGM, COL),
+  };
+  llvm::ArrayRef<llvm::Constant *> FieldsRef(Fields);
+  if (!isImageRelative(CGM))
+    FieldsRef = FieldsRef.slice(0, FieldsRef.size() - 1);
+  COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
+  return COL;
+}
+
+/// \brief Gets a TypeDescriptor.  Returns a llvm::Constant * rather than a
+/// llvm::GlobalVariable * because different type descriptors have different
+/// types, and need to be abstracted.  They are abstracting by casting the
+/// address to an Int8PtrTy.
+llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) {
+  auto &Mangler(getMangleContext());
+  SmallString<256> MangledName, TypeInfoString;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    Mangler.mangleCXXRTTI(Type, Out);
+  }
+
+  // Check to see if we've already declared this TypeDescriptor.
+  if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
+    return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
+
+  // Compute the fields for the TypeDescriptor.
+  {
+    llvm::raw_svector_ostream Out(TypeInfoString);
+    Mangler.mangleCXXRTTIName(Type, Out);
+  }
+
+  // Declare and initialize the TypeDescriptor.
+  llvm::Constant *Fields[] = {
+    getTypeInfoVTable(CGM),                        // VFPtr
+    llvm::ConstantPointerNull::get(CGM.Int8PtrTy), // Runtime data
+    llvm::ConstantDataArray::getString(CGM.getLLVMContext(), TypeInfoString)};
+  llvm::StructType *TypeDescriptorType =
+      getTypeDescriptorType(CGM, TypeInfoString);
+  return llvm::ConstantExpr::getBitCast(
+      new llvm::GlobalVariable(
+          CGM.getModule(), TypeDescriptorType, /*Constant=*/false,
+          getLinkageForRTTI(Type),
+          llvm::ConstantStruct::get(TypeDescriptorType, Fields),
+          MangledName.c_str()),
+      CGM.Int8PtrTy);
+}
+
+/// \brief Gets or a creates a Microsoft CompleteObjectLocator.
+llvm::GlobalVariable *
+MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
+                                            const VPtrInfo *Info) {
+  return MSRTTIBuilder(CGM, RD).getCompleteObjectLocator(Info);
+}

Removed: cfe/trunk/lib/CodeGen/MicrosoftRTTI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftRTTI.cpp?rev=212434&view=auto
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftRTTI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftRTTI.cpp (removed)
@@ -1,529 +0,0 @@
-//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with C++ code generation of RTTI descriptors.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenModule.h"
-#include "CGCXXABI.h"
-#include "CGObjCRuntime.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/AST/Type.h"
-#include "clang/Frontend/CodeGenOptions.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-// MS RTTI Overview:
-// The run time type information emitted by cl.exe contains 5 distinct types of
-// structures.  Many of them reference each other.
-//
-// TypeInfo:  Static classes that are returned by typeid.
-//
-// CompleteObjectLocator:  Referenced by vftables.  They contain information
-//   required for dynamic casting, including OffsetFromTop.  They also contain
-//   a reference to the TypeInfo for the type and a reference to the
-//   CompleteHierarchyDescriptor for the type.
-//
-// ClassHieararchyDescriptor: Contains information about a class hierarchy.
-//   Used during dynamic_cast to walk a class hierarchy.  References a base
-//   class array and the size of said array.
-//
-// BaseClassArray: Contains a list of classes in a hierarchy.  BaseClassArray is
-//   somewhat of a misnomer because the most derived class is also in the list
-//   as well as multiple copies of virtual bases (if they occur multiple times
-//   in the hiearchy.)  The BaseClassArray contains one BaseClassDescriptor for
-//   every path in the hierarchy, in pre-order depth first order.  Note, we do
-//   not declare a specific llvm type for BaseClassArray, it's merely an array
-//   of BaseClassDescriptor pointers.
-//
-// BaseClassDescriptor: Contains information about a class in a class hierarchy.
-//   BaseClassDescriptor is also somewhat of a misnomer for the same reason that
-//   BaseClassArray is.  It contains information about a class within a
-//   hierarchy such as: is this base is ambiguous and what is its offset in the
-//   vbtable.  The names of the BaseClassDescriptors have all of their fields
-//   mangled into them so they can be aggressively deduplicated by the linker.
-
-static bool isImageRelative(CodeGenModule &CGM) {
-  return CGM.getTarget().getPointerWidth(/*AddressSpace=*/0) == 64;
-}
-
-static llvm::Type *getImageRelativeType(CodeGenModule &CGM,
-                                        llvm::Type *PtrType) {
-  if (!isImageRelative(CGM))
-    return PtrType;
-  return CGM.IntTy;
-}
-
-static llvm::GlobalVariable *getImageBase(CodeGenModule &CGM) {
-  StringRef Name = "__ImageBase";
-  if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
-    return GV;
-
-  return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
-                                  /*isConstant=*/true,
-                                  llvm::GlobalValue::ExternalLinkage,
-                                  /*Initializer=*/nullptr, Name);
-}
-
-static llvm::Constant *getImageRelativeConstant(CodeGenModule &CGM,
-                                                llvm::Constant *PtrVal) {
-  if (!isImageRelative(CGM))
-    return PtrVal;
-
-  llvm::Constant *ImageBaseAsInt =
-      llvm::ConstantExpr::getPtrToInt(getImageBase(CGM), CGM.IntPtrTy);
-  llvm::Constant *PtrValAsInt =
-      llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
-  llvm::Constant *Diff =
-      llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
-                                 /*HasNUW=*/true, /*HasNSW=*/true);
-  return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
-}
-
-// 5 routines for constructing the llvm types for MS RTTI structs.
-static llvm::StructType *getClassHierarchyDescriptorType(CodeGenModule &CGM);
-
-static llvm::StructType *getTypeDescriptorType(CodeGenModule &CGM,
-                                               StringRef TypeInfoString) {
-  llvm::SmallString<32> TDTypeName("MSRTTITypeDescriptor");
-  TDTypeName += TypeInfoString.size();
-  if (auto Type = CGM.getModule().getTypeByName(TDTypeName))
-    return Type;
-  llvm::Type *FieldTypes[] = {
-      CGM.Int8PtrPtrTy,
-      CGM.Int8PtrTy,
-      llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
-  return llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, TDTypeName);
-}
-
-static llvm::StructType *getBaseClassDescriptorType(CodeGenModule &CGM) {
-  static const char Name[] = "MSRTTIBaseClassDescriptor";
-  if (auto Type = CGM.getModule().getTypeByName(Name))
-    return Type;
-  llvm::Type *FieldTypes[] = {
-      getImageRelativeType(CGM, CGM.Int8PtrTy),
-      CGM.IntTy,
-      CGM.IntTy,
-      CGM.IntTy,
-      CGM.IntTy,
-      CGM.IntTy,
-      getImageRelativeType(
-          CGM, getClassHierarchyDescriptorType(CGM)->getPointerTo()),
-  };
-  return llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, Name);
-}
-
-static llvm::StructType *getClassHierarchyDescriptorType(CodeGenModule &CGM) {
-  static const char Name[] = "MSRTTIClassHierarchyDescriptor";
-  if (auto Type = CGM.getModule().getTypeByName(Name))
-    return Type;
-  // Forward-declare RTTIClassHierarchyDescriptor to break a cycle.
-  llvm::StructType *Type = llvm::StructType::create(CGM.getLLVMContext(), Name);
-  llvm::Type *FieldTypes[] = {
-    CGM.IntTy,
-    CGM.IntTy,
-    CGM.IntTy,
-    getImageRelativeType(
-        CGM,
-        getBaseClassDescriptorType(CGM)->getPointerTo()->getPointerTo()),
-  };
-  Type->setBody(FieldTypes);
-  return Type;
-}
-
-static llvm::StructType *getCompleteObjectLocatorType(CodeGenModule &CGM) {
-  static const char Name[] = "MSRTTICompleteObjectLocator";
-  if (auto Type = CGM.getModule().getTypeByName(Name))
-    return Type;
-  llvm::StructType *Type = llvm::StructType::create(CGM.getLLVMContext(), Name);
-  llvm::Type *FieldTypes[] = {
-    CGM.IntTy,
-    CGM.IntTy,
-    CGM.IntTy,
-    getImageRelativeType(CGM, CGM.Int8PtrTy),
-    getImageRelativeType(
-        CGM, getClassHierarchyDescriptorType(CGM)->getPointerTo()),
-    getImageRelativeType(CGM, Type),
-  };
-  ArrayRef<llvm::Type *> FieldTypesRef(
-      std::begin(FieldTypes),
-      isImageRelative(CGM) ? std::end(FieldTypes) : std::end(FieldTypes) - 1);
-  Type->setBody(FieldTypesRef);
-  return Type;
-}
-
-static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) {
-  StringRef MangledName("\01??_7type_info@@6B@");
-  if (auto VTable = CGM.getModule().getNamedGlobal(MangledName))
-    return VTable;
-  return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
-                                  /*Constant=*/true,
-                                  llvm::GlobalVariable::ExternalLinkage,
-                                  /*Initializer=*/nullptr, MangledName);
-}
-
-namespace {
-
-/// \brief A Helper struct that stores information about a class in a class
-/// hierarchy.  The information stored in these structs struct is used during
-/// the generation of ClassHierarchyDescriptors and BaseClassDescriptors.
-// During RTTI creation, MSRTTIClasses are stored in a contiguous array with
-// implicit depth first pre-order tree connectivity.  getFirstChild and
-// getNextSibling allow us to walk the tree efficiently.
-struct MSRTTIClass {
-  enum {
-    IsPrivateOnPath = 1 | 8,
-    IsAmbiguous = 2,
-    IsPrivate = 4,
-    IsVirtual = 16,
-    HasHierarchyDescriptor = 64
-  };
-  MSRTTIClass(const CXXRecordDecl *RD) : RD(RD) {}
-  uint32_t initialize(const MSRTTIClass *Parent,
-                      const CXXBaseSpecifier *Specifier);
-
-  MSRTTIClass *getFirstChild() { return this + 1; }
-  static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
-    return Child + 1 + Child->NumBases;
-  }
-
-  const CXXRecordDecl *RD, *VirtualRoot;
-  uint32_t Flags, NumBases, OffsetInVBase;
-};
-
-/// \brief Recursively initialize the base class array.
-uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent,
-                                 const CXXBaseSpecifier *Specifier) {
-  Flags = HasHierarchyDescriptor;
-  if (!Parent) {
-    VirtualRoot = nullptr;
-    OffsetInVBase = 0;
-  } else {
-    if (Specifier->getAccessSpecifier() != AS_public)
-      Flags |= IsPrivate | IsPrivateOnPath;
-    if (Specifier->isVirtual()) {
-      Flags |= IsVirtual;
-      VirtualRoot = RD;
-      OffsetInVBase = 0;
-    } else {
-      if (Parent->Flags & IsPrivateOnPath)
-        Flags |= IsPrivateOnPath;
-      VirtualRoot = Parent->VirtualRoot;
-      OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
-          .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
-    }
-  }
-  NumBases = 0;
-  MSRTTIClass *Child = getFirstChild();
-  for (const CXXBaseSpecifier &Base : RD->bases()) {
-    NumBases += Child->initialize(this, &Base) + 1;
-    Child = getNextChild(Child);
-  }
-  return NumBases;
-}
-
-static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
-  switch (Ty->getLinkage()) {
-  case NoLinkage:
-  case InternalLinkage:
-  case UniqueExternalLinkage:
-    return llvm::GlobalValue::InternalLinkage;
-
-  case VisibleNoLinkage:
-  case ExternalLinkage:
-    return llvm::GlobalValue::LinkOnceODRLinkage;
-  }
-  llvm_unreachable("Invalid linkage!");
-}
-
-/// \brief An ephemeral helper class for building MS RTTI types.  It caches some
-/// calls to the module and information about the most derived class in a
-/// hierarchy.
-struct MSRTTIBuilder {
-  enum {
-    HasBranchingHierarchy = 1,
-    HasVirtualBranchingHierarchy = 2,
-    HasAmbiguousBases = 4
-  };
-
-  MSRTTIBuilder(CodeGenModule &CGM, const CXXRecordDecl *RD)
-      : CGM(CGM), Context(CGM.getContext()), VMContext(CGM.getLLVMContext()),
-        Module(CGM.getModule()), RD(RD),
-        Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
-        Mangler(
-            cast<MicrosoftMangleContext>(CGM.getCXXABI().getMangleContext())) {}
-
-  llvm::GlobalVariable *getBaseClassDescriptor(const MSRTTIClass &Classes);
-  llvm::GlobalVariable *
-  getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
-  llvm::GlobalVariable *getClassHierarchyDescriptor();
-  llvm::GlobalVariable *getCompleteObjectLocator(const VPtrInfo *Info);
-
-  CodeGenModule &CGM;
-  ASTContext &Context;
-  llvm::LLVMContext &VMContext;
-  llvm::Module &Module;
-  const CXXRecordDecl *RD;
-  llvm::GlobalVariable::LinkageTypes Linkage;
-  MicrosoftMangleContext &Mangler;
-};
-
-} // namespace
-
-/// \brief Recursively serializes a class hierarchy in pre-order depth first
-/// order.
-static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes,
-                                    const CXXRecordDecl *RD) {
-  Classes.push_back(MSRTTIClass(RD));
-  for (const CXXBaseSpecifier &Base : RD->bases())
-    serializeClassHierarchy(Classes, Base.getType()->getAsCXXRecordDecl());
-}
-
-/// \brief Find ambiguity among base classes.
-static void
-detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> &Classes) {
-  llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
-  llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
-  llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
-  for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
-    if ((Class->Flags & MSRTTIClass::IsVirtual) &&
-        !VirtualBases.insert(Class->RD)) {
-      Class = MSRTTIClass::getNextChild(Class);
-      continue;
-    }
-    if (!UniqueBases.insert(Class->RD))
-      AmbiguousBases.insert(Class->RD);
-    Class++;
-  }
-  if (AmbiguousBases.empty())
-    return;
-  for (MSRTTIClass &Class : Classes)
-    if (AmbiguousBases.count(Class.RD))
-      Class.Flags |= MSRTTIClass::IsAmbiguous;
-}
-
-llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
-  SmallString<256> MangledName;
-  {
-    llvm::raw_svector_ostream Out(MangledName);
-    Mangler.mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
-  }
-
-  // Check to see if we've already declared this ClassHierarchyDescriptor.
-  if (auto CHD = Module.getNamedGlobal(MangledName))
-    return CHD;
-
-  // Serialize the class hierarchy and initialize the CHD Fields.
-  SmallVector<MSRTTIClass, 8> Classes;
-  serializeClassHierarchy(Classes, RD);
-  Classes.front().initialize(/*Parent=*/nullptr, /*Specifier=*/nullptr);
-  detectAmbiguousBases(Classes);
-  int Flags = 0;
-  for (auto Class : Classes) {
-    if (Class.RD->getNumBases() > 1)
-      Flags |= HasBranchingHierarchy;
-    // Note: cl.exe does not calculate "HasAmbiguousBases" correctly.  We
-    // believe the field isn't actually used.
-    if (Class.Flags & MSRTTIClass::IsAmbiguous)
-      Flags |= HasAmbiguousBases;
-  }
-  if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
-    Flags |= HasVirtualBranchingHierarchy;
-  // These gep indices are used to get the address of the first element of the
-  // base class array.
-  llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
-                               llvm::ConstantInt::get(CGM.IntTy, 0)};
-
-  // Forward-declare the class hierarchy descriptor
-  auto Type = getClassHierarchyDescriptorType(CGM);
-  auto CHD = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
-                                      /*Initializer=*/nullptr,
-                                      MangledName.c_str());
-
-  // Initialize the base class ClassHierarchyDescriptor.
-  llvm::Constant *Fields[] = {
-    llvm::ConstantInt::get(CGM.IntTy, 0), // Unknown
-    llvm::ConstantInt::get(CGM.IntTy, Flags),
-    llvm::ConstantInt::get(CGM.IntTy, Classes.size()),
-    getImageRelativeConstant(CGM,
-                             llvm::ConstantExpr::getInBoundsGetElementPtr(
-                                 getBaseClassArray(Classes),
-                                 ArrayRef<llvm::Value *>(GEPIndices))),
-  };
-  CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
-  return CHD;
-}
-
-llvm::GlobalVariable *
-MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
-  SmallString<256> MangledName;
-  {
-    llvm::raw_svector_ostream Out(MangledName);
-    Mangler.mangleCXXRTTIBaseClassArray(RD, Out);
-  }
-
-  // Forward-declare the base class array.
-  // cl.exe pads the base class array with 1 (in 32 bit mode) or 4 (in 64 bit
-  // mode) bytes of padding.  We provide a pointer sized amount of padding by
-  // adding +1 to Classes.size().  The sections have pointer alignment and are
-  // marked pick-any so it shouldn't matter.
-  auto PtrType = getImageRelativeType(
-      CGM, getBaseClassDescriptorType(CGM)->getPointerTo());
-  auto ArrayType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
-  auto BCA = new llvm::GlobalVariable(Module, ArrayType,
-      /*Constant=*/true, Linkage, /*Initializer=*/nullptr, MangledName.c_str());
-
-  // Initialize the BaseClassArray.
-  SmallVector<llvm::Constant *, 8> BaseClassArrayData;
-  for (MSRTTIClass &Class : Classes)
-    BaseClassArrayData.push_back(
-        getImageRelativeConstant(CGM, getBaseClassDescriptor(Class)));
-  BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
-  BCA->setInitializer(llvm::ConstantArray::get(ArrayType, BaseClassArrayData));
-  return BCA;
-}
-
-llvm::GlobalVariable *
-MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) {
-  // Compute the fields for the BaseClassDescriptor.  They are computed up front
-  // because they are mangled into the name of the object.
-  uint32_t OffsetInVBTable = 0;
-  int32_t VBPtrOffset = -1;
-  if (Class.VirtualRoot) {
-    auto &VTableContext = CGM.getMicrosoftVTableContext();
-    OffsetInVBTable = VTableContext.getVBTableIndex(RD, Class.VirtualRoot) * 4;
-    VBPtrOffset = Context.getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
-  }
-
-  SmallString<256> MangledName;
-  {
-    llvm::raw_svector_ostream Out(MangledName);
-    Mangler.mangleCXXRTTIBaseClassDescriptor(Class.RD, Class.OffsetInVBase,
-                                             VBPtrOffset, OffsetInVBTable,
-                                             Class.Flags, Out);
-  }
-
-  // Check to see if we've already declared declared this object.
-  if (auto BCD = Module.getNamedGlobal(MangledName))
-    return BCD;
-
-  // Forward-declare the base class descriptor.
-  auto Type = getBaseClassDescriptorType(CGM);
-  auto BCD = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
-                                      /*Initializer=*/nullptr,
-                                      MangledName.c_str());
-
-  // Initialize the BaseClassDescriptor.
-  llvm::Constant *Fields[] = {
-    getImageRelativeConstant(
-        CGM, CGM.getMSTypeDescriptor(Context.getTypeDeclType(Class.RD))),
-    llvm::ConstantInt::get(CGM.IntTy, Class.NumBases),
-    llvm::ConstantInt::get(CGM.IntTy, Class.OffsetInVBase),
-    llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
-    llvm::ConstantInt::get(CGM.IntTy, OffsetInVBTable),
-    llvm::ConstantInt::get(CGM.IntTy, Class.Flags),
-    getImageRelativeConstant(
-        CGM, MSRTTIBuilder(CGM, Class.RD).getClassHierarchyDescriptor()),
-  };
-  BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
-  return BCD;
-}
-
-llvm::GlobalVariable *
-MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo *Info) {
-  SmallString<256> MangledName;
-  {
-    llvm::raw_svector_ostream Out(MangledName);
-    Mangler.mangleCXXRTTICompleteObjectLocator(RD, Info->MangledPath, Out);
-  }
-
-  // Check to see if we've already computed this complete object locator.
-  if (auto COL = Module.getNamedGlobal(MangledName))
-    return COL;
-
-  // Compute the fields of the complete object locator.
-  int OffsetToTop = Info->FullOffsetInMDC.getQuantity();
-  int VFPtrOffset = 0;
-  // The offset includes the vtordisp if one exists.
-  if (const CXXRecordDecl *VBase = Info->getVBaseWithVPtr())
-    if (Context.getASTRecordLayout(RD)
-      .getVBaseOffsetsMap()
-      .find(VBase)
-      ->second.hasVtorDisp())
-      VFPtrOffset = Info->NonVirtualOffset.getQuantity() + 4;
-
-  // Forward-declare the complete object locator.
-  llvm::StructType *Type = getCompleteObjectLocatorType(CGM);
-  auto COL = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
-    /*Initializer=*/nullptr, MangledName.c_str());
-
-  // Initialize the CompleteObjectLocator.
-  llvm::Constant *Fields[] = {
-    llvm::ConstantInt::get(CGM.IntTy, isImageRelative(CGM)),
-    llvm::ConstantInt::get(CGM.IntTy, OffsetToTop),
-    llvm::ConstantInt::get(CGM.IntTy, VFPtrOffset),
-    getImageRelativeConstant(
-        CGM, CGM.getMSTypeDescriptor(Context.getTypeDeclType(RD))),
-    getImageRelativeConstant(CGM, getClassHierarchyDescriptor()),
-    getImageRelativeConstant(CGM, COL),
-  };
-  ArrayRef<llvm::Constant *> FieldsRef(Fields);
-  if (!isImageRelative(CGM))
-    FieldsRef = FieldsRef.slice(0, FieldsRef.size() - 1);
-  COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
-  return COL;
-}
-
-
-/// \brief Gets a TypeDescriptor.  Returns a llvm::Constant * rather than a
-/// llvm::GlobalVariable * because different type descriptors have different
-/// types, and need to be abstracted.  They are abstracting by casting the
-/// address to an Int8PtrTy.
-llvm::Constant *CodeGenModule::getMSTypeDescriptor(QualType Type) {
-  auto &Mangler(cast<MicrosoftMangleContext>(getCXXABI().getMangleContext()));
-  SmallString<256> MangledName, TypeInfoString;
-  {
-    llvm::raw_svector_ostream Out(MangledName);
-    Mangler.mangleCXXRTTI(Type, Out);
-  }
-
-  // Check to see if we've already declared this TypeDescriptor.
-  if (auto TypeDescriptor = getModule().getNamedGlobal(MangledName))
-    return llvm::ConstantExpr::getBitCast(TypeDescriptor, Int8PtrTy);
-
-  // Compute the fields for the TypeDescriptor.
-  {
-    llvm::raw_svector_ostream Out(TypeInfoString);
-    Mangler.mangleCXXRTTIName(Type, Out);
-  }
-
-  // Declare and initialize the TypeDescriptor.
-  llvm::Constant *Fields[] = {
-    getTypeInfoVTable(*this),                  // VFPtr
-    llvm::ConstantPointerNull::get(Int8PtrTy), // Runtime data
-    llvm::ConstantDataArray::getString(VMContext, TypeInfoString)};
-  auto TypeDescriptorType = getTypeDescriptorType(*this, TypeInfoString);
-  return llvm::ConstantExpr::getBitCast(
-      new llvm::GlobalVariable(
-          getModule(), TypeDescriptorType, /*Constant=*/false,
-          getLinkageForRTTI(Type),
-          llvm::ConstantStruct::get(TypeDescriptorType, Fields),
-          MangledName.c_str()),
-      Int8PtrTy);
-}
-
-llvm::Constant *
-CodeGenModule::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
-                                          const VPtrInfo *Info) {
-  if (!getLangOpts().RTTIData)
-    return llvm::Constant::getNullValue(Int8PtrTy);
-  return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info);
-}





More information about the cfe-commits mailing list