blob: 4b7814bdb0eff1bfdf5f6d3ef7a3f4eee5184662 [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
Anders Carlssonc9882012009-12-11 01:27:37 +000028 // Type info flags.
29 enum {
30 /// TI_Const - Type has const qualifier.
31 TI_Const = 0x1,
32
33 /// TI_Volatile - Type has volatile qualifier.
34 TI_Volatile = 0x2,
35
36 /// TI_Restrict - Type has restrict qualifier.
37 TI_Restrict = 0x4,
38
39 /// TI_Incomplete - Type is incomplete.
40 TI_Incomplete = 0x8,
41
42 /// TI_ContainingClassIncomplete - Containing class is incomplete.
43 /// (in pointer to member).
44 TI_ContainingClassIncomplete = 0x10
45 };
46
Mike Stump14718422009-11-14 14:25:18 +000047public:
Mike Stumpc01c2b82009-12-02 18:57:08 +000048 RTTIBuilder(CodeGenModule &cgm)
Mike Stump14718422009-11-14 14:25:18 +000049 : CGM(cgm), VMContext(cgm.getModule().getContext()),
50 Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
51
Mike Stumpf5b28692009-11-14 23:32:21 +000052 /// BuildVtableRef - Build a reference to a vtable.
53 llvm::Constant *BuildVtableRef(const char *Name) {
54 // Build a descriptor for Name
Mike Stump1acec6a2009-11-14 15:55:18 +000055 llvm::Constant *GV = CGM.getModule().getGlobalVariable(Name);
56 if (GV)
57 GV = llvm::ConstantExpr::getBitCast(GV,
58 llvm::PointerType::get(Int8PtrTy, 0));
59 else {
60 llvm::GlobalVariable::LinkageTypes linktype;
61 linktype = llvm::GlobalValue::ExternalLinkage;
62 GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy,
63 true, linktype, 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +000064 }
Mike Stump1acec6a2009-11-14 15:55:18 +000065 llvm::Constant *C;
66 C = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 2);
67 C = llvm::ConstantExpr::getInBoundsGetElementPtr(GV, &C, 1);
68 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
69 }
Mike Stumpf5b28692009-11-14 23:32:21 +000070
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +000071 // FIXME: This should be removed, and clients should pass in the linkage
72 // directly instead.
73 static inline llvm::GlobalVariable::LinkageTypes
74 GetLinkageFromExternFlag(bool Extern) {
75 if (Extern)
76 return llvm::GlobalValue::WeakODRLinkage;
77
78 return llvm::GlobalValue::InternalLinkage;
79 }
80
81 // FIXME: This should be removed, and clients should pass in the linkage
82 // directly instead.
Mike Stump1a139f82009-11-19 01:08:19 +000083 llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +000084 return BuildName(Ty, Hidden, GetLinkageFromExternFlag(Extern));
85 }
86
87 llvm::Constant *BuildName(QualType Ty, bool Hidden,
88 llvm::GlobalVariable::LinkageTypes Linkage) {
Mike Stump14718422009-11-14 14:25:18 +000089 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +000090 CGM.getMangleContext().mangleCXXRTTIName(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +000091 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +000092
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +000093 llvm::GlobalVariable *OGV = CGM.getModule().getGlobalVariable(Name);
94 if (OGV && !OGV->isDeclaration())
95 return llvm::ConstantExpr::getBitCast(OGV, Int8PtrTy);
Mike Stump1a139f82009-11-19 01:08:19 +000096
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +000097 llvm::Constant *C = llvm::ConstantArray::get(VMContext, Name.substr(4));
Mike Stump14718422009-11-14 14:25:18 +000098
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +000099 llvm::GlobalVariable *GV =
100 new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, Linkage,
101 C, Name);
Mike Stump1a139f82009-11-19 01:08:19 +0000102 if (OGV) {
103 GV->takeName(OGV);
104 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
105 OGV->getType());
106 OGV->replaceAllUsesWith(NewPtr);
107 OGV->eraseFromParent();
108 }
Mike Stump83d5e002009-11-18 03:46:51 +0000109 if (Hidden)
110 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
111 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump14718422009-11-14 14:25:18 +0000112 };
Mike Stump1acec6a2009-11-14 15:55:18 +0000113
Mike Stumpf5b28692009-11-14 23:32:21 +0000114 /// - BuildFlags - Build a psABI __flags value for __vmi_class_type_info.
115 llvm::Constant *BuildFlags(int f) {
116 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
117 }
118
119 /// BuildBaseCount - Build a psABI __base_count value for
120 /// __vmi_class_type_info.
121 llvm::Constant *BuildBaseCount(unsigned c) {
122 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), c);
123 }
124
Mike Stump3f75d552009-11-17 02:16:21 +0000125 llvm::Constant *BuildTypeRef(QualType Ty) {
Mike Stumpf5b28692009-11-14 23:32:21 +0000126 llvm::Constant *C;
Mike Stump1acec6a2009-11-14 15:55:18 +0000127
Mike Stump1acec6a2009-11-14 15:55:18 +0000128 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000129 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000130 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000131
Mike Stump1a139f82009-11-19 01:08:19 +0000132 C = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000133 if (C)
134 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
135
136 llvm::GlobalVariable::LinkageTypes linktype;
137 linktype = llvm::GlobalValue::ExternalLinkage;;
138
139 C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
Mike Stump1a139f82009-11-19 01:08:19 +0000140 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000141 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
142 }
143
Mike Stump3f75d552009-11-17 02:16:21 +0000144 llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
145 return BuildTypeRef(CGM.getContext().getTagDeclType(RD));
146 }
147
Mike Stump4c808df2009-11-15 03:28:10 +0000148 /// CalculateFlags - Calculate the flags for the __vmi_class_type_info
149 /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond
150 /// shaped class.
151 int CalculateFlags(const CXXRecordDecl*RD) {
152 int flags = 0;
153 if (SeenBase.count(RD))
154 flags |= 1;
155 else
156 SeenBase.insert(RD);
157 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
158 e = RD->bases_end(); i != e; ++i) {
159 const CXXRecordDecl *Base =
160 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
161 if (i->isVirtual()) {
162 if (SeenVBase.count(Base))
163 flags |= 2;
164 else
165 SeenVBase.insert(Base);
166 }
167 flags |= CalculateFlags(Base);
168 }
169 return flags;
170 }
171
172 bool SimpleInheritance(const CXXRecordDecl *RD) {
173 if (RD->getNumBases() != 1)
174 return false;
175 CXXRecordDecl::base_class_const_iterator i = RD->bases_begin();
176 if (i->isVirtual())
177 return false;
178 if (i->getAccessSpecifier() != AS_public)
179 return false;
180
181 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
182 const CXXRecordDecl *Base =
183 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
184 if (Layout.getBaseClassOffset(Base) != 0)
185 return false;
186 return true;
187 }
188
Anders Carlssone7025c52009-12-13 16:38:01 +0000189 llvm::Constant *finish(llvm::Constant *const *Values, unsigned NumValues,
Mike Stump96b96d52009-11-17 23:11:22 +0000190 llvm::GlobalVariable *GV,
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000191 llvm::StringRef Name, bool Hidden,
192 llvm::GlobalVariable::LinkageTypes Linkage) {
193 llvm::Constant *C =
Anders Carlssone7025c52009-12-13 16:38:01 +0000194 llvm::ConstantStruct::get(VMContext, Values, NumValues, /*Packed=*/false);
Mike Stump96b96d52009-11-17 23:11:22 +0000195
Mike Stump1a139f82009-11-19 01:08:19 +0000196 llvm::GlobalVariable *OGV = GV;
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000197 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, Linkage,
Mike Stump1a139f82009-11-19 01:08:19 +0000198 C, Name);
199 if (OGV) {
Mike Stump96b96d52009-11-17 23:11:22 +0000200 GV->takeName(OGV);
201 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
202 OGV->getType());
203 OGV->replaceAllUsesWith(NewPtr);
204 OGV->eraseFromParent();
205 }
Mike Stump83d5e002009-11-18 03:46:51 +0000206 if (Hidden)
Mike Stumpc5d2ed72009-11-18 03:21:29 +0000207 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
Mike Stump96b96d52009-11-17 23:11:22 +0000208 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
209 }
210
211
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000212 llvm::Constant *
213 Buildclass_type_info(const CXXRecordDecl *RD,
214 llvm::GlobalVariable::LinkageTypes Linkage) {
Anders Carlsson1d6ad502009-12-11 16:41:51 +0000215 std::vector<llvm::Constant *> info;
216 assert(info.empty() && "Info vector must be empty!");
217
Mike Stump96b96d52009-11-17 23:11:22 +0000218 llvm::Constant *C;
219
Mike Stumpf5b28692009-11-14 23:32:21 +0000220 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000221 CGM.getMangleContext().mangleCXXRTTI(CGM.getContext().getTagDeclType(RD),
Daniel Dunbare128dd12009-11-21 09:06:22 +0000222 OutName);
223 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000224
225 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000226 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000227 if (GV && !GV->isDeclaration())
228 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
229
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000230 // If we're in an anonymous namespace, then we always want internal linkage.
Eli Friedman3ace52b2009-12-11 20:48:18 +0000231 if (RD->isInAnonymousNamespace() || !RD->hasLinkage())
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000232 Linkage = llvm::GlobalVariable::InternalLinkage;
233
Mike Stump83d5e002009-11-18 03:46:51 +0000234 bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
235
Mike Stump4c808df2009-11-15 03:28:10 +0000236 bool simple = false;
Mike Stumpf5b28692009-11-14 23:32:21 +0000237 if (RD->getNumBases() == 0)
238 C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
Mike Stump4c808df2009-11-15 03:28:10 +0000239 else if (SimpleInheritance(RD)) {
240 simple = true;
241 C = BuildVtableRef("_ZTVN10__cxxabiv120__si_class_type_infoE");
242 } else
Mike Stumpf5b28692009-11-14 23:32:21 +0000243 C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
244 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000245 info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000246 Linkage));
Mike Stump1acec6a2009-11-14 15:55:18 +0000247
Mike Stumpf5b28692009-11-14 23:32:21 +0000248 // If we have no bases, there are no more fields.
249 if (RD->getNumBases()) {
Mike Stump4c808df2009-11-15 03:28:10 +0000250 if (!simple) {
251 info.push_back(BuildFlags(CalculateFlags(RD)));
252 info.push_back(BuildBaseCount(RD->getNumBases()));
253 }
Mike Stumpf5b28692009-11-14 23:32:21 +0000254
255 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
256 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
257 e = RD->bases_end(); i != e; ++i) {
258 const CXXRecordDecl *Base =
259 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Anders Carlssona0b98f02009-12-11 16:37:06 +0000260 info.push_back(CGM.GetAddrOfRTTI(Base));
Mike Stump4c808df2009-11-15 03:28:10 +0000261 if (simple)
262 break;
Mike Stumpf5b28692009-11-14 23:32:21 +0000263 int64_t offset;
264 if (!i->isVirtual())
Mike Stump4c808df2009-11-15 03:28:10 +0000265 offset = Layout.getBaseClassOffset(Base)/8;
Mike Stumpf5b28692009-11-14 23:32:21 +0000266 else
267 offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
268 offset <<= 8;
269 // Now set the flags.
270 offset += i->isVirtual() ? 1 : 0;;
271 offset += i->getAccessSpecifier() == AS_public ? 2 : 0;
272 const llvm::Type *LongTy =
273 CGM.getTypes().ConvertType(CGM.getContext().LongTy);
274 C = llvm::ConstantInt::get(LongTy, offset);
275 info.push_back(C);
276 }
277 }
278
Anders Carlssone7025c52009-12-13 16:38:01 +0000279 return finish(&info[0], info.size(), GV, Name, Hidden, Linkage);
Mike Stump1acec6a2009-11-14 15:55:18 +0000280 }
Mike Stump3f75d552009-11-17 02:16:21 +0000281
Mike Stumpdb72c892009-11-17 21:44:24 +0000282 /// - BuildFlags - Build a __flags value for __pbase_type_info.
Anders Carlssonc9882012009-12-11 01:27:37 +0000283 llvm::Constant *BuildInt(unsigned n) {
284 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), n);
Mike Stumpdb72c892009-11-17 21:44:24 +0000285 }
286
Mike Stump1a139f82009-11-19 01:08:19 +0000287 bool DecideExtern(QualType Ty) {
288 // For this type, see if all components are never in an anonymous namespace.
289 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
290 return (DecideExtern(MPT->getPointeeType())
291 && DecideExtern(QualType(MPT->getClass(), 0)));
292 if (const PointerType *PT = Ty->getAs<PointerType>())
293 return DecideExtern(PT->getPointeeType());
294 if (const RecordType *RT = Ty->getAs<RecordType>())
295 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
Eli Friedman3ace52b2009-12-11 20:48:18 +0000296 return !RD->isInAnonymousNamespace() && RD->hasLinkage();
Mike Stump1a139f82009-11-19 01:08:19 +0000297 return true;
298 }
299
300 bool DecideHidden(QualType Ty) {
301 // For this type, see if all components are never hidden.
302 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
303 return (DecideHidden(MPT->getPointeeType())
304 && DecideHidden(QualType(MPT->getClass(), 0)));
305 if (const PointerType *PT = Ty->getAs<PointerType>())
306 return DecideHidden(PT->getPointeeType());
307 if (const RecordType *RT = Ty->getAs<RecordType>())
308 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
309 return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
310 return false;
311 }
312
Mike Stumpdb72c892009-11-17 21:44:24 +0000313 llvm::Constant *BuildPointerType(QualType Ty) {
Anders Carlsson1d6ad502009-12-11 16:41:51 +0000314 std::vector<llvm::Constant *> info;
315 assert(info.empty() && "Info vector must be empty!");
316
Mike Stumpdb72c892009-11-17 21:44:24 +0000317 llvm::Constant *C;
318
319 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000320 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000321 llvm::StringRef Name = OutName.str();
Mike Stumpdb72c892009-11-17 21:44:24 +0000322
323 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000324 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpdb72c892009-11-17 21:44:24 +0000325 if (GV && !GV->isDeclaration())
326 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
327
Mike Stump1a139f82009-11-19 01:08:19 +0000328 bool Extern = DecideExtern(Ty);
329 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000330
Anders Carlssonc9882012009-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 Stumpdb72c892009-11-17 21:44:24 +0000338
Anders Carlssonc9882012009-12-11 01:27:37 +0000339 if (PtrMemTy)
Mike Stumpdb72c892009-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 Carlssonc9882012009-12-11 01:27:37 +0000343
Mike Stumpdb72c892009-11-17 21:44:24 +0000344 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000345 info.push_back(BuildName(Ty, Hidden, Extern));
Anders Carlssonc9882012009-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
365 info.push_back(BuildInt(Flags));
Mike Stumpdb72c892009-11-17 21:44:24 +0000366 info.push_back(BuildInt(0));
Anders Carlssonc9882012009-12-11 01:27:37 +0000367 info.push_back(BuildType(PointeeTy));
Mike Stumpdb72c892009-11-17 21:44:24 +0000368
Anders Carlssonc9882012009-12-11 01:27:37 +0000369 if (PtrMemTy)
370 info.push_back(BuildType(QualType(PtrMemTy->getClass(), 0)));
Mike Stump4aaf79a2009-11-17 23:51:10 +0000371
Mike Stump1a139f82009-11-19 01:08:19 +0000372 // We always generate these as hidden, only the name isn't hidden.
Anders Carlssone7025c52009-12-13 16:38:01 +0000373 return finish(&info[0], info.size(), GV, Name, /*Hidden=*/true,
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000374 GetLinkageFromExternFlag(Extern));
Mike Stump96b96d52009-11-17 23:11:22 +0000375 }
Mike Stumpdb72c892009-11-17 21:44:24 +0000376
Mike Stump103a0842009-11-17 23:45:57 +0000377 llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
Mike Stump96b96d52009-11-17 23:11:22 +0000378 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000379 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000380 llvm::StringRef Name = OutName.str();
Mike Stump96b96d52009-11-17 23:11:22 +0000381
382 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000383 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump96b96d52009-11-17 23:11:22 +0000384 if (GV && !GV->isDeclaration())
385 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
386
Mike Stump1a139f82009-11-19 01:08:19 +0000387 bool Extern = DecideExtern(Ty);
388 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000389
Anders Carlssonc67974c2009-12-13 23:47:29 +0000390 llvm::Constant *Info[] = {
391 BuildVtableRef(vtbl), BuildName(Ty, Hidden, Extern)
392 };
393
Mike Stump1a139f82009-11-19 01:08:19 +0000394 // We always generate these as hidden, only the name isn't hidden.
Anders Carlssonc67974c2009-12-13 23:47:29 +0000395 return finish(&Info[0], llvm::array_lengthof(Info), GV, Name,
396 /*Hidden=*/true, GetLinkageFromExternFlag(Extern));
Mike Stumpdb72c892009-11-17 21:44:24 +0000397 }
398
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000399 /// BuildType - Builds the type info for the given type.
Mike Stump3f75d552009-11-17 02:16:21 +0000400 llvm::Constant *BuildType(QualType Ty) {
401 const clang::Type &Type
402 = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
Mike Stump101f0522009-11-20 00:31:50 +0000403
404 if (const RecordType *RT = Ty.getTypePtr()->getAs<RecordType>())
405 if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()))
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000406 return BuildClassTypeInfo(RD);
Mike Stump101f0522009-11-20 00:31:50 +0000407
Mike Stump3f75d552009-11-17 02:16:21 +0000408 switch (Type.getTypeClass()) {
409 default: {
Mike Stump3f75d552009-11-17 02:16:21 +0000410 assert(0 && "typeid expression");
Mike Stump3f75d552009-11-17 02:16:21 +0000411 return llvm::Constant::getNullValue(Int8PtrTy);
412 }
413
414 case Type::Builtin: {
415 // We expect all type_info objects for builtin types to be in the library.
416 return BuildTypeRef(Ty);
417 }
Mike Stump8f5e6772009-11-17 02:57:13 +0000418
419 case Type::Pointer: {
420 QualType PTy = Ty->getPointeeType();
421 Qualifiers Q = PTy.getQualifiers();
422 Q.removeConst();
423 // T* and const T* for all builtin types T are expected in the library.
424 if (isa<BuiltinType>(PTy) && Q.empty())
425 return BuildTypeRef(Ty);
426
Mike Stumpdb72c892009-11-17 21:44:24 +0000427 return BuildPointerType(Ty);
Mike Stump8f5e6772009-11-17 02:57:13 +0000428 }
Mike Stump6fdfea62009-11-17 22:33:00 +0000429 case Type::MemberPointer:
430 return BuildPointerType(Ty);
Mike Stump96b96d52009-11-17 23:11:22 +0000431 case Type::FunctionProto:
Mike Stump103a0842009-11-17 23:45:57 +0000432 case Type::FunctionNoProto:
433 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv120__function_type_infoE");
434 case Type::ConstantArray:
435 case Type::IncompleteArray:
436 case Type::VariableArray:
437 case Type::Vector:
438 case Type::ExtVector:
439 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
440 case Type::Enum:
441 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv116__enum_type_infoE");
Mike Stump3f75d552009-11-17 02:16:21 +0000442 }
443 }
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000444
445 /// BuildClassTypeInfo - Builds the class type info (or a reference to it)
446 /// for the given record decl.
447 llvm::Constant *BuildClassTypeInfo(const CXXRecordDecl *RD) {
448 const CXXMethodDecl *KeyFunction = 0;
449
450 if (RD->isDynamicClass())
451 KeyFunction = CGM.getContext().getKeyFunction(RD);
452
453 if (KeyFunction) {
454 // If the key function is defined in this translation unit, then the RTTI
455 // related constants should also be emitted here, with external linkage.
456 if (KeyFunction->getBody())
457 return Buildclass_type_info(RD, llvm::GlobalValue::ExternalLinkage);
458
459 // Otherwise, we just want a reference to the type info.
460 return Buildclass_type_infoRef(RD);
461 }
462
463 // If there is no key function (or if the record doesn't have any virtual
464 // member functions or virtual bases), emit the type info with weak_odr
465 // linkage.
466 return Buildclass_type_info(RD, llvm::GlobalValue::WeakODRLinkage);
467 }
Mike Stump14718422009-11-14 14:25:18 +0000468};
Mike Stumpae1b85d2009-12-02 19:07:44 +0000469}
Mike Stump14718422009-11-14 14:25:18 +0000470
Anders Carlssonfd7dfeb2009-12-11 02:46:30 +0000471llvm::Constant *CodeGenModule::GetAddrOfRTTI(const CXXRecordDecl *RD) {
472 if (!getContext().getLangOptions().RTTI) {
473 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
474 return llvm::Constant::getNullValue(Int8PtrTy);
475 }
476
477 return RTTIBuilder(*this).BuildClassTypeInfo(RD);
478}
479
480llvm::Constant *CodeGenModule::GetAddrOfRTTI(QualType Ty) {
481 if (!getContext().getLangOptions().RTTI) {
482 const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
483 return llvm::Constant::getNullValue(Int8PtrTy);
484 }
485
486 return RTTIBuilder(*this).BuildType(Ty);
487}