[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.
This commit is contained in:
Matheus Izvekov 2025-03-14 19:41:38 -03:00
parent df203b5f17
commit 0a363317b9
No known key found for this signature in database
18 changed files with 201 additions and 130 deletions

View File

@ -1266,7 +1266,7 @@ class DeclRefExpr final
: public Expr, : public Expr,
private llvm::TrailingObjects<DeclRefExpr, NestedNameSpecifierLoc, private llvm::TrailingObjects<DeclRefExpr, NestedNameSpecifierLoc,
NamedDecl *, ASTTemplateKWAndArgsInfo, NamedDecl *, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> { TemplateArgumentLoc, QualType> {
friend class ASTStmtReader; friend class ASTStmtReader;
friend class ASTStmtWriter; friend class ASTStmtWriter;
friend TrailingObjects; friend TrailingObjects;
@ -1292,17 +1292,27 @@ class DeclRefExpr final
return hasTemplateKWAndArgsInfo(); 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 /// Test whether there is a distinct FoundDecl attached to the end of
/// this DRE. /// this DRE.
bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; } bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
static bool needsDeclTypeStorage(ValueDecl *VD, QualType DeclType);
DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc, ValueDecl *D, SourceLocation TemplateKWLoc, ValueDecl *D,
bool RefersToEnclosingVariableOrCapture, bool RefersToEnclosingVariableOrCapture,
const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentListInfo *TemplateArgs,
const TemplateArgumentList *ConvertedArgs, QualType T, const TemplateArgumentList *ConvertedArgs, QualType T,
ExprValueKind VK, NonOdrUseReason NOUR); ExprValueKind VK, QualType DeclType, NonOdrUseReason NOUR);
/// Construct an empty declaration reference expression. /// Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {} explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {}
@ -1318,7 +1328,8 @@ public:
Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc, ValueDecl *D, SourceLocation TemplateKWLoc, ValueDecl *D,
bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, 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 TemplateArgumentListInfo *TemplateArgs = nullptr,
const TemplateArgumentList *ConvertedArgs = nullptr, const TemplateArgumentList *ConvertedArgs = nullptr,
NonOdrUseReason NOUR = NOUR_None); NonOdrUseReason NOUR = NOUR_None);
@ -1328,7 +1339,7 @@ public:
SourceLocation TemplateKWLoc, ValueDecl *D, SourceLocation TemplateKWLoc, ValueDecl *D,
bool RefersToEnclosingVariableOrCapture, bool RefersToEnclosingVariableOrCapture,
const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK, const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
NamedDecl *FoundD = nullptr, QualType DeclType = QualType(), NamedDecl *FoundD = nullptr,
const TemplateArgumentListInfo *TemplateArgs = nullptr, const TemplateArgumentListInfo *TemplateArgs = nullptr,
const TemplateArgumentList *ConvertedArgs = nullptr, const TemplateArgumentList *ConvertedArgs = nullptr,
NonOdrUseReason NOUR = NOUR_None); NonOdrUseReason NOUR = NOUR_None);
@ -1337,11 +1348,22 @@ public:
static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier, static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier,
bool HasFoundDecl, bool HasFoundDecl,
bool HasTemplateKWAndArgsInfo, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs); unsigned NumTemplateArgs,
bool HasResugaredDeclType);
ValueDecl *getDecl() { return D; } ValueDecl *getDecl() { return D; }
const ValueDecl *getDecl() const { return D; } const ValueDecl *getDecl() const { return D; }
void setDecl(ValueDecl *NewD); 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 { DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc); return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc);

View File

@ -448,6 +448,8 @@ protected:
unsigned NonOdrUseReason : 2; unsigned NonOdrUseReason : 2;
LLVM_PREFERRED_TYPE(bool) LLVM_PREFERRED_TYPE(bool)
unsigned IsImmediateEscalating : 1; unsigned IsImmediateEscalating : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned HasResugaredDeclType : 1;
/// The location of the declaration name itself. /// The location of the declaration name itself.
SourceLocation Loc; SourceLocation Loc;

View File

@ -6849,22 +6849,23 @@ public:
DeclRefExpr *BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, DeclRefExpr *BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
SourceLocation Loc, SourceLocation Loc,
QualType DeclType = QualType(),
const CXXScopeSpec *SS = nullptr); const CXXScopeSpec *SS = nullptr);
DeclRefExpr * DeclRefExpr *BuildDeclRefExpr(
BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, ValueDecl *D, QualType Ty, ExprValueKind VK,
const DeclarationNameInfo &NameInfo, const DeclarationNameInfo &NameInfo, QualType DeclType = QualType(),
const CXXScopeSpec *SS = nullptr, const CXXScopeSpec *SS = nullptr, NamedDecl *FoundD = nullptr,
NamedDecl *FoundD = nullptr, SourceLocation TemplateKWLoc = SourceLocation(),
SourceLocation TemplateKWLoc = SourceLocation(), const TemplateArgumentListInfo *TemplateArgs = nullptr,
const TemplateArgumentListInfo *TemplateArgs = nullptr, const TemplateArgumentList *ConvertArgs = nullptr);
const TemplateArgumentList *ConvertArgs = nullptr);
/// BuildDeclRefExpr - Build an expression that references a /// BuildDeclRefExpr - Build an expression that references a
/// declaration that does not require a closure capture. /// declaration that does not require a closure capture.
DeclRefExpr * DeclRefExpr *
BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
const DeclarationNameInfo &NameInfo, const DeclarationNameInfo &NameInfo,
NestedNameSpecifierLoc NNS, NamedDecl *FoundD = nullptr, NestedNameSpecifierLoc NNS, QualType DeclType = QualType(),
NamedDecl *FoundD = nullptr,
SourceLocation TemplateKWLoc = SourceLocation(), SourceLocation TemplateKWLoc = SourceLocation(),
const TemplateArgumentListInfo *TemplateArgs = nullptr, const TemplateArgumentListInfo *TemplateArgs = nullptr,
const TemplateArgumentList *ConvertArgs = nullptr); const TemplateArgumentList *ConvertArgs = nullptr);
@ -14011,6 +14012,7 @@ public:
QualType resugar(const Type *Base, QualType T); QualType resugar(const Type *Base, QualType T);
QualType resugar(const Type *Base, NamedDecl *ND, QualType resugar(const Type *Base, NamedDecl *ND,
ArrayRef<TemplateArgument> Args, QualType T); ArrayRef<TemplateArgument> Args, QualType T);
QualType resugar(DeclRefExpr *DRE, ValueDecl *VD);
/// Performs template instantiation for all implicit template /// Performs template instantiation for all implicit template
/// instantiations we have seen until this point. /// instantiations we have seen until this point.

