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);
43 I = FunctionInfos.begin(),
E = FunctionInfos.end();
I !=
E; )
51 llvm::raw_svector_ostream OS(TypeName);
59 if (RD->getDeclContext())
66 if (TDD->getDeclContext())
67 TDD->printQualifiedName(OS);
76 Ty->setName(OS.str());
87 if (!R->isIntegerTy(1))
99 llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator
I =
100 RecordDeclTypes.find(Ty);
101 return I != RecordDeclTypes.end() && !I->second->isOpaque();
106 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked);
114 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) {
117 if (!AlreadyChecked.insert(RD).second)
133 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
134 for (
const auto &
I : CRD->bases())
136 CGT, AlreadyChecked))
142 for (
const auto *
I : RD->
fields())
155 llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) {
158 T = AT->getValueType();
182 llvm::SmallPtrSet<const RecordDecl*, 16> AlreadyChecked;
199 if (!TT)
return true;
207 if (!RT)
return true;
230 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
243 if (
const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
245 if (TypeCache.count(ED->getTypeForDecl())) {
249 if (!
ConvertType(ED->getIntegerType())->isIntegerTy(32))
255 DI->completeType(ED);
272 DI->completeType(RD);
280 if (RecordsWithOpaqueMemberPointers.count(Ty)) {
282 RecordsWithOpaqueMemberPointers.clear();
287 const llvm::fltSemantics &format,
288 bool UseNativeHalf =
false) {
289 if (&format == &llvm::APFloat::IEEEhalf) {
291 return llvm::Type::getHalfTy(VMContext);
293 return llvm::Type::getInt16Ty(VMContext);
295 if (&format == &llvm::APFloat::IEEEsingle)
296 return llvm::Type::getFloatTy(VMContext);
297 if (&format == &llvm::APFloat::IEEEdouble)
298 return llvm::Type::getDoubleTy(VMContext);
299 if (&format == &llvm::APFloat::IEEEquad)
300 return llvm::Type::getFP128Ty(VMContext);
301 if (&format == &llvm::APFloat::PPCDoubleDouble)
302 return llvm::Type::getPPC_FP128Ty(VMContext);
303 if (&format == &llvm::APFloat::x87DoubleExtended)
304 return llvm::Type::getX86_FP80Ty(VMContext);
305 llvm_unreachable(
"Unknown float format!");
324 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
328 SkippedLayout =
true;
337 if (!RecordsBeingLaidOut.insert(Ty).second) {
338 SkippedLayout =
true;
357 if (FunctionsBeingProcessed.count(FI)) {
360 SkippedLayout =
true;
367 RecordsBeingLaidOut.erase(Ty);
372 if (RecordsBeingLaidOut.empty())
373 while (!DeferredRecords.empty())
385 if (
const RecordType *RT = dyn_cast<RecordType>(Ty))
391 if (TCI != TypeCache.end())
398 #define TYPE(Class, Base)
399 #define ABSTRACT_TYPE(Class, Base)
400 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
401 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
402 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
403 #include "clang/AST/TypeNodes.def"
404 llvm_unreachable(
"Non-canonical or dependent types aren't possible.");
406 case Type::Builtin: {
407 switch (cast<BuiltinType>(Ty)->
getKind()) {
408 case BuiltinType::Void:
409 case BuiltinType::ObjCId:
410 case BuiltinType::ObjCClass:
411 case BuiltinType::ObjCSel:
417 case BuiltinType::Bool:
422 case BuiltinType::Char_S:
423 case BuiltinType::Char_U:
424 case BuiltinType::SChar:
425 case BuiltinType::UChar:
426 case BuiltinType::Short:
427 case BuiltinType::UShort:
428 case BuiltinType::Int:
429 case BuiltinType::UInt:
430 case BuiltinType::Long:
431 case BuiltinType::ULong:
432 case BuiltinType::LongLong:
433 case BuiltinType::ULongLong:
434 case BuiltinType::WChar_S:
435 case BuiltinType::WChar_U:
436 case BuiltinType::Char16:
437 case BuiltinType::Char32:
442 case BuiltinType::Half:
449 case BuiltinType::Float:
450 case BuiltinType::Double:
451 case BuiltinType::LongDouble:
452 case BuiltinType::Float128:
458 case BuiltinType::NullPtr:
463 case BuiltinType::UInt128:
464 case BuiltinType::Int128:
468 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
469 case BuiltinType::Id:
470 #include "clang/Basic/OpenCLImageTypes.def"
471 case BuiltinType::OCLSampler:
472 case BuiltinType::OCLEvent:
473 case BuiltinType::OCLClkEvent:
474 case BuiltinType::OCLQueue:
475 case BuiltinType::OCLNDRange:
476 case BuiltinType::OCLReserveID:
480 case BuiltinType::Dependent:
481 #define BUILTIN_TYPE(Id, SingletonId)
482 #define PLACEHOLDER_TYPE(Id, SingletonId) \
483 case BuiltinType::Id:
484 #include "clang/AST/BuiltinTypes.def"
485 llvm_unreachable(
"Unexpected placeholder builtin type!");
490 llvm_unreachable(
"Unexpected undeduced auto type!");
491 case Type::Complex: {
493 ResultType = llvm::StructType::get(EltTy, EltTy,
nullptr);
496 case Type::LValueReference:
497 case Type::RValueReference: {
502 ResultType = llvm::PointerType::get(PointeeType, AS);
505 case Type::Pointer: {
509 if (PointeeType->isVoidTy())
512 ResultType = llvm::PointerType::get(PointeeType, AS);
516 case Type::VariableArray: {
519 "FIXME: We only handle trivial array types so far!");
525 case Type::IncompleteArray: {
528 "FIXME: We only handle trivial array types so far!");
532 if (!ResultType->isSized()) {
533 SkippedLayout =
true;
536 ResultType = llvm::ArrayType::get(ResultType, 0);
539 case Type::ConstantArray: {
545 if (!EltTy->isSized()) {
546 SkippedLayout =
true;
550 ResultType = llvm::ArrayType::get(EltTy, A->
getSize().getZExtValue());
553 case Type::ExtVector:
560 case Type::FunctionNoProto:
561 case Type::FunctionProto:
564 case Type::ObjCObject:
565 ResultType =
ConvertType(cast<ObjCObjectType>(Ty)->getBaseType());
568 case Type::ObjCInterface: {
572 llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(Ty)];
579 case Type::ObjCObjectPointer: {
585 ResultType = T->getPointerTo();
590 const EnumDecl *ED = cast<EnumType>(Ty)->getDecl();
600 case Type::BlockPointer: {
601 const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();
604 ResultType = llvm::PointerType::get(PointeeType, AS);
608 case Type::MemberPointer: {
609 auto *MPTy = cast<MemberPointerType>(Ty);
611 RecordsWithOpaqueMemberPointers.insert(MPTy->getClass());
620 QualType valueType = cast<AtomicType>(Ty)->getValueType();
624 uint64_t valueSize = Context.
getTypeSize(valueType);
626 if (valueSize != atomicSize) {
627 assert(valueSize < atomicSize);
630 llvm::ArrayType::get(CGM.
Int8Ty, (atomicSize - valueSize) / 8)
633 llvm::makeArrayRef(elts));
643 assert(ResultType &&
"Didn't convert a type?");
645 TypeCache[Ty] = ResultType;
663 llvm::StructType *&Entry = RecordDeclTypes[Key];
670 llvm::StructType *Ty = Entry;
680 DeferredRecords.push_back(RD);
685 bool InsertResult = RecordsBeingLaidOut.insert(Key).second;
687 assert(InsertResult &&
"Recursively compiling a struct?");
690 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
691 for (
const auto &
I : CRD->bases()) {
692 if (
I.isVirtual())
continue;
700 CGRecordLayouts[Key] = Layout;
703 bool EraseResult = RecordsBeingLaidOut.erase(Key); (void)EraseResult;
704 assert(EraseResult &&
"struct not in RecordsBeingLaidOut set?");
714 if (RecordsBeingLaidOut.empty())
715 while (!DeferredRecords.empty())
732 Layout = CGRecordLayouts.lookup(Key);
735 assert(Layout &&
"Unable to find record layout information for type");
745 if (isa<IncompleteArrayType>(AT))
747 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
756 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.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
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...
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
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...
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...
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
The base class of the type hierarchy.
QualType getRecordType(const RecordDecl *Decl) const
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
const llvm::APInt & getSize() const
CGDebugInfo * getModuleDebugInfo()
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
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.
RecordDecl - Represents a struct/union/class.
unsigned getIndexTypeCVRQualifiers() const
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
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 ...
const LangOptions & getLangOpts() const
QualType getReturnType() const
field_range fields() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
RecordDecl * getDecl() const
TypeClass getTypeClass() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
detail::InMemoryDirectory::const_iterator I
virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
Find the LLVM type used to represent the given member pointer type.
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...
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Represents a prototype with parameter type info, e.g.
virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const
Return whether or not a member pointers type is convertible to an IR type.
CodeGenTypes(CodeGenModule &cgm)
Represents a GCC generic vector type.
QualType getElementType() const
RecordDecl * getDefinition() const
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
TypedefNameDecl * getTypedefNameForAnonDecl() const
The l-value was considered opaque, so the alignment was determined from a type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
const TemplateArgument * iterator
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()
const T * castAs() const
Member-template castAs<specific type>.
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
printQualifiedName - Returns human-readable qualified name for declaration, like A::B::i, for i being member of namespace A::B.
QualType getPointeeType() const
bool isRecordBeingLaidOut(const Type *Ty) const
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.
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.
EnumDecl - Represents an enum.
detail::InMemoryDirectory::const_iterator E
A pointer to member type per C++ 8.3.3 - Pointers to members.
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const T * getAs() const
Member-template getAs<specific type>'.
llvm::Type * ConvertFunctionType(QualType FT, const FunctionDecl *FD=nullptr)
Converts the GlobalDecl into an llvm::Type.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
QualType getIntegerType() const
getIntegerType - Return the integer type this enum decl corresponds to.
Base for LValueReferenceType and RValueReferenceType.
bool isRecordLayoutComplete(const Type *Ty) const
isRecordLayoutComplete - Return true if the specified type is already completely laid out...
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.
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...
virtual llvm::Type * getPipeType()
void RefreshTypeCacheForClass(const CXXRecordDecl *RD)
Remove stale types from the type cache when an inheritance model gets assigned to a class...
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.
Represents a C array with a specified size that is not an integer-constant-expression.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
bool noRecordsBeingLaidOut() const
Represents the canonical version of C arrays with a specified constant size.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
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.