[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-08-20 Thread Timm Bäder via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG8a58f0d370b0: [clang][Interp] Handle global composite 
temporaries (authored by tbaeder).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

Files:
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/AST/Interp/Descriptor.h
  clang/lib/AST/Interp/Interp.h
  clang/lib/AST/Interp/Opcodes.td
  clang/lib/AST/Interp/Pointer.cpp
  clang/lib/AST/Interp/Pointer.h
  clang/lib/AST/Interp/Record.h
  clang/test/AST/Interp/records.cpp

Index: clang/test/AST/Interp/records.cpp
===
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -114,6 +114,21 @@
 static_assert(c2.a == 100, "");
 static_assert(c2.b == 200, "");
 
+
+/// A global, composite temporary variable.
+constexpr const C  = C().get();
+
+/// Same, but with a bitfield.
+class D {
+public:
+  unsigned a : 4;
+  constexpr D() : a(15) {}
+  constexpr D get() const {
+return *this;
+  }
+};
+constexpr const D  = D().get();
+
 constexpr int getB() {
   C c;
   int  = c.b;
Index: clang/lib/AST/Interp/Record.h
===
--- clang/lib/AST/Interp/Record.h
+++ clang/lib/AST/Interp/Record.h
@@ -87,7 +87,10 @@
   }
 
   unsigned getNumBases() const { return Bases.size(); }
-  const Base *getBase(unsigned I) const { return [I]; }
+  const Base *getBase(unsigned I) const {
+assert(I < getNumBases());
+return [I];
+  }
 
   using const_virtual_iter = VirtualBaseList::const_iterator;
   llvm::iterator_range virtual_bases() const {
Index: clang/lib/AST/Interp/Pointer.h
===
--- clang/lib/AST/Interp/Pointer.h
+++ clang/lib/AST/Interp/Pointer.h
@@ -27,6 +27,7 @@
 class Block;
 class DeadBlock;
 class Pointer;
+class Context;
 enum PrimType : unsigned;
 
 class Pointer;
@@ -87,6 +88,9 @@
 return reinterpret_cast(Pointee) + Offset;
   }
 
+  /// Converts the pointer to an APValue that is an rvalue.
+  APValue toRValue(const Context ) const;
+
   /// Offsets a pointer inside an array.
   Pointer atIndex(unsigned Idx) const {
 if (Base == RootPtrMark)
Index: clang/lib/AST/Interp/Pointer.cpp
===
--- clang/lib/AST/Interp/Pointer.cpp
+++ clang/lib/AST/Interp/Pointer.cpp
@@ -7,9 +7,14 @@
 //===--===//
 
 #include "Pointer.h"
+#include "Boolean.h"
+#include "Context.h"
+#include "Floating.h"
 #include "Function.h"
+#include "Integral.h"
 #include "InterpBlock.h"
 #include "PrimType.h"
+#include "Record.h"
 
 using namespace clang;
 using namespace clang::interp;
@@ -217,3 +222,34 @@
 bool Pointer::hasSameArray(const Pointer , const Pointer ) {
   return hasSameBase(A, B) && A.Base == B.Base && A.getFieldDesc()->IsArray;
 }
+
+APValue Pointer::toRValue(const Context ) const {
+  // Primitives.
+  if (getFieldDesc()->isPrimitive()) {
+PrimType PT = *Ctx.classify(getType());
+TYPE_SWITCH(PT, return deref().toAPValue());
+llvm_unreachable("Unhandled PrimType?");
+  }
+
+  APValue Result;
+  // Records.
+  if (getFieldDesc()->isRecord()) {
+const Record *R = getRecord();
+Result =
+APValue(APValue::UninitStruct(), R->getNumBases(), R->getNumFields());
+
+for (unsigned I = 0; I != R->getNumFields(); ++I) {
+  const Pointer  = this->atField(R->getField(I)->Offset);
+  Result.getStructField(I) = FieldPtr.toRValue(Ctx);
+}
+
+for (unsigned I = 0; I != R->getNumBases(); ++I) {
+  const Pointer  = this->atField(R->getBase(I)->Offset);
+  Result.getStructBase(I) = BasePtr.toRValue(Ctx);
+}
+  }
+
+  // TODO: Arrays
+
+  return Result;
+}
Index: clang/lib/AST/Interp/Opcodes.td
===
--- clang/lib/AST/Interp/Opcodes.td
+++ clang/lib/AST/Interp/Opcodes.td
@@ -353,6 +353,12 @@
 def InitGlobalTemp : AccessOpcode {
   let Args = [ArgUint32, ArgLETD];
 }
+// [Pointer] -> [Pointer]
+def InitGlobalTempComp : Opcode {
+  let Args = [ArgLETD];
+  let Types = [];
+  let HasGroup = 0;
+}
 // [Value] -> []
 def SetGlobal : AccessOpcode;
 
Index: clang/lib/AST/Interp/Interp.h
===
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -996,6 +996,19 @@
   return true;
 }
 
+/// 1) Converts the value on top of the stack to an APValue
+/// 2) Sets that APValue on \Temp
+/// 3) Initialized global with index \I with that
+inline bool InitGlobalTempComp(InterpState , CodePtr OpPC,
+   const LifetimeExtendedTemporaryDecl *Temp) {
+  assert(Temp);
+  const Pointer  = S.Stk.peek();
+  APValue *Cached = 

[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-08-18 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM!


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-08-18 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder updated this revision to Diff 551435.
tbaeder marked 6 inline comments as done.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

Files:
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/AST/Interp/Descriptor.h
  clang/lib/AST/Interp/Interp.h
  clang/lib/AST/Interp/Opcodes.td
  clang/lib/AST/Interp/Pointer.cpp
  clang/lib/AST/Interp/Pointer.h
  clang/lib/AST/Interp/Record.h
  clang/test/AST/Interp/records.cpp

Index: clang/test/AST/Interp/records.cpp
===
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -114,6 +114,21 @@
 static_assert(c2.a == 100, "");
 static_assert(c2.b == 200, "");
 
+
+/// A global, composite temporary variable.
+constexpr const C  = C().get();
+
+/// Same, but with a bitfield.
+class D {
+public:
+  unsigned a : 4;
+  constexpr D() : a(15) {}
+  constexpr D get() const {
+return *this;
+  }
+};
+constexpr const D  = D().get();
+
 constexpr int getB() {
   C c;
   int  = c.b;
Index: clang/lib/AST/Interp/Record.h
===
--- clang/lib/AST/Interp/Record.h
+++ clang/lib/AST/Interp/Record.h
@@ -88,7 +88,10 @@
   }
 
   unsigned getNumBases() const { return Bases.size(); }
-  const Base *getBase(unsigned I) const { return [I]; }
+  const Base *getBase(unsigned I) const {
+assert(I < getNumBases());
+return [I];
+  }
 
   using const_virtual_iter = VirtualBaseList::const_iterator;
   llvm::iterator_range virtual_bases() const {
Index: clang/lib/AST/Interp/Pointer.h
===
--- clang/lib/AST/Interp/Pointer.h
+++ clang/lib/AST/Interp/Pointer.h
@@ -27,6 +27,7 @@
 class Block;
 class DeadBlock;
 class Pointer;
+class Context;
 enum PrimType : unsigned;
 
 class Pointer;
@@ -87,6 +88,9 @@
 return reinterpret_cast(Pointee) + Offset;
   }
 
+  /// Converts the pointer to an APValue that is an rvalue.
+  APValue toRValue(const Context ) const;
+
   /// Offsets a pointer inside an array.
   Pointer atIndex(unsigned Idx) const {
 if (Base == RootPtrMark)
Index: clang/lib/AST/Interp/Pointer.cpp
===
--- clang/lib/AST/Interp/Pointer.cpp
+++ clang/lib/AST/Interp/Pointer.cpp
@@ -7,9 +7,14 @@
 //===--===//
 
 #include "Pointer.h"
+#include "Boolean.h"
+#include "Context.h"
+#include "Floating.h"
 #include "Function.h"
+#include "Integral.h"
 #include "InterpBlock.h"
 #include "PrimType.h"
+#include "Record.h"
 
 using namespace clang;
 using namespace clang::interp;
@@ -217,3 +222,34 @@
 bool Pointer::hasSameArray(const Pointer , const Pointer ) {
   return hasSameBase(A, B) && A.Base == B.Base && A.getFieldDesc()->IsArray;
 }
+
+APValue Pointer::toRValue(const Context ) const {
+  // Primitives.
+  if (getFieldDesc()->isPrimitive()) {
+PrimType PT = *Ctx.classify(getType());
+TYPE_SWITCH(PT, return deref().toAPValue());
+llvm_unreachable("Unhandled PrimType?");
+  }
+
+  APValue Result;
+  // Records.
+  if (getFieldDesc()->isRecord()) {
+const Record *R = getRecord();
+Result =
+APValue(APValue::UninitStruct(), R->getNumBases(), R->getNumFields());
+
+for (unsigned I = 0; I != R->getNumFields(); ++I) {
+  const Pointer  = this->atField(R->getField(I)->Offset);
+  Result.getStructField(I) = FieldPtr.toRValue(Ctx);
+}
+
+for (unsigned I = 0; I != R->getNumBases(); ++I) {
+  const Pointer  = this->atField(R->getBase(I)->Offset);
+  Result.getStructBase(I) = BasePtr.toRValue(Ctx);
+}
+  }
+
+  // TODO: Arrays
+
+  return Result;
+}
Index: clang/lib/AST/Interp/Opcodes.td
===
--- clang/lib/AST/Interp/Opcodes.td
+++ clang/lib/AST/Interp/Opcodes.td
@@ -353,6 +353,12 @@
 def InitGlobalTemp : AccessOpcode {
   let Args = [ArgUint32, ArgLETD];
 }
+// [Pointer] -> [Pointer]
+def InitGlobalTempComp : Opcode {
+  let Args = [ArgLETD];
+  let Types = [];
+  let HasGroup = 0;
+}
 // [Value] -> []
 def SetGlobal : AccessOpcode;
 
Index: clang/lib/AST/Interp/Interp.h
===
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -993,6 +993,19 @@
   return true;
 }
 
+/// 1) Converts the value on top of the stack to an APValue
+/// 2) Sets that APValue on \Temp
+/// 3) Initialized global with index \I with that
+inline bool InitGlobalTempComp(InterpState , CodePtr OpPC,
+   const LifetimeExtendedTemporaryDecl *Temp) {
+  assert(Temp);
+  const Pointer  = S.Stk.peek();
+  APValue *Cached = Temp->getOrCreateValue(true);
+
+  *Cached = P.toRValue(S.getCtx());
+  return true;
+}
+
 template ::T>
 bool InitThisField(InterpState , CodePtr OpPC, uint32_t I) {
   if 

[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-08-18 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added inline comments.



Comment at: clang/lib/AST/Interp/ByteCodeExprGen.cpp:852
+  return false;
+return this->emitInitGlobalTempComp(TempDecl, E);
   }

aaron.ballman wrote:
> Should this still happen even if `TempDecl` is null? It looks like 
> `getLifetimeExtendedTemporaryDecl()` can return a null pointer, but perhaps 
> there's a reason we can't get that result here?
AFAIK it never returns null if the storage duration is `SD_Static`, but that's 
just based on what I was seeing. Could add an assertion to be sure.



Comment at: clang/lib/AST/Interp/Pointer.cpp:236
+for (unsigned I = 0; I != R->getNumFields(); ++I) {
+  const Pointer FieldPtr = this->atField(R->getField(I)->Offset);
+  Result.getStructField(I) = FieldPtr.toRValue(Ctx);

aaron.ballman wrote:
> 
`const Pointer &` instead? :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-08-17 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/lib/AST/Interp/ByteCodeExprGen.cpp:852
+  return false;
+return this->emitInitGlobalTempComp(TempDecl, E);
   }

Should this still happen even if `TempDecl` is null? It looks like 
`getLifetimeExtendedTemporaryDecl()` can return a null pointer, but perhaps 
there's a reason we can't get that result here?



Comment at: clang/lib/AST/Interp/Pointer.cpp:235-237
+for (unsigned I = 0; I != R->getNumFields(); ++I) {
+  const Pointer FieldPtr = this->atField(R->getField(I)->Offset);
+  Result.getStructField(I) = FieldPtr.toRValue(Ctx);

Pointer to a field? That means, I would like tests that involve bit-fields. :-)



Comment at: clang/lib/AST/Interp/Pointer.cpp:236
+for (unsigned I = 0; I != R->getNumFields(); ++I) {
+  const Pointer FieldPtr = this->atField(R->getField(I)->Offset);
+  Result.getStructField(I) = FieldPtr.toRValue(Ctx);





Comment at: clang/lib/AST/Interp/Pointer.cpp:241
+for (unsigned I = 0; I != R->getNumBases(); ++I) {
+  const Pointer BasePtr = this->atField(R->getBase(I)->Offset);
+  Result.getStructBase(I) = BasePtr.toRValue(Ctx);





Comment at: clang/lib/AST/Interp/Record.h:90
   unsigned getNumBases() const { return Bases.size(); }
+  const Base *getBase(unsigned I) const { return [I]; }
   Base *getBase(unsigned I) { return [I]; }

It might make sense to add an assert to both `getBase()` functions to verify 
that `I` is within a valid range.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-08-17 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-08-09 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-08-03 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-08-01 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-07-25 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-07-18 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-06-16 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-06-01 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added inline comments.



Comment at: clang/lib/AST/Interp/Pointer.cpp:10
 #include "Pointer.h"
+#include "Boolean.h"
+#include "Context.h"

shafik wrote:
> Are all these headers really needed for the change below?
We access `.toAPValue()` on all of them in the `TYPE_SWITCH` below, so yes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-05-18 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added a comment.

I think it mostly makes sense but I want Aaron to also look at it.




Comment at: clang/lib/AST/Interp/Pointer.cpp:10
 #include "Pointer.h"
+#include "Boolean.h"
+#include "Context.h"

Are all these headers really needed for the change below?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-05-11 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-05-01 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-04-21 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-04-13 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-04-04 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-03-27 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-03-19 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-03-10 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-02-23 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Thinking about this some more, the new `Pointer::toRValue()` is probably just 
the same thing we're already doing in `EvalEmitter::emtiRetValue()`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144457/new/

https://reviews.llvm.org/D144457

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144457: [clang][Interp] Handle global composite temporaries

2023-02-21 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

  We only did this for primitive temporaries.
  
  Unfortunately, the existing Pointer::toAPValue() won't do here, since
  we're expected to set an rvalue on the LifetimeExtendedTemporaryDecl.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D144457

Files:
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/AST/Interp/Descriptor.h
  clang/lib/AST/Interp/Interp.h
  clang/lib/AST/Interp/Opcodes.td
  clang/lib/AST/Interp/Pointer.cpp
  clang/lib/AST/Interp/Pointer.h
  clang/lib/AST/Interp/Record.h
  clang/test/AST/Interp/records.cpp

Index: clang/test/AST/Interp/records.cpp
===
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -114,6 +114,9 @@
 static_assert(c.a == 100, "");
 static_assert(c.b == 200, "");
 
+
+constexpr const C  = C().get();
+
 constexpr int getB() {
   C c;
   int  = c.b;
Index: clang/lib/AST/Interp/Record.h
===
--- clang/lib/AST/Interp/Record.h
+++ clang/lib/AST/Interp/Record.h
@@ -87,6 +87,7 @@
   }
 
   unsigned getNumBases() const { return Bases.size(); }
+  const Base *getBase(unsigned I) const { return [I]; }
   Base *getBase(unsigned I) { return [I]; }
 
   using const_virtual_iter = VirtualBaseList::const_iterator;
Index: clang/lib/AST/Interp/Pointer.h
===
--- clang/lib/AST/Interp/Pointer.h
+++ clang/lib/AST/Interp/Pointer.h
@@ -27,6 +27,7 @@
 class Block;
 class DeadBlock;
 class Pointer;
+class Context;
 enum PrimType : unsigned;
 
 /// A pointer to a memory block, live or dead.
@@ -78,6 +79,9 @@
   /// Converts the pointer to an APValue.
   APValue toAPValue() const;
 
+  /// Converts the pointer to an APValue that is an rvalue.
+  APValue toRValue(const Context ) const;
+
   /// Offsets a pointer inside an array.
   Pointer atIndex(unsigned Idx) const {
 if (!Pointee)
Index: clang/lib/AST/Interp/Pointer.cpp
===
--- clang/lib/AST/Interp/Pointer.cpp
+++ clang/lib/AST/Interp/Pointer.cpp
@@ -7,9 +7,14 @@
 //===--===//
 
 #include "Pointer.h"
+#include "Boolean.h"
+#include "Context.h"
+#include "Floating.h"
 #include "Function.h"
+#include "Integral.h"
 #include "InterpBlock.h"
 #include "PrimType.h"
+#include "Record.h"
 
 using namespace clang;
 using namespace clang::interp;
@@ -211,3 +216,34 @@
 bool Pointer::hasSameArray(const Pointer , const Pointer ) {
   return hasSameBase(A, B) && A.Base == B.Base && A.getFieldDesc()->IsArray;
 }
+
+APValue Pointer::toRValue(const Context ) const {
+  // Primitives.
+  if (getFieldDesc()->isPrimitive()) {
+PrimType PT = *Ctx.classify(getType());
+TYPE_SWITCH(PT, return deref().toAPValue());
+llvm_unreachable("Unhandled PrimType?");
+  }
+
+  APValue Result;
+  // Records.
+  if (getFieldDesc()->isRecord()) {
+const Record *R = getRecord();
+Result =
+APValue(APValue::UninitStruct(), R->getNumBases(), R->getNumFields());
+
+for (unsigned I = 0; I != R->getNumFields(); ++I) {
+  const Pointer FieldPtr = this->atField(R->getField(I)->Offset);
+  Result.getStructField(I) = FieldPtr.toRValue(Ctx);
+}
+
+for (unsigned I = 0; I != R->getNumBases(); ++I) {
+  const Pointer BasePtr = this->atField(R->getBase(I)->Offset);
+  Result.getStructBase(I) = BasePtr.toRValue(Ctx);
+}
+  }
+
+  // TODO: Arrays
+
+  return Result;
+}
Index: clang/lib/AST/Interp/Opcodes.td
===
--- clang/lib/AST/Interp/Opcodes.td
+++ clang/lib/AST/Interp/Opcodes.td
@@ -351,6 +351,12 @@
 def InitGlobalTemp : AccessOpcode {
   let Args = [ArgUint32, ArgLETD];
 }
+// [Pointer] -> [Pointer]
+def InitGlobalTempComp : Opcode {
+  let Args = [ArgLETD];
+  let Types = [];
+  let HasGroup = 0;
+}
 // [Value] -> []
 def SetGlobal : AccessOpcode;
 
Index: clang/lib/AST/Interp/Interp.h
===
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -835,6 +835,19 @@
   return true;
 }
 
+/// 1) Converts the value on top of the stack to an APValue
+/// 2) Sets that APValue on \Temp
+/// 3) Initialized global with index \I with that
+inline bool InitGlobalTempComp(InterpState , CodePtr OpPC,
+   const LifetimeExtendedTemporaryDecl *Temp) {
+  assert(Temp);
+  const Pointer  = S.Stk.peek();
+  APValue *Cached = Temp->getOrCreateValue(true);
+
+  *Cached = P.toRValue(S.getCtx());
+  return true;
+}
+
 template ::T>
 bool InitThisField(InterpState , CodePtr