return this->emitRet(*ReturnType, RS);
} else {
// RVO - construct the value in the return location.
+ if (!this->emitRVOPtr(RE))
+ return false;
if (!this->visitInitializer(RE))
return false;
+ if (!this->emitPopPtr(RE))
+ return false;
+
this->emitCleanup();
return this->emitRetVoid(RS);
}
return true;
}
+inline bool RVOPtr(InterpState &S, CodePtr OpPC) {
+ assert(S.Current->getFunction()->hasRVO());
+ S.Stk.push<Pointer>(S.Current->getRVOPtr());
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// Shr, Shl
//===----------------------------------------------------------------------===//
// If the fuction has a This pointer, that one is next.
// Then follow the actual arguments (but those are handled
// in getParamPointer()).
+ if (Func->hasRVO())
+ RVOPtr = stackRef<Pointer>(0);
+
if (Func->hasThisPointer()) {
if (Func->hasRVO())
This = stackRef<Pointer>(sizeof(Pointer));
/// Creates a new frame with the values that make sense.
/// I.e., the caller is the current frame of S,
- /// and the This() pointer is the current Pointer on the top of S's stack,
+ /// the This() pointer is the current Pointer on the top of S's stack,
+ /// and the RVO pointer is before that.
InterpFrame(InterpState &S, const Function *Func, CodePtr RetPC);
/// Destroys the frame, killing all live pointers to stack slots.
/// Returns the 'this' pointer.
const Pointer &getThis() const { return This; }
+ /// Returns the RVO pointer, if the Function has one.
+ const Pointer &getRVOPtr() const { return RVOPtr; }
+
/// Checks if the frame is a root frame - return should quit the interpreter.
bool isRoot() const { return !Func; }
const Function *Func;
/// Current object pointer for methods.
Pointer This;
+ /// Pointer the non-primitive return value gets constructed in.
+ Pointer RVOPtr;
/// Return address.
CodePtr RetPC;
/// The size of all the arguments.
// [] -> [Pointer]
def This : Opcode;
+// [] -> [Pointer]
+def RVOPtr : Opcode;
+
// [Pointer] -> [Pointer]
def NarrowPtr : Opcode;
// [Pointer] -> [Pointer]
return C();
}
constexpr C RVOAndParamsResult = RVOAndParams(&c);
+
+/// Parameter and return value have different types.
+constexpr C RVOAndParams(int a) {
+ return C();
+}
+constexpr C RVOAndParamsResult2 = RVOAndParams(12);
#endif
class Bar { // expected-note {{definition of 'Bar' is not complete}} \