[clang] [clang][Interp] Member Pointers (PR #91303)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Tue May 7 00:25:19 PDT 2024


================
@@ -0,0 +1,80 @@
+
+
+#include "MemberPointer.h"
+#include "Context.h"
+#include "FunctionPointer.h"
+#include "Program.h"
+#include "Record.h"
+
+namespace clang {
+namespace interp {
+
+std::optional<Pointer> MemberPointer::toPointer(const Context &Ctx) const {
+  if (!Dcl || isa<FunctionDecl>(Dcl))
+    return Base;
+  const FieldDecl *FD = cast<FieldDecl>(Dcl);
+  assert(FD);
+
+  Pointer CastedBase =
+      (PtrOffset < 0 ? Base.atField(-PtrOffset) : Base.atFieldSub(PtrOffset));
+
+  // FIXME: The Base Pointer might be a dummy pointer. In that case, we can
+  // still do all of this and return yet another dummy pointer, but with the
+  // Base/Offset adjusted. However, right now we don't have the necessary type
+  // information for dummy pointers.
+  if (CastedBase.isDummy())
+    return std::nullopt;
+
+  const Record *BaseRecord = CastedBase.getRecord();
+  assert(BaseRecord);
+
+  if (FD->getParent() == BaseRecord->getDecl())
+    return CastedBase.atField(BaseRecord->getField(FD)->Offset);
+
+  unsigned Offset;
+  const RecordDecl *FieldParent = FD->getParent();
+  const Record *FieldRecord = Ctx.getRecord(FieldParent);
+
+  Offset = 0;
+  Offset += FieldRecord->getField(FD)->Offset;
+  Offset += CastedBase.block()->getDescriptor()->getMetadataSize();
+
+  if (Offset > CastedBase.block()->getSize())
+    return std::nullopt;
+
+  unsigned O = 0;
+  if (Base.getDeclPtr().getRecord()->getDecl() != FieldParent) {
+    O = Ctx.collectBaseOffset(FieldParent,
+                              Pointer(const_cast<Block *>(Base.block()), 16, 16)
+                                  .getRecord()
+                                  ->getDecl());
----------------
tbaederr wrote:

This part needs some work.

https://github.com/llvm/llvm-project/pull/91303


More information about the cfe-commits mailing list