clang API Documentation

CGRTTI.cpp

Go to the documentation of this file.
00001 //===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This contains code dealing with C++ code generation of RTTI descriptors.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/AST/Type.h"
00015 #include "clang/AST/RecordLayout.h"
00016 #include "CodeGenModule.h"
00017 using namespace clang;
00018 using namespace CodeGen;
00019 
00020 namespace {
00021 class RTTIBuilder {
00022   CodeGenModule &CGM;  // Per-module state.
00023   llvm::LLVMContext &VMContext;
00024   
00025   const llvm::Type *Int8PtrTy;
00026   
00027   /// Fields - The fields of the RTTI descriptor currently being built.
00028   llvm::SmallVector<llvm::Constant *, 16> Fields;
00029 
00030   /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI 
00031   /// descriptor of the given type.
00032   llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
00033   
00034   /// BuildVTablePointer - Build the vtable pointer for the given type.
00035   void BuildVTablePointer(const Type *Ty);
00036   
00037   /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
00038   /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
00039   void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
00040   
00041   /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
00042   /// classes with bases that do not satisfy the abi::__si_class_type_info 
00043   /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
00044   void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
00045   
00046   /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
00047   /// for pointer types.
00048   void BuildPointerTypeInfo(const PointerType *Ty);
00049   
00050   /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
00051   /// struct, used for member pointer types.
00052   void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
00053   
00054 public:
00055   RTTIBuilder(CodeGenModule &cgm)
00056     : CGM(cgm), VMContext(cgm.getModule().getContext()),
00057       Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
00058 
00059   llvm::Constant *BuildName(QualType Ty, bool Hidden, 
00060                             llvm::GlobalVariable::LinkageTypes Linkage) {
00061     llvm::SmallString<256> OutName;
00062     CGM.getMangleContext().mangleCXXRTTIName(Ty, OutName);
00063     llvm::StringRef Name = OutName.str();
00064 
00065     llvm::GlobalVariable *OGV = CGM.getModule().getNamedGlobal(Name);
00066     if (OGV && !OGV->isDeclaration())
00067       return llvm::ConstantExpr::getBitCast(OGV, Int8PtrTy);
00068 
00069     llvm::Constant *C = llvm::ConstantArray::get(VMContext, Name.substr(4));
00070 
00071     llvm::GlobalVariable *GV = 
00072       new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, Linkage,
00073                                C, Name);
00074     if (OGV) {
00075       GV->takeName(OGV);
00076       llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
00077                                                               OGV->getType());
00078       OGV->replaceAllUsesWith(NewPtr);
00079       OGV->eraseFromParent();
00080     }
00081     if (Hidden)
00082       GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
00083     return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
00084   }
00085 
00086   // FIXME: unify with DecideExtern
00087   bool DecideHidden(QualType Ty) {
00088     // For this type, see if all components are never hidden.
00089     if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
00090       return (DecideHidden(MPT->getPointeeType())
00091               && DecideHidden(QualType(MPT->getClass(), 0)));
00092     if (const PointerType *PT = Ty->getAs<PointerType>())
00093       return DecideHidden(PT->getPointeeType());
00094     if (const FunctionType *FT = Ty->getAs<FunctionType>()) {
00095       if (DecideHidden(FT->getResultType()) == false)
00096         return false;
00097       if (const FunctionProtoType *FPT = Ty->getAs<FunctionProtoType>()) {
00098         for (unsigned i = 0; i <FPT->getNumArgs(); ++i)
00099           if (DecideHidden(FPT->getArgType(i)) == false)
00100             return false;
00101         for (unsigned i = 0; i <FPT->getNumExceptions(); ++i)
00102           if (DecideHidden(FPT->getExceptionType(i)) == false)
00103             return false;
00104         return true;
00105       }
00106     }
00107     if (const RecordType *RT = Ty->getAs<RecordType>())
00108       if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
00109         return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
00110     return false;
00111   }
00112   
00113   // Pointer type info flags.
00114   enum {
00115     /// PTI_Const - Type has const qualifier.
00116     PTI_Const = 0x1,
00117     
00118     /// PTI_Volatile - Type has volatile qualifier.
00119     PTI_Volatile = 0x2,
00120     
00121     /// PTI_Restrict - Type has restrict qualifier.
00122     PTI_Restrict = 0x4,
00123     
00124     /// PTI_Incomplete - Type is incomplete.
00125     PTI_Incomplete = 0x8,
00126     
00127     /// PTI_ContainingClassIncomplete - Containing class is incomplete.
00128     /// (in pointer to member).
00129     PTI_ContainingClassIncomplete = 0x10
00130   };
00131   
00132   // VMI type info flags.
00133   enum {
00134     /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
00135     VMI_NonDiamondRepeat = 0x1,
00136     
00137     /// VMI_DiamondShaped - Class is diamond shaped.
00138     VMI_DiamondShaped = 0x2
00139   };
00140   
00141   // Base class type info flags.
00142   enum {
00143     /// BCTI_Virtual - Base class is virtual.
00144     BCTI_Virtual = 0x1,
00145     
00146     /// BCTI_Public - Base class is public.
00147     BCTI_Public = 0x2
00148   };
00149   
00150   /// BuildTypeInfo - Build the RTTI type info struct for the given type.
00151   ///
00152   /// \param Force - true to force the creation of this RTTI value
00153   /// \param ForEH - true if this is for exception handling
00154   llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
00155 };
00156 }
00157 
00158 llvm::Constant *RTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
00159   // Mangle the RTTI name.
00160   llvm::SmallString<256> OutName;
00161   CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
00162   llvm::StringRef Name = OutName.str();
00163 
00164   // Look for an existing global.
00165   llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
00166   
00167   if (!GV) {
00168     // Create a new global variable.
00169     GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, /*Constant=*/true,
00170                                   llvm::GlobalValue::ExternalLinkage, 0, Name);
00171   }
00172   
00173   return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
00174 }
00175 
00176 /// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
00177 /// info for that type is defined in the standard library.
00178 static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
00179   // Itanium C++ ABI 2.9.2:
00180   //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
00181   //   the run-time support library. Specifically, the run-time support
00182   //   library should contain type_info objects for the types X, X* and 
00183   //   X const*, for every X in: void, bool, wchar_t, char, unsigned char, 
00184   //   signed char, short, unsigned short, int, unsigned int, long, 
00185   //   unsigned long, long long, unsigned long long, float, double, long double, 
00186   //   char16_t, char32_t, and the IEEE 754r decimal and half-precision 
00187   //   floating point types.
00188   switch (Ty->getKind()) {
00189     case BuiltinType::Void:
00190     case BuiltinType::Bool:
00191     case BuiltinType::WChar:
00192     case BuiltinType::Char_U:
00193     case BuiltinType::Char_S:
00194     case BuiltinType::UChar:
00195     case BuiltinType::SChar:
00196     case BuiltinType::Short:
00197     case BuiltinType::UShort:
00198     case BuiltinType::Int:
00199     case BuiltinType::UInt:
00200     case BuiltinType::Long:
00201     case BuiltinType::ULong:
00202     case BuiltinType::LongLong:
00203     case BuiltinType::ULongLong:
00204     case BuiltinType::Float:
00205     case BuiltinType::Double:
00206     case BuiltinType::LongDouble:
00207     case BuiltinType::Char16:
00208     case BuiltinType::Char32:
00209     case BuiltinType::Int128:
00210     case BuiltinType::UInt128:
00211       return true;
00212       
00213     case BuiltinType::Overload:
00214     case BuiltinType::Dependent:
00215     case BuiltinType::UndeducedAuto:
00216       assert(false && "Should not see this type here!");
00217       
00218     case BuiltinType::NullPtr:
00219       assert(false && "FIXME: nullptr_t is not handled!");
00220 
00221     case BuiltinType::ObjCId:
00222     case BuiltinType::ObjCClass:
00223     case BuiltinType::ObjCSel:
00224       assert(false && "FIXME: Objective-C types are unsupported!");
00225   }
00226   
00227   // Silent gcc.
00228   return false;
00229 }
00230 
00231 static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
00232   QualType PointeeTy = PointerTy->getPointeeType();
00233   const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
00234   if (!BuiltinTy)
00235     return false;
00236     
00237   // Check the qualifiers.
00238   Qualifiers Quals = PointeeTy.getQualifiers();
00239   Quals.removeConst();
00240     
00241   if (!Quals.empty())
00242     return false;
00243     
00244   return TypeInfoIsInStandardLibrary(BuiltinTy);
00245 }
00246 
00247 /// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
00248 /// the given type exists somewhere else, and that we should not emit the type
00249 /// information in this translation unit.
00250 static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context,
00251                                             QualType Ty) {
00252   // Type info for builtin types is defined in the standard library.
00253   if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
00254     return TypeInfoIsInStandardLibrary(BuiltinTy);
00255   
00256   // Type info for some pointer types to builtin types is defined in the
00257   // standard library.
00258   if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
00259     return TypeInfoIsInStandardLibrary(PointerTy);
00260 
00261   // If RTTI is disabled, don't consider key functions.
00262   if (!Context.getLangOptions().RTTI) return false;
00263 
00264   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
00265     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
00266     if (!RD->hasDefinition())
00267       return false;
00268 
00269     if (!RD->isDynamicClass())
00270       return false;
00271 
00272     // Get the key function.
00273     const CXXMethodDecl *KeyFunction = RD->getASTContext().getKeyFunction(RD);
00274     if (KeyFunction && !KeyFunction->getBody()) {
00275       // The class has a key function, but it is not defined in this translation
00276       // unit, so we should use the external descriptor for it.
00277       return true;
00278     }
00279   }
00280   
00281   return false;
00282 }
00283 
00284 /// IsIncompleteClassType - Returns whether the given record type is incomplete.
00285 static bool IsIncompleteClassType(const RecordType *RecordTy) {
00286   return !RecordTy->getDecl()->isDefinition();
00287 }  
00288 
00289 /// ContainsIncompleteClassType - Returns whether the given type contains an
00290 /// incomplete class type. This is true if
00291 ///
00292 ///   * The given type is an incomplete class type.
00293 ///   * The given type is a pointer type whose pointee type contains an 
00294 ///     incomplete class type.
00295 ///   * The given type is a member pointer type whose class is an incomplete
00296 ///     class type.
00297 ///   * The given type is a member pointer type whoise pointee type contains an
00298 ///     incomplete class type.
00299 /// is an indirect or direct pointer to an incomplete class type.
00300 static bool ContainsIncompleteClassType(QualType Ty) {
00301   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
00302     if (IsIncompleteClassType(RecordTy))
00303       return true;
00304   }
00305   
00306   if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
00307     return ContainsIncompleteClassType(PointerTy->getPointeeType());
00308   
00309   if (const MemberPointerType *MemberPointerTy = 
00310       dyn_cast<MemberPointerType>(Ty)) {
00311     // Check if the class type is incomplete.
00312     const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
00313     if (IsIncompleteClassType(ClassType))
00314       return true;
00315     
00316     return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
00317   }
00318   
00319   return false;
00320 }
00321 
00322 /// getTypeInfoLinkage - Return the linkage that the type info and type info
00323 /// name constants should have for the given type.
00324 static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
00325   // Itanium C++ ABI 2.9.5p7:
00326   //   In addition, it and all of the intermediate abi::__pointer_type_info 
00327   //   structs in the chain down to the abi::__class_type_info for the
00328   //   incomplete class type must be prevented from resolving to the 
00329   //   corresponding type_info structs for the complete class type, possibly
00330   //   by making them local static objects. Finally, a dummy class RTTI is
00331   //   generated for the incomplete type that will not resolve to the final 
00332   //   complete class RTTI (because the latter need not exist), possibly by 
00333   //   making it a local static object.
00334   if (ContainsIncompleteClassType(Ty))
00335     return llvm::GlobalValue::InternalLinkage;
00336   
00337   switch (Ty->getLinkage()) {
00338   case NoLinkage:
00339   case InternalLinkage:
00340   case UniqueExternalLinkage:
00341     return llvm::GlobalValue::InternalLinkage;
00342 
00343   case ExternalLinkage:
00344     if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
00345       const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
00346       if (RD->isDynamicClass())
00347         return CodeGenModule::getVTableLinkage(RD);
00348     }
00349 
00350     return llvm::GlobalValue::WeakODRLinkage;
00351   }
00352 
00353   return llvm::GlobalValue::WeakODRLinkage;
00354 }
00355 
00356 // CanUseSingleInheritance - Return whether the given record decl has a "single, 
00357 // public, non-virtual base at offset zero (i.e. the derived class is dynamic 
00358 // iff the base is)", according to Itanium C++ ABI, 2.95p6b.
00359 static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
00360   // Check the number of bases.
00361   if (RD->getNumBases() != 1)
00362     return false;
00363   
00364   // Get the base.
00365   CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
00366   
00367   // Check that the base is not virtual.
00368   if (Base->isVirtual())
00369     return false;
00370   
00371   // Check that the base is public.
00372   if (Base->getAccessSpecifier() != AS_public)
00373     return false;
00374   
00375   // Check that the class is dynamic iff the base is.
00376   const CXXRecordDecl *BaseDecl = 
00377     cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
00378   if (!BaseDecl->isEmpty() && 
00379       BaseDecl->isDynamicClass() != RD->isDynamicClass())
00380     return false;
00381   
00382   return true;
00383 }
00384 
00385 void RTTIBuilder::BuildVTablePointer(const Type *Ty) {
00386   const char *VTableName;
00387 
00388   switch (Ty->getTypeClass()) {
00389   default: assert(0 && "Unhandled type!");
00390 
00391   case Type::Builtin:
00392   // GCC treats vector types as fundamental types.
00393   case Type::Vector:
00394   case Type::ExtVector:
00395     // abi::__fundamental_type_info.
00396     VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
00397     break;
00398 
00399   case Type::ConstantArray:
00400   case Type::IncompleteArray:
00401     // abi::__array_type_info.
00402     VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
00403     break;
00404 
00405   case Type::FunctionNoProto:
00406   case Type::FunctionProto:
00407     // abi::__function_type_info.
00408     VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
00409     break;
00410 
00411   case Type::Enum:
00412     // abi::__enum_type_info.
00413     VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
00414     break;
00415       
00416   case Type::Record: {
00417     const CXXRecordDecl *RD = 
00418       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
00419     
00420     if (!RD->hasDefinition() || !RD->getNumBases()) {
00421       // abi::__class_type_info.
00422       VTableName = "_ZTVN10__cxxabiv117__class_type_infoE";
00423     } else if (CanUseSingleInheritance(RD)) {
00424       // abi::__si_class_type_info.
00425       VTableName = "_ZTVN10__cxxabiv120__si_class_type_infoE";
00426     } else {
00427       // abi::__vmi_class_type_info.
00428       VTableName = "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
00429     }
00430     
00431     break;
00432   }
00433 
00434   case Type::Pointer:
00435     // abi::__pointer_type_info.
00436     VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
00437     break;
00438 
00439   case Type::MemberPointer:
00440     // abi::__pointer_to_member_type_info.
00441     VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
00442     break;
00443   }
00444 
00445   llvm::Constant *VTable = 
00446     CGM.getModule().getOrInsertGlobal(VTableName, Int8PtrTy);
00447     
00448   const llvm::Type *PtrDiffTy = 
00449     CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
00450 
00451   // The vtable address point is 2.
00452   llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
00453   VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, &Two, 1);
00454   VTable = llvm::ConstantExpr::getBitCast(VTable, Int8PtrTy);
00455 
00456   Fields.push_back(VTable);
00457 }
00458 
00459 llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty,
00460                                            bool Force) {
00461   // We want to operate on the canonical type.
00462   Ty = CGM.getContext().getCanonicalType(Ty);
00463 
00464   // Check if we've already emitted an RTTI descriptor for this type.
00465   llvm::SmallString<256> OutName;
00466   CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
00467   llvm::StringRef Name = OutName.str();
00468   
00469   llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
00470   if (OldGV && !OldGV->isDeclaration())
00471     return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy);
00472   
00473   // Check if there is already an external RTTI descriptor for this type.
00474   if (!Force && ShouldUseExternalRTTIDescriptor(CGM.getContext(), Ty))
00475     return GetAddrOfExternalRTTIDescriptor(Ty);
00476 
00477   llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(Ty);
00478 
00479   // Add the vtable pointer.
00480   BuildVTablePointer(cast<Type>(Ty));
00481   
00482   // And the name.
00483   Fields.push_back(BuildName(Ty, DecideHidden(Ty), Linkage));
00484   
00485   switch (Ty->getTypeClass()) {
00486   default: assert(false && "Unhandled type class!");
00487 
00488   // GCC treats vector types as fundamental types.
00489   case Type::Builtin:
00490   case Type::Vector:
00491   case Type::ExtVector:
00492     // Itanium C++ ABI 2.9.5p4:
00493     // abi::__fundamental_type_info adds no data members to std::type_info.
00494     break;
00495       
00496   case Type::ConstantArray:
00497   case Type::IncompleteArray:
00498     // Itanium C++ ABI 2.9.5p5:
00499     // abi::__array_type_info adds no data members to std::type_info.
00500     break;
00501 
00502   case Type::FunctionNoProto:
00503   case Type::FunctionProto:
00504     // Itanium C++ ABI 2.9.5p5:
00505     // abi::__function_type_info adds no data members to std::type_info.
00506     break;
00507 
00508   case Type::Enum:
00509     // Itanium C++ ABI 2.9.5p5:
00510     // abi::__enum_type_info adds no data members to std::type_info.
00511     break;
00512 
00513   case Type::Record: {
00514     const CXXRecordDecl *RD = 
00515       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
00516     if (!RD->hasDefinition() || !RD->getNumBases()) {
00517       // We don't need to emit any fields.
00518       break;
00519     }
00520     
00521     if (CanUseSingleInheritance(RD))
00522       BuildSIClassTypeInfo(RD);
00523     else 
00524       BuildVMIClassTypeInfo(RD);
00525 
00526     break;
00527   }
00528       
00529   case Type::Pointer:
00530     BuildPointerTypeInfo(cast<PointerType>(Ty));
00531     break;
00532   
00533   case Type::MemberPointer:
00534     BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
00535     break;
00536   }
00537 
00538   llvm::Constant *Init = 
00539     llvm::ConstantStruct::get(VMContext, &Fields[0], Fields.size(), 
00540                               /*Packed=*/false);
00541 
00542   llvm::GlobalVariable *GV = 
00543     new llvm::GlobalVariable(CGM.getModule(), Init->getType(), 
00544                              /*Constant=*/true, Linkage, Init, Name);
00545   
00546   // If there's already an old global variable, replace it with the new one.
00547   if (OldGV) {
00548     GV->takeName(OldGV);
00549     llvm::Constant *NewPtr = 
00550       llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
00551     OldGV->replaceAllUsesWith(NewPtr);
00552     OldGV->eraseFromParent();
00553   }
00554     
00555   return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
00556 }
00557 
00558 /// ComputeQualifierFlags - Compute the pointer type info flags from the
00559 /// given qualifier.
00560 static unsigned ComputeQualifierFlags(Qualifiers Quals) {
00561   unsigned Flags = 0;
00562 
00563   if (Quals.hasConst())
00564     Flags |= RTTIBuilder::PTI_Const;
00565   if (Quals.hasVolatile())
00566     Flags |= RTTIBuilder::PTI_Volatile;
00567   if (Quals.hasRestrict())
00568     Flags |= RTTIBuilder::PTI_Restrict;
00569 
00570   return Flags;
00571 }
00572 
00573 /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
00574 /// inheritance, according to the Itanium C++ ABI, 2.95p6b.
00575 void RTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
00576   // Itanium C++ ABI 2.9.5p6b:
00577   // It adds to abi::__class_type_info a single member pointing to the 
00578   // type_info structure for the base type,
00579   llvm::Constant *BaseTypeInfo = 
00580     RTTIBuilder(CGM).BuildTypeInfo(RD->bases_begin()->getType());
00581   Fields.push_back(BaseTypeInfo);
00582 }
00583 
00584 /// SeenBases - Contains virtual and non-virtual bases seen when traversing
00585 /// a class hierarchy.
00586 struct SeenBases {
00587   llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
00588   llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
00589 };
00590 
00591 /// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
00592 /// abi::__vmi_class_type_info.
00593 ///
00594 static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, 
00595                                              SeenBases &Bases) {
00596   
00597   unsigned Flags = 0;
00598   
00599   const CXXRecordDecl *BaseDecl = 
00600     cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
00601   
00602   if (Base->isVirtual()) {
00603     if (Bases.VirtualBases.count(BaseDecl)) {
00604       // If this virtual base has been seen before, then the class is diamond
00605       // shaped.
00606       Flags |= RTTIBuilder::VMI_DiamondShaped;
00607     } else {
00608       if (Bases.NonVirtualBases.count(BaseDecl))
00609         Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
00610 
00611       // Mark the virtual base as seen.
00612       Bases.VirtualBases.insert(BaseDecl);
00613     }
00614   } else {
00615     if (Bases.NonVirtualBases.count(BaseDecl)) {
00616       // If this non-virtual base has been seen before, then the class has non-
00617       // diamond shaped repeated inheritance.
00618       Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
00619     } else {
00620       if (Bases.VirtualBases.count(BaseDecl))
00621         Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
00622         
00623       // Mark the non-virtual base as seen.
00624       Bases.NonVirtualBases.insert(BaseDecl);
00625     }
00626   }
00627 
00628   // Walk all bases.
00629   for (CXXRecordDecl::base_class_const_iterator I = BaseDecl->bases_begin(),
00630        E = BaseDecl->bases_end(); I != E; ++I) 
00631     Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);
00632   
00633   return Flags;
00634 }
00635 
00636 static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
00637   unsigned Flags = 0;
00638   SeenBases Bases;
00639   
00640   // Walk all bases.
00641   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
00642        E = RD->bases_end(); I != E; ++I) 
00643     Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);
00644   
00645   return Flags;
00646 }
00647 
00648 /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
00649 /// classes with bases that do not satisfy the abi::__si_class_type_info 
00650 /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
00651 void RTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
00652   const llvm::Type *UnsignedIntLTy = 
00653     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
00654   
00655   // Itanium C++ ABI 2.9.5p6c:
00656   //   __flags is a word with flags describing details about the class 
00657   //   structure, which may be referenced by using the __flags_masks 
00658   //   enumeration. These flags refer to both direct and indirect bases. 
00659   unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
00660   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
00661 
00662   // Itanium C++ ABI 2.9.5p6c:
00663   //   __base_count is a word with the number of direct proper base class 
00664   //   descriptions that follow.
00665   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
00666   
00667   if (!RD->getNumBases())
00668     return;
00669   
00670   const llvm::Type *LongLTy = 
00671     CGM.getTypes().ConvertType(CGM.getContext().LongTy);
00672 
00673   // Now add the base class descriptions.
00674   
00675   // Itanium C++ ABI 2.9.5p6c:
00676   //   __base_info[] is an array of base class descriptions -- one for every 
00677   //   direct proper base. Each description is of the type:
00678   //
00679   //   struct abi::__base_class_type_info {
00680   //   public:
00681   //     const __class_type_info *__base_type;
00682   //     long __offset_flags;
00683   //
00684   //     enum __offset_flags_masks {
00685   //       __virtual_mask = 0x1,
00686   //       __public_mask = 0x2,
00687   //       __offset_shift = 8
00688   //     };
00689   //   };
00690   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
00691        E = RD->bases_end(); I != E; ++I) {
00692     const CXXBaseSpecifier *Base = I;
00693 
00694     // The __base_type member points to the RTTI for the base type.
00695     Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(Base->getType()));
00696 
00697     const CXXRecordDecl *BaseDecl = 
00698       cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
00699 
00700     int64_t OffsetFlags = 0;
00701     
00702     // All but the lower 8 bits of __offset_flags are a signed offset. 
00703     // For a non-virtual base, this is the offset in the object of the base
00704     // subobject. For a virtual base, this is the offset in the virtual table of
00705     // the virtual base offset for the virtual base referenced (negative).
00706     if (Base->isVirtual())
00707       OffsetFlags = CGM.getVTables().getVirtualBaseOffsetOffset(RD, BaseDecl);
00708     else {
00709       const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
00710       OffsetFlags = Layout.getBaseClassOffset(BaseDecl) / 8;
00711     };
00712     
00713     OffsetFlags <<= 8;
00714     
00715     // The low-order byte of __offset_flags contains flags, as given by the 
00716     // masks from the enumeration __offset_flags_masks.
00717     if (Base->isVirtual())
00718       OffsetFlags |= BCTI_Virtual;
00719     if (Base->getAccessSpecifier() == AS_public)
00720       OffsetFlags |= BCTI_Public;
00721 
00722     Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
00723   }
00724 }
00725 
00726 /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
00727 /// used for pointer types.
00728 void RTTIBuilder::BuildPointerTypeInfo(const PointerType *Ty) {
00729   QualType PointeeTy = Ty->getPointeeType();
00730   
00731   // Itanium C++ ABI 2.9.5p7:
00732   //   __flags is a flag word describing the cv-qualification and other 
00733   //   attributes of the type pointed to
00734   unsigned Flags = ComputeQualifierFlags(PointeeTy.getQualifiers());
00735 
00736   // Itanium C++ ABI 2.9.5p7:
00737   //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
00738   //   incomplete class type, the incomplete target type flag is set. 
00739   if (ContainsIncompleteClassType(PointeeTy))
00740     Flags |= PTI_Incomplete;
00741 
00742   const llvm::Type *UnsignedIntLTy = 
00743     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
00744   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
00745   
00746   // Itanium C++ ABI 2.9.5p7:
00747   //  __pointee is a pointer to the std::type_info derivation for the 
00748   //  unqualified type being pointed to.
00749   llvm::Constant *PointeeTypeInfo = 
00750     RTTIBuilder(CGM).BuildTypeInfo(PointeeTy.getUnqualifiedType());
00751   Fields.push_back(PointeeTypeInfo);
00752 }
00753 
00754 /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
00755 /// struct, used for member pointer types.
00756 void RTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
00757   QualType PointeeTy = Ty->getPointeeType();
00758   
00759   // Itanium C++ ABI 2.9.5p7:
00760   //   __flags is a flag word describing the cv-qualification and other 
00761   //   attributes of the type pointed to.
00762   unsigned Flags = ComputeQualifierFlags(PointeeTy.getQualifiers());
00763 
00764   const RecordType *ClassType = cast<RecordType>(Ty->getClass());
00765 
00766   // Itanium C++ ABI 2.9.5p7:
00767   //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
00768   //   incomplete class type, the incomplete target type flag is set. 
00769   if (ContainsIncompleteClassType(PointeeTy))
00770     Flags |= PTI_Incomplete;
00771 
00772   if (IsIncompleteClassType(ClassType))
00773     Flags |= PTI_ContainingClassIncomplete;
00774   
00775   const llvm::Type *UnsignedIntLTy = 
00776     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
00777   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
00778   
00779   // Itanium C++ ABI 2.9.5p7:
00780   //   __pointee is a pointer to the std::type_info derivation for the 
00781   //   unqualified type being pointed to.
00782   llvm::Constant *PointeeTypeInfo = 
00783     RTTIBuilder(CGM).BuildTypeInfo(PointeeTy.getUnqualifiedType());
00784   Fields.push_back(PointeeTypeInfo);
00785 
00786   // Itanium C++ ABI 2.9.5p9:
00787   //   __context is a pointer to an abi::__class_type_info corresponding to the
00788   //   class type containing the member pointed to 
00789   //   (e.g., the "A" in "int A::*").
00790   Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));
00791 }
00792 
00793 llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
00794                                                        bool ForEH) {
00795   // Return a bogus pointer if RTTI is disabled, unless it's for EH.
00796   // FIXME: should we even be calling this method if RTTI is disabled
00797   // and it's not for EH?
00798   if (!ForEH && !getContext().getLangOptions().RTTI) {
00799     const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
00800     return llvm::Constant::getNullValue(Int8PtrTy);
00801   }
00802 
00803   return RTTIBuilder(*this).BuildTypeInfo(Ty);
00804 }
00805 
00806 void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) {
00807   QualType PointerType = Context.getPointerType(Type);
00808   QualType PointerTypeConst = Context.getPointerType(Type.withConst());
00809   RTTIBuilder(*this).BuildTypeInfo(Type, true);
00810   RTTIBuilder(*this).BuildTypeInfo(PointerType, true);
00811   RTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);
00812 }
00813 
00814 void CodeGenModule::EmitFundamentalRTTIDescriptors() {
00815   QualType FundamentalTypes[] = { Context.VoidTy, Context.Char32Ty,
00816                                   Context.Char16Ty, Context.UnsignedLongLongTy,
00817                                   Context.LongLongTy, Context.WCharTy,
00818                                   Context.UnsignedShortTy, Context.ShortTy,
00819                                   Context.UnsignedLongTy, Context.LongTy,
00820                                   Context.UnsignedIntTy, Context.IntTy,
00821                                   Context.UnsignedCharTy, Context.FloatTy,
00822                                   Context.LongDoubleTy, Context.DoubleTy,
00823                                   Context.CharTy, Context.BoolTy,
00824                                   Context.SignedCharTy };
00825   for (unsigned i = 0; i < sizeof(FundamentalTypes)/sizeof(QualType); ++i)
00826     EmitFundamentalRTTIDescriptor(FundamentalTypes[i]);
00827 }