Initial stab at implement dependent member references to member
templates, e.g.,
  
  x.template get<T>

We can now parse these, represent them within an UnresolvedMemberExpr
expression, then instantiate that expression node in simple cases.

This allows us to stumble through parsing LLVM's Casting.h.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81300 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 86c5227..7c36caa 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -523,6 +523,77 @@
   return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
 }
 
+CXXUnresolvedMemberExpr::CXXUnresolvedMemberExpr(ASTContext &C, 
+                                                 Expr *Base, bool IsArrow, 
+                                                 SourceLocation OperatorLoc,
+                                                 NestedNameSpecifier *Qualifier,
+                                                 SourceRange QualifierRange,
+                                          NamedDecl *FirstQualifierFoundInScope,
+                                                 DeclarationName Member,
+                                                 SourceLocation MemberLoc,
+                                                 bool HasExplicitTemplateArgs,
+                                                 SourceLocation LAngleLoc,
+                                           const TemplateArgument *TemplateArgs,
+                                                 unsigned NumTemplateArgs,
+                                                 SourceLocation RAngleLoc)
+  : Expr(CXXUnresolvedMemberExprClass, C.DependentTy, true, true),
+    Base(Base), IsArrow(IsArrow), 
+    HasExplicitTemplateArgumentList(HasExplicitTemplateArgs),
+    OperatorLoc(OperatorLoc),
+    Qualifier(Qualifier), QualifierRange(QualifierRange),
+    FirstQualifierFoundInScope(FirstQualifierFoundInScope),
+    Member(Member), MemberLoc(MemberLoc)
+{
+  if (HasExplicitTemplateArgumentList) {
+    ExplicitTemplateArgumentList *ETemplateArgs 
+      = getExplicitTemplateArgumentList();
+    ETemplateArgs->LAngleLoc = LAngleLoc;
+    ETemplateArgs->RAngleLoc = RAngleLoc;
+    ETemplateArgs->NumTemplateArgs = NumTemplateArgs;
+    
+    TemplateArgument *SavedTemplateArgs = ETemplateArgs->getTemplateArgs();
+    for (unsigned I = 0; I < NumTemplateArgs; ++I)
+      new (SavedTemplateArgs + I) TemplateArgument(TemplateArgs[I]);            
+  }
+}
+
+CXXUnresolvedMemberExpr *
+CXXUnresolvedMemberExpr::Create(ASTContext &C, 
+                                Expr *Base, bool IsArrow, 
+                                SourceLocation OperatorLoc,
+                                NestedNameSpecifier *Qualifier,
+                                SourceRange QualifierRange,
+                                NamedDecl *FirstQualifierFoundInScope,
+                                DeclarationName Member,
+                                SourceLocation MemberLoc,
+                                bool HasExplicitTemplateArgs,
+                                SourceLocation LAngleLoc,
+                                const TemplateArgument *TemplateArgs,
+                                unsigned NumTemplateArgs,
+                                SourceLocation RAngleLoc)
+{
+  if (!HasExplicitTemplateArgs)
+    return new (C) CXXUnresolvedMemberExpr(C, Base, IsArrow, OperatorLoc,
+                                           Qualifier, QualifierRange,
+                                           FirstQualifierFoundInScope,
+                                           Member, MemberLoc);
+  
+  void *Mem = C.Allocate(sizeof(CXXUnresolvedMemberExpr) +
+                         sizeof(ExplicitTemplateArgumentList) + 
+                         sizeof(TemplateArgument) * NumTemplateArgs,
+                         llvm::alignof<CXXUnresolvedMemberExpr>());
+  return new (Mem) CXXUnresolvedMemberExpr(C, Base, IsArrow, OperatorLoc,
+                                           Qualifier, QualifierRange,
+                                           FirstQualifierFoundInScope,
+                                           Member,
+                                           MemberLoc,
+                                           HasExplicitTemplateArgs,
+                                           LAngleLoc,
+                                           TemplateArgs,
+                                           NumTemplateArgs,
+                                           RAngleLoc);
+}
+
 Stmt::child_iterator CXXUnresolvedMemberExpr::child_begin() {
   return child_iterator(&Base);
 }