28#include "llvm/IR/DataLayout.h"
29#include "llvm/IR/DerivedTypes.h"
30#include "llvm/IR/Module.h"
36 : CGM(cgm), Context(cgm.
getContext()), TheModule(cgm.getModule()),
38 SkippedLayout =
false;
39 LongDoubleReferenced =
false;
43 for (llvm::FoldingSet<CGFunctionInfo>::iterator
44 I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; )
51 return CGM.getCodeGenOpts();
58 llvm::raw_svector_ostream OS(
TypeName);
80 if (TDD->getDeclContext())
81 TDD->printQualifiedName(OS, Policy);
90 Ty->setName(OS.str());
105 if (
const auto *ArrayTy = dyn_cast<ConstantArrayType>(
T.getTypePtr())) {
107 return llvm::ArrayType::get(ElementTy, ArrayTy->getZExtSize());
110 if (
T->isConstantMatrixType()) {
111 const Type *Ty = Context.getCanonicalType(
T).getTypePtr();
114 if (Context.getLangOpts().HLSL) {
115 if (
T->isConstantMatrixBoolType())
121 unsigned VecLen = IsRowMajor ? NumCols : NumRows;
122 unsigned ArrayLen = IsRowMajor ? NumRows : NumCols;
123 llvm::Type *VecTy = llvm::FixedVectorType::get(IRElemTy, VecLen);
124 return llvm::ArrayType::get(VecTy, ArrayLen);
132 if (
T->isExtVectorBoolType()) {
135 if (Context.getLangOpts().HLSL) {
137 return llvm::FixedVectorType::get(IRElemTy, FixedVT->getNumElements());
141 uint64_t BytePadded = std::max<uint64_t>(FixedVT->getNumElements(), 8);
142 return llvm::IntegerType::get(FixedVT->getContext(), BytePadded);
158 if (
T->isBitIntType()) {
160 return llvm::ArrayType::get(CGM.Int8Ty,
161 Context.getTypeSizeInChars(
T).getQuantity());
163 (
unsigned)Context.getTypeSize(
T));
166 if (R->isIntegerTy(1))
168 (
unsigned)Context.getTypeSize(
T));
175 llvm::Type *LLVMTy) {
179 CharUnits ASTSize = Context.getTypeSizeInChars(ASTTy);
182 return ASTSize != LLVMSize;
186 llvm::Type *LLVMTy) {
190 if (
T->isBitIntType())
191 return llvm::Type::getIntNTy(
194 if (LLVMTy->isIntegerTy(1))
196 (
unsigned)Context.getTypeSize(
T));
198 if (
T->isConstantMatrixBoolType()) {
202 const Type *Ty = Context.getCanonicalType(
T).getTypePtr();
208 if (
T->isExtVectorBoolType())
217 llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I =
218 RecordDeclTypes.find(Ty);
219 return I != RecordDeclTypes.end() && !I->second->isOpaque();
232 const TagType *TT = Ty->
getAs<TagType>();
233 if (!TT)
return true;
236 return !TT->isIncompleteType();
250 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
260 CanQualType T = CGM.getContext().getCanonicalTagType(TD);
264 if (
const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
266 if (TypeCache.count(
T->getTypePtr())) {
270 if (!
ConvertType(ED->getIntegerType())->isIntegerTy(32))
276 DI->completeType(ED);
287 if (RecordDeclTypes.count(
T.getTypePtr()))
293 DI->completeType(RD);
298 T = Context.getCanonicalType(
T);
300 const Type *Ty =
T.getTypePtr();
301 if (RecordsWithOpaqueMemberPointers.count(Ty)) {
303 RecordsWithOpaqueMemberPointers.clear();
307llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(
QualType QFT) {
321 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
322 if (
const auto *RD = FPT->getParamType(i)->getAsRecordDecl())
325 SkippedLayout =
true;
343 llvm::Type *ResultType =
nullptr;
346 if (FunctionsBeingProcessed.count(FI)) {
349 SkippedLayout =
true;
361 T = Context.getCanonicalType(
T);
363 const Type *Ty =
T.getTypePtr();
367 if (Context.getLangOpts().CUDAIsDevice) {
368 if (
T->isCUDADeviceBuiltinSurfaceType()) {
369 if (
auto *Ty = CGM.getTargetCodeGenInfo()
370 .getCUDADeviceBuiltinSurfaceDeviceType())
372 }
else if (
T->isCUDADeviceBuiltinTextureType()) {
373 if (
auto *Ty = CGM.getTargetCodeGenInfo()
374 .getCUDADeviceBuiltinTextureDeviceType())
380 if (
const auto *RT = dyn_cast<RecordType>(Ty))
383 llvm::Type *CachedType =
nullptr;
384 auto TCI = TypeCache.find(Ty);
385 if (TCI != TypeCache.end())
386 CachedType = TCI->second;
389#ifndef EXPENSIVE_CHECKS
395 llvm::Type *ResultType =
nullptr;
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.inc"
404 llvm_unreachable(
"Non-canonical or dependent types aren't possible.");
406 case Type::Builtin: {
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::Char8:
437 case BuiltinType::Char16:
438 case BuiltinType::Char32:
439 case BuiltinType::ShortAccum:
440 case BuiltinType::Accum:
441 case BuiltinType::LongAccum:
442 case BuiltinType::UShortAccum:
443 case BuiltinType::UAccum:
444 case BuiltinType::ULongAccum:
445 case BuiltinType::ShortFract:
446 case BuiltinType::Fract:
447 case BuiltinType::LongFract:
448 case BuiltinType::UShortFract:
449 case BuiltinType::UFract:
450 case BuiltinType::ULongFract:
451 case BuiltinType::SatShortAccum:
452 case BuiltinType::SatAccum:
453 case BuiltinType::SatLongAccum:
454 case BuiltinType::SatUShortAccum:
455 case BuiltinType::SatUAccum:
456 case BuiltinType::SatULongAccum:
457 case BuiltinType::SatShortFract:
458 case BuiltinType::SatFract:
459 case BuiltinType::SatLongFract:
460 case BuiltinType::SatUShortFract:
461 case BuiltinType::SatUFract:
462 case BuiltinType::SatULongFract:
464 static_cast<unsigned>(Context.getTypeSize(
T)));
467 case BuiltinType::Float16:
468 ResultType = llvm::Type::getFloatingPointTy(
472 case BuiltinType::Half:
475 ResultType = llvm::Type::getFloatingPointTy(
478 case BuiltinType::LongDouble:
479 LongDoubleReferenced =
true;
481 case BuiltinType::BFloat16:
482 case BuiltinType::Float:
483 case BuiltinType::Double:
484 case BuiltinType::Float128:
485 case BuiltinType::Ibm128:
486 ResultType = llvm::Type::getFloatingPointTy(
490 case BuiltinType::NullPtr:
495 case BuiltinType::MetaInfo:
502 case BuiltinType::UInt128:
503 case BuiltinType::Int128:
507#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
508 case BuiltinType::Id:
509#include "clang/Basic/OpenCLImageTypes.def"
510#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
511 case BuiltinType::Id:
512#include "clang/Basic/OpenCLExtensionTypes.def"
513 case BuiltinType::OCLSampler:
514 case BuiltinType::OCLEvent:
515 case BuiltinType::OCLClkEvent:
516 case BuiltinType::OCLQueue:
517 case BuiltinType::OCLReserveID:
518 ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty);
520#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \
521 case BuiltinType::Id:
522#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
523 case BuiltinType::Id:
524#include "clang/Basic/AArch64ACLETypes.def"
534 auto *VTy = llvm::VectorType::get(EltTy, Info.
EC);
537 llvm_unreachable(
"Expected 1, 2, 3 or 4 vectors!");
541 return llvm::StructType::get(VTy, VTy);
543 return llvm::StructType::get(VTy, VTy, VTy);
545 return llvm::StructType::get(VTy, VTy, VTy, VTy);
548 case BuiltinType::SveCount:
549 return llvm::TargetExtType::get(
getLLVMContext(),
"aarch64.svcount");
550 case BuiltinType::MFloat8:
551 return llvm::VectorType::get(llvm::Type::getInt8Ty(
getLLVMContext()), 1,
553#define PPC_VECTOR_TYPE(Name, Id, Size) \
554 case BuiltinType::Id: \
556 llvm::FixedVectorType::get(ConvertType(Context.BoolTy), Size); \
558#include "clang/Basic/PPCTypes.def"
559#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
560#include "clang/Basic/RISCVVTypes.def"
565 unsigned I8EltCount =
566 Info.
EC.getKnownMinValue() *
568 return llvm::TargetExtType::get(
570 llvm::ScalableVectorType::get(
575 Info.
EC.getKnownMinValue());
577#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
578 case BuiltinType::Id: { \
579 if (BuiltinType::Id == BuiltinType::WasmExternRef) \
580 ResultType = CGM.getTargetCodeGenInfo().getWasmExternrefReferenceType(); \
582 llvm_unreachable("Unexpected wasm reference builtin type!"); \
584#include "clang/Basic/WebAssemblyReferenceTypes.def"
585#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
586 case BuiltinType::Id: { \
587 if (BuiltinType::Id == BuiltinType::AMDGPUTexture) { \
588 return llvm::FixedVectorType::get( \
589 llvm::Type::getInt32Ty(getLLVMContext()), 8); \
591 return llvm::PointerType::get(getLLVMContext(), AS); \
593#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
594 case BuiltinType::Id: \
595 return llvm::TargetExtType::get(getLLVMContext(), "amdgcn.named.barrier", \
597#define AMDGPU_FEATURE_PREDICATE_TYPE(Name, Id, SingletonId, Width, Align) \
598 case BuiltinType::Id: \
599 return ConvertType(getContext().getLogicalOperationType());
600#include "clang/Basic/AMDGPUTypes.def"
601#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
602#include "clang/Basic/HLSLIntangibleTypes.def"
603 ResultType = CGM.getHLSLRuntime().convertHLSLSpecificType(Ty);
605#define HLSL_PACKED_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
606#include "clang/Basic/HLSLPackedTypes.def"
609#define SPIRV_TYPE(Name, Id, SingletonId) \
610 case BuiltinType::Id: \
611 return llvm::TargetExtType::get(getLLVMContext(), "spirv.Event");
612#include "clang/Basic/SPIRVTypes.def"
613 case BuiltinType::Dependent:
614#define BUILTIN_TYPE(Id, SingletonId)
615#define PLACEHOLDER_TYPE(Id, SingletonId) \
616 case BuiltinType::Id:
617#include "clang/AST/BuiltinTypes.def"
618 llvm_unreachable(
"Unexpected placeholder builtin type!");
623 case Type::DeducedTemplateSpecialization:
624 llvm_unreachable(
"Unexpected undeduced type!");
625 case Type::Complex: {
627 ResultType = llvm::StructType::get(EltTy, EltTy);
630 case Type::LValueReference:
631 case Type::RValueReference: {
638 case Type::Pointer: {
642 ResultType = CGM.getTargetCodeGenInfo().getWasmFuncrefReferenceType();
650 case Type::VariableArray: {
653 "FIXME: We only handle trivial array types so far!");
659 case Type::IncompleteArray: {
662 "FIXME: We only handle trivial array types so far!");
666 if (!ResultType->isSized()) {
667 SkippedLayout =
true;
670 ResultType = llvm::ArrayType::get(ResultType, 0);
673 case Type::ArrayParameter:
674 case Type::ConstantArray: {
680 if (!EltTy->isSized()) {
681 SkippedLayout =
true;
685 ResultType = llvm::ArrayType::get(EltTy, A->
getZExtSize());
688 case Type::ExtVector:
692 llvm::Type *IRElemTy = VT->isPackedVectorBoolType(Context)
694 : VT->getElementType()->isMFloat8Type()
697 ResultType = llvm::FixedVectorType::get(IRElemTy, VT->getNumElements());
700 case Type::ConstantMatrix: {
707 case Type::FunctionNoProto:
708 case Type::FunctionProto:
709 ResultType = ConvertFunctionTypeInternal(
T);
711 case Type::ObjCObject:
715 case Type::ObjCInterface: {
726 case Type::ObjCObjectPointer:
732 if (ED->isCompleteDefinition() || ED->isFixed())
741 case Type::BlockPointer: {
754 case Type::MemberPointer: {
756 if (!
getCXXABI().isMemberPointerConvertible(MPTy)) {
758 MPTy->getMostRecentCXXRecordDecl());
760 RecordsWithOpaqueMemberPointers.try_emplace(
T.getTypePtr());
761 if (Insertion.second)
762 Insertion.first->second = llvm::StructType::create(
getLLVMContext());
763 ResultType = Insertion.first->second;
775 uint64_t valueSize = Context.getTypeSize(valueType);
776 uint64_t atomicSize = Context.getTypeSize(Ty);
777 if (valueSize != atomicSize) {
778 assert(valueSize < atomicSize);
779 llvm::Type *elts[] = {
781 llvm::ArrayType::get(CGM.Int8Ty, (atomicSize - valueSize) / 8)
789 ResultType = CGM.getOpenCLRuntime().getPipeType(
cast<PipeType>(Ty));
794 ResultType = llvm::Type::getIntNTy(
getLLVMContext(), EIT->getNumBits());
797 case Type::HLSLAttributedResource:
798 case Type::HLSLInlineSpirv:
799 ResultType = CGM.getHLSLRuntime().convertHLSLSpecificType(Ty);
801 case Type::OverflowBehavior:
807 assert(ResultType &&
"Didn't convert a type?");
808 assert((!CachedType || CachedType == ResultType) &&
809 "Cached type doesn't match computed type");
811 TypeCache[Ty] = ResultType;
820 return Context.getTypeSize(
type) != Context.getTypeSize(
type->getValueType());
827 const Type *Key = Context.getCanonicalTagType(RD).getTypePtr();
829 llvm::StructType *&Entry = RecordDeclTypes[Key];
836 llvm::StructType *Ty = Entry;
845 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
846 for (
const auto &I : CRD->bases()) {
847 if (I.isVirtual())
continue;
854 CGRecordLayouts[Key] = std::move(Layout);
868 const Type *Key = Context.getCanonicalTagType(RD).getTypePtr();
870 auto I = CGRecordLayouts.find(Key);
871 if (I != CGRecordLayouts.end())
877 I = CGRecordLayouts.find(Key);
879 assert(I != CGRecordLayouts.end() &&
880 "Unable to find record layout information for type");
885 assert((
T->isAnyPointerType() ||
T->isBlockPointerType() ||
886 T->isNullPtrType()) &&
893 return Context.getTargetNullPointerValue(
T) == 0;
895 if (
const auto *AT = Context.getAsArrayType(
T)) {
898 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
899 if (Context.getConstantArrayElementCount(CAT) == 0)
901 T = Context.getBaseElementType(
T);
906 if (
const auto *RD =
T->getAsRecordDecl())
914 if (
T->getAs<HLSLInlineSpirvType>())
930 return T->isFunctionType() && !
T.hasAddressSpace()
Defines the clang::ASTContext interface.
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines AST-level helper utilities for matrix types.
static QualType getUnderlyingType(const SubRegion *R)
static CharUnits getTypeAllocSize(CodeGenModule &CGM, llvm::Type *type)
const clang::PrintingPolicy & getPrintingPolicy() const
unsigned getTargetAddressSpace(LangAS AS) const
QualType getElementType() const
unsigned getIndexTypeCVRQualifiers() const
Represents a C++ struct/union/class.
static CanQual< T > CreateUnsafe(QualType Other)
Builds a canonical type from a QualType.
This is an opaque type for sizes expressed in character units.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
Implements C++ ABI-specific code generation functions.
virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const
Return whether or not a member pointers type is convertible to an IR type.
virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
Find the LLVM type used to represent the given member pointer type.
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...
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
CGFunctionInfo - Class to encapsulate the information about a function definition.
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
bool isZeroInitializable() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer.
This class organizes the cross-function state that is used while generating LLVM code.
bool isPaddedAtomicType(QualType type)
CGCXXABI & getCXXABI() const
CodeGenTypes(CodeGenModule &cgm)
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
CGCXXABI & getCXXABI() const
bool isPointerZeroInitializable(QualType T)
Check if the pointer type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
const CodeGenOptions & getCodeGenOpts() const
ASTContext & getContext() const
const CGFunctionInfo & arrangeFreeFunctionType(CanQual< FunctionProtoType > Ty)
Arrange the argument and result information for a value of the given freestanding function type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i....
const TargetInfo & getTarget() const
std::unique_ptr< CGRecordLayout > ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty)
Compute a new LLVM record layout object for the given record.
llvm::Type * convertTypeForLoadStore(QualType T, llvm::Type *LLVMTy=nullptr)
Given that T is a scalar type, return the IR type that should be used for load and store operations.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
unsigned getTargetAddressSpace(QualType T) const
llvm::StructType * ConvertRecordDeclType(const RecordDecl *TD)
ConvertRecordDeclType - Lay out a tagged decl type like struct or union.
void RefreshTypeCacheForClass(const CXXRecordDecl *RD)
Remove stale types from the type cache when an inheritance model gets assigned to a class.
bool isRecordLayoutComplete(const Type *Ty) const
isRecordLayoutComplete - Return true if the specified type is already completely laid out.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
CodeGenModule & getCGM() const
void UpdateCompletedType(const TagDecl *TD)
UpdateCompletedType - When we find the full definition for a TagDecl, replace the 'opaque' type we pr...
llvm::LLVMContext & getLLVMContext()
bool typeRequiresSplitIntoByteArray(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
Check whether the given type needs to be laid out in memory using an opaque byte-array type because i...
const llvm::DataLayout & getDataLayout() const
bool isFuncParamTypeConvertible(QualType Ty)
isFuncParamTypeConvertible - Return true if the specified type in a function parameter or result posi...
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
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...
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
unsigned getNumElementsFlattened() const
Returns the number of elements required to embed the matrix into a vector.
ASTContext & getASTContext() const LLVM_READONLY
DeclContext * getDeclContext()
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.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
Represents a C array with an unspecified size.
QualType getElementType() const
Returns type of the elements being stored in the matrix.
A pointer to member type per C++ 8.3.3 - Pointers to members.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
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.
LangAS getAddressSpace() const
Return the address space of this type.
Represents a struct/union/class.
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
Base for LValueReferenceType and RValueReferenceType.
QualType getPointeeType() const
Represents the declaration of a struct/union/class/enum.
StringRef getKindName() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override
Pretty-print the unqualified name of this declaration.
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
bool isMFloat8Type() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
EnumDecl * castAsEnumDecl() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
Base class for declarations which introduce a typedef-name.
Represents a C array with a specified size that is not an integer-constant-expression.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
bool isMatrixRowMajor(const LangOptions &LangOpts, QualType T)
Returns true if matrices of T should be laid out in row-major order.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.