mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 06:46:33 +00:00
[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:
parent
df203b5f17
commit
0a363317b9
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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);
|
||||
|
@ -448,6 +448,8 @@ protected:
|
||||
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;
|
||||
|
@ -6849,22 +6849,23 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
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.
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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[] = {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -399,7 +399,7 @@ public:
|
||||
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;
|
||||
|
@ -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,
|
||||
|
@ -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)) {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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@-1 {{with an rvalue of type 'int'}}
|
||||
// expected-error@-1 {{with an rvalue of type 'Int' (aka 'int')}}
|
||||
} // namespace t4
|
||||
|
||||
namespace t5 {
|
||||
@ -128,9 +127,8 @@ namespace t12 {
|
||||
template<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@-1 {{with an lvalue of type 'int[0]'}}
|
||||
// expected-error@-1 {{with an lvalue of type 'Int[0]' (aka 'int[0]'}}
|
||||
} // namespace t12
|
||||
|
||||
namespace t13 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user