[llvm-branch-commits] [clang] [clang] resugar decltype of DeclRefExpr (PR #132447)
Matheus Izvekov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Mar 21 11:44:14 PDT 2025
https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/132447
>From 29cc63d882332f4c476388a8817def7de564ad4b 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 fa4abdb489203..c966d70b66f25 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 934ac60806b7b..26db3567c86d2 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -6848,22 +6848,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);
@@ -14006,6 +14007,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 9d0c1d110062d..d7604484792dc 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -7503,6 +7503,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);
@@ -7527,7 +7528,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 46c3b37f0a6d9..25dea4e230797 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1850,8 +1850,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 ed4c6ef1d4441..66a2f857a2ca4 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 f01962807c350..9af85a8d6fe88 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -4951,11 +4951,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));
@@ -5025,10 +5023,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));
@@ -14693,8 +14690,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 d3638bcf6bb5a..14a20138dfda7 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
@@ -6641,10 +6640,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))
@@ -19465,8 +19465,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: {
@@ -19870,20 +19870,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);
@@ -20930,6 +20923,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();
}
@@ -21197,7 +21192,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 4276e9828c2e0..2e83ed58474db 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 e6c46c7ffdea2..47fe68e77b2af 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -922,6 +922,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 664e4c8adcc39..e30c8faceaccf 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9015,11 +9015,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
@@ -9618,7 +9621,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 d71b663d56ce1..bf239df389a0d 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -16145,9 +16145,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 690c7dc3be6b0..88223fb0bf449 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());
@@ -3186,11 +3190,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 042a096fc89d1..5d57ea8758ad5 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