This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG400d3261a0da: [HLSL] Cleanup support for `this` as an l-value (authored by beanz).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D159247/new/ https://reviews.llvm.org/D159247 Files: clang/include/clang/AST/ExprCXX.h clang/lib/AST/ASTImporter.cpp clang/lib/AST/DeclCXX.cpp clang/lib/AST/ExprCXX.cpp clang/lib/Analysis/Consumed.cpp clang/lib/CodeGen/CGCall.cpp clang/lib/CodeGen/CGClass.cpp clang/lib/CodeGen/CGOpenMPRuntime.cpp clang/lib/CodeGen/CGVTables.cpp clang/lib/Sema/HLSLExternalSemaSource.cpp clang/lib/Sema/SemaCoroutine.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaExprMember.cpp clang/lib/Sema/SemaOverload.cpp clang/lib/Sema/SemaStmt.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Serialization/ASTReaderStmt.cpp clang/test/CodeGenHLSL/this-reference.hlsl
Index: clang/test/CodeGenHLSL/this-reference.hlsl =================================================================== --- clang/test/CodeGenHLSL/this-reference.hlsl +++ clang/test/CodeGenHLSL/this-reference.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes -o - -hlsl-entry main %s | FileCheck %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes -o - -hlsl-entry main %s -debug-info-kind=standalone -dwarf-version=4 | FileCheck %s struct Pair { int First; @@ -26,3 +26,9 @@ // CHECK-NEXT: store i32 %call, ptr %First, align 4 // CHECK-NEXT: %call1 = call noundef float @"?getSecond@Pair@@QAAMXZ"(ptr noundef nonnull align 4 dereferenceable(8) %Vals) // CHECK-NEXT: %Second = getelementptr inbounds %struct.Pair, ptr %Vals, i32 0, i32 1 + +// CHECK: [[Pair:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Pair" +// CHECK: [[getFirst:![0-9]+]] = distinct !DISubprogram(name: "getFirst" +// CHECK-SAME: scope: [[Pair]] +// CHECK: [[FirstThis:![0-9]+]] = !DILocalVariable(name: "this", arg: 1, scope: [[getFirst]], type: [[thisType:![0-9]+]] +// CHECK: [[thisType]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: [[Pair]], size: 32) Index: clang/lib/Serialization/ASTReaderStmt.cpp =================================================================== --- clang/lib/Serialization/ASTReaderStmt.cpp +++ clang/lib/Serialization/ASTReaderStmt.cpp @@ -3876,7 +3876,7 @@ break; case EXPR_CXX_THIS: - S = new (Context) CXXThisExpr(Empty); + S = CXXThisExpr::CreateEmpty(Context); break; case EXPR_CXX_THROW: Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -754,15 +754,16 @@ if (!MightBeCxx11UnevalField && !isAddressOfOperand && !IsEnum && isa<CXXMethodDecl>(DC) && cast<CXXMethodDecl>(DC)->isInstance()) { - QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType(); + QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType().getNonReferenceType(); // Since the 'this' expression is synthesized, we don't need to // perform the double-lookup check. NamedDecl *FirstQualifierInScope = nullptr; return CXXDependentScopeMemberExpr::Create( - Context, /*This*/ nullptr, ThisType, /*IsArrow*/ true, - /*Op*/ SourceLocation(), SS.getWithLocInContext(Context), TemplateKWLoc, + Context, /*This=*/nullptr, ThisType, + /*IsArrow=*/!Context.getLangOpts().HLSL, + /*Op=*/SourceLocation(), SS.getWithLocInContext(Context), TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs); } Index: clang/lib/Sema/SemaStmt.cpp =================================================================== --- clang/lib/Sema/SemaStmt.cpp +++ clang/lib/Sema/SemaStmt.cpp @@ -689,7 +689,7 @@ if (CMD->isStatic()) Type.MemberType = FuncType::ft_static_member; else { - Type.This = CMD->getThisType()->getPointeeType(); + Type.This = CMD->getThisObjectType(); Type.MemberType = FuncType::ft_non_static_member; } Type.Func = CMD->getType()->castAs<FunctionProtoType>(); Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -3532,14 +3532,14 @@ case OR_Success: { // Record the standard conversion we used and the conversion function. CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function); - QualType ThisType = Constructor->getThisType(); + QualType ThisType = Constructor->getThisObjectType(); // Initializer lists don't have conversions as such. User.Before.setAsIdentityConversion(); User.HadMultipleCandidates = HadMultipleCandidates; User.ConversionFunction = Constructor; User.FoundConversionFunction = Best->FoundDecl; User.After.setAsIdentityConversion(); - User.After.setFromType(ThisType->castAs<PointerType>()->getPointeeType()); + User.After.setFromType(ThisType); User.After.setAllToTypes(ToType); return Result; } @@ -3719,7 +3719,6 @@ // sequence converts the source type to the type required by // the argument of the constructor. // - QualType ThisType = Constructor->getThisType(); if (isa<InitListExpr>(From)) { // Initializer lists don't have conversions as such. User.Before.setAsIdentityConversion(); @@ -3735,7 +3734,7 @@ User.ConversionFunction = Constructor; User.FoundConversionFunction = Best->FoundDecl; User.After.setAsIdentityConversion(); - User.After.setFromType(ThisType->castAs<PointerType>()->getPointeeType()); + User.After.setFromType(Constructor->getThisObjectType()); User.After.setAllToTypes(ToType); return Result; } @@ -5639,8 +5638,7 @@ NamedDecl *FoundDecl, CXXMethodDecl *Method) { QualType FromRecordType, DestType; - QualType ImplicitParamRecordType = - Method->getThisType()->castAs<PointerType>()->getPointeeType(); + QualType ImplicitParamRecordType = Method->getThisObjectType(); Expr::Classification FromClassification; if (const PointerType *PT = From->getType()->getAs<PointerType>()) { Index: clang/lib/Sema/SemaExprMember.cpp =================================================================== --- clang/lib/Sema/SemaExprMember.cpp +++ clang/lib/Sema/SemaExprMember.cpp @@ -1897,20 +1897,11 @@ if (SS.getRange().isValid()) Loc = SS.getRange().getBegin(); baseExpr = BuildCXXThisExpr(loc, ThisTy, /*IsImplicit=*/true); - if (getLangOpts().HLSL && ThisTy.getTypePtr()->isPointerType()) { - ThisTy = ThisTy.getTypePtr()->getPointeeType(); - return BuildMemberReferenceExpr(baseExpr, ThisTy, - /*OpLoc*/ SourceLocation(), - /*IsArrow*/ false, SS, TemplateKWLoc, - /*FirstQualifierInScope*/ nullptr, R, - TemplateArgs, S); - } } - return BuildMemberReferenceExpr(baseExpr, ThisTy, - /*OpLoc*/ SourceLocation(), - /*IsArrow*/ true, - SS, TemplateKWLoc, - /*FirstQualifierInScope*/ nullptr, - R, TemplateArgs, S); + return BuildMemberReferenceExpr( + baseExpr, ThisTy, + /*OpLoc=*/SourceLocation(), + /*IsArrow=*/!getLangOpts().HLSL, SS, TemplateKWLoc, + /*FirstQualifierInScope=*/nullptr, R, TemplateArgs, S); } Index: clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- clang/lib/Sema/SemaExprCXX.cpp +++ clang/lib/Sema/SemaExprCXX.cpp @@ -1217,7 +1217,7 @@ if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC)) { if (method && method->isInstance()) - ThisTy = method->getThisType(); + ThisTy = method->getThisType().getNonReferenceType(); } if (ThisTy.isNull() && isLambdaCallOperator(CurContext) && @@ -1259,7 +1259,8 @@ QualType T = S.Context.getRecordType(Record); T = S.getASTContext().getQualifiedType(T, CXXThisTypeQuals); - S.CXXThisTypeOverride = S.Context.getPointerType(T); + S.CXXThisTypeOverride = + S.Context.getLangOpts().HLSL ? T : S.Context.getPointerType(T); this->Enabled = true; } @@ -1406,14 +1407,7 @@ Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit) { - if (getLangOpts().HLSL && Type.getTypePtr()->isPointerType()) { - auto *This = new (Context) - CXXThisExpr(Loc, Type.getTypePtr()->getPointeeType(), IsImplicit); - This->setValueKind(ExprValueKind::VK_LValue); - MarkThisReferenced(This); - return This; - } - auto *This = new (Context) CXXThisExpr(Loc, Type, IsImplicit); + auto *This = CXXThisExpr::Create(Context, Loc, Type, IsImplicit); MarkThisReferenced(This); return This; } @@ -3966,7 +3960,7 @@ if (getSourceManager().isInSystemHeader(PointeeRD->getLocation())) return; - QualType ClassType = dtor->getThisType()->getPointeeType(); + QualType ClassType = dtor->getThisObjectType(); if (PointeeRD->isAbstract()) { // If the class is abstract, we warn by default, because we're // sure the code has undefined behavior. Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -3220,8 +3220,8 @@ if (Method->isStatic()) return From; - DestType = Method->getThisType(); - DestRecordType = DestType->getPointeeType(); + DestType = Method->getThisType().getNonReferenceType(); + DestRecordType = Method->getThisObjectType(); if (FromType->getAs<PointerType>()) { FromRecordType = FromType->getPointeeType(); Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ clang/lib/Sema/SemaDeclAttr.cpp @@ -1234,7 +1234,7 @@ static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD, const ParsedAttr &AL) { - QualType ThisType = MD->getThisType()->getPointeeType(); + QualType ThisType = MD->getThisObjectType(); if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) { if (!RD->hasAttr<ConsumableAttr>()) { @@ -1343,7 +1343,7 @@ // //} else if (const CXXConstructorDecl *Constructor = // dyn_cast<CXXConstructorDecl>(D)) { - // ReturnType = Constructor->getThisType()->getPointeeType(); + // ReturnType = Constructor->getThisObjectType(); // //} else { // Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -11969,7 +11969,7 @@ // struct B { struct Y { ~Y(); }; using X = Y; }; // template struct A<B>; if (NewFD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None || - !Destructor->getThisType()->isDependentType()) { + !Destructor->getThisObjectType()->isDependentType()) { CXXRecordDecl *Record = Destructor->getParent(); QualType ClassType = Context.getTypeDeclType(Record); Index: clang/lib/Sema/SemaCoroutine.cpp =================================================================== --- clang/lib/Sema/SemaCoroutine.cpp +++ clang/lib/Sema/SemaCoroutine.cpp @@ -78,7 +78,7 @@ // ref-qualifier or with the & ref-qualifier // -- "rvalue reference to cv X" for functions declared with the && // ref-qualifier - QualType T = MD->getThisType()->castAs<PointerType>()->getPointeeType(); + QualType T = MD->getThisObjectType(); T = FnType->getRefQualifier() == RQ_RValue ? S.Context.getRValueReferenceType(T) : S.Context.getLValueReferenceType(T, /*SpelledAsLValue*/ true); @@ -565,7 +565,7 @@ auto *FD = cast<FunctionDecl>(CurContext); bool IsThisDependentType = [&] { if (auto *MD = dyn_cast_or_null<CXXMethodDecl>(FD)) - return MD->isInstance() && MD->getThisType()->isDependentType(); + return MD->isInstance() && MD->getThisObjectType()->isDependentType(); else return false; }(); Index: clang/lib/Sema/HLSLExternalSemaSource.cpp =================================================================== --- clang/lib/Sema/HLSLExternalSemaSource.cpp +++ clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -174,10 +174,9 @@ Expr *Call = CallExpr::Create(AST, Fn, {RCExpr}, AST.VoidPtrTy, VK_PRValue, SourceLocation(), FPOptionsOverride()); - CXXThisExpr *This = new (AST) CXXThisExpr( - SourceLocation(), - Constructor->getThisType().getTypePtr()->getPointeeType(), true); - This->setValueKind(ExprValueKind::VK_LValue); + CXXThisExpr *This = CXXThisExpr::Create( + AST, SourceLocation(), + Constructor->getThisObjectType(), true); Expr *Handle = MemberExpr::CreateImplicit(AST, This, false, Fields["h"], Fields["h"]->getType(), VK_LValue, OK_Ordinary); @@ -261,10 +260,9 @@ auto FnProtoLoc = TSInfo->getTypeLoc().getAs<FunctionProtoTypeLoc>(); FnProtoLoc.setParam(0, IdxParam); - auto *This = new (AST) CXXThisExpr( - SourceLocation(), - MethodDecl->getThisType().getTypePtr()->getPointeeType(), true); - This->setValueKind(ExprValueKind::VK_LValue); + auto *This = CXXThisExpr::Create( + AST, SourceLocation(), + MethodDecl->getThisObjectType(), true); auto *HandleAccess = MemberExpr::CreateImplicit( AST, This, false, Handle, Handle->getType(), VK_LValue, OK_Ordinary); Index: clang/lib/CodeGen/CGVTables.cpp =================================================================== --- clang/lib/CodeGen/CGVTables.cpp +++ clang/lib/CodeGen/CGVTables.cpp @@ -201,7 +201,7 @@ // Find the first store of "this", which will be to the alloca associated // with "this". Address ThisPtr = - Address(&*AI, ConvertTypeForMem(MD->getThisType()->getPointeeType()), + Address(&*AI, ConvertTypeForMem(MD->getThisObjectType()), CGM.getClassPointerAlignment(MD->getParent())); llvm::BasicBlock *EntryBB = &Fn->front(); llvm::BasicBlock::iterator ThisStore = Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -8278,7 +8278,7 @@ // of tofrom. // Emit this[:1] CombinedInfo.Pointers.push_back(PartialStruct.Base.getPointer()); - QualType Ty = MD->getThisType()->getPointeeType(); + QualType Ty = MD->getThisObjectType(); llvm::Value *Size = CGF.Builder.CreateIntCast(CGF.getTypeSize(Ty), CGF.Int64Ty, /*isSigned=*/true); Index: clang/lib/CodeGen/CGClass.cpp =================================================================== --- clang/lib/CodeGen/CGClass.cpp +++ clang/lib/CodeGen/CGClass.cpp @@ -138,7 +138,7 @@ CXXThisAlignment = CGM.getClassPointerAlignment(MD->getParent()); } - llvm::Type *Ty = ConvertType(MD->getThisType()->getPointeeType()); + llvm::Type *Ty = ConvertType(MD->getThisObjectType()); return Address(LoadCXXThis(), Ty, CXXThisAlignment, KnownNonNull); } @@ -2114,8 +2114,7 @@ CallArgList Args; Address This = ThisAVS.getAddress(); LangAS SlotAS = ThisAVS.getQualifiers().getAddressSpace(); - QualType ThisType = D->getThisType(); - LangAS ThisAS = ThisType.getTypePtr()->getPointeeType().getAddressSpace(); + LangAS ThisAS = D->getThisObjectType().getAddressSpace(); llvm::Value *ThisPtr = This.getPointer(); if (SlotAS != ThisAS) { Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ clang/lib/CodeGen/CGCall.cpp @@ -2585,7 +2585,7 @@ llvm::AttrBuilder Attrs(getLLVMContext()); QualType ThisTy = - FI.arg_begin()->type.castAs<PointerType>()->getPointeeType(); + FI.arg_begin()->type.getTypePtr()->getPointeeType(); if (!CodeGenOpts.NullPointerIsValid && getTypes().getTargetAddressSpace(FI.arg_begin()->type) == 0) { Index: clang/lib/Analysis/Consumed.cpp =================================================================== --- clang/lib/Analysis/Consumed.cpp +++ clang/lib/Analysis/Consumed.cpp @@ -771,7 +771,7 @@ void ConsumedStmtVisitor::VisitCXXConstructExpr(const CXXConstructExpr *Call) { CXXConstructorDecl *Constructor = Call->getConstructor(); - QualType ThisType = Constructor->getThisType()->getPointeeType(); + QualType ThisType = Constructor->getThisObjectType(); if (!isConsumableType(ThisType)) return; @@ -1199,7 +1199,7 @@ const FunctionDecl *D) { QualType ReturnType; if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(D)) { - ReturnType = Constructor->getThisType()->getPointeeType(); + ReturnType = Constructor->getThisObjectType(); } else ReturnType = D->getCallResultType(); Index: clang/lib/AST/ExprCXX.cpp =================================================================== --- clang/lib/AST/ExprCXX.cpp +++ clang/lib/AST/ExprCXX.cpp @@ -1515,6 +1515,16 @@ EmptyShell(), HasTemplateKWAndArgsInfo, HasFirstQualifierFoundInScope); } +CXXThisExpr *CXXThisExpr::Create(const ASTContext &Ctx, SourceLocation L, + QualType Ty, bool IsImplicit) { + return new (Ctx) CXXThisExpr(L, Ty, IsImplicit, + Ctx.getLangOpts().HLSL ? VK_LValue : VK_PRValue); +} + +CXXThisExpr *CXXThisExpr::CreateEmpty(const ASTContext &Ctx) { + return new (Ctx) CXXThisExpr(EmptyShell()); +} + static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin, UnresolvedSetIterator end) { do { Index: clang/lib/AST/DeclCXX.cpp =================================================================== --- clang/lib/AST/DeclCXX.cpp +++ clang/lib/AST/DeclCXX.cpp @@ -2492,7 +2492,8 @@ const CXXRecordDecl *Decl) { ASTContext &C = Decl->getASTContext(); QualType ObjectTy = ::getThisObjectType(C, FPT, Decl); - return C.getPointerType(ObjectTy); + return C.getLangOpts().HLSL ? C.getLValueReferenceType(ObjectTy) + : C.getPointerType(ObjectTy); } QualType CXXMethodDecl::getThisObjectType(const FunctionProtoType *FPT, Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -8173,8 +8173,8 @@ if (!ToLocationOrErr) return ToLocationOrErr.takeError(); - return new (Importer.getToContext()) CXXThisExpr( - *ToLocationOrErr, *ToTypeOrErr, E->isImplicit()); + return CXXThisExpr::Create(Importer.getToContext(), *ToLocationOrErr, + *ToTypeOrErr, E->isImplicit()); } ExpectedStmt ASTNodeImporter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { Index: clang/include/clang/AST/ExprCXX.h =================================================================== --- clang/include/clang/AST/ExprCXX.h +++ clang/include/clang/AST/ExprCXX.h @@ -1146,9 +1146,8 @@ /// }; /// \endcode class CXXThisExpr : public Expr { -public: - CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit) - : Expr(CXXThisExprClass, Ty, VK_PRValue, OK_Ordinary) { + CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit, ExprValueKind VK) + : Expr(CXXThisExprClass, Ty, VK, OK_Ordinary) { CXXThisExprBits.IsImplicit = IsImplicit; CXXThisExprBits.Loc = L; setDependence(computeDependence(this)); @@ -1156,6 +1155,12 @@ CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {} +public: + static CXXThisExpr *Create(const ASTContext &Ctx, SourceLocation L, + QualType Ty, bool IsImplicit); + + static CXXThisExpr *CreateEmpty(const ASTContext &Ctx); + SourceLocation getLocation() const { return CXXThisExprBits.Loc; } void setLocation(SourceLocation L) { CXXThisExprBits.Loc = L; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits