blob: d8c718c7c60b409467920521d19d75d4c4889fb0 [file] [log] [blame]
Mike Stumpde050572009-12-02 18:57:08 +00001//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
Anders Carlsson656e4c12009-10-10 20:49:04 +00002//
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
Mike Stumpae9b2be2009-11-17 23:45:57 +000014#include "clang/AST/Type.h"
Mike Stumpcbcd4e52009-11-14 23:32:21 +000015#include "clang/AST/RecordLayout.h"
Mike Stump61c38012009-11-17 21:44:24 +000016#include "CodeGenModule.h"
Anders Carlsson656e4c12009-10-10 20:49:04 +000017using namespace clang;
18using namespace CodeGen;
19
Mike Stump92f2fe22009-12-02 19:07:44 +000020namespace {
Mike Stumpde050572009-12-02 18:57:08 +000021class RTTIBuilder {
Mike Stump2b1bf312009-11-14 14:25:18 +000022 CodeGenModule &CGM; // Per-module state.
23 llvm::LLVMContext &VMContext;
24 const llvm::Type *Int8PtrTy;
Mike Stumpa8285a82009-11-15 03:28:10 +000025 llvm::SmallSet<const CXXRecordDecl *, 16> SeenVBase;
26 llvm::SmallSet<const CXXRecordDecl *, 32> SeenBase;
Anders Carlsson44636d12009-12-11 16:41:51 +000027
Anders Carlsson23440772009-12-17 05:06:03 +000028 std::vector<llvm::Constant *> Info;
29
Anders Carlssond6baec82009-12-11 01:27:37 +000030 // Type info flags.
31 enum {
32 /// TI_Const - Type has const qualifier.
33 TI_Const = 0x1,
34
35 /// TI_Volatile - Type has volatile qualifier.
36 TI_Volatile = 0x2,
37
38 /// TI_Restrict - Type has restrict qualifier.
39 TI_Restrict = 0x4,
40
41 /// TI_Incomplete - Type is incomplete.
42 TI_Incomplete = 0x8,
43
44 /// TI_ContainingClassIncomplete - Containing class is incomplete.
45 /// (in pointer to member).
46 TI_ContainingClassIncomplete = 0x10
47 };
48
Mike Stump2b1bf312009-11-14 14:25:18 +000049public:
Mike Stumpde050572009-12-02 18:57:08 +000050 RTTIBuilder(CodeGenModule &cgm)
Mike Stump2b1bf312009-11-14 14:25:18 +000051 : CGM(cgm), VMContext(cgm.getModule().getContext()),
52 Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
53
Mike Stumpcbcd4e52009-11-14 23:32:21 +000054 /// BuildVtableRef - Build a reference to a vtable.
55 llvm::Constant *BuildVtableRef(const char *Name) {
56 // Build a descriptor for Name
Mike Stumpc7a05bd2009-11-14 15:55:18 +000057 llvm::Constant *GV = CGM.getModule().getGlobalVariable(Name);
58 if (GV)
59 GV = llvm::ConstantExpr::getBitCast(GV,
60 llvm::PointerType::get(Int8PtrTy, 0));
61 else {
62 llvm::GlobalVariable::LinkageTypes linktype;
63 linktype = llvm::GlobalValue::ExternalLinkage;
64 GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy,
65 true, linktype, 0, Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +000066 }
Mike Stumpc7a05bd2009-11-14 15:55:18 +000067 llvm::Constant *C;
68 C = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 2);
69 C = llvm::ConstantExpr::getInBoundsGetElementPtr(GV, &C, 1);
70 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
71 }
Mike Stumpcbcd4e52009-11-14 23:32:21 +000072
Anders Carlsson31b7f522009-12-11 02:46:30 +000073 // FIXME: This should be removed, and clients should pass in the linkage
74 // directly instead.
75 static inline llvm::GlobalVariable::LinkageTypes
76 GetLinkageFromExternFlag(bool Extern) {
77 if (Extern)
78 return llvm::GlobalValue::WeakODRLinkage;
79
80 return llvm::GlobalValue::InternalLinkage;
81 }
82
83 // FIXME: This should be removed, and clients should pass in the linkage
84 // directly instead.
Mike Stump58588942009-11-19 01:08:19 +000085 llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
Anders Carlsson31b7f522009-12-11 02:46:30 +000086 return BuildName(Ty, Hidden, GetLinkageFromExternFlag(Extern));
87 }
88
89 llvm::Constant *BuildName(QualType Ty, bool Hidden,
90 llvm::GlobalVariable::LinkageTypes Linkage) {
Mike Stump2b1bf312009-11-14 14:25:18 +000091 llvm::SmallString<256> OutName;
Mike Stumpde050572009-12-02 18:57:08 +000092 CGM.getMangleContext().mangleCXXRTTIName(Ty, OutName);
Daniel Dunbar94fd26d2009-11-21 09:06:22 +000093 llvm::StringRef Name = OutName.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +000094
Anders Carlsson31b7f522009-12-11 02:46:30 +000095 llvm::GlobalVariable *OGV = CGM.getModule().getGlobalVariable(Name);
96 if (OGV && !OGV->isDeclaration())
97 return llvm::ConstantExpr::getBitCast(OGV, Int8PtrTy);
Mike Stump58588942009-11-19 01:08:19 +000098
Anders Carlsson31b7f522009-12-11 02:46:30 +000099 llvm::Constant *C = llvm::ConstantArray::get(VMContext, Name.substr(4));
Mike Stump2b1bf312009-11-14 14:25:18 +0000100
Anders Carlsson31b7f522009-12-11 02:46:30 +0000101 llvm::GlobalVariable *GV =
102 new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, Linkage,
103 C, Name);
Mike Stump58588942009-11-19 01:08:19 +0000104 if (OGV) {
105 GV->takeName(OGV);
106 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
107 OGV->getType());
108 OGV->replaceAllUsesWith(NewPtr);
109 OGV->eraseFromParent();
110 }
Mike Stump582b0372009-11-18 03:46:51 +0000111 if (Hidden)
112 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
113 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump2b1bf312009-11-14 14:25:18 +0000114 };
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000115
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000116 /// - BuildFlags - Build a psABI __flags value for __vmi_class_type_info.
117 llvm::Constant *BuildFlags(int f) {
118 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
119 }
120
121 /// BuildBaseCount - Build a psABI __base_count value for
122 /// __vmi_class_type_info.
123 llvm::Constant *BuildBaseCount(unsigned c) {
124 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), c);
125 }
126
Mike Stumpea2c0b52009-11-17 02:16:21 +0000127 llvm::Constant *BuildTypeRef(QualType Ty) {
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000128 llvm::Constant *C;
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000129
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000130 llvm::SmallString<256> OutName;
Mike Stumpde050572009-12-02 18:57:08 +0000131 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000132 llvm::StringRef Name = OutName.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000133
Mike Stump58588942009-11-19 01:08:19 +0000134 C = CGM.getModule().getGlobalVariable(Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000135 if (C)
136 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
137
138 llvm::GlobalVariable::LinkageTypes linktype;
139 linktype = llvm::GlobalValue::ExternalLinkage;;
140
141 C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
Mike Stump58588942009-11-19 01:08:19 +0000142 0, Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000143 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
144 }
145
Mike Stumpea2c0b52009-11-17 02:16:21 +0000146 llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
147 return BuildTypeRef(CGM.getContext().getTagDeclType(RD));
148 }
149
Mike Stumpa8285a82009-11-15 03:28:10 +0000150 /// CalculateFlags - Calculate the flags for the __vmi_class_type_info
151 /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond
152 /// shaped class.
153 int CalculateFlags(const CXXRecordDecl*RD) {
154 int flags = 0;
155 if (SeenBase.count(RD))
156 flags |= 1;
157 else
158 SeenBase.insert(RD);
159 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
160 e = RD->bases_end(); i != e; ++i) {
161 const CXXRecordDecl *Base =
162 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
163 if (i->isVirtual()) {
164 if (SeenVBase.count(Base))
165 flags |= 2;
166 else
167 SeenVBase.insert(Base);
168 }
169 flags |= CalculateFlags(Base);
170 }
171 return flags;
172 }
173
174 bool SimpleInheritance(const CXXRecordDecl *RD) {
175 if (RD->getNumBases() != 1)
176 return false;
177 CXXRecordDecl::base_class_const_iterator i = RD->bases_begin();
178 if (i->isVirtual())
179 return false;
180 if (i->getAccessSpecifier() != AS_public)
181 return false;
182
183 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
184 const CXXRecordDecl *Base =
185 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
186 if (Layout.getBaseClassOffset(Base) != 0)
187 return false;
188 return true;
189 }
190
Anders Carlsson5ba7d212009-12-13 16:38:01 +0000191 llvm::Constant *finish(llvm::Constant *const *Values, unsigned NumValues,
Mike Stump64989f02009-11-17 23:11:22 +0000192 llvm::GlobalVariable *GV,
Anders Carlsson31b7f522009-12-11 02:46:30 +0000193 llvm::StringRef Name, bool Hidden,
194 llvm::GlobalVariable::LinkageTypes Linkage) {
195 llvm::Constant *C =
Anders Carlsson5ba7d212009-12-13 16:38:01 +0000196 llvm::ConstantStruct::get(VMContext, Values, NumValues, /*Packed=*/false);
Mike Stump64989f02009-11-17 23:11:22 +0000197
Mike Stump58588942009-11-19 01:08:19 +0000198 llvm::GlobalVariable *OGV = GV;
Anders Carlsson31b7f522009-12-11 02:46:30 +0000199 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, Linkage,
Mike Stump58588942009-11-19 01:08:19 +0000200 C, Name);
201 if (OGV) {
Mike Stump64989f02009-11-17 23:11:22 +0000202 GV->takeName(OGV);
203 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
204 OGV->getType());
205 OGV->replaceAllUsesWith(NewPtr);
206 OGV->eraseFromParent();
207 }
Mike Stump582b0372009-11-18 03:46:51 +0000208 if (Hidden)
Mike Stump88a4a622009-11-18 03:21:29 +0000209 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
Mike Stump64989f02009-11-17 23:11:22 +0000210 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
211 }
212
213
Anders Carlsson31b7f522009-12-11 02:46:30 +0000214 llvm::Constant *
215 Buildclass_type_info(const CXXRecordDecl *RD,
216 llvm::GlobalVariable::LinkageTypes Linkage) {
Anders Carlsson23440772009-12-17 05:06:03 +0000217 assert(Info.empty() && "Info vector must be empty!");
Anders Carlsson44636d12009-12-11 16:41:51 +0000218
Mike Stump64989f02009-11-17 23:11:22 +0000219 llvm::Constant *C;
220
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000221 llvm::SmallString<256> OutName;
Mike Stumpde050572009-12-02 18:57:08 +0000222 CGM.getMangleContext().mangleCXXRTTI(CGM.getContext().getTagDeclType(RD),
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000223 OutName);
224 llvm::StringRef Name = OutName.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000225
226 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000227 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000228 if (GV && !GV->isDeclaration())
229 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
230
Anders Carlsson31b7f522009-12-11 02:46:30 +0000231 // If we're in an anonymous namespace, then we always want internal linkage.
Eli Friedman470fb732009-12-11 20:48:18 +0000232 if (RD->isInAnonymousNamespace() || !RD->hasLinkage())
Anders Carlsson31b7f522009-12-11 02:46:30 +0000233 Linkage = llvm::GlobalVariable::InternalLinkage;
234
Mike Stump582b0372009-11-18 03:46:51 +0000235 bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
236
Mike Stumpa8285a82009-11-15 03:28:10 +0000237 bool simple = false;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000238 if (RD->getNumBases() == 0)
239 C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
Mike Stumpa8285a82009-11-15 03:28:10 +0000240 else if (SimpleInheritance(RD)) {
241 simple = true;
242 C = BuildVtableRef("_ZTVN10__cxxabiv120__si_class_type_infoE");
243 } else
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000244 C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
Anders Carlsson23440772009-12-17 05:06:03 +0000245 Info.push_back(C);
246 Info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
Anders Carlsson31b7f522009-12-11 02:46:30 +0000247 Linkage));
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000248
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000249 // If we have no bases, there are no more fields.
250 if (RD->getNumBases()) {
Mike Stumpa8285a82009-11-15 03:28:10 +0000251 if (!simple) {
Anders Carlsson23440772009-12-17 05:06:03 +0000252 Info.push_back(BuildFlags(CalculateFlags(RD)));
253 Info.push_back(BuildBaseCount(RD->getNumBases()));
Mike Stumpa8285a82009-11-15 03:28:10 +0000254 }
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000255
256 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
257 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
258 e = RD->bases_end(); i != e; ++i) {
259 const CXXRecordDecl *Base =
260 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Anders Carlsson23440772009-12-17 05:06:03 +0000261 Info.push_back(CGM.GetAddrOfRTTI(Base));
Mike Stumpa8285a82009-11-15 03:28:10 +0000262 if (simple)
263 break;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000264 int64_t offset;
265 if (!i->isVirtual())
Mike Stumpa8285a82009-11-15 03:28:10 +0000266 offset = Layout.getBaseClassOffset(Base)/8;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000267 else
268 offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
269 offset <<= 8;
270 // Now set the flags.
271 offset += i->isVirtual() ? 1 : 0;;
272 offset += i->getAccessSpecifier() == AS_public ? 2 : 0;
273 const llvm::Type *LongTy =
274 CGM.getTypes().ConvertType(CGM.getContext().LongTy);
275 C = llvm::ConstantInt::get(LongTy, offset);
Anders Carlsson23440772009-12-17 05:06:03 +0000276 Info.push_back(C);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000277 }
278 }
279
Anders Carlsson23440772009-12-17 05:06:03 +0000280 return finish(&Info[0], Info.size(), GV, Name, Hidden, Linkage);
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000281 }
Mike Stumpea2c0b52009-11-17 02:16:21 +0000282
Mike Stump61c38012009-11-17 21:44:24 +0000283 /// - BuildFlags - Build a __flags value for __pbase_type_info.
Anders Carlssond6baec82009-12-11 01:27:37 +0000284 llvm::Constant *BuildInt(unsigned n) {
285 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), n);
Mike Stump61c38012009-11-17 21:44:24 +0000286 }
287
Mike Stump58588942009-11-19 01:08:19 +0000288 bool DecideExtern(QualType Ty) {
289 // For this type, see if all components are never in an anonymous namespace.
290 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
291 return (DecideExtern(MPT->getPointeeType())
292 && DecideExtern(QualType(MPT->getClass(), 0)));
293 if (const PointerType *PT = Ty->getAs<PointerType>())
294 return DecideExtern(PT->getPointeeType());
295 if (const RecordType *RT = Ty->getAs<RecordType>())
296 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
Eli Friedman470fb732009-12-11 20:48:18 +0000297 return !RD->isInAnonymousNamespace() && RD->hasLinkage();
Mike Stump58588942009-11-19 01:08:19 +0000298 return true;
299 }
300
301 bool DecideHidden(QualType Ty) {
302 // For this type, see if all components are never hidden.
303 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
304 return (DecideHidden(MPT->getPointeeType())
305 && DecideHidden(QualType(MPT->getClass(), 0)));
306 if (const PointerType *PT = Ty->getAs<PointerType>())
307 return DecideHidden(PT->getPointeeType());
308 if (const RecordType *RT = Ty->getAs<RecordType>())
309 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
310 return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
311 return false;
312 }
313
Mike Stump61c38012009-11-17 21:44:24 +0000314 llvm::Constant *BuildPointerType(QualType Ty) {
Anders Carlsson23440772009-12-17 05:06:03 +0000315 assert(Info.empty() && "Info vector must be empty!");
Anders Carlsson44636d12009-12-11 16:41:51 +0000316
Mike Stump61c38012009-11-17 21:44:24 +0000317 llvm::Constant *C;
318
319 llvm::SmallString<256> OutName;
Mike Stumpde050572009-12-02 18:57:08 +0000320 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000321 llvm::StringRef Name = OutName.str();
Mike Stump61c38012009-11-17 21:44:24 +0000322
323 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000324 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump61c38012009-11-17 21:44:24 +0000325 if (GV && !GV->isDeclaration())
326 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
327
Mike Stump58588942009-11-19 01:08:19 +0000328 bool Extern = DecideExtern(Ty);
329 bool Hidden = DecideHidden(Ty);
Mike Stump582b0372009-11-18 03:46:51 +0000330
Anders Carlssond6baec82009-12-11 01:27:37 +0000331 const MemberPointerType *PtrMemTy = dyn_cast<MemberPointerType>(Ty);
332 QualType PointeeTy;
333
334 if (PtrMemTy)
335 PointeeTy = PtrMemTy->getPointeeType();
336 else
337 PointeeTy = Ty->getPointeeType();
Mike Stump61c38012009-11-17 21:44:24 +0000338
Anders Carlssond6baec82009-12-11 01:27:37 +0000339 if (PtrMemTy)
Mike Stump61c38012009-11-17 21:44:24 +0000340 C = BuildVtableRef("_ZTVN10__cxxabiv129__pointer_to_member_type_infoE");
341 else
342 C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
Anders Carlssond6baec82009-12-11 01:27:37 +0000343
Anders Carlsson23440772009-12-17 05:06:03 +0000344 Info.push_back(C);
345 Info.push_back(BuildName(Ty, Hidden, Extern));
Anders Carlssond6baec82009-12-11 01:27:37 +0000346 Qualifiers Q = PointeeTy.getQualifiers();
347
348 PointeeTy =
349 CGM.getContext().getCanonicalType(PointeeTy).getUnqualifiedType();
350
351 unsigned Flags = 0;
352 if (Q.hasConst())
353 Flags |= TI_Const;
354 if (Q.hasVolatile())
355 Flags |= TI_Volatile;
356 if (Q.hasRestrict())
357 Flags |= TI_Restrict;
358
359 if (Ty->isIncompleteType())
360 Flags |= TI_Incomplete;
361
362 if (PtrMemTy && PtrMemTy->getClass()->isIncompleteType())
363 Flags |= TI_ContainingClassIncomplete;
364
Anders Carlsson23440772009-12-17 05:06:03 +0000365 Info.push_back(BuildInt(Flags));
366 Info.push_back(BuildInt(0));
367 Info.push_back(RTTIBuilder(CGM).BuildType(PointeeTy));
Mike Stump61c38012009-11-17 21:44:24 +0000368
Anders Carlssond6baec82009-12-11 01:27:37 +0000369 if (PtrMemTy)
Anders Carlsson23440772009-12-17 05:06:03 +0000370 Info.push_back(RTTIBuilder(CGM).BuildType(
371 QualType(PtrMemTy->getClass(), 0)));
Mike Stump265df622009-11-17 23:51:10 +0000372
Mike Stump58588942009-11-19 01:08:19 +0000373 // We always generate these as hidden, only the name isn't hidden.
Anders Carlsson23440772009-12-17 05:06:03 +0000374 return finish(&Info[0], Info.size(), GV, Name, /*Hidden=*/true,
Anders Carlsson31b7f522009-12-11 02:46:30 +0000375 GetLinkageFromExternFlag(Extern));
Mike Stump64989f02009-11-17 23:11:22 +0000376 }
Mike Stump61c38012009-11-17 21:44:24 +0000377
Mike Stumpae9b2be2009-11-17 23:45:57 +0000378 llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
Mike Stump64989f02009-11-17 23:11:22 +0000379 llvm::SmallString<256> OutName;
Mike Stumpde050572009-12-02 18:57:08 +0000380 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000381 llvm::StringRef Name = OutName.str();
Mike Stump64989f02009-11-17 23:11:22 +0000382
383 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000384 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump64989f02009-11-17 23:11:22 +0000385 if (GV && !GV->isDeclaration())
386 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
387
Mike Stump58588942009-11-19 01:08:19 +0000388 bool Extern = DecideExtern(Ty);
389 bool Hidden = DecideHidden(Ty);
Mike Stump582b0372009-11-18 03:46:51 +0000390
Anders Carlsson3bf190e2009-12-13 23:47:29 +0000391 llvm::Constant *Info[] = {
392 BuildVtableRef(vtbl), BuildName(Ty, Hidden, Extern)
393 };
394
Mike Stump58588942009-11-19 01:08:19 +0000395 // We always generate these as hidden, only the name isn't hidden.
Anders Carlsson3bf190e2009-12-13 23:47:29 +0000396 return finish(&Info[0], llvm::array_lengthof(Info), GV, Name,
397 /*Hidden=*/true, GetLinkageFromExternFlag(Extern));
Mike Stump61c38012009-11-17 21:44:24 +0000398 }
399
Anders Carlsson31b7f522009-12-11 02:46:30 +0000400 /// BuildType - Builds the type info for the given type.
Mike Stumpea2c0b52009-11-17 02:16:21 +0000401 llvm::Constant *BuildType(QualType Ty) {
402 const clang::Type &Type
403 = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
Mike Stump7e1365a2009-11-20 00:31:50 +0000404
405 if (const RecordType *RT = Ty.getTypePtr()->getAs<RecordType>())
406 if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()))
Anders Carlsson31b7f522009-12-11 02:46:30 +0000407 return BuildClassTypeInfo(RD);
Mike Stump7e1365a2009-11-20 00:31:50 +0000408
Mike Stumpea2c0b52009-11-17 02:16:21 +0000409 switch (Type.getTypeClass()) {
410 default: {
Mike Stumpea2c0b52009-11-17 02:16:21 +0000411 assert(0 && "typeid expression");
Mike Stumpea2c0b52009-11-17 02:16:21 +0000412 return llvm::Constant::getNullValue(Int8PtrTy);
413 }
414
415 case Type::Builtin: {
416 // We expect all type_info objects for builtin types to be in the library.
417 return BuildTypeRef(Ty);
418 }
Mike Stump21f5d5d2009-11-17 02:57:13 +0000419
420 case Type::Pointer: {
421 QualType PTy = Ty->getPointeeType();
422 Qualifiers Q = PTy.getQualifiers();
423 Q.removeConst();
424 // T* and const T* for all builtin types T are expected in the library.
425 if (isa<BuiltinType>(PTy) && Q.empty())
426 return BuildTypeRef(Ty);
427
Mike Stump61c38012009-11-17 21:44:24 +0000428 return BuildPointerType(Ty);
Mike Stump21f5d5d2009-11-17 02:57:13 +0000429 }
Mike Stump5fae8562009-11-17 22:33:00 +0000430 case Type::MemberPointer:
431 return BuildPointerType(Ty);
Mike Stump64989f02009-11-17 23:11:22 +0000432 case Type::FunctionProto:
Mike Stumpae9b2be2009-11-17 23:45:57 +0000433 case Type::FunctionNoProto:
434 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv120__function_type_infoE");
435 case Type::ConstantArray:
436 case Type::IncompleteArray:
437 case Type::VariableArray:
438 case Type::Vector:
439 case Type::ExtVector:
440 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
441 case Type::Enum:
442 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv116__enum_type_infoE");
Mike Stumpea2c0b52009-11-17 02:16:21 +0000443 }
444 }
Anders Carlsson31b7f522009-12-11 02:46:30 +0000445
446 /// BuildClassTypeInfo - Builds the class type info (or a reference to it)
447 /// for the given record decl.
448 llvm::Constant *BuildClassTypeInfo(const CXXRecordDecl *RD) {
449 const CXXMethodDecl *KeyFunction = 0;
450
451 if (RD->isDynamicClass())
452 KeyFunction = CGM.getContext().getKeyFunction(RD);
453
454 if (KeyFunction) {
455 // If the key function is defined in this translation unit, then the RTTI
456 // related constants should also be emitted here, with external linkage.
457 if (KeyFunction->getBody())
458 return Buildclass_type_info(RD, llvm::GlobalValue::ExternalLinkage);
459
460 // Otherwise, we just want a reference to the type info.
461 return Buildclass_type_infoRef(RD);
462 }
463
464 // If there is no key function (or if the record doesn't have any virtual
465 // member functions or virtual bases), emit the type info with weak_odr
466 // linkage.
467 return Buildclass_type_info(RD, llvm::GlobalValue::WeakODRLinkage);
468 }
Mike Stump2b1bf312009-11-14 14:25:18 +0000469};
Mike Stump92f2fe22009-12-02 19:07:44 +0000470}
Mike Stump2b1bf312009-11-14 14:25:18 +0000471
Anders Carlsson31b7f522009-12-11 02:46:30 +0000472llvm::Constant *CodeGenModule::GetAddrOfRTTI(const CXXRecordDecl *RD) {
473 if (!getContext().getLangOptions().RTTI) {
474 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
475 return llvm::Constant::getNullValue(Int8PtrTy);
476 }
477
478 return RTTIBuilder(*this).BuildClassTypeInfo(RD);
479}
480
481llvm::Constant *CodeGenModule::GetAddrOfRTTI(QualType Ty) {
482 if (!getContext().getLangOptions().RTTI) {
483 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
484 return llvm::Constant::getNullValue(Int8PtrTy);
485 }
486
487 return RTTIBuilder(*this).BuildType(Ty);
488}