Skip to content

Commit 3231a7b

Browse files
committed
get inout working
1 parent 119def0 commit 3231a7b

File tree

6 files changed

+55
-25
lines changed

6 files changed

+55
-25
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
14801480
/// type to the decayed type.
14811481
QualType getDecayedType(QualType Orig, QualType Decayed) const;
14821482

1483+
/// Return the uniqued reference to a constant array type from the
1484+
/// original array parameter type.
1485+
QualType getConstantArrayFromArrayParameterType(QualType Ty) const;
1486+
14831487
/// Return the uniqued reference to a specified array parameter type from the
14841488
/// original array type.
14851489
QualType getArrayParameterType(QualType Ty) const;

clang/lib/AST/ASTContext.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3852,6 +3852,16 @@ QualType ASTContext::getDecayedType(QualType T) const {
38523852
return getDecayedType(T, Decayed);
38533853
}
38543854

3855+
QualType ASTContext::getConstantArrayFromArrayParameterType(QualType Ty) const {
3856+
if (Ty->isConstantArrayType() && !Ty->isArrayParameterType())
3857+
return Ty;
3858+
assert(Ty->isArrayParameterType() && "Ty must be an array parameter type.");
3859+
const auto *ATy = cast<ArrayParameterType>(Ty);
3860+
return getConstantArrayType(ATy->getElementType(), ATy->getSize(),
3861+
ATy->getSizeExpr(), ATy->getSizeModifier(),
3862+
ATy->getIndexTypeQualifiers().getAsOpaqueValue());
3863+
}
3864+
38553865
QualType ASTContext::getArrayParameterType(QualType Ty) const {
38563866
if (Ty->isArrayParameterType())
38573867
return Ty;

clang/lib/CodeGen/CGCall.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4726,7 +4726,8 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
47264726
return emitWritebackArg(*this, args, CRE);
47274727
}
47284728

4729-
assert(type->isReferenceType() == E->isGLValue() &&
4729+
assert(type->isArrayParameterType() ||
4730+
(type->isReferenceType() == E->isGLValue()) &&
47304731
"reference binding to unmaterialized r-value!");
47314732

47324733
// Add writeback for HLSLOutParamExpr.

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5830,9 +5830,12 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
58305830
// This function implements trivial copy assignment for HLSL's
58315831
// assignable constant arrays.
58325832
LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) {
5833-
LValue TrivialAssignmentRHS = EmitLValue(E->getRHS());
5833+
// Don't emit an LValue for the RHS because it might not be an LValue
58345834
LValue LHS = EmitLValue(E->getLHS());
5835-
EmitAggregateAssign(LHS, TrivialAssignmentRHS, E->getLHS()->getType());
5835+
// In C assignment operator RHS is often an RValue.
5836+
// EmitAggregateAssign expects an LValue for the RHS so call the below
5837+
// function instead.
5838+
EmitInitializationToLValue(E->getRHS(), LHS);
58365839
return LHS;
58375840
}
58385841

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4431,10 +4431,17 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
44314431
break;
44324432

44334433
case ICK_HLSL_Array_RValue:
4434-
FromType = Context.getArrayParameterType(FromType);
4435-
From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue,
4436-
/*BasePath=*/nullptr, CCK)
4434+
if (ToType->isArrayParameterType()) {
4435+
FromType = Context.getArrayParameterType(FromType);
4436+
From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue,
4437+
/*BasePath=*/nullptr, CCK)
44374438
.get();
4439+
} else { // FromType must be ArrayParameterType
4440+
FromType = Context.getConstantArrayFromArrayParameterType(FromType);
4441+
From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue,
4442+
/*BasePath=*/nullptr, CCK)
4443+
.get();
4444+
}
44384445
break;
44394446

44404447
case ICK_Function_To_Pointer:

clang/lib/Sema/SemaOverload.cpp

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,33 +2242,19 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
22422242
return false;
22432243
}
22442244
}
2245-
// Lvalue-to-rvalue conversion (C++11 4.1):
2246-
// A glvalue (3.10) of a non-function, non-array type T can
2247-
// be converted to a prvalue.
2248-
bool argIsLValue = From->isGLValue();
2249-
if (argIsLValue && !FromType->canDecayToPointerType() &&
2250-
S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) {
2251-
SCS.First = ICK_Lvalue_To_Rvalue;
2252-
2253-
// C11 6.3.2.1p2:
2254-
// ... if the lvalue has atomic type, the value has the non-atomic version
2255-
// of the type of the lvalue ...
2256-
if (const AtomicType *Atomic = FromType->getAs<AtomicType>())
2257-
FromType = Atomic->getValueType();
22582245

2259-
// If T is a non-class type, the type of the rvalue is the
2260-
// cv-unqualified version of T. Otherwise, the type of the rvalue
2261-
// is T (C++ 4.1p1). C++ can't get here with class types; in C, we
2262-
// just strip the qualifiers because they don't matter.
2263-
FromType = FromType.getUnqualifiedType();
2264-
} else if (S.getLangOpts().HLSL && FromType->isConstantArrayType() &&
2246+
bool argIsLValue = From->isGLValue();
2247+
if (S.getLangOpts().HLSL && FromType->isConstantArrayType() &&
22652248
ToType->isConstantArrayType()) {
22662249
// HLSL constant array parameters do not decay, so if the argument is a
22672250
// constant array and the parameter is an ArrayParameterType we have special
22682251
// handling here.
22692252
if (ToType->isArrayParameterType()) {
22702253
FromType = S.Context.getArrayParameterType(FromType);
22712254
SCS.First = ICK_HLSL_Array_RValue;
2255+
} else if (FromType->isArrayParameterType()) {
2256+
FromType = S.Context.getConstantArrayFromArrayParameterType(FromType);
2257+
SCS.First = ICK_HLSL_Array_RValue;
22722258
} else {
22732259
SCS.First = ICK_Identity;
22742260
}
@@ -2279,6 +2265,25 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
22792265

22802266
SCS.setAllToTypes(ToType);
22812267
return true;
2268+
} else if (argIsLValue && !FromType->canDecayToPointerType() &&
2269+
S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) {
2270+
// Lvalue-to-rvalue conversion (C++11 4.1):
2271+
// A glvalue (3.10) of a non-function, non-array type T can
2272+
// be converted to a prvalue.
2273+
2274+
SCS.First = ICK_Lvalue_To_Rvalue;
2275+
2276+
// C11 6.3.2.1p2:
2277+
// ... if the lvalue has atomic type, the value has the non-atomic version
2278+
// of the type of the lvalue ...
2279+
if (const AtomicType *Atomic = FromType->getAs<AtomicType>())
2280+
FromType = Atomic->getValueType();
2281+
2282+
// If T is a non-class type, the type of the rvalue is the
2283+
// cv-unqualified version of T. Otherwise, the type of the rvalue
2284+
// is T (C++ 4.1p1). C++ can't get here with class types; in C, we
2285+
// just strip the qualifiers because they don't matter.
2286+
FromType = FromType.getUnqualifiedType();
22822287
} else if (FromType->isArrayType()) {
22832288
// Array-to-pointer conversion (C++ 4.2)
22842289
SCS.First = ICK_Array_To_Pointer;

0 commit comments

Comments
 (0)