@@ -7112,6 +7112,103 @@ class ArraySectionExpr : public Expr {
71127112 void setRBracketLoc (SourceLocation L) { RBracketLoc = L; }
71137113};
71147114
7115+ // / This class represents temporary values used to represent inout and out
7116+ // / arguments in HLSL. From the callee perspective these parameters are more or
7117+ // / less __restrict__ T&. They are guaranteed to not alias any memory. inout
7118+ // / parameters are initialized by the caller, and out parameters are references
7119+ // / to uninitialized memory.
7120+ // /
7121+ // / In the caller, the argument expression creates a temporary in local memory
7122+ // / and the address of the temporary is passed into the callee. There may be
7123+ // / implicit conversion sequences to initialize the temporary, and on expiration
7124+ // / of the temporary an inverse conversion sequence is applied as a write-back
7125+ // / conversion to the source l-value.
7126+ // /
7127+ // / This AST node has three sub-expressions:
7128+ // / - An OpaqueValueExpr with a source that is the argument lvalue expression.
7129+ // / - An OpaqueValueExpr with a source that is an implicit conversion
7130+ // / sequence from the source lvalue to the argument type.
7131+ // / - An expression that assigns the second expression into the first,
7132+ // / performing any necessary conversions.
7133+ class HLSLOutArgExpr : public Expr {
7134+ friend class ASTStmtReader ;
7135+
7136+ enum {
7137+ BaseLValue,
7138+ CastedTemporary,
7139+ WritebackCast,
7140+ NumSubExprs,
7141+ };
7142+
7143+ Stmt *SubExprs[NumSubExprs];
7144+ bool IsInOut;
7145+
7146+ HLSLOutArgExpr (QualType Ty, OpaqueValueExpr *B, OpaqueValueExpr *OpV,
7147+ Expr *WB, bool IsInOut)
7148+ : Expr(HLSLOutArgExprClass, Ty, VK_LValue, OK_Ordinary),
7149+ IsInOut (IsInOut) {
7150+ SubExprs[BaseLValue] = B;
7151+ SubExprs[CastedTemporary] = OpV;
7152+ SubExprs[WritebackCast] = WB;
7153+ assert (!Ty->isDependentType () && " HLSLOutArgExpr given a dependent type!" );
7154+ }
7155+
7156+ explicit HLSLOutArgExpr (EmptyShell Shell)
7157+ : Expr(HLSLOutArgExprClass, Shell) {}
7158+
7159+ public:
7160+ static HLSLOutArgExpr *Create (const ASTContext &C, QualType Ty,
7161+ OpaqueValueExpr *Base, OpaqueValueExpr *OpV,
7162+ Expr *WB, bool IsInOut);
7163+ static HLSLOutArgExpr *CreateEmpty (const ASTContext &Ctx);
7164+
7165+ const OpaqueValueExpr *getOpaqueArgLValue () const {
7166+ return cast<OpaqueValueExpr>(SubExprs[BaseLValue]);
7167+ }
7168+ OpaqueValueExpr *getOpaqueArgLValue () {
7169+ return cast<OpaqueValueExpr>(SubExprs[BaseLValue]);
7170+ }
7171+
7172+ // / Return the l-value expression that was written as the argument
7173+ // / in source. Everything else here is implicitly generated.
7174+ const Expr *getArgLValue () const {
7175+ return getOpaqueArgLValue ()->getSourceExpr ();
7176+ }
7177+ Expr *getArgLValue () { return getOpaqueArgLValue ()->getSourceExpr (); }
7178+
7179+ const Expr *getWritebackCast () const {
7180+ return cast<Expr>(SubExprs[WritebackCast]);
7181+ }
7182+ Expr *getWritebackCast () { return cast<Expr>(SubExprs[WritebackCast]); }
7183+
7184+ const OpaqueValueExpr *getCastedTemporary () const {
7185+ return cast<OpaqueValueExpr>(SubExprs[CastedTemporary]);
7186+ }
7187+ OpaqueValueExpr *getCastedTemporary () {
7188+ return cast<OpaqueValueExpr>(SubExprs[CastedTemporary]);
7189+ }
7190+
7191+ // / returns true if the parameter is inout and false if the parameter is out.
7192+ bool isInOut () const { return IsInOut; }
7193+
7194+ SourceLocation getBeginLoc () const LLVM_READONLY {
7195+ return SubExprs[BaseLValue]->getBeginLoc ();
7196+ }
7197+
7198+ SourceLocation getEndLoc () const LLVM_READONLY {
7199+ return SubExprs[BaseLValue]->getEndLoc ();
7200+ }
7201+
7202+ static bool classof (const Stmt *T) {
7203+ return T->getStmtClass () == HLSLOutArgExprClass;
7204+ }
7205+
7206+ // Iterators
7207+ child_range children () {
7208+ return child_range (&SubExprs[BaseLValue], &SubExprs[NumSubExprs]);
7209+ }
7210+ };
7211+
71157212// / Frontend produces RecoveryExprs on semantic errors that prevent creating
71167213// / other well-formed expressions. E.g. when type-checking of a binary operator
71177214// / fails, we cannot produce a BinaryOperator expression. Instead, we can choose
0 commit comments