================ @@ -7071,6 +7071,102 @@ class ArraySectionExpr : public Expr { void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } }; +/// This class represents temporary values used to represent inout and out +/// arguments in HLSL. From the callee perspective these parameters are more or +/// less __restrict__ T&. They are guaranteed to not alias any memory. inout +/// parameters are initialized by the caller, and out parameters are references +/// to uninitialized memory. +/// +/// In the caller, the argument expression creates a temporary in local memory +/// and the address of the temporary is passed into the callee. There may be +/// implicit conversion sequences to initialize the temporary, and on expiration +/// of the temporary an inverse conversion sequence is applied as a write-back +/// conversion to the source l-value. +/// +/// This AST node has three sub-expressions: +/// - An OpaqueValueExpr with a source that is the argument lvalue expression. +/// - An OpaqueValueExpr with a source that is a an implicit conversion +/// sequence from the source lvalue to the argument type. +/// - A BinaryOperatorExpr that assigns the first sub-expression with the +/// value from an implict conversion sequence from the second expression to +/// the argument expression's type. +class HLSLOutArgExpr : public Expr { + friend class ASTStmtReader; + + enum { + BaseLValue, + CastedTemporary, + WritebackCast, + NumSubExprs, + }; + + Stmt *SubExprs[NumSubExprs]; + bool IsInOut; + + HLSLOutArgExpr(QualType Ty, OpaqueValueExpr *B, OpaqueValueExpr *OpV, + Expr *WB, bool IsInOut) + : Expr(HLSLOutArgExprClass, Ty, VK_LValue, OK_Ordinary), + IsInOut(IsInOut) { + SubExprs[BaseLValue] = B; + SubExprs[CastedTemporary] = OpV; + SubExprs[WritebackCast] = WB; + assert(!Ty->isDependentType() && "HLSLOutArgExpr given a dependent type!"); + } + + explicit HLSLOutArgExpr(EmptyShell Shell) + : Expr(HLSLOutArgExprClass, Shell) {} + +public: + static HLSLOutArgExpr *Create(const ASTContext &C, QualType Ty, + OpaqueValueExpr *Base, OpaqueValueExpr *OpV, + Expr *WB, bool IsInOut); + static HLSLOutArgExpr *CreateEmpty(const ASTContext &Ctx); + + const OpaqueValueExpr *getOpaqueArgLValue() const { + return cast<OpaqueValueExpr>(SubExprs[BaseLValue]); + } + OpaqueValueExpr *getOpaqueArgLValue() { + return cast<OpaqueValueExpr>(SubExprs[BaseLValue]); + } + + const Expr *getArgLValue() const { ---------------- rjmccall wrote:
```suggestion /// Return the l-value expression that was written as the argument /// in source. Everything else here is implicitly generated. const Expr *getArgLValue() const { ``` People writing source tools will appreciate this being explicitly called out. https://github.com/llvm/llvm-project/pull/101083 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits