Centralize and complete the computation of value- and type-dependence for DeclRefExprs

llvm-svn: 89649
This commit is contained in:
Douglas Gregor 2009-11-23 11:41:28 +00:00
parent 9d786d701d
commit ed6c744091
11 changed files with 89 additions and 119 deletions

View File

@ -429,26 +429,23 @@ class DeclRefExpr : public Expr {
DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
NamedDecl *D, SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, bool TD, bool VD);
QualType T);
protected:
// FIXME: Eventually, this constructor will go away and all subclasses
// will have to provide the type- and value-dependent flags.
DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
Expr(SC, t), DecoratedD(d, 0), Loc(l) {}
/// \brief Computes the type- and value-dependence flags for this
/// declaration reference expression.
void computeDependence();
DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l, bool TD,
bool VD) :
Expr(SC, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) {
computeDependence();
}
public:
// FIXME: Eventually, this constructor will go away and all clients
// will have to provide the type- and value-dependent flags.
DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) :
Expr(DeclRefExprClass, t), DecoratedD(d, 0), Loc(l) {}
DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l, bool TD, bool VD) :
Expr(DeclRefExprClass, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) {
computeDependence();
}
/// \brief Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty)
@ -459,15 +456,8 @@ public:
SourceRange QualifierRange,
NamedDecl *D,
SourceLocation NameLoc,
QualType T, bool TD, bool VD);
static DeclRefExpr *Create(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NamedDecl *D,
SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, bool TD, bool VD);
QualType T,
const TemplateArgumentListInfo *TemplateArgs = 0);
NamedDecl *getDecl() { return DecoratedD.getPointer(); }
const NamedDecl *getDecl() const { return DecoratedD.getPointer(); }

View File

@ -681,10 +681,7 @@ public:
CXXConditionDeclExpr(SourceLocation startLoc,
SourceLocation eqLoc, VarDecl *var)
: DeclRefExpr(CXXConditionDeclExprClass, var,
var->getType().getNonReferenceType(), startLoc,
var->getType()->isDependentType(),
/*FIXME:integral constant?*/
var->getType()->isDependentType()) {}
var->getType().getNonReferenceType(), startLoc) {}
SourceLocation getStartLoc() const { return getLocation(); }

View File

@ -214,9 +214,7 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
} else if (NonTypeTemplateParmDecl *NTTP =
dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
NTTP->getLocation(),
NTTP->getType()->isDependentType(),
/*Value-dependent=*/true);
NTTP->getLocation());
TemplateArgs.push_back(TemplateArgument(E));
} else {
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);

View File

@ -56,12 +56,64 @@ std::size_t ExplicitTemplateArgumentList::sizeFor(
sizeof(TemplateArgumentLoc) * Info.size();
}
void DeclRefExpr::computeDependence() {
TypeDependent = false;
ValueDependent = false;
NamedDecl *D = getDecl();
// (TD) C++ [temp.dep.expr]p3:
// An id-expression is type-dependent if it contains:
//
// and
//
// (VD) C++ [temp.dep.constexpr]p2:
// An identifier is value-dependent if it is:
// (TD) - an identifier that was declared with dependent type
// (VD) - a name declared with a dependent type,
if (getType()->isDependentType()) {
TypeDependent = true;
ValueDependent = true;
}
// (TD) - a conversion-function-id that specifies a dependent type
else if (D->getDeclName().getNameKind()
== DeclarationName::CXXConversionFunctionName &&
D->getDeclName().getCXXNameType()->isDependentType()) {
TypeDependent = true;
ValueDependent = true;
}
// (TD) - a template-id that is dependent,
else if (hasExplicitTemplateArgumentList() &&
TemplateSpecializationType::anyDependentTemplateArguments(
getTemplateArgs(),
getNumTemplateArgs())) {
TypeDependent = true;
ValueDependent = true;
}
// (VD) - the name of a non-type template parameter,
else if (isa<NonTypeTemplateParmDecl>(D))
ValueDependent = true;
// (VD) - a constant with integral or enumeration type and is
// initialized with an expression that is value-dependent.
else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
if (Var->getType()->isIntegralType() &&
Var->getType().getCVRQualifiers() == Qualifiers::Const &&
Var->getInit() &&
Var->getInit()->isValueDependent())
ValueDependent = true;
}
// (TD) - a nested-name-specifier or a qualified-id that names a
// member of an unknown specialization.
// (handled by DependentScopeDeclRefExpr)
}
DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NamedDecl *D, SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, bool TD, bool VD)
: Expr(DeclRefExprClass, T, TD, VD),
QualType T)
: Expr(DeclRefExprClass, T, false, false),
DecoratedD(D,
(Qualifier? HasQualifierFlag : 0) |
(TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
@ -75,6 +127,8 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
if (TemplateArgs)
getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
computeDependence();
}
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
@ -82,18 +136,8 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
SourceRange QualifierRange,
NamedDecl *D,
SourceLocation NameLoc,
QualType T, bool TD, bool VD) {
return Create(Context, Qualifier, QualifierRange, D, NameLoc,
/*TemplateArgs*/ 0, T, TD, VD);
}
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NamedDecl *D,
SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, bool TD, bool VD) {
QualType T,
const TemplateArgumentListInfo *TemplateArgs) {
std::size_t Size = sizeof(DeclRefExpr);
if (Qualifier != 0)
Size += sizeof(NameQualifier);
@ -103,7 +147,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
TemplateArgs, T, TD, VD);
TemplateArgs, T);
}
SourceRange DeclRefExpr::getSourceRange() const {

View File

@ -297,8 +297,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
continue;
} else
E = new (getContext()) DeclRefExpr (cast<NamedDecl>(VD),
VD->getType(), SourceLocation(),
false, false);
VD->getType(),
SourceLocation());
}
if (BDRE->isByRef()) {
NoteForHelper[helpersize].flag = BLOCK_FIELD_IS_BYREF |
@ -836,7 +836,7 @@ uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) {
0, QualType(PadTy), 0, VarDecl::None);
Expr *E;
E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(),
SourceLocation(), false, false);
SourceLocation());
BlockDeclRefDecls.push_back(E);
}
BlockDeclRefDecls.push_back(BDRE);

View File

@ -2627,7 +2627,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
IdentifierInfo *ID = &Context->Idents.get(Name);
VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
ID, QualType()/*UNUSED*/, 0, VarDecl::Extern);
ID, getProtocolType(), 0, VarDecl::Extern);
DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation());
Expr *DerefExpr = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
Context->getPointerType(DRE->getType()),

View File

@ -1391,8 +1391,7 @@ public:
bool IsAddressOfOperand);
OwningExprResult BuildDeclRefExpr(NamedDecl *D, QualType Ty,
SourceLocation Loc, bool TypeDependent,
bool ValueDependent,
SourceLocation Loc,
const CXXScopeSpec *SS = 0);
VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
llvm::SmallVectorImpl<FieldDecl *> &Path);

View File

