Representation of and template instantiation for member
expressions. This change introduces another AST node,
CXXUnresolvedMemberExpr, that captures member references (x->m, x.m)
when the base of the expression (the "x") is type-dependent, and we
therefore cannot resolve the member reference yet.

Note that our parsing of member references for C++ is still quite
poor, e.g., we don't handle x->Base::m or x->operator int.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72281 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index fd88b93..6ef748c 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -48,7 +48,7 @@
     OwningExprResult VisitUnaryOperator(UnaryOperator *E);
     OwningExprResult VisitArraySubscriptExpr(ArraySubscriptExpr *E);
     OwningExprResult VisitCallExpr(CallExpr *E);
-    // FIXME: VisitMemberExpr
+    OwningExprResult VisitMemberExpr(MemberExpr *E);
     OwningExprResult VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
     OwningExprResult VisitBinaryOperator(BinaryOperator *E);
     OwningExprResult VisitCompoundAssignOperator(CompoundAssignOperator *E);
@@ -96,6 +96,7 @@
     OwningExprResult VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
     OwningExprResult VisitCXXUnresolvedConstructExpr(
                                                CXXUnresolvedConstructExpr *E);
+    OwningExprResult VisitCXXUnresolvedMemberExpr(CXXUnresolvedMemberExpr *E);
     OwningExprResult VisitGNUNullExpr(GNUNullExpr *E);
     OwningExprResult VisitUnresolvedFunctionNameExpr(
                                               UnresolvedFunctionNameExpr *E);
@@ -289,6 +290,26 @@
 }
 
 Sema::OwningExprResult 
+TemplateExprInstantiator::VisitMemberExpr(MemberExpr *E) {
+  // Instantiate the base of the expression.
+  OwningExprResult Base = Visit(E->getBase());
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+
+  // FIXME: Handle declaration names here
+  SourceLocation FakeOperatorLoc = 
+    SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
+  return SemaRef.ActOnMemberReferenceExpr(/*Scope=*/0,
+                                          move(Base), 
+                                          /*FIXME*/FakeOperatorLoc,
+                                          E->isArrow()? tok::arrow 
+                                                      : tok::period,
+                                          E->getMemberLoc(),
+                               /*FIXME:*/*E->getMemberDecl()->getIdentifier(),
+                                   /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
+}
+
+Sema::OwningExprResult 
 TemplateExprInstantiator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
   SourceLocation FakeTypeLoc 
     = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
@@ -1159,6 +1180,24 @@
 }
 
 Sema::OwningExprResult 
+TemplateExprInstantiator::VisitCXXUnresolvedMemberExpr(
+                                                 CXXUnresolvedMemberExpr *E) {
+  // Instantiate the base of the expression.
+  OwningExprResult Base = Visit(E->getBase());
+  if (Base.isInvalid())
+    return SemaRef.ExprError();
+
+  // FIXME: Instantiate the declaration name.
+  return SemaRef.ActOnMemberReferenceExpr(/*Scope=*/0,
+                                          move(Base), E->getOperatorLoc(),
+                                          E->isArrow()? tok::arrow 
+                                                      : tok::period,
+                                          E->getMemberLoc(),
+                              /*FIXME:*/*E->getMember().getAsIdentifierInfo(),
+                                   /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
+}
+
+Sema::OwningExprResult 
 Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
   if (!E)
     return Owned((Expr *)0);