Skip to content

Commit ed6c744

Browse files
committed
Centralize and complete the computation of value- and type-dependence for DeclRefExprs
llvm-svn: 89649
1 parent 9d786d7 commit ed6c744

File tree

11 files changed

+88
-118
lines changed

11 files changed

+88
-118
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -429,26 +429,23 @@ class DeclRefExpr : public Expr {
429429
DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
430430
NamedDecl *D, SourceLocation NameLoc,
431431
const TemplateArgumentListInfo *TemplateArgs,
432-
QualType T, bool TD, bool VD);
432+
QualType T);
433433

434434
protected:
435-
// FIXME: Eventually, this constructor will go away and all subclasses
436-
// will have to provide the type- and value-dependent flags.
437-
DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
438-
Expr(SC, t), DecoratedD(d, 0), Loc(l) {}
435+
/// \brief Computes the type- and value-dependence flags for this
436+
/// declaration reference expression.
437+
void computeDependence();
439438

440-
DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l, bool TD,
441-
bool VD) :
442-
Expr(SC, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
439+
DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
440+
Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) {
441+
computeDependence();
442+
}
443443

444444
public:
445-
// FIXME: Eventually, this constructor will go away and all clients
446-
// will have to provide the type- and value-dependent flags.
447445
DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) :
448-
Expr(DeclRefExprClass, t), DecoratedD(d, 0), Loc(l) {}
449-
450-
DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l, bool TD, bool VD) :
451-
Expr(DeclRefExprClass, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
446+
Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) {
447+
computeDependence();
448+
}
452449

453450
/// \brief Construct an empty declaration reference expression.
454451
explicit DeclRefExpr(EmptyShell Empty)
@@ -459,15 +456,8 @@ class DeclRefExpr : public Expr {
459456
SourceRange QualifierRange,
460457
NamedDecl *D,
461458
SourceLocation NameLoc,
462-
QualType T, bool TD, bool VD);
463-
464-
static DeclRefExpr *Create(ASTContext &Context,
465-
NestedNameSpecifier *Qualifier,
466-
SourceRange QualifierRange,
467-
NamedDecl *D,
468-
SourceLocation NameLoc,
469-
const TemplateArgumentListInfo *TemplateArgs,
470-
QualType T, bool TD, bool VD);
459+
QualType T,
460+
const TemplateArgumentListInfo *TemplateArgs = 0);
471461

472462
NamedDecl *getDecl() { return DecoratedD.getPointer(); }
473463
const NamedDecl *getDecl() const { return DecoratedD.getPointer(); }

clang/include/clang/AST/ExprCXX.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -681,10 +681,7 @@ class CXXConditionDeclExpr : public DeclRefExpr {
681681
CXXConditionDeclExpr(SourceLocation startLoc,
682682
SourceLocation eqLoc, VarDecl *var)
683683
: DeclRefExpr(CXXConditionDeclExprClass, var,
684-
var->getType().getNonReferenceType(), startLoc,
685-
var->getType()->isDependentType(),
686-
/*FIXME:integral constant?*/
687-
var->getType()->isDependentType()) {}
684+
var->getType().getNonReferenceType(), startLoc) {}
688685

689686
SourceLocation getStartLoc() const { return getLocation(); }
690687

clang/lib/AST/DeclTemplate.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,7 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
214214
} else if (NonTypeTemplateParmDecl *NTTP =
215215
dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
216216
Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
217-
NTTP->getLocation(),
218-
NTTP->getType()->isDependentType(),
219-
/*Value-dependent=*/true);
217+
NTTP->getLocation());
220218
TemplateArgs.push_back(TemplateArgument(E));
221219
} else {
222220
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);

clang/lib/AST/Expr.cpp

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,64 @@ std::size_t ExplicitTemplateArgumentList::sizeFor(
5656
sizeof(TemplateArgumentLoc) * Info.size();
5757
}
5858