@ -415,7 +415,6 @@ static bool ShouldSnapshotBlockValueReference(BlockSemaInfo *CurBlock,
/// BuildDeclRefExpr - Build a DeclRefExpr.
Sema::OwningExprResult
Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
bool TypeDependent, bool ValueDependent,
const CXXScopeSpec *SS) {
assert(!isa<OverloadedFunctionDecl>(D));
@ -445,8 +444,7 @@ Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
return Owned(DeclRefExpr::Create(Context,
SS? (NestedNameSpecifier *)SS->getScopeRep() : 0,
SS? SS->getRange() : SourceRange(),
D, Loc,
Ty, TypeDependent, ValueDependent));
D, Loc, Ty));
}
/// getObjectForAnonymousRecordDecl - Retrieve the (unnamed) field or
@ -842,7 +840,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
QualType NoProtoType = T;
if (const FunctionProtoType *Proto = T->getAs<FunctionProtoType>())
NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
return BuildDeclRefExpr(Func, NoProtoType, Loc, false, false, SS);
return BuildDeclRefExpr(Func, NoProtoType, Loc, SS);
}
}
@ -1139,56 +1137,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
// If this reference is not in a block or if the referenced variable is
// within the block, create a normal DeclRefExpr.
bool TypeDependent = false;
bool ValueDependent = false;
if (getLangOptions().CPlusPlus) {
// C++ [temp.dep.expr]p3:
// An id-expression is type-dependent if it contains:
// - an identifier that was declared with a dependent type,
if (VD->getType()->isDependentType())
TypeDependent = true;
// - FIXME: a template-id that is dependent,
// - a conversion-function-id that specifies a dependent type,
else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
Name.getCXXNameType()->isDependentType())
TypeDependent = true;
// - a nested-name-specifier that contains a class-name that
// names a dependent type.
else {
for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) {
// FIXME: could stop early at namespace scope.
if (DC->isRecord()) {
CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
if (Context.getTypeDeclType(Record)->isDependentType()) {
TypeDependent = true;
break;
}
}
}
}
// C++ [temp.dep.constexpr]p2:
//
// An identifier is value-dependent if it is:
// - a name declared with a dependent type,
if (TypeDependent)
ValueDependent = true;
// - the name of a non-type template parameter,
else if (isa<NonTypeTemplateParmDecl>(VD))
ValueDependent = true;
// - a constant with integral or enumeration type and is
// initialized with an expression that is value-dependent
else if (const VarDecl *Dcl = dyn_cast<VarDecl>(VD)) {
if (Context.getCanonicalType(Dcl->getType()).getCVRQualifiers()
== Qualifiers::Const &&
Dcl->getInit()) {
ValueDependent = Dcl->getInit()->isValueDependent();
}
}
}
return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc,
TypeDependent, ValueDependent, SS);
return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, SS);
}
Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,

View File

@ -5647,11 +5647,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
DRE->getQualifierRange(),
Fn,
DRE->getLocation(),
(DRE->hasExplicitTemplateArgumentList()
? &TemplateArgs : 0),
Fn->getType(),
DRE->isTypeDependent(),
DRE->isValueDependent());
(DRE->hasExplicitTemplateArgumentList()
? &TemplateArgs : 0));
}
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
@ -5660,9 +5658,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
ULE->getQualifierRange(),
Fn,
ULE->getNameLoc(),
Fn->getType(),
Fn->getType()->isDependentType(),
false);
Fn->getType());
}
@ -5699,9 +5695,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
return DeclRefExpr::Create(Context,
TID->getQualifier(), TID->getQualifierRange(),
Fn, TID->getTemplateNameLoc(),
&TemplateArgs,
Fn->getType(),
/*FIXME?*/false, /*FIXME?*/false);
Fn->getType(),
&TemplateArgs);
}
assert(false && "Invalid reference to overloaded function");

View File

@ -790,7 +790,6 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E,
= SemaRef.BuildDeclRefExpr(VD,
VD->getType().getNonReferenceType(),
E->getLocation(),
/*FIXME:*/false, /*FIXME:*/false,
&SS);
if (RefExpr.isInvalid())
return SemaRef.ExprError();
@ -802,8 +801,7 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E,
}
return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
E->getLocation(),
/*FIXME:*/false, /*FIXME:*/false);
E->getLocation());
}
assert(Arg.getKind() == TemplateArgument::Integral);

View File

@ -1643,7 +1643,7 @@ public:
FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Expr *Callee
= new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
BuiltinLoc, false, false);
BuiltinLoc);
SemaRef.UsualUnaryConversions(Callee);
// Build the CallExpr