[llvm-branch-commits] [clang] [clang] resugar decltype of DeclRefExpr (PR #132447)
Matheus Izvekov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Apr 3 11:14:27 PDT 2025
https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/132447
>From 0a363317b9ac02a6a6e2f70e805223bdb135fed3 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 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<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 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<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 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<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));
@@ -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<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 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<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 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<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 ead3784b061a0..fb9536c11dec3 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -16197,9 +16197,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 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<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 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<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