зеркало из https://github.com/microsoft/clang.git
Mark constructors used in initialization of base(s) and fields
as referecned with location where they are used. Still need to look at destructor aspects of them. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80950 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
80545ad0f9
Коммит
9d436205be
|
@ -948,17 +948,27 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
||||||
if (VBase->getType()->isDependentType())
|
if (VBase->getType()->isDependentType())
|
||||||
continue;
|
continue;
|
||||||
if (CXXBaseOrMemberInitializer *Value =
|
if (CXXBaseOrMemberInitializer *Value =
|
||||||
AllBaseFields.lookup(VBase->getType()->getAs<RecordType>()))
|
AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) {
|
||||||
|
CXXRecordDecl *BaseDecl =
|
||||||
|
cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
|
||||||
|
assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
|
||||||
|
if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context))
|
||||||
|
MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
|
||||||
AllToInit.push_back(Value);
|
AllToInit.push_back(Value);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
CXXRecordDecl *VBaseDecl =
|
CXXRecordDecl *VBaseDecl =
|
||||||
cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
|
cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
|
||||||
assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null");
|
assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null");
|
||||||
if (!VBaseDecl->getDefaultConstructor(Context))
|
CXXConstructorDecl *Ctor = VBaseDecl->getDefaultConstructor(Context);
|
||||||
|
if (!Ctor)
|
||||||
Bases.push_back(VBase);
|
Bases.push_back(VBase);
|
||||||
|
else
|
||||||
|
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
|
||||||
|
|
||||||
CXXBaseOrMemberInitializer *Member =
|
CXXBaseOrMemberInitializer *Member =
|
||||||
new (Context) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
|
new (Context) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
|
||||||
VBaseDecl->getDefaultConstructor(Context),
|
Ctor,
|
||||||
SourceLocation(),
|
SourceLocation(),
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
AllToInit.push_back(Member);
|
AllToInit.push_back(Member);
|
||||||
|
@ -975,14 +985,24 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
||||||
if (Base->getType()->isDependentType())
|
if (Base->getType()->isDependentType())
|
||||||
continue;
|
continue;
|
||||||
if (CXXBaseOrMemberInitializer *Value =
|
if (CXXBaseOrMemberInitializer *Value =
|
||||||
AllBaseFields.lookup(Base->getType()->getAs<RecordType>()))
|
AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) {
|
||||||
|
CXXRecordDecl *BaseDecl =
|
||||||
|
cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
|
||||||
|
assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
|
||||||
|
if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context))
|
||||||
|
MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
|
||||||
AllToInit.push_back(Value);
|
AllToInit.push_back(Value);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
CXXRecordDecl *BaseDecl =
|
CXXRecordDecl *BaseDecl =
|
||||||
cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
|
cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
|
||||||
assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
|
assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
|
||||||
if (!BaseDecl->getDefaultConstructor(Context))
|
CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context);
|
||||||
|
if (!Ctor)
|
||||||
Bases.push_back(Base);
|
Bases.push_back(Base);
|
||||||
|
else
|
||||||
|
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
|
||||||
|
|
||||||
CXXBaseOrMemberInitializer *Member =
|
CXXBaseOrMemberInitializer *Member =
|
||||||
new (Context) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
|
new (Context) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
|
||||||
BaseDecl->getDefaultConstructor(Context),
|
BaseDecl->getDefaultConstructor(Context),
|
||||||
|
@ -1017,6 +1037,14 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*Field)) {
|
if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*Field)) {
|
||||||
|
QualType FT = (*Field)->getType();
|
||||||
|
if (const RecordType* RT = FT->getAs<RecordType>()) {
|
||||||
|
CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RT->getDecl());
|
||||||
|
assert(FieldRecDecl && "setBaseOrMemberInitializers - BaseDecl null");
|
||||||
|
if (CXXConstructorDecl *Ctor =
|
||||||
|
FieldRecDecl->getDefaultConstructor(Context))
|
||||||
|
MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
|
||||||
|
}
|
||||||
AllToInit.push_back(Value);
|
AllToInit.push_back(Value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1033,6 +1061,8 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
||||||
SourceLocation(),
|
SourceLocation(),
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
AllToInit.push_back(Member);
|
AllToInit.push_back(Member);
|
||||||
|
if (Ctor)
|
||||||
|
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
|
||||||
if (FT.isConstQualified() && (!Ctor || Ctor->isTrivial())) {
|
if (FT.isConstQualified() && (!Ctor || Ctor->isTrivial())) {
|
||||||
Diag(Constructor->getLocation(), diag::err_unintialized_member_in_ctor)
|
Diag(Constructor->getLocation(), diag::err_unintialized_member_in_ctor)
|
||||||
<< Context.getTagDeclType(ClassDecl) << 1 << (*Field)->getDeclName();
|
<< Context.getTagDeclType(ClassDecl) << 1 << (*Field)->getDeclName();
|
||||||
|
@ -1176,25 +1206,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
|
||||||
|
|
||||||
if (Constructor->isDependentContext())
|
if (Constructor->isDependentContext())
|
||||||
return;
|
return;
|
||||||
// Mark all constructors used in initialization of class's members
|
|
||||||
// as referenced.
|
|
||||||
// FIXME. We can do this while building the initializer list. But
|
|
||||||
// MarkDeclarationReferenced is not accessible in ASTContext.
|
|
||||||
for (CXXConstructorDecl::init_const_iterator B = Constructor->init_begin(),
|
|
||||||
E = Constructor->init_end();
|
|
||||||
B != E; ++B) {
|
|
||||||
CXXBaseOrMemberInitializer *Member = (*B);
|
|
||||||
if (!Member->isMemberInitializer())
|
|
||||||
continue;
|
|
||||||
FieldDecl *Field = Member->getMember();
|
|
||||||
QualType FT = Context.getBaseElementType(Field->getType());
|
|
||||||
if (FT->isDependentType())
|
|
||||||
continue;
|
|
||||||
if (const RecordType* RT = FT->getAs<RecordType>())
|
|
||||||
if (CXXConstructorDecl *Ctor =
|
|
||||||
cast<CXXRecordDecl>(RT->getDecl())->getDefaultConstructor(Context))
|
|
||||||
MarkDeclarationReferenced(Ctor->getLocation(), Ctor);
|
|
||||||
}
|
|
||||||
if (Diags.getDiagnosticLevel(diag::warn_base_initialized) ==
|
if (Diags.getDiagnosticLevel(diag::warn_base_initialized) ==
|
||||||
Diagnostic::Ignored &&
|
Diagnostic::Ignored &&
|
||||||
Diags.getDiagnosticLevel(diag::warn_field_initialized) ==
|
Diags.getDiagnosticLevel(diag::warn_field_initialized) ==
|
||||||
|
|
|
@ -24,7 +24,14 @@ public:
|
||||||
List(){ } // List<BinomialNode<int>*>::List() remains undefined.
|
List(){ } // List<BinomialNode<int>*>::List() remains undefined.
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> class BinomialNode {
|
template <typename T> class Node {
|
||||||
|
int i;
|
||||||
|
public:
|
||||||
|
Node(){ } // Node<BinomialNode<int>*>::Node() remains undefined.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T> class BinomialNode : Node<BinomialNode<T>*> {
|
||||||
public:
|
public:
|
||||||
BinomialNode(T value) {}
|
BinomialNode(T value) {}
|
||||||
List<BinomialNode<T>*> nodes;
|
List<BinomialNode<T>*> nodes;
|
||||||
|
@ -35,7 +42,8 @@ int main() {
|
||||||
BinomialNode<int> *node = new BinomialNode<int>(1);
|
BinomialNode<int> *node = new BinomialNode<int>(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC1Ev:
|
||||||
// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev:
|
// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev:
|
||||||
|
|
||||||
|
// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC1Ev:
|
||||||
// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev:
|
// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev:
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче