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;
32 : CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()),
33 Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()),
34 TheABIInfo(cgm.getTargetCodeGenInfo().getABIInfo()) {
35 SkippedLayout =
false;
39 llvm::DeleteContainerSeconds(CGRecordLayouts);
41 for (llvm::FoldingSet<CGFunctionInfo>::iterator
42 I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; )
54 llvm::raw_svector_ostream OS(TypeName);
69 if (TDD->getDeclContext())
70 TDD->printQualifiedName(OS);
79 Ty->setName(OS.str());
90 if (!R->isIntegerTy(1))
102 llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I =
103 RecordDeclTypes.find(Ty);
104 return I != RecordDeclTypes.end() && !I->second->isOpaque();
109 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked);
117 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) {
120 if (!AlreadyChecked.insert(RD).second)
136 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
137 for (
const auto &I : CRD->bases())
139 CGT, AlreadyChecked))
145 for (
const auto *I : RD->
fields())
158 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) {
161 T = AT->getValueType();
185 llvm::SmallPtrSet<const RecordDecl*, 16> AlreadyChecked;
202 if (!TT)
return true;
210 if (!RT)
return true;
233 for (
unsigned i = 0, e = FPT->getNumParams();
i != e;
i++)
246 if (
const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
248 if (TypeCache.count(ED->getTypeForDecl())) {
252 if (!
ConvertType(ED->getIntegerType())->isIntegerTy(32))
258 DI->completeType(ED);
275 DI->completeType(RD);
283 if (RecordsWithOpaqueMemberPointers.count(Ty)) {
285 RecordsWithOpaqueMemberPointers.clear();
290 const llvm::fltSemantics &format,
291 bool UseNativeHalf =
false) {
292 if (&format == &llvm::APFloat::IEEEhalf()) {
294 return llvm::Type::getHalfTy(VMContext);
296 return llvm::Type::getInt16Ty(VMContext);
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!");
326 for (
unsigned i = 0, e = FPT->getNumParams();
i != e;
i++)
330 SkippedLayout =
true;
339 if (!RecordsBeingLaidOut.insert(Ty).second) {
340 SkippedLayout =
true;
359 if (FunctionsBeingProcessed.count(FI)) {
362 SkippedLayout =
true;
369 RecordsBeingLaidOut.erase(Ty);
374 if (RecordsBeingLaidOut.empty())
375 while (!DeferredRecords.empty())
387 if (
const RecordType *RT = dyn_cast<RecordType>(Ty))
391 llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI = TypeCache.find(Ty);
393 if (TCI != TypeCache.end())
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.");
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:
419 case BuiltinType::Bool:
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:
469 case BuiltinType::Float16:
475 case BuiltinType::Half:
482 case BuiltinType::Float:
483 case BuiltinType::Double:
484 case BuiltinType::LongDouble:
485 case BuiltinType::Float128:
491 case BuiltinType::NullPtr:
496 case BuiltinType::UInt128:
497 case BuiltinType::Int128:
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:
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!");
525 case Type::DeducedTemplateSpecialization:
526 llvm_unreachable(
"Unexpected undeduced type!");
527 case Type::Complex: {
529 ResultType = llvm::StructType::get(EltTy, EltTy);
532 case Type::LValueReference:
533 case Type::RValueReference: {
538 ResultType = llvm::PointerType::get(PointeeType, AS);
541 case Type::Pointer: {
545 if (PointeeType->isVoidTy())
548 ResultType = llvm::PointerType::get(PointeeType, AS);
552 case Type::VariableArray: {
555 "FIXME: We only handle trivial array types so far!");
561 case Type::IncompleteArray: {
564 "FIXME: We only handle trivial array types so far!");
568 if (!ResultType->isSized()) {
569 SkippedLayout =
true;
572 ResultType = llvm::ArrayType::get(ResultType, 0);
575 case Type::ConstantArray: {
581 if (!EltTy->isSized()) {
582 SkippedLayout =
true;
586 ResultType = llvm::ArrayType::get(EltTy, A->
getSize().getZExtValue());
589 case Type::ExtVector:
596 case Type::FunctionNoProto:
597 case Type::FunctionProto:
598 ResultType = ConvertFunctionTypeInternal(T);
600 case Type::ObjCObject:
601 ResultType =
ConvertType(cast<ObjCObjectType>(Ty)->getBaseType());
604 case Type::ObjCInterface: {
608 llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(Ty)];
615 case Type::ObjCObjectPointer: {
621 ResultType = T->getPointerTo();
626 const EnumDecl *ED = cast<EnumType>(Ty)->getDecl();
636 case Type::BlockPointer: {
637 const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();
642 ResultType = llvm::PointerType::get(PointeeType, AS);
646 case Type::MemberPointer: {
647 auto *MPTy = cast<MemberPointerType>(Ty);
649 RecordsWithOpaqueMemberPointers.insert(MPTy->getClass());
658 QualType valueType = cast<AtomicType>(Ty)->getValueType();
662 uint64_t valueSize = Context.
getTypeSize(valueType);
664 if (valueSize != atomicSize) {
665 assert(valueSize < atomicSize);
668 llvm::ArrayType::get(CGM.
Int8Ty, (atomicSize - valueSize) / 8)
671 llvm::makeArrayRef(elts));
681 assert(ResultType &&
"Didn't convert a type?");
683 TypeCache[Ty] = ResultType;
701 llvm::StructType *&Entry = RecordDeclTypes[Key];
708 llvm::StructType *Ty = Entry;
718 DeferredRecords.push_back(RD);
723 bool InsertResult = RecordsBeingLaidOut.insert(Key).second;
725 assert(InsertResult &&
"Recursively compiling a struct?");
728 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
729 for (
const auto &I : CRD->bases()) {
730 if (I.isVirtual())
continue;
738 CGRecordLayouts[Key] = Layout;
741 bool EraseResult = RecordsBeingLaidOut.erase(Key); (void)EraseResult;
742 assert(EraseResult &&
"struct not in RecordsBeingLaidOut set?");
752 if (RecordsBeingLaidOut.empty())
753 while (!DeferredRecords.empty())
770 Layout = CGRecordLayouts.lookup(Key);
773 assert(Layout &&
"Unable to find record layout information for type");
787 if (isa<IncompleteArrayType>(AT))
789 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
bool noRecordsBeingLaidOut() const
CGCXXABI & getCXXABI() const
CGOpenCLRuntime & getOpenCLRuntime()
Return a reference to the configured OpenCL runtime.
Defines the clang::ASTContext interface.
llvm::Type * getGenericBlockLiteralType()
The type of a generic block literal.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isBlockPointerType() const
const CodeGenOptions & getCodeGenOpts() const
void UpdateCompletedType(const TagDecl *TD)
UpdateCompletedType - When we find the full definition for a TagDecl, replace the 'opaque' type we pr...
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
static llvm::Type * getTypeForFormat(llvm::LLVMContext &VMContext, const llvm::fltSemantics &format, bool UseNativeHalf=false)
FunctionType - C99 6.7.5.3 - Function Declarators.
void addRecordTypeName(const RecordDecl *RD, llvm::StructType *Ty, StringRef suffix)
addRecordTypeName - Compute a name from the given record decl with an optional suffix and name the gi...
bool isRecordBeingLaidOut(const Type *Ty) const
The base class of the type hierarchy.
const TargetInfo & getTargetInfo() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i...
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
QualType getElementType() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
const T * getAs() const
Member-template getAs<specific type>'.
CGDebugInfo * getModuleDebugInfo()
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeFreeFunctionType(CanQual< FunctionProtoType > Ty)
Arrange the argument and result information for a value of the given freestanding function type...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a struct/union/class.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
field_range fields() const
bool isPaddedAtomicType(QualType type)
static bool isSafeToConvert(QualType T, CodeGenTypes &CGT, llvm::SmallPtrSet< const RecordDecl *, 16 > &AlreadyChecked)
isSafeToConvert - Return true if it is safe to convert this field type, which requires the structure ...
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isZeroInitializable() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer.
virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
Find the LLVM type used to represent the given member pointer type.
virtual llvm::Type * getPipeType(const PipeType *T, StringRef Name, llvm::Type *&PipeTy)
virtual llvm::Type * convertOpenCLSpecificType(const Type *T)
virtual bool isZeroInitializable(const MemberPointerType *MPT)
Return true if the given member pointer can be zero-initialized (in the C++ sense) with an LLVM zeroi...
Represents a K&R-style 'int foo()' function, which has no information available about its arguments...
Represents a prototype with parameter type info, e.g.
bool isPointerZeroInitializable(QualType T)
Check if the pointer type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer...
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
CodeGenTypes(CodeGenModule &cgm)
StringRef getKindName() const
QualType getPointeeType() const
const T * castAs() const
Member-template castAs<specific type>.
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
DeclContext * getDeclContext()
const CodeGenOptions & getCodeGenOpts() const
QualType getRecordType(const RecordDecl *Decl) const
Represents a GCC generic vector type.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
const LangOptions & getLangOpts() const
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
virtual void printName(raw_ostream &os) const
QualType getReturnType() const
Represents the declaration of a struct/union/class/enum.
QualType getElementType() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Represents a canonical, potentially-qualified type.
bool isRecordLayoutComplete(const Type *Ty) const
isRecordLayoutComplete - Return true if the specified type is already completely laid out...
bool isAnyPointerType() const
llvm::LLVMContext & getLLVMContext()
TypeClass getTypeClass() const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
Base class for declarations which introduce a typedef-name.
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
Dataflow Directional Tag Classes.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const
Return whether or not a member pointers type is convertible to an IR type.
A pointer to member type per C++ 8.3.3 - Pointers to members.
llvm::StructType * ConvertRecordDeclType(const RecordDecl *TD)
ConvertRecordDeclType - Lay out a tagged decl type like struct or union.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
unsigned getIndexTypeCVRQualifiers() const
const llvm::APInt & getSize() const
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
Base for LValueReferenceType and RValueReferenceType.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
ASTContext & getContext() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
TypedefNameDecl * getTypedefNameForAnonDecl() const
Represents a C++ struct/union/class.
Represents a C array with an unspecified size.
bool isFuncParamTypeConvertible(QualType Ty)
isFuncParamTypeConvertible - Return true if the specified type in a function parameter or result posi...
void RefreshTypeCacheForClass(const CXXRecordDecl *RD)
Remove stale types from the type cache when an inheritance model gets assigned to a class...
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
static Decl::Kind getKind(const Decl *D)
unsigned getNumElements() const
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
CGRecordLayout * ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty)
Compute a new LLVM record layout object for the given record.
Represents a C array with a specified size that is not an integer-constant-expression.
unsigned getTargetAddressSpace(QualType T) const
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
const LangOptions & getLangOpts() const
Represents the canonical version of C arrays with a specified constant size.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.