View File

@ -7496,6 +7496,7 @@ ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
auto ToConvertedArgs = importChecked(Err, E->getConvertedArgs()); auto ToConvertedArgs = importChecked(Err, E->getConvertedArgs());
auto ToLocation = importChecked(Err, E->getLocation()); auto ToLocation = importChecked(Err, E->getLocation());
auto ToType = importChecked(Err, E->getType()); auto ToType = importChecked(Err, E->getType());
auto ToDeclType = importChecked(Err, E->getDeclType());
if (Err) if (Err)
return std::move(Err); return std::move(Err);
@ -7520,7 +7521,7 @@ ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
auto *ToE = DeclRefExpr::Create( auto *ToE = DeclRefExpr::Create(
Importer.getToContext(), ToQualifierLoc, ToTemplateKeywordLoc, ToDecl, Importer.getToContext(), ToQualifierLoc, ToTemplateKeywordLoc, ToDecl,
E->refersToEnclosingVariableOrCapture(), ToLocation, ToType, E->refersToEnclosingVariableOrCapture(), ToLocation, ToType,
E->getValueKind(), ToFoundD, ToResInfo, ToConvertedArgs, E->getValueKind(), ToDeclType, ToFoundD, ToResInfo, ToConvertedArgs,
E->isNonOdrUse()); E->isNonOdrUse());
if (E->hadMultipleCandidates()) if (E->hadMultipleCandidates())
ToE->setHadMultipleCandidates(true); ToE->setHadMultipleCandidates(true);

View File

