blob: f52c6586d76fea57f3359f72eb6afe90b50ac8c4 [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 Stumpc01c2b82009-12-02 18:57:08 +000020class RTTIBuilder {
Mike Stump14718422009-11-14 14:25:18 +000021 CodeGenModule &CGM; // Per-module state.
22 llvm::LLVMContext &VMContext;
23 const llvm::Type *Int8PtrTy;
Mike Stump4c808df2009-11-15 03:28:10 +000024 llvm::SmallSet<const CXXRecordDecl *, 16> SeenVBase;
25 llvm::SmallSet<const CXXRecordDecl *, 32> SeenBase;
Mike Stump14718422009-11-14 14:25:18 +000026public:
Mike Stumpc01c2b82009-12-02 18:57:08 +000027 RTTIBuilder(CodeGenModule &cgm)
Mike Stump14718422009-11-14 14:25:18 +000028 : CGM(cgm), VMContext(cgm.getModule().getContext()),
29 Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
30
Mike Stumpf5b28692009-11-14 23:32:21 +000031 /// BuildVtableRef - Build a reference to a vtable.
32 llvm::Constant *BuildVtableRef(const char *Name) {
33 // Build a descriptor for Name
Mike Stump1acec6a2009-11-14 15:55:18 +000034 llvm::Constant *GV = CGM.getModule().getGlobalVariable(Name);
35 if (GV)
36 GV = llvm::ConstantExpr::getBitCast(GV,
37 llvm::PointerType::get(Int8PtrTy, 0));
38 else {
39 llvm::GlobalVariable::LinkageTypes linktype;
40 linktype = llvm::GlobalValue::ExternalLinkage;
41 GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy,
42 true, linktype, 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +000043 }
Mike Stump1acec6a2009-11-14 15:55:18 +000044 llvm::Constant *C;
45 C = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 2);
46 C = llvm::ConstantExpr::getInBoundsGetElementPtr(GV, &C, 1);
47 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
48 }
Mike Stumpf5b28692009-11-14 23:32:21 +000049
Mike Stump1a139f82009-11-19 01:08:19 +000050 llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
Mike Stump14718422009-11-14 14:25:18 +000051 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +000052 CGM.getMangleContext().mangleCXXRTTIName(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +000053 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +000054
Mike Stump14718422009-11-14 14:25:18 +000055 llvm::GlobalVariable::LinkageTypes linktype;
56 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump1a139f82009-11-19 01:08:19 +000057 if (!Extern)
58 linktype = llvm::GlobalValue::InternalLinkage;
59
60 llvm::GlobalVariable *GV;
61 GV = CGM.getModule().getGlobalVariable(Name);
62 if (GV && !GV->isDeclaration())
63 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump14718422009-11-14 14:25:18 +000064
65 llvm::Constant *C;
Mike Stump1a139f82009-11-19 01:08:19 +000066 C = llvm::ConstantArray::get(VMContext, Name.substr(4));
Mike Stumpf5b28692009-11-14 23:32:21 +000067
Mike Stump1a139f82009-11-19 01:08:19 +000068 llvm::GlobalVariable *OGV = GV;
69 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
70 C, Name);
71 if (OGV) {
72 GV->takeName(OGV);
73 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
74 OGV->getType());
75 OGV->replaceAllUsesWith(NewPtr);
76 OGV->eraseFromParent();
77 }
Mike Stump83d5e002009-11-18 03:46:51 +000078 if (Hidden)
79 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
80 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump14718422009-11-14 14:25:18 +000081 };
Mike Stump1acec6a2009-11-14 15:55:18 +000082
Mike Stumpf5b28692009-11-14 23:32:21 +000083 /// - BuildFlags - Build a psABI __flags value for __vmi_class_type_info.
84 llvm::Constant *BuildFlags(int f) {
85 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
86 }
87
88 /// BuildBaseCount - Build a psABI __base_count value for
89 /// __vmi_class_type_info.
90 llvm::Constant *BuildBaseCount(unsigned c) {
91 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), c);
92 }
93
Mike Stump3f75d552009-11-17 02:16:21 +000094 llvm::Constant *BuildTypeRef(QualType Ty) {
Mike Stumpf5b28692009-11-14 23:32:21 +000095 llvm::Constant *C;
Mike Stump1acec6a2009-11-14 15:55:18 +000096
Mike Stumpc01c2b82009-12-02 18:57:08 +000097 if (!CGM.getContext().getLangOptions().RTTI)
Mike Stump1acec6a2009-11-14 15:55:18 +000098 return llvm::Constant::getNullValue(Int8PtrTy);
99
100 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000101 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000102 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000103
Mike Stump1a139f82009-11-19 01:08:19 +0000104 C = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000105 if (C)
106 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
107
108 llvm::GlobalVariable::LinkageTypes linktype;
109 linktype = llvm::GlobalValue::ExternalLinkage;;
110
111 C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
Mike Stump1a139f82009-11-19 01:08:19 +0000112 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000113 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
114 }
115
Mike Stump3f75d552009-11-17 02:16:21 +0000116 llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
117 return BuildTypeRef(CGM.getContext().getTagDeclType(RD));
118 }
119
Mike Stump4c808df2009-11-15 03:28:10 +0000120 /// CalculateFlags - Calculate the flags for the __vmi_class_type_info
121 /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond
122 /// shaped class.
123 int CalculateFlags(const CXXRecordDecl*RD) {
124 int flags = 0;
125 if (SeenBase.count(RD))
126 flags |= 1;
127 else
128 SeenBase.insert(RD);
129 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
130 e = RD->bases_end(); i != e; ++i) {
131 const CXXRecordDecl *Base =
132 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
133 if (i->isVirtual()) {
134 if (SeenVBase.count(Base))
135 flags |= 2;
136 else
137 SeenVBase.insert(Base);
138 }
139 flags |= CalculateFlags(Base);
140 }
141 return flags;
142 }
143
144 bool SimpleInheritance(const CXXRecordDecl *RD) {
145 if (RD->getNumBases() != 1)
146 return false;
147 CXXRecordDecl::base_class_const_iterator i = RD->bases_begin();
148 if (i->isVirtual())
149 return false;
150 if (i->getAccessSpecifier() != AS_public)
151 return false;
152
153 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
154 const CXXRecordDecl *Base =
155 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
156 if (Layout.getBaseClassOffset(Base) != 0)
157 return false;
158 return true;
159 }
160
Mike Stump96b96d52009-11-17 23:11:22 +0000161 llvm::Constant *finish(std::vector<llvm::Constant *> &info,
162 llvm::GlobalVariable *GV,
Mike Stump1a139f82009-11-19 01:08:19 +0000163 llvm::StringRef Name, bool Hidden, bool Extern) {
Mike Stump96b96d52009-11-17 23:11:22 +0000164 llvm::GlobalVariable::LinkageTypes linktype;
165 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump1a139f82009-11-19 01:08:19 +0000166 if (!Extern)
167 linktype = llvm::GlobalValue::InternalLinkage;
Mike Stumpf5b28692009-11-14 23:32:21 +0000168
Mike Stump96b96d52009-11-17 23:11:22 +0000169 llvm::Constant *C;
170 C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
171
Mike Stump1a139f82009-11-19 01:08:19 +0000172 llvm::GlobalVariable *OGV = GV;
173 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
174 C, Name);
175 if (OGV) {
Mike Stump96b96d52009-11-17 23:11:22 +0000176 GV->takeName(OGV);
177 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
178 OGV->getType());
179 OGV->replaceAllUsesWith(NewPtr);
180 OGV->eraseFromParent();
181 }
Mike Stump83d5e002009-11-18 03:46:51 +0000182 if (Hidden)
Mike Stumpc5d2ed72009-11-18 03:21:29 +0000183 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
Mike Stump96b96d52009-11-17 23:11:22 +0000184 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
185 }
186
187
188 llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) {
Mike Stumpc01c2b82009-12-02 18:57:08 +0000189 if (!CGM.getContext().getLangOptions().RTTI)
Mike Stumpf5b28692009-11-14 23:32:21 +0000190 return llvm::Constant::getNullValue(Int8PtrTy);
191
Mike Stump96b96d52009-11-17 23:11:22 +0000192 llvm::Constant *C;
193
Mike Stumpf5b28692009-11-14 23:32:21 +0000194 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000195 CGM.getMangleContext().mangleCXXRTTI(CGM.getContext().getTagDeclType(RD),
Daniel Dunbare128dd12009-11-21 09:06:22 +0000196 OutName);
197 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000198
199 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000200 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000201 if (GV && !GV->isDeclaration())
202 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
203
Mike Stump1acec6a2009-11-14 15:55:18 +0000204 std::vector<llvm::Constant *> info;
205
Mike Stump83d5e002009-11-18 03:46:51 +0000206 bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
Mike Stump1a139f82009-11-19 01:08:19 +0000207 bool Extern = !RD->isInAnonymousNamespace();
Mike Stump83d5e002009-11-18 03:46:51 +0000208
Mike Stump4c808df2009-11-15 03:28:10 +0000209 bool simple = false;
Mike Stumpf5b28692009-11-14 23:32:21 +0000210 if (RD->getNumBases() == 0)
211 C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
Mike Stump4c808df2009-11-15 03:28:10 +0000212 else if (SimpleInheritance(RD)) {
213 simple = true;
214 C = BuildVtableRef("_ZTVN10__cxxabiv120__si_class_type_infoE");
215 } else
Mike Stumpf5b28692009-11-14 23:32:21 +0000216 C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
217 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000218 info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
219 Extern));
Mike Stump1acec6a2009-11-14 15:55:18 +0000220
Mike Stumpf5b28692009-11-14 23:32:21 +0000221 // If we have no bases, there are no more fields.
222 if (RD->getNumBases()) {
Mike Stump4c808df2009-11-15 03:28:10 +0000223 if (!simple) {
224 info.push_back(BuildFlags(CalculateFlags(RD)));
225 info.push_back(BuildBaseCount(RD->getNumBases()));
226 }
Mike Stumpf5b28692009-11-14 23:32:21 +0000227
228 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
229 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
230 e = RD->bases_end(); i != e; ++i) {
231 const CXXRecordDecl *Base =
232 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Mike Stumpc01c2b82009-12-02 18:57:08 +0000233 info.push_back(CGM.GenerateRTTIRef(Base));
Mike Stump4c808df2009-11-15 03:28:10 +0000234 if (simple)
235 break;
Mike Stumpf5b28692009-11-14 23:32:21 +0000236 int64_t offset;
237 if (!i->isVirtual())
Mike Stump4c808df2009-11-15 03:28:10 +0000238 offset = Layout.getBaseClassOffset(Base)/8;
Mike Stumpf5b28692009-11-14 23:32:21 +0000239 else
240 offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
241 offset <<= 8;
242 // Now set the flags.
243 offset += i->isVirtual() ? 1 : 0;;
244 offset += i->getAccessSpecifier() == AS_public ? 2 : 0;
245 const llvm::Type *LongTy =
246 CGM.getTypes().ConvertType(CGM.getContext().LongTy);
247 C = llvm::ConstantInt::get(LongTy, offset);
248 info.push_back(C);
249 }
250 }
251
Mike Stump1a139f82009-11-19 01:08:19 +0000252 return finish(info, GV, Name, Hidden, Extern);
Mike Stump1acec6a2009-11-14 15:55:18 +0000253 }
Mike Stump3f75d552009-11-17 02:16:21 +0000254
Mike Stumpdb72c892009-11-17 21:44:24 +0000255 /// - BuildFlags - Build a __flags value for __pbase_type_info.
256 llvm::Constant *BuildInt(int f) {
257 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
258 }
259
Mike Stump1a139f82009-11-19 01:08:19 +0000260 bool DecideExtern(QualType Ty) {
261 // For this type, see if all components are never in an anonymous namespace.
262 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
263 return (DecideExtern(MPT->getPointeeType())
264 && DecideExtern(QualType(MPT->getClass(), 0)));
265 if (const PointerType *PT = Ty->getAs<PointerType>())
266 return DecideExtern(PT->getPointeeType());
267 if (const RecordType *RT = Ty->getAs<RecordType>())
268 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
269 return !RD->isInAnonymousNamespace();
270 return true;
271 }
272
273 bool DecideHidden(QualType Ty) {
274 // For this type, see if all components are never hidden.
275 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
276 return (DecideHidden(MPT->getPointeeType())
277 && DecideHidden(QualType(MPT->getClass(), 0)));
278 if (const PointerType *PT = Ty->getAs<PointerType>())
279 return DecideHidden(PT->getPointeeType());
280 if (const RecordType *RT = Ty->getAs<RecordType>())
281 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
282 return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
283 return false;
284 }
285
Mike Stumpdb72c892009-11-17 21:44:24 +0000286 llvm::Constant *BuildPointerType(QualType Ty) {
Mike Stumpdb72c892009-11-17 21:44:24 +0000287 llvm::Constant *C;
288
289 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000290 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000291 llvm::StringRef Name = OutName.str();
Mike Stumpdb72c892009-11-17 21:44:24 +0000292
293 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000294 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpdb72c892009-11-17 21:44:24 +0000295 if (GV && !GV->isDeclaration())
296 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
297
Mike Stumpdb72c892009-11-17 21:44:24 +0000298 std::vector<llvm::Constant *> info;
299
Mike Stump1a139f82009-11-19 01:08:19 +0000300 bool Extern = DecideExtern(Ty);
301 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000302
Mike Stumpdb72c892009-11-17 21:44:24 +0000303 QualType PTy = Ty->getPointeeType();
Mike Stumpdb72c892009-11-17 21:44:24 +0000304 QualType BTy;
Mike Stumpdb72c892009-11-17 21:44:24 +0000305 bool PtrMem = false;
Mike Stump6fdfea62009-11-17 22:33:00 +0000306 if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(Ty)) {
307 PtrMem = true;
308 BTy = QualType(MPT->getClass(), 0);
309 PTy = MPT->getPointeeType();
310 }
Mike Stumpdb72c892009-11-17 21:44:24 +0000311
312 if (PtrMem)
313 C = BuildVtableRef("_ZTVN10__cxxabiv129__pointer_to_member_type_infoE");
314 else
315 C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
316 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000317 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stumpdb72c892009-11-17 21:44:24 +0000318 Qualifiers Q = PTy.getQualifiers();
319 PTy = CGM.getContext().getCanonicalType(PTy).getUnqualifiedType();
320 int flags = 0;
321 flags += Q.hasConst() ? 0x1 : 0;
322 flags += Q.hasVolatile() ? 0x2 : 0;
323 flags += Q.hasRestrict() ? 0x4 : 0;
324 flags += Ty.getTypePtr()->isIncompleteType() ? 0x8 : 0;
325 if (PtrMem && BTy.getTypePtr()->isIncompleteType())
326 flags += 0x10;
Mike Stump4aaf79a2009-11-17 23:51:10 +0000327
Mike Stumpdb72c892009-11-17 21:44:24 +0000328 info.push_back(BuildInt(flags));
329 info.push_back(BuildInt(0));
Mike Stump101f0522009-11-20 00:31:50 +0000330 info.push_back(BuildType(PTy));
Mike Stumpdb72c892009-11-17 21:44:24 +0000331
332 if (PtrMem)
Mike Stump101f0522009-11-20 00:31:50 +0000333 info.push_back(BuildType(BTy));
Mike Stump4aaf79a2009-11-17 23:51:10 +0000334
Mike Stump1a139f82009-11-19 01:08:19 +0000335 // We always generate these as hidden, only the name isn't hidden.
336 return finish(info, GV, Name, true, Extern);
Mike Stump96b96d52009-11-17 23:11:22 +0000337 }
Mike Stumpdb72c892009-11-17 21:44:24 +0000338
Mike Stump103a0842009-11-17 23:45:57 +0000339 llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
Mike Stump96b96d52009-11-17 23:11:22 +0000340 llvm::Constant *C;
341
342 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000343 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000344 llvm::StringRef Name = OutName.str();
Mike Stump96b96d52009-11-17 23:11:22 +0000345
346 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000347 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump96b96d52009-11-17 23:11:22 +0000348 if (GV && !GV->isDeclaration())
349 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
350
351 std::vector<llvm::Constant *> info;
352
Mike Stump1a139f82009-11-19 01:08:19 +0000353 bool Extern = DecideExtern(Ty);
354 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000355
Mike Stump103a0842009-11-17 23:45:57 +0000356 C = BuildVtableRef(vtbl);
Mike Stump96b96d52009-11-17 23:11:22 +0000357 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000358 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stump4aaf79a2009-11-17 23:51:10 +0000359
Mike Stump1a139f82009-11-19 01:08:19 +0000360 // We always generate these as hidden, only the name isn't hidden.
361 return finish(info, GV, Name, true, Extern);
Mike Stumpdb72c892009-11-17 21:44:24 +0000362 }
363
Mike Stump3f75d552009-11-17 02:16:21 +0000364 llvm::Constant *BuildType(QualType Ty) {
365 const clang::Type &Type
366 = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
Mike Stump101f0522009-11-20 00:31:50 +0000367
368 if (const RecordType *RT = Ty.getTypePtr()->getAs<RecordType>())
369 if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()))
370 return Buildclass_type_info(RD);
371
Mike Stump3f75d552009-11-17 02:16:21 +0000372 switch (Type.getTypeClass()) {
373 default: {
Mike Stump3f75d552009-11-17 02:16:21 +0000374 assert(0 && "typeid expression");
Mike Stump3f75d552009-11-17 02:16:21 +0000375 return llvm::Constant::getNullValue(Int8PtrTy);
376 }
377
378 case Type::Builtin: {
379 // We expect all type_info objects for builtin types to be in the library.
380 return BuildTypeRef(Ty);
381 }
Mike Stump8f5e6772009-11-17 02:57:13 +0000382
383 case Type::Pointer: {
384 QualType PTy = Ty->getPointeeType();
385 Qualifiers Q = PTy.getQualifiers();
386 Q.removeConst();
387 // T* and const T* for all builtin types T are expected in the library.
388 if (isa<BuiltinType>(PTy) && Q.empty())
389 return BuildTypeRef(Ty);
390
Mike Stumpdb72c892009-11-17 21:44:24 +0000391 return BuildPointerType(Ty);
Mike Stump8f5e6772009-11-17 02:57:13 +0000392 }
Mike Stump6fdfea62009-11-17 22:33:00 +0000393 case Type::MemberPointer:
394 return BuildPointerType(Ty);
Mike Stump96b96d52009-11-17 23:11:22 +0000395 case Type::FunctionProto:
Mike Stump103a0842009-11-17 23:45:57 +0000396 case Type::FunctionNoProto:
397 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv120__function_type_infoE");
398 case Type::ConstantArray:
399 case Type::IncompleteArray:
400 case Type::VariableArray:
401 case Type::Vector:
402 case Type::ExtVector:
403 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
404 case Type::Enum:
405 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv116__enum_type_infoE");
Mike Stump3f75d552009-11-17 02:16:21 +0000406 }
407 }
Mike Stump14718422009-11-14 14:25:18 +0000408};
409
Mike Stumpc01c2b82009-12-02 18:57:08 +0000410llvm::Constant *CodeGenModule::GenerateRTTIRef(const CXXRecordDecl *RD) {
411 RTTIBuilder b(*this);
Mike Stumpf5b28692009-11-14 23:32:21 +0000412
413 return b.Buildclass_type_infoRef(RD);
414}
415
Mike Stumpc01c2b82009-12-02 18:57:08 +0000416llvm::Constant *CodeGenModule::GenerateRTTI(const CXXRecordDecl *RD) {
417 RTTIBuilder b(*this);
Mike Stump14718422009-11-14 14:25:18 +0000418
Mike Stumpf5b28692009-11-14 23:32:21 +0000419 return b.Buildclass_type_info(RD);
Anders Carlsson6ce51fd2009-10-10 20:49:04 +0000420}
Mike Stump3f75d552009-11-17 02:16:21 +0000421
Mike Stumpc01c2b82009-12-02 18:57:08 +0000422llvm::Constant *CodeGenModule::GenerateRTTI(QualType Ty) {
423 RTTIBuilder b(*this);
Mike Stump3f75d552009-11-17 02:16:21 +0000424
425 return b.BuildType(Ty);
426}