Skip to content

Commit

Permalink
Re-land "[lldb] Upstream support for Foundation constant classes"
Browse files Browse the repository at this point in the history
Upstream support for NSConstantArray, NSConstantIntegerNumber,
NSConstant{Float,Double}Number and NSConstantDictionary.

We would've upstreamed this earlier but testing it requires
-fno-constant-nsnumber-literals, -fno-constant-nsarray-literals and
-fno-constant-nsdictionary-literals which haven't been upstreamed yet.
As a temporary workaround use the system compiler (xcrun clang) for the
constant variant of the tests.

I'm just upstreaming this. The patch and the tests were all authored by
Fred Riss.

Differential revision: https://reviews.llvm.org/D107660
  • Loading branch information
JDevlieghere committed Aug 7, 2021
1 parent 4e5af6e commit 9d5e95d
Show file tree
Hide file tree
Showing 19 changed files with 516 additions and 19 deletions.
102 changes: 99 additions & 3 deletions lldb/source/Plugins/Language/ObjC/Cocoa.cpp
Expand Up @@ -7,7 +7,9 @@
//===----------------------------------------------------------------------===//

#include "Cocoa.h"
#include "NSString.h"

#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Core/ValueObject.h"
Expand All @@ -28,9 +30,37 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/bit.h"

#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"

#include "NSString.h"
// Objective-C Type Encoding
#define _C_ID '@'
#define _C_CLASS '#'
#define _C_SEL ':'
#define _C_CHR 'c'
#define _C_UCHR 'C'
#define _C_SHT 's'
#define _C_USHT 'S'
#define _C_INT 'i'
#define _C_UINT 'I'
#define _C_LNG 'l'
#define _C_ULNG 'L'
#define _C_LNG_LNG 'q'
#define _C_ULNG_LNG 'Q'
#define _C_FLT 'f'
#define _C_DBL 'd'
#define _C_BFLD 'b'
#define _C_BOOL 'B'
#define _C_VOID 'v'
#define _C_UNDEF '?'
#define _C_PTR '^'
#define _C_CHARPTR '*'
#define _C_ATOM '%'
#define _C_ARY_B '['
#define _C_ARY_E ']'
#define _C_UNION_B '('
#define _C_UNION_E ')'
#define _C_STRUCT_B '{'
#define _C_STRUCT_E '}'
#define _C_VECTOR '!'
#define _C_CONST 'r'

using namespace lldb;
using namespace lldb_private;
Expand Down Expand Up @@ -456,6 +486,72 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
if (class_name == "NSDecimalNumber")
return NSDecimalNumberSummaryProvider(valobj, stream, options);

if (class_name == "NSConstantIntegerNumber") {
Status error;
int64_t value = process_sp->ReadSignedIntegerFromMemory(
valobj_addr + 2 * ptr_size, 8, 0, error);
if (error.Fail())
return false;
uint64_t encoding_addr = process_sp->ReadUnsignedIntegerFromMemory(
valobj_addr + ptr_size, ptr_size, 0, error);
if (error.Fail())
return false;
char encoding =
process_sp->ReadUnsignedIntegerFromMemory(encoding_addr, 1, 0, error);
if (error.Fail())
return false;

switch (encoding) {
case _C_CHR:
NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
return true;
case _C_SHT:
NSNumber_FormatShort(valobj, stream, (short)value, options.GetLanguage());
return true;
case _C_INT:
NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
return true;
case _C_LNG:
case _C_LNG_LNG:
NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
return true;

case _C_UCHR:
case _C_USHT:
case _C_UINT:
case _C_ULNG:
case _C_ULNG_LNG:
stream.Printf("%" PRIu64, value);
return true;
}

return false;
}

if (class_name == "NSConstantFloatNumber") {
Status error;
uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(
valobj_addr + ptr_size, 4, 0, error);
if (error.Fail())
return false;
float flt_value = 0.0f;
memcpy(&flt_value, &flt_as_int, sizeof(flt_as_int));
NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage());
return true;
}

if (class_name == "NSConstantDoubleNumber") {
Status error;
uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(
valobj_addr + ptr_size, 8, 0, error);
if (error.Fail())
return false;
double dbl_value = 0.0;
memcpy(&dbl_value, &dbl_as_lng, sizeof(dbl_as_lng));
NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage());
return true;
}

if (class_name == "NSNumber" || class_name == "__NSCFNumber") {
int64_t value = 0;
uint64_t i_bits = 0;
Expand Down
26 changes: 26 additions & 0 deletions lldb/source/Plugins/Language/ObjC/NSArray.cpp
Expand Up @@ -280,6 +280,22 @@ namespace Foundation1436 {
}
}

namespace ConstantArray {

struct ConstantArray32 {
uint64_t used;
uint32_t list;
};

struct ConstantArray64 {
uint64_t used;
uint64_t list;
};

using NSConstantArraySyntheticFrontEnd =
GenericNSArrayISyntheticFrontEnd<ConstantArray32, ConstantArray64, false>;
} // namespace ConstantArray

class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
NSArray0SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
Expand Down Expand Up @@ -356,6 +372,7 @@ bool lldb_private::formatters::NSArraySummaryProvider(
static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy");
static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable");
static const ConstString g_NSCallStackArray("_NSCallStackArray");
static const ConstString g_NSConstantArray("NSConstantArray");

if (class_name.IsEmpty())
return false;
Expand All @@ -366,6 +383,12 @@ bool lldb_private::formatters::NSArraySummaryProvider(
ptr_size, 0, error);
if (error.Fail())
return false;
} else if (class_name == g_NSConstantArray) {
Status error;
value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 8,
0, error);
if (error.Fail())
return false;
} else if (class_name == g_NSArrayM) {
AppleObjCRuntime *apple_runtime =
llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
Expand Down Expand Up @@ -803,6 +826,7 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
ConstString class_name(descriptor->GetClassName());

static const ConstString g_NSArrayI("__NSArrayI");
static const ConstString g_NSConstantArray("NSConstantArray");
static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer");
static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM");
static const ConstString g_NSArrayM("__NSArrayM");
Expand All @@ -823,6 +847,8 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSArrayI_Transfer) {
return (new Foundation1436::NSArrayI_TransferSyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSConstantArray) {
return new ConstantArray::NSConstantArraySyntheticFrontEnd(valobj_sp);
} else if (class_name == g_NSFrozenArrayM) {
return (new Foundation1436::NSFrozenArrayMSyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSArray0) {
Expand Down

0 comments on commit 9d5e95d

Please sign in to comment.