17 : cgm(genModule), astContext(genModule.getASTContext()),
18 builder(cgm.getBuilder()), theCXXABI(cgm.getCXXABI()),
19 theABIInfo(cgm.getTargetCIRGenInfo().getABIInfo()) {}
22 for (
auto i = functionInfos.begin(), e = functionInfos.end(); i != e;)
27 return *builder.getContext();
45 return !
tagType->isIncompleteType();
57 if (
const auto *fpt = dyn_cast<FunctionProtoType>(ft))
58 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; i++)
65mlir::Type CIRGenTypes::convertFunctionTypeInternal(
QualType qft) {
78 if (
const auto *fpt = dyn_cast<FunctionProtoType>(ft)) {
97 llvm::raw_svector_ostream outStream(typeName);
107 .
print(outStream, policy);
121 const auto it = recordDeclTypes.find(ty);
122 return it != recordDeclTypes.end() && it->second.isComplete();
129 llvm::SmallPtrSetImpl<const RecordDecl *> &alreadyChecked);
136 llvm::SmallPtrSetImpl<const RecordDecl *> &alreadyChecked) {
139 if (!alreadyChecked.insert(rd).second)
143 "Expect RecordDecl to be CompleteDefinition");
158 if (
const CXXRecordDecl *crd = dyn_cast<CXXRecordDecl>(rd)) {
164 cgt, alreadyChecked))
182 llvm::SmallPtrSetImpl<const RecordDecl *> &alreadyChecked) {
185 qt = at->getValueType();
218 cir::RecordType entry = recordDeclTypes[key];
226 recordDeclTypes[key] = entry;
235 deferredRecords.push_back(rd);
240 bool insertResult = recordsBeingLaidOut.insert(key).second;
242 assert(insertResult &&
"isSafeToCovert() should have caught this.");
245 if (
const auto *
cxxRecordDecl = dyn_cast<CXXRecordDecl>(rd)) {
247 if (base.isVirtual())
255 recordDeclTypes[key] = entry;
256 cirGenRecordLayouts[key] = std::move(layout);
259 bool eraseResult = recordsBeingLaidOut.erase(key);
261 assert(eraseResult &&
"record not in RecordsBeingLaidOut set?");
269 if (recordsBeingLaidOut.empty())
270 while (!deferredRecords.empty())
283 recordType->getOriginalDecl()->getDefinitionOrSelf());
286 TypeCacheTy::iterator tci =
typeCache.find(ty);
293 mlir::Type resultType =
nullptr;
296 llvm_unreachable(
"Should have been handled above");
298 case Type::Builtin: {
299 switch (cast<BuiltinType>(ty)->
getKind()) {
301 case BuiltinType::Void:
306 case BuiltinType::Bool:
311 case BuiltinType::Char_S:
312 case BuiltinType::Int:
313 case BuiltinType::Int128:
314 case BuiltinType::Long:
315 case BuiltinType::LongLong:
316 case BuiltinType::SChar:
317 case BuiltinType::Short:
318 case BuiltinType::WChar_S:
324 case BuiltinType::Char8:
325 case BuiltinType::Char16:
326 case BuiltinType::Char32:
327 case BuiltinType::Char_U:
328 case BuiltinType::UChar:
329 case BuiltinType::UInt:
330 case BuiltinType::UInt128:
331 case BuiltinType::ULong:
332 case BuiltinType::ULongLong:
333 case BuiltinType::UShort:
334 case BuiltinType::WChar_U:
341 case BuiltinType::Float16:
344 case BuiltinType::Half:
353 case BuiltinType::BFloat16:
356 case BuiltinType::Float:
358 &llvm::APFloat::IEEEsingle() &&
359 "ClangIR NYI: 'float' in a format other than IEEE 32-bit");
362 case BuiltinType::Double:
364 &llvm::APFloat::IEEEdouble() &&
365 "ClangIR NYI: 'double' in a format other than IEEE 64-bit");
368 case BuiltinType::LongDouble:
372 case BuiltinType::Float128:
375 case BuiltinType::Ibm128:
380 case BuiltinType::NullPtr:
396 case Type::Complex: {
397 const auto *ct = cast<clang::ComplexType>(ty);
398 mlir::Type elementTy =
convertType(ct->getElementType());
399 resultType = cir::ComplexType::get(elementTy);
403 case Type::LValueReference:
404 case Type::RValueReference: {
409 assert(resultType &&
"Cannot get pointer type?");
413 case Type::Pointer: {
424 case Type::IncompleteArray: {
436 resultType = cir::ArrayType::get(elemTy, 0);
440 case Type::ConstantArray: {
452 resultType = cir::ArrayType::get(elemTy, arrTy->
getSize().getZExtValue());
456 case Type::ExtVector:
466 if (
auto integerType = ed->getIntegerType(); !integerType.isNull())
475 case Type::FunctionNoProto:
476 case Type::FunctionProto:
477 resultType = convertFunctionTypeInternal(
type);
481 const auto *bitIntTy = cast<BitIntType>(
type);
482 if (bitIntTy->getNumBits() > cir::IntType::maxBitwidth()) {
486 resultType = cir::IntType::get(&
getMLIRContext(), bitIntTy->getNumBits(),
487 bitIntTy->isSigned());
493 QualType valueType = cast<AtomicType>(ty)->getValueType();
497 uint64_t valueSize = astContext.
getTypeSize(valueType);
499 if (valueSize != atomicSize) {
500 cgm.
errorNYI(
"convertType: atomic type value size != atomic size");
508 type->getTypeClassName());
513 assert(resultType &&
"Type conversion not yet implemented");
521 assert(!
qualType->isConstantMatrixType() &&
"Matrix types NYI");
525 assert(!forBitField &&
"Bit fields NYI");
529 if (forBitField &&
qualType->isBitIntType())
530 assert(!
qualType->isBitIntType() &&
"Bit field with type _BitInt NYI");
532 return convertedType;
541 auto it = cirGenRecordLayouts.find(key);
542 if (it != cirGenRecordLayouts.end())
549 it = cirGenRecordLayouts.find(key);
551 assert(it != cirGenRecordLayouts.end() &&
552 "Unable to find record layout information for type");
561 if (isa<IncompleteArrayType>(at))
564 if (
const auto *cat = dyn_cast<ConstantArrayType>(at))
589 assert(llvm::all_of(argTypes,
592 llvm::FoldingSetNodeID id;
595 void *insertPos =
nullptr;
603 "Bad match based on CIRGenFunctionInfo folding set id");
611 functionInfos.InsertNode(fi, insertPos);
617 assert(!dyn_cast<ObjCMethodDecl>(gd.
getDecl()) &&
618 "This is reported as a FIXME in LLVM codegen");
619 const auto *fd = cast<FunctionDecl>(gd.
getDecl());
621 if (isa<CXXConstructorDecl>(gd.
getDecl()) ||
622 isa<CXXDestructorDecl>(gd.
getDecl())) {
624 "arrangeGlobalDeclaration for C++ constructor or destructor");
636 if (
const auto *ed = dyn_cast<EnumDecl>(td)) {
644 ed->getASTContext().getCanonicalTagType(ed)->getTypePtr()) ||
646 typeCache[ed->getASTContext().getCanonicalTagType(ed)->getTypePtr()]));
655 const auto *rd = cast<RecordDecl>(td);
656 if (rd->isDependentType())
Defines the clang::ASTContext interface.
static bool isSafeToConvert(QualType qt, CIRGenTypes &cgt, llvm::SmallPtrSetImpl< const RecordDecl * > &alreadyChecked)
Return true if it is safe to convert this field type, which requires the record elements contained by...
static Decl::Kind getKind(const Decl *D)
C Language Family Type Representation.
cir::PointerType getPointerTo(mlir::Type ty)
cir::PointerType getVoidPtrTy()
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const LangOptions & getLangOpts() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
const TargetInfo & getTargetInfo() const
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
CanQualType getCanonicalTagType(const TagDecl *TD) const
QualType getElementType() const
unsigned getIndexTypeCVRQualifiers() const
cir::RecordType getIncompleteRecordTy(llvm::StringRef name, const clang::RecordDecl *rd)
Get an incomplete CIR struct type.
std::string getUniqueRecordName(const std::string &baseName)
std::string getUniqueAnonRecordName()
cir::LongDoubleType getLongDoubleTy(const llvm::fltSemantics &format) const
CanQualType getReturnType() const
const_arg_iterator argTypesEnd() const
static void Profile(llvm::FoldingSetNodeID &id, RequiredArgs required, CanQualType resultType, llvm::ArrayRef< CanQualType > argTypes)
const_arg_iterator argTypesBegin() const
static CIRGenFunctionInfo * create(CanQualType resultType, llvm::ArrayRef< CanQualType > argTypes, RequiredArgs required)
This class organizes the cross-function state that is used while generating CIR code.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
This class handles record and union layout info while lowering AST types to CIR types.
bool isZeroInitializable() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer.
This class organizes the cross-module state that is used while lowering AST types to CIR types.
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeFreeFunctionType(CanQual< FunctionProtoType > fpt)
bool isZeroInitializable(clang::QualType ty)
Return whether a type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
bool isFuncTypeConvertible(const clang::FunctionType *ft)
Utility to check whether a function type can be converted to a CIR type (i.e.
CIRGenTypes(CIRGenModule &cgm)
bool isRecordBeingLaidOut(const clang::Type *ty) const
mlir::MLIRContext & getMLIRContext() const
const CIRGenFunctionInfo & arrangeCIRFunctionInfo(CanQualType returnType, llvm::ArrayRef< CanQualType > argTypes, RequiredArgs required)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
bool isFuncParamTypeConvertible(clang::QualType type)
Return true if the specified type in a function parameter or result position can be converted to a CI...
void updateCompletedType(const clang::TagDecl *td)
UpdateCompletedType - when we find the full definition for a TagDecl, replace the 'opaque' type we pr...
std::string getRecordTypeName(const clang::RecordDecl *, llvm::StringRef suffix)
bool noRecordsBeingLaidOut() const
const CIRGenFunctionInfo & arrangeFunctionDeclaration(const clang::FunctionDecl *fd)
Free functions are functions that are compatible with an ordinary C function pointer type.
clang::ASTContext & getASTContext() const
bool isRecordLayoutComplete(const clang::Type *ty) const
Return true if the specified type is already completely laid out.
mlir::Type convertType(clang::QualType type)
Convert a Clang type into a mlir::Type.
const CIRGenRecordLayout & getCIRGenRecordLayout(const clang::RecordDecl *rd)
Return record layout info for the given record decl.
std::unique_ptr< CIRGenRecordLayout > computeRecordLayout(const clang::RecordDecl *rd, cir::RecordType *ty)
mlir::Type convertRecordDeclType(const clang::RecordDecl *recordDecl)
Lay out a tagged decl type like struct or union.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
A class for recording the number of arguments that a function signature requires.
Represents a base class of a C++ class.
Represents a C++ struct/union/class.
Represents a canonical, potentially-qualified type.
bool isCanonicalAsParam() const
Determines if this canonical type is furthermore canonical as a parameter.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
Represents a member of a struct/union/class.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
GlobalDecl - represents a global declaration.
const Decl * getDecl() const
Represents a C array with an unspecified size.
A pointer to member type per C++ 8.3.3 - Pointers to members.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
RecordDecl * getDefinitionOrSelf() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
Base for LValueReferenceType and RValueReferenceType.
QualType getPointeeType() const
Encodes a location in the source.
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
The base class of the type hierarchy.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isConstantMatrixType() const
EnumDecl * castAsEnumDecl() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
Defines the clang::TargetInfo interface.
bool isSized(mlir::Type ty)
Returns true if the type is a CIR sized type.
const internal::VariadicDynCastAllOfMatcher< Decl, TypedefNameDecl > typedefNameDecl
Matches typedef name declarations.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< TagType > tagType
Matches tag types (record and enum types).
const AstTypeMatcher< RecordType > recordType
Matches record types (e.g.
const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl > cxxRecordDecl
Matches C++ class declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, RecordDecl > recordDecl
Matches class, struct, and union declarations.
const internal::VariadicAllOfMatcher< QualType > qualType
Matches QualTypes in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
static bool skippedLayout()
static bool opCallCallConv()
static bool generateDebugInfo()
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressTagKeyword
Whether type printing should skip printing the tag keyword.
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.