7#include "mlir/IR/BuiltinTypes.h"
24 builder(cgm.
getBuilder()), theCXXABI(cgm.getCXXABI()),
25 theABIInfo(cgm.getTargetCIRGenInfo().
getABIInfo()) {}
28 for (
auto i = functionInfos.begin(), e = functionInfos.end(); i != e;)
33 return *builder.getContext();
53 return !
tagType->isIncompleteType();
65 if (
const auto *fpt = dyn_cast<FunctionProtoType>(ft))
66 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; i++)
73mlir::Type CIRGenTypes::convertFunctionTypeInternal(
QualType qft) {
86 if (
const auto *fpt = dyn_cast<FunctionProtoType>(ft)) {
105 llvm::raw_svector_ostream outStream(typeName);
110 policy.AlwaysIncludeTypeForTemplateArgument =
true;
111 policy.PrintAsCanonical =
true;
116 .
print(outStream, policy);
120 outStream << builder.getUniqueAnonRecordName();
125 return builder.getUniqueRecordName(std::string(typeName));
130 const auto it = recordDeclTypes.find(ty);
131 return it != recordDeclTypes.end() && it->second.isComplete();
138 llvm::SmallPtrSetImpl<const RecordDecl *> &alreadyChecked);
145 llvm::SmallPtrSetImpl<const RecordDecl *> &alreadyChecked) {
148 if (!alreadyChecked.insert(rd).second)
152 "Expect RecordDecl to be CompleteDefinition");
173 if (
const CXXRecordDecl *crd = dyn_cast<CXXRecordDecl>(rd)) {
176 ->castAs<RecordType>()
178 ->getDefinitionOrSelf(),
179 cgt, alreadyChecked))
201 llvm::SmallPtrSetImpl<const RecordDecl *> &alreadyChecked) {
204 qt = at->getValueType();
237 return astContext.getTypeSize(
type) !=
238 astContext.getTypeSize(
type->getValueType());
245 const Type *key = astContext.getCanonicalTagType(rd).getTypePtr();
253 entry = builder.getIncompleteRecordTy(name, rd);
254 recordDeclTypes[key] = entry;
263 deferredRecords.push_back(rd);
268 bool insertResult = recordsBeingLaidOut.insert(key).second;
270 assert(insertResult &&
"isSafeToCovert() should have caught this.");
273 safeToConvertCache.clear();
276 if (
const auto *
cxxRecordDecl = dyn_cast<CXXRecordDecl>(rd)) {
278 if (base.isVirtual())
286 recordDeclTypes[key] = entry;
287 cirGenRecordLayouts[key] = std::move(layout);
290 bool eraseResult = recordsBeingLaidOut.erase(key);
292 assert(eraseResult &&
"record not in RecordsBeingLaidOut set?");
295 safeToConvertCache.clear();
299 if (recordsBeingLaidOut.empty())
300 while (!deferredRecords.empty())
307 type = astContext.getCanonicalType(
type);
310 if (astContext.getLangOpts().CUDAIsDevice) {
311 if (
type->isCUDADeviceBuiltinSurfaceType()) {
313 cgm.getTargetCIRGenInfo().getCUDADeviceBuiltinSurfaceDeviceType())
315 }
else if (
type->isCUDADeviceBuiltinTextureType()) {
317 cgm.getTargetCIRGenInfo().getCUDADeviceBuiltinTextureDeviceType())
329 TypeCacheTy::iterator tci =
typeCache.find(ty);
336 mlir::Type resultType =
nullptr;
339 llvm_unreachable(
"Should have been handled above");
341 case Type::Builtin: {
344 case BuiltinType::Void:
345 resultType = cgm.voidTy;
349 case BuiltinType::Bool:
354 case BuiltinType::Char_S:
355 case BuiltinType::Int:
356 case BuiltinType::Int128:
357 case BuiltinType::Long:
358 case BuiltinType::LongLong:
359 case BuiltinType::SChar:
360 case BuiltinType::Short:
361 case BuiltinType::WChar_S:
362 case BuiltinType::Accum:
363 case BuiltinType::Fract:
364 case BuiltinType::LongAccum:
365 case BuiltinType::LongFract:
366 case BuiltinType::ShortAccum:
367 case BuiltinType::ShortFract:
369 case BuiltinType::SatAccum:
370 case BuiltinType::SatFract:
371 case BuiltinType::SatLongAccum:
372 case BuiltinType::SatLongFract:
373 case BuiltinType::SatShortAccum:
374 case BuiltinType::SatShortFract:
381 case BuiltinType::SveInt8:
382 resultType = cir::VectorType::getScalable(builder.getSInt8Ty(), 16);
384 case BuiltinType::SveUint8:
385 resultType = cir::VectorType::getScalable(builder.getUInt8Ty(), 16);
387 case BuiltinType::SveInt16:
388 resultType = cir::VectorType::getScalable(builder.getSInt16Ty(), 8);
390 case BuiltinType::SveUint16:
391 resultType = cir::VectorType::getScalable(builder.getUInt16Ty(), 8);
393 case BuiltinType::SveFloat16:
394 resultType = cir::VectorType::getScalable(builder.getFp16Ty(), 8);
396 case BuiltinType::SveBFloat16:
397 resultType = cir::VectorType::getScalable(builder.getBfloat16Ty(), 8);
399 case BuiltinType::SveInt32:
400 resultType = cir::VectorType::getScalable(builder.getSInt32Ty(), 4);
402 case BuiltinType::SveUint32:
403 resultType = cir::VectorType::getScalable(builder.getUInt32Ty(), 4);
405 case BuiltinType::SveFloat32:
406 resultType = cir::VectorType::getScalable(builder.getSingleTy(), 4);
408 case BuiltinType::SveInt64:
409 resultType = cir::VectorType::getScalable(builder.getSInt64Ty(), 2);
411 case BuiltinType::SveUint64:
412 resultType = cir::VectorType::getScalable(builder.getUInt64Ty(), 2);
414 case BuiltinType::SveFloat64:
415 resultType = cir::VectorType::getScalable(builder.getDoubleTy(), 2);
417 case BuiltinType::SveBool:
418 resultType = cir::VectorType::getScalable(builder.getUIntNTy(1), 16);
422 case BuiltinType::Char8:
423 case BuiltinType::Char16:
424 case BuiltinType::Char32:
425 case BuiltinType::Char_U:
426 case BuiltinType::UChar:
427 case BuiltinType::UInt:
428 case BuiltinType::UInt128:
429 case BuiltinType::ULong:
430 case BuiltinType::ULongLong:
431 case BuiltinType::UShort:
432 case BuiltinType::WChar_U:
433 case BuiltinType::UAccum:
434 case BuiltinType::UFract:
435 case BuiltinType::ULongAccum:
436 case BuiltinType::ULongFract:
437 case BuiltinType::UShortAccum:
438 case BuiltinType::UShortFract:
440 case BuiltinType::SatUAccum:
441 case BuiltinType::SatUFract:
442 case BuiltinType::SatULongAccum:
443 case BuiltinType::SatULongFract:
444 case BuiltinType::SatUShortAccum:
445 case BuiltinType::SatUShortFract:
452 case BuiltinType::Float16:
453 resultType = cgm.fP16Ty;
455 case BuiltinType::Half:
456 resultType = cgm.fP16Ty;
458 case BuiltinType::BFloat16:
459 resultType = cgm.bFloat16Ty;
461 case BuiltinType::MFloat8:
462 resultType = cgm.uInt8Ty;
464 case BuiltinType::Float:
465 assert(&astContext.getFloatTypeSemantics(
type) ==
466 &llvm::APFloat::IEEEsingle() &&
467 "ClangIR NYI: 'float' in a format other than IEEE 32-bit");
468 resultType = cgm.floatTy;
470 case BuiltinType::Double:
471 assert(&astContext.getFloatTypeSemantics(
type) ==
472 &llvm::APFloat::IEEEdouble() &&
473 "ClangIR NYI: 'double' in a format other than IEEE 64-bit");
474 resultType = cgm.doubleTy;
476 case BuiltinType::LongDouble:
478 builder.getLongDoubleTy(astContext.getFloatTypeSemantics(
type));
480 case BuiltinType::Float128:
481 resultType = cgm.fP128Ty;
483 case BuiltinType::Ibm128:
485 resultType = cgm.sInt32Ty;
488 case BuiltinType::NullPtr:
493 resultType = builder.getVoidPtrTy();
496#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
497 case BuiltinType::Id: { \
498 if (BuiltinType::Id == BuiltinType::AMDGPUTexture) { \
499 resultType = cir::VectorType::getFixed(builder.getSInt32Ty(), 8); \
501 resultType = builder.getPointerTo( \
503 cir::TargetAddressSpaceAttr::get(&getMLIRContext(), AS)); \
507#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
508 case BuiltinType::Id: \
509 llvm_unreachable("NYI");
510#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) \
511 case BuiltinType::Id: \
512 llvm_unreachable("NYI");
513#include "clang/Basic/AMDGPUTypes.def"
517 resultType = cgm.sInt32Ty;
523 case Type::Complex: {
525 mlir::Type elementTy =
convertType(ct->getElementType());
526 resultType = cir::ComplexType::get(elementTy);
530 case Type::LValueReference:
531 case Type::RValueReference: {
537 assert(resultType &&
"Cannot get pointer type?");
541 case Type::Pointer: {
551 case Type::VariableArray: {
558 "Parameter types cannot make it here");
565 case Type::IncompleteArray: {
572 "Parameter types cannot make it here");
577 elemTy = cgm.sInt8Ty;
580 resultType = cir::ArrayType::get(elemTy, 0);
584 case Type::ConstantArray: {
592 resultType = cir::ArrayType::get(elemTy, arrTy->
getSize().getZExtValue());
596 case Type::ExtVector:
600 resultType = cir::VectorType::getFixed(elemTy, vec->
getNumElements());
604 case Type::ConstantMatrix: {
614 if (
auto integerType = ed->getIntegerType(); !integerType.isNull())
619 resultType = cgm.uInt32Ty;
623 case Type::MemberPointer: {
627 auto clsTy = mlir::cast<cir::RecordType>(
629 if (mpt->isMemberDataPointer()) {
630 mlir::Type memberTy =
convertType(mpt->getPointeeType());
631 resultType = cir::DataMemberType::get(memberTy, clsTy);
633 auto memberFuncTy =
getFunctionType(cgm.getTypes().arrangeCXXMethodType(
637 resultType = cir::MethodType::get(memberFuncTy, clsTy);
642 case Type::FunctionNoProto:
643 case Type::FunctionProto:
644 resultType = convertFunctionTypeInternal(
type);
649 unsigned numBits = bitIntTy->getNumBits();
650 assert(numBits <= cir::IntType::maxBitwidth() &&
651 "_BitInt width exceeds CIR IntType maximum");
653 cir::IntType::get(&
getMLIRContext(), numBits, bitIntTy->isSigned(),
663 uint64_t valueSize = astContext.getTypeSize(valueType);
664 uint64_t atomicSize = astContext.getTypeSize(ty);
665 if (valueSize != atomicSize) {
666 assert(valueSize < atomicSize);
668 cir::ArrayType::get(cgm.sInt8Ty, (atomicSize - valueSize) / 8);
669 mlir::Type elements[] = {resultType, paddingArray};
670 cir::RecordMemberKind kinds[] = {cir::RecordMemberKind::Data,
671 cir::RecordMemberKind::Pad};
674 false,
false, kinds);
682 type->getTypeClassName());
683 resultType = cgm.sInt32Ty;
687 assert(resultType &&
"Type conversion not yet implemented");
695 if (astContext.getLangOpts().HLSL &&
qualType->isConstantMatrixType()) {
697 cgm.errorNYI(
"convertTypeForMem: HLSL & Matrix row major");
703 assert(!forBitField &&
"Bit fields NYI");
707 if (forBitField &&
qualType->isBitIntType())
708 assert(!
qualType->isBitIntType() &&
"Bit field with type _BitInt NYI");
710 return convertedType;
716 const auto *key = astContext.getCanonicalTagType(rd).getTypePtr();
719 auto it = cirGenRecordLayouts.find(key);
720 if (it != cirGenRecordLayouts.end())
727 it = cirGenRecordLayouts.find(key);
729 assert(it != cirGenRecordLayouts.end() &&
730 "Unable to find record layout information for type");
736 return astContext.getTargetNullPointerValue(t) == 0;
738 if (
const auto *at = astContext.getAsArrayType(t)) {
742 if (
const auto *cat = dyn_cast<ConstantArrayType>(at))
743 if (astContext.getConstantArrayElementCount(cat) == 0)
746 t = astContext.getBaseElementType(t);
753 return theCXXABI.isZeroInitializable(mpt);
755 if (t->
getAs<HLSLInlineSpirvType>())
757 "isZeroInitializable for HLSLInlineSpirvType");
771 if (cgm.getTriple().isSPIROrSPIRV())
772 return cir::CallingConv::SpirFunction;
773 return cir::CallingConv::C;
775 return cgm.getTargetCIRGenInfo().getDeviceKernelCallingConv();
780 return cir::CallingConv::C;
798 if (
const CXXRecordDecl *cxxRD = dyn_cast<CXXRecordDecl>(rd)) {
814 assert(llvm::all_of(argTypes,
819 if (containsAtomic(returnType) || llvm::any_of(argTypes, containsAtomic))
820 cgm.errorNYI(
"passing or returning atomic types");
822 llvm::FoldingSetNodeID id;
826 llvm::FoldingSetInsertToken insertToken;
834 "Bad match based on CIRGenFunctionInfo folding set id");
843 functionInfos.insert(fi, insertToken);
852 for (
const VarDecl *arg : args)
853 argTypes.push_back(astContext.getCanonicalParamType(arg->getType()));
863 assert(!dyn_cast<ObjCMethodDecl>(gd.
getDecl()) &&
864 "This is reported as a FIXME in LLVM codegen");
880 if ([[maybe_unused]]
const auto *ed = dyn_cast<EnumDecl>(td)) {
888 ed->getASTContext().getCanonicalTagType(ed)->getTypePtr()) ||
890 typeCache[ed->getASTContext().getCanonicalTagType(ed)->getTypePtr()]));
900 if (rd->isDependentType())
905 if (recordDeclTypes.count(astContext.getCanonicalTagType(rd).getTypePtr()))
913mlir::ptr::MemorySpaceAttrInterface
927 return cir::TargetAddressSpaceAttr::get(&
getMLIRContext(), targetAS);
936 ? cgm.getDataLayout().getProgramAddressSpace()
Defines the clang::ASTContext interface.
static bool typeContainsAtomicForABI(QualType ty, ASTContext &ctx)
Whether a by-value ABI type is _Atomic or contains an _Atomic member.
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)
Defines AST-level helper utilities for matrix types.
C Language Family Type Representation.
C++ view class that accepts both !cir.struct and !cir.union types.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CanQualType getCanonicalTagType(const TagDecl *TD) const
unsigned getTargetAddressSpace(LangAS AS) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
unsigned getIndexTypeCVRQualifiers() const
CanQualType getReturnType() const
const_arg_iterator argTypesEnd() const
static CIRGenFunctionInfo * create(cir::CallingConv cirCC, FunctionType::ExtInfo info, bool instanceMethod, CanQualType resultType, llvm::ArrayRef< CanQualType > argTypes, RequiredArgs required)
static void Profile(llvm::FoldingSetNodeID &id, bool instanceMethod, FunctionType::ExtInfo info, RequiredArgs required, CanQualType resultType, llvm::ArrayRef< CanQualType > argTypes)
const_arg_iterator argTypesBegin() const
This class organizes the cross-function state that is used while generating CIR code.
bool isPaddedAtomicType(QualType type)
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.
cir::CallingConv clangCallConvToCIRCallConv(clang::CallingConv cc)
Convert a clang calling convention to a CIR calling convention.
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
unsigned getTargetAddressSpace(QualType ty) const
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCIRFunctionInfo(CanQualType returnType, bool isInstanceMethod, llvm::ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, RequiredArgs required)
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::ptr::MemorySpaceAttrInterface getPointerAddressSpace(clang::QualType pointeeTy) const
Returns the CIR address space for a pointer/reference to pointeeTy, or a null attribute for the defau...
CIRGenBuilderTy & getBuilder() const
mlir::MLIRContext & getMLIRContext() const
bool isCachedSafeToConvert(const clang::Type *key) const
Check if a record type key is in the safe-to-convert cache.
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 ABIInfo & getABIInfo() 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.
const CIRGenFunctionInfo & arrangeDeviceKernelCallerDeclaration(clang::QualType resultType, const FunctionArgList &args)
Arrange the function info for a device kernel caller entry point (e.g.
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.
void cacheSafeToConvert(const clang::Type *key)
Add a record type key to the safe-to-convert cache.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
Type for representing both the decl and type of parameters to a function.
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.
static CanQual< T > CreateUnsafe(QualType Other)
Builds a canonical type from a QualType.
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 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.
Represents a member of a struct/union/class.
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.
A class which abstracts out some details necessary for making a call.
FunctionType - C99 6.7.5.3 - Function Declarators.
static StringRef getNameForCallConv(CallingConv CC)
QualType getReturnType() const
GlobalDecl - represents a global declaration.
const Decl * getDecl() 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.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier, or null.
const Type * getAsType() const
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.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
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.
The base class of the type hierarchy.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
CanQualType getCanonicalTypeUnqualified() const
bool isAtomicType() const
EnumDecl * castAsEnumDecl() const
bool isFunctionType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
Represents a variable declaration or definition.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
Defines the clang::TargetInfo interface.
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
bool isSized(mlir::Type ty)
Returns true if the type is a CIR sized type.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
const internal::VariadicDynCastAllOfMatcher< Decl, TypedefNameDecl > typedefNameDecl
Matches typedef name declarations.
const AstTypeMatcher< TagType > tagType
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< RecordType > recordType
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.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
QualType pointeeType(QualType T)
bool isInstanceMethod(const Decl *D)
bool isMatrixRowMajor(const LangOptions &LangOpts, QualType T)
Returns true if matrices of T should be laid out in row-major order.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
static bool cudaTextureType()
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 SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.