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::Float16:
452 case BuiltinType::Half:
459 case BuiltinType::Float:
460 case BuiltinType::Double:
461 case BuiltinType::LongDouble:
462 case BuiltinType::Float128:
468 case BuiltinType::NullPtr:
473 case BuiltinType::UInt128:
474 case BuiltinType::Int128:
478 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 479 case BuiltinType::Id: 480 #include "clang/Basic/OpenCLImageTypes.def" 481 case BuiltinType::OCLSampler:
482 case BuiltinType::OCLEvent:
483 case BuiltinType::OCLClkEvent:
484 case BuiltinType::OCLQueue:
485 case BuiltinType::OCLReserveID:
489 case BuiltinType::Dependent:
490 #define BUILTIN_TYPE(Id, SingletonId) 491 #define PLACEHOLDER_TYPE(Id, SingletonId) \ 492 case BuiltinType::Id: 493 #include "clang/AST/BuiltinTypes.def" 494 llvm_unreachable(
"Unexpected placeholder builtin type!");
499 case Type::DeducedTemplateSpecialization:
500 llvm_unreachable(
"Unexpected undeduced type!");
501 case Type::Complex: {
503 ResultType = llvm::StructType::get(EltTy, EltTy);
506 case Type::LValueReference:
507 case Type::RValueReference: {
512 ResultType = llvm::PointerType::get(PointeeType, AS);
515 case Type::Pointer: {
519 if (PointeeType->isVoidTy())
522 ResultType = llvm::PointerType::get(PointeeType, AS);
526 case Type::VariableArray: {
529 "FIXME: We only handle trivial array types so far!");
535 case Type::IncompleteArray: {
538 "FIXME: We only handle trivial array types so far!");
542 if (!ResultType->isSized()) {
543 SkippedLayout =
true;
546 ResultType = llvm::ArrayType::get(ResultType, 0);
549 case Type::ConstantArray: {
555 if (!EltTy->isSized()) {
556 SkippedLayout =
true;
560 ResultType = llvm::ArrayType::get(EltTy, A->
getSize().getZExtValue());
563 case Type::ExtVector:
570 case Type::FunctionNoProto:
571 case Type::FunctionProto:
574 case Type::ObjCObject:
575 ResultType =
ConvertType(cast<ObjCObjectType>(Ty)->getBaseType());
578 case Type::ObjCInterface: {
582 llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(Ty)];
589 case Type::ObjCObjectPointer: {
595 ResultType = T->getPointerTo();
600 const EnumDecl *ED = cast<EnumType>(Ty)->getDecl();
610 case Type::BlockPointer: {
611 const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();
614 ResultType = llvm::PointerType::get(PointeeType, AS);
618 case Type::MemberPointer: {
619 auto *MPTy = cast<MemberPointerType>(Ty);
621 RecordsWithOpaqueMemberPointers.insert(MPTy->getClass());
630 QualType valueType = cast<AtomicType>(Ty)->getValueType();
634 uint64_t valueSize = Context.
getTypeSize(valueType);
636 if (valueSize != atomicSize) {
637 assert(valueSize < atomicSize);
640 llvm::ArrayType::get(CGM.
Int8Ty, (atomicSize - valueSize) / 8)
643 llvm::makeArrayRef(elts));
653 assert(ResultType &&
"Didn't convert a type?");
655 TypeCache[Ty] = ResultType;
673 llvm::StructType *&Entry = RecordDeclTypes[Key];
680 llvm::StructType *Ty = Entry;
690 DeferredRecords.push_back(RD);
695 bool InsertResult = RecordsBeingLaidOut.insert(Key).second;
697 assert(InsertResult &&
"Recursively compiling a struct?");
700 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
701 for (
const auto &I : CRD->bases()) {
702 if (I.isVirtual())
continue;
710 CGRecordLayouts[Key] = Layout;
713 bool EraseResult = RecordsBeingLaidOut.erase(Key); (void)EraseResult;
714 assert(EraseResult &&
"struct not in RecordsBeingLaidOut set?");
724 if (RecordsBeingLaidOut.empty())
725 while (!DeferredRecords.empty())
742 Layout = CGRecordLayouts.lookup(Key);
745 assert(Layout &&
"Unable to find record layout information for type");
759 if (isa<IncompleteArrayType>(AT))
761 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
770 auto RD = cast<RecordDecl>(RT->getDecl());
bool noRecordsBeingLaidOut() const
CGCXXABI & getCXXABI() const
CGOpenCLRuntime & getOpenCLRuntime()
Return a reference to the configured OpenCL runtime.
Defines the clang::ASTContext interface.
An instance of this class is created to represent 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
isCompleteDefinition - 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
getIdentifier - Get the identifier that names this declaration, if there is one.
RecordDecl - Represents a struct/union/class.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
RecordDecl * getDefinition() const
getDefinition - 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 * 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 FunctionProtoType * T
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
printQualifiedName - Returns human-readable qualified name for declaration, like A::B::i, for i being member of namespace A::B.
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
TagDecl - 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.
virtual llvm::Type * getPipeType(const PipeType *T)
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.
EnumDecl - Represents an enum.
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
getIntegerType - 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.