clang API Documentation
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 }