@ -426,6 +426,11 @@ APValue ConstantExpr::getAPValueResult() const {
llvm_unreachable("invalid ResultKind"); 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, DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
bool RefersToEnclosingVariableOrCapture, QualType T, bool RefersToEnclosingVariableOrCapture, QualType T,
ExprValueKind VK, SourceLocation L, ExprValueKind VK, SourceLocation L,
@ -442,6 +447,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
DeclRefExprBits.NonOdrUseReason = NOUR; DeclRefExprBits.NonOdrUseReason = NOUR;
DeclRefExprBits.IsImmediateEscalating = false; DeclRefExprBits.IsImmediateEscalating = false;
DeclRefExprBits.HasResugaredDeclType = false;
DeclRefExprBits.Loc = L; DeclRefExprBits.Loc = L;
setDependence(computeDependence(this, Ctx)); setDependence(computeDependence(this, Ctx));
} }
@ -453,7 +459,8 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentListInfo *TemplateArgs,
const TemplateArgumentList *ConvertedArgs, QualType T, const TemplateArgumentList *ConvertedArgs, QualType T,
ExprValueKind VK, NonOdrUseReason NOUR) ExprValueKind VK, QualType DeclType,
NonOdrUseReason NOUR)
: Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D), : Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D),
ConvertedArgs(ConvertedArgs), DNLoc(NameInfo.getInfo()) { ConvertedArgs(ConvertedArgs), DNLoc(NameInfo.getInfo()) {
assert(!TemplateArgs || ConvertedArgs); assert(!TemplateArgs || ConvertedArgs);
@ -472,6 +479,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
RefersToEnclosingVariableOrCapture; RefersToEnclosingVariableOrCapture;
DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
DeclRefExprBits.NonOdrUseReason = NOUR; DeclRefExprBits.NonOdrUseReason = NOUR;
DeclRefExprBits.HasResugaredDeclType = needsDeclTypeStorage(D, DeclType);
if (TemplateArgs) { if (TemplateArgs) {
auto Deps = TemplateArgumentDependence::None; auto Deps = TemplateArgumentDependence::None;
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
@ -483,33 +491,39 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc); TemplateKWLoc);
} }
if (HasResugaredDeclType()) {
assert(Ctx.hasSameType(DeclType, D->getType()));
*getTrailingObjects<QualType>() =
DeclType.isNull() ? D->getType() : DeclType;
}
DeclRefExprBits.IsImmediateEscalating = false; DeclRefExprBits.IsImmediateEscalating = false;
DeclRefExprBits.HadMultipleCandidates = 0; DeclRefExprBits.HadMultipleCandidates = 0;
setDependence(computeDependence(this, Ctx)); 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, DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc, ValueDecl *D, SourceLocation TemplateKWLoc, ValueDecl *D,
bool RefersToEnclosingVariableOrCapture, bool RefersToEnclosingVariableOrCapture,
SourceLocation NameLoc, QualType T, const DeclarationNameInfo &NameInfo,
ExprValueKind VK, NamedDecl *FoundD, QualType T, ExprValueKind VK,
QualType DeclType, NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentListInfo *TemplateArgs,
const TemplateArgumentList *ConvertedArgs, const TemplateArgumentList *ConvertedArgs,
NonOdrUseReason NOUR) { 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. // Filter out cases where the found Decl is the same as the value refenenced.
if (D == FoundD) if (D == FoundD)
FoundD = nullptr; FoundD = nullptr;
@ -517,38 +531,52 @@ DeclRefExpr *DeclRefExpr::Create(
bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid(); bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
std::size_t Size = std::size_t Size =
totalSizeToAlloc<NestedNameSpecifierLoc, NamedDecl *, totalSizeToAlloc<NestedNameSpecifierLoc, NamedDecl *,
ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>( ASTTemplateKWAndArgsInfo, TemplateArgumentLoc, QualType>(
QualifierLoc ? 1 : 0, FoundD ? 1 : 0, QualifierLoc ? 1 : 0, FoundD ? 1 : 0,
HasTemplateKWAndArgsInfo ? 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)); void *Mem = Context.Allocate(Size, alignof(DeclRefExpr));
return new (Mem) return new (Mem)
DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D, DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D,
RefersToEnclosingVariableOrCapture, NameInfo, FoundD, RefersToEnclosingVariableOrCapture, NameInfo, FoundD,
TemplateArgs, ConvertedArgs, T, VK, NOUR); TemplateArgs, ConvertedArgs, T, VK, DeclType, NOUR);
} }
DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context, DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context,
bool HasQualifier, bool HasQualifier, bool HasFoundDecl,
bool HasFoundDecl,
bool HasTemplateKWAndArgsInfo, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) { unsigned NumTemplateArgs,
bool HasResugaredDeclType) {
assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo); assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
std::size_t Size = std::size_t Size =
totalSizeToAlloc<NestedNameSpecifierLoc, NamedDecl *, totalSizeToAlloc<NestedNameSpecifierLoc, NamedDecl *,
ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>( ASTTemplateKWAndArgsInfo, TemplateArgumentLoc, QualType>(
HasQualifier ? 1 : 0, HasFoundDecl ? 1 : 0, HasTemplateKWAndArgsInfo, HasQualifier ? 1 : 0, HasFoundDecl ? 1 : 0, HasTemplateKWAndArgsInfo,
NumTemplateArgs); NumTemplateArgs, HasResugaredDeclType ? 1 : 0);
void *Mem = Context.Allocate(Size, alignof(DeclRefExpr)); void *Mem = Context.Allocate(Size, alignof(DeclRefExpr));
return new (Mem) DeclRefExpr(EmptyShell()); return new (Mem) DeclRefExpr(EmptyShell());
} }
void DeclRefExpr::setDecl(ValueDecl *NewD) { void DeclRefExpr::setDecl(ValueDecl *NewD) {
assert(D != NewD);
assert(declaresSameEntity(D, NewD));
assert(!HasResugaredDeclType() ||
D->getASTContext().hasSameType(NewD->getType(),
*getTrailingObjects<QualType>()));
D = NewD; D = NewD;
if (getType()->isUndeducedType()) recomputeDependency();
setType(NewD->getType()); }
setDependence(computeDependence(this, NewD->getASTContext()));
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 { SourceLocation DeclRefExpr::getBeginLoc() const {

View File

@ -1867,8 +1867,8 @@ static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CodeGenFunction &CGF,
return DeclRefExpr::Create( return DeclRefExpr::Create(
CGF.getContext(), NestedNameSpecifierLoc(), SourceLocation(), VD, CGF.getContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
/*RefersToEnclosingVariableOrCapture=*/false, ME->getExprLoc(), /*RefersToEnclosingVariableOrCapture=*/false, ME->getExprLoc(),
ME->getType(), ME->getValueKind(), nullptr, nullptr, nullptr, ME->getType(), ME->getValueKind(), QualType(), nullptr, nullptr,
ME->isNonOdrUse()); nullptr, ME->isNonOdrUse());
} }
return nullptr; return nullptr;
} }

View File

