blob: a574703935cf390ec2dd814da7a059a25ac6ff50 [file] [log] [blame]
Mike Stumpc01c2b82009-12-02 18:57:08 +00001//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
Anders Carlsson6ce51fd2009-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 Stump103a0842009-11-17 23:45:57 +000014#include "clang/AST/Type.h"
Mike Stumpf5b28692009-11-14 23:32:21 +000015#include "clang/AST/RecordLayout.h"
Mike Stumpdb72c892009-11-17 21:44:24 +000016#include "CodeGenModule.h"
Anders Carlsson6ce51fd2009-10-10 20:49:04 +000017using namespace clang;
18using namespace CodeGen;
19
Mike Stumpae1b85d2009-12-02 19:07:44 +000020namespace {
Mike Stumpc01c2b82009-12-02 18:57:08 +000021class RTTIBuilder {
Mike Stump14718422009-11-14 14:25:18 +000022 CodeGenModule &CGM; // Per-module state.
23 llvm::LLVMContext &VMContext;
24 const llvm::Type *Int8PtrTy;
Mike Stump4c808df2009-11-15 03:28:10 +000025 llvm::SmallSet<const CXXRecordDecl *, 16> SeenVBase;
26 llvm::SmallSet<const CXXRecordDecl *, 32> SeenBase;
Anders Carlsson1d6ad502009-12-11 16:41:51 +000027
28
Anders Carlssonc9882012009-12-11 01:27:37 +000029 // Type info flags.
30 enum {
31 /// TI_Const - Type has const qualifier.
32 TI_Const = 0x1,
33
34 /// TI_Volatile - Type has volatile qualifier.
35 TI_Volatile = 0x2,
36
37 /// TI_Restrict - Type has restrict qualifier.
38 TI_Restrict = 0x4,
39
40 /// TI_Incomplete - Type is incomplete.
41 TI_Incomplete = 0x8,
42
43 /// TI_ContainingClassIncomplete - Containing class is incomplete.
44 /// (in pointer to member).
45 TI_ContainingClassIncomplete = 0x10
46 };
47
Mike Stump14718422009-11-14 14:25:18 +000048public:
Mike Stumpc01c2b82009-12-02 18:57:08 +000049 RTTIBuilder(CodeGenModule &cgm)
Mike Stump14718422009-11-14 14:25:18 +000050 : CGM(cgm), VMContext(cgm.getModule().getContext()),
51 Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
52
Mike Stumpf5b28692009-11-14 23:32:21 +000053 /// BuildVtableRef - Build a reference to a vtable.
54 llvm::Constant *BuildVtableRef(const char *Name) {
55 // Build a descriptor for Name
Mike Stump1acec6a2009-11-14 15:55:18 +000056 llvm::Constant *GV = CGM.getModule().getGlobalVariable(Name);
57 if (GV)
58 GV = llvm::ConstantExpr::getBitCast(GV,
59 llvm::PointerType::get(Int8PtrTy, 0));
60 else {
61 llvm::GlobalVariable::LinkageTypes linktype;
62 linktype = llvm::GlobalValue::ExternalLinkage;
63 GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy,
64 true, linktype, 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +000065 }
Mike Stump1acec6a2009-11-14 15:55:18 +000066 llvm::Constant *C;
67 C = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 2);
68 C = llvm::ConstantExpr::getInBoundsGetElementPtr(GV, &C, 1);
69 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
70 }
Mike Stumpf5b28692009-11-14 23:32:21 +000071
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +000072 // FIXME: This should be removed, and clients should pass in the linkage
73 // directly instead.
74 static inline llvm::GlobalVariable::LinkageTypes
75 GetLinkageFromExternFlag(bool Extern) {
76 if (Extern)
77 return llvm::GlobalValue::WeakODRLinkage;
78
79 return llvm::GlobalValue::InternalLinkage;
80 }
81
82 // FIXME: This should be removed, and clients should pass in the linkage
83 // directly instead.
Mike Stump1a139f82009-11-19 01:08:19 +000084 llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +000085 return BuildName(Ty, Hidden, GetLinkageFromExternFlag(Extern));
86 }
87
88 llvm::Constant *BuildName(QualType Ty, bool Hidden,
89 llvm::GlobalVariable::LinkageTypes Linkage) {
Mike Stump14718422009-11-14 14:25:18 +000090 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +000091 CGM.getMangleContext().mangleCXXRTTIName(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +000092 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +000093
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +000094 llvm::GlobalVariable *OGV = CGM.getModule().getGlobalVariable(Name);
95 if (OGV && !OGV->isDeclaration())
96 return llvm::ConstantExpr::getBitCast(OGV, Int8PtrTy);
Mike Stump1a139f82009-11-19 01:08:19 +000097
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +000098 llvm::Constant *C = llvm::ConstantArray::get(VMContext, Name.substr(4));
Mike Stump14718422009-11-14 14:25:18 +000099
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000100 llvm::GlobalVariable *GV =
101 new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, Linkage,
102 C, Name);
Mike Stump1a139f82009-11-19 01:08:19 +0000103 if (OGV) {
104 GV->takeName(OGV);
105 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
106 OGV->getType());
107 OGV->replaceAllUsesWith(NewPtr);
108 OGV->eraseFromParent();
109 }
Mike Stump83d5e002009-11-18 03:46:51 +0000110 if (Hidden)
111 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
112 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump14718422009-11-14 14:25:18 +0000113 };
Mike Stump1acec6a2009-11-14 15:55:18 +0000114
Mike Stumpf5b28692009-11-14 23:32:21 +0000115 /// - BuildFlags - Build a psABI __flags value for __vmi_class_type_info.
116 llvm::Constant *BuildFlags(int f) {
117 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
118 }
119
120 /// BuildBaseCount - Build a psABI __base_count value for
121 /// __vmi_class_type_info.
122 llvm::Constant *BuildBaseCount(unsigned c) {
123 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), c);
124 }
125
Mike Stump3f75d552009-11-17 02:16:21 +0000126 llvm::Constant *BuildTypeRef(QualType Ty) {
Mike Stumpf5b28692009-11-14 23:32:21 +0000127 llvm::Constant *C;
Mike Stump1acec6a2009-11-14 15:55:18 +0000128
Mike Stump1acec6a2009-11-14 15:55:18 +0000129 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000130 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000131 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000132
Mike Stump1a139f82009-11-19 01:08:19 +0000133 C = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000134 if (C)
135 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
136
137 llvm::GlobalVariable::LinkageTypes linktype;
138 linktype = llvm::GlobalValue::ExternalLinkage;;
139
140 C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
Mike Stump1a139f82009-11-19 01:08:19 +0000141 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000142 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
143 }
144
Mike Stump3f75d552009-11-17 02:16:21 +0000145 llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
146 return BuildTypeRef(CGM.getContext().getTagDeclType(RD));
147 }
148
Mike Stump4c808df2009-11-15 03:28:10 +0000149 /// CalculateFlags - Calculate the flags for the __vmi_class_type_info
150 /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond
151 /// shaped class.
152 int CalculateFlags(const CXXRecordDecl*RD) {
153 int flags = 0;
154 if (SeenBase.count(RD))
155 flags |= 1;
156 else
157 SeenBase.insert(RD);
158 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
159 e = RD->bases_end(); i != e; ++i) {
160 const CXXRecordDecl *Base =
161 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
162 if (i->isVirtual()) {
163 if (SeenVBase.count(Base))
164 flags |= 2;
165 else
166 SeenVBase.insert(Base);
167 }
168 flags |= CalculateFlags(Base);
169 }
170 return flags;
171 }
172
173 bool SimpleInheritance(const CXXRecordDecl *RD) {
174 if (RD->getNumBases() != 1)
175 return false;
176 CXXRecordDecl::base_class_const_iterator i = RD->bases_begin();
177 if (i->isVirtual())
178 return false;
179 if (i->getAccessSpecifier() != AS_public)
180 return false;
181
182 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
183 const CXXRecordDecl *Base =
184 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
185 if (Layout.getBaseClassOffset(Base) != 0)
186 return false;
187 return true;
188 }
189
Mike Stump96b96d52009-11-17 23:11:22 +0000190 llvm::Constant *finish(std::vector<llvm::Constant *> &info,
191 llvm::GlobalVariable *GV,
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000192 llvm::StringRef Name, bool Hidden,
193 llvm::GlobalVariable::LinkageTypes Linkage) {
194 llvm::Constant *C =
195 llvm::ConstantStruct::get(VMContext, &info[0], info.size(),
196 /*Packed=*/false);
Mike Stump96b96d52009-11-17 23:11:22 +0000197
Mike Stump1a139f82009-11-19 01:08:19 +0000198 llvm::GlobalVariable *OGV = GV;
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000199 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, Linkage,
Mike Stump1a139f82009-11-19 01:08:19 +0000200 C, Name);
201 if (OGV) {
Mike Stump96b96d52009-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 Stump83d5e002009-11-18 03:46:51 +0000208 if (Hidden)
Mike Stumpc5d2ed72009-11-18 03:21:29 +0000209 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
Mike Stump96b96d52009-11-17 23:11:22 +0000210 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
211 }
212
213
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000214 llvm::Constant *
215 Buildclass_type_info(const CXXRecordDecl *RD,
216 llvm::GlobalVariable::LinkageTypes Linkage) {
Anders Carlsson1d6ad502009-12-11 16:41:51 +0000217 std::vector<llvm::Constant *> info;
218 assert(info.empty() && "Info vector must be empty!");
219
Mike Stump96b96d52009-11-17 23:11:22 +0000220 llvm::Constant *C;
221
Mike Stumpf5b28692009-11-14 23:32:21 +0000222 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000223 CGM.getMangleContext().mangleCXXRTTI(CGM.getContext().getTagDeclType(RD),
Daniel Dunbare128dd12009-11-21 09:06:22 +0000224 OutName);
225 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000226
227 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000228 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000229 if (GV && !GV->isDeclaration())
230 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
231
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000232 // If we're in an anonymous namespace, then we always want internal linkage.
233 if (RD->isInAnonymousNamespace())
234 Linkage = llvm::GlobalVariable::InternalLinkage;
235
Mike Stump83d5e002009-11-18 03:46:51 +0000236 bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
237
Mike Stump4c808df2009-11-15 03:28:10 +0000238 bool simple = false;
Mike Stumpf5b28692009-11-14 23:32:21 +0000239 if (RD->getNumBases() == 0)
240 C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
Mike Stump4c808df2009-11-15 03:28:10 +0000241 else if (SimpleInheritance(RD)) {
242 simple = true;
243 C = BuildVtableRef("_ZTVN10__cxxabiv120__si_class_type_infoE");
244 } else
Mike Stumpf5b28692009-11-14 23:32:21 +0000245 C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
246 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000247 info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000248 Linkage));
Mike Stump1acec6a2009-11-14 15:55:18 +0000249
Mike Stumpf5b28692009-11-14 23:32:21 +0000250 // If we have no bases, there are no more fields.
251 if (RD->getNumBases()) {
Mike Stump4c808df2009-11-15 03:28:10 +0000252 if (!simple) {
253 info.push_back(BuildFlags(CalculateFlags(RD)));
254 info.push_back(BuildBaseCount(RD->getNumBases()));
255 }
Mike Stumpf5b28692009-11-14 23:32:21 +0000256
257 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
258 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
259 e = RD->bases_end(); i != e; ++i) {
260 const CXXRecordDecl *Base =
261 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Anders Carlssona0b98f02009-12-11 16:37:06 +0000262 info.push_back(CGM.GetAddrOfRTTI(Base));
Mike Stump4c808df2009-11-15 03:28:10 +0000263 if (simple)
264 break;
Mike Stumpf5b28692009-11-14 23:32:21 +0000265 int64_t offset;
266 if (!i->isVirtual())
Mike Stump4c808df2009-11-15 03:28:10 +0000267 offset = Layout.getBaseClassOffset(Base)/8;
Mike Stumpf5b28692009-11-14 23:32:21 +0000268 else
269 offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
270 offset <<= 8;
271 // Now set the flags.
272 offset += i->isVirtual() ? 1 : 0;;
273 offset += i->getAccessSpecifier() == AS_public ? 2 : 0;
274 const llvm::Type *LongTy =
275 CGM.getTypes().ConvertType(CGM.getContext().LongTy);
276 C = llvm::ConstantInt::get(LongTy, offset);
277 info.push_back(C);
278 }
279 }
280
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000281 return finish(info, GV, Name, Hidden, Linkage);
Mike Stump1acec6a2009-11-14 15:55:18 +0000282 }
Mike Stump3f75d552009-11-17 02:16:21 +0000283
Mike Stumpdb72c892009-11-17 21:44:24 +0000284 /// - BuildFlags - Build a __flags value for __pbase_type_info.
Anders Carlssonc9882012009-12-11 01:27:37 +0000285 llvm::Constant *BuildInt(unsigned n) {
286 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), n);
Mike Stumpdb72c892009-11-17 21:44:24 +0000287 }
288
Mike Stump1a139f82009-11-19 01:08:19 +0000289 bool DecideExtern(QualType Ty) {
290 // For this type, see if all components are never in an anonymous namespace.
291 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
292 return (DecideExtern(MPT->getPointeeType())
293 && DecideExtern(QualType(MPT->getClass(), 0)));
294 if (const PointerType *PT = Ty->getAs<PointerType>())
295 return DecideExtern(PT->getPointeeType());
296 if (const RecordType *RT = Ty->getAs<RecordType>())
297 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
298 return !RD->isInAnonymousNamespace();
299 return true;
300 }
301
302 bool DecideHidden(QualType Ty) {
303 // For this type, see if all components are never hidden.
304 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
305 return (DecideHidden(MPT->getPointeeType())
306 && DecideHidden(QualType(MPT->getClass(), 0)));
307 if (const PointerType *PT = Ty->getAs<PointerType>())
308 return DecideHidden(PT->getPointeeType());
309 if (const RecordType *RT = Ty->getAs<RecordType>())
310 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
311 return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
312 return false;
313 }
314
Mike Stumpdb72c892009-11-17 21:44:24 +0000315 llvm::Constant *BuildPointerType(QualType Ty) {
Anders Carlsson1d6ad502009-12-11 16:41:51 +0000316 std::vector<llvm::Constant *> info;
317 assert(info.empty() && "Info vector must be empty!");
318
Mike Stumpdb72c892009-11-17 21:44:24 +0000319 llvm::Constant *C;
320
321 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000322 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000323 llvm::StringRef Name = OutName.str();
Mike Stumpdb72c892009-11-17 21:44:24 +0000324
325 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000326 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpdb72c892009-11-17 21:44:24 +0000327 if (GV && !GV->isDeclaration())
328 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
329
Mike Stump1a139f82009-11-19 01:08:19 +0000330 bool Extern = DecideExtern(Ty);
331 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000332
Anders Carlssonc9882012009-12-11 01:27:37 +0000333 const MemberPointerType *PtrMemTy = dyn_cast<MemberPointerType>(Ty);
334 QualType PointeeTy;
335
336 if (PtrMemTy)
337 PointeeTy = PtrMemTy->getPointeeType();
338 else
339 PointeeTy = Ty->getPointeeType();
Mike Stumpdb72c892009-11-17 21:44:24 +0000340
Anders Carlssonc9882012009-12-11 01:27:37 +0000341 if (PtrMemTy)
Mike Stumpdb72c892009-11-17 21:44:24 +0000342 C = BuildVtableRef("_ZTVN10__cxxabiv129__pointer_to_member_type_infoE");
343 else
344 C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
Anders Carlssonc9882012009-12-11 01:27:37 +0000345
Mike Stumpdb72c892009-11-17 21:44:24 +0000346 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000347 info.push_back(BuildName(Ty, Hidden, Extern));
Anders Carlssonc9882012009-12-11 01:27:37 +0000348 Qualifiers Q = PointeeTy.getQualifiers();
349
350 PointeeTy =
351 CGM.getContext().getCanonicalType(PointeeTy).getUnqualifiedType();
352
353 unsigned Flags = 0;
354 if (Q.hasConst())
355 Flags |= TI_Const;
356 if (Q.hasVolatile())
357 Flags |= TI_Volatile;
358 if (Q.hasRestrict())
359 Flags |= TI_Restrict;
360
361 if (Ty->isIncompleteType())
362 Flags |= TI_Incomplete;
363
364 if (PtrMemTy && PtrMemTy->getClass()->isIncompleteType())
365 Flags |= TI_ContainingClassIncomplete;
366
367 info.push_back(BuildInt(Flags));
Mike Stumpdb72c892009-11-17 21:44:24 +0000368 info.push_back(BuildInt(0));
Anders Carlssonc9882012009-12-11 01:27:37 +0000369 info.push_back(BuildType(PointeeTy));
Mike Stumpdb72c892009-11-17 21:44:24 +0000370
Anders Carlssonc9882012009-12-11 01:27:37 +0000371 if (PtrMemTy)
372 info.push_back(BuildType(QualType(PtrMemTy->getClass(), 0)));
Mike Stump4aaf79a2009-11-17 23:51:10 +0000373
Mike Stump1a139f82009-11-19 01:08:19 +0000374 // We always generate these as hidden, only the name isn't hidden.
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000375 return finish(info, GV, Name, /*Hidden=*/true,
376 GetLinkageFromExternFlag(Extern));
Mike Stump96b96d52009-11-17 23:11:22 +0000377 }
Mike Stumpdb72c892009-11-17 21:44:24 +0000378
Mike Stump103a0842009-11-17 23:45:57 +0000379 llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
Anders Carlsson1d6ad502009-12-11 16:41:51 +0000380 std::vector<llvm::Constant *> info;
381 assert(info.empty() && "Info vector must be empty!");
382
Mike Stump96b96d52009-11-17 23:11:22 +0000383 llvm::Constant *C;
384
385 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000386 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000387 llvm::StringRef Name = OutName.str();
Mike Stump96b96d52009-11-17 23:11:22 +0000388
389 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000390 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump96b96d52009-11-17 23:11:22 +0000391 if (GV && !GV->isDeclaration())
392 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
393
Mike Stump1a139f82009-11-19 01:08:19 +0000394 bool Extern = DecideExtern(Ty);
395 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000396
Mike Stump103a0842009-11-17 23:45:57 +0000397 C = BuildVtableRef(vtbl);
Mike Stump96b96d52009-11-17 23:11:22 +0000398 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000399 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stump4aaf79a2009-11-17 23:51:10 +0000400
Mike Stump1a139f82009-11-19 01:08:19 +0000401 // We always generate these as hidden, only the name isn't hidden.
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000402 return finish(info, GV, Name, /*Hidden=*/true,
403 GetLinkageFromExternFlag(Extern));
Mike Stumpdb72c892009-11-17 21:44:24 +0000404 }
405
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000406 /// BuildType - Builds the type info for the given type.
Mike Stump3f75d552009-11-17 02:16:21 +0000407 llvm::Constant *BuildType(QualType Ty) {
408 const clang::Type &Type
409 = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
Mike Stump101f0522009-11-20 00:31:50 +0000410
411 if (const RecordType *RT = Ty.getTypePtr()->getAs<RecordType>())
412 if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()))
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000413 return BuildClassTypeInfo(RD);
Mike Stump101f0522009-11-20 00:31:50 +0000414
Mike Stump3f75d552009-11-17 02:16:21 +0000415 switch (Type.getTypeClass()) {
416 default: {
Mike Stump3f75d552009-11-17 02:16:21 +0000417 assert(0 && "typeid expression");
Mike Stump3f75d552009-11-17 02:16:21 +0000418 return llvm::Constant::getNullValue(Int8PtrTy);
419 }
420
421 case Type::Builtin: {
422 // We expect all type_info objects for builtin types to be in the library.
423 return BuildTypeRef(Ty);
424 }
Mike Stump8f5e6772009-11-17 02:57:13 +0000425
426 case Type::Pointer: {
427 QualType PTy = Ty->getPointeeType();
428 Qualifiers Q = PTy.getQualifiers();
429 Q.removeConst();
430 // T* and const T* for all builtin types T are expected in the library.
431 if (isa<BuiltinType>(PTy) && Q.empty())
432 return BuildTypeRef(Ty);
433
Mike Stumpdb72c892009-11-17 21:44:24 +0000434 return BuildPointerType(Ty);
Mike Stump8f5e6772009-11-17 02:57:13 +0000435 }
Mike Stump6fdfea62009-11-17 22:33:00 +0000436 case Type::MemberPointer:
437 return BuildPointerType(Ty);
Mike Stump96b96d52009-11-17 23:11:22 +0000438 case Type::FunctionProto:
Mike Stump103a0842009-11-17 23:45:57 +0000439 case Type::FunctionNoProto:
440 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv120__function_type_infoE");
441 case Type::ConstantArray:
442 case Type::IncompleteArray:
443 case Type::VariableArray:
444 case Type::Vector:
445 case Type::ExtVector:
446 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
447 case Type::Enum:
448 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv116__enum_type_infoE");
Mike Stump3f75d552009-11-17 02:16:21 +0000449 }
450 }
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000451
452 /// BuildClassTypeInfo - Builds the class type info (or a reference to it)
453 /// for the given record decl.
454 llvm::Constant *BuildClassTypeInfo(const CXXRecordDecl *RD) {
455 const CXXMethodDecl *KeyFunction = 0;
456
457 if (RD->isDynamicClass())
458 KeyFunction = CGM.getContext().getKeyFunction(RD);
459
460 if (KeyFunction) {
461 // If the key function is defined in this translation unit, then the RTTI
462 // related constants should also be emitted here, with external linkage.
463 if (KeyFunction->getBody())
464 return Buildclass_type_info(RD, llvm::GlobalValue::ExternalLinkage);
465
466 // Otherwise, we just want a reference to the type info.
467 return Buildclass_type_infoRef(RD);
468 }
469
470 // If there is no key function (or if the record doesn't have any virtual
471 // member functions or virtual bases), emit the type info with weak_odr
472 // linkage.
473 return Buildclass_type_info(RD, llvm::GlobalValue::WeakODRLinkage);
474 }
Mike Stump14718422009-11-14 14:25:18 +0000475};
Mike Stumpae1b85d2009-12-02 19:07:44 +0000476}
Mike Stump14718422009-11-14 14:25:18 +0000477
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000478llvm::Constant *CodeGenModule::GetAddrOfRTTI(const CXXRecordDecl *RD) {
479 if (!getContext().getLangOptions().RTTI) {
480 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
481 return llvm::Constant::getNullValue(Int8PtrTy);
482 }
483
484 return RTTIBuilder(*this).BuildClassTypeInfo(RD);
485}
486
487llvm::Constant *CodeGenModule::GetAddrOfRTTI(QualType Ty) {
488 if (!getContext().getLangOptions().RTTI) {
489 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
490 return llvm::Constant::getNullValue(Int8PtrTy);
491 }
492
493 return RTTIBuilder(*this).BuildType(Ty);
494}
495
Mike Stumpc01c2b82009-12-02 18:57:08 +0000496llvm::Constant *CodeGenModule::GenerateRTTIRef(const CXXRecordDecl *RD) {
497 RTTIBuilder b(*this);
Mike Stumpf5b28692009-11-14 23:32:21 +0000498
499 return b.Buildclass_type_infoRef(RD);
500}
501
Mike Stumpc01c2b82009-12-02 18:57:08 +0000502llvm::Constant *CodeGenModule::GenerateRTTI(const CXXRecordDecl *RD) {
503 RTTIBuilder b(*this);
Mike Stump14718422009-11-14 14:25:18 +0000504
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000505 return b.Buildclass_type_info(RD, llvm::GlobalValue::ExternalLinkage);
Anders Carlsson6ce51fd2009-10-10 20:49:04 +0000506}
Mike Stump3f75d552009-11-17 02:16:21 +0000507
Mike Stumpc01c2b82009-12-02 18:57:08 +0000508llvm::Constant *CodeGenModule::GenerateRTTI(QualType Ty) {
509 RTTIBuilder b(*this);
Mike Stump3f75d552009-11-17 02:16:21 +0000510
511 return b.BuildType(Ty);
512}