59+
void DeclRefExpr::computeDependence() {
60+
TypeDependent = false;
61+
ValueDependent = false;
62+
63+
NamedDecl *D = getDecl();
64+
65+
// (TD) C++ [temp.dep.expr]p3:
66+
// An id-expression is type-dependent if it contains:
67+
//
68+
// and
69+
//
70+
// (VD) C++ [temp.dep.constexpr]p2:
71+
// An identifier is value-dependent if it is:
72+
73+
// (TD) - an identifier that was declared with dependent type
74+
// (VD) - a name declared with a dependent type,
75+
if (getType()->isDependentType()) {
76+
TypeDependent = true;
77+
ValueDependent = true;
78+
}
79+
// (TD) - a conversion-function-id that specifies a dependent type
80+
else if (D->getDeclName().getNameKind()
81+
== DeclarationName::CXXConversionFunctionName &&
82+
D->getDeclName().getCXXNameType()->isDependentType()) {
83+
TypeDependent = true;
84+
ValueDependent = true;
85+
}
86+
// (TD) - a template-id that is dependent,
87+
else if (hasExplicitTemplateArgumentList() &&
88+
TemplateSpecializationType::anyDependentTemplateArguments(
89+
getTemplateArgs(),
90+
getNumTemplateArgs())) {
91+
TypeDependent = true;
92+
ValueDependent = true;
93+
}
94+
// (VD) - the name of a non-type template parameter,
95+
else if (isa<NonTypeTemplateParmDecl>(D))
96+
ValueDependent = true;
97+
// (VD) - a constant with integral or enumeration type and is
98+
// initialized with an expression that is value-dependent.
99+
else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
100+
if (Var->getType()->isIntegralType() &&
101+
Var->getType().getCVRQualifiers() == Qualifiers::Const &&
102+
Var->getInit() &&
103+
Var->getInit()->isValueDependent())
104+
ValueDependent = true;
105+
}
106+
// (TD) - a nested-name-specifier or a qualified-id that names a
107+
// member of an unknown specialization.
108+
// (handled by DependentScopeDeclRefExpr)
109+
}
110+
59111
DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
60112
SourceRange QualifierRange,
61113
NamedDecl *D, SourceLocation NameLoc,
62114
const TemplateArgumentListInfo *TemplateArgs,
63-
QualType T, bool TD, bool VD)
64-
: Expr(DeclRefExprClass, T, TD, VD),
115+
QualType T)
116+
: Expr(DeclRefExprClass, T, false, false),
65117
DecoratedD(D,
66118
(Qualifier? HasQualifierFlag : 0) |
67119
(TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
@@ -75,25 +127,17 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
75127

76128
if (TemplateArgs)
77129
getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
78-
}
79130

80-
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
81-
NestedNameSpecifier *Qualifier,
82-
SourceRange QualifierRange,
83-
NamedDecl *D,
84-
SourceLocation NameLoc,
85-
QualType T, bool TD, bool VD) {
86-
return Create(Context, Qualifier, QualifierRange, D, NameLoc,
87-
/*TemplateArgs*/ 0, T, TD, VD);
131+
computeDependence();
88132
}
89133

90134
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
91135
NestedNameSpecifier *Qualifier,
92136
SourceRange QualifierRange,
93137
NamedDecl *D,
94138
SourceLocation NameLoc,
95-
const TemplateArgumentListInfo *TemplateArgs,
96-
QualType T, bool TD, bool VD) {
139+
QualType T,
140+
const TemplateArgumentListInfo *TemplateArgs) {
97141
std::size_t Size = sizeof(DeclRefExpr);
98142
if (Qualifier != 0)
99143
Size += sizeof(NameQualifier);
@@ -103,7 +147,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
103147

104148
void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
105149
return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
106-
TemplateArgs, T, TD, VD);
150+
TemplateArgs, T);
107151
}
108152

109153
SourceRange DeclRefExpr::getSourceRange() const {

clang/lib/CodeGen/CGBlocks.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
297297
continue;
298298
} else
299299
E = new (getContext()) DeclRefExpr (cast<NamedDecl>(VD),
300-
VD->getType(), SourceLocation(),
301-
false, false);
300+
VD->getType(),
301+
SourceLocation());
302302
}
303303
if (BDRE->isByRef()) {
304304
NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
@@ -836,7 +836,7 @@ uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) {
836836
0, QualType(PadTy), 0, VarDecl::None);
837837
Expr *E;
838838
E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
839-
SourceLocation(), false, false);
839+
SourceLocation());
840840
BlockDeclRefDecls.push_back(E);
841841
}
842842
BlockDeclRefDecls.push_back(BDRE);

clang/lib/Frontend/RewriteObjC.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2627,7 +2627,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
26272627
std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
26282628
IdentifierInfo *ID = &Context->Idents.get(Name);
26292629
VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
2630-
ID, QualType()/*UNUSED*/, 0, VarDecl::Extern);
2630+
ID, getProtocolType(), 0, VarDecl::Extern);
26312631
DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation());
26322632
Expr *DerefExpr = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
26332633
Context->getPointerType(DRE->getType()),

clang/lib/Sema/Sema.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,8 +1391,7 @@ class Sema : public Action {
13911391
bool IsAddressOfOperand);
13921392

13931393
OwningExprResult BuildDeclRefExpr(NamedDecl *D, QualType Ty,
1394-
SourceLocation Loc, bool TypeDependent,
1395-
bool ValueDependent,
1394+
SourceLocation Loc,
13961395
const CXXScopeSpec *SS = 0);
13971396
VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
13981397
llvm::SmallVectorImpl<FieldDecl *> &Path);

clang/lib/Sema/SemaExpr.cpp

Lines changed: 3 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,6 @@ static bool ShouldSnapshotBlockValueReference(BlockSemaInfo *CurBlock,
415415
/// BuildDeclRefExpr - Build a DeclRefExpr.
416416
Sema::OwningExprResult
417417
Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
418-
bool TypeDependent, bool ValueDependent,
419418
const CXXScopeSpec *SS) {
420419
assert(!isa<OverloadedFunctionDecl>(D));
421420

@@ -445,8 +444,7 @@ Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
445444
return Owned(DeclRefExpr::Create(Context,
446445
SS? (NestedNameSpecifier *)SS->getScopeRep() : 0,
447446
SS? SS->getRange() : SourceRange(),
448-
D, Loc,
449-
Ty, TypeDependent, ValueDependent));
447+
D, Loc, Ty));
450448
}
451449

452450
/// getObjectForAnonymousRecordDecl - Retrieve the (unnamed) field or
@@ -842,7 +840,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
842840
QualType NoProtoType = T;
843841
if (const FunctionProtoType *Proto = T->getAs<FunctionProtoType>())
844842
NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
845-
return BuildDeclRefExpr(Func, NoProtoType, Loc, false, false, SS);
843+
return BuildDeclRefExpr(Func, NoProtoType, Loc, SS);
846844
}
847845
}
848846

@@ -1139,56 +1137,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
11391137
// If this reference is not in a block or if the referenced variable is
11401138
// within the block, create a normal DeclRefExpr.
11411139

