@@ -7346,6 +7346,102 @@ CompilerType TypeSystemClang::GetTypeForFormatters(void *type) {
73467346 return CompilerType ();
73477347}
73487348
7349+ bool TypeSystemClang::IsPromotableIntegerType (
7350+ lldb::opaque_compiler_type_t type) {
7351+ // Unscoped enums are always considered as promotable, even if their
7352+ // underlying type does not need to be promoted (e.g. "int").
7353+ bool is_signed = false ;
7354+ bool isUnscopedEnumerationType =
7355+ IsEnumerationType (type, is_signed) && !IsScopedEnumerationType (type);
7356+ if (isUnscopedEnumerationType)
7357+ return true ;
7358+
7359+ switch (GetBasicTypeEnumeration (type)) {
7360+ case lldb::eBasicTypeBool:
7361+ case lldb::eBasicTypeChar:
7362+ case lldb::eBasicTypeSignedChar:
7363+ case lldb::eBasicTypeUnsignedChar:
7364+ case lldb::eBasicTypeShort:
7365+ case lldb::eBasicTypeUnsignedShort:
7366+ case lldb::eBasicTypeWChar:
7367+ case lldb::eBasicTypeSignedWChar:
7368+ case lldb::eBasicTypeUnsignedWChar:
7369+ case lldb::eBasicTypeChar16:
7370+ case lldb::eBasicTypeChar32:
7371+ return true ;
7372+
7373+ default :
7374+ return false ;
7375+ }
7376+
7377+ llvm_unreachable (" All cases handled above." );
7378+ }
7379+
7380+ llvm::Expected<CompilerType>
7381+ TypeSystemClang::DoIntegralPromotion (CompilerType from,
7382+ ExecutionContextScope *exe_scope) {
7383+ if (!from.IsInteger () && !from.IsUnscopedEnumerationType ())
7384+ return from;
7385+
7386+ if (!from.IsPromotableIntegerType ())
7387+ return from;
7388+
7389+ if (from.IsUnscopedEnumerationType ()) {
7390+ EnumDecl *enum_decl = GetAsEnumDecl (from);
7391+ CompilerType promotion_type = GetType (enum_decl->getPromotionType ());
7392+ return DoIntegralPromotion (promotion_type, exe_scope);
7393+ }
7394+
7395+ lldb::BasicType builtin_type =
7396+ from.GetCanonicalType ().GetBasicTypeEnumeration ();
7397+ uint64_t from_size = 0 ;
7398+ if (builtin_type == lldb::eBasicTypeWChar ||
7399+ builtin_type == lldb::eBasicTypeSignedWChar ||
7400+ builtin_type == lldb::eBasicTypeUnsignedWChar ||
7401+ builtin_type == lldb::eBasicTypeChar16 ||
7402+ builtin_type == lldb::eBasicTypeChar32) {
7403+ // Find the type that can hold the entire range of values for our type.
7404+ bool is_signed = from.IsSigned ();
7405+ llvm::Expected<uint64_t > from_size = from.GetByteSize (exe_scope);
7406+ if (!from_size)
7407+ return from_size.takeError ();
7408+ CompilerType promote_types[] = {
7409+ GetBasicTypeFromAST (lldb::eBasicTypeInt),
7410+ GetBasicTypeFromAST (lldb::eBasicTypeUnsignedInt),
7411+ GetBasicTypeFromAST (lldb::eBasicTypeLong),
7412+ GetBasicTypeFromAST (lldb::eBasicTypeUnsignedLong),
7413+ GetBasicTypeFromAST (lldb::eBasicTypeLongLong),
7414+ GetBasicTypeFromAST (lldb::eBasicTypeUnsignedLongLong),
7415+ };
7416+ for (CompilerType &type : promote_types) {
7417+ llvm::Expected<uint64_t > byte_size = type.GetByteSize (exe_scope);
7418+ if (!byte_size)
7419+ return byte_size.takeError ();
7420+ if (*from_size < *byte_size ||
7421+ (*from_size == *byte_size && is_signed == type.IsSigned ())) {
7422+ return type;
7423+ }
7424+ }
7425+ llvm_unreachable (" char type should fit into long long" );
7426+ }
7427+
7428+ // Here we can promote only to "int" or "unsigned int".
7429+ CompilerType int_type = GetBasicTypeFromAST (lldb::eBasicTypeInt);
7430+ llvm::Expected<uint64_t > int_byte_size = int_type.GetByteSize (exe_scope);
7431+ if (!int_byte_size)
7432+ return int_byte_size.takeError ();
7433+
7434+ // Signed integer types can be safely promoted to "int".
7435+ if (from.IsSigned ()) {
7436+ return int_type;
7437+ }
7438+ // Unsigned integer types are promoted to "unsigned int" if "int" cannot hold
7439+ // their entire value range.
7440+ return (from_size == *int_byte_size)
7441+ ? GetBasicTypeFromAST (lldb::eBasicTypeUnsignedInt)
7442+ : int_type;
7443+ }
7444+
73497445clang::EnumDecl *TypeSystemClang::GetAsEnumDecl (const CompilerType &type) {
73507446 const clang::EnumType *enutype =
73517447 llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType (type));
0 commit comments