diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -2171,12 +2171,20 @@ /// See getThisType() for usage restriction. QualType getThisObjectType() const; + /// Return the type of the implicit this argument \c this. + /// + /// See getThisType() for usage restriction. + QualType getThisArgType() const; + static QualType getThisType(const FunctionProtoType *FPT, const CXXRecordDecl *Decl); static QualType getThisObjectType(const FunctionProtoType *FPT, const CXXRecordDecl *Decl); + static QualType getThisArgType(const FunctionProtoType *FPT, + const CXXRecordDecl *Decl); + Qualifiers getMethodQualifiers() const { return getType()->castAs()->getMethodQuals(); } diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h --- a/clang/include/clang/AST/ExprCXX.h +++ b/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; } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -8089,8 +8089,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) { diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp --- a/clang/lib/AST/DeclCXX.cpp +++ b/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 ? ObjectTy + : C.getPointerType(ObjectTy); } QualType CXXMethodDecl::getThisObjectType(const FunctionProtoType *FPT, @@ -2501,6 +2502,14 @@ return ::getThisObjectType(C, FPT, Decl); } +QualType CXXMethodDecl::getThisArgType(const FunctionProtoType *FPT, + const CXXRecordDecl *Decl) { + ASTContext &C = Decl->getASTContext(); + QualType ObjectTy = ::getThisObjectType(C, FPT, Decl); + return C.getLangOpts().HLSL ? C.getLValueReferenceType(ObjectTy) + : C.getPointerType(ObjectTy); +} + QualType CXXMethodDecl::getThisType() const { // C++ 9.3.2p1: The type of this in a member function of a class X is X*. // If the member function is declared const, the type of this is const X*, @@ -2519,6 +2528,13 @@ getType()->castAs(), getParent()); } +QualType CXXMethodDecl::getThisArgType() const { + // Ditto getThisType. + assert(isInstance() && "No 'this' for static methods!"); + return CXXMethodDecl::getThisArgType( + getType()->castAs(), getParent()); +} + bool CXXMethodDecl::hasInlineBody() const { // If this function is a template instantiation, look at the template from // which it was instantiated. diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp --- a/clang/lib/AST/ExprCXX.cpp +++ b/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 { diff --git a/clang/lib/Analysis/Consumed.cpp b/clang/lib/Analysis/Consumed.cpp --- a/clang/lib/Analysis/Consumed.cpp +++ b/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; @@ -789,7 +789,7 @@ } else if (Constructor->isCopyConstructor()) { // Copy state from arg. If setStateOnRead then set arg to CS_Unknown. ConsumedState NS = - isSetOnReadPtrType(Constructor->getThisType()) ? + isSetOnReadPtrType(Constructor->getThisArgType()) ? CS_Unknown : CS_None; copyInfo(Call->getArg(0), Call, NS); } else { @@ -1199,7 +1199,7 @@ const FunctionDecl *D) { QualType ReturnType; if (const auto *Constructor = dyn_cast(D)) { - ReturnType = Constructor->getThisType()->getPointeeType(); + ReturnType = Constructor->getThisObjectType(); } else ReturnType = D->getCallResultType(); diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -580,7 +580,7 @@ if (block->capturesCXXThis()) { assert(CGF && CGF->CurFuncDecl && isa(CGF->CurFuncDecl) && "Can't capture 'this' outside a method"); - QualType thisType = cast(CGF->CurFuncDecl)->getThisType(); + QualType thisType = cast(CGF->CurFuncDecl)->getThisArgType(); // Theoretically, this could be in a different address space, so // don't assume standard pointer size/align. diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp --- a/clang/lib/CodeGen/CGCXXABI.cpp +++ b/clang/lib/CodeGen/CGCXXABI.cpp @@ -122,7 +122,7 @@ // generation. Maybe we can come up with a better way? auto *ThisDecl = ImplicitParamDecl::Create( CGM.getContext(), nullptr, MD->getLocation(), - &CGM.getContext().Idents.get("this"), MD->getThisType(), + &CGM.getContext().Idents.get("this"), MD->getThisArgType(), ImplicitParamDecl::CXXThis); params.push_back(ThisDecl); CGF.CXXABIThisDecl = ThisDecl; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2607,7 +2607,7 @@ llvm::AttrBuilder Attrs(getLLVMContext()); QualType ThisTy = - FI.arg_begin()->type.castAs()->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 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/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) { @@ -2127,7 +2126,7 @@ } // Push the this ptr. - Args.add(RValue::get(ThisPtr), D->getThisType()); + Args.add(RValue::get(ThisPtr), D->getThisArgType()); // If this is a trivial constructor, emit a memcpy now before we lose // the alignment information on the argument. @@ -2261,7 +2260,7 @@ const CXXConstructorDecl *D, bool ForVirtualBase, Address This, bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) { CallArgList Args; - CallArg ThisArg(RValue::get(This.getPointer()), D->getThisType()); + CallArg ThisArg(RValue::get(This.getPointer()), D->getThisArgType()); // Forward the parameters. if (InheritedFromVBase && @@ -2386,7 +2385,7 @@ CallArgList Args; // Push the this ptr. - Args.add(RValue::get(This.getPointer()), D->getThisType()); + Args.add(RValue::get(This.getPointer()), D->getThisArgType()); // Push the src ptr. QualType QT = *(FPT->param_type_begin()); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1801,7 +1801,7 @@ if (Method->isStatic()) return cast_or_null( getOrCreateType(QualType(Func, 0), Unit)); - return getOrCreateInstanceMethodType(Method->getThisType(), Func, Unit); + return getOrCreateInstanceMethodType(Method->getThisArgType(), Func, Unit); } llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType( @@ -5115,7 +5115,7 @@ QualType type; if (auto *Method = cast_or_null(blockDecl->getNonClosureContext())) - type = Method->getThisType(); + type = Method->getThisArgType(); else if (auto *RDecl = dyn_cast(blockDecl->getParent())) type = QualType(RDecl->getTypeForDecl(), 0); else diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -105,7 +105,7 @@ LangAS SrcAS = ThisTy.getAddressSpace(); LangAS DstAS = DtorDecl->getMethodQualifiers().getAddressSpace(); if (SrcAS != DstAS) { - QualType DstTy = DtorDecl->getThisType(); + QualType DstTy = DtorDecl->getThisArgType(); llvm::Type *NewType = CGM.getTypes().ConvertType(DstTy); This = getTargetHooks().performAddrSpaceCast(*this, This, SrcAS, DstAS, NewType); diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/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); diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/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 = @@ -246,7 +246,7 @@ // Build FunctionArgs. const CXXMethodDecl *MD = cast(GD.getDecl()); - QualType ThisType = MD->getThisType(); + QualType ThisType = MD->getThisArgType(); QualType ResultType; if (IsUnprototyped) ResultType = CGM.getContext().VoidTy; @@ -327,7 +327,7 @@ // Start building CallArgs. CallArgList CallArgs; - QualType ThisType = MD->getThisType(); + QualType ThisType = MD->getThisArgType(); CallArgs.add(RValue::get(AdjustedThisPtr), ThisType); if (isa(MD)) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1213,7 +1213,7 @@ if (CXXABIThisValue) { SanitizerSet SkippedChecks; SkippedChecks.set(SanitizerKind::ObjectSize, true); - QualType ThisTy = MD->getThisType(); + QualType ThisTy = MD->getThisArgType(); // If this is the call operator of a lambda with no capture-default, it // may have a static invoker function, which may call this operator with @@ -1315,7 +1315,7 @@ const CXXMethodDecl *MD = dyn_cast(FD); if (MD && MD->isInstance()) { if (CGM.getCXXABI().HasThisReturn(GD)) - ResTy = MD->getThisType(); + ResTy = MD->getThisArgType(); else if (CGM.getCXXABI().hasMostDerivedReturn(GD)) ResTy = CGM.getContext().VoidPtrTy; CGM.getCXXABI().buildThisParam(*this, Args); diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -4148,7 +4148,7 @@ CallArgList Args; // Push the this ptr. - Args.add(RValue::get(This), CD->getThisType()); + Args.add(RValue::get(This), CD->getThisArgType()); // Push the src ptr. if (SrcVal) diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/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(); 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 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/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()->getPointeeType(); + QualType T = MD->getThisObjectType(); T = FnType->getRefQualifier() == RQ_RValue ? S.Context.getRValueReferenceType(T) : S.Context.getLValueReferenceType(T, /*SpelledAsLValue*/ true); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11969,7 +11969,7 @@ // struct B { struct Y { ~Y(); }; using X = Y; }; // template struct A; 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 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/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()) { @@ -1343,7 +1343,7 @@ // //} else if (const CXXConstructorDecl *Constructor = // dyn_cast(D)) { - // ReturnType = Constructor->getThisType()->getPointeeType(); + // ReturnType = Constructor->getThisObjectType(); // //} else { // diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3212,7 +3212,7 @@ return From; DestType = Method->getThisType(); - DestRecordType = DestType->getPointeeType(); + DestRecordType = Method->getThisObjectType(); if (FromType->getAs()) { FromRecordType = FromType->getPointeeType(); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1258,7 +1258,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; } @@ -1405,14 +1406,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; } @@ -3965,7 +3959,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. diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -1897,19 +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, + /*IsArrow*/ !getLangOpts().HLSL, SS, TemplateKWLoc, /*FirstQualifierInScope*/ nullptr, R, TemplateArgs, S); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/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(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()->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(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()->getPointeeType()); + User.After.setFromType(Constructor->getThisObjectType()); User.After.setAllToTypes(ToType); return Result; } @@ -5639,13 +5638,12 @@ NamedDecl *FoundDecl, CXXMethodDecl *Method) { QualType FromRecordType, DestType; - QualType ImplicitParamRecordType = - Method->getThisType()->castAs()->getPointeeType(); + QualType ImplicitParamRecordType = Method->getThisObjectType(); Expr::Classification FromClassification; if (const PointerType *PT = From->getType()->getAs()) { FromRecordType = PT->getPointeeType(); - DestType = Method->getThisType(); + DestType = Method->getThisArgType(); FromClassification = Expr::Classification::makeSimpleLValue(); } else { FromRecordType = From->getType(); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp --- a/clang/lib/Sema/SemaStmt.cpp +++ b/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(); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -760,7 +760,8 @@ NamedDecl *FirstQualifierInScope = nullptr; return CXXDependentScopeMemberExpr::Create( - Context, /*This*/ nullptr, ThisType, /*IsArrow*/ true, + 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 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -3880,7 +3880,7 @@ 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 --- 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 @@ // 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)