blob: 43fcb31858f8e8587d40cf945280f5f0bfe301f2 [file] [log] [blame]
Anders Carlsson656e4c12009-10-10 20:49:04 +00001//===--- CGCXXRtti.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
2//
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 Stump2b1bf312009-11-14 14:25:18 +000020class RttiBuilder {
21 CodeGenModule &CGM; // Per-module state.
22 llvm::LLVMContext &VMContext;
23 const llvm::Type *Int8PtrTy;
Mike Stumpa8285a82009-11-15 03:28:10 +000024 llvm::SmallSet<const CXXRecordDecl *, 16> SeenVBase;
25 llvm::SmallSet<const CXXRecordDecl *, 32> SeenBase;
Mike Stump2b1bf312009-11-14 14:25:18 +000026public:
27 RttiBuilder(CodeGenModule &cgm)
28 : CGM(cgm), VMContext(cgm.getModule().getContext()),
29 Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
30
Mike Stumpcbcd4e52009-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 Stumpc7a05bd2009-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 Stumpcbcd4e52009-11-14 23:32:21 +000043 }
Mike Stumpc7a05bd2009-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 Stumpcbcd4e52009-11-14 23:32:21 +000049
Mike Stump58588942009-11-19 01:08:19 +000050 llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
Mike Stump2b1bf312009-11-14 14:25:18 +000051 llvm::SmallString<256> OutName;
Daniel Dunbar94fd26d2009-11-21 09:06:22 +000052 CGM.getMangleContext().mangleCXXRttiName(Ty, OutName);
53 llvm::StringRef Name = OutName.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +000054
Mike Stump2b1bf312009-11-14 14:25:18 +000055 llvm::GlobalVariable::LinkageTypes linktype;
56 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump58588942009-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 Stump2b1bf312009-11-14 14:25:18 +000064
65 llvm::Constant *C;
Mike Stump58588942009-11-19 01:08:19 +000066 C = llvm::ConstantArray::get(VMContext, Name.substr(4));
Mike Stumpcbcd4e52009-11-14 23:32:21 +000067
Mike Stump58588942009-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 Stump582b0372009-11-18 03:46:51 +000078 if (Hidden)
79 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
80 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump2b1bf312009-11-14 14:25:18 +000081 };
Mike Stumpc7a05bd2009-11-14 15:55:18 +000082
Mike Stumpcbcd4e52009-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 Stumpea2c0b52009-11-17 02:16:21 +000094 llvm::Constant *BuildTypeRef(QualType Ty) {
Mike Stumpcbcd4e52009-11-14 23:32:21 +000095 llvm::Constant *C;
Mike Stumpc7a05bd2009-11-14 15:55:18 +000096
97 if (!CGM.getContext().getLangOptions().Rtti)
98 return llvm::Constant::getNullValue(Int8PtrTy);
99
100 llvm::SmallString<256> OutName;
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000101 CGM.getMangleContext().mangleCXXRtti(Ty, OutName);
102 llvm::StringRef Name = OutName.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000103
Mike Stump58588942009-11-19 01:08:19 +0000104 C = CGM.getModule().getGlobalVariable(Name);
Mike Stumpcbcd4e52009-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 Stump58588942009-11-19 01:08:19 +0000112 0, Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000113 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
114 }
115
Mike Stumpea2c0b52009-11-17 02:16:21 +0000116 llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
117 return BuildTypeRef(CGM.getContext().getTagDeclType(RD));
118 }
119
Mike Stumpa8285a82009-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 Stump64989f02009-11-17 23:11:22 +0000161 llvm::Constant *finish(std::vector<llvm::Constant *> &info,
162 llvm::GlobalVariable *GV,
Mike Stump58588942009-11-19 01:08:19 +0000163 llvm::StringRef Name, bool Hidden, bool Extern) {
Mike Stump64989f02009-11-17 23:11:22 +0000164 llvm::GlobalVariable::LinkageTypes linktype;
165 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump58588942009-11-19 01:08:19 +0000166 if (!Extern)
167 linktype = llvm::GlobalValue::InternalLinkage;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000168
Mike Stump64989f02009-11-17 23:11:22 +0000169 llvm::Constant *C;
170 C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
171
Mike Stump58588942009-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 Stump64989f02009-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 Stump582b0372009-11-18 03:46:51 +0000182 if (Hidden)
Mike Stump88a4a622009-11-18 03:21:29 +0000183 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
Mike Stump64989f02009-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 Stumpcbcd4e52009-11-14 23:32:21 +0000189 if (!CGM.getContext().getLangOptions().Rtti)
190 return llvm::Constant::getNullValue(Int8PtrTy);
191
Mike Stump64989f02009-11-17 23:11:22 +0000192 llvm::Constant *C;
193
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000194 llvm::SmallString<256> OutName;
Daniel Dunbar1b077112009-11-21 09:06:10 +0000195 CGM.getMangleContext().mangleCXXRtti(CGM.getContext().getTagDeclType(RD),
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000196 OutName);
197 llvm::StringRef Name = OutName.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000198
199 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000200 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000201 if (GV && !GV->isDeclaration())
202 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
203
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000204 std::vector<llvm::Constant *> info;
205
Mike Stump582b0372009-11-18 03:46:51 +0000206 bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
Mike Stump58588942009-11-19 01:08:19 +0000207 bool Extern = !RD->isInAnonymousNamespace();
Mike Stump582b0372009-11-18 03:46:51 +0000208
Mike Stumpa8285a82009-11-15 03:28:10 +0000209 bool simple = false;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000210 if (RD->getNumBases() == 0)
211 C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
Mike Stumpa8285a82009-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 Stumpcbcd4e52009-11-14 23:32:21 +0000216 C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
217 info.push_back(C);
Mike Stump58588942009-11-19 01:08:19 +0000218 info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
219 Extern));
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000220
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000221 // If we have no bases, there are no more fields.
222 if (RD->getNumBases()) {
Mike Stumpa8285a82009-11-15 03:28:10 +0000223 if (!simple) {
224 info.push_back(BuildFlags(CalculateFlags(RD)));
225 info.push_back(BuildBaseCount(RD->getNumBases()));
226 }
Mike Stumpcbcd4e52009-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 Stumpa8285a82009-11-15 03:28:10 +0000233 info.push_back(CGM.GenerateRttiRef(Base));
234 if (simple)
235 break;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000236 int64_t offset;
237 if (!i->isVirtual())
Mike Stumpa8285a82009-11-15 03:28:10 +0000238 offset = Layout.getBaseClassOffset(Base)/8;
Mike Stumpcbcd4e52009-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 Stump58588942009-11-19 01:08:19 +0000252 return finish(info, GV, Name, Hidden, Extern);
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000253 }
Mike Stumpea2c0b52009-11-17 02:16:21 +0000254
Mike Stump61c38012009-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 Stump58588942009-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 Stump61c38012009-11-17 21:44:24 +0000286 llvm::Constant *BuildPointerType(QualType Ty) {
Mike Stump61c38012009-11-17 21:44:24 +0000287 llvm::Constant *C;
288
289 llvm::SmallString<256> OutName;
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000290 CGM.getMangleContext().mangleCXXRtti(Ty, OutName);
291 llvm::StringRef Name = OutName.str();
Mike Stump61c38012009-11-17 21:44:24 +0000292
293 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000294 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump61c38012009-11-17 21:44:24 +0000295 if (GV && !GV->isDeclaration())
296 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
297
Mike Stump61c38012009-11-17 21:44:24 +0000298 std::vector<llvm::Constant *> info;
299
Mike Stump58588942009-11-19 01:08:19 +0000300 bool Extern = DecideExtern(Ty);
301 bool Hidden = DecideHidden(Ty);
Mike Stump582b0372009-11-18 03:46:51 +0000302
Mike Stump61c38012009-11-17 21:44:24 +0000303 QualType PTy = Ty->getPointeeType();
Mike Stump61c38012009-11-17 21:44:24 +0000304 QualType BTy;
Mike Stump61c38012009-11-17 21:44:24 +0000305 bool PtrMem = false;
Mike Stump5fae8562009-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 Stump61c38012009-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 Stump58588942009-11-19 01:08:19 +0000317 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stump61c38012009-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 Stump265df622009-11-17 23:51:10 +0000327
Mike Stump61c38012009-11-17 21:44:24 +0000328 info.push_back(BuildInt(flags));
329 info.push_back(BuildInt(0));
Mike Stump7e1365a2009-11-20 00:31:50 +0000330 info.push_back(BuildType(PTy));
Mike Stump61c38012009-11-17 21:44:24 +0000331
332 if (PtrMem)
Mike Stump7e1365a2009-11-20 00:31:50 +0000333 info.push_back(BuildType(BTy));
Mike Stump265df622009-11-17 23:51:10 +0000334
Mike Stump58588942009-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 Stump64989f02009-11-17 23:11:22 +0000337 }
Mike Stump61c38012009-11-17 21:44:24 +0000338
Mike Stumpae9b2be2009-11-17 23:45:57 +0000339 llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
Mike Stump64989f02009-11-17 23:11:22 +0000340 llvm::Constant *C;
341
342 llvm::SmallString<256> OutName;
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000343 CGM.getMangleContext().mangleCXXRtti(Ty, OutName);
344 llvm::StringRef Name = OutName.str();
Mike Stump64989f02009-11-17 23:11:22 +0000345
346 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000347 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump64989f02009-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 Stump58588942009-11-19 01:08:19 +0000353 bool Extern = DecideExtern(Ty);
354 bool Hidden = DecideHidden(Ty);
Mike Stump582b0372009-11-18 03:46:51 +0000355
Mike Stumpae9b2be2009-11-17 23:45:57 +0000356 C = BuildVtableRef(vtbl);
Mike Stump64989f02009-11-17 23:11:22 +0000357 info.push_back(C);
Mike Stump58588942009-11-19 01:08:19 +0000358 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stump265df622009-11-17 23:51:10 +0000359
Mike Stump58588942009-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 Stump61c38012009-11-17 21:44:24 +0000362 }
363
Mike Stumpea2c0b52009-11-17 02:16:21 +0000364 llvm::Constant *BuildType(QualType Ty) {
365 const clang::Type &Type
366 = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
Mike Stump7e1365a2009-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 Stumpea2c0b52009-11-17 02:16:21 +0000372 switch (Type.getTypeClass()) {
373 default: {
Mike Stumpea2c0b52009-11-17 02:16:21 +0000374 assert(0 && "typeid expression");
Mike Stumpea2c0b52009-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 Stump21f5d5d2009-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 Stump61c38012009-11-17 21:44:24 +0000391 return BuildPointerType(Ty);
Mike Stump21f5d5d2009-11-17 02:57:13 +0000392 }
Mike Stump5fae8562009-11-17 22:33:00 +0000393 case Type::MemberPointer:
394 return BuildPointerType(Ty);
Mike Stump64989f02009-11-17 23:11:22 +0000395 case Type::FunctionProto:
Mike Stumpae9b2be2009-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 Stumpea2c0b52009-11-17 02:16:21 +0000406 }
407 }
Mike Stump2b1bf312009-11-14 14:25:18 +0000408};
409
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000410llvm::Constant *CodeGenModule::GenerateRttiRef(const CXXRecordDecl *RD) {
411 RttiBuilder b(*this);
412
413 return b.Buildclass_type_infoRef(RD);
414}
415
Anders Carlsson656e4c12009-10-10 20:49:04 +0000416llvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) {
Mike Stump2b1bf312009-11-14 14:25:18 +0000417 RttiBuilder b(*this);
418
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000419 return b.Buildclass_type_info(RD);
Anders Carlsson656e4c12009-10-10 20:49:04 +0000420}
Mike Stumpea2c0b52009-11-17 02:16:21 +0000421
Mike Stump7e1365a2009-11-20 00:31:50 +0000422llvm::Constant *CodeGenModule::GenerateRtti(QualType Ty) {
Mike Stumpea2c0b52009-11-17 02:16:21 +0000423 RttiBuilder b(*this);
424
425 return b.BuildType(Ty);
426}