@ -4632,7 +4632,8 @@ ExprResult Sema::BuiltinAtomicOverloaded(ExprResult TheCallResult) {
DeclRefExpr *NewDRE = DeclRefExpr::Create( DeclRefExpr *NewDRE = DeclRefExpr::Create(
Context, DRE->getQualifierLoc(), SourceLocation(), NewBuiltinDecl, Context, DRE->getQualifierLoc(), SourceLocation(), NewBuiltinDecl,
/*enclosing*/ false, DRE->getLocation(), Context.BuiltinFnTy, /*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. // Set the callee in the CallExpr.
// FIXME: This loses syntactic information. // FIXME: This loses syntactic information.

View File

@ -4920,11 +4920,9 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
ParmVarDecl *Param = Constructor->getParamDecl(0); ParmVarDecl *Param = Constructor->getParamDecl(0);
QualType ParamType = Param->getType().getNonReferenceType(); QualType ParamType = Param->getType().getNonReferenceType();
Expr *CopyCtorArg = Expr *CopyCtorArg = DeclRefExpr::Create(
DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), SemaRef.Context, NestedNameSpecifierLoc(), SourceLocation(), Param,
SourceLocation(), Param, false, false, Constructor->getLocation(), ParamType, VK_LValue);
Constructor->getLocation(), ParamType,
VK_LValue, nullptr);
SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(CopyCtorArg)); SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(CopyCtorArg));
@ -4994,10 +4992,9 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
if (Field->isZeroLengthBitField()) if (Field->isZeroLengthBitField())
return false; return false;
Expr *MemberExprBase = Expr *MemberExprBase = DeclRefExpr::Create(
DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), SemaRef.Context, NestedNameSpecifierLoc(), SourceLocation(), Param,
SourceLocation(), Param, false, false, Loc, ParamType, VK_LValue);
Loc, ParamType, VK_LValue, nullptr);
SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(MemberExprBase)); SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(MemberExprBase));
@ -14676,8 +14673,8 @@ buildMemcpyForAssignmentOp(Sema &S, SourceLocation Loc, QualType T,
// about it. // about it.
return StmtError(); return StmtError();
ExprResult MemCpyRef = S.BuildDeclRefExpr(MemCpy, S.Context.BuiltinFnTy, ExprResult MemCpyRef =
VK_PRValue, Loc, nullptr); S.BuildDeclRefExpr(MemCpy, S.Context.BuiltinFnTy, VK_PRValue, Loc);
assert(MemCpyRef.isUsable() && "Builtin reference cannot fail"); assert(MemCpyRef.isUsable() && "Builtin reference cannot fail");
Expr *CallArgs[] = { Expr *CallArgs[] = {

View File

@ -2219,25 +2219,24 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {
llvm_unreachable("unexpected literal operator lookup result"); llvm_unreachable("unexpected literal operator lookup result");
} }
DeclRefExpr * DeclRefExpr *Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, QualType DeclType,
SourceLocation Loc, const CXXScopeSpec *SS) {
const CXXScopeSpec *SS) {
DeclarationNameInfo NameInfo(D->getDeclName(), Loc); DeclarationNameInfo NameInfo(D->getDeclName(), Loc);
return BuildDeclRefExpr(D, Ty, VK, NameInfo, SS); return BuildDeclRefExpr(D, Ty, VK, NameInfo, DeclType, SS);
} }
DeclRefExpr * DeclRefExpr *
Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
const DeclarationNameInfo &NameInfo, const DeclarationNameInfo &NameInfo, QualType DeclType,
const CXXScopeSpec *SS, NamedDecl *FoundD, const CXXScopeSpec *SS, NamedDecl *FoundD,
SourceLocation TemplateKWLoc, SourceLocation TemplateKWLoc,
const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentListInfo *TemplateArgs,
const TemplateArgumentList *ConvertedArgs) { const TemplateArgumentList *ConvertedArgs) {
NestedNameSpecifierLoc NNS = NestedNameSpecifierLoc NNS =
SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(); SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc();
return BuildDeclRefExpr(D, Ty, VK, NameInfo, NNS, FoundD, TemplateKWLoc, return BuildDeclRefExpr(D, Ty, VK, NameInfo, NNS, DeclType, FoundD,
TemplateArgs, ConvertedArgs); TemplateKWLoc, TemplateArgs, ConvertedArgs);
} }
// CUDA/HIP: Check whether a captured reference variable is referencing a // CUDA/HIP: Check whether a captured reference variable is referencing a
@ -2300,18 +2299,18 @@ NonOdrUseReason Sema::getNonOdrUseReasonInCurrentContext(ValueDecl *D) {
DeclRefExpr * DeclRefExpr *
Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
const DeclarationNameInfo &NameInfo, const DeclarationNameInfo &NameInfo,
NestedNameSpecifierLoc NNS, NamedDecl *FoundD, NestedNameSpecifierLoc NNS, QualType DeclType,
SourceLocation TemplateKWLoc, NamedDecl *FoundD, SourceLocation TemplateKWLoc,
const TemplateArgumentListInfo *TemplateArgs, const TemplateArgumentListInfo *TemplateArgs,
const TemplateArgumentList *ConvertedArgs) { const TemplateArgumentList *ConvertedArgs) {
bool RefersToCapturedVariable = isa<VarDecl, BindingDecl>(D) && bool RefersToCapturedVariable = isa<VarDecl, BindingDecl>(D) &&
NeedToCaptureVariable(D, NameInfo.getLoc()); NeedToCaptureVariable(D, NameInfo.getLoc());
assert(!TemplateArgs || ConvertedArgs); assert(!TemplateArgs || ConvertedArgs);
DeclRefExpr *E = DeclRefExpr::Create(Context, NNS, TemplateKWLoc, D, DeclRefExpr *E = DeclRefExpr::Create(
RefersToCapturedVariable, NameInfo, Ty, Context, NNS, TemplateKWLoc, D, RefersToCapturedVariable, NameInfo, Ty,
VK, FoundD, TemplateArgs, ConvertedArgs, VK, DeclType, FoundD, TemplateArgs, ConvertedArgs,
getNonOdrUseReasonInCurrentContext(D)); getNonOdrUseReasonInCurrentContext(D));
MarkDeclRefReferenced(E); MarkDeclRefReferenced(E);
// C++ [except.spec]p17: // C++ [except.spec]p17:
@ -2732,6 +2731,7 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
// LookupName handles a name lookup from within anonymous struct. // LookupName handles a name lookup from within anonymous struct.
if (LookupName(R, S)) { if (LookupName(R, S)) {
if (auto *VD = dyn_cast<ValueDecl>(R.getFoundDecl())) { if (auto *VD = dyn_cast<ValueDecl>(R.getFoundDecl())) {
// FIXME: resugar
QualType type = VD->getType().getNonReferenceType(); QualType type = VD->getType().getNonReferenceType();
// This will eventually be translated into MemberExpr upon // This will eventually be translated into MemberExpr upon
// the use of instantiated struct fields. // the use of instantiated struct fields.
@ -3306,19 +3306,19 @@ ExprResult Sema::BuildDeclarationNameExpr(
return BuildAnonymousStructUnionMemberReference(SS, NameInfo.getLoc(), return BuildAnonymousStructUnionMemberReference(SS, NameInfo.getLoc(),
IndirectField); IndirectField);
QualType type = VD->getType(); QualType DeclType = VD->getType();
if (type.isNull()) if (DeclType.isNull())
return ExprError(); return ExprError();
assert(!TemplateArgs || ConvertedArgs); assert(!TemplateArgs || ConvertedArgs);
type = ConvertedArgs DeclType = ConvertedArgs ? resugar(SS.getScopeRep(), VD,
? resugar(SS.getScopeRep(), VD, ConvertedArgs->asArray(), type) ConvertedArgs->asArray(), DeclType)
: resugar(SS.getScopeRep(), type); : resugar(SS.getScopeRep(), DeclType);
ExprValueKind valueKind = VK_PRValue; ExprValueKind valueKind = VK_PRValue;
// In 'T ...V;', the type of the declaration 'V' is 'T...', but the type of // 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, // a reference to 'V' is simply (unexpanded) 'T'. The type, like the value,
// is expanded by some outer '...' in the context of the use. // is expanded by some outer '...' in the context of the use.
type = type.getNonPackExpansionType(); QualType type = DeclType.getNonPackExpansionType();
switch (D->getKind()) { switch (D->getKind()) {
// Ignore all the non-ValueDecl kinds. // Ignore all the non-ValueDecl kinds.
@ -3473,8 +3473,7 @@ ExprResult Sema::BuildDeclarationNameExpr(
// If we're referring to a method with an __unknown_anytype // If we're referring to a method with an __unknown_anytype
// result type, make the entire expression __unknown_anytype. // result type, make the entire expression __unknown_anytype.
// This should only be possible with a type written directly. // This should only be possible with a type written directly.
if (const FunctionProtoType *proto = if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(DeclType))
dyn_cast<FunctionProtoType>(VD->getType()))
if (proto->getReturnType() == Context.UnknownAnyTy) { if (proto->getReturnType() == Context.UnknownAnyTy) {
type = Context.UnknownAnyTy; type = Context.UnknownAnyTy;
valueKind = VK_PRValue; valueKind = VK_PRValue;
@ -3495,9 +3494,9 @@ ExprResult Sema::BuildDeclarationNameExpr(
break; break;
} }
auto *E = BuildDeclRefExpr(VD, type, valueKind, NameInfo, &SS, FoundD, auto *E = BuildDeclRefExpr(
/*FIXME: TemplateKWLoc*/ SourceLocation(), VD, type, valueKind, NameInfo, DeclType, &SS, FoundD,
TemplateArgs, ConvertedArgs); /*FIXME: TemplateKWLoc*/ SourceLocation(), TemplateArgs, ConvertedArgs);
// Clang AST consumers assume a DeclRefExpr refers to a valid decl. We // Clang AST consumers assume a DeclRefExpr refers to a valid decl. We
// wrap a DeclRefExpr referring to an invalid decl with a dependent-type // wrap a DeclRefExpr referring to an invalid decl with a dependent-type
// RecoveryExpr to avoid follow-up semantic analysis (thus prevent bogus // 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 = if ((FDecl =
rewriteBuiltinFunctionDecl(this, Context, FDecl, ArgExprs))) { rewriteBuiltinFunctionDecl(this, Context, FDecl, ArgExprs))) {
NDecl = FDecl; NDecl = FDecl;
Fn = DeclRefExpr::Create( NestedNameSpecifierLoc NNS = FDecl->getQualifierLoc();
Context, FDecl->getQualifierLoc(), SourceLocation(), FDecl, false, QualType T = resugar(NNS.getNestedNameSpecifier(), FDecl->getType());
SourceLocation(), FDecl->getType(), Fn->getValueKind(), FDecl, Fn = DeclRefExpr::Create(Context, NNS, SourceLocation(), FDecl, false,
nullptr, nullptr, DRE->isNonOdrUse()); SourceLocation(), T, Fn->getValueKind(), T,
FDecl, nullptr, nullptr, DRE->isNonOdrUse());
} }
} }
} else if (auto *ME = dyn_cast<MemberExpr>(NakedFn)) } 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(), S.Context, DRE->getQualifierLoc(), DRE->getTemplateKeywordLoc(),
DRE->getDecl(), DRE->refersToEnclosingVariableOrCapture(), DRE->getDecl(), DRE->refersToEnclosingVariableOrCapture(),
DRE->getNameInfo(), DRE->getType(), DRE->getValueKind(), DRE->getNameInfo(), DRE->getType(), DRE->getValueKind(),
DRE->getFoundDecl(), CopiedTemplateArgs(DRE), DRE->getConvertedArgs(), DRE->getDeclType(), DRE->getFoundDecl(), CopiedTemplateArgs(DRE),
NOUR); DRE->getConvertedArgs(), NOUR);
} }
case Expr::FunctionParmPackExprClass: { case Expr::FunctionParmPackExprClass: {
@ -19900,20 +19900,13 @@ static void DoMarkVarDeclReferenced(
// Re-set the member to trigger a recomputation of the dependence bits // Re-set the member to trigger a recomputation of the dependence bits
// for the expression. // for the expression.
CXXScopeSpec SS;
if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
DRE->setDecl(DRE->getDecl()); if (DRE->getType()->isUndeducedType())
SS.Adopt(DRE->getQualifierLoc()); DRE->setType(SemaRef.resugar(DRE, DRE->getDecl()));
assert(DRE->template_arguments().size() == 0 || DRE->recomputeDependency();
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);
} else if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) { } else if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) {
ME->setMemberDecl(ME->getMemberDecl()); ME->setMemberDecl(ME->getMemberDecl());
CXXScopeSpec SS;
SS.Adopt(ME->getQualifierLoc()); SS.Adopt(ME->getQualifierLoc());
assert(ME->template_arguments().size() == 0 || assert(ME->template_arguments().size() == 0 ||
ME->getDeduced() != nullptr); ME->getDeduced() != nullptr);
@ -20960,6 +20953,8 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {
Params.push_back(Param); Params.push_back(Param);
} }
NewFD->setParams(Params); NewFD->setParams(Params);
NewFD->setPreviousDeclaration(FD);
// FIXME: resugar?
DRE->setDecl(NewFD); DRE->setDecl(NewFD);
VD = DRE->getDecl(); VD = DRE->getDecl();
} }
@ -21227,7 +21222,7 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
DRE->copyTemplateArgumentsInto(TemplateArgs); DRE->copyTemplateArgumentsInto(TemplateArgs);
// FIXME: resugar // FIXME: resugar
return BuildDeclRefExpr( return BuildDeclRefExpr(
FD, FD->getType(), VK_LValue, DRE->getNameInfo(), FD, FD->getType(), VK_LValue, DRE->getNameInfo(), QualType(),
DRE->hasQualifier() ? &SS : nullptr, DRE->getFoundDecl(), DRE->hasQualifier() ? &SS : nullptr, DRE->getFoundDecl(),
DRE->getTemplateKeywordLoc(), DRE->getTemplateKeywordLoc(),
DRE->hasExplicitTemplateArgs() ? &TemplateArgs : nullptr, DRE->hasExplicitTemplateArgs() ? &TemplateArgs : nullptr,

View File

@ -5416,7 +5416,7 @@ static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
// Get the LValue expression for the result. // Get the LValue expression for the result.
ImplicitParamDecl *DistParam = CS->getParam(0); ImplicitParamDecl *DistParam = CS->getParam(0);
DeclRefExpr *DistRef = Actions.BuildDeclRefExpr( DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); DistParam, LogicalTy, VK_LValue, SourceLocation());
SmallVector<Stmt *, 4> BodyStmts; SmallVector<Stmt *, 4> BodyStmts;
@ -5571,10 +5571,10 @@ static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
ImplicitParamDecl *TargetParam = CS->getParam(0); ImplicitParamDecl *TargetParam = CS->getParam(0);
DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr( DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); TargetParam, LoopVarTy, VK_LValue, SourceLocation());
ImplicitParamDecl *IndvarParam = CS->getParam(1); ImplicitParamDecl *IndvarParam = CS->getParam(1);
DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr( DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); IndvarParam, LogicalTy, VK_LValue, SourceLocation());
// Capture the Start expression. // Capture the Start expression.
CaptureVars Recap(Actions); CaptureVars Recap(Actions);
@ -5747,9 +5747,8 @@ StmtResult SemaOpenMP::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
buildDistanceFunc(SemaRef, LogicalTy, CondRel, LHS, RHS, Step); buildDistanceFunc(SemaRef, LogicalTy, CondRel, LHS, RHS, Step);
CapturedStmt *LoopVarFunc = buildLoopVarFunc( CapturedStmt *LoopVarFunc = buildLoopVarFunc(
SemaRef, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt)); SemaRef, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
DeclRefExpr *LVRef = DeclRefExpr *LVRef = SemaRef.BuildDeclRefExpr(LUVDecl, LUVDecl->getType(),
SemaRef.BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, {}, VK_LValue, SourceLocation());
nullptr, nullptr, {}, nullptr);
return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc, return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
LoopVarFunc, LVRef); LoopVarFunc, LVRef);
} }

