diff options
author | Anders Carlsson <andersca@mac.com> | 2009-05-15 23:10:19 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-05-15 23:10:19 +0000 |
commit | ffce2df6ae280d354d51371282a579df1eb86876 (patch) | |
tree | e3a499d53e8bb1e8a9615d3a394758def2792b64 | |
parent | 74d4b127d9f924ad354f47012e0d0e42ab1ee32b (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.h | 3 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 16 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-function-1.cpp | 15 |
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}} + } +}; |