Eliminate QualifiedDeclRefExpr, which captured the notion of a
qualified reference to a declaration that is not a non-static data
member or non-static member function, e.g., 

  namespace N { int i; }
  int j = N::i;

Instead, extend DeclRefExpr to optionally store the qualifier. Most
clients won't see or care about the difference (since
QualifierDeclRefExpr inherited DeclRefExpr). However, this reduces the
number of top-level expression types that clients need to cope with,
brings the implementation of DeclRefExpr into line with MemberExpr,
and simplifies and unifies our handling of declaration references.

Extended DeclRefExpr to (optionally) store explicitly-specified
template arguments. This occurs when naming a declaration via a
template-id (which will be stored in a TemplateIdRefExpr) that,
following template argument deduction and (possibly) overload
resolution, is replaced with a DeclRefExpr that refers to a template
specialization but maintains the template arguments as written.





git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84962 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index a4de3e5..47df95d 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -30,6 +30,91 @@
 // Primary Expressions.
 //===----------------------------------------------------------------------===//
 
+DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, 
+                         SourceRange QualifierRange,
+                         NamedDecl *D, SourceLocation NameLoc,
+                         bool HasExplicitTemplateArgumentList,
+                         SourceLocation LAngleLoc,
+                         const TemplateArgument *ExplicitTemplateArgs,
+                         unsigned NumExplicitTemplateArgs,
+                         SourceLocation RAngleLoc,
+                         QualType T, bool TD, bool VD)
+  : Expr(DeclRefExprClass, T, TD, VD),
+    DecoratedD(D,
+               (Qualifier? HasQualifierFlag : 0) |
+               (HasExplicitTemplateArgumentList? 
+                                    HasExplicitTemplateArgumentListFlag : 0)),
+    Loc(NameLoc) {
+  if (Qualifier) {
+    NameQualifier *NQ = getNameQualifier();
+    NQ->NNS = Qualifier;
+    NQ->Range = QualifierRange;
+  }
+      
+  if (HasExplicitTemplateArgumentList) {
+    ExplicitTemplateArgumentList *ETemplateArgs
+      = getExplicitTemplateArgumentList();
+    ETemplateArgs->LAngleLoc = LAngleLoc;
+    ETemplateArgs->RAngleLoc = RAngleLoc;
+    ETemplateArgs->NumTemplateArgs = NumExplicitTemplateArgs;
+    
+    TemplateArgument *TemplateArgs = ETemplateArgs->getTemplateArgs();
+    for (unsigned I = 0; I < NumExplicitTemplateArgs; ++I)
+      new (TemplateArgs + I) TemplateArgument(ExplicitTemplateArgs[I]);
+  }
+}
+
+DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
+                                 NestedNameSpecifier *Qualifier,
+                                 SourceRange QualifierRange,
+                                 NamedDecl *D,
+                                 SourceLocation NameLoc,
+                                 QualType T, bool TD, bool VD) {
+  return Create(Context, Qualifier, QualifierRange, D, NameLoc,
+                false, SourceLocation(), 0, 0, SourceLocation(),
+                T, TD, VD);
+}
+
+DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
+                                 NestedNameSpecifier *Qualifier,
+                                 SourceRange QualifierRange,
+                                 NamedDecl *D,
+                                 SourceLocation NameLoc,
+                                 bool HasExplicitTemplateArgumentList,
+                                 SourceLocation LAngleLoc,
+                                 const TemplateArgument *ExplicitTemplateArgs,
+                                 unsigned NumExplicitTemplateArgs,
+                                 SourceLocation RAngleLoc,
+                                 QualType T, bool TD, bool VD) {
+  std::size_t Size = sizeof(DeclRefExpr);
+  if (Qualifier != 0)
+    Size += sizeof(NameQualifier);
+  
+  if (HasExplicitTemplateArgumentList)
+    Size += sizeof(ExplicitTemplateArgumentList) +
+            sizeof(TemplateArgument) * NumExplicitTemplateArgs;
+  
+  void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
+  return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
+                               HasExplicitTemplateArgumentList,
+                               LAngleLoc, 
+                               ExplicitTemplateArgs, 
+                               NumExplicitTemplateArgs,
+                               RAngleLoc,
+                               T, TD, VD);
+}
+
+SourceRange DeclRefExpr::getSourceRange() const {
+  // FIXME: Does not handle multi-token names well, e.g., operator[].
+  SourceRange R(Loc);
+  
+  if (hasQualifier())
+    R.setBegin(getQualifierRange().getBegin());
+  if (hasExplicitTemplateArgumentList())
+    R.setEnd(getRAngleLoc());
+  return R;
+}
+
 // FIXME: Maybe this should use DeclPrinter with a special "print predefined
 // expr" policy instead.
 std::string PredefinedExpr::ComputeName(ASTContext &Context, IdentType IT,
@@ -855,8 +940,7 @@
     if (cast<ArraySubscriptExpr>(this)->getBase()->getType()->isVectorType())
       return cast<ArraySubscriptExpr>(this)->getBase()->isLvalue(Ctx);
     return LV_Valid;
-  case DeclRefExprClass:
-  case QualifiedDeclRefExprClass: { // C99 6.5.1p2
+  case DeclRefExprClass: { // C99 6.5.1p2
     const NamedDecl *RefdDecl = cast<DeclRefExpr>(this)->getDecl();
     if (DeclCanBeLvalue(RefdDecl, Ctx))
       return LV_Valid;
@@ -1133,8 +1217,7 @@
     return cast<ImplicitCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
   case CStyleCastExprClass:
     return cast<CStyleCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
-  case DeclRefExprClass:
-  case QualifiedDeclRefExprClass: {
+  case DeclRefExprClass: {
     const Decl *D = cast<DeclRefExpr>(this)->getDecl();
     if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
       if (VD->hasGlobalStorage())
@@ -1432,7 +1515,6 @@
     return ICEDiag(2, E->getLocStart());
   }
   case Expr::DeclRefExprClass:
-  case Expr::QualifiedDeclRefExprClass:
     if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
       return NoDiag();
     if (Ctx.getLangOptions().CPlusPlus &&