aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ByteCode/Compiler.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp40
1 files changed, 20 insertions, 20 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index f131ac1..5275b86 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2062,12 +2062,16 @@ bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
template <class Emitter>
bool Compiler<Emitter>::visitCallArgs(ArrayRef<const Expr *> Args,
const FunctionDecl *FuncDecl,
- bool Activate) {
+ bool Activate, bool IsOperatorCall) {
assert(VarScope->getKind() == ScopeKind::Call);
llvm::BitVector NonNullArgs;
if (FuncDecl && FuncDecl->hasAttr<NonNullAttr>())
NonNullArgs = collectNonNullArgs(FuncDecl, Args);
+ bool ExplicitMemberFn = false;
+ if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
+ ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
+
unsigned ArgIndex = 0;
for (const Expr *Arg : Args) {
if (canClassify(Arg)) {
@@ -2075,8 +2079,19 @@ bool Compiler<Emitter>::visitCallArgs(ArrayRef<const Expr *> Args,
return false;
} else {
- std::optional<unsigned> LocalIndex = allocateLocal(
- Arg, Arg->getType(), /*ExtendingDecl=*/nullptr, ScopeKind::Call);
+ DeclTy Source = Arg;
+ if (FuncDecl) {
+ // Try to use the parameter declaration instead of the argument
+ // expression as a source.
+ unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
+ if (DeclIndex < FuncDecl->getNumParams())
+ Source = FuncDecl->getParamDecl(ArgIndex - IsOperatorCall +
+ ExplicitMemberFn);
+ }
+
+ std::optional<unsigned> LocalIndex =
+ allocateLocal(std::move(Source), Arg->getType(),
+ /*ExtendingDecl=*/nullptr, ScopeKind::Call);
if (!LocalIndex)
return false;
@@ -4489,14 +4504,6 @@ template <class Emitter>
unsigned Compiler<Emitter>::allocateLocalPrimitive(
DeclTy &&Src, PrimType Ty, bool IsConst, const ValueDecl *ExtendingDecl,
ScopeKind SC, bool IsConstexprUnknown) {
- // Make sure we don't accidentally register the same decl twice.
- if (const auto *VD =
- dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
- assert(!P.getGlobal(VD));
- assert(!Locals.contains(VD));
- (void)VD;
- }
-
// FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
// (int){12} in C. Consider using Expr::isTemporaryObject() instead
// or isa<MaterializeTemporaryExpr>().
@@ -4518,19 +4525,11 @@ std::optional<unsigned>
Compiler<Emitter>::allocateLocal(DeclTy &&Src, QualType Ty,
const ValueDecl *ExtendingDecl, ScopeKind SC,
bool IsConstexprUnknown) {
- // Make sure we don't accidentally register the same decl twice.
- if ([[maybe_unused]] const auto *VD =
- dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
- assert(!P.getGlobal(VD));
- assert(!Locals.contains(VD));
- }
-
const ValueDecl *Key = nullptr;
const Expr *Init = nullptr;
bool IsTemporary = false;
if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
Key = VD;
- Ty = VD->getType();
if (const auto *VarD = dyn_cast<VarDecl>(VD))
Init = VarD->getInit();
@@ -5167,7 +5166,8 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
return false;
}
- if (!this->visitCallArgs(Args, FuncDecl, IsAssignmentOperatorCall))
+ if (!this->visitCallArgs(Args, FuncDecl, IsAssignmentOperatorCall,
+ isa<CXXOperatorCallExpr>(E)))
return false;
// Undo the argument reversal we did earlier.