forked from OSchip/llvm-project
Centralize and complete the computation of value- and type-dependence for DeclRefExprs
llvm-svn: 89649
This commit is contained in:
parent
9d786d701d
commit
ed6c744091
|
@ -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(); }
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue