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