26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/IR/DerivedTypes.h"
28 #include "llvm/IR/Module.h"
29 using namespace clang;
30 using namespace CodeGen;
33 : CGM(cgm),
Context(cgm.getContext()), TheModule(cgm.getModule()),
34 TheDataLayout(cgm.getDataLayout()),
35 Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()),
36 TheABIInfo(cgm.getTargetCodeGenInfo().getABIInfo()) {
37 SkippedLayout =
false;
41 llvm::DeleteContainerSeconds(CGRecordLayouts);
43 for (llvm::FoldingSet<CGFunctionInfo>::iterator
44 I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; )
52 llvm::raw_svector_ostream OS(TypeName);
67 if (TDD->getDeclContext())
68 TDD->printQualifiedName(OS);
77 Ty->setName(OS.str());
88 if (!R->isIntegerTy(1))
100 llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I =
101 RecordDeclTypes.find(Ty);
102 return I != RecordDeclTypes.end() && !I->second->isOpaque();
107 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked);
115 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) {
118 if (!AlreadyChecked.insert(RD).second)
134 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
135 for (
const auto &I : CRD->bases())
137 CGT, AlreadyChecked))
143 for (
const auto *I : RD->
fields())
156 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) {
159 T = AT->getValueType();
183 llvm::SmallPtrSet<const RecordDecl*, 16> AlreadyChecked;
200 if (!TT)
return true;
208 if (!RT)
return true;
231 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
244 if (
const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
246 if (TypeCache.count(ED->getTypeForDecl())) {
250 if (!
ConvertType(ED->getIntegerType())->isIntegerTy(32))
256 DI->completeType(ED);
273 DI->completeType(RD);
277 const llvm::fltSemantics &format,
278 bool UseNativeHalf =
false) {
279 if (&format == &llvm::APFloat::IEEEhalf) {
281 return llvm::Type::getHalfTy(VMContext);
283 return llvm::Type::getInt16Ty(VMContext);
285 if (&format == &llvm::APFloat::IEEEsingle)
286 return llvm::Type::getFloatTy(VMContext);
287 if (&format == &llvm::APFloat::IEEEdouble)
288 return llvm::Type::getDoubleTy(VMContext);
289 if (&format == &llvm::APFloat::IEEEquad)
290 return llvm::Type::getFP128Ty(VMContext);
291 if (&format == &llvm::APFloat::PPCDoubleDouble)
292 return llvm::Type::getPPC_FP128Ty(VMContext);
293 if (&format == &llvm::APFloat::x87DoubleExtended)
294 return llvm::Type::getX86_FP80Ty(VMContext);
295 llvm_unreachable(
"Unknown float format!");
305 if (
const RecordType *RT = dyn_cast<RecordType>(Ty))
309 llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI = TypeCache.find(Ty);
311 if (TCI != TypeCache.end())
315 llvm::Type *ResultType =
nullptr;
318 #define TYPE(Class, Base)
319 #define ABSTRACT_TYPE(Class, Base)
320 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
321 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
322 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
323 #include "clang/AST/TypeNodes.def"
324 llvm_unreachable(
"Non-canonical or dependent types aren't possible.");
326 case Type::Builtin: {
327 switch (cast<BuiltinType>(Ty)->
getKind()) {
328 case BuiltinType::Void:
329 case BuiltinType::ObjCId:
330 case BuiltinType::ObjCClass:
331 case BuiltinType::ObjCSel:
337 case BuiltinType::Bool:
342 case BuiltinType::Char_S:
343 case BuiltinType::Char_U:
344 case BuiltinType::SChar:
345 case BuiltinType::UChar:
346 case BuiltinType::Short:
347 case BuiltinType::UShort:
348 case BuiltinType::Int:
349 case BuiltinType::UInt:
350 case BuiltinType::Long:
351 case BuiltinType::ULong:
352 case BuiltinType::LongLong:
353 case BuiltinType::ULongLong:
354 case BuiltinType::WChar_S:
355 case BuiltinType::WChar_U:
356 case BuiltinType::Char16:
357 case BuiltinType::Char32:
362 case BuiltinType::Half:
369 case BuiltinType::Float:
370 case BuiltinType::Double:
371 case BuiltinType::LongDouble:
377 case BuiltinType::NullPtr:
382 case BuiltinType::UInt128:
383 case BuiltinType::Int128:
387 case BuiltinType::OCLImage1d:
388 case BuiltinType::OCLImage1dArray:
389 case BuiltinType::OCLImage1dBuffer:
390 case BuiltinType::OCLImage2d:
391 case BuiltinType::OCLImage2dArray:
392 case BuiltinType::OCLImage3d:
393 case BuiltinType::OCLSampler:
394 case BuiltinType::OCLEvent:
398 case BuiltinType::Dependent:
399 #define BUILTIN_TYPE(Id, SingletonId)
400 #define PLACEHOLDER_TYPE(Id, SingletonId) \
401 case BuiltinType::Id:
402 #include "clang/AST/BuiltinTypes.def"
403 llvm_unreachable(
"Unexpected placeholder builtin type!");
408 llvm_unreachable(
"Unexpected undeduced auto type!");
409 case Type::Complex: {
411 ResultType = llvm::StructType::get(EltTy, EltTy,
nullptr);
414 case Type::LValueReference:
415 case Type::RValueReference: {
420 ResultType = llvm::PointerType::get(PointeeType, AS);
423 case Type::Pointer: {
427 if (PointeeType->isVoidTy())
430 ResultType = llvm::PointerType::get(PointeeType, AS);
434 case Type::VariableArray: {
437 "FIXME: We only handle trivial array types so far!");
443 case Type::IncompleteArray: {
446 "FIXME: We only handle trivial array types so far!");
450 if (!ResultType->isSized()) {
451 SkippedLayout =
true;
454 ResultType = llvm::ArrayType::get(ResultType, 0);
457 case Type::ConstantArray: {
463 if (!EltTy->isSized()) {
464 SkippedLayout =
true;
468 ResultType = llvm::ArrayType::get(EltTy, A->
getSize().getZExtValue());
471 case Type::ExtVector:
478 case Type::FunctionNoProto:
479 case Type::FunctionProto: {
492 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
499 SkippedLayout =
true;
506 if (!RecordsBeingLaidOut.insert(Ty).second) {
509 SkippedLayout =
true;
527 if (FunctionsBeingProcessed.count(FI)) {
530 SkippedLayout =
true;
537 RecordsBeingLaidOut.erase(Ty);
542 if (RecordsBeingLaidOut.empty())
543 while (!DeferredRecords.empty())
548 case Type::ObjCObject:
549 ResultType =
ConvertType(cast<ObjCObjectType>(Ty)->getBaseType());
552 case Type::ObjCInterface: {
556 llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(Ty)];
563 case Type::ObjCObjectPointer: {
569 ResultType = T->getPointerTo();
574 const EnumDecl *ED = cast<EnumType>(Ty)->getDecl();
584 case Type::BlockPointer: {
585 const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();
588 ResultType = llvm::PointerType::get(PointeeType, AS);
592 case Type::MemberPointer: {
593 if (!
getCXXABI().isMemberPointerConvertible(cast<MemberPointerType>(Ty)))
601 QualType valueType = cast<AtomicType>(Ty)->getValueType();
605 uint64_t valueSize = Context.
getTypeSize(valueType);
607 if (valueSize != atomicSize) {
608 assert(valueSize < atomicSize);
609 llvm::Type *elts[] = {
611 llvm::ArrayType::get(CGM.
Int8Ty, (atomicSize - valueSize) / 8)
614 llvm::makeArrayRef(elts));
620 assert(ResultType &&
"Didn't convert a type?");
622 TypeCache[Ty] = ResultType;
640 llvm::StructType *&Entry = RecordDeclTypes[Key];
647 llvm::StructType *Ty = Entry;
657 DeferredRecords.push_back(RD);
662 bool InsertResult = RecordsBeingLaidOut.insert(Key).second;
664 assert(InsertResult &&
"Recursively compiling a struct?");
667 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
668 for (
const auto &I : CRD->bases()) {
669 if (I.isVirtual())
continue;
677 CGRecordLayouts[Key] = Layout;
680 bool EraseResult = RecordsBeingLaidOut.erase(Key); (void)EraseResult;
681 assert(EraseResult &&
"struct not in RecordsBeingLaidOut set?");
691 if (RecordsBeingLaidOut.empty())
692 while (!DeferredRecords.empty())
709 Layout = CGRecordLayouts.lookup(Key);
712 assert(Layout &&
"Unable to find record layout information for type");
722 if (isa<IncompleteArrayType>(AT))
724 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
733 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
unsigned getNumElements() const
CGOpenCLRuntime & getOpenCLRuntime()
Return a reference to the configured OpenCL runtime.
Defines the clang::ASTContext interface.
void UpdateCompletedType(const TagDecl *TD)
IdentifierInfo * getIdentifier() const
static llvm::Type * getTypeForFormat(llvm::LLVMContext &VMContext, const llvm::fltSemantics &format, bool UseNativeHalf=false)
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
void addRecordTypeName(const RecordDecl *RD, llvm::StructType *Ty, StringRef suffix)
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
bool isFuncTypeConvertible(const FunctionType *FT)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
const llvm::APInt & getSize() const
CGDebugInfo * getModuleDebugInfo()
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
llvm::Type * ConvertTypeForMem(QualType T)
const CGFunctionInfo & arrangeFreeFunctionType(CanQual< FunctionProtoType > Ty)
unsigned getIndexTypeCVRQualifiers() const
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
bool isCompleteDefinition() const
bool isPaddedAtomicType(QualType type)
static bool isSafeToConvert(QualType T, CodeGenTypes &CGT, llvm::SmallPtrSet< const RecordDecl *, 16 > &AlreadyChecked)
const LangOptions & getLangOpts() const
QualType getReturnType() const
field_range fields() const
const ArrayType * getAsArrayType(QualType T) const
RecordDecl * getDecl() const
TypeClass getTypeClass() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Def If non-NULL, and the type refers to some kind of declaration that can be completed (such as a C s...
virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
virtual llvm::Type * convertOpenCLSpecificType(const Type *T)
virtual bool isZeroInitializable(const MemberPointerType *MPT)
QualType getValueType() const
virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const
Return whether or not a member pointers type is convertible to an IR type.
CodeGenTypes(CodeGenModule &cgm)
DeclContext * getDeclContext()
QualType getElementType() const
RecordDecl * getDefinition() const
TypedefNameDecl * getTypedefNameForAnonDecl() const
const Type * getTypePtr() const
TagDecl - Represents the declaration of a struct/union/class/enum.
void printName(raw_ostream &os) const
Represents a canonical, potentially-qualified type.
llvm::LLVMContext & getLLVMContext()
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
void printQualifiedName(raw_ostream &OS) const
QualType getPointeeType() const
bool isRecordBeingLaidOut(const Type *Ty) const
Base class for declarations which introduce a typedef-name.
static const Type * getElementType(const Expr *BaseExpr)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
bool isZeroInitializable() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
llvm::StructType * ConvertRecordDeclType(const RecordDecl *TD)
ConvertRecordDeclType - Lay out a tagged decl type like struct or union.
QualType getIntegerType() const
bool isRecordLayoutComplete(const Type *Ty) const
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
QualType getPointeeType() const
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Represents a C++ struct/union/class.
bool isFuncParamTypeConvertible(QualType Ty)
static Decl::Kind getKind(const Decl *D)
unsigned getTargetAddressSpace(QualType T) const
QualType getElementType() const
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
CGRecordLayout * ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty)
Compute a new LLVM record layout object for the given record.
StringRef getKindName() const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
bool noRecordsBeingLaidOut() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
bool isZeroInitializable(QualType T)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.