public:
MemberExpr(Expr *base, bool isarrow, NamedDecl *memberdecl, SourceLocation l,
QualType ty)
- : Expr(MemberExprClass, ty),
+ : Expr(MemberExprClass, ty,
+ base->isTypeDependent(), base->isValueDependent()),
Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow) {}
/// \brief Build an empty member reference expression.
/// warning.
bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
SourceRange &R2) const {
+ // Don't warn if the expr is type dependent. The type could end up
+ // instantiating to void.
+ if (isTypeDependent())
+ return false;
+
switch (getStmtClass()) {
default:
Loc = getExprLoc();
// Get the type being accessed in BaseType. If this is an arrow, the BaseExpr
// must have pointer type, and the accessed type is the pointee.
if (OpKind == tok::arrow) {
- if (const PointerType *PT = BaseType->getAsPointerType())
+ if (BaseType->isDependentType())
+ return Owned(new (Context) MemberExpr(BaseExpr, true, 0,
+ MemberLoc, Context.DependentTy));
+ else if (const PointerType *PT = BaseType->getAsPointerType())
BaseType = PT->getPointeeType();
else if (getLangOptions().CPlusPlus && BaseType->isRecordType())
return Owned(BuildOverloadedArrowExpr(S, BaseExpr, OpLoc,
return ExprError(Diag(MemberLoc,
diag::err_typecheck_member_reference_arrow)
<< BaseType << BaseExpr->getSourceRange());
+ } else {
+ // We use isTemplateTypeParmType directly here, instead of simply checking
+ // whether BaseType is dependent, because we want to report an error for
+ //
+ // T *t;
+ // t.foo;
+ //
+ //
+ if (BaseType->isTemplateTypeParmType())
+ return Owned(new (Context) MemberExpr(BaseExpr, false, 0,
+ MemberLoc, Context.DependentTy));
}
// Handle field access to simple records. This also handles access to fields