[PATCH] D156027: [clang][Interp] Rework how initializers work

Timm Bäder via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 22 07:51:12 PDT 2023


tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, shafik, cor3ntin.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Before this patch, we had `visitRecordInitializer()` and `visitArrayInitializer()`, which were different from the regular `visit()` in that they expected a pointer on the top of the stack, which they initialized. For example, `visitArrayInitializer` handled `InitListExprs` by looping over the members and initializing the elements of that pointer.

However, this had a few corner cases and problems. For example, in `visitLambdaExpr()` (a lambda is always of record type), it was not clear whether we should always create a new local variable to save the lambda to, or not. This is why https://reviews.llvm.org/D153616 changed things around.

There is also a long-standing problem with fucnction calls, because we always visit the call arguments like:

  for (const auto *Arg : CtorExpr->arguments()) {
    if (!this->visit(Arg))
      return false;
  }

but if the argument returns a composite type, where does the storage for it come from? Before this patch, it sometimes works and sometimes doesn't.

This patch changes the visiting functions to:

1. `visit()`: Always leaves a new value on the stack. If the expression can be mapped to a primitive type, it's just visited and the value is put on the stack. If it's of composite type, this function will create a local variable for the expression value and call `visitInitializer()`. The pointer to the local variable will stay on the stack.
2. `visitInitializer()`: Visits the given expression, assuming there is a pointer on top of the stack that will be initialized by it.
3. `discard()`: Visit the expression for side-effects, but don't leave a value on the stack.

It also adds an additional `Initializing` flag to differentiate between the initializing and non-initializing case.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156027

Files:
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/AST/Interp/ByteCodeExprGen.h
  clang/lib/AST/Interp/Context.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D156027.543186.patch
Type: text/x-patch
Size: 35115 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230722/c6e12f15/attachment-0001.bin>


More information about the cfe-commits mailing list