summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Rowe <mrowe@bdash.net.nz>2025-05-30 09:16:48 -0700
committerkat <kat@vector35.com>2025-06-18 10:41:33 -0400
commitb6b98c07eb8ce704da4edf5a0b16959215a2c450 (patch)
tree09fb73e17eb949e489f95acd9beea9ef619ac013
parenta7ff3ca06a7684a688628b9afb36398b3a4d9d45 (diff)
[ObjC] Prefer displaying id rather than objc_object*
-rw-r--r--lang/c/objctypes.cpp45
-rw-r--r--lang/c/objctypes.h24
-rw-r--r--lang/c/pseudoobjc.cpp6
-rw-r--r--lang/c/pseudoobjc.h1
4 files changed, 76 insertions, 0 deletions
diff --git a/lang/c/objctypes.cpp b/lang/c/objctypes.cpp
new file mode 100644
index 00000000..83a097be
--- /dev/null
+++ b/lang/c/objctypes.cpp
@@ -0,0 +1,45 @@
+#include "objctypes.h"
+#include "binaryninjaapi.h"
+
+using namespace BinaryNinja;
+
+namespace {
+
+bool IsPointerToObjCObject(const Ref<Type>& type)
+{
+ if (!type || type->GetClass() != PointerTypeClass)
+ return false;
+
+ auto childType = type->GetChildType();
+ if (!childType || childType->GetClass() != NamedTypeReferenceClass)
+ return false;
+
+ auto namedType = childType->GetNamedTypeReference();
+ return namedType && namedType->GetName().GetString() == "objc_object";
+}
+
+} // unnamed namespace
+
+PseudoObjCTypePrinter::PseudoObjCTypePrinter() : TypePrinter("Objective-C") {}
+
+std::vector<InstructionTextToken> PseudoObjCTypePrinter::GetTypeTokensBeforeName(
+ Ref<Type> type, Ref<Platform> platform, uint8_t baseConfidence, Ref<Type> parentType, BNTokenEscapingType escaping)
+{
+ // It is idiomatic in Objective-C to use `id` rather than `objc_object*`.
+ if (IsPointerToObjCObject(type))
+ return {InstructionTextToken {baseConfidence, TypeNameToken, "id"}};
+
+ return TypePrinter::GetDefault()->GetTypeTokensBeforeName(type, platform, baseConfidence, parentType, escaping);
+}
+
+std::vector<InstructionTextToken> PseudoObjCTypePrinter::GetTypeTokensAfterName(
+ Ref<Type> type, Ref<Platform> platform, uint8_t baseConfidence, Ref<Type> parentType, BNTokenEscapingType escaping)
+{
+ return TypePrinter::GetDefault()->GetTypeTokensAfterName(type, platform, baseConfidence, parentType, escaping);
+}
+
+std::vector<TypeDefinitionLine> PseudoObjCTypePrinter::GetTypeLines(Ref<Type> type, const TypeContainer& types,
+ const QualifiedName& name, int paddingCols, bool collapsed, BNTokenEscapingType escaping)
+{
+ return TypePrinter::GetDefault()->GetTypeLines(type, types, name, paddingCols, collapsed, escaping);
+}
diff --git a/lang/c/objctypes.h b/lang/c/objctypes.h
new file mode 100644
index 00000000..c9f0037d
--- /dev/null
+++ b/lang/c/objctypes.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "binaryninjaapi.h"
+
+class PseudoObjCTypePrinter : public BinaryNinja::TypePrinter
+{
+public:
+ PseudoObjCTypePrinter();
+
+ std::vector<BinaryNinja::InstructionTextToken> GetTypeTokensBeforeName(BinaryNinja::Ref<BinaryNinja::Type> type,
+ BinaryNinja::Ref<BinaryNinja::Platform> platform,
+ uint8_t baseConfidence = BN_FULL_CONFIDENCE, BinaryNinja::Ref<BinaryNinja::Type> parentType = nullptr,
+ BNTokenEscapingType escaping = NoTokenEscapingType) override;
+
+ std::vector<BinaryNinja::InstructionTextToken> GetTypeTokensAfterName(BinaryNinja::Ref<BinaryNinja::Type> type,
+ BinaryNinja::Ref<BinaryNinja::Platform> platform,
+ uint8_t baseConfidence = BN_FULL_CONFIDENCE, BinaryNinja::Ref<BinaryNinja::Type> parentType = nullptr,
+ BNTokenEscapingType escaping = NoTokenEscapingType) override;
+
+ std::vector<BinaryNinja::TypeDefinitionLine> GetTypeLines(BinaryNinja::Ref<BinaryNinja::Type> type,
+ const BinaryNinja::TypeContainer& types,
+ const BinaryNinja::QualifiedName& name, int paddingCols = 64, bool collapsed = false,
+ BNTokenEscapingType escaping = NoTokenEscapingType) override;
+};
diff --git a/lang/c/pseudoobjc.cpp b/lang/c/pseudoobjc.cpp
index 7794e938..9b6dd0c7 100644
--- a/lang/c/pseudoobjc.cpp
+++ b/lang/c/pseudoobjc.cpp
@@ -2,6 +2,7 @@
#include "binaryninjaapi.h"
#include "highlevelilinstruction.h"
+#include "objctypes.h"
#include <optional>
#include <string>
#include <string_view>
@@ -518,3 +519,8 @@ Ref<LanguageRepresentationFunction> PseudoObjCFunctionType::Create(
{
return new PseudoObjCFunction(this, arch, owner, highLevelILFunction);
}
+
+Ref<TypePrinter> PseudoObjCFunctionType::GetTypePrinter()
+{
+ return new PseudoObjCTypePrinter();
+}
diff --git a/lang/c/pseudoobjc.h b/lang/c/pseudoobjc.h
index d7d63196..5ee3d870 100644
--- a/lang/c/pseudoobjc.h
+++ b/lang/c/pseudoobjc.h
@@ -47,4 +47,5 @@ public:
PseudoObjCFunctionType();
BinaryNinja::Ref<BinaryNinja::LanguageRepresentationFunction> Create(BinaryNinja::Architecture* arch,
BinaryNinja::Function* owner, BinaryNinja::HighLevelILFunction* highLevelILFunction) override;
+ BinaryNinja::Ref<BinaryNinja::TypePrinter> GetTypePrinter() override;
};