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 Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()),
35 TheABIInfo(cgm.getTargetCodeGenInfo().getABIInfo()) {
36 SkippedLayout =
false;
40 llvm::DeleteContainerSeconds(CGRecordLayouts);
42 for (llvm::FoldingSet<CGFunctionInfo>::iterator
43 I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; )
55 llvm::raw_svector_ostream OS(TypeName);
70 if (TDD->getDeclContext())
71 TDD->printQualifiedName(OS);
80 Ty->setName(OS.str());
91 if (!R->isIntegerTy(1))
103 llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I =
104 RecordDeclTypes.find(Ty);
105 return I != RecordDeclTypes.end() && !I->second->isOpaque();
110 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked);
118 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) {
121 if (!AlreadyChecked.insert(RD).second)
137 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
138 for (
const auto &I : CRD->bases())
140 CGT, AlreadyChecked))
146 for (
const auto *I : RD->
fields())
159 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) {
162 T = AT->getValueType();
186 llvm::SmallPtrSet<const RecordDecl*, 16> AlreadyChecked;
203 if (!TT)
return true;
211 if (!RT)
return true;
234 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
247 if (
const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
249 if (TypeCache.count(ED->getTypeForDecl())) {
253 if (!
ConvertType(ED->getIntegerType())->isIntegerTy(32))
259 DI->completeType(ED);
276 DI->completeType(RD);
284 if (RecordsWithOpaqueMemberPointers.count(Ty)) {
286 RecordsWithOpaqueMemberPointers.clear();
291 const llvm::fltSemantics &format,
292 bool UseNativeHalf =
false) {
293 if (&format == &llvm::APFloat::IEEEhalf()) {
295 return llvm::Type::getHalfTy(VMContext);
297 return llvm::Type::getInt16Ty(VMContext);
299 if (&format == &llvm::APFloat::IEEEsingle())
300 return llvm::Type::getFloatTy(VMContext);
301 if (&format == &llvm::APFloat::IEEEdouble())
302 return llvm::Type::getDoubleTy(VMContext);
303 if (&format == &llvm::APFloat::IEEEquad())
304 return llvm::Type::getFP128Ty(VMContext);
305 if (&format == &llvm::APFloat::PPCDoubleDouble())
306 return llvm::Type::getPPC_FP128Ty(VMContext);
307 if (&format == &llvm::APFloat::x87DoubleExtended())
308 return llvm::Type::getX86_FP80Ty(VMContext);
309 llvm_unreachable(
"Unknown float format!");
328 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
332 SkippedLayout =
true;
341 if (!RecordsBeingLaidOut.insert(Ty).second) {
342 SkippedLayout =
true;
361 if (FunctionsBeingProcessed.count(FI)) {
364 SkippedLayout =
true;
371 RecordsBeingLaidOut.erase(Ty);
376 if (RecordsBeingLaidOut.empty())
377 while (!DeferredRecords.empty())
389 if (
const RecordType *RT = dyn_cast<RecordType>(Ty))
393 llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI = TypeCache.find(Ty);
395 if (TCI != TypeCache.end())
402 #define TYPE(Class, Base) 403 #define ABSTRACT_TYPE(Class, Base) 404 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 405 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 406 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 407 #include "clang/AST/TypeNodes.def" 408 llvm_unreachable(
"Non-canonical or dependent types aren't possible.");
410 case Type::Builtin: {
411 switch (cast<BuiltinType>(Ty)->
getKind()) {
412 case BuiltinType::Void:
413 case BuiltinType::ObjCId:
414 case BuiltinType::ObjCClass:
415 case BuiltinType::ObjCSel:
421 case BuiltinType::Bool:
426 case BuiltinType::Char_S:
427 case BuiltinType::Char_U:
428 case BuiltinType::SChar:
429 case BuiltinType::UChar:
430 case BuiltinType::Short:
431 case BuiltinType::UShort:
432 case BuiltinType::Int:
433 case BuiltinType::UInt:
434 case BuiltinType::Long:
435 case BuiltinType::ULong:
436 case BuiltinType::LongLong:
437 case BuiltinType::ULongLong:
438 case BuiltinType::WChar_S:
439 case BuiltinType::WChar_U:
440 case BuiltinType::Char8:
441 case BuiltinType::Char16:
442 case BuiltinType::Char32:
443 case BuiltinType::ShortAccum:
444 case BuiltinType::Accum:
445 case BuiltinType::LongAccum:
446 case BuiltinType::UShortAccum:
447 case BuiltinType::UAccum:
448 case BuiltinType::ULongAccum:
449 case BuiltinType::ShortFract:
450 case BuiltinType::Fract:
451 case BuiltinType::LongFract:
452 case BuiltinType::UShortFract:
453 case BuiltinType::UFract:
454 case BuiltinType::ULongFract:
455 case BuiltinType::SatShortAccum:
456 case BuiltinType::SatAccum:
457 case BuiltinType::SatLongAccum:
458 case BuiltinType::SatUShortAccum:
459 case BuiltinType::SatUAccum:
460 case BuiltinType::SatULongAccum:
461 case BuiltinType::SatShortFract:
462 case BuiltinType::SatFract:
463 case BuiltinType::SatLongFract:
464 case BuiltinType::SatUShortFract:
465 case BuiltinType::SatUFract:
466 case BuiltinType::SatULongFract:
471 case BuiltinType::Float16:
477 case BuiltinType::Half:
484 case BuiltinType::Float:
485 case BuiltinType::Double:
486 case BuiltinType::LongDouble:
487 case BuiltinType::Float128:
493 case BuiltinType::NullPtr:
498 case BuiltinType::UInt128:
499 case BuiltinType::Int128:
503 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 504 case BuiltinType::Id: 505 #include "clang/Basic/OpenCLImageTypes.def" 506 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 507 case BuiltinType::Id: 508 #include "clang/Basic/OpenCLExtensionTypes.def" 509 case BuiltinType::OCLSampler:
510 case BuiltinType::OCLEvent:
511 case BuiltinType::OCLClkEvent:
512 case BuiltinType::OCLQueue:
513 case BuiltinType::OCLReserveID:
517 case BuiltinType::Dependent:
518 #define BUILTIN_TYPE(Id, SingletonId) 519 #define PLACEHOLDER_TYPE(Id, SingletonId) \ 520 case BuiltinType::Id: 521 #include "clang/AST/BuiltinTypes.def" 522 llvm_unreachable(
"Unexpected placeholder builtin type!");
527 case Type::DeducedTemplateSpecialization:
528 llvm_unreachable(
"Unexpected undeduced type!");
529 case Type::Complex: {
531 ResultType = llvm::StructType::get(EltTy, EltTy);
534 case Type::LValueReference:
535 case Type::RValueReference: {
540 ResultType = llvm::PointerType::get(PointeeType, AS);
543 case Type::Pointer: {
547 if (PointeeType->isVoidTy())
550 ResultType = llvm::PointerType::get(PointeeType, AS);
554 case Type::VariableArray: {
557 "FIXME: We only handle trivial array types so far!");
563 case Type::IncompleteArray: {
566 "FIXME: We only handle trivial array types so far!");
570 if (!ResultType->isSized()) {
571 SkippedLayout =
true;
574 ResultType = llvm::ArrayType::get(ResultType, 0);
577 case Type::ConstantArray: {
583 if (!EltTy->isSized()) {
584 SkippedLayout =
true;
588 ResultType = llvm::ArrayType::get(EltTy, A->
getSize().getZExtValue());
591 case Type::ExtVector:
598 case Type::FunctionNoProto:
599 case Type::FunctionProto:
602 case Type::ObjCObject:
603 ResultType =
ConvertType(cast<ObjCObjectType>(Ty)->getBaseType());
606 case Type::ObjCInterface: {
610 llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(Ty)];
617 case Type::ObjCObjectPointer: {
623 ResultType = T->getPointerTo();
628 const EnumDecl *ED = cast<EnumType>(Ty)->getDecl();
638 case Type::BlockPointer: {
639 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.
Represents a function declaration or definition.
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.
const CGFunctionInfo & arrangeFreeFunctionType(CanQual< FunctionProtoType > Ty, const FunctionDecl *FD)
Arrange the argument and result information for a value of the given freestanding function type...
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.
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...
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
llvm::Type * ConvertFunctionType(QualType FT, const FunctionDecl *FD=nullptr)
Converts the GlobalDecl into an llvm::Type.
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.