1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "CodeGenTypes.h" |
14 | #include "CGCXXABI.h" |
15 | #include "CGCall.h" |
16 | #include "CGOpenCLRuntime.h" |
17 | #include "CGRecordLayout.h" |
18 | #include "TargetInfo.h" |
19 | #include "clang/AST/ASTContext.h" |
20 | #include "clang/AST/DeclCXX.h" |
21 | #include "clang/AST/DeclObjC.h" |
22 | #include "clang/AST/Expr.h" |
23 | #include "clang/AST/RecordLayout.h" |
24 | #include "clang/CodeGen/CGFunctionInfo.h" |
25 | #include "llvm/IR/DataLayout.h" |
26 | #include "llvm/IR/DerivedTypes.h" |
27 | #include "llvm/IR/Module.h" |
28 | using namespace clang; |
29 | using namespace CodeGen; |
30 | |
31 | CodeGenTypes::CodeGenTypes(CodeGenModule &cgm) |
32 | : CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()), |
33 | Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()), |
34 | TheABIInfo(cgm.getTargetCodeGenInfo().getABIInfo()) { |
35 | SkippedLayout = false; |
36 | } |
37 | |
38 | CodeGenTypes::~CodeGenTypes() { |
39 | llvm::DeleteContainerSeconds(CGRecordLayouts); |
40 | |
41 | for (llvm::FoldingSet<CGFunctionInfo>::iterator |
42 | I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; ) |
43 | delete &*I++; |
44 | } |
45 | |
46 | const CodeGenOptions &CodeGenTypes::getCodeGenOpts() const { |
47 | return CGM.getCodeGenOpts(); |
48 | } |
49 | |
50 | void CodeGenTypes::addRecordTypeName(const RecordDecl *RD, |
51 | llvm::StructType *Ty, |
52 | StringRef suffix) { |
53 | SmallString<256> TypeName; |
54 | llvm::raw_svector_ostream OS(TypeName); |
55 | OS << RD->getKindName() << '.'; |
56 | |
57 | |
58 | |
59 | if (RD->getIdentifier()) { |
60 | |
61 | |
62 | if (RD->getDeclContext()) |
63 | RD->printQualifiedName(OS); |
64 | else |
65 | RD->printName(OS); |
66 | } else if (const TypedefNameDecl *TDD = RD->getTypedefNameForAnonDecl()) { |
67 | |
68 | |
69 | if (TDD->getDeclContext()) |
70 | TDD->printQualifiedName(OS); |
71 | else |
72 | TDD->printName(OS); |
73 | } else |
74 | OS << "anon"; |
75 | |
76 | if (!suffix.empty()) |
77 | OS << suffix; |
78 | |
79 | Ty->setName(OS.str()); |
80 | } |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) { |
87 | llvm::Type *R = ConvertType(T); |
88 | |
89 | |
90 | if (!R->isIntegerTy(1)) |
91 | return R; |
92 | |
93 | |
94 | return llvm::IntegerType::get(getLLVMContext(), |
95 | (unsigned)Context.getTypeSize(T)); |
96 | } |
97 | |
98 | |
99 | |
100 | |
101 | bool CodeGenTypes::isRecordLayoutComplete(const Type *Ty) const { |
102 | llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I = |
103 | RecordDeclTypes.find(Ty); |
104 | return I != RecordDeclTypes.end() && !I->second->isOpaque(); |
105 | } |
106 | |
107 | static bool |
108 | isSafeToConvert(QualType T, CodeGenTypes &CGT, |
109 | llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked); |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | static bool |
116 | isSafeToConvert(const RecordDecl *RD, CodeGenTypes &CGT, |
117 | llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) { |
118 | |
119 | |
120 | if (!AlreadyChecked.insert(RD).second) |
121 | return true; |
122 | |
123 | const Type *Key = CGT.getContext().getTagDeclType(RD).getTypePtr(); |
124 | |
125 | |
126 | if (CGT.isRecordLayoutComplete(Key)) return true; |
127 | |
128 | |
129 | if (CGT.isRecordBeingLaidOut(Key)) |
130 | return false; |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { |
137 | for (const auto &I : CRD->bases()) |
138 | if (!isSafeToConvert(I.getType()->getAs<RecordType>()->getDecl(), |
139 | CGT, AlreadyChecked)) |
140 | return false; |
141 | } |
142 | |
143 | |
144 | |
145 | for (const auto *I : RD->fields()) |
146 | if (!isSafeToConvert(I->getType(), CGT, AlreadyChecked)) |
147 | return false; |
148 | |
149 | |
150 | return true; |
151 | } |
152 | |
153 | |
154 | |
155 | |
156 | static bool |
157 | isSafeToConvert(QualType T, CodeGenTypes &CGT, |
158 | llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) { |
159 | |
160 | if (const auto *AT = T->getAs<AtomicType>()) |
161 | T = AT->getValueType(); |
162 | |
163 | |
164 | if (const auto *RT = T->getAs<RecordType>()) |
165 | return isSafeToConvert(RT->getDecl(), CGT, AlreadyChecked); |
166 | |
167 | |
168 | if (const auto *AT = CGT.getContext().getAsArrayType(T)) |
169 | return isSafeToConvert(AT->getElementType(), CGT, AlreadyChecked); |
170 | |
171 | |
172 | |
173 | |
174 | return true; |
175 | } |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | static bool isSafeToConvert(const RecordDecl *RD, CodeGenTypes &CGT) { |
182 | |
183 | if (CGT.noRecordsBeingLaidOut()) return true; |
184 | |
185 | llvm::SmallPtrSet<const RecordDecl*, 16> AlreadyChecked; |
186 | return isSafeToConvert(RD, CGT, AlreadyChecked); |
187 | } |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | bool CodeGenTypes::isFuncParamTypeConvertible(QualType Ty) { |
195 | |
196 | |
197 | if (const auto *MPT = Ty->getAs<MemberPointerType>()) |
198 | return getCXXABI().isMemberPointerConvertible(MPT); |
199 | |
200 | |
201 | const TagType *TT = Ty->getAs<TagType>(); |
202 | if (!TT) return true; |
203 | |
204 | |
205 | if (TT->isIncompleteType()) |
206 | return false; |
207 | |
208 | |
209 | const RecordType *RT = dyn_cast<RecordType>(TT); |
210 | if (!RT) return true; |
211 | |
212 | |
213 | |
214 | |
215 | |
216 | |
217 | |
218 | |
219 | return isSafeToConvert(RT->getDecl(), *this); |
220 | } |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | bool CodeGenTypes::isFuncTypeConvertible(const FunctionType *FT) { |
229 | if (!isFuncParamTypeConvertible(FT->getReturnType())) |
230 | return false; |
231 | |
232 | if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) |
233 | for (unsigned i = 0, e = FPT->getNumParams(); i != e; i++) |
234 | if (!isFuncParamTypeConvertible(FPT->getParamType(i))) |
235 | return false; |
236 | |
237 | return true; |
238 | } |
239 | |
240 | |
241 | |
242 | void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) { |
243 | |
244 | |
245 | |
246 | if (const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) { |
247 | |
248 | if (TypeCache.count(ED->getTypeForDecl())) { |
249 | |
250 | |
251 | |
252 | if (!ConvertType(ED->getIntegerType())->isIntegerTy(32)) |
253 | TypeCache.clear(); |
254 | } |
255 | |
256 | |
257 | if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) |
258 | DI->completeType(ED); |
259 | return; |
260 | } |
261 | |
262 | |
263 | |
264 | const RecordDecl *RD = cast<RecordDecl>(TD); |
265 | if (RD->isDependentType()) return; |
266 | |
267 | |
268 | |
269 | if (RecordDeclTypes.count(Context.getTagDeclType(RD).getTypePtr())) |
270 | ConvertRecordDeclType(RD); |
271 | |
272 | |
273 | |
274 | if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) |
275 | DI->completeType(RD); |
276 | } |
277 | |
278 | void CodeGenTypes::RefreshTypeCacheForClass(const CXXRecordDecl *RD) { |
279 | QualType T = Context.getRecordType(RD); |
280 | T = Context.getCanonicalType(T); |
281 | |
282 | const Type *Ty = T.getTypePtr(); |
283 | if (RecordsWithOpaqueMemberPointers.count(Ty)) { |
284 | TypeCache.clear(); |
285 | RecordsWithOpaqueMemberPointers.clear(); |
286 | } |
287 | } |
288 | |
289 | static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext, |
290 | const llvm::fltSemantics &format, |
291 | bool UseNativeHalf = false) { |
292 | if (&format == &llvm::APFloat::IEEEhalf()) { |
293 | if (UseNativeHalf) |
294 | return llvm::Type::getHalfTy(VMContext); |
295 | else |
296 | return llvm::Type::getInt16Ty(VMContext); |
297 | } |
298 | if (&format == &llvm::APFloat::IEEEsingle()) |
299 | return llvm::Type::getFloatTy(VMContext); |
300 | if (&format == &llvm::APFloat::IEEEdouble()) |
301 | return llvm::Type::getDoubleTy(VMContext); |
302 | if (&format == &llvm::APFloat::IEEEquad()) |
303 | return llvm::Type::getFP128Ty(VMContext); |
304 | if (&format == &llvm::APFloat::PPCDoubleDouble()) |
305 | return llvm::Type::getPPC_FP128Ty(VMContext); |
306 | if (&format == &llvm::APFloat::x87DoubleExtended()) |
307 | return llvm::Type::getX86_FP80Ty(VMContext); |
308 | llvm_unreachable("Unknown float format!"); |
309 | } |
310 | |
311 | llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(QualType QFT) { |
312 | assert(QFT.isCanonical()); |
313 | const Type *Ty = QFT.getTypePtr(); |
314 | const FunctionType *FT = cast<FunctionType>(QFT.getTypePtr()); |
315 | |
316 | |
317 | |
318 | if (!isFuncTypeConvertible(FT)) { |
319 | |
320 | |
321 | |
322 | |
323 | if (const RecordType *RT = FT->getReturnType()->getAs<RecordType>()) |
324 | ConvertRecordDeclType(RT->getDecl()); |
325 | if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) |
326 | for (unsigned i = 0, e = FPT->getNumParams(); i != e; i++) |
327 | if (const RecordType *RT = FPT->getParamType(i)->getAs<RecordType>()) |
328 | ConvertRecordDeclType(RT->getDecl()); |
329 | |
330 | SkippedLayout = true; |
331 | |
332 | |
333 | return llvm::StructType::get(getLLVMContext()); |
334 | } |
335 | |
336 | |
337 | |
338 | |
339 | if (!RecordsBeingLaidOut.insert(Ty).second) { |
340 | SkippedLayout = true; |
341 | return llvm::StructType::get(getLLVMContext()); |
342 | } |
343 | |
344 | |
345 | |
346 | const CGFunctionInfo *FI; |
347 | if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) { |
348 | FI = &arrangeFreeFunctionType( |
349 | CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT, 0))); |
350 | } else { |
351 | const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(FT); |
352 | FI = &arrangeFreeFunctionType( |
353 | CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(FNPT, 0))); |
354 | } |
355 | |
356 | llvm::Type *ResultType = nullptr; |
357 | |
358 | |
359 | if (FunctionsBeingProcessed.count(FI)) { |
360 | |
361 | ResultType = llvm::StructType::get(getLLVMContext()); |
362 | SkippedLayout = true; |
363 | } else { |
364 | |
365 | |
366 | ResultType = GetFunctionType(*FI); |
367 | } |
368 | |
369 | RecordsBeingLaidOut.erase(Ty); |
370 | |
371 | if (SkippedLayout) |
372 | TypeCache.clear(); |
373 | |
374 | if (RecordsBeingLaidOut.empty()) |
375 | while (!DeferredRecords.empty()) |
376 | ConvertRecordDeclType(DeferredRecords.pop_back_val()); |
377 | return ResultType; |
378 | } |
379 | |
380 | |
381 | llvm::Type *CodeGenTypes::ConvertType(QualType T) { |
382 | T = Context.getCanonicalType(T); |
383 | |
384 | const Type *Ty = T.getTypePtr(); |
385 | |
386 | |
387 | if (const RecordType *RT = dyn_cast<RecordType>(Ty)) |
388 | return ConvertRecordDeclType(RT->getDecl()); |
389 | |
390 | |
391 | llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI = TypeCache.find(Ty); |
392 | |
393 | if (TCI != TypeCache.end()) |
394 | return TCI->second; |
395 | |
396 | |
397 | llvm::Type *ResultType = nullptr; |
398 | switch (Ty->getTypeClass()) { |
399 | case Type::Record: |
400 | #define TYPE(Class, Base) |
401 | #define ABSTRACT_TYPE(Class, Base) |
402 | #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: |
403 | #define DEPENDENT_TYPE(Class, Base) case Type::Class: |
404 | #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: |
405 | #include "clang/AST/TypeNodes.def" |
406 | llvm_unreachable("Non-canonical or dependent types aren't possible."); |
407 | |
408 | case Type::Builtin: { |
409 | switch (cast<BuiltinType>(Ty)->getKind()) { |
410 | case BuiltinType::Void: |
411 | case BuiltinType::ObjCId: |
412 | case BuiltinType::ObjCClass: |
413 | case BuiltinType::ObjCSel: |
414 | |
415 | |
416 | ResultType = llvm::Type::getInt8Ty(getLLVMContext()); |
417 | break; |
418 | |
419 | case BuiltinType::Bool: |
420 | |
421 | ResultType = llvm::Type::getInt1Ty(getLLVMContext()); |
422 | break; |
423 | |
424 | case BuiltinType::Char_S: |
425 | case BuiltinType::Char_U: |
426 | case BuiltinType::SChar: |
427 | case BuiltinType::UChar: |
428 | case BuiltinType::Short: |
429 | case BuiltinType::UShort: |
430 | case BuiltinType::Int: |
431 | case BuiltinType::UInt: |
432 | case BuiltinType::Long: |
433 | case BuiltinType::ULong: |
434 | case BuiltinType::LongLong: |
435 | case BuiltinType::ULongLong: |
436 | case BuiltinType::WChar_S: |
437 | case BuiltinType::WChar_U: |
438 | case BuiltinType::Char8: |
439 | case BuiltinType::Char16: |
440 | case BuiltinType::Char32: |
441 | case BuiltinType::ShortAccum: |
442 | case BuiltinType::Accum: |
443 | case BuiltinType::LongAccum: |
444 | case BuiltinType::UShortAccum: |
445 | case BuiltinType::UAccum: |
446 | case BuiltinType::ULongAccum: |
447 | case BuiltinType::ShortFract: |
448 | case BuiltinType::Fract: |
449 | case BuiltinType::LongFract: |
450 | case BuiltinType::UShortFract: |
451 | case BuiltinType::UFract: |
452 | case BuiltinType::ULongFract: |
453 | case BuiltinType::SatShortAccum: |
454 | case BuiltinType::SatAccum: |
455 | case BuiltinType::SatLongAccum: |
456 | case BuiltinType::SatUShortAccum: |
457 | case BuiltinType::SatUAccum: |
458 | case BuiltinType::SatULongAccum: |
459 | case BuiltinType::SatShortFract: |
460 | case BuiltinType::SatFract: |
461 | case BuiltinType::SatLongFract: |
462 | case BuiltinType::SatUShortFract: |
463 | case BuiltinType::SatUFract: |
464 | case BuiltinType::SatULongFract: |
465 | ResultType = llvm::IntegerType::get(getLLVMContext(), |
466 | static_cast<unsigned>(Context.getTypeSize(T))); |
467 | break; |
468 | |
469 | case BuiltinType::Float16: |
470 | ResultType = |
471 | getTypeForFormat(getLLVMContext(), Context.getFloatTypeSemantics(T), |
472 | true); |
473 | break; |
474 | |
475 | case BuiltinType::Half: |
476 | |
477 | ResultType = getTypeForFormat( |
478 | getLLVMContext(), Context.getFloatTypeSemantics(T), |
479 | Context.getLangOpts().NativeHalfType || |
480 | !Context.getTargetInfo().useFP16ConversionIntrinsics()); |
481 | break; |
482 | case BuiltinType::Float: |
483 | case BuiltinType::Double: |
484 | case BuiltinType::LongDouble: |
485 | case BuiltinType::Float128: |
486 | ResultType = getTypeForFormat(getLLVMContext(), |
487 | Context.getFloatTypeSemantics(T), |
488 | false); |
489 | break; |
490 | |
491 | case BuiltinType::NullPtr: |
492 | |
493 | ResultType = llvm::Type::getInt8PtrTy(getLLVMContext()); |
494 | break; |
495 | |
496 | case BuiltinType::UInt128: |
497 | case BuiltinType::Int128: |
498 | ResultType = llvm::IntegerType::get(getLLVMContext(), 128); |
499 | break; |
500 | |
501 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ |
502 | case BuiltinType::Id: |
503 | #include "clang/Basic/OpenCLImageTypes.def" |
504 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ |
505 | case BuiltinType::Id: |
506 | #include "clang/Basic/OpenCLExtensionTypes.def" |
507 | case BuiltinType::OCLSampler: |
508 | case BuiltinType::OCLEvent: |
509 | case BuiltinType::OCLClkEvent: |
510 | case BuiltinType::OCLQueue: |
511 | case BuiltinType::OCLReserveID: |
512 | ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty); |
513 | break; |
514 | |
515 | case BuiltinType::Dependent: |
516 | #define BUILTIN_TYPE(Id, SingletonId) |
517 | #define PLACEHOLDER_TYPE(Id, SingletonId) \ |
518 | case BuiltinType::Id: |
519 | #include "clang/AST/BuiltinTypes.def" |
520 | llvm_unreachable("Unexpected placeholder builtin type!"); |
521 | } |
522 | break; |
523 | } |
524 | case Type::Auto: |
525 | case Type::DeducedTemplateSpecialization: |
526 | llvm_unreachable("Unexpected undeduced type!"); |
527 | case Type::Complex: { |
528 | llvm::Type *EltTy = ConvertType(cast<ComplexType>(Ty)->getElementType()); |
529 | ResultType = llvm::StructType::get(EltTy, EltTy); |
530 | break; |
531 | } |
532 | case Type::LValueReference: |
533 | case Type::RValueReference: { |
534 | const ReferenceType *RTy = cast<ReferenceType>(Ty); |
535 | QualType ETy = RTy->getPointeeType(); |
536 | llvm::Type *PointeeType = ConvertTypeForMem(ETy); |
537 | unsigned AS = Context.getTargetAddressSpace(ETy); |
538 | ResultType = llvm::PointerType::get(PointeeType, AS); |
539 | break; |
540 | } |
541 | case Type::Pointer: { |
542 | const PointerType *PTy = cast<PointerType>(Ty); |
543 | QualType ETy = PTy->getPointeeType(); |
544 | llvm::Type *PointeeType = ConvertTypeForMem(ETy); |
545 | if (PointeeType->isVoidTy()) |
546 | PointeeType = llvm::Type::getInt8Ty(getLLVMContext()); |
547 | unsigned AS = Context.getTargetAddressSpace(ETy); |
548 | ResultType = llvm::PointerType::get(PointeeType, AS); |
549 | break; |
550 | } |
551 | |
552 | case Type::VariableArray: { |
553 | const VariableArrayType *A = cast<VariableArrayType>(Ty); |
554 | (0) . __assert_fail ("A->getIndexTypeCVRQualifiers() == 0 && \"FIXME. We only handle trivial array types so far!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CodeGenTypes.cpp", 555, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(A->getIndexTypeCVRQualifiers() == 0 && |
555 | (0) . __assert_fail ("A->getIndexTypeCVRQualifiers() == 0 && \"FIXME. We only handle trivial array types so far!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CodeGenTypes.cpp", 555, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "FIXME: We only handle trivial array types so far!"); |
556 | |
557 | |
558 | ResultType = ConvertTypeForMem(A->getElementType()); |
559 | break; |
560 | } |
561 | case Type::IncompleteArray: { |
562 | const IncompleteArrayType *A = cast<IncompleteArrayType>(Ty); |
563 | (0) . __assert_fail ("A->getIndexTypeCVRQualifiers() == 0 && \"FIXME. We only handle trivial array types so far!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CodeGenTypes.cpp", 564, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(A->getIndexTypeCVRQualifiers() == 0 && |
564 | (0) . __assert_fail ("A->getIndexTypeCVRQualifiers() == 0 && \"FIXME. We only handle trivial array types so far!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CodeGenTypes.cpp", 564, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "FIXME: We only handle trivial array types so far!"); |
565 | |
566 | |
567 | ResultType = ConvertTypeForMem(A->getElementType()); |
568 | if (!ResultType->isSized()) { |
569 | SkippedLayout = true; |
570 | ResultType = llvm::Type::getInt8Ty(getLLVMContext()); |
571 | } |
572 | ResultType = llvm::ArrayType::get(ResultType, 0); |
573 | break; |
574 | } |
575 | case Type::ConstantArray: { |
576 | const ConstantArrayType *A = cast<ConstantArrayType>(Ty); |
577 | llvm::Type *EltTy = ConvertTypeForMem(A->getElementType()); |
578 | |
579 | |
580 | |
581 | if (!EltTy->isSized()) { |
582 | SkippedLayout = true; |
583 | EltTy = llvm::Type::getInt8Ty(getLLVMContext()); |
584 | } |
585 | |
586 | ResultType = llvm::ArrayType::get(EltTy, A->getSize().getZExtValue()); |
587 | break; |
588 | } |
589 | case Type::ExtVector: |
590 | case Type::Vector: { |
591 | const VectorType *VT = cast<VectorType>(Ty); |
592 | ResultType = llvm::VectorType::get(ConvertType(VT->getElementType()), |
593 | VT->getNumElements()); |
594 | break; |
595 | } |
596 | case Type::FunctionNoProto: |
597 | case Type::FunctionProto: |
598 | ResultType = ConvertFunctionTypeInternal(T); |
599 | break; |
600 | case Type::ObjCObject: |
601 | ResultType = ConvertType(cast<ObjCObjectType>(Ty)->getBaseType()); |
602 | break; |
603 | |
604 | case Type::ObjCInterface: { |
605 | |
606 | |
607 | |
608 | llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(Ty)]; |
609 | if (!T) |
610 | T = llvm::StructType::create(getLLVMContext()); |
611 | ResultType = T; |
612 | break; |
613 | } |
614 | |
615 | case Type::ObjCObjectPointer: { |
616 | |
617 | |
618 | |
619 | llvm::Type *T = |
620 | ConvertTypeForMem(cast<ObjCObjectPointerType>(Ty)->getPointeeType()); |
621 | ResultType = T->getPointerTo(); |
622 | break; |
623 | } |
624 | |
625 | case Type::Enum: { |
626 | const EnumDecl *ED = cast<EnumType>(Ty)->getDecl(); |
627 | if (ED->isCompleteDefinition() || ED->isFixed()) |
628 | return ConvertType(ED->getIntegerType()); |
629 | |
630 | |
631 | |
632 | ResultType = llvm::Type::getInt32Ty(getLLVMContext()); |
633 | break; |
634 | } |
635 | |
636 | case Type::BlockPointer: { |
637 | const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType(); |
638 | llvm::Type *PointeeType = CGM.getLangOpts().OpenCL |
639 | ? CGM.getGenericBlockLiteralType() |
640 | : ConvertTypeForMem(FTy); |
641 | unsigned AS = Context.getTargetAddressSpace(FTy); |
642 | ResultType = llvm::PointerType::get(PointeeType, AS); |
643 | break; |
644 | } |
645 | |
646 | case Type::MemberPointer: { |
647 | auto *MPTy = cast<MemberPointerType>(Ty); |
648 | if (!getCXXABI().isMemberPointerConvertible(MPTy)) { |
649 | RecordsWithOpaqueMemberPointers.insert(MPTy->getClass()); |
650 | ResultType = llvm::StructType::create(getLLVMContext()); |
651 | } else { |
652 | ResultType = getCXXABI().ConvertMemberPointerType(MPTy); |
653 | } |
654 | break; |
655 | } |
656 | |
657 | case Type::Atomic: { |
658 | QualType valueType = cast<AtomicType>(Ty)->getValueType(); |
659 | ResultType = ConvertTypeForMem(valueType); |
660 | |
661 | |
662 | uint64_t valueSize = Context.getTypeSize(valueType); |
663 | uint64_t atomicSize = Context.getTypeSize(Ty); |
664 | if (valueSize != atomicSize) { |
665 | assert(valueSize < atomicSize); |
666 | llvm::Type *elts[] = { |
667 | ResultType, |
668 | llvm::ArrayType::get(CGM.Int8Ty, (atomicSize - valueSize) / 8) |
669 | }; |
670 | ResultType = llvm::StructType::get(getLLVMContext(), |
671 | llvm::makeArrayRef(elts)); |
672 | } |
673 | break; |
674 | } |
675 | case Type::Pipe: { |
676 | ResultType = CGM.getOpenCLRuntime().getPipeType(cast<PipeType>(Ty)); |
677 | break; |
678 | } |
679 | } |
680 | |
681 | (0) . __assert_fail ("ResultType && \"Didn't convert a type?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CodeGenTypes.cpp", 681, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ResultType && "Didn't convert a type?"); |
682 | |
683 | TypeCache[Ty] = ResultType; |
684 | return ResultType; |
685 | } |
686 | |
687 | bool CodeGenModule::isPaddedAtomicType(QualType type) { |
688 | return isPaddedAtomicType(type->castAs<AtomicType>()); |
689 | } |
690 | |
691 | bool CodeGenModule::isPaddedAtomicType(const AtomicType *type) { |
692 | return Context.getTypeSize(type) != Context.getTypeSize(type->getValueType()); |
693 | } |
694 | |
695 | |
696 | llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) { |
697 | |
698 | |
699 | const Type *Key = Context.getTagDeclType(RD).getTypePtr(); |
700 | |
701 | llvm::StructType *&Entry = RecordDeclTypes[Key]; |
702 | |
703 | |
704 | if (!Entry) { |
705 | Entry = llvm::StructType::create(getLLVMContext()); |
706 | addRecordTypeName(RD, Entry, ""); |
707 | } |
708 | llvm::StructType *Ty = Entry; |
709 | |
710 | |
711 | |
712 | RD = RD->getDefinition(); |
713 | if (!RD || !RD->isCompleteDefinition() || !Ty->isOpaque()) |
714 | return Ty; |
715 | |
716 | |
717 | if (!isSafeToConvert(RD, *this)) { |
718 | DeferredRecords.push_back(RD); |
719 | return Ty; |
720 | } |
721 | |
722 | |
723 | bool InsertResult = RecordsBeingLaidOut.insert(Key).second; |
724 | (void)InsertResult; |
725 | (0) . __assert_fail ("InsertResult && \"Recursively compiling a struct?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CodeGenTypes.cpp", 725, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(InsertResult && "Recursively compiling a struct?"); |
726 | |
727 | |
728 | if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { |
729 | for (const auto &I : CRD->bases()) { |
730 | if (I.isVirtual()) continue; |
731 | |
732 | ConvertRecordDeclType(I.getType()->getAs<RecordType>()->getDecl()); |
733 | } |
734 | } |
735 | |
736 | |
737 | CGRecordLayout *Layout = ComputeRecordLayout(RD, Ty); |
738 | CGRecordLayouts[Key] = Layout; |
739 | |
740 | |
741 | bool EraseResult = RecordsBeingLaidOut.erase(Key); (void)EraseResult; |
742 | (0) . __assert_fail ("EraseResult && \"struct not in RecordsBeingLaidOut set?\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CodeGenTypes.cpp", 742, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(EraseResult && "struct not in RecordsBeingLaidOut set?"); |
743 | |
744 | |
745 | |
746 | |
747 | if (SkippedLayout) |
748 | TypeCache.clear(); |
749 | |
750 | |
751 | |
752 | if (RecordsBeingLaidOut.empty()) |
753 | while (!DeferredRecords.empty()) |
754 | ConvertRecordDeclType(DeferredRecords.pop_back_val()); |
755 | |
756 | return Ty; |
757 | } |
758 | |
759 | |
760 | const CGRecordLayout & |
761 | CodeGenTypes::getCGRecordLayout(const RecordDecl *RD) { |
762 | const Type *Key = Context.getTagDeclType(RD).getTypePtr(); |
763 | |
764 | const CGRecordLayout *Layout = CGRecordLayouts.lookup(Key); |
765 | if (!Layout) { |
766 | |
767 | ConvertRecordDeclType(RD); |
768 | |
769 | |
770 | Layout = CGRecordLayouts.lookup(Key); |
771 | } |
772 | |
773 | (0) . __assert_fail ("Layout && \"Unable to find record layout information for type\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CodeGenTypes.cpp", 773, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Layout && "Unable to find record layout information for type"); |
774 | return *Layout; |
775 | } |
776 | |
777 | bool CodeGenTypes::isPointerZeroInitializable(QualType T) { |
778 | (0) . __assert_fail ("(T->isAnyPointerType() || T->isBlockPointerType()) && \"Invalid type\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/CodeGenTypes.cpp", 778, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((T->isAnyPointerType() || T->isBlockPointerType()) && "Invalid type"); |
779 | return isZeroInitializable(T); |
780 | } |
781 | |
782 | bool CodeGenTypes::isZeroInitializable(QualType T) { |
783 | if (T->getAs<PointerType>()) |
784 | return Context.getTargetNullPointerValue(T) == 0; |
785 | |
786 | if (const auto *AT = Context.getAsArrayType(T)) { |
787 | if (isa<IncompleteArrayType>(AT)) |
788 | return true; |
789 | if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) |
790 | if (Context.getConstantArrayElementCount(CAT) == 0) |
791 | return true; |
792 | T = Context.getBaseElementType(T); |
793 | } |
794 | |
795 | |
796 | |
797 | if (const RecordType *RT = T->getAs<RecordType>()) { |
798 | const RecordDecl *RD = RT->getDecl(); |
799 | return isZeroInitializable(RD); |
800 | } |
801 | |
802 | |
803 | if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) |
804 | return getCXXABI().isZeroInitializable(MPT); |
805 | |
806 | |
807 | return true; |
808 | } |
809 | |
810 | bool CodeGenTypes::isZeroInitializable(const RecordDecl *RD) { |
811 | return getCGRecordLayout(RD).isZeroInitializable(); |
812 | } |
813 | |