View File

@ -16590,21 +16590,19 @@ Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
: VK_PRValue; : VK_PRValue;
// FIXME: Duplicated from BuildDeclarationNameExpr. // FIXME: Duplicated from BuildDeclarationNameExpr.
QualType Type; QualType DeclType =
{ Deduced ? resugar(NNS.getNestedNameSpecifier(), Fn, Deduced->asArray(),
unsigned BID = Fn->getBuiltinID(); Fn->getType())
if (BID && !Context.BuiltinInfo.isDirectlyAddressable(BID)) { : resugar(NNS.getNestedNameSpecifier(), Fn->getType());
Type = Context.BuiltinFnTy; QualType Type = DeclType;
ValueKind = VK_PRValue; if (unsigned BID = Fn->getBuiltinID();
} else { BID && !Context.BuiltinInfo.isDirectlyAddressable(BID)) {
Type = Deduced ? resugar(NNS.getNestedNameSpecifier(), Fn, Type = Context.BuiltinFnTy;
Deduced->asArray(), Fn->getType()) ValueKind = VK_PRValue;
: resugar(NNS.getNestedNameSpecifier(), Fn->getType());
}
} }
DeclRefExpr *DRE = BuildDeclRefExpr( DeclRefExpr *DRE = BuildDeclRefExpr(
Fn, Type, ValueKind, ULE->getNameInfo(), NNS, Found.getDecl(), Fn, Type, ValueKind, ULE->getNameInfo(), NNS, DeclType, Found.getDecl(),
ULE->getTemplateKeywordLoc(), TemplateArgs, Deduced); ULE->getTemplateKeywordLoc(), TemplateArgs, Deduced);
DRE->setHadMultipleCandidates(ULE->getNumDecls() > 1); DRE->setHadMultipleCandidates(ULE->getNumDecls() > 1);
return DRE; return DRE;
@ -16628,12 +16626,13 @@ Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
// implicit member access, rewrite to a simple decl ref. // implicit member access, rewrite to a simple decl ref.
if (MemExpr->isImplicitAccess()) { if (MemExpr->isImplicitAccess()) {
if (cast<CXXMethodDecl>(Fn)->isStatic()) { if (cast<CXXMethodDecl>(Fn)->isStatic()) {
// FIXME: Include the MemberExpr Qualifier.
QualType Type = Deduced ? resugar(BasePointeeType, Fn, QualType Type = Deduced ? resugar(BasePointeeType, Fn,
Deduced->asArray(), Fn->getType()) Deduced->asArray(), Fn->getType())
: resugar(BasePointeeType, Fn->getType()); : resugar(BasePointeeType, Fn->getType());
DeclRefExpr *DRE = BuildDeclRefExpr( DeclRefExpr *DRE = BuildDeclRefExpr(
Fn, Type, VK_LValue, MemExpr->getNameInfo(), Fn, Type, VK_LValue, MemExpr->getNameInfo(),
MemExpr->getQualifierLoc(), Found.getDecl(), MemExpr->getQualifierLoc(), Type, Found.getDecl(),
MemExpr->getTemplateKeywordLoc(), TemplateArgs, Deduced); MemExpr->getTemplateKeywordLoc(), TemplateArgs, Deduced);
DRE->setHadMultipleCandidates(MemExpr->getNumDecls() > 1); DRE->setHadMultipleCandidates(MemExpr->getNumDecls() > 1);
return DRE; return DRE;

View File

@ -399,7 +399,7 @@ public:
return DeclRefExpr::Create( return DeclRefExpr::Create(
SemaRef.getASTContext(), DRE->getQualifierLoc(), SemaRef.getASTContext(), DRE->getQualifierLoc(),
DRE->getTemplateKeywordLoc(), VD, false, DRE->getNameInfo(), DRE->getTemplateKeywordLoc(), VD, false, DRE->getNameInfo(),
DRE->getType(), DRE->getValueKind()); DRE->getType(), DRE->getValueKind(), DRE->getDeclType());
} }
} }
return DRE; return DRE;

