[llvm-branch-commits] [clang] [clang] resugar decltype of DeclRefExpr (PR #132447)
Matheus Izvekov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Apr 2 18:53:35 PDT 2025
https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/132447
>From 6b9e8d13fa1bd6a6583eab3eef74833b023f1d06 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Fri, 14 Mar 2025 19:41:38 -0300
Subject: [PATCH] [clang] resugar decltype of DeclRefExpr
This keeps around the resugared DeclType for DeclRefExpr,
which is otherwise partially lost as the expression type
removes top level references.
This helps 'decltype' resugaring work without any loss
of information.
---
clang/include/clang/AST/Expr.h | 32 +++++++--
clang/include/clang/AST/Stmt.h | 2 +
clang/include/clang/Sema/Sema.h | 20 +++---
clang/lib/AST/ASTImporter.cpp | 3 +-
clang/lib/AST/Expr.cpp | 82 +++++++++++++++--------
clang/lib/CodeGen/CGExpr.cpp | 4 +-
clang/lib/Sema/SemaChecking.cpp | 3 +-
clang/lib/Sema/SemaDeclCXX.cpp | 19 +++---
clang/lib/Sema/SemaExpr.cpp | 81 +++++++++++-----------
clang/lib/Sema/SemaOpenMP.cpp | 11 ++-
clang/lib/Sema/SemaOverload.cpp | 25 ++++---
clang/lib/Sema/SemaSYCL.cpp | 2 +-
clang/lib/Sema/SemaTemplate.cpp | 13 ++++
clang/lib/Sema/SemaType.cpp | 9 ++-
clang/lib/Sema/TreeTransform.h | 5 +-
clang/lib/Serialization/ASTReaderStmt.cpp | 8 ++-
clang/lib/Serialization/ASTWriterStmt.cpp | 6 +-
clang/test/Sema/Resugar/resugar-expr.cpp | 6 +-
18 files changed, 201 insertions(+), 130 deletions(-)
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<DeclRefExpr, NestedNameSpecifierLoc,
NamedDecl *, ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
+ TemplateArgumentLoc, QualType> {
friend class ASTStmtReader;
friend class ASTStmtWriter;
friend TrailingObjects;
@@ -1292,17 +1292,27 @@ class DeclRefExpr final
return hasTemplateKWAndArgsInfo();
}
+ size_t numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
+ return getNumTemplateArgs();
+ }
+
+ size_t numTrailingObjects(OverloadToken<QualType>) 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<QualType>()
+ : 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 5ac183deec4d0..d4bc49b056252 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<TemplateArgument> 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 c9bb9525a09d7..474c23bb9495a 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 d33d6cdb120cb..57bb5796c64a9 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<ASTTemplateKWAndArgsInfo>()->initializeFrom(
@@ -483,33 +491,39 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
}
+ if (HasResugaredDeclType()) {
+ assert(Ctx.hasSameType(DeclType, D->getType()));
+ *getTrailingObjects<QualType>() =
+ 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<NestedNameSpecifierLoc, NamedDecl *,
- ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ 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<NestedNameSpecifierLoc, NamedDecl *,
- ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
+ 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<QualType>()));
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<QualType>() = T;
}
SourceLocation DeclRefExpr::getBeginLoc() const {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 599cbfdb7b5a5..e9e154912619b 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1864,8 +1864,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 9300729b80ba3..b2b7abd56f822 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<DeclRefExpr>(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<DeclRefExpr>(MemberExprBase));
@@ -14677,8 +14674,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<Token> 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<VarDecl, BindingDecl>(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<ValueDecl>(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<FunctionProtoType>(VD->getType()))
+ if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(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<MemberExpr>(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<DeclRefExpr>(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<MemberExpr>(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<Stmt *, 4> 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<CXXForRangeStmt>(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 d9a8531a34259..e04a8f452f4c1 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -16587,21 +16587,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;
@@ -16625,12 +16623,13 @@ Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
// implicit member access, rewrite to a simple decl ref.
if (MemExpr->isImplicitAccess()) {
if (cast<CXXMethodDecl>(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 ecf762e5b8da7..b65612e0b5737 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 277045c5606bb..f7410564b3661 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9005,11 +9005,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
@@ -9608,7 +9611,7 @@ QualType Sema::getDecltypeForExpr(Expr *E) {
// We apply the same rules for Objective-C ivar and property references.
if (const auto *DRE = dyn_cast<DeclRefExpr>(IDExpr)) {
const ValueDecl *VD = DRE->getDecl();
- QualType T = VD->getType();
+ QualType T = DRE->getDeclType();
return isa<TemplateParamObjectDecl>(VD) ? T.getUnqualifiedType() : T;
}
if (const auto *ME = dyn_cast<MemberExpr>(IDExpr)) {
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 237b3dbc74830..2e93334fbca26 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -16196,9 +16196,10 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
} else {
auto *VD = cast<ValueDecl>(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 0e4819a48c11d..81c3788686933 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<ASTTemplateKWAndArgsInfo>(),
E->getTrailingObjects<TemplateArgumentLoc>(), NumTemplateArgs);
+ if (E->HasResugaredDeclType())
+ *E->getTrailingObjects<QualType>() = Record.readQualType();
+
E->D = readDeclAs<ValueDecl>();
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 0128df1b3fc0f..7a129ddb49579 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<ASTTemplateKWAndArgsInfo>(),
E->getTrailingObjects<TemplateArgumentLoc>());
+ 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<Float>::B<Bar>::a;
namespace t4 {
template <class A1> A1 (*a) ();
-// FIXME: resugar this
Z x1 = decltype(a<Int>){}();
-// expected-error at -1 {{with an rvalue of type 'int'}}
+// expected-error at -1 {{with an rvalue of type 'Int' (aka 'int')}}
} // namespace t4
namespace t5 {
@@ -128,9 +127,8 @@ namespace t12 {
template<class A1> A1 *a;
template<int A3, class A4> decltype(a<A4[A3 - 1]>) a<A4[A3]>;
-// FIXME: resugar this
Z x1 = *a<Int[1]>;
-// expected-error at -1 {{with an lvalue of type 'int[0]'}}
+// expected-error at -1 {{with an lvalue of type 'Int[0]' (aka 'int[0]'}}
} // namespace t12
namespace t13 {
More information about the llvm-branch-commits
mailing list