 |
|
 |
|
| 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 |
| |
 |
|
 |
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