View File

@ -935,6 +935,19 @@ QualType Sema::resugar(const Type *Base, const NestedNameSpecifier *FieldNNS,
bool Changed = false; bool Changed = false;
return Resugarer(*this, Names).transform(T, Changed); 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 /// \brief Determine whether the declaration found is acceptable as the name
/// of a template and, if so, return that template declaration. Otherwise, /// of a template and, if so, return that template declaration. Otherwise,

View File

@ -9010,11 +9010,14 @@ void Sema::completeExprArrayBound(Expr *E) {
// Update the type to the definition's type both here and within the // Update the type to the definition's type both here and within the
// expression. // expression.
if (Def) { if (Def) {
DRE->setDecl(Def); QualType T = SemaRef.resugar(DRE, Def);
QualType T = Def->getType();
DRE->setType(T); DRE->setType(T);
// FIXME: Update the type on all intervening expressions. // FIXME: Update the type on all intervening expressions.
E->setType(T); 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 // 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. // We apply the same rules for Objective-C ivar and property references.
if (const auto *DRE = dyn_cast<DeclRefExpr>(IDExpr)) { if (const auto *DRE = dyn_cast<DeclRefExpr>(IDExpr)) {
const ValueDecl *VD = DRE->getDecl(); const ValueDecl *VD = DRE->getDecl();
QualType T = VD->getType(); QualType T = DRE->getDeclType();
return isa<TemplateParamObjectDecl>(VD) ? T.getUnqualifiedType() : T; return isa<TemplateParamObjectDecl>(VD) ? T.getUnqualifiedType() : T;
} }
if (const auto *ME = dyn_cast<MemberExpr>(IDExpr)) { if (const auto *ME = dyn_cast<MemberExpr>(IDExpr)) {

View File

@ -16197,9 +16197,10 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt); ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
} else { } else {
auto *VD = cast<ValueDecl>(Pack); auto *VD = cast<ValueDecl>(Pack);
QualType DeclType = VD->getType();
ExprResult DRE = getSema().BuildDeclRefExpr( ExprResult DRE = getSema().BuildDeclRefExpr(
VD, VD->getType().getNonLValueExprType(getSema().Context), VD, DeclType.getNonLValueExprType(getSema().Context),
VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue, DeclType->isReferenceType() ? VK_LValue : VK_PRValue,
E->getPackLoc()); E->getPackLoc());
if (DRE.isInvalid()) if (DRE.isInvalid())
return ExprError(); return ExprError();

View File

@ -622,6 +622,7 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
E->DeclRefExprBits.HasQualifier = CurrentUnpackingBits->getNextBit(); E->DeclRefExprBits.HasQualifier = CurrentUnpackingBits->getNextBit();
E->DeclRefExprBits.HasTemplateKWAndArgsInfo = E->DeclRefExprBits.HasTemplateKWAndArgsInfo =
CurrentUnpackingBits->getNextBit(); CurrentUnpackingBits->getNextBit();
E->DeclRefExprBits.HasResugaredDeclType = CurrentUnpackingBits->getNextBit();
E->DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; E->DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
unsigned NumTemplateArgs = 0; unsigned NumTemplateArgs = 0;
@ -640,6 +641,9 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(), *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
E->getTrailingObjects<TemplateArgumentLoc>(), NumTemplateArgs); E->getTrailingObjects<TemplateArgumentLoc>(), NumTemplateArgs);
if (E->HasResugaredDeclType())
*E->getTrailingObjects<QualType>() = Record.readQualType();
E->D = readDeclAs<ValueDecl>(); E->D = readDeclAs<ValueDecl>();
E->ConvertedArgs = Record.readTemplateArgumentList(); E->ConvertedArgs = Record.readTemplateArgumentList();
E->setLocation(readSourceLocation()); E->setLocation(readSourceLocation());
@ -3184,11 +3188,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
bool HasFoundDecl = DeclRefExprBits.getNextBit(); bool HasFoundDecl = DeclRefExprBits.getNextBit();
bool HasQualifier = DeclRefExprBits.getNextBit(); bool HasQualifier = DeclRefExprBits.getNextBit();
bool HasTemplateKWAndArgsInfo = DeclRefExprBits.getNextBit(); bool HasTemplateKWAndArgsInfo = DeclRefExprBits.getNextBit();
bool HasResugaredDeclType = DeclRefExprBits.getNextBit();
unsigned NumTemplateArgs = HasTemplateKWAndArgsInfo unsigned NumTemplateArgs = HasTemplateKWAndArgsInfo
? Record[ASTStmtReader::NumExprFields + 1] ? Record[ASTStmtReader::NumExprFields + 1]
: 0; : 0;
S = DeclRefExpr::CreateEmpty(Context, HasQualifier, HasFoundDecl, S = DeclRefExpr::CreateEmpty(Context, HasQualifier, HasFoundDecl,
HasTemplateKWAndArgsInfo, NumTemplateArgs); HasTemplateKWAndArgsInfo, NumTemplateArgs,
HasResugaredDeclType);
break; break;
} }

View File

@ -696,6 +696,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
CurrentPackingBits.addBit(E->getDecl() != E->getFoundDecl()); CurrentPackingBits.addBit(E->getDecl() != E->getFoundDecl());
CurrentPackingBits.addBit(E->hasQualifier()); CurrentPackingBits.addBit(E->hasQualifier());
CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo()); CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
CurrentPackingBits.addBit(E->HasResugaredDeclType());
if (E->hasTemplateKWAndArgsInfo()) { if (E->hasTemplateKWAndArgsInfo()) {
unsigned NumTemplateArgs = E->getNumTemplateArgs(); unsigned NumTemplateArgs = E->getNumTemplateArgs();
@ -707,7 +708,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) && if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
(E->getDecl() == E->getFoundDecl()) && (E->getDecl() == E->getFoundDecl()) &&
nk == DeclarationName::Identifier && E->getObjectKind() == OK_Ordinary && nk == DeclarationName::Identifier && E->getObjectKind() == OK_Ordinary &&
!E->getConvertedArgs()) { !E->getConvertedArgs() && !E->HasResugaredDeclType()) {
AbbrevToUse = Writer.getDeclRefExprAbbrev(); AbbrevToUse = Writer.getDeclRefExprAbbrev();
} }
@ -721,6 +722,9 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(), AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
E->getTrailingObjects<TemplateArgumentLoc>()); E->getTrailingObjects<TemplateArgumentLoc>());
if (E->HasResugaredDeclType())
Record.writeQualType(E->getDeclType());
Record.AddDeclRef(E->getDecl()); Record.AddDeclRef(E->getDecl());
if (E->ConvertedArgs) if (E->ConvertedArgs)
Record.AddTemplateArgumentList(E->ConvertedArgs); Record.AddTemplateArgumentList(E->ConvertedArgs);

View File

@ -40,9 +40,8 @@ Z x1 = A<Float>::B<Bar>::a;
namespace t4 { namespace t4 {
template <class A1> A1 (*a) (); template <class A1> A1 (*a) ();
// FIXME: resugar this
Z x1 = decltype(a<Int>){}(); Z x1 = decltype(a<Int>){}();
// expected-error@-1 {{with an rvalue of type 'int'}} // expected-error@-1 {{with an rvalue of type 'Int' (aka 'int')}}
} // namespace t4 } // namespace t4
namespace t5 { namespace t5 {
@ -128,9 +127,8 @@ namespace t12 {
template<class A1> A1 *a; template<class A1> A1 *a;
template<int A3, class A4> decltype(a<A4[A3 - 1]>) a<A4[A3]>; template<int A3, class A4> decltype(a<A4[A3 - 1]>) a<A4[A3]>;
// FIXME: resugar this
Z x1 = *a<Int[1]>; Z x1 = *a<Int[1]>;
// expected-error@-1 {{with an lvalue of type 'int[0]'}} // expected-error@-1 {{with an lvalue of type 'Int[0]' (aka 'int[0]'}}
} // namespace t12 } // namespace t12
namespace t13 { namespace t13 {