[cfe-commits] r143410 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/DeclCXX.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/SemaTemplate/delegating-constructors.cpp tools/libclang/CIndex.cpp
Douglas Gregor
dgregor at apple.com
Mon Oct 31 18:16:04 PDT 2011
Author: dgregor
Date: Mon Oct 31 20:16:03 2011
New Revision: 143410
URL: http://llvm.org/viewvc/llvm-project?rev=143410&view=rev
Log:
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).
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/test/SemaTemplate/delegating-constructors.cpp
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=143410&r1=143409&r2=143410&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Oct 31 20:16:03 2011
@@ -1445,11 +1445,10 @@
/// };
/// @endcode
class CXXCtorInitializer {
- /// \brief Either the base class name (stored as a TypeSourceInfo*), an normal
- /// field (FieldDecl), anonymous field (IndirectFieldDecl*), or target
- /// constructor (CXXConstructorDecl*) being initialized.
- llvm::PointerUnion4<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *,
- CXXConstructorDecl *>
+ /// \brief Either the base class name/delegating constructor type (stored as
+ /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
+ /// (IndirectFieldDecl*) being initialized.
+ llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *>
Initializee;
/// \brief The source location for the field name or, for a base initializer
@@ -1470,6 +1469,10 @@
/// RParenLoc - Location of the right paren of the ctor-initializer.
SourceLocation RParenLoc;
+ /// \brief If the initializee is a type, whether that type makes this
+ /// a delegating initialization.
+ bool IsDelegating : 1;
+
/// IsVirtual - If the initializer is a base initializer, this keeps track
/// of whether the base is virtual or not.
bool IsVirtual : 1;
@@ -1483,7 +1486,7 @@
/// original sources, counting from 0; otherwise, if IsWritten is false,
/// it stores the number of array index variables stored after this
/// object in memory.
- unsigned SourceOrderOrNumArrayIndices : 14;
+ unsigned SourceOrderOrNumArrayIndices : 13;
CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
SourceLocation MemberLoc, SourceLocation L, Expr *Init,
@@ -1510,8 +1513,8 @@
/// CXXCtorInitializer - Creates a new delegating Initializer.
explicit
- CXXCtorInitializer(ASTContext &Context, SourceLocation D, SourceLocation L,
- CXXConstructorDecl *Target, Expr *Init, SourceLocation R);
+ CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
+ SourceLocation L, Expr *Init, SourceLocation R);
/// \brief Creates a new member initializer that optionally contains
/// array indices used to describe an elementwise initialization.
@@ -1522,7 +1525,9 @@
/// isBaseInitializer - Returns true when this initializer is
/// initializing a base class.
- bool isBaseInitializer() const { return Initializee.is<TypeSourceInfo*>(); }
+ bool isBaseInitializer() const {
+ return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
+ }
/// isMemberInitializer - Returns true when this initializer is
/// initializing a non-static data member.
@@ -1546,7 +1551,7 @@
/// isDelegatingInitializer - Returns true when this initializer is creating
/// a delegating constructor.
bool isDelegatingInitializer() const {
- return Initializee.is<CXXConstructorDecl *>();
+ return Initializee.is<TypeSourceInfo*>() && IsDelegating;
}
/// \brief Determine whether this initializer is a pack expansion.
@@ -1576,8 +1581,9 @@
return IsVirtual;
}
- /// \brief Returns the declarator information for a base class initializer.
- TypeSourceInfo *getBaseClassInfo() const {
+ /// \brief Returns the declarator information for a base class or delegating
+ /// initializer.
+ TypeSourceInfo *getTypeSourceInfo() const {
return Initializee.dyn_cast<TypeSourceInfo *>();
}
@@ -1606,13 +1612,6 @@
return 0;
}
- CXXConstructorDecl *getTargetConstructor() const {
- if (isDelegatingInitializer())
- return Initializee.get<CXXConstructorDecl*>();
- else
- return 0;
- }
-
SourceLocation getMemberLocation() const {
return MemberOrEllipsisLocation;
}
@@ -1821,11 +1820,7 @@
/// getTargetConstructor - When this constructor delegates to
/// another, retrieve the target
- CXXConstructorDecl *getTargetConstructor() const {
- assert(isDelegatingConstructor() &&
- "A non-delegating constructor has no target");
- return CtorInitializers[0]->getTargetConstructor();
- }
+ CXXConstructorDecl *getTargetConstructor() const;
/// isDefaultConstructor - Whether this constructor is a default
/// constructor (C++ [class.ctor]p5), which can be used to
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=143410&r1=143409&r2=143410&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon Oct 31 20:16:03 2011
@@ -667,7 +667,9 @@
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
CXXCtorInitializer *Init) {
- // FIXME: recurse on TypeLoc of the base initializer if isBaseInitializer()?
+ if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+
if (Init->isWritten())
TRY_TO(TraverseStmt(Init->getInit()));
return true;
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=143410&r1=143409&r2=143410&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Oct 31 20:16:03 2011
@@ -3518,7 +3518,6 @@
MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo,
const MultiInitializer &Args,
- SourceLocation BaseLoc,
CXXRecordDecl *ClassDecl);
bool SetDelegatingInitializer(CXXConstructorDecl *Constructor,
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=143410&r1=143409&r2=143410&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Oct 31 20:16:03 2011
@@ -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
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=143410&r1=143409&r2=143410&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Oct 31 20:16:03 2011
@@ -2125,13 +2125,12 @@
MemInitResult
Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo,
const MultiInitializer &Args,
- SourceLocation NameLoc,
CXXRecordDecl *ClassDecl) {
- SourceLocation Loc = TInfo->getTypeLoc().getLocalSourceRange().getBegin();
+ SourceLocation NameLoc = TInfo->getTypeLoc().getLocalSourceRange().getBegin();
if (!LangOpts.CPlusPlus0x)
- return Diag(Loc, diag::err_delegating_ctor)
+ return Diag(NameLoc, diag::err_delegating_ctor)
<< TInfo->getTypeLoc().getLocalSourceRange();
- Diag(Loc, diag::warn_cxx98_compat_delegating_ctor);
+ Diag(NameLoc, diag::warn_cxx98_compat_delegating_ctor);
// Initialize the object.
InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation(
@@ -2158,9 +2157,7 @@
if (DelegationInit.isInvalid())
return true;
- assert(!CurContext->isDependentContext());
- return new (Context) CXXCtorInitializer(Context, Loc, Args.getStartLoc(),
- Constructor,
+ return new (Context) CXXCtorInitializer(Context, TInfo, Args.getStartLoc(),
DelegationInit.takeAs<Expr>(),
Args.getEndLoc());
}
@@ -2210,7 +2207,7 @@
if (!Dependent) {
if (Context.hasSameUnqualifiedType(QualType(ClassDecl->getTypeForDecl(),0),
BaseType))
- return BuildDelegatingInitializer(BaseTInfo, Args, BaseLoc, ClassDecl);
+ return BuildDelegatingInitializer(BaseTInfo, Args, ClassDecl);
FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec,
VirtualBaseSpec);
@@ -3000,12 +2997,12 @@
if (PrevInit->isAnyMemberInitializer())
D << 0 << PrevInit->getAnyMember()->getDeclName();
else
- D << 1 << PrevInit->getBaseClassInfo()->getType();
+ D << 1 << PrevInit->getTypeSourceInfo()->getType();
if (Init->isAnyMemberInitializer())
D << 0 << Init->getAnyMember()->getDeclName();
else
- D << 1 << Init->getBaseClassInfo()->getType();
+ D << 1 << Init->getTypeSourceInfo()->getType();
// Move back to the initializer's location in the ideal list.
for (IdealIndex = 0; IdealIndex != NumIdealInits; ++IdealIndex)
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=143410&r1=143409&r2=143410&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Oct 31 20:16:03 2011
@@ -2744,7 +2744,7 @@
if (Init->isPackExpansion()) {
// This is a pack expansion. We should expand it now.
- TypeLoc BaseTL = Init->getBaseClassInfo()->getTypeLoc();
+ TypeLoc BaseTL = Init->getTypeSourceInfo()->getTypeLoc();
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
collectUnexpandedParameterPacks(BaseTL, Unexpanded);
bool ShouldExpand = false;
@@ -2774,7 +2774,7 @@
}
// Instantiate the base type.
- TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(),
+ TypeSourceInfo *BaseTInfo = SubstType(Init->getTypeSourceInfo(),
TemplateArgs,
Init->getSourceLocation(),
New->getDeclName());
@@ -2809,20 +2809,25 @@
}
MemInitResult NewInit;
- if (Init->isBaseInitializer()) {
- TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(),
- TemplateArgs,
- Init->getSourceLocation(),
- New->getDeclName());
- if (!BaseTInfo) {
+ if (Init->isDelegatingInitializer() || Init->isBaseInitializer()) {
+ TypeSourceInfo *TInfo = SubstType(Init->getTypeSourceInfo(),
+ TemplateArgs,
+ Init->getSourceLocation(),
+ New->getDeclName());
+ if (!TInfo) {
AnyErrors = true;
New->setInvalidDecl();
continue;
}
MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init));
- NewInit = BuildBaseInitializer(BaseTInfo->getType(), BaseTInfo, MultiInit,
- New->getParent(), EllipsisLoc);
+
+ if (Init->isBaseInitializer())
+ NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, MultiInit,
+ New->getParent(), EllipsisLoc);
+ else
+ NewInit = BuildDelegatingInitializer(TInfo, MultiInit,
+ cast<CXXRecordDecl>(CurContext->getParent()));
} else if (Init->isMemberInitializer()) {
FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl(
Init->getMemberLocation(),
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=143410&r1=143409&r2=143410&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Oct 31 20:16:03 2011
@@ -5152,21 +5152,20 @@
CtorInitializers
= new (Context) CXXCtorInitializer*[NumInitializers];
for (unsigned i=0; i != NumInitializers; ++i) {
- TypeSourceInfo *BaseClassInfo = 0;
+ TypeSourceInfo *TInfo = 0;
bool IsBaseVirtual = false;
FieldDecl *Member = 0;
IndirectFieldDecl *IndirectMember = 0;
- CXXConstructorDecl *Target = 0;
CtorInitializerType Type = (CtorInitializerType)Record[Idx++];
switch (Type) {
- case CTOR_INITIALIZER_BASE:
- BaseClassInfo = GetTypeSourceInfo(F, Record, Idx);
+ case CTOR_INITIALIZER_BASE:
+ TInfo = GetTypeSourceInfo(F, Record, Idx);
IsBaseVirtual = Record[Idx++];
break;
-
- case CTOR_INITIALIZER_DELEGATING:
- Target = ReadDeclAs<CXXConstructorDecl>(F, Record, Idx);
+
+ case CTOR_INITIALIZER_DELEGATING:
+ TInfo = GetTypeSourceInfo(F, Record, Idx);
break;
case CTOR_INITIALIZER_MEMBER:
@@ -5196,12 +5195,12 @@
CXXCtorInitializer *BOMInit;
if (Type == CTOR_INITIALIZER_BASE) {
- BOMInit = new (Context) CXXCtorInitializer(Context, BaseClassInfo, IsBaseVirtual,
+ BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, IsBaseVirtual,
LParenLoc, Init, RParenLoc,
MemberOrEllipsisLoc);
} else if (Type == CTOR_INITIALIZER_DELEGATING) {
- BOMInit = new (Context) CXXCtorInitializer(Context, MemberOrEllipsisLoc, LParenLoc,
- Target, Init, RParenLoc);
+ BOMInit = new (Context) CXXCtorInitializer(Context, TInfo, LParenLoc,
+ Init, RParenLoc);
} else if (IsWritten) {
if (Member)
BOMInit = new (Context) CXXCtorInitializer(Context, Member, MemberOrEllipsisLoc,
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=143410&r1=143409&r2=143410&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Oct 31 20:16:03 2011
@@ -3881,11 +3881,11 @@
if (Init->isBaseInitializer()) {
Record.push_back(CTOR_INITIALIZER_BASE);
- AddTypeSourceInfo(Init->getBaseClassInfo(), Record);
+ AddTypeSourceInfo(Init->getTypeSourceInfo(), Record);
Record.push_back(Init->isBaseVirtual());
} else if (Init->isDelegatingInitializer()) {
Record.push_back(CTOR_INITIALIZER_DELEGATING);
- AddDeclRef(Init->getTargetConstructor(), Record);
+ AddTypeSourceInfo(Init->getTypeSourceInfo(), Record);
} else if (Init->isMemberInitializer()){
Record.push_back(CTOR_INITIALIZER_MEMBER);
AddDeclRef(Init->getMember(), Record);
Modified: cfe/trunk/test/SemaTemplate/delegating-constructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/delegating-constructors.cpp?rev=143410&r1=143409&r2=143410&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/delegating-constructors.cpp (original)
+++ cfe/trunk/test/SemaTemplate/delegating-constructors.cpp Mon Oct 31 20:16:03 2011
@@ -15,4 +15,17 @@
void f() {
string s("hello");
}
+
+ struct Foo {
+ Foo(int) { }
+
+
+ template <typename T>
+ Foo(T, int i) : Foo(i) { }
+};
+
+ void test_Foo()
+ {
+ Foo f(1, 1);
+ }
}
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=143410&r1=143409&r2=143410&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Oct 31 20:16:03 2011
@@ -828,8 +828,8 @@
if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Init->getMemberLocation(), TU)))
return true;
- } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
- if (Visit(BaseInfo->getTypeLoc()))
+ } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
+ if (Visit(TInfo->getTypeLoc()))
return true;
}
More information about the cfe-commits
mailing list