Fix type detection for 'char' variables
A char can have signed and unsigned encoding but previously lldb always assumed it is signed. This CL adds a logic to detect the encoding of 'char' types based on the default encoding on the target architecture. It fixes variable printing and expression evaluation on architectures where 'char' is signed by default. Differential revision: http://reviews.llvm.org/D8636 llvm-svn: 233682
This commit is contained in:
parent
4c1b746771
commit
dccbfaf917
|
@ -418,8 +418,18 @@ public:
|
|||
GetDefaultEndian () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Compare an ArchSpec to another ArchSpec, requiring an exact cpu
|
||||
/// type match between them.
|
||||
/// Returns true if 'char' is a signed type by defualt in the
|
||||
/// architecture false otherwise
|
||||
///
|
||||
/// @return True if 'char' is a signed type by default on the
|
||||
/// architecture and false otherwise.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
CharIsSignedByDefault () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Compare an ArchSpec to another ArchSpec, requiring an exact cpu
|
||||
/// type match between them.
|
||||
/// e.g. armv7s is not an exact match with armv7 - this would return false
|
||||
///
|
||||
/// @return true if the two ArchSpecs match.
|
||||
|
|
|
@ -577,6 +577,32 @@ ArchSpec::GetDefaultEndian () const
|
|||
return eByteOrderInvalid;
|
||||
}
|
||||
|
||||
bool
|
||||
ArchSpec::CharIsSignedByDefault () const
|
||||
{
|
||||
switch (m_triple.getArch()) {
|
||||
default:
|
||||
return true;
|
||||
|
||||
case llvm::Triple::aarch64:
|
||||
case llvm::Triple::aarch64_be:
|
||||
case llvm::Triple::arm:
|
||||
case llvm::Triple::armeb:
|
||||
case llvm::Triple::thumb:
|
||||
case llvm::Triple::thumbeb:
|
||||
return m_triple.isOSDarwin() || m_triple.isOSWindows();
|
||||
|
||||
case llvm::Triple::ppc:
|
||||
case llvm::Triple::ppc64:
|
||||
return m_triple.isOSDarwin();
|
||||
|
||||
case llvm::Triple::ppc64le:
|
||||
case llvm::Triple::systemz:
|
||||
case llvm::Triple::xcore:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
lldb::ByteOrder
|
||||
ArchSpec::GetByteOrder () const
|
||||
{
|
||||
|
|
|
@ -228,6 +228,9 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
|
|||
if (expr.DesiredResultType() == ClangExpression::eResultTypeId)
|
||||
m_compiler->getLangOpts().DebuggerCastResultToId = true;
|
||||
|
||||
m_compiler->getLangOpts().CharIsSigned =
|
||||
ArchSpec(m_compiler->getTargetOpts().Triple.c_str()).CharIsSignedByDefault();
|
||||
|
||||
// Spell checking is a nice feature, but it ends up completing a
|
||||
// lot of types that we didn't strictly speaking need to complete.
|
||||
// As a result, we spend a long time parsing and importing debug
|
||||
|
|
|
@ -109,13 +109,8 @@ ClangASTContext::ConvertAccessTypeToAccessSpecifier (AccessType access)
|
|||
return AS_none;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ParseLangArgs
|
||||
(
|
||||
LangOptions &Opts,
|
||||
InputKind IK
|
||||
)
|
||||
ParseLangArgs (LangOptions &Opts, InputKind IK, const char* triple)
|
||||
{
|
||||
// FIXME: Cleanup per-file based stuff.
|
||||
|
||||
|
@ -235,7 +230,7 @@ ParseLangArgs
|
|||
// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
|
||||
// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
|
||||
// Opts.Blocks = Args.hasArg(OPT_fblocks);
|
||||
// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
|
||||
Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
|
||||
// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
|
||||
// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
|
||||
// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
|
||||
|
@ -450,7 +445,7 @@ ClangASTContext::getLanguageOptions()
|
|||
if (m_language_options_ap.get() == nullptr)
|
||||
{
|
||||
m_language_options_ap.reset(new LangOptions());
|
||||
ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
|
||||
ParseLangArgs(*m_language_options_ap, IK_ObjCXX, GetTargetTriple());
|
||||
// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
|
||||
}
|
||||
return m_language_options_ap.get();
|
||||
|
@ -952,18 +947,13 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name
|
|||
if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
|
||||
return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr());
|
||||
break;
|
||||
|
||||
|
||||
case DW_ATE_signed_char:
|
||||
if (type_name)
|
||||
if (ast->getLangOpts().CharIsSigned && type_name && streq(type_name, "char"))
|
||||
{
|
||||
if (streq(type_name, "signed char"))
|
||||
{
|
||||
if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
|
||||
return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr());
|
||||
}
|
||||
if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
|
||||
return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
|
||||
}
|
||||
if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
|
||||
return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
|
||||
if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
|
||||
return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr());
|
||||
break;
|
||||
|
@ -1013,8 +1003,13 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name
|
|||
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
|
||||
return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr());
|
||||
break;
|
||||
|
||||
|
||||
case DW_ATE_unsigned_char:
|
||||
if (!ast->getLangOpts().CharIsSigned && type_name && streq(type_name, "char"))
|
||||
{
|
||||
if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
|
||||
return ClangASTType (ast, ast->CharTy.getAsOpaquePtr());
|
||||
}
|
||||
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
|
||||
return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr());
|
||||
if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
|
||||
|
|
Loading…
Reference in New Issue