diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 2ba787ac6df55..e92f6696027f9 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1266,7 +1266,7 @@ class DeclRefExpr final : public Expr, private llvm::TrailingObjects { + TemplateArgumentLoc, QualType> { friend class ASTStmtReader; friend class ASTStmtWriter; friend TrailingObjects; @@ -1292,17 +1292,27 @@ class DeclRefExpr final return hasTemplateKWAndArgsInfo(); } + size_t numTrailingObjects(OverloadToken) const { + return getNumTemplateArgs(); + } + + size_t numTrailingObjects(OverloadToken) const { + return HasResugaredDeclType(); + } + /// Test whether there is a distinct FoundDecl attached to the end of /// this DRE. bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; } + static bool needsDeclTypeStorage(ValueDecl *VD, QualType DeclType); + DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentList *ConvertedArgs, QualType T, - ExprValueKind VK, NonOdrUseReason NOUR); + ExprValueKind VK, QualType DeclType, NonOdrUseReason NOUR); /// Construct an empty declaration reference expression. explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {} @@ -1318,7 +1328,8 @@ class DeclRefExpr final Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, - QualType T, ExprValueKind VK, NamedDecl *FoundD = nullptr, + QualType T, ExprValueKind VK, QualType DeclType = QualType(), + NamedDecl *FoundD = nullptr, const TemplateArgumentListInfo *TemplateArgs = nullptr, const TemplateArgumentList *ConvertedArgs = nullptr, NonOdrUseReason NOUR = NOUR_None); @@ -1328,7 +1339,7 @@ class DeclRefExpr final SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK, - NamedDecl *FoundD = nullptr, + QualType DeclType = QualType(), NamedDecl *FoundD = nullptr, const TemplateArgumentListInfo *TemplateArgs = nullptr, const TemplateArgumentList *ConvertedArgs = nullptr, NonOdrUseReason NOUR = NOUR_None); @@ -1337,11 +1348,22 @@ class DeclRefExpr final static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier, bool HasFoundDecl, bool HasTemplateKWAndArgsInfo, - unsigned NumTemplateArgs); + unsigned NumTemplateArgs, + bool HasResugaredDeclType); ValueDecl *getDecl() { return D; } const ValueDecl *getDecl() const { return D; } void setDecl(ValueDecl *NewD); + void recomputeDependency(); + + bool HasResugaredDeclType() const { + return DeclRefExprBits.HasResugaredDeclType; + } + QualType getDeclType() const { + return HasResugaredDeclType() ? *getTrailingObjects() + : D->getType(); + } + void setDeclType(QualType T); DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc); diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 1ab951a005fd9..805d301b95f8e 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -448,6 +448,8 @@ class alignas(void *) Stmt { unsigned NonOdrUseReason : 2; LLVM_PREFERRED_TYPE(bool) unsigned IsImmediateEscalating : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned HasResugaredDeclType : 1; /// The location of the declaration name itself. SourceLocation Loc; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index cb47d2a01b8e9..c476c80f5237d 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -6849,22 +6849,23 @@ class Sema final : public SemaBase { DeclRefExpr *BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, + QualType DeclType = QualType(), const CXXScopeSpec *SS = nullptr); - DeclRefExpr * - BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, - const DeclarationNameInfo &NameInfo, - const CXXScopeSpec *SS = nullptr, - NamedDecl *FoundD = nullptr, - SourceLocation TemplateKWLoc = SourceLocation(), - const TemplateArgumentListInfo *TemplateArgs = nullptr, - const TemplateArgumentList *ConvertArgs = nullptr); + DeclRefExpr *BuildDeclRefExpr( + ValueDecl *D, QualType Ty, ExprValueKind VK, + const DeclarationNameInfo &NameInfo, QualType DeclType = QualType(), + const CXXScopeSpec *SS = nullptr, NamedDecl *FoundD = nullptr, + SourceLocation TemplateKWLoc = SourceLocation(), + const TemplateArgumentListInfo *TemplateArgs = nullptr, + const TemplateArgumentList *ConvertArgs = nullptr); /// BuildDeclRefExpr - Build an expression that references a /// declaration that does not require a closure capture. DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, const DeclarationNameInfo &NameInfo, - NestedNameSpecifierLoc NNS, NamedDecl *FoundD = nullptr, + NestedNameSpecifierLoc NNS, QualType DeclType = QualType(), + NamedDecl *FoundD = nullptr, SourceLocation TemplateKWLoc = SourceLocation(), const TemplateArgumentListInfo *TemplateArgs = nullptr, const TemplateArgumentList *ConvertArgs = nullptr); @@ -14011,6 +14012,7 @@ class Sema final : public SemaBase { QualType resugar(const Type *Base, QualType T); QualType resugar(const Type *Base, NamedDecl *ND, ArrayRef Args, QualType T); + QualType resugar(DeclRefExpr *DRE, ValueDecl *VD); /// Performs template instantiation for all implicit template /// instantiations we have seen until this point. diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 2d163873c740d..876e6cd26ff7b 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -7496,6 +7496,7 @@ ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { auto ToConvertedArgs = importChecked(Err, E->getConvertedArgs()); auto ToLocation = importChecked(Err, E->getLocation()); auto ToType = importChecked(Err, E->getType()); + auto ToDeclType = importChecked(Err, E->getDeclType()); if (Err) return std::move(Err); @@ -7520,7 +7521,7 @@ ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { auto *ToE = DeclRefExpr::Create( Importer.getToContext(), ToQualifierLoc, ToTemplateKeywordLoc, ToDecl, E->refersToEnclosingVariableOrCapture(), ToLocation, ToType, - E->getValueKind(), ToFoundD, ToResInfo, ToConvertedArgs, + E->getValueKind(), ToDeclType, ToFoundD, ToResInfo, ToConvertedArgs, E->isNonOdrUse()); if (E->hadMultipleCandidates()) ToE->setHadMultipleCandidates(true); diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 7d3918c80ff1b..80f22a4eab99c 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -426,6 +426,11 @@ APValue ConstantExpr::getAPValueResult() const { llvm_unreachable("invalid ResultKind"); } +bool DeclRefExpr::needsDeclTypeStorage(ValueDecl *VD, QualType DeclType) { + return !DeclType.isNull() && + (DeclType != VD->getType() || VD->getType()->isUndeducedType()); +} + DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T, ExprValueKind VK, SourceLocation L, @@ -442,6 +447,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; DeclRefExprBits.NonOdrUseReason = NOUR; DeclRefExprBits.IsImmediateEscalating = false; + DeclRefExprBits.HasResugaredDeclType = false; DeclRefExprBits.Loc = L; setDependence(computeDependence(this, Ctx)); } @@ -453,7 +459,8 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentList *ConvertedArgs, QualType T, - ExprValueKind VK, NonOdrUseReason NOUR) + ExprValueKind VK, QualType DeclType, + NonOdrUseReason NOUR) : Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D), ConvertedArgs(ConvertedArgs), DNLoc(NameInfo.getInfo()) { assert(!TemplateArgs || ConvertedArgs); @@ -472,6 +479,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, RefersToEnclosingVariableOrCapture; DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; DeclRefExprBits.NonOdrUseReason = NOUR; + DeclRefExprBits.HasResugaredDeclType = needsDeclTypeStorage(D, DeclType); if (TemplateArgs) { auto Deps = TemplateArgumentDependence::None; getTrailingObjects()->initializeFrom( @@ -483,33 +491,39 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, getTrailingObjects()->initializeFrom( TemplateKWLoc); } + if (HasResugaredDeclType()) { + assert(Ctx.hasSameType(DeclType, D->getType())); + *getTrailingObjects() = + DeclType.isNull() ? D->getType() : DeclType; + } DeclRefExprBits.IsImmediateEscalating = false; DeclRefExprBits.HadMultipleCandidates = 0; setDependence(computeDependence(this, Ctx)); } +DeclRefExpr *DeclRefExpr::Create( + const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *D, + bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, + ExprValueKind VK, QualType DeclType, NamedDecl *FoundD, + const TemplateArgumentListInfo *TemplateArgs, + const TemplateArgumentList *ConvertedArgs, NonOdrUseReason NOUR) { + return Create(Context, QualifierLoc, TemplateKWLoc, D, + RefersToEnclosingVariableOrCapture, + DeclarationNameInfo(D->getDeclName(), NameLoc), T, VK, DeclType, + FoundD, TemplateArgs, ConvertedArgs, NOUR); +} + DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, - SourceLocation NameLoc, QualType T, - ExprValueKind VK, NamedDecl *FoundD, + const DeclarationNameInfo &NameInfo, + QualType T, ExprValueKind VK, + QualType DeclType, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentList *ConvertedArgs, NonOdrUseReason NOUR) { - return Create(Context, QualifierLoc, TemplateKWLoc, D, - RefersToEnclosingVariableOrCapture, - DeclarationNameInfo(D->getDeclName(), NameLoc), T, VK, FoundD, - TemplateArgs, ConvertedArgs, NOUR); -} - -DeclRefExpr *DeclRefExpr::Create( - const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, ValueDecl *D, - bool RefersToEnclosingVariableOrCapture, - const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK, - NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, - const TemplateArgumentList *ConvertedArgs, NonOdrUseReason NOUR) { // Filter out cases where the found Decl is the same as the value refenenced. if (D == FoundD) FoundD = nullptr; @@ -517,38 +531,52 @@ DeclRefExpr *DeclRefExpr::Create( bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid(); std::size_t Size = totalSizeToAlloc( + ASTTemplateKWAndArgsInfo, TemplateArgumentLoc, QualType>( QualifierLoc ? 1 : 0, FoundD ? 1 : 0, HasTemplateKWAndArgsInfo ? 1 : 0, - TemplateArgs ? TemplateArgs->size() : 0); + TemplateArgs ? TemplateArgs->size() : 0, + needsDeclTypeStorage(D, DeclType) ? 1 : 0); void *Mem = Context.Allocate(Size, alignof(DeclRefExpr)); return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D, RefersToEnclosingVariableOrCapture, NameInfo, FoundD, - TemplateArgs, ConvertedArgs, T, VK, NOUR); + TemplateArgs, ConvertedArgs, T, VK, DeclType, NOUR); } DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context, - bool HasQualifier, - bool HasFoundDecl, + bool HasQualifier, bool HasFoundDecl, bool HasTemplateKWAndArgsInfo, - unsigned NumTemplateArgs) { + unsigned NumTemplateArgs, + bool HasResugaredDeclType) { assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); std::size_t Size = totalSizeToAlloc( + ASTTemplateKWAndArgsInfo, TemplateArgumentLoc, QualType>( HasQualifier ? 1 : 0, HasFoundDecl ? 1 : 0, HasTemplateKWAndArgsInfo, - NumTemplateArgs); + NumTemplateArgs, HasResugaredDeclType ? 1 : 0); void *Mem = Context.Allocate(Size, alignof(DeclRefExpr)); return new (Mem) DeclRefExpr(EmptyShell()); } void DeclRefExpr::setDecl(ValueDecl *NewD) { + assert(D != NewD); + assert(declaresSameEntity(D, NewD)); + assert(!HasResugaredDeclType() || + D->getASTContext().hasSameType(NewD->getType(), + *getTrailingObjects())); D = NewD; - if (getType()->isUndeducedType()) - setType(NewD->getType()); - setDependence(computeDependence(this, NewD->getASTContext())); + recomputeDependency(); +} + +void DeclRefExpr::recomputeDependency() { + setDependence(computeDependence(this, D->getASTContext())); +} + +void DeclRefExpr::setDeclType(QualType T) { + assert(!T.isNull()); + if (HasResugaredDeclType()) + *getTrailingObjects() = T; } SourceLocation DeclRefExpr::getBeginLoc() const { diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 01d2b3af362ab..6b9b6199e575b 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1867,8 +1867,8 @@ static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CodeGenFunction &CGF, return DeclRefExpr::Create( CGF.getContext(), NestedNameSpecifierLoc(), SourceLocation(), VD, /*RefersToEnclosingVariableOrCapture=*/false, ME->getExprLoc(), - ME->getType(), ME->getValueKind(), nullptr, nullptr, nullptr, - ME->isNonOdrUse()); + ME->getType(), ME->getValueKind(), QualType(), nullptr, nullptr, + nullptr, ME->isNonOdrUse()); } return nullptr; } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 974bf3b018c09..f7424e3e60b30 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -4632,7 +4632,8 @@ ExprResult Sema::BuiltinAtomicOverloaded(ExprResult TheCallResult) { DeclRefExpr *NewDRE = DeclRefExpr::Create( Context, DRE->getQualifierLoc(), SourceLocation(), NewBuiltinDecl, /*enclosing*/ false, DRE->getLocation(), Context.BuiltinFnTy, - DRE->getValueKind(), nullptr, nullptr, nullptr, DRE->isNonOdrUse()); + DRE->getValueKind(), QualType(), nullptr, nullptr, nullptr, + DRE->isNonOdrUse()); // Set the callee in the CallExpr. // FIXME: This loses syntactic information. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 0ed14abf6f8ac..b46ab2cde3209 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4920,11 +4920,9 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, ParmVarDecl *Param = Constructor->getParamDecl(0); QualType ParamType = Param->getType().getNonReferenceType(); - Expr *CopyCtorArg = - DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), - SourceLocation(), Param, false, - Constructor->getLocation(), ParamType, - VK_LValue, nullptr); + Expr *CopyCtorArg = DeclRefExpr::Create( + SemaRef.Context, NestedNameSpecifierLoc(), SourceLocation(), Param, + false, Constructor->getLocation(), ParamType, VK_LValue); SemaRef.MarkDeclRefReferenced(cast(CopyCtorArg)); @@ -4994,10 +4992,9 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, if (Field->isZeroLengthBitField()) return false; - Expr *MemberExprBase = - DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), - SourceLocation(), Param, false, - Loc, ParamType, VK_LValue, nullptr); + Expr *MemberExprBase = DeclRefExpr::Create( + SemaRef.Context, NestedNameSpecifierLoc(), SourceLocation(), Param, + false, Loc, ParamType, VK_LValue); SemaRef.MarkDeclRefReferenced(cast(MemberExprBase)); @@ -14676,8 +14673,8 @@ buildMemcpyForAssignmentOp(Sema &S, SourceLocation Loc, QualType T, // about it. return StmtError(); - ExprResult MemCpyRef = S.BuildDeclRefExpr(MemCpy, S.Context.BuiltinFnTy, - VK_PRValue, Loc, nullptr); + ExprResult MemCpyRef = + S.BuildDeclRefExpr(MemCpy, S.Context.BuiltinFnTy, VK_PRValue, Loc); assert(MemCpyRef.isUsable() && "Builtin reference cannot fail"); Expr *CallArgs[] = { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0077d8321ac88..18e5c77b55c49 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2219,25 +2219,24 @@ Sema::ActOnStringLiteral(ArrayRef StringToks, Scope *UDLScope) { llvm_unreachable("unexpected literal operator lookup result"); } -DeclRefExpr * -Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, - SourceLocation Loc, - const CXXScopeSpec *SS) { +DeclRefExpr *Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, + SourceLocation Loc, QualType DeclType, + const CXXScopeSpec *SS) { DeclarationNameInfo NameInfo(D->getDeclName(), Loc); - return BuildDeclRefExpr(D, Ty, VK, NameInfo, SS); + return BuildDeclRefExpr(D, Ty, VK, NameInfo, DeclType, SS); } DeclRefExpr * Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, - const DeclarationNameInfo &NameInfo, + const DeclarationNameInfo &NameInfo, QualType DeclType, const CXXScopeSpec *SS, NamedDecl *FoundD, SourceLocation TemplateKWLoc, const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentList *ConvertedArgs) { NestedNameSpecifierLoc NNS = SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(); - return BuildDeclRefExpr(D, Ty, VK, NameInfo, NNS, FoundD, TemplateKWLoc, - TemplateArgs, ConvertedArgs); + return BuildDeclRefExpr(D, Ty, VK, NameInfo, NNS, DeclType, FoundD, + TemplateKWLoc, TemplateArgs, ConvertedArgs); } // CUDA/HIP: Check whether a captured reference variable is referencing a @@ -2300,18 +2299,18 @@ NonOdrUseReason Sema::getNonOdrUseReasonInCurrentContext(ValueDecl *D) { DeclRefExpr * Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, const DeclarationNameInfo &NameInfo, - NestedNameSpecifierLoc NNS, NamedDecl *FoundD, - SourceLocation TemplateKWLoc, + NestedNameSpecifierLoc NNS, QualType DeclType, + NamedDecl *FoundD, SourceLocation TemplateKWLoc, const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentList *ConvertedArgs) { bool RefersToCapturedVariable = isa(D) && NeedToCaptureVariable(D, NameInfo.getLoc()); assert(!TemplateArgs || ConvertedArgs); - DeclRefExpr *E = DeclRefExpr::Create(Context, NNS, TemplateKWLoc, D, - RefersToCapturedVariable, NameInfo, Ty, - VK, FoundD, TemplateArgs, ConvertedArgs, - getNonOdrUseReasonInCurrentContext(D)); + DeclRefExpr *E = DeclRefExpr::Create( + Context, NNS, TemplateKWLoc, D, RefersToCapturedVariable, NameInfo, Ty, + VK, DeclType, FoundD, TemplateArgs, ConvertedArgs, + getNonOdrUseReasonInCurrentContext(D)); MarkDeclRefReferenced(E); // C++ [except.spec]p17: @@ -2732,6 +2731,7 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // LookupName handles a name lookup from within anonymous struct. if (LookupName(R, S)) { if (auto *VD = dyn_cast(R.getFoundDecl())) { + // FIXME: resugar QualType type = VD->getType().getNonReferenceType(); // This will eventually be translated into MemberExpr upon // the use of instantiated struct fields. @@ -3306,19 +3306,19 @@ ExprResult Sema::BuildDeclarationNameExpr( return BuildAnonymousStructUnionMemberReference(SS, NameInfo.getLoc(), IndirectField); - QualType type = VD->getType(); - if (type.isNull()) + QualType DeclType = VD->getType(); + if (DeclType.isNull()) return ExprError(); assert(!TemplateArgs || ConvertedArgs); - type = ConvertedArgs - ? resugar(SS.getScopeRep(), VD, ConvertedArgs->asArray(), type) - : resugar(SS.getScopeRep(), type); + DeclType = ConvertedArgs ? resugar(SS.getScopeRep(), VD, + ConvertedArgs->asArray(), DeclType) + : resugar(SS.getScopeRep(), DeclType); ExprValueKind valueKind = VK_PRValue; // In 'T ...V;', the type of the declaration 'V' is 'T...', but the type of // a reference to 'V' is simply (unexpanded) 'T'. The type, like the value, // is expanded by some outer '...' in the context of the use. - type = type.getNonPackExpansionType(); + QualType type = DeclType.getNonPackExpansionType(); switch (D->getKind()) { // Ignore all the non-ValueDecl kinds. @@ -3473,8 +3473,7 @@ ExprResult Sema::BuildDeclarationNameExpr( // If we're referring to a method with an __unknown_anytype // result type, make the entire expression __unknown_anytype. // This should only be possible with a type written directly. - if (const FunctionProtoType *proto = - dyn_cast(VD->getType())) + if (const FunctionProtoType *proto = dyn_cast(DeclType)) if (proto->getReturnType() == Context.UnknownAnyTy) { type = Context.UnknownAnyTy; valueKind = VK_PRValue; @@ -3495,9 +3494,9 @@ ExprResult Sema::BuildDeclarationNameExpr( break; } - auto *E = BuildDeclRefExpr(VD, type, valueKind, NameInfo, &SS, FoundD, - /*FIXME: TemplateKWLoc*/ SourceLocation(), - TemplateArgs, ConvertedArgs); + auto *E = BuildDeclRefExpr( + VD, type, valueKind, NameInfo, DeclType, &SS, FoundD, + /*FIXME: TemplateKWLoc*/ SourceLocation(), TemplateArgs, ConvertedArgs); // Clang AST consumers assume a DeclRefExpr refers to a valid decl. We // wrap a DeclRefExpr referring to an invalid decl with a dependent-type // RecoveryExpr to avoid follow-up semantic analysis (thus prevent bogus @@ -6664,10 +6663,11 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, if ((FDecl = rewriteBuiltinFunctionDecl(this, Context, FDecl, ArgExprs))) { NDecl = FDecl; - Fn = DeclRefExpr::Create( - Context, FDecl->getQualifierLoc(), SourceLocation(), FDecl, false, - SourceLocation(), FDecl->getType(), Fn->getValueKind(), FDecl, - nullptr, nullptr, DRE->isNonOdrUse()); + NestedNameSpecifierLoc NNS = FDecl->getQualifierLoc(); + QualType T = resugar(NNS.getNestedNameSpecifier(), FDecl->getType()); + Fn = DeclRefExpr::Create(Context, NNS, SourceLocation(), FDecl, false, + SourceLocation(), T, Fn->getValueKind(), T, + FDecl, nullptr, nullptr, DRE->isNonOdrUse()); } } } else if (auto *ME = dyn_cast(NakedFn)) @@ -19489,8 +19489,8 @@ static ExprResult rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E, S.Context, DRE->getQualifierLoc(), DRE->getTemplateKeywordLoc(), DRE->getDecl(), DRE->refersToEnclosingVariableOrCapture(), DRE->getNameInfo(), DRE->getType(), DRE->getValueKind(), - DRE->getFoundDecl(), CopiedTemplateArgs(DRE), DRE->getConvertedArgs(), - NOUR); + DRE->getDeclType(), DRE->getFoundDecl(), CopiedTemplateArgs(DRE), + DRE->getConvertedArgs(), NOUR); } case Expr::FunctionParmPackExprClass: { @@ -19900,20 +19900,13 @@ static void DoMarkVarDeclReferenced( // Re-set the member to trigger a recomputation of the dependence bits // for the expression. - CXXScopeSpec SS; if (auto *DRE = dyn_cast_or_null(E)) { - DRE->setDecl(DRE->getDecl()); - SS.Adopt(DRE->getQualifierLoc()); - assert(DRE->template_arguments().size() == 0 || - DRE->getConvertedArgs() != nullptr); - QualType T = DRE->getConvertedArgs() - ? SemaRef.resugar(SS.getScopeRep(), DRE->getDecl(), - DRE->getConvertedArgs()->asArray(), - DRE->getType()) - : SemaRef.resugar(SS.getScopeRep(), DRE->getType()); - DRE->setType(T); + if (DRE->getType()->isUndeducedType()) + DRE->setType(SemaRef.resugar(DRE, DRE->getDecl())); + DRE->recomputeDependency(); } else if (auto *ME = dyn_cast_or_null(E)) { ME->setMemberDecl(ME->getMemberDecl()); + CXXScopeSpec SS; SS.Adopt(ME->getQualifierLoc()); assert(ME->template_arguments().size() == 0 || ME->getDeduced() != nullptr); @@ -20960,6 +20953,8 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) { Params.push_back(Param); } NewFD->setParams(Params); + NewFD->setPreviousDeclaration(FD); + // FIXME: resugar? DRE->setDecl(NewFD); VD = DRE->getDecl(); } @@ -21227,7 +21222,7 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { DRE->copyTemplateArgumentsInto(TemplateArgs); // FIXME: resugar return BuildDeclRefExpr( - FD, FD->getType(), VK_LValue, DRE->getNameInfo(), + FD, FD->getType(), VK_LValue, DRE->getNameInfo(), QualType(), DRE->hasQualifier() ? &SS : nullptr, DRE->getFoundDecl(), DRE->getTemplateKeywordLoc(), DRE->hasExplicitTemplateArgs() ? &TemplateArgs : nullptr, diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index a382947455aef..11ae32c655408 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5416,7 +5416,7 @@ static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy, // Get the LValue expression for the result. ImplicitParamDecl *DistParam = CS->getParam(0); DeclRefExpr *DistRef = Actions.BuildDeclRefExpr( - DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); + DistParam, LogicalTy, VK_LValue, SourceLocation()); SmallVector BodyStmts; @@ -5571,10 +5571,10 @@ static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, ImplicitParamDecl *TargetParam = CS->getParam(0); DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr( - TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); + TargetParam, LoopVarTy, VK_LValue, SourceLocation()); ImplicitParamDecl *IndvarParam = CS->getParam(1); DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr( - IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); + IndvarParam, LogicalTy, VK_LValue, SourceLocation()); // Capture the Start expression. CaptureVars Recap(Actions); @@ -5747,9 +5747,8 @@ StmtResult SemaOpenMP::ActOnOpenMPCanonicalLoop(Stmt *AStmt) { buildDistanceFunc(SemaRef, LogicalTy, CondRel, LHS, RHS, Step); CapturedStmt *LoopVarFunc = buildLoopVarFunc( SemaRef, LVTy, LogicalTy, CounterRef, Step, isa(AStmt)); - DeclRefExpr *LVRef = - SemaRef.BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, {}, - nullptr, nullptr, {}, nullptr); + DeclRefExpr *LVRef = SemaRef.BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), + VK_LValue, SourceLocation()); return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc, LoopVarFunc, LVRef); } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 8f89e159cc964..934e0d05b4948 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -16590,21 +16590,19 @@ Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, : VK_PRValue; // FIXME: Duplicated from BuildDeclarationNameExpr. - QualType Type; - { - unsigned BID = Fn->getBuiltinID(); - if (BID && !Context.BuiltinInfo.isDirectlyAddressable(BID)) { - Type = Context.BuiltinFnTy; - ValueKind = VK_PRValue; - } else { - Type = Deduced ? resugar(NNS.getNestedNameSpecifier(), Fn, - Deduced->asArray(), Fn->getType()) - : resugar(NNS.getNestedNameSpecifier(), Fn->getType()); - } + QualType DeclType = + Deduced ? resugar(NNS.getNestedNameSpecifier(), Fn, Deduced->asArray(), + Fn->getType()) + : resugar(NNS.getNestedNameSpecifier(), Fn->getType()); + QualType Type = DeclType; + if (unsigned BID = Fn->getBuiltinID(); + BID && !Context.BuiltinInfo.isDirectlyAddressable(BID)) { + Type = Context.BuiltinFnTy; + ValueKind = VK_PRValue; } DeclRefExpr *DRE = BuildDeclRefExpr( - Fn, Type, ValueKind, ULE->getNameInfo(), NNS, Found.getDecl(), + Fn, Type, ValueKind, ULE->getNameInfo(), NNS, DeclType, Found.getDecl(), ULE->getTemplateKeywordLoc(), TemplateArgs, Deduced); DRE->setHadMultipleCandidates(ULE->getNumDecls() > 1); return DRE; @@ -16628,12 +16626,13 @@ Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, // implicit member access, rewrite to a simple decl ref. if (MemExpr->isImplicitAccess()) { if (cast(Fn)->isStatic()) { + // FIXME: Include the MemberExpr Qualifier. QualType Type = Deduced ? resugar(BasePointeeType, Fn, Deduced->asArray(), Fn->getType()) : resugar(BasePointeeType, Fn->getType()); DeclRefExpr *DRE = BuildDeclRefExpr( Fn, Type, VK_LValue, MemExpr->getNameInfo(), - MemExpr->getQualifierLoc(), Found.getDecl(), + MemExpr->getQualifierLoc(), Type, Found.getDecl(), MemExpr->getTemplateKeywordLoc(), TemplateArgs, Deduced); DRE->setHadMultipleCandidates(MemExpr->getNumDecls() > 1); return DRE; diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index ddd92782366b5..03a0ba9c58152 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -399,7 +399,7 @@ class OutlinedFunctionDeclBodyInstantiator return DeclRefExpr::Create( SemaRef.getASTContext(), DRE->getQualifierLoc(), DRE->getTemplateKeywordLoc(), VD, false, DRE->getNameInfo(), - DRE->getType(), DRE->getValueKind()); + DRE->getType(), DRE->getValueKind(), DRE->getDeclType()); } } return DRE; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index bb3eecbf60bb3..ec4d3a30bbb01 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -935,6 +935,19 @@ QualType Sema::resugar(const Type *Base, const NestedNameSpecifier *FieldNNS, bool Changed = false; return Resugarer(*this, Names).transform(T, Changed); } +QualType Sema::resugar(DeclRefExpr *DRE, ValueDecl *VD) { + assert(DRE->template_arguments().size() == 0 || + DRE->getConvertedArgs() != nullptr); + const NestedNameSpecifier *NNS = + DRE->getQualifierLoc().getNestedNameSpecifier(); + QualType T = VD->getType(); + QualType NewT = + DRE->getConvertedArgs() + ? SemaRef.resugar(NNS, VD, DRE->getConvertedArgs()->asArray(), T) + : SemaRef.resugar(NNS, T); + DRE->setDeclType(NewT); + return NewT; +} /// \brief Determine whether the declaration found is acceptable as the name /// of a template and, if so, return that template declaration. Otherwise, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 23eda1cb17d9a..c94d706a829c4 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -9010,11 +9010,14 @@ void Sema::completeExprArrayBound(Expr *E) { // Update the type to the definition's type both here and within the // expression. if (Def) { - DRE->setDecl(Def); - QualType T = Def->getType(); + QualType T = SemaRef.resugar(DRE, Def); DRE->setType(T); // FIXME: Update the type on all intervening expressions. E->setType(T); + if (Var != Def) + DRE->setDecl(Def); + else + DRE->recomputeDependency(); } // We still go on to try to complete the type independently, as it @@ -9613,7 +9616,7 @@ QualType Sema::getDecltypeForExpr(Expr *E) { // We apply the same rules for Objective-C ivar and property references. if (const auto *DRE = dyn_cast(IDExpr)) { const ValueDecl *VD = DRE->getDecl(); - QualType T = VD->getType(); + QualType T = DRE->getDeclType(); return isa(VD) ? T.getUnqualifiedType() : T; } if (const auto *ME = dyn_cast(IDExpr)) { diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index ead3784b061a0..fb9536c11dec3 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -16197,9 +16197,10 @@ TreeTransform::TransformSizeOfPackExpr(SizeOfPackExpr *E) { ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt); } else { auto *VD = cast(Pack); + QualType DeclType = VD->getType(); ExprResult DRE = getSema().BuildDeclRefExpr( - VD, VD->getType().getNonLValueExprType(getSema().Context), - VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue, + VD, DeclType.getNonLValueExprType(getSema().Context), + DeclType->isReferenceType() ? VK_LValue : VK_PRValue, E->getPackLoc()); if (DRE.isInvalid()) return ExprError(); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index a4f1856401b71..57f47bd75a745 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -622,6 +622,7 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { E->DeclRefExprBits.HasQualifier = CurrentUnpackingBits->getNextBit(); E->DeclRefExprBits.HasTemplateKWAndArgsInfo = CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.HasResugaredDeclType = CurrentUnpackingBits->getNextBit(); E->DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; unsigned NumTemplateArgs = 0; @@ -640,6 +641,9 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { *E->getTrailingObjects(), E->getTrailingObjects(), NumTemplateArgs); + if (E->HasResugaredDeclType()) + *E->getTrailingObjects() = Record.readQualType(); + E->D = readDeclAs(); E->ConvertedArgs = Record.readTemplateArgumentList(); E->setLocation(readSourceLocation()); @@ -3184,11 +3188,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { bool HasFoundDecl = DeclRefExprBits.getNextBit(); bool HasQualifier = DeclRefExprBits.getNextBit(); bool HasTemplateKWAndArgsInfo = DeclRefExprBits.getNextBit(); + bool HasResugaredDeclType = DeclRefExprBits.getNextBit(); unsigned NumTemplateArgs = HasTemplateKWAndArgsInfo ? Record[ASTStmtReader::NumExprFields + 1] : 0; S = DeclRefExpr::CreateEmpty(Context, HasQualifier, HasFoundDecl, - HasTemplateKWAndArgsInfo, NumTemplateArgs); + HasTemplateKWAndArgsInfo, NumTemplateArgs, + HasResugaredDeclType); break; } diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 85a89b2a1308b..82ed11d0f0607 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -696,6 +696,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { CurrentPackingBits.addBit(E->getDecl() != E->getFoundDecl()); CurrentPackingBits.addBit(E->hasQualifier()); CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo()); + CurrentPackingBits.addBit(E->HasResugaredDeclType()); if (E->hasTemplateKWAndArgsInfo()) { unsigned NumTemplateArgs = E->getNumTemplateArgs(); @@ -707,7 +708,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) && (E->getDecl() == E->getFoundDecl()) && nk == DeclarationName::Identifier && E->getObjectKind() == OK_Ordinary && - !E->getConvertedArgs()) { + !E->getConvertedArgs() && !E->HasResugaredDeclType()) { AbbrevToUse = Writer.getDeclRefExprAbbrev(); } @@ -721,6 +722,9 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { AddTemplateKWAndArgsInfo(*E->getTrailingObjects(), E->getTrailingObjects()); + if (E->HasResugaredDeclType()) + Record.writeQualType(E->getDeclType()); + Record.AddDeclRef(E->getDecl()); if (E->ConvertedArgs) Record.AddTemplateArgumentList(E->ConvertedArgs); diff --git a/clang/test/Sema/Resugar/resugar-expr.cpp b/clang/test/Sema/Resugar/resugar-expr.cpp index 336c480b359cc..4b6b82f1b9eaa 100644 --- a/clang/test/Sema/Resugar/resugar-expr.cpp +++ b/clang/test/Sema/Resugar/resugar-expr.cpp @@ -40,9 +40,8 @@ Z x1 = A::B::a; namespace t4 { template A1 (*a) (); -// FIXME: resugar this Z x1 = decltype(a){}(); -// expected-error@-1 {{with an rvalue of type 'int'}} +// expected-error@-1 {{with an rvalue of type 'Int' (aka 'int')}} } // namespace t4 namespace t5 { @@ -128,9 +127,8 @@ namespace t12 { template A1 *a; template decltype(a) a; -// FIXME: resugar this Z x1 = *a; -// expected-error@-1 {{with an lvalue of type 'int[0]'}} +// expected-error@-1 {{with an lvalue of type 'Int[0]' (aka 'int[0]'}} } // namespace t12 namespace t13 {