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);
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);
276 const llvm::fltSemantics &format,
277 bool UseNativeHalf =
false) {
278 if (&format == &llvm::APFloat::IEEEhalf) {
280 return llvm::Type::getHalfTy(VMContext);
282 return llvm::Type::getInt16Ty(VMContext);
284 if (&format == &llvm::APFloat::IEEEsingle)
285 return llvm::Type::getFloatTy(VMContext);
286 if (&format == &llvm::APFloat::IEEEdouble)
287 return llvm::Type::getDoubleTy(VMContext);
288 if (&format == &llvm::APFloat::IEEEquad)
289 return llvm::Type::getFP128Ty(VMContext);
290 if (&format == &llvm::APFloat::PPCDoubleDouble)
291 return llvm::Type::getPPC_FP128Ty(VMContext);
292 if (&format == &llvm::APFloat::x87DoubleExtended)
293 return llvm::Type::getX86_FP80Ty(VMContext);
294 llvm_unreachable(
"Unknown float format!");
313 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
317 SkippedLayout =
true;
326 if (!RecordsBeingLaidOut.insert(Ty).second) {
327 SkippedLayout =
true;
346 if (FunctionsBeingProcessed.count(FI)) {
349 SkippedLayout =
true;
356 RecordsBeingLaidOut.erase(Ty);
361 if (RecordsBeingLaidOut.empty())
362 while (!DeferredRecords.empty())
374 if (
const RecordType *RT = dyn_cast<RecordType>(Ty))
380 if (TCI != TypeCache.end())
387 #define TYPE(Class, Base)
388 #define ABSTRACT_TYPE(Class, Base)
389 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
390 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
391 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
392 #include "clang/AST/TypeNodes.def"
393 llvm_unreachable(
"Non-canonical or dependent types aren't possible.");
395 case Type::Builtin: {
396 switch (cast<BuiltinType>(Ty)->
getKind()) {
397 case BuiltinType::Void:
398 case BuiltinType::ObjCId:
399 case BuiltinType::ObjCClass:
400 case BuiltinType::ObjCSel:
406 case BuiltinType::Bool:
411 case BuiltinType::Char_S:
412 case BuiltinType::Char_U:
413 case BuiltinType::SChar:
414 case BuiltinType::UChar:
415 case BuiltinType::Short:
416 case BuiltinType::UShort:
417 case BuiltinType::Int:
418 case BuiltinType::UInt:
419 case BuiltinType::Long:
420 case BuiltinType::ULong:
421 case BuiltinType::LongLong:
422 case BuiltinType::ULongLong:
423 case BuiltinType::WChar_S:
424 case BuiltinType::WChar_U:
425 case BuiltinType::Char16:
426 case BuiltinType::Char32:
431 case BuiltinType::Half:
438 case BuiltinType::Float:
439 case BuiltinType::Double:
440 case BuiltinType::LongDouble:
446 case BuiltinType::NullPtr:
451 case BuiltinType::UInt128:
452 case BuiltinType::Int128:
456 case BuiltinType::OCLImage1d:
457 case BuiltinType::OCLImage1dArray:
458 case BuiltinType::OCLImage1dBuffer:
459 case BuiltinType::OCLImage2d:
460 case BuiltinType::OCLImage2dArray:
461 case BuiltinType::OCLImage2dDepth:
462 case BuiltinType::OCLImage2dArrayDepth:
463 case BuiltinType::OCLImage2dMSAA:
464 case BuiltinType::OCLImage2dArrayMSAA:
465 case BuiltinType::OCLImage2dMSAADepth:
466 case BuiltinType::OCLImage2dArrayMSAADepth:
467 case BuiltinType::OCLImage3d:
468 case BuiltinType::OCLSampler:
469 case BuiltinType::OCLEvent:
470 case BuiltinType::OCLClkEvent:
471 case BuiltinType::OCLQueue:
472 case BuiltinType::OCLNDRange:
473 case BuiltinType::OCLReserveID:
477 case BuiltinType::Dependent:
478 #define BUILTIN_TYPE(Id, SingletonId)
479 #define PLACEHOLDER_TYPE(Id, SingletonId) \
480 case BuiltinType::Id:
481 #include "clang/AST/BuiltinTypes.def"
482 llvm_unreachable(
"Unexpected placeholder builtin type!");
487 llvm_unreachable(
"Unexpected undeduced auto type!");
488 case Type::Complex: {
490 ResultType = llvm::StructType::get(EltTy, EltTy,
nullptr);
493 case Type::LValueReference:
494 case Type::RValueReference: {
499 ResultType = llvm::PointerType::get(PointeeType, AS);
502 case Type::Pointer: {
506 if (PointeeType->isVoidTy())
509 ResultType = llvm::PointerType::get(PointeeType, AS);
513 case Type::VariableArray: {
516 "FIXME: We only handle trivial array types so far!");
522 case Type::IncompleteArray: {
525 "FIXME: We only handle trivial array types so far!");
529 if (!ResultType->isSized()) {
530 SkippedLayout =
true;
533 ResultType = llvm::ArrayType::get(ResultType, 0);
536 case Type::ConstantArray: {
542 if (!EltTy->isSized()) {
543 SkippedLayout =
true;
547 ResultType = llvm::ArrayType::get(EltTy, A->
getSize().getZExtValue());
550 case Type::ExtVector:
557 case Type::FunctionNoProto:
558 case Type::FunctionProto:
561 case Type::ObjCObject:
562 ResultType =
ConvertType(cast<ObjCObjectType>(Ty)->getBaseType());
565 case Type::ObjCInterface: {
569 llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(Ty)];
576 case Type::ObjCObjectPointer: {
582 ResultType = T->getPointerTo();
587 const EnumDecl *ED = cast<EnumType>(Ty)->getDecl();
597 case Type::BlockPointer: {
598 const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();
601 ResultType = llvm::PointerType::get(PointeeType, AS);
605 case Type::MemberPointer: {
606 if (!
getCXXABI().isMemberPointerConvertible(cast<MemberPointerType>(Ty)))
614 QualType valueType = cast<AtomicType>(Ty)->getValueType();
618 uint64_t valueSize = Context.
getTypeSize(valueType);
620 if (valueSize != atomicSize) {
621 assert(valueSize < atomicSize);
624 llvm::ArrayType::get(CGM.
Int8Ty, (atomicSize - valueSize) / 8)
627 llvm::makeArrayRef(elts));
637 assert(ResultType &&
"Didn't convert a type?");
639 TypeCache[Ty] = ResultType;
657 llvm::StructType *&Entry = RecordDeclTypes[Key];
664 llvm::StructType *Ty = Entry;
674 DeferredRecords.push_back(RD);
679 bool InsertResult = RecordsBeingLaidOut.insert(Key).second;
681 assert(InsertResult &&
"Recursively compiling a struct?");
684 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
685 for (
const auto &
I : CRD->bases()) {
686 if (
I.isVirtual())
continue;
694 CGRecordLayouts[Key] = Layout;
697 bool EraseResult = RecordsBeingLaidOut.erase(Key); (void)EraseResult;
698 assert(EraseResult &&
"struct not in RecordsBeingLaidOut set?");
708 if (RecordsBeingLaidOut.empty())
709 while (!DeferredRecords.empty())
726 Layout = CGRecordLayouts.lookup(Key);
729 assert(Layout &&
"Unable to find record layout information for type");
739 if (isa<IncompleteArrayType>(AT))
741 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
750 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.
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)
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.
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.
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.
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()
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.