blob: 79d866427f0b839c5e6189e263af5f7550670b8c [file] [log] [blame]
Anders Carlsson6ce51fd2009-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 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 Stump14718422009-11-14 14:25:18 +000020class RttiBuilder {
21 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:
27 RttiBuilder(CodeGenModule &cgm)
28 : 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;
52 llvm::raw_svector_ostream Out(OutName);
Mike Stumpdb72c892009-11-17 21:44:24 +000053 mangleCXXRttiName(CGM.getMangleContext(), Ty, Out);
Mike Stump1a139f82009-11-19 01:08:19 +000054 llvm::StringRef Name = Out.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
98 if (!CGM.getContext().getLangOptions().Rtti)
99 return llvm::Constant::getNullValue(Int8PtrTy);
100
101 llvm::SmallString<256> OutName;
102 llvm::raw_svector_ostream Out(OutName);
Mike Stump3f75d552009-11-17 02:16:21 +0000103 mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
Mike Stump1a139f82009-11-19 01:08:19 +0000104 llvm::StringRef Name = Out.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000105
Mike Stump1a139f82009-11-19 01:08:19 +0000106 C = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000107 if (C)
108 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
109
110 llvm::GlobalVariable::LinkageTypes linktype;
111 linktype = llvm::GlobalValue::ExternalLinkage;;
112
113 C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
Mike Stump1a139f82009-11-19 01:08:19 +0000114 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000115 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
116 }
117
Mike Stump3f75d552009-11-17 02:16:21 +0000118 llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
119 return BuildTypeRef(CGM.getContext().getTagDeclType(RD));
120 }
121
Mike Stump4c808df2009-11-15 03:28:10 +0000122 /// CalculateFlags - Calculate the flags for the __vmi_class_type_info
123 /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond
124 /// shaped class.
125 int CalculateFlags(const CXXRecordDecl*RD) {
126 int flags = 0;
127 if (SeenBase.count(RD))
128 flags |= 1;
129 else
130 SeenBase.insert(RD);
131 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
132 e = RD->bases_end(); i != e; ++i) {
133 const CXXRecordDecl *Base =
134 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
135 if (i->isVirtual()) {
136 if (SeenVBase.count(Base))
137 flags |= 2;
138 else
139 SeenVBase.insert(Base);
140 }
141 flags |= CalculateFlags(Base);
142 }
143 return flags;
144 }
145
146 bool SimpleInheritance(const CXXRecordDecl *RD) {
147 if (RD->getNumBases() != 1)
148 return false;
149 CXXRecordDecl::base_class_const_iterator i = RD->bases_begin();
150 if (i->isVirtual())
151 return false;
152 if (i->getAccessSpecifier() != AS_public)
153 return false;
154
155 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
156 const CXXRecordDecl *Base =
157 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
158 if (Layout.getBaseClassOffset(Base) != 0)
159 return false;
160 return true;
161 }
162
Mike Stump96b96d52009-11-17 23:11:22 +0000163 llvm::Constant *finish(std::vector<llvm::Constant *> &info,
164 llvm::GlobalVariable *GV,
Mike Stump1a139f82009-11-19 01:08:19 +0000165 llvm::StringRef Name, bool Hidden, bool Extern) {
Mike Stump96b96d52009-11-17 23:11:22 +0000166 llvm::GlobalVariable::LinkageTypes linktype;
167 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump1a139f82009-11-19 01:08:19 +0000168 if (!Extern)
169 linktype = llvm::GlobalValue::InternalLinkage;
Mike Stumpf5b28692009-11-14 23:32:21 +0000170
Mike Stump96b96d52009-11-17 23:11:22 +0000171 llvm::Constant *C;
172 C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
173
Mike Stump1a139f82009-11-19 01:08:19 +0000174 llvm::GlobalVariable *OGV = GV;
175 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
176 C, Name);
177 if (OGV) {
Mike Stump96b96d52009-11-17 23:11:22 +0000178 GV->takeName(OGV);
179 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
180 OGV->getType());
181 OGV->replaceAllUsesWith(NewPtr);
182 OGV->eraseFromParent();
183 }
Mike Stump83d5e002009-11-18 03:46:51 +0000184 if (Hidden)
Mike Stumpc5d2ed72009-11-18 03:21:29 +0000185 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
Mike Stump96b96d52009-11-17 23:11:22 +0000186 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
187 }
188
189
190 llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) {
Mike Stumpf5b28692009-11-14 23:32:21 +0000191 if (!CGM.getContext().getLangOptions().Rtti)
192 return llvm::Constant::getNullValue(Int8PtrTy);
193
Mike Stump96b96d52009-11-17 23:11:22 +0000194 llvm::Constant *C;
195
Mike Stumpf5b28692009-11-14 23:32:21 +0000196 llvm::SmallString<256> OutName;
197 llvm::raw_svector_ostream Out(OutName);
198 mangleCXXRtti(CGM.getMangleContext(), CGM.getContext().getTagDeclType(RD),
199 Out);
Mike Stump1a139f82009-11-19 01:08:19 +0000200 llvm::StringRef Name = Out.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000201
202 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000203 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000204 if (GV && !GV->isDeclaration())
205 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
206
Mike Stump1acec6a2009-11-14 15:55:18 +0000207 std::vector<llvm::Constant *> info;
208
Mike Stump83d5e002009-11-18 03:46:51 +0000209 bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
Mike Stump1a139f82009-11-19 01:08:19 +0000210 bool Extern = !RD->isInAnonymousNamespace();
Mike Stump83d5e002009-11-18 03:46:51 +0000211
Mike Stump4c808df2009-11-15 03:28:10 +0000212 bool simple = false;
Mike Stumpf5b28692009-11-14 23:32:21 +0000213 if (RD->getNumBases() == 0)
214 C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
Mike Stump4c808df2009-11-15 03:28:10 +0000215 else if (SimpleInheritance(RD)) {
216 simple = true;
217 C = BuildVtableRef("_ZTVN10__cxxabiv120__si_class_type_infoE");
218 } else
Mike Stumpf5b28692009-11-14 23:32:21 +0000219 C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
220 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000221 info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
222 Extern));
Mike Stump1acec6a2009-11-14 15:55:18 +0000223
Mike Stumpf5b28692009-11-14 23:32:21 +0000224 // If we have no bases, there are no more fields.
225 if (RD->getNumBases()) {
Mike Stump4c808df2009-11-15 03:28:10 +0000226 if (!simple) {
227 info.push_back(BuildFlags(CalculateFlags(RD)));
228 info.push_back(BuildBaseCount(RD->getNumBases()));
229 }
Mike Stumpf5b28692009-11-14 23:32:21 +0000230
231 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
232 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
233 e = RD->bases_end(); i != e; ++i) {
234 const CXXRecordDecl *Base =
235 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Mike Stump4c808df2009-11-15 03:28:10 +0000236 info.push_back(CGM.GenerateRttiRef(Base));
237 if (simple)
238 break;
Mike Stumpf5b28692009-11-14 23:32:21 +0000239 int64_t offset;
240 if (!i->isVirtual())
Mike Stump4c808df2009-11-15 03:28:10 +0000241 offset = Layout.getBaseClassOffset(Base)/8;
Mike Stumpf5b28692009-11-14 23:32:21 +0000242 else
243 offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
244 offset <<= 8;
245 // Now set the flags.
246 offset += i->isVirtual() ? 1 : 0;;
247 offset += i->getAccessSpecifier() == AS_public ? 2 : 0;
248 const llvm::Type *LongTy =
249 CGM.getTypes().ConvertType(CGM.getContext().LongTy);
250 C = llvm::ConstantInt::get(LongTy, offset);
251 info.push_back(C);
252 }
253 }
254
Mike Stump1a139f82009-11-19 01:08:19 +0000255 return finish(info, GV, Name, Hidden, Extern);
Mike Stump1acec6a2009-11-14 15:55:18 +0000256 }
Mike Stump3f75d552009-11-17 02:16:21 +0000257
Mike Stumpdb72c892009-11-17 21:44:24 +0000258 /// - BuildFlags - Build a __flags value for __pbase_type_info.
259 llvm::Constant *BuildInt(int f) {
260 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
261 }
262
263 llvm::Constant *BuildType2(QualType Ty) {
264 if (const RecordType *RT = Ty.getTypePtr()->getAs<RecordType>())
265 if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()))
266 return Buildclass_type_info(RD);
267 return BuildType(Ty);
268 }
269
Mike Stump1a139f82009-11-19 01:08:19 +0000270 bool DecideExtern(QualType Ty) {
271 // For this type, see if all components are never in an anonymous namespace.
272 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
273 return (DecideExtern(MPT->getPointeeType())
274 && DecideExtern(QualType(MPT->getClass(), 0)));
275 if (const PointerType *PT = Ty->getAs<PointerType>())
276 return DecideExtern(PT->getPointeeType());
277 if (const RecordType *RT = Ty->getAs<RecordType>())
278 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
279 return !RD->isInAnonymousNamespace();
280 return true;
281 }
282
283 bool DecideHidden(QualType Ty) {
284 // For this type, see if all components are never hidden.
285 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
286 return (DecideHidden(MPT->getPointeeType())
287 && DecideHidden(QualType(MPT->getClass(), 0)));
288 if (const PointerType *PT = Ty->getAs<PointerType>())
289 return DecideHidden(PT->getPointeeType());
290 if (const RecordType *RT = Ty->getAs<RecordType>())
291 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
292 return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
293 return false;
294 }
295
Mike Stumpdb72c892009-11-17 21:44:24 +0000296 llvm::Constant *BuildPointerType(QualType Ty) {
Mike Stumpdb72c892009-11-17 21:44:24 +0000297 llvm::Constant *C;
298
299 llvm::SmallString<256> OutName;
300 llvm::raw_svector_ostream Out(OutName);
301 mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
Mike Stump1a139f82009-11-19 01:08:19 +0000302 llvm::StringRef Name = Out.str();
Mike Stumpdb72c892009-11-17 21:44:24 +0000303
304 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000305 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpdb72c892009-11-17 21:44:24 +0000306 if (GV && !GV->isDeclaration())
307 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
308
Mike Stumpdb72c892009-11-17 21:44:24 +0000309 std::vector<llvm::Constant *> info;
310
Mike Stump1a139f82009-11-19 01:08:19 +0000311 bool Extern = DecideExtern(Ty);
312 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000313
Mike Stumpdb72c892009-11-17 21:44:24 +0000314 QualType PTy = Ty->getPointeeType();
Mike Stumpdb72c892009-11-17 21:44:24 +0000315 QualType BTy;
Mike Stumpdb72c892009-11-17 21:44:24 +0000316 bool PtrMem = false;
Mike Stump6fdfea62009-11-17 22:33:00 +0000317 if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(Ty)) {
318 PtrMem = true;
319 BTy = QualType(MPT->getClass(), 0);
320 PTy = MPT->getPointeeType();
321 }
Mike Stumpdb72c892009-11-17 21:44:24 +0000322
323 if (PtrMem)
324 C = BuildVtableRef("_ZTVN10__cxxabiv129__pointer_to_member_type_infoE");
325 else
326 C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
327 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000328 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stumpdb72c892009-11-17 21:44:24 +0000329 Qualifiers Q = PTy.getQualifiers();
330 PTy = CGM.getContext().getCanonicalType(PTy).getUnqualifiedType();
331 int flags = 0;
332 flags += Q.hasConst() ? 0x1 : 0;
333 flags += Q.hasVolatile() ? 0x2 : 0;
334 flags += Q.hasRestrict() ? 0x4 : 0;
335 flags += Ty.getTypePtr()->isIncompleteType() ? 0x8 : 0;
336 if (PtrMem && BTy.getTypePtr()->isIncompleteType())
337 flags += 0x10;
Mike Stump4aaf79a2009-11-17 23:51:10 +0000338
Mike Stumpdb72c892009-11-17 21:44:24 +0000339 info.push_back(BuildInt(flags));
340 info.push_back(BuildInt(0));
341 info.push_back(BuildType2(PTy));
342
343 if (PtrMem)
344 info.push_back(BuildType2(BTy));
Mike Stump4aaf79a2009-11-17 23:51:10 +0000345
Mike Stump1a139f82009-11-19 01:08:19 +0000346 // We always generate these as hidden, only the name isn't hidden.
347 return finish(info, GV, Name, true, Extern);
Mike Stump96b96d52009-11-17 23:11:22 +0000348 }
Mike Stumpdb72c892009-11-17 21:44:24 +0000349
Mike Stump103a0842009-11-17 23:45:57 +0000350 llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
Mike Stump96b96d52009-11-17 23:11:22 +0000351 llvm::Constant *C;
352
353 llvm::SmallString<256> OutName;
354 llvm::raw_svector_ostream Out(OutName);
355 mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
Mike Stump1a139f82009-11-19 01:08:19 +0000356 llvm::StringRef Name = Out.str();
Mike Stump96b96d52009-11-17 23:11:22 +0000357
358 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000359 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump96b96d52009-11-17 23:11:22 +0000360 if (GV && !GV->isDeclaration())
361 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
362
363 std::vector<llvm::Constant *> info;
364
Mike Stump1a139f82009-11-19 01:08:19 +0000365 bool Extern = DecideExtern(Ty);
366 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000367
Mike Stump103a0842009-11-17 23:45:57 +0000368 C = BuildVtableRef(vtbl);
Mike Stump96b96d52009-11-17 23:11:22 +0000369 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000370 info.push_back(BuildName(Ty, Hidden, Extern));
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.
373 return finish(info, GV, Name, true, Extern);
Mike Stumpdb72c892009-11-17 21:44:24 +0000374 }
375
Mike Stump3f75d552009-11-17 02:16:21 +0000376 llvm::Constant *BuildType(QualType Ty) {
377 const clang::Type &Type
378 = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
379 switch (Type.getTypeClass()) {
380 default: {
Mike Stump3f75d552009-11-17 02:16:21 +0000381 assert(0 && "typeid expression");
Mike Stump3f75d552009-11-17 02:16:21 +0000382 return llvm::Constant::getNullValue(Int8PtrTy);
383 }
384
385 case Type::Builtin: {
386 // We expect all type_info objects for builtin types to be in the library.
387 return BuildTypeRef(Ty);
388 }
Mike Stump8f5e6772009-11-17 02:57:13 +0000389
390 case Type::Pointer: {
391 QualType PTy = Ty->getPointeeType();
392 Qualifiers Q = PTy.getQualifiers();
393 Q.removeConst();
394 // T* and const T* for all builtin types T are expected in the library.
395 if (isa<BuiltinType>(PTy) && Q.empty())
396 return BuildTypeRef(Ty);
397
Mike Stumpdb72c892009-11-17 21:44:24 +0000398 return BuildPointerType(Ty);
Mike Stump8f5e6772009-11-17 02:57:13 +0000399 }
Mike Stump6fdfea62009-11-17 22:33:00 +0000400 case Type::MemberPointer:
401 return BuildPointerType(Ty);
Mike Stump96b96d52009-11-17 23:11:22 +0000402 case Type::FunctionProto:
Mike Stump103a0842009-11-17 23:45:57 +0000403 case Type::FunctionNoProto:
404 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv120__function_type_infoE");
405 case Type::ConstantArray:
406 case Type::IncompleteArray:
407 case Type::VariableArray:
408 case Type::Vector:
409 case Type::ExtVector:
410 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
411 case Type::Enum:
412 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv116__enum_type_infoE");
Mike Stump3f75d552009-11-17 02:16:21 +0000413 }
414 }
Mike Stump14718422009-11-14 14:25:18 +0000415};
416
Mike Stumpf5b28692009-11-14 23:32:21 +0000417llvm::Constant *CodeGenModule::GenerateRttiRef(const CXXRecordDecl *RD) {
418 RttiBuilder b(*this);
419
420 return b.Buildclass_type_infoRef(RD);
421}
422
Anders Carlsson6ce51fd2009-10-10 20:49:04 +0000423llvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) {
Mike Stump14718422009-11-14 14:25:18 +0000424 RttiBuilder b(*this);
425
Mike Stumpf5b28692009-11-14 23:32:21 +0000426 return b.Buildclass_type_info(RD);
Anders Carlsson6ce51fd2009-10-10 20:49:04 +0000427}
Mike Stump3f75d552009-11-17 02:16:21 +0000428
429llvm::Constant *CodeGenModule::GenerateRttiNonClass(QualType Ty) {
430 RttiBuilder b(*this);
431
432 return b.BuildType(Ty);
433}