zcov: / lib/CodeGen/CGRTTI.cpp


Files: 1 Branches Taken: 75.9% 151 / 199
Generated: 2010-02-10 01:31 Branches Executed: 89.9% 179 / 199
Line Coverage: 84.9% 253 / 298


Programs: 1 Runs 2897


       1                 : //===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This contains code dealing with C++ code generation of RTTI descriptors.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/AST/Type.h"
      15                 : #include "clang/AST/RecordLayout.h"
      16                 : #include "CodeGenModule.h"
      17                 : using namespace clang;
      18                 : using namespace CodeGen;
      19                 : 
      20                 : namespace {
      21              671: class RTTIBuilder {
      22                 :   CodeGenModule &CGM;  // Per-module state.
      23                 :   llvm::LLVMContext &VMContext;
      24                 :   
      25                 :   const llvm::Type *Int8PtrTy;
      26                 :   
      27                 :   /// Fields - The fields of the RTTI descriptor currently being built.
      28                 :   llvm::SmallVector<llvm::Constant *, 16> Fields;
      29                 : 
      30                 :   /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI 
      31                 :   /// descriptor of the given type.
      32                 :   llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
      33                 :   
      34                 :   /// BuildVtablePointer - Build the vtable pointer for the given type.
      35                 :   void BuildVtablePointer(const Type *Ty);
      36                 :   
      37                 :   /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
      38                 :   /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
      39                 :   void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
      40                 :   
      41                 :   /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
      42                 :   /// classes with bases that do not satisfy the abi::__si_class_type_info 
      43                 :   /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
      44                 :   void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
      45                 :   
      46                 :   /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
      47                 :   /// for pointer types.
      48                 :   void BuildPointerTypeInfo(const PointerType *Ty);
      49                 :   
      50                 :   /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
      51                 :   /// struct, used for member pointer types.
      52                 :   void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
      53                 :   
      54                 : public:
      55              671:   RTTIBuilder(CodeGenModule &cgm)
      56                 :     : CGM(cgm), VMContext(cgm.getModule().getContext()),
      57              671:       Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
      58                 : 
      59                 :   llvm::Constant *BuildName(QualType Ty, bool Hidden, 
      60              292:                             llvm::GlobalVariable::LinkageTypes Linkage) {
      61              292:     llvm::SmallString<256> OutName;
      62              292:     CGM.getMangleContext().mangleCXXRTTIName(Ty, OutName);
      63              292:     llvm::StringRef Name = OutName.str();
      64                 : 
      65              292:     llvm::GlobalVariable *OGV = CGM.getModule().getNamedGlobal(Name);
                        0: branch 0 not taken
                      292: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                      292: branch 6 taken
      66              292:     if (OGV && !OGV->isDeclaration())
      67                0:       return llvm::ConstantExpr::getBitCast(OGV, Int8PtrTy);
      68                 : 
      69              292:     llvm::Constant *C = llvm::ConstantArray::get(VMContext, Name.substr(4));
      70                 : 
      71                 :     llvm::GlobalVariable *GV = 
      72                 :       new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, Linkage,
      73              292:                                C, Name);
                        0: branch 0 not taken
                      292: branch 1 taken
      74              292:     if (OGV) {
      75                0:       GV->takeName(OGV);
      76                 :       llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
      77                0:                                                               OGV->getType());
      78                0:       OGV->replaceAllUsesWith(NewPtr);
      79                0:       OGV->eraseFromParent();
      80                 :     }
                        0: branch 0 not taken
                      292: branch 1 taken
      81              292:     if (Hidden)
      82                0:       GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
      83              292:     return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
      84                 :   }
      85                 : 
      86                 :   // FIXME: unify with DecideExtern
      87              324:   bool DecideHidden(QualType Ty) {
      88                 :     // For this type, see if all components are never hidden.
                        9: branch 2 taken
                      315: branch 3 taken
      89              324:     if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
      90                 :       return (DecideHidden(MPT->getPointeeType())
                        0: branch 2 not taken
                        9: branch 3 taken
                        0: branch 7 not taken
                        0: branch 8 not taken
      91                9:               && DecideHidden(QualType(MPT->getClass(), 0)));
                       17: branch 2 taken
                      298: branch 3 taken
      92              315:     if (const PointerType *PT = Ty->getAs<PointerType>())
      93               17:       return DecideHidden(PT->getPointeeType());
                        6: branch 2 taken
                      292: branch 3 taken
      94              298:     if (const FunctionType *FT = Ty->getAs<FunctionType>()) {
                        6: branch 2 taken
                        0: branch 3 not taken
      95                6:       if (DecideHidden(FT->getResultType()) == false)
      96                6:         return false;
                        0: branch 2 not taken
                        0: branch 3 not taken
      97                0:       if (const FunctionProtoType *FPT = Ty->getAs<FunctionProtoType>()) {
                        0: branch 1 not taken
                        0: branch 2 not taken
      98                0:         for (unsigned i = 0; i <FPT->getNumArgs(); ++i)
                        0: branch 2 not taken
                        0: branch 3 not taken
      99                0:           if (DecideHidden(FPT->getArgType(i)) == false)
     100                0:             return false;
                        0: branch 1 not taken
                        0: branch 2 not taken
     101                0:         for (unsigned i = 0; i <FPT->getNumExceptions(); ++i)
                        0: branch 2 not taken
                        0: branch 3 not taken
     102                0:           if (DecideHidden(FPT->getExceptionType(i)) == false)
     103                0:             return false;
     104                0:         return true;
     105                 :       }
     106                 :     }
                      283: branch 2 taken
                        9: branch 3 taken
     107              292:     if (const RecordType *RT = Ty->getAs<RecordType>())
                      283: branch 2 taken
                        0: branch 3 not taken
     108              283:       if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
     109              283:         return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
     110                9:     return false;
     111                 :   }
     112                 :   
     113                 :   // Pointer type info flags.
     114                 :   enum {
     115                 :     /// PTI_Const - Type has const qualifier.
     116                 :     PTI_Const = 0x1,
     117                 :     
     118                 :     /// PTI_Volatile - Type has volatile qualifier.
     119                 :     PTI_Volatile = 0x2,
     120                 :     
     121                 :     /// PTI_Restrict - Type has restrict qualifier.
     122                 :     PTI_Restrict = 0x4,
     123                 :     
     124                 :     /// PTI_Incomplete - Type is incomplete.
     125                 :     PTI_Incomplete = 0x8,
     126                 :     
     127                 :     /// PTI_ContainingClassIncomplete - Containing class is incomplete.
     128                 :     /// (in pointer to member).
     129                 :     PTI_ContainingClassIncomplete = 0x10
     130                 :   };
     131                 :   
     132                 :   // VMI type info flags.
     133                 :   enum {
     134                 :     /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
     135                 :     VMI_NonDiamondRepeat = 0x1,
     136                 :     
     137                 :     /// VMI_DiamondShaped - Class is diamond shaped.
     138                 :     VMI_DiamondShaped = 0x2
     139                 :   };
     140                 :   
     141                 :   // Base class type info flags.
     142                 :   enum {
     143                 :     /// BCTI_Virtual - Base class is virtual.
     144                 :     BCTI_Virtual = 0x1,
     145                 :     
     146                 :     /// BCTI_Public - Base class is public.
     147                 :     BCTI_Public = 0x2
     148                 :   };
     149                 :   
     150                 :   /// BuildTypeInfo - Build the RTTI type info struct for the given type.
     151                 :   llvm::Constant *BuildTypeInfo(QualType Ty);
     152                 : };
     153                 : }
     154                 : 
     155               83: llvm::Constant *RTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
     156                 :   // Mangle the RTTI name.
     157               83:   llvm::SmallString<256> OutName;
     158               83:   CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
     159               83:   llvm::StringRef Name = OutName.str();
     160                 : 
     161                 :   // Look for an existing global.
     162               83:   llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
     163                 :   
                       61: branch 0 taken
                       22: branch 1 taken
     164               83:   if (!GV) {
     165                 :     // Create a new global variable.
     166                 :     GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, /*Constant=*/true,
     167               61:                                   llvm::GlobalValue::ExternalLinkage, 0, Name);
     168                 :   }
     169                 :   
     170               83:   return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
     171                 : }
     172                 : 
     173                 : /// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
     174                 : /// info for that type is defined in the standard library.
     175                4: static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
     176                 :   // Itanium C++ ABI 2.9.2:
     177                 :   //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
     178                 :   //   the run-time support library. Specifically, the run-time support
     179                 :   //   library should contain type_info objects for the types X, X* and 
     180                 :   //   X const*, for every X in: void, bool, wchar_t, char, unsigned char, 
     181                 :   //   signed char, short, unsigned short, int, unsigned int, long, 
     182                 :   //   unsigned long, long long, unsigned long long, float, double, long double, 
     183                 :   //   char16_t, char32_t, and the IEEE 754r decimal and half-precision 
     184                 :   //   floating point types.
                        4: branch 1 taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
     185                4:   switch (Ty->getKind()) {
     186                 :     case BuiltinType::Void:
     187                 :     case BuiltinType::Bool:
     188                 :     case BuiltinType::WChar:
     189                 :     case BuiltinType::Char_U:
     190                 :     case BuiltinType::Char_S:
     191                 :     case BuiltinType::UChar:
     192                 :     case BuiltinType::SChar:
     193                 :     case BuiltinType::Short:
     194                 :     case BuiltinType::UShort:
     195                 :     case BuiltinType::Int:
     196                 :     case BuiltinType::UInt:
     197                 :     case BuiltinType::Long:
     198                 :     case BuiltinType::ULong:
     199                 :     case BuiltinType::LongLong:
     200                 :     case BuiltinType::ULongLong:
     201                 :     case BuiltinType::Float:
     202                 :     case BuiltinType::Double:
     203                 :     case BuiltinType::LongDouble:
     204                 :     case BuiltinType::Char16:
     205                 :     case BuiltinType::Char32:
     206                 :     case BuiltinType::Int128:
     207                 :     case BuiltinType::UInt128:
     208                4:       return true;
     209                 :       
     210                 :     case BuiltinType::Overload:
     211                 :     case BuiltinType::Dependent:
     212                 :     case BuiltinType::UndeducedAuto:
     213                0:       assert(false && "Should not see this type here!");
     214                 :       
     215                 :     case BuiltinType::NullPtr:
     216                0:       assert(false && "FIXME: nullptr_t is not handled!");
     217                 : 
     218                 :     case BuiltinType::ObjCId:
     219                 :     case BuiltinType::ObjCClass:
     220                 :     case BuiltinType::ObjCSel:
     221                0:       assert(false && "FIXME: Objective-C types are unsupported!");
     222                 :   }
     223                 :   
     224                 :   // Silent gcc.
     225                0:   return false;
     226                 : }
     227                 : 
     228               11: static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
     229               11:   QualType PointeeTy = PointerTy->getPointeeType();
     230               11:   const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
                       11: branch 0 taken
                        0: branch 1 not taken
     231               11:   if (!BuiltinTy)
     232               11:     return false;
     233                 :     
     234                 :   // Check the qualifiers.
     235                0:   Qualifiers Quals = PointeeTy.getQualifiers();
     236                0:   Quals.removeConst();
     237                 :     
                        0: branch 1 not taken
                        0: branch 2 not taken
     238                0:   if (!Quals.empty())
     239                0:     return false;
     240                 :     
     241                0:   return TypeInfoIsInStandardLibrary(BuiltinTy);
     242                 : }
     243                 : 
     244                 : /// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
     245                 : /// the given type exists somewhere else, and that we should not emit the typ
     246                 : /// information in this translation unit.
     247              375: bool ShouldUseExternalRTTIDescriptor(QualType Ty) {
     248                 :   // Type info for builtin types is defined in the standard library.
                        4: branch 1 taken
                      371: branch 2 taken
     249              375:   if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
     250                4:     return TypeInfoIsInStandardLibrary(BuiltinTy);
     251                 :   
     252                 :   // Type info for some pointer types to builtin types is defined in the
     253                 :   // standard library.
                       11: branch 1 taken
                      360: branch 2 taken
     254              371:   if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
     255               11:     return TypeInfoIsInStandardLibrary(PointerTy);
     256                 : 
                      347: branch 1 taken
                       13: branch 2 taken
     257              360:   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
     258              347:     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
                        2: branch 1 taken
                      345: branch 2 taken
     259              347:     if (!RD->hasDefinition())
     260                2:       return false;
     261                 : 
                       43: branch 1 taken
                      302: branch 2 taken
     262              345:     if (!RD->isDynamicClass())
     263               43:       return false;
     264                 : 
     265                 :     // Get the key function.
     266              302:     const CXXMethodDecl *KeyFunction = RD->getASTContext().getKeyFunction(RD);
                      117: branch 0 taken
                      185: branch 1 taken
                       79: branch 3 taken
                       38: branch 4 taken
                       79: branch 5 taken
                      223: branch 6 taken
     267              302:     if (KeyFunction && !KeyFunction->getBody()) {
     268                 :       // The class has a key function, but it is not defined in this translation
     269                 :       // unit, so we should use the external descriptor for it.
     270               79:       return true;
     271                 :     }
     272                 :   }
     273                 :   
     274              236:   return false;
     275                 : }
     276                 : 
     277                 : /// IsIncompleteClassType - Returns whether the given record type is incomplete.
     278              315: static bool IsIncompleteClassType(const RecordType *RecordTy) {
     279              315:   return !RecordTy->getDecl()->isDefinition();
     280                 : }  
     281                 : 
     282                 : /// ContainsIncompleteClassType - Returns whether the given type contains an
     283                 : /// incomplete class type. This is true if
     284                 : ///
     285                 : ///   * The given type is an incomplete class type.
     286                 : ///   * The given type is a pointer type whose pointee type contains an 
     287                 : ///     incomplete class type.
     288                 : ///   * The given type is a member pointer type whose class is an incomplete
     289                 : ///     class type.
     290                 : ///   * The given type is a member pointer type whoise pointee type contains an
     291                 : ///     incomplete class type.
     292                 : /// is an indirect or direct pointer to an incomplete class type.
     293              349: static bool ContainsIncompleteClassType(QualType Ty) {
                      297: branch 1 taken
                       52: branch 2 taken
     294              349:   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
                       21: branch 1 taken
                      276: branch 2 taken
     295              297:     if (IsIncompleteClassType(RecordTy))
     296               21:       return true;
     297                 :   }
     298                 :   
                       22: branch 1 taken
                      306: branch 2 taken
     299              328:   if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
     300               22:     return ContainsIncompleteClassType(PointerTy->getPointeeType());
     301                 :   
                       10: branch 0 taken
                      296: branch 1 taken
     302              306:   if (const MemberPointerType *MemberPointerTy = 
     303              306:       dyn_cast<MemberPointerType>(Ty)) {
     304                 :     // Check if the class type is incomplete.
     305               10:     const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
                        7: branch 1 taken
                        3: branch 2 taken
     306               10:     if (IsIncompleteClassType(ClassType))
     307                7:       return true;
     308                 :     
     309                3:     return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
     310                 :   }
     311                 :   
     312              296:   return false;
     313                 : }
     314                 : 
     315                 : /// getTypeInfoLinkage - Return the linkage that the type info and type info
     316                 : /// name constants should have for the given type.
     317              305: static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
     318                 :   // Itanium C++ ABI 2.9.5p7:
     319                 :   //   In addition, it and all of the intermediate abi::__pointer_type_info 
     320                 :   //   structs in the chain down to the abi::__class_type_info for the
     321                 :   //   incomplete class type must be prevented from resolving to the 
     322                 :   //   corresponding type_info structs for the complete class type, possibly
     323                 :   //   by making them local static objects. Finally, a dummy class RTTI is
     324                 :   //   generated for the incomplete type that will not resolve to the final 
     325                 :   //   complete class RTTI (because the latter need not exist), possibly by 
     326                 :   //   making it a local static object.
                       16: branch 1 taken
                      289: branch 2 taken
     327              305:   if (ContainsIncompleteClassType(Ty))
     328               16:     return llvm::GlobalValue::InternalLinkage;
     329                 :   
                        0: branch 2 not taken
                        5: branch 3 taken
                        1: branch 4 taken
                      272: branch 5 taken
                        5: branch 6 taken
                        6: branch 7 taken
                        0: branch 8 not taken
     330              289:   switch (Ty->getTypeClass()) {
     331                 :   default:   
     332                 :     // FIXME: We need to add code to handle all types.
     333                0:     assert(false && "Unhandled type!");
     334                 :     break;
     335                 : 
     336                 :   case Type::Pointer: {
     337                5:     const PointerType *PointerTy = cast<PointerType>(Ty);
     338                 :  
     339                 :     // If the pointee type has internal linkage, then the pointer type needs to
     340                 :     // have it as well.
                        3: branch 2 taken
                        2: branch 3 taken
     341                5:     if (getTypeInfoLinkage(PointerTy->getPointeeType()) == 
     342                 :         llvm::GlobalVariable::InternalLinkage)
     343                3:       return llvm::GlobalVariable::InternalLinkage;
     344                 :     
     345                2:     return llvm::GlobalVariable::WeakODRLinkage;
     346                 :   }
     347                 : 
     348                 :   case Type::Enum: {
     349                1:     const EnumType *EnumTy = cast<EnumType>(Ty);
     350                1:     const EnumDecl *ED = EnumTy->getDecl();
     351                 :     
     352                 :     // If we're in an anonymous namespace, then we always want internal linkage.
                        0: branch 1 not taken
                        1: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
     353                1:     if (ED->isInAnonymousNamespace() || !ED->hasLinkage())
     354                1:       return llvm::GlobalVariable::InternalLinkage;
     355                 :     
     356                0:     return llvm::GlobalValue::WeakODRLinkage;
     357                 :   }
     358                 : 
     359                 :   case Type::Record: {
     360              272:     const RecordType *RecordTy = cast<RecordType>(Ty);
     361              272:     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
     362                 : 
     363                 :     // If we're in an anonymous namespace, then we always want internal linkage.
                      264: branch 1 taken
                        8: branch 2 taken
                        3: branch 4 taken
                      261: branch 5 taken
                       11: branch 6 taken
                      261: branch 7 taken
     364              272:     if (RD->isInAnonymousNamespace() || !RD->hasLinkage())
     365               11:       return llvm::GlobalVariable::InternalLinkage;
     366                 : 
     367                 :     // If this class does not have a vtable, we want weak linkage.
                       42: branch 1 taken
                      219: branch 2 taken
     368              261:     if (!RD->isDynamicClass())
     369               42:       return llvm::GlobalValue::WeakODRLinkage;
     370                 :     
     371              219:     return CodeGenModule::getVtableLinkage(RD);
     372                 :   }
     373                 : 
     374                 :   case Type::Vector:
     375                 :   case Type::ExtVector:
     376                 :   case Type::Builtin:
     377                5:     return llvm::GlobalValue::WeakODRLinkage;
     378                 : 
     379                 :   case Type::FunctionProto: {
     380                6:     const FunctionProtoType *FPT = cast<FunctionProtoType>(Ty);
     381                 : 
     382                 :     // Check the return type.
                        2: branch 2 taken
                        4: branch 3 taken
     383                6:     if (getTypeInfoLinkage(FPT->getResultType()) == 
     384                 :         llvm::GlobalValue::InternalLinkage)
     385                2:       return llvm::GlobalValue::InternalLinkage;
     386                 :     
     387                 :     // Check the parameter types.
                        2: branch 1 taken
                        2: branch 2 taken
     388                4:     for (unsigned i = 0; i != FPT->getNumArgs(); ++i) {
                        2: branch 2 taken
                        0: branch 3 not taken
     389                2:       if (getTypeInfoLinkage(FPT->getArgType(i)) == 
     390                 :           llvm::GlobalValue::InternalLinkage)
     391                2:         return llvm::GlobalValue::InternalLinkage;
     392                 :     }
     393                 :     
     394                2:     return llvm::GlobalValue::WeakODRLinkage;
     395                 :   }
     396                 :   
     397                 :   case Type::ConstantArray: 
     398                 :   case Type::IncompleteArray: {
     399                0:     const ArrayType *AT = cast<ArrayType>(Ty);
     400                 : 
     401                 :     // Check the element type.
                        0: branch 2 not taken
                        0: branch 3 not taken
     402                0:     if (getTypeInfoLinkage(AT->getElementType()) ==
     403                 :         llvm::GlobalValue::InternalLinkage)
     404                0:       return llvm::GlobalValue::InternalLinkage;
     405                 :   }
     406                 : 
     407                 :   }
     408                 : 
     409                0:   return llvm::GlobalValue::WeakODRLinkage;
     410                 : }
     411                 : 
     412                 : // CanUseSingleInheritance - Return whether the given record decl has a "single, 
     413                 : // public, non-virtual base at offset zero (i.e. the derived class is dynamic 
     414                 : // iff the base is)", according to Itanium C++ ABI, 2.95p6b.
     415              286: static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
     416                 :   // Check the number of bases.
                      144: branch 1 taken
                      142: branch 2 taken
     417              286:   if (RD->getNumBases() != 1)
     418              144:     return false;
     419                 :   
     420                 :   // Get the base.
     421              142:   CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
     422                 :   
     423                 :   // Check that the base is not virtual.
                       70: branch 1 taken
                       72: branch 2 taken
     424              142:   if (Base->isVirtual())
     425               70:     return false;
     426                 :   
     427                 :   // Check that the base is public.
                        4: branch 1 taken
                       68: branch 2 taken
     428               72:   if (Base->getAccessSpecifier() != AS_public)
     429                4:     return false;
     430                 :   
     431                 :   // Check that the class is dynamic iff the base is.
     432                 :   const CXXRecordDecl *BaseDecl = 
     433               68:     cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
                       60: branch 1 taken
                        8: branch 2 taken
                        2: branch 5 taken
                       58: branch 6 taken
                        2: branch 7 taken
                       66: branch 8 taken
     434               68:   if (!BaseDecl->isEmpty() && 
     435                 :       BaseDecl->isDynamicClass() != RD->isDynamicClass())
     436                2:     return false;
     437                 :   
     438               66:   return true;
     439                 : }
     440                 : 
     441              292: void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
     442                 :   const char *VtableName;
     443                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
                        0: branch 3 not taken
                        3: branch 4 taken
                        1: branch 5 taken
                      268: branch 6 taken
                       11: branch 7 taken
                        8: branch 8 taken
     444              292:   switch (Ty->getTypeClass()) {
     445                0:   default: assert(0 && "Unhandled type!");
     446                 : 
     447                 :   // GCC treats vector types as fundamental types.
     448                 :   case Type::Vector:
     449                 :   case Type::ExtVector:
     450                 :     // abi::__fundamental_type_info.
     451                1:     VtableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
     452                1:     break;
     453                 : 
     454                 :   case Type::ConstantArray:
     455                 :   case Type::IncompleteArray:
     456                 :     // abi::__array_type_info.
     457                0:     VtableName = "_ZTVN10__cxxabiv117__array_type_infoE";
     458                0:     break;
     459                 : 
     460                 :   case Type::FunctionNoProto:
     461                 :   case Type::FunctionProto:
     462                 :     // abi::__function_type_info.
     463                3:     VtableName = "_ZTVN10__cxxabiv120__function_type_infoE";
     464                3:     break;
     465                 : 
     466                 :   case Type::Enum:
     467                 :     // abi::__enum_type_info.
     468                1:     VtableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
     469                1:     break;
     470                 :       
     471                 :   case Type::Record: {
     472                 :     const CXXRecordDecl *RD = 
     473              268:       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
     474                 :     
                      266: branch 1 taken
                        2: branch 2 taken
                      123: branch 4 taken
                      143: branch 5 taken
                      125: branch 6 taken
                      143: branch 7 taken
     475              268:     if (!RD->hasDefinition() || !RD->getNumBases()) {
     476                 :       // abi::__class_type_info.
     477              125:       VtableName = "_ZTVN10__cxxabiv117__class_type_infoE";
                       33: branch 1 taken
                      110: branch 2 taken
     478              143:     } else if (CanUseSingleInheritance(RD)) {
     479                 :       // abi::__si_class_type_info.
     480               33:       VtableName = "_ZTVN10__cxxabiv120__si_class_type_infoE";
     481                 :     } else {
     482                 :       // abi::__vmi_class_type_info.
     483              110:       VtableName = "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
     484                 :     }
     485                 :     
     486              268:     break;
     487                 :   }
     488                 : 
     489                 :   case Type::Pointer:
     490                 :     // abi::__pointer_type_info.
     491               11:     VtableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
     492               11:     break;
     493                 : 
     494                 :   case Type::MemberPointer:
     495                 :     // abi::__pointer_to_member_type_info.
     496                8:     VtableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
     497                 :     break;
     498                 :   }
     499                 : 
     500                 :   llvm::Constant *Vtable = 
     501              292:     CGM.getModule().getOrInsertGlobal(VtableName, Int8PtrTy);
     502                 :     
     503                 :   const llvm::Type *PtrDiffTy = 
     504              292:     CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
     505                 : 
     506                 :   // The vtable address point is 2.
     507              292:   llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
     508              292:   Vtable = llvm::ConstantExpr::getInBoundsGetElementPtr(Vtable, &Two, 1);
     509              292:   Vtable = llvm::ConstantExpr::getBitCast(Vtable, Int8PtrTy);
     510                 : 
     511              292:   Fields.push_back(Vtable);
     512              292: }
     513                 : 
     514              671: llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty) {
     515                 :   // We want to operate on the canonical type.
     516              671:   Ty = CGM.getContext().getCanonicalType(Ty);
     517                 : 
     518                 :   // Check if we've already emitted an RTTI descriptor for this type.
     519              671:   llvm::SmallString<256> OutName;
     520              671:   CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
     521              671:   llvm::StringRef Name = OutName.str();
     522                 :   
     523              671:   llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
                      318: branch 0 taken
                      353: branch 1 taken
                      296: branch 3 taken
                       22: branch 4 taken
                      296: branch 5 taken
                      375: branch 6 taken
     524              671:   if (OldGV && !OldGV->isDeclaration())
     525              296:     return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy);
     526                 :   
     527                 :   // Check if there is already an external RTTI descriptor for this type.
                       83: branch 1 taken
                      292: branch 2 taken
     528              375:   if (ShouldUseExternalRTTIDescriptor(Ty))
     529               83:     return GetAddrOfExternalRTTIDescriptor(Ty);
     530                 : 
     531              292:   llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(Ty);
     532                 : 
     533                 :   // Add the vtable pointer.
     534              292:   BuildVtablePointer(cast<Type>(Ty));
     535                 :   
     536                 :   // And the name.
     537              292:   Fields.push_back(BuildName(Ty, DecideHidden(Ty), Linkage));
     538                 :   
                        0: branch 2 not taken
                        0: branch 3 not taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        3: branch 6 taken
                        1: branch 7 taken
                      268: branch 8 taken
                       11: branch 9 taken
                        8: branch 10 taken
     539              292:   switch (Ty->getTypeClass()) {
     540                0:   default: assert(false && "Unhandled type class!");
     541                 :   case Type::Builtin:
     542                0:     assert(false && "Builtin type info must be in the standard library!");
     543                 :     break;
     544                 : 
     545                 :   // GCC treats vector types as fundamental types.
     546                 :   case Type::Vector:
     547                 :   case Type::ExtVector:
     548                 :     // Itanium C++ ABI 2.9.5p4:
     549                 :     // abi::__fundamental_type_info adds no data members to std::type_info.
     550                1:     break;
     551                 :       
     552                 :   case Type::ConstantArray:
     553                 :   case Type::IncompleteArray:
     554                 :     // Itanium C++ ABI 2.9.5p5:
     555                 :     // abi::__array_type_info adds no data members to std::type_info.
     556                0:     break;
     557                 : 
     558                 :   case Type::FunctionNoProto:
     559                 :   case Type::FunctionProto:
     560                 :     // Itanium C++ ABI 2.9.5p5:
     561                 :     // abi::__function_type_info adds no data members to std::type_info.
     562                3:     break;
     563                 : 
     564                 :   case Type::Enum:
     565                 :     // Itanium C++ ABI 2.9.5p5:
     566                 :     // abi::__enum_type_info adds no data members to std::type_info.
     567                1:     break;
     568                 : 
     569                 :   case Type::Record: {
     570                 :     const CXXRecordDecl *RD = 
     571              268:       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
                      266: branch 1 taken
                        2: branch 2 taken
                      123: branch 4 taken
                      143: branch 5 taken
                      125: branch 6 taken
                      143: branch 7 taken
     572              268:     if (!RD->hasDefinition() || !RD->getNumBases()) {
     573                 :       // We don't need to emit any fields.
     574              125:       break;
     575                 :     }
     576                 :     
                       33: branch 1 taken
                      110: branch 2 taken
     577              143:     if (CanUseSingleInheritance(RD))
     578               33:       BuildSIClassTypeInfo(RD);
     579                 :     else 
     580              110:       BuildVMIClassTypeInfo(RD);
     581                 : 
     582              143:     break;
     583                 :   }
     584                 :       
     585                 :   case Type::Pointer:
     586               11:     BuildPointerTypeInfo(cast<PointerType>(Ty));
     587               11:     break;
     588                 :   
     589                 :   case Type::MemberPointer:
     590                8:     BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
     591                 :     break;
     592                 :   }
     593                 : 
     594                 :   llvm::Constant *Init = 
     595                 :     llvm::ConstantStruct::get(VMContext, &Fields[0], Fields.size(), 
     596              292:                               /*Packed=*/false);
     597                 : 
     598                 :   llvm::GlobalVariable *GV = 
     599                 :     new llvm::GlobalVariable(CGM.getModule(), Init->getType(), 
     600              292:                              /*Constant=*/true, Linkage, Init, Name);
     601                 :   
     602                 :   // If there's already an old global variable, replace it with the new one.
                        0: branch 0 not taken
                      292: branch 1 taken
     603              292:   if (OldGV) {
     604                0:     GV->takeName(OldGV);
     605                 :     llvm::Constant *NewPtr = 
     606                0:       llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
     607                0:     OldGV->replaceAllUsesWith(NewPtr);
     608                0:     OldGV->eraseFromParent();
     609                 :   }
     610                 :     
     611              292:   return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
     612                 : }
     613                 : 
     614                 : /// ComputeQualifierFlags - Compute the pointer type info flags from the
     615                 : /// given qualifier.
     616               19: static unsigned ComputeQualifierFlags(Qualifiers Quals) {
     617               19:   unsigned Flags = 0;
     618                 : 
                        0: branch 1 not taken
                       19: branch 2 taken
     619               19:   if (Quals.hasConst())
     620                0:     Flags |= RTTIBuilder::PTI_Const;
                        1: branch 1 taken
                       18: branch 2 taken
     621               19:   if (Quals.hasVolatile())
     622                1:     Flags |= RTTIBuilder::PTI_Volatile;
                        0: branch 1 not taken
                       19: branch 2 taken
     623               19:   if (Quals.hasRestrict())
     624                0:     Flags |= RTTIBuilder::PTI_Restrict;
     625                 : 
     626               19:   return Flags;
     627                 : }
     628                 : 
     629                 : /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
     630                 : /// inheritance, according to the Itanium C++ ABI, 2.95p6b.
     631               33: void RTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
     632                 :   // Itanium C++ ABI 2.9.5p6b:
     633                 :   // It adds to abi::__class_type_info a single member pointing to the 
     634                 :   // type_info structure for the base type,
     635                 :   llvm::Constant *BaseTypeInfo = 
     636               33:     RTTIBuilder(CGM).BuildTypeInfo(RD->bases_begin()->getType());
     637               33:   Fields.push_back(BaseTypeInfo);
     638               33: }
     639                 : 
     640                 : /// SeenBases - Contains virtual and non-virtual bases seen when traversing
     641                 : /// a class hierarchy.
     642              220: struct SeenBases {
     643                 :   llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
     644                 :   llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
     645                 : };
     646                 : 
     647                 : /// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
     648                 : /// abi::__vmi_class_type_info.
     649                 : ///
     650                 : static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, 
     651              398:                                              SeenBases &Bases) {
     652                 :   
     653              398:   unsigned Flags = 0;
     654                 :   
     655                 :   const CXXRecordDecl *BaseDecl = 
     656              398:     cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
     657                 :   
                      229: branch 1 taken
                      169: branch 2 taken
     658              398:   if (Base->isVirtual()) {
                       16: branch 1 taken
                      213: branch 2 taken
     659              229:     if (Bases.VirtualBases.count(BaseDecl)) {
     660                 :       // If this virtual base has been seen before, then the class is diamond
     661                 :       // shaped.
     662               16:       Flags |= RTTIBuilder::VMI_DiamondShaped;
     663                 :     } else {
                        5: branch 1 taken
                      208: branch 2 taken
     664              213:       if (Bases.NonVirtualBases.count(BaseDecl))
     665                5:         Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
     666                 : 
     667                 :       // Mark the virtual base as seen.
     668              213:       Bases.VirtualBases.insert(BaseDecl);
     669                 :     }
     670                 :   } else {
                       21: branch 1 taken
                      148: branch 2 taken
     671              169:     if (Bases.NonVirtualBases.count(BaseDecl)) {
     672                 :       // If this non-virtual base has been seen before, then the class has non-
     673                 :       // diamond shaped repeated inheritance.
     674               21:       Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
     675                 :     } else {
                        0: branch 1 not taken
                      148: branch 2 taken
     676              148:       if (Bases.VirtualBases.count(BaseDecl))
     677                0:         Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
     678                 :         
     679                 :       // Mark the non-virtual base as seen.
     680              148:       Bases.NonVirtualBases.insert(BaseDecl);
     681                 :     }
     682                 :   }
     683                 : 
     684                 :   // Walk all bases.
                      199: branch 1 taken
                      398: branch 2 taken
     685              995:   for (CXXRecordDecl::base_class_const_iterator I = BaseDecl->bases_begin(),
     686              398:        E = BaseDecl->bases_end(); I != E; ++I) 
     687              199:     Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);
     688                 :   
     689              398:   return Flags;
     690                 : }
     691                 : 
     692              110: static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
     693              110:   unsigned Flags = 0;
     694              110:   SeenBases Bases;
     695                 :   
     696                 :   // Walk all bases.
                      199: branch 1 taken
                      110: branch 2 taken
     697              419:   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
     698              110:        E = RD->bases_end(); I != E; ++I) 
     699              199:     Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);
     700                 :   
     701              110:   return Flags;
     702                 : }
     703                 : 
     704                 : /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
     705                 : /// classes with bases that do not satisfy the abi::__si_class_type_info 
     706                 : /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
     707              110: void RTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
     708                 :   const llvm::Type *UnsignedIntLTy = 
     709              110:     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
     710                 :   
     711                 :   // Itanium C++ ABI 2.9.5p6c:
     712                 :   //   __flags is a word with flags describing details about the class 
     713                 :   //   structure, which may be referenced by using the __flags_masks 
     714                 :   //   enumeration. These flags refer to both direct and indirect bases. 
     715              110:   unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
     716              110:   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
     717                 : 
     718                 :   // Itanium C++ ABI 2.9.5p6c:
     719                 :   //   __base_count is a word with the number of direct proper base class 
     720                 :   //   descriptions that follow.
     721              110:   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
     722                 :   
                        0: branch 1 not taken
                      110: branch 2 taken
     723              110:   if (!RD->getNumBases())
     724                0:     return;
     725                 :   
     726                 :   const llvm::Type *LongLTy = 
     727              110:     CGM.getTypes().ConvertType(CGM.getContext().LongTy);
     728                 : 
     729                 :   // Now add the base class descriptions.
     730                 :   
     731                 :   // Itanium C++ ABI 2.9.5p6c:
     732                 :   //   __base_info[] is an array of base class descriptions -- one for every 
     733                 :   //   direct proper base. Each description is of the type:
     734                 :   //
     735                 :   //   struct abi::__base_class_type_info {
     736                 : 	//   public:
     737                 :   //     const __class_type_info *__base_type;
     738                 :   //     long __offset_flags;
     739                 :   //
     740                 :   //     enum __offset_flags_masks {
     741                 :   //       __virtual_mask = 0x1,
     742                 :   //       __public_mask = 0x2,
     743                 :   //       __offset_shift = 8
     744                 :   //     };
     745                 :   //   };
                      199: branch 1 taken
                      110: branch 2 taken
     746              419:   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
     747              110:        E = RD->bases_end(); I != E; ++I) {
     748              199:     const CXXBaseSpecifier *Base = I;
     749                 : 
     750                 :     // The __base_type member points to the RTTI for the base type.
     751              199:     Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(Base->getType()));
     752                 : 
     753                 :     const CXXRecordDecl *BaseDecl = 
     754              199:       cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
     755                 : 
     756              199:     int64_t OffsetFlags = 0;
     757                 :     
     758                 :     // All but the lower 8 bits of __offset_flags are a signed offset. 
     759                 :     // For a non-virtual base, this is the offset in the object of the base
     760                 :     // subobject. For a virtual base, this is the offset in the virtual table of
     761                 :     // the virtual base offset for the virtual base referenced (negative).
                      102: branch 1 taken
                       97: branch 2 taken
     762              199:     if (Base->isVirtual())
     763              102:       OffsetFlags = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, BaseDecl);
     764                 :     else {
     765               97:       const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
     766               97:       OffsetFlags = Layout.getBaseClassOffset(BaseDecl) / 8;
     767                 :     };
     768                 :     
     769              199:     OffsetFlags <<= 8;
     770                 :     
     771                 :     // The low-order byte of __offset_flags contains flags, as given by the 
     772                 :     // masks from the enumeration __offset_flags_masks.
                      102: branch 1 taken
                       97: branch 2 taken
     773              199:     if (Base->isVirtual())
     774              102:       OffsetFlags |= BCTI_Virtual;
                      167: branch 1 taken
                       32: branch 2 taken
     775              199:     if (Base->getAccessSpecifier() == AS_public)
     776              167:       OffsetFlags |= BCTI_Public;
     777                 : 
     778              199:     Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
     779                 :   }
     780                 : }
     781                 : 
     782                 : /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
     783                 : /// used for pointer types.
     784               11: void RTTIBuilder::BuildPointerTypeInfo(const PointerType *Ty) {
     785               11:   QualType PointeeTy = Ty->getPointeeType();
     786                 :   
     787                 :   // Itanium C++ ABI 2.9.5p7:
     788                 :   //   __flags is a flag word describing the cv-qualification and other 
     789                 :   //   attributes of the type pointed to
     790               11:   unsigned Flags = ComputeQualifierFlags(PointeeTy.getQualifiers());
     791                 : 
     792                 :   // Itanium C++ ABI 2.9.5p7:
     793                 :   //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
     794                 :   //   incomplete class type, the incomplete target type flag is set. 
                        6: branch 1 taken
                        5: branch 2 taken
     795               11:   if (ContainsIncompleteClassType(PointeeTy))
     796                6:     Flags |= PTI_Incomplete;
     797                 : 
     798                 :   const llvm::Type *UnsignedIntLTy = 
     799               11:     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
     800               11:   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
     801                 :   
     802                 :   // Itanium C++ ABI 2.9.5p7:
     803                 :   //  __pointee is a pointer to the std::type_info derivation for the 
     804                 :   //  unqualified type being pointed to.
     805                 :   llvm::Constant *PointeeTypeInfo = 
     806               11:     RTTIBuilder(CGM).BuildTypeInfo(PointeeTy.getUnqualifiedType());
     807               11:   Fields.push_back(PointeeTypeInfo);
     808               11: }
     809                 : 
     810                 : /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
     811                 : /// struct, used for member pointer types.
     812                8: void RTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
     813                8:   QualType PointeeTy = Ty->getPointeeType();
     814                 :   
     815                 :   // Itanium C++ ABI 2.9.5p7:
     816                 :   //   __flags is a flag word describing the cv-qualification and other 
     817                 :   //   attributes of the type pointed to.
     818                8:   unsigned Flags = ComputeQualifierFlags(PointeeTy.getQualifiers());
     819                 : 
     820                8:   const RecordType *ClassType = cast<RecordType>(Ty->getClass());
     821                 : 
     822                 :   // Itanium C++ ABI 2.9.5p7:
     823                 :   //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
     824                 :   //   incomplete class type, the incomplete target type flag is set. 
                        6: branch 1 taken
                        2: branch 2 taken
     825                8:   if (ContainsIncompleteClassType(PointeeTy))
     826                6:     Flags |= PTI_Incomplete;
     827                 : 
                        5: branch 1 taken
                        3: branch 2 taken
     828                8:   if (IsIncompleteClassType(ClassType))
     829                5:     Flags |= PTI_ContainingClassIncomplete;
     830                 :   
     831                 :   const llvm::Type *UnsignedIntLTy = 
     832                8:     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
     833                8:   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
     834                 :   
     835                 :   // Itanium C++ ABI 2.9.5p7:
     836                 :   //   __pointee is a pointer to the std::type_info derivation for the 
     837                 :   //   unqualified type being pointed to.
     838                 :   llvm::Constant *PointeeTypeInfo = 
     839                8:     RTTIBuilder(CGM).BuildTypeInfo(PointeeTy.getUnqualifiedType());
     840                8:   Fields.push_back(PointeeTypeInfo);
     841                 : 
     842                 :   // Itanium C++ ABI 2.9.5p9:
     843                 :   //   __context is a pointer to an abi::__class_type_info corresponding to the
     844                 :   //   class type containing the member pointed to 
     845                 :   //   (e.g., the "A" in "int A::*").
     846                8:   Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));
     847                8: }
     848                 : 
     849              412: llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty) {
                        0: branch 2 not taken
                      412: branch 3 taken
     850              412:   if (!getContext().getLangOptions().RTTI) {
     851                0:     const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
     852                0:     return llvm::Constant::getNullValue(Int8PtrTy);
     853                 :   }
     854                 :   
     855              412:   return RTTIBuilder(*this).BuildTypeInfo(Ty);
     856                 : }

Generated: 2010-02-10 01:31 by zcov