================
@@ -0,0 +1,508 @@
+//===------------- InterpBuiltinObjectSize.cpp ------------------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Implementation of the frontend part of the __builtin_object_size and
+// __builtin_dynamic_object_size builtins.
+
+#include "InterpHelpers.h"
+#include "Pointer.h"
+#include "Record.h"
+#include "clang/AST/RecordLayout.h"
+
+using namespace clang;
+using namespace clang::interp;
+
+enum : uint8_t {
+  Regular = 1 << 0,
+  IgnoreBaseCasts = 1 << 1,
+  SurroundingArray = 1 << 2,
+};
+
+// Helper to check if a RecordDecl can be passed to
+// ASTContext::getRecordLayout().
+static bool validRecordDecl(const RecordDecl *D) {
+  D = D->getDefinition();
+  return D && !D->isInvalidDecl() && D->isCompleteDefinition();
+}
+
+// Same but for types.
+static bool validType(QualType T) {
+  if (const RecordDecl *RD = T->getAsRecordDecl())
+    return validRecordDecl(RD);
+  return true;
+}
+
+static QualType computeFieldType(const ASTContext &ASTCtx,
+                                 const OpaquePointer &OP,
+                                 unsigned TypeModifier = 0) {
+  QualType CurType = OP.getObjectType();
+
+  unsigned Drop = 0;
+  if (TypeModifier & IgnoreBaseCasts && OP.PathLength != 0 &&
+      OP.path().back().Kind == PointerPathEntry::Base)
+    Drop = 1;
+
+  if (TypeModifier & SurroundingArray && OP.PathLength != 0 &&
+      OP.path().back().Kind == PointerPathEntry::Array)
+    Drop = 1;
+
+  for (const PointerPathEntry &Entry : OP.path().drop_back(Drop)) {
+    switch (Entry.Kind) {
+    case PointerPathEntry::Base:
+      CurType = ASTCtx.getCanonicalTagType(Entry.RD.getPointer());
+      break;
+    case PointerPathEntry::Field:
+      CurType = Entry.FD->getType();
+      break;
+    case PointerPathEntry::Array:
+      if (!CurType->isArrayType())
+        continue;
+      CurType = CurType->getAsArrayTypeUnsafe()->getElementType();
+    }
+  }
+
+  return CurType;
+}
+
+static std::optional<unsigned> computeFullDescSize(const ASTContext &ASTCtx,
+                                                   const Descriptor *Desc) {
+  if (Desc->isPrimitive() || Desc->isArray()) {
+    QualType T = Desc->getType();
+    if (!validType(T))
+      return std::nullopt;
+    return ASTCtx.getTypeSizeInChars(T).getQuantity();
+  }
+
+  if (Desc->isRecord()) {
----------------
ojhunt wrote:

Based on this being a code motion vs terrible diffs I'm ok with this code

https://github.com/llvm/llvm-project/pull/213017
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to