1142-
bool TypeDependent = false;
1143-
bool ValueDependent = false;
1144-
if (getLangOptions().CPlusPlus) {
1145-
// C++ [temp.dep.expr]p3:
1146-
// An id-expression is type-dependent if it contains:
1147-
// - an identifier that was declared with a dependent type,
1148-
if (VD->getType()->isDependentType())
1149-
TypeDependent = true;
1150-
// - FIXME: a template-id that is dependent,
1151-
// - a conversion-function-id that specifies a dependent type,
1152-
else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
1153-
Name.getCXXNameType()->isDependentType())
1154-
TypeDependent = true;
1155-
// - a nested-name-specifier that contains a class-name that
1156-
// names a dependent type.
1157-
else {
1158-
for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) {
1159-
// FIXME: could stop early at namespace scope.
1160-
if (DC->isRecord()) {
1161-
CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
1162-
if (Context.getTypeDeclType(Record)->isDependentType()) {
1163-
TypeDependent = true;
1164-
break;
1165-
}
1166-
}
1167-
}
1168-
}
1169-
1170-
// C++ [temp.dep.constexpr]p2:
1171-
//
1172-
// An identifier is value-dependent if it is:
1173-
// - a name declared with a dependent type,
1174-
if (TypeDependent)
1175-
ValueDependent = true;
1176-
// - the name of a non-type template parameter,
1177-
else if (isa<NonTypeTemplateParmDecl>(VD))
1178-
ValueDependent = true;
1179-
// - a constant with integral or enumeration type and is
1180-
// initialized with an expression that is value-dependent
1181-
else if (const VarDecl *Dcl = dyn_cast<VarDecl>(VD)) {
1182-
if (Context.getCanonicalType(Dcl->getType()).getCVRQualifiers()
1183-
== Qualifiers::Const &&
1184-
Dcl->getInit()) {
1185-
ValueDependent = Dcl->getInit()->isValueDependent();
1186-
}
1187-
}
1188-
}
1189-
1190-
return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc,
1191-
TypeDependent, ValueDependent, SS);
1140+
return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, SS);
11921141
}
11931142

11941143
Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,

clang/lib/Sema/SemaOverload.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5647,11 +5647,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
56475647
DRE->getQualifierRange(),
56485648
Fn,
56495649
DRE->getLocation(),
5650-
(DRE->hasExplicitTemplateArgumentList()
5651-
? &TemplateArgs : 0),
56525650
Fn->getType(),
5653-
DRE->isTypeDependent(),
5654-
DRE->isValueDependent());
5651+
(DRE->hasExplicitTemplateArgumentList()
5652+
? &TemplateArgs : 0));
56555653
}
56565654

56575655
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
@@ -5660,9 +5658,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
56605658
ULE->getQualifierRange(),
56615659
Fn,
56625660
ULE->getNameLoc(),
5663-
Fn->getType(),
5664-
Fn->getType()->isDependentType(),
5665-
false);
5661+
Fn->getType());
56665662
}
56675663

56685664

@@ -5699,9 +5695,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
56995695
return DeclRefExpr::Create(Context,
57005696
TID->getQualifier(), TID->getQualifierRange(),
57015697
Fn, TID->getTemplateNameLoc(),
5702-
&TemplateArgs,
5703-
Fn->getType(),
5704-
/*FIXME?*/false, /*FIXME?*/false);
5698+
Fn->getType(),
5699+
&TemplateArgs);
57055700
}
57065701

57075702
assert(false && "Invalid reference to overloaded function");

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,6 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E,
790790
= SemaRef.BuildDeclRefExpr(VD,
791791
VD->getType().getNonReferenceType(),
792792
E->getLocation(),
793-
/*FIXME:*/false, /*FIXME:*/false,
794793
&SS);
795794
if (RefExpr.isInvalid())
796795
return SemaRef.ExprError();
@@ -802,8 +801,7 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E,
802801
}
803802

804803
return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
805-
E->getLocation(),
806-
/*FIXME:*/false, /*FIXME:*/false);
804+
E->getLocation());
807805
}
808806

809807
assert(Arg.getKind() == TemplateArgument::Integral);

clang/lib/Sema/TreeTransform.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1643,7 +1643,7 @@ class TreeTransform {
16431643
FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
16441644
Expr *Callee
16451645
= new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1646-
BuiltinLoc, false, false);
1646+
BuiltinLoc);
16471647
SemaRef.UsualUnaryConversions(Callee);
16481648

16491649
// Build the CallExpr

0 commit comments

Comments
 (0)