The outermost function doesn't have a This pointers, but inner calls
can. This still doesn't match the diagnostic output of the current
interpreter properly, but it's closer I think.
Differentiate between a volarile read via a lvalue-to-rvalue cast of a
volatile qualified subexpression and a read from a pointer with a
volatile base object.
Fix comparing type id pointers, add mor info when print()ing them, use
the most derived type in GetTypeidPtr() and the canonically unqualified
type when we know the type statically.
The Pointer class already has the capability to be a function pointer,
but we still classifed function pointers as PT_FnPtr/FunctionPointer.
This means when converting from a Pointer to a FunctionPointer, we lost
the information of what the original Pointer pointed to.
This issue is very convoluted, but in essence, in the new version:
For a Pointer P that points to the root of a multidimensional, primitive
array:
`P.narrow()` does nothing.
`P.atIndex(0)` points `P[0]`
`P.atIndex(0).atIndex(0)` is the same as `P.atIndex(0)` (as before)
`P.atIndex(0).narrow().atIndex(0)` points to `P[0][0]`
`P.atIndex(0).narrow().narrow()` is the same as `P.atIndex(0).narrow()`.
Handles #123121
This patch updates `note_constexpr_invalid_cast` diagnostic to use
`enum_select` instead of `select,` improving readability and reducing
reliance on magic numbers in caller sites.
getRecord() returns null on array elements, even for composite arrays.
The assertion here was overly restrictive and having an array element as
instance pointer should be fine otherwise.
Use the regular code paths for interpreting.
Add new instructions: `StartSpeculation` will reset the diagnostics
pointers to `nullptr`, which will keep us from reporting any diagnostics
during speculation. `EndSpeculation` will undo this.
The rest depends on what `Emitter` we use.
For `EvalEmitter`, we have no bytecode, so we implement `speculate()` by
simply visiting the first argument of `__builtin_constant_p`. If the
evaluation fails, we push a `0` on the stack, otherwise a `1`.
For `ByteCodeEmitter`, add another instrucion called `BCP`, that
interprets all the instructions following it until the next
`EndSpeculation` instruction. If any of those instructions fails, we
jump to the `EndLabel`, which brings us right before the
`EndSpeculation`. We then push the result on the stack.
For `new A[N]{1,2,3}`, we need to allocate N elements of type A, and
initialize the first three with the given InitListExpr elements.
However, if N is larger than 3, we need to initialize the remaining
elements with the InitListExpr array filler.
Similarly, for `new A[N];`, we need to initilize all fields with the
constructor of A. The initializer type is a CXXConstructExpr of
IncompleteArrayType in this case, which we can't generally handle.
Make lifetime management more explicit. We're only using this for
CXXPseudoDestructorExprs for now but we need this to handle
std::construct_at/placement-new after destructor calls later anyway.
Instead of heap-allocating it. This is similar to what the current
interpeter does. In C, we have no function calls, so the extra heap
allocation never makes sense.
This reverts commit 81fc3add1e627c23b7270fe2739cdacc09063e54.
This breaks some LLDB tests, e.g.
SymbolFile/DWARF/x86/no_unique_address-with-bitfields.cpp:
lldb: ../llvm-project/clang/lib/AST/Decl.cpp:4604: unsigned int clang::FieldDecl::getBitWidthValue() const: Assertion `isa<ConstantExpr>(getBitWidth())' failed.
Save the bitwidth value as a `ConstantExpr` with the value set. Remove
the `ASTContext` parameter from `getBitWidthValue()`, so the latter
simply returns the value from the `ConstantExpr` instead of
constant-evaluating the bitwidth expression every time it is called.
Add it as another kind of pointer, saving both a `Type*` for the result
of the typeid() expression as well as one for the type of the typeid
expression.