blob: 248fe89271c1697b93936b64bab5c91e196f7bf8 [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;
Mike Stump14718422009-11-14 14:25:18 +000027public:
Mike Stumpc01c2b82009-12-02 18:57:08 +000028 RTTIBuilder(CodeGenModule &cgm)
Mike Stump14718422009-11-14 14:25:18 +000029 : CGM(cgm), VMContext(cgm.getModule().getContext()),
30 Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
31
Mike Stumpf5b28692009-11-14 23:32:21 +000032 /// BuildVtableRef - Build a reference to a vtable.
33 llvm::Constant *BuildVtableRef(const char *Name) {
34 // Build a descriptor for Name
Mike Stump1acec6a2009-11-14 15:55:18 +000035 llvm::Constant *GV = CGM.getModule().getGlobalVariable(Name);
36 if (GV)
37 GV = llvm::ConstantExpr::getBitCast(GV,
38 llvm::PointerType::get(Int8PtrTy, 0));
39 else {
40 llvm::GlobalVariable::LinkageTypes linktype;
41 linktype = llvm::GlobalValue::ExternalLinkage;
42 GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy,
43 true, linktype, 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +000044 }
Mike Stump1acec6a2009-11-14 15:55:18 +000045 llvm::Constant *C;
46 C = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 2);
47 C = llvm::ConstantExpr::getInBoundsGetElementPtr(GV, &C, 1);
48 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
49 }
Mike Stumpf5b28692009-11-14 23:32:21 +000050
Mike Stump1a139f82009-11-19 01:08:19 +000051 llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
Mike Stump14718422009-11-14 14:25:18 +000052 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +000053 CGM.getMangleContext().mangleCXXRTTIName(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +000054 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +000055
Mike Stump14718422009-11-14 14:25:18 +000056 llvm::GlobalVariable::LinkageTypes linktype;
57 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump1a139f82009-11-19 01:08:19 +000058 if (!Extern)
59 linktype = llvm::GlobalValue::InternalLinkage;
60
61 llvm::GlobalVariable *GV;
62 GV = CGM.getModule().getGlobalVariable(Name);
63 if (GV && !GV->isDeclaration())
64 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump14718422009-11-14 14:25:18 +000065
66 llvm::Constant *C;
Mike Stump1a139f82009-11-19 01:08:19 +000067 C = llvm::ConstantArray::get(VMContext, Name.substr(4));
Mike Stumpf5b28692009-11-14 23:32:21 +000068
Mike Stump1a139f82009-11-19 01:08:19 +000069 llvm::GlobalVariable *OGV = GV;
70 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
71 C, Name);
72 if (OGV) {
73 GV->takeName(OGV);
74 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
75 OGV->getType());
76 OGV->replaceAllUsesWith(NewPtr);
77 OGV->eraseFromParent();
78 }
Mike Stump83d5e002009-11-18 03:46:51 +000079 if (Hidden)
80 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
81 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump14718422009-11-14 14:25:18 +000082 };
Mike Stump1acec6a2009-11-14 15:55:18 +000083
Mike Stumpf5b28692009-11-14 23:32:21 +000084 /// - BuildFlags - Build a psABI __flags value for __vmi_class_type_info.
85 llvm::Constant *BuildFlags(int f) {
86 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
87 }
88
89 /// BuildBaseCount - Build a psABI __base_count value for
90 /// __vmi_class_type_info.
91 llvm::Constant *BuildBaseCount(unsigned c) {
92 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), c);
93 }
94
Mike Stump3f75d552009-11-17 02:16:21 +000095 llvm::Constant *BuildTypeRef(QualType Ty) {
Mike Stumpf5b28692009-11-14 23:32:21 +000096 llvm::Constant *C;
Mike Stump1acec6a2009-11-14 15:55:18 +000097
Mike Stumpc01c2b82009-12-02 18:57:08 +000098 if (!CGM.getContext().getLangOptions().RTTI)
Mike Stump1acec6a2009-11-14 15:55:18 +000099 return llvm::Constant::getNullValue(Int8PtrTy);
100
101 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000102 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000103 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000104
Mike Stump1a139f82009-11-19 01:08:19 +0000105 C = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000106 if (C)
107 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
108
109 llvm::GlobalVariable::LinkageTypes linktype;
110 linktype = llvm::GlobalValue::ExternalLinkage;;
111
112 C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
Mike Stump1a139f82009-11-19 01:08:19 +0000113 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000114 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
115 }
116
Mike Stump3f75d552009-11-17 02:16:21 +0000117 llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
118 return BuildTypeRef(CGM.getContext().getTagDeclType(RD));
119 }
120
Mike Stump4c808df2009-11-15 03:28:10 +0000121 /// CalculateFlags - Calculate the flags for the __vmi_class_type_info
122 /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond
123 /// shaped class.
124 int CalculateFlags(const CXXRecordDecl*RD) {
125 int flags = 0;
126 if (SeenBase.count(RD))
127 flags |= 1;
128 else
129 SeenBase.insert(RD);
130 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
131 e = RD->bases_end(); i != e; ++i) {
132 const CXXRecordDecl *Base =
133 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
134 if (i->isVirtual()) {
135 if (SeenVBase.count(Base))
136 flags |= 2;
137 else
138 SeenVBase.insert(Base);
139 }
140 flags |= CalculateFlags(Base);
141 }
142 return flags;
143 }
144
145 bool SimpleInheritance(const CXXRecordDecl *RD) {
146 if (RD->getNumBases() != 1)
147 return false;
148 CXXRecordDecl::base_class_const_iterator i = RD->bases_begin();
149 if (i->isVirtual())
150 return false;
151 if (i->getAccessSpecifier() != AS_public)
152 return false;
153
154 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
155 const CXXRecordDecl *Base =
156 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
157 if (Layout.getBaseClassOffset(Base) != 0)
158 return false;
159 return true;
160 }
161
Mike Stump96b96d52009-11-17 23:11:22 +0000162 llvm::Constant *finish(std::vector<llvm::Constant *> &info,
163 llvm::GlobalVariable *GV,
Mike Stump1a139f82009-11-19 01:08:19 +0000164 llvm::StringRef Name, bool Hidden, bool Extern) {
Mike Stump96b96d52009-11-17 23:11:22 +0000165 llvm::GlobalVariable::LinkageTypes linktype;
166 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump1a139f82009-11-19 01:08:19 +0000167 if (!Extern)
168 linktype = llvm::GlobalValue::InternalLinkage;
Mike Stumpf5b28692009-11-14 23:32:21 +0000169
Mike Stump96b96d52009-11-17 23:11:22 +0000170 llvm::Constant *C;
171 C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
172
Mike Stump1a139f82009-11-19 01:08:19 +0000173 llvm::GlobalVariable *OGV = GV;
174 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
175 C, Name);
176 if (OGV) {
Mike Stump96b96d52009-11-17 23:11:22 +0000177 GV->takeName(OGV);
178 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
179 OGV->getType());
180 OGV->replaceAllUsesWith(NewPtr);
181 OGV->eraseFromParent();
182 }
Mike Stump83d5e002009-11-18 03:46:51 +0000183 if (Hidden)
Mike Stumpc5d2ed72009-11-18 03:21:29 +0000184 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
Mike Stump96b96d52009-11-17 23:11:22 +0000185 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
186 }
187
188
189 llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) {
Mike Stumpc01c2b82009-12-02 18:57:08 +0000190 if (!CGM.getContext().getLangOptions().RTTI)
Mike Stumpf5b28692009-11-14 23:32:21 +0000191 return llvm::Constant::getNullValue(Int8PtrTy);
192
Mike Stump96b96d52009-11-17 23:11:22 +0000193 llvm::Constant *C;
194
Mike Stumpf5b28692009-11-14 23:32:21 +0000195 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000196 CGM.getMangleContext().mangleCXXRTTI(CGM.getContext().getTagDeclType(RD),
Daniel Dunbare128dd12009-11-21 09:06:22 +0000197 OutName);
198 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000199
200 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000201 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000202 if (GV && !GV->isDeclaration())
203 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
204
Mike Stump1acec6a2009-11-14 15:55:18 +0000205 std::vector<llvm::Constant *> info;
206
Mike Stump83d5e002009-11-18 03:46:51 +0000207 bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
Mike Stump1a139f82009-11-19 01:08:19 +0000208 bool Extern = !RD->isInAnonymousNamespace();
Mike Stump83d5e002009-11-18 03:46:51 +0000209
Mike Stump4c808df2009-11-15 03:28:10 +0000210 bool simple = false;
Mike Stumpf5b28692009-11-14 23:32:21 +0000211 if (RD->getNumBases() == 0)
212 C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
Mike Stump4c808df2009-11-15 03:28:10 +0000213 else if (SimpleInheritance(RD)) {
214 simple = true;
215 C = BuildVtableRef("_ZTVN10__cxxabiv120__si_class_type_infoE");
216 } else
Mike Stumpf5b28692009-11-14 23:32:21 +0000217 C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
218 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000219 info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
220 Extern));
Mike Stump1acec6a2009-11-14 15:55:18 +0000221
Mike Stumpf5b28692009-11-14 23:32:21 +0000222 // If we have no bases, there are no more fields.
223 if (RD->getNumBases()) {
Mike Stump4c808df2009-11-15 03:28:10 +0000224 if (!simple) {
225 info.push_back(BuildFlags(CalculateFlags(RD)));
226 info.push_back(BuildBaseCount(RD->getNumBases()));
227 }
Mike Stumpf5b28692009-11-14 23:32:21 +0000228
229 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
230 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
231 e = RD->bases_end(); i != e; ++i) {
232 const CXXRecordDecl *Base =
233 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Mike Stumpafe47642009-12-04 20:55:13 +0000234 if (Base->isPolymorphic())
235 info.push_back(CGM.GenerateRTTIRef(Base));
236 else
237 info.push_back(CGM.GenerateRTTI(Base));
Mike Stump4c808df2009-11-15 03:28:10 +0000238 if (simple)
239 break;
Mike Stumpf5b28692009-11-14 23:32:21 +0000240 int64_t offset;
241 if (!i->isVirtual())
Mike Stump4c808df2009-11-15 03:28:10 +0000242 offset = Layout.getBaseClassOffset(Base)/8;
Mike Stumpf5b28692009-11-14 23:32:21 +0000243 else
244 offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
245 offset <<= 8;
246 // Now set the flags.
247 offset += i->isVirtual() ? 1 : 0;;
248 offset += i->getAccessSpecifier() == AS_public ? 2 : 0;
249 const llvm::Type *LongTy =
250 CGM.getTypes().ConvertType(CGM.getContext().LongTy);
251 C = llvm::ConstantInt::get(LongTy, offset);
252 info.push_back(C);
253 }
254 }
255
Mike Stump1a139f82009-11-19 01:08:19 +0000256 return finish(info, GV, Name, Hidden, Extern);
Mike Stump1acec6a2009-11-14 15:55:18 +0000257 }
Mike Stump3f75d552009-11-17 02:16:21 +0000258
Mike Stumpdb72c892009-11-17 21:44:24 +0000259 /// - BuildFlags - Build a __flags value for __pbase_type_info.
260 llvm::Constant *BuildInt(int f) {
261 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
262 }
263
Mike Stump1a139f82009-11-19 01:08:19 +0000264 bool DecideExtern(QualType Ty) {
265 // For this type, see if all components are never in an anonymous namespace.
266 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
267 return (DecideExtern(MPT->getPointeeType())
268 && DecideExtern(QualType(MPT->getClass(), 0)));
269 if (const PointerType *PT = Ty->getAs<PointerType>())
270 return DecideExtern(PT->getPointeeType());
271 if (const RecordType *RT = Ty->getAs<RecordType>())
272 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
273 return !RD->isInAnonymousNamespace();
274 return true;
275 }
276
277 bool DecideHidden(QualType Ty) {
278 // For this type, see if all components are never hidden.
279 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
280 return (DecideHidden(MPT->getPointeeType())
281 && DecideHidden(QualType(MPT->getClass(), 0)));
282 if (const PointerType *PT = Ty->getAs<PointerType>())
283 return DecideHidden(PT->getPointeeType());
284 if (const RecordType *RT = Ty->getAs<RecordType>())
285 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
286 return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
287 return false;
288 }
289
Mike Stumpdb72c892009-11-17 21:44:24 +0000290 llvm::Constant *BuildPointerType(QualType Ty) {
Mike Stumpdb72c892009-11-17 21:44:24 +0000291 llvm::Constant *C;
292
293 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000294 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000295 llvm::StringRef Name = OutName.str();
Mike Stumpdb72c892009-11-17 21:44:24 +0000296
297 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000298 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpdb72c892009-11-17 21:44:24 +0000299 if (GV && !GV->isDeclaration())
300 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
301
Mike Stumpdb72c892009-11-17 21:44:24 +0000302 std::vector<llvm::Constant *> info;
303
Mike Stump1a139f82009-11-19 01:08:19 +0000304 bool Extern = DecideExtern(Ty);
305 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000306
Mike Stumpdb72c892009-11-17 21:44:24 +0000307 QualType PTy = Ty->getPointeeType();
Mike Stumpdb72c892009-11-17 21:44:24 +0000308 QualType BTy;
Mike Stumpdb72c892009-11-17 21:44:24 +0000309 bool PtrMem = false;
Mike Stump6fdfea62009-11-17 22:33:00 +0000310 if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(Ty)) {
311 PtrMem = true;
312 BTy = QualType(MPT->getClass(), 0);
313 PTy = MPT->getPointeeType();
314 }
Mike Stumpdb72c892009-11-17 21:44:24 +0000315
316 if (PtrMem)
317 C = BuildVtableRef("_ZTVN10__cxxabiv129__pointer_to_member_type_infoE");
318 else
319 C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
320 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000321 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stumpdb72c892009-11-17 21:44:24 +0000322 Qualifiers Q = PTy.getQualifiers();
323 PTy = CGM.getContext().getCanonicalType(PTy).getUnqualifiedType();
324 int flags = 0;
325 flags += Q.hasConst() ? 0x1 : 0;
326 flags += Q.hasVolatile() ? 0x2 : 0;
327 flags += Q.hasRestrict() ? 0x4 : 0;
328 flags += Ty.getTypePtr()->isIncompleteType() ? 0x8 : 0;
329 if (PtrMem && BTy.getTypePtr()->isIncompleteType())
330 flags += 0x10;
Mike Stump4aaf79a2009-11-17 23:51:10 +0000331
Mike Stumpdb72c892009-11-17 21:44:24 +0000332 info.push_back(BuildInt(flags));
333 info.push_back(BuildInt(0));
Mike Stump101f0522009-11-20 00:31:50 +0000334 info.push_back(BuildType(PTy));
Mike Stumpdb72c892009-11-17 21:44:24 +0000335
336 if (PtrMem)
Mike Stump101f0522009-11-20 00:31:50 +0000337 info.push_back(BuildType(BTy));
Mike Stump4aaf79a2009-11-17 23:51:10 +0000338
Mike Stump1a139f82009-11-19 01:08:19 +0000339 // We always generate these as hidden, only the name isn't hidden.
340 return finish(info, GV, Name, true, Extern);
Mike Stump96b96d52009-11-17 23:11:22 +0000341 }
Mike Stumpdb72c892009-11-17 21:44:24 +0000342
Mike Stump103a0842009-11-17 23:45:57 +0000343 llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
Mike Stump96b96d52009-11-17 23:11:22 +0000344 llvm::Constant *C;
345
346 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000347 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000348 llvm::StringRef Name = OutName.str();
Mike Stump96b96d52009-11-17 23:11:22 +0000349
350 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000351 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump96b96d52009-11-17 23:11:22 +0000352 if (GV && !GV->isDeclaration())
353 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
354
355 std::vector<llvm::Constant *> info;
356
Mike Stump1a139f82009-11-19 01:08:19 +0000357 bool Extern = DecideExtern(Ty);
358 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000359
Mike Stump103a0842009-11-17 23:45:57 +0000360 C = BuildVtableRef(vtbl);
Mike Stump96b96d52009-11-17 23:11:22 +0000361 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000362 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stump4aaf79a2009-11-17 23:51:10 +0000363
Mike Stump1a139f82009-11-19 01:08:19 +0000364 // We always generate these as hidden, only the name isn't hidden.
365 return finish(info, GV, Name, true, Extern);
Mike Stumpdb72c892009-11-17 21:44:24 +0000366 }
367
Mike Stump3f75d552009-11-17 02:16:21 +0000368 llvm::Constant *BuildType(QualType Ty) {
369 const clang::Type &Type
370 = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
Mike Stump101f0522009-11-20 00:31:50 +0000371
372 if (const RecordType *RT = Ty.getTypePtr()->getAs<RecordType>())
373 if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()))
374 return Buildclass_type_info(RD);
375
Mike Stump3f75d552009-11-17 02:16:21 +0000376 switch (Type.getTypeClass()) {
377 default: {
Mike Stump3f75d552009-11-17 02:16:21 +0000378 assert(0 && "typeid expression");
Mike Stump3f75d552009-11-17 02:16:21 +0000379 return llvm::Constant::getNullValue(Int8PtrTy);
380 }
381
382 case Type::Builtin: {
383 // We expect all type_info objects for builtin types to be in the library.
384 return BuildTypeRef(Ty);
385 }
Mike Stump8f5e6772009-11-17 02:57:13 +0000386
387 case Type::Pointer: {
388 QualType PTy = Ty->getPointeeType();
389 Qualifiers Q = PTy.getQualifiers();
390 Q.removeConst();
391 // T* and const T* for all builtin types T are expected in the library.
392 if (isa<BuiltinType>(PTy) && Q.empty())
393 return BuildTypeRef(Ty);
394
Mike Stumpdb72c892009-11-17 21:44:24 +0000395 return BuildPointerType(Ty);
Mike Stump8f5e6772009-11-17 02:57:13 +0000396 }
Mike Stump6fdfea62009-11-17 22:33:00 +0000397 case Type::MemberPointer:
398 return BuildPointerType(Ty);
Mike Stump96b96d52009-11-17 23:11:22 +0000399 case Type::FunctionProto:
Mike Stump103a0842009-11-17 23:45:57 +0000400 case Type::FunctionNoProto:
401 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv120__function_type_infoE");
402 case Type::ConstantArray:
403 case Type::IncompleteArray:
404 case Type::VariableArray:
405 case Type::Vector:
406 case Type::ExtVector:
407 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
408 case Type::Enum:
409 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv116__enum_type_infoE");
Mike Stump3f75d552009-11-17 02:16:21 +0000410 }
411 }
Mike Stump14718422009-11-14 14:25:18 +0000412};
Mike Stumpae1b85d2009-12-02 19:07:44 +0000413}
Mike Stump14718422009-11-14 14:25:18 +0000414
Mike Stumpc01c2b82009-12-02 18:57:08 +0000415llvm::Constant *CodeGenModule::GenerateRTTIRef(const CXXRecordDecl *RD) {
416 RTTIBuilder b(*this);
Mike Stumpf5b28692009-11-14 23:32:21 +0000417
418 return b.Buildclass_type_infoRef(RD);
419}
420
Mike Stumpc01c2b82009-12-02 18:57:08 +0000421llvm::Constant *CodeGenModule::GenerateRTTI(const CXXRecordDecl *RD) {
422 RTTIBuilder b(*this);
Mike Stump14718422009-11-14 14:25:18 +0000423
Mike Stumpf5b28692009-11-14 23:32:21 +0000424 return b.Buildclass_type_info(RD);
Anders Carlsson6ce51fd2009-10-10 20:49:04 +0000425}
Mike Stump3f75d552009-11-17 02:16:21 +0000426
Mike Stumpc01c2b82009-12-02 18:57:08 +0000427llvm::Constant *CodeGenModule::GenerateRTTI(QualType Ty) {
428 RTTIBuilder b(*this);
Mike Stump3f75d552009-11-17 02:16:21 +0000429
430 return b.BuildType(Ty);
431}