Author: Chris Bieneman Date: 2023-09-05T19:38:50-05:00 New Revision: 400d3261a0da56554aee8e5a2fbc27eade9d05db
URL: https://github.com/llvm/llvm-project/commit/400d3261a0da56554aee8e5a2fbc27eade9d05db DIFF: https://github.com/llvm/llvm-project/commit/400d3261a0da56554aee8e5a2fbc27eade9d05db.diff LOG: [HLSL] Cleanup support for `this` as an l-value The goal of this change is to clean up some of the code surrounding HLSL using CXXThisExpr as a non-pointer l-value. This change cleans up a bunch of assumptions and inconsistencies around how the type of `this` is handled through the AST and code generation. This change is be mostly NFC for HLSL, and completely NFC for other language modes. This change introduces a new member to query for the this object's type and seeks to clarify the normal usages of the this type. With the introudction of HLSL to clang, CXXThisExpr may now be an l-value and behave like a reference type rather than C++'s normal method of it being an r-value of pointer type. With this change there are now three ways in which a caller might need to query the type of `this`: * The type of the `CXXThisExpr` * The type of the object `this` referrs to * The type of the implicit (or explicit) `this` argument This change codifies those three ways you may need to query respectively as: * CXXMethodDecl::getThisType() * CXXMethodDecl::getThisObjectType() * CXXMethodDecl::getThisArgType() This change then revisits all uses of `getThisType()`, and in cases where the only use was to resolve the pointee type, it replaces the call with `getThisObjectType()`. In other cases it evaluates whether the desired returned type is the type of the `this` expr, or the type of the `this` function argument. The `this` expr type is used for creating additional expr AST nodes and for member lookup, while the argument type is used mostly for code generation. Additionally some cases that used `getThisType` in simple queries could be substituted for `getThisObjectType`. Since `getThisType` is implemented in terms of `getThisObjectType` calling the later should be more efficient if the former isn't needed. Reviewed By: aaron.ballman, bogner Differential Revision: https://reviews.llvm.org/D159247 Added: Modified: 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 Removed: ################################################################################ diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 02fa997d674c8c8..17dbb5e888ebdd3 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -1146,9 +1146,8 @@ class CXXUuidofExpr : public Expr { /// }; /// \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 @@ class CXXThisExpr : public Expr { 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; } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 282a83980632224..c7c2aecc8b179a4 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -8173,8 +8173,8 @@ ExpectedStmt ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) { 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) { diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index e4572aab5b092a0..9d9c33820c36401 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2492,7 +2492,8 @@ QualType CXXMethodDecl::getThisType(const FunctionProtoType *FPT, 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, diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 72feb206cc3e229..efb64842fb6d96d 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1515,6 +1515,16 @@ CXXDependentScopeMemberExpr *CXXDependentScopeMemberExpr::CreateEmpty( 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 { diff --git a/clang/lib/Analysis/Consumed.cpp b/clang/lib/Analysis/Consumed.cpp index 8ab6d7a7f3b05b0..d90a8a966b210b4 100644 --- a/clang/lib/Analysis/Consumed.cpp +++ b/clang/lib/Analysis/Consumed.cpp @@ -771,7 +771,7 @@ void ConsumedStmtVisitor::VisitCXXBindTemporaryExpr( 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 @@ void ConsumedAnalyzer::determineExpectedReturnState(AnalysisDeclContext &AC, const FunctionDecl *D) { QualType ReturnType; if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(D)) { - ReturnType = Constructor->getThisType()->getPointeeType(); + ReturnType = Constructor->getThisObjectType(); } else ReturnType = D->getCallResultType(); diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 37ccd0d8a2c6cd6..177059191bf4948 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2585,7 +2585,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, 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) { diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index a365365430efe3c..e7ed3ec431f75be 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -138,7 +138,7 @@ Address CodeGenFunction::LoadCXXThisAddress() { 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 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 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) { diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 336cb04b9ad2bed..380bab65c14f2e6 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -8278,7 +8278,7 @@ class MappableExprsHandler { // 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); diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 91dd7a8e046b180..23cfcdd138439f0 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -201,7 +201,7 @@ CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn, // 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 = diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index f29f92aceb50d29..af24d727c2bdbd2 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -174,10 +174,9 @@ struct BuiltinTypeDeclBuilder { 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 @@ struct BuiltinTypeDeclBuilder { 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); diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 42e428344888a8a..cfbe176d8300c23 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -78,7 +78,7 @@ static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD, // 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 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) { 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; }(); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 2ee216fffaa275c..d94366dac102a2a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11969,7 +11969,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // 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); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 728ee4acf429a31..59e0f3e83cfdd80 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1234,7 +1234,7 @@ static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) { 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 @@ static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) { // //} else if (const CXXConstructorDecl *Constructor = // dyn_cast<CXXConstructorDecl>(D)) { - // ReturnType = Constructor->getThisType()->getPointeeType(); + // ReturnType = Constructor->getThisObjectType(); // //} else { // diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 14a33e8688da2fa..3e9c3fad03918f0 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3220,8 +3220,8 @@ Sema::PerformObjectMemberConversion(Expr *From, 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(); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 833223f79689444..a7be01319a72393 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1217,7 +1217,7 @@ QualType Sema::getCurrentThisType() { 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 @@ Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S, 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 @@ ExprResult Sema::ActOnCXXThis(SourceLocation Loc) { 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 @@ void Sema::CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc, 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. diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index 3d14ca3859bb61a..fe92215ae46776f 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -1897,20 +1897,11 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS, 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); } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 5d0299dfa752f92..fb62dee4aa58eae 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -3532,14 +3532,14 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType, 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 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, // 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 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, 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 @@ Sema::PerformObjectArgumentInitialization(Expr *From, 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>()) { diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 88ea3f1c3349dd0..7cc509542d5381d 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -689,7 +689,7 @@ bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) { 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>(); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 808a8b000aff723..994d89e25b3848e 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -754,15 +754,16 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS, 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); } diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 0ab6047ec9e3b92..b9d934983929933 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -3876,7 +3876,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_CXX_THIS: - S = new (Context) CXXThisExpr(Empty); + S = CXXThisExpr::CreateEmpty(Context); break; case EXPR_CXX_THROW: diff --git a/clang/test/CodeGenHLSL/this-reference.hlsl b/clang/test/CodeGenHLSL/this-reference.hlsl index 22bab1d90c70a75..e57f48ccaf3abde 100644 --- a/clang/test/CodeGenHLSL/this-reference.hlsl +++ b/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 @@ void main() { // 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) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits