Rework the AST for the initializer of a delegating constructor, so
that it retains source location information for the type. Aside from
general goodness (being able to walk the types described in that
information), we now have a proper representation for dependent
delegating constructors. Fixes PR10457 (for real).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143410 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 576d0d5..b8c20e4 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "llvm/ADT/STLExtras.h"
@@ -1299,8 +1300,8 @@
                                        SourceLocation R,
                                        SourceLocation EllipsisLoc)
   : Initializee(TInfo), MemberOrEllipsisLocation(EllipsisLoc), Init(Init), 
-    LParenLoc(L), RParenLoc(R), IsVirtual(IsVirtual), IsWritten(false),
-    SourceOrderOrNumArrayIndices(0)
+    LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(IsVirtual), 
+    IsWritten(false), SourceOrderOrNumArrayIndices(0)
 {
 }
 
@@ -1310,7 +1311,7 @@
                                        SourceLocation L, Expr *Init,
                                        SourceLocation R)
   : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
-    LParenLoc(L), RParenLoc(R), IsVirtual(false),
+    LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
     IsWritten(false), SourceOrderOrNumArrayIndices(0)
 {
 }
@@ -1321,17 +1322,17 @@
                                        SourceLocation L, Expr *Init,
                                        SourceLocation R)
   : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
-    LParenLoc(L), RParenLoc(R), IsVirtual(false),
+    LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
     IsWritten(false), SourceOrderOrNumArrayIndices(0)
 {
 }
 
 CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
-                                       SourceLocation D, SourceLocation L,
-                                       CXXConstructorDecl *Target, Expr *Init,
+                                       TypeSourceInfo *TInfo,
+                                       SourceLocation L, Expr *Init, 
                                        SourceLocation R)
-  : Initializee(Target), MemberOrEllipsisLocation(D), Init(Init),
-    LParenLoc(L), RParenLoc(R), IsVirtual(false),
+  : Initializee(TInfo), MemberOrEllipsisLocation(), Init(Init),
+    LParenLoc(L), RParenLoc(R), IsDelegating(true), IsVirtual(false),
     IsWritten(false), SourceOrderOrNumArrayIndices(0)
 {
 }
@@ -1380,13 +1381,16 @@
 }
 
 SourceLocation CXXCtorInitializer::getSourceLocation() const {
-  if (isAnyMemberInitializer() || isDelegatingInitializer())
+  if (isAnyMemberInitializer())
     return getMemberLocation();
 
   if (isInClassMemberInitializer())
     return getAnyMember()->getLocation();
   
-  return getBaseClassLoc().getLocalSourceRange().getBegin();
+  if (TypeSourceInfo *TSInfo = Initializee.get<TypeSourceInfo*>())
+    return TSInfo->getTypeLoc().getLocalSourceRange().getBegin();
+  
+  return SourceLocation();
 }
 
 SourceRange CXXCtorInitializer::getSourceRange() const {
@@ -1421,6 +1425,15 @@
                                     isConstexpr);
 }
 
+CXXConstructorDecl *CXXConstructorDecl::getTargetConstructor() const {
+  assert(isDelegatingConstructor() && "Not a delegating constructor!");
+  Expr *E = (*init_begin())->getInit()->IgnoreImplicit();
+  if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(E))
+    return Construct->getConstructor();
+  
+  return 0;
+}
+
 bool CXXConstructorDecl::isDefaultConstructor() const {
   // C++ [class.ctor]p5:
   //   A default constructor for a class X is a constructor of class