aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-05-15 23:10:19 +0000
committerAnders Carlsson <andersca@mac.com>2009-05-15 23:10:19 +0000
commitffce2df6ae280d354d51371282a579df1eb86876 (patch)
treee3a499d53e8bb1e8a9615d3a394758def2792b64
parent74d4b127d9f924ad354f47012e0d0e42ab1ee32b (diff)
Basic support for member exprs where the base expr type is dependent.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71907 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Expr.h3
-rw-r--r--lib/AST/Expr.cpp5
-rw-r--r--lib/Sema/SemaExpr.cpp16
-rw-r--r--test/SemaTemplate/instantiate-function-1.cpp15
4 files changed, 37 insertions, 2 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 441aae2c73..eceb93e64a 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -1040,7 +1040,8 @@ class MemberExpr : public Expr {
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.
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 0d38dd2cd1..9a860033df 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -417,6 +417,11 @@ Stmt *BlockExpr::getBody() {
/// 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();
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 0d72a7534e..41c868e005 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2024,7 +2024,10 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
// 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,
@@ -2033,6 +2036,17 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation 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
diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp
index dc48598050..1dfe9e2da6 100644
--- a/test/SemaTemplate/instantiate-function-1.cpp
+++ b/test/SemaTemplate/instantiate-function-1.cpp
@@ -125,3 +125,18 @@ template<typename T> struct For0 {
};
template struct For0<int*>;
+
+template<typename T> struct Member0 {
+ void f(T t) {
+ t;
+ t.f;
+ t->f;
+
+ T* tp;
+ tp.f; // expected-error{{member reference base type 'T *' is not a structure or union}}
+ tp->f;
+
+ this->f;
+ this.f; // expected-error{{member reference base type 'struct Member0 *const' is not a structure or union}}
+ }
+};