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::Char16:
441 case BuiltinType::Char32:
446 case BuiltinType::Half:
453 case BuiltinType::Float:
454 case BuiltinType::Double:
455 case BuiltinType::LongDouble:
456 case BuiltinType::Float128:
462 case BuiltinType::NullPtr:
467 case BuiltinType::UInt128:
468 case BuiltinType::Int128:
472 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
473 case BuiltinType::Id:
474 #include "clang/Basic/OpenCLImageTypes.def"
475 case BuiltinType::OCLSampler:
476 case BuiltinType::OCLEvent:
477 case BuiltinType::OCLClkEvent:
478 case BuiltinType::OCLQueue:
479 case BuiltinType::OCLReserveID:
483 case BuiltinType::Dependent:
484 #define BUILTIN_TYPE(Id, SingletonId)
485 #define PLACEHOLDER_TYPE(Id, SingletonId) \
486 case BuiltinType::Id:
487 #include "clang/AST/BuiltinTypes.def"
488 llvm_unreachable(
"Unexpected placeholder builtin type!");
493 case Type::DeducedTemplateSpecialization:
494 llvm_unreachable(
"Unexpected undeduced type!");
495 case Type::Complex: {
497 ResultType = llvm::StructType::get(EltTy, EltTy);
500 case Type::LValueReference:
501 case Type::RValueReference: {
506 ResultType = llvm::PointerType::get(PointeeType, AS);
509 case Type::Pointer: {
513 if (PointeeType->isVoidTy())
516 ResultType = llvm::PointerType::get(PointeeType, AS);
520 case Type::VariableArray: {
523 "FIXME: We only handle trivial array types so far!");
529 case Type::IncompleteArray: {
532 "FIXME: We only handle trivial array types so far!");
536 if (!ResultType->isSized()) {
537 SkippedLayout =
true;
540 ResultType = llvm::ArrayType::get(ResultType, 0);
543 case Type::ConstantArray: {
549 if (!EltTy->isSized()) {
550 SkippedLayout =
true;
554 ResultType = llvm::ArrayType::get(EltTy, A->
getSize().getZExtValue());
557 case Type::ExtVector:
564 case Type::FunctionNoProto:
565 case Type::FunctionProto:
568 case Type::ObjCObject:
569 ResultType =
ConvertType(cast<ObjCObjectType>(Ty)->getBaseType());
572 case Type::ObjCInterface: {
576 llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(Ty)];
583 case Type::ObjCObjectPointer: {
589 ResultType = T->getPointerTo();
594 const EnumDecl *ED = cast<EnumType>(Ty)->getDecl();
604 case Type::BlockPointer: {
605 const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();
608 ResultType = llvm::PointerType::get(PointeeType, AS);
612 case Type::MemberPointer: {
613 auto *MPTy = cast<MemberPointerType>(Ty);
615 RecordsWithOpaqueMemberPointers.insert(MPTy->getClass());
624 QualType valueType = cast<AtomicType>(Ty)->getValueType();
628 uint64_t valueSize = Context.
getTypeSize(valueType);
630 if (valueSize != atomicSize) {
631 assert(valueSize < atomicSize);
634 llvm::ArrayType::get(CGM.
Int8Ty, (atomicSize - valueSize) / 8)
637 llvm::makeArrayRef(elts));
647 assert(ResultType &&
"Didn't convert a type?");
649 TypeCache[Ty] = ResultType;
667 llvm::StructType *&Entry = RecordDeclTypes[Key];
674 llvm::StructType *Ty = Entry;
684 DeferredRecords.push_back(RD);
689 bool InsertResult = RecordsBeingLaidOut.insert(Key).second;
691 assert(InsertResult &&
"Recursively compiling a struct?");
694 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
695 for (
const auto &
I : CRD->bases()) {
696 if (
I.isVirtual())
continue;
704 CGRecordLayouts[Key] = Layout;
707 bool EraseResult = RecordsBeingLaidOut.erase(Key); (void)EraseResult;
708 assert(EraseResult &&
"struct not in RecordsBeingLaidOut set?");
718 if (RecordsBeingLaidOut.empty())
719 while (!DeferredRecords.empty())
736 Layout = CGRecordLayouts.lookup(Key);
739 assert(Layout &&
"Unable to find record layout information for type");
753 if (isa<IncompleteArrayType>(AT))
755 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
764 auto RD = cast<RecordDecl>(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...
bool isBlockPointerType() const
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 isAnyPointerType() 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 ...
const LangOptions & getLangOpts() const
QualType getReturnType() const
virtual void printName(raw_ostream &os) 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...
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
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.
bool isPointerZeroInitializable(QualType T)
Check if the pointer type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer...
CodeGenTypes(CodeGenModule &cgm)
DeclContext * getDeclContext()
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.
TagDecl - Represents the declaration of a struct/union/class/enum.
Represents a canonical, potentially-qualified type.
const CodeGenOptions & getCodeGenOpts() const
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 CodeGenOptions & getCodeGenOpts() const
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.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
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.