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:
Tamas Berghammer 2015-03-31 10:21:50 +00:00
parent 4c1b746771
commit dccbfaf917
4 changed files with 54 additions and 20 deletions

View File

@ -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.

View File

@ -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
{

View File

@ -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

View File

@ -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))