forked from OSchip/llvm-project
parent
9fc30d5c30
commit
4044d995c9
|
@ -1654,6 +1654,8 @@ void Sema::AddCXXDirectInitializerToDecl(DeclTy *Dcl, SourceLocation LParenLoc,
|
|||
return;
|
||||
}
|
||||
|
||||
// FIXME: Need to handle dependent types and expressions here.
|
||||
|
||||
// We will treat direct-initialization as a copy-initialization:
|
||||
// int x(1); -as-> int x = 1;
|
||||
// ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
|
||||
|
@ -1672,6 +1674,13 @@ void Sema::AddCXXDirectInitializerToDecl(DeclTy *Dcl, SourceLocation LParenLoc,
|
|||
if (const ArrayType *Array = Context.getAsArrayType(DeclInitType))
|
||||
DeclInitType = Array->getElementType();
|
||||
|
||||
// FIXME: This isn't the right place to complete the type.
|
||||
if (RequireCompleteType(VDecl->getLocation(), VDecl->getType(),
|
||||
diag::err_typecheck_decl_incomplete_type)) {
|
||||
VDecl->setInvalidDecl();
|
||||
return;
|
||||
}
|
||||
|
||||
if (VDecl->getType()->isRecordType()) {
|
||||
CXXConstructorDecl *Constructor
|
||||
= PerformInitializationByConstructor(DeclInitType,
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace {
|
|||
Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
|
||||
Decl *VisitEnumDecl(EnumDecl *D);
|
||||
Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
|
||||
Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
|
||||
Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
|
||||
Decl *VisitParmVarDecl(ParmVarDecl *D);
|
||||
Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
|
||||
|
@ -247,6 +248,50 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
|
|||
return Method;
|
||||
}
|
||||
|
||||
Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
|
||||
llvm::SmallVector<ParmVarDecl *, 16> Params;
|
||||
QualType T = InstantiateFunctionType(D, Params);
|
||||
if (T.isNull())
|
||||
return 0;
|
||||
|
||||
// Build the instantiated method declaration.
|
||||
CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
|
||||
QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
|
||||
DeclarationName Name
|
||||
= SemaRef.Context.DeclarationNames.getCXXConstructorName(ClassTy);
|
||||
CXXConstructorDecl *Constructor
|
||||
= CXXConstructorDecl::Create(SemaRef.Context, Record, D->getLocation(),
|
||||
Name, T, D->isExplicit(), D->isInline(),
|
||||
false);
|
||||
|
||||
// Attach the parameters
|
||||
for (unsigned P = 0; P < Params.size(); ++P)
|
||||
Params[P]->setOwningFunction(Constructor);
|
||||
Constructor->setParams(SemaRef.Context, &Params[0], Params.size());
|
||||
|
||||
if (InitMethodInstantiation(Constructor, D))
|
||||
Constructor->setInvalidDecl();
|
||||
|
||||
NamedDecl *PrevDecl
|
||||
= SemaRef.LookupQualifiedName(Owner, Name, Sema::LookupOrdinaryName, true);
|
||||
|
||||
// In C++, the previous declaration we find might be a tag type
|
||||
// (class or enum). In this case, the new declaration will hide the
|
||||
// tag type. Note that this does does not apply if we're declaring a
|
||||
// typedef (C++ [dcl.typedef]p4).
|
||||
if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
|
||||
PrevDecl = 0;
|
||||
bool Redeclaration = false;
|
||||
bool OverloadableAttrRequired = false;
|
||||
if (SemaRef.CheckFunctionDeclaration(Constructor, PrevDecl, Redeclaration,
|
||||
/*FIXME:*/OverloadableAttrRequired))
|
||||
Constructor->setInvalidDecl();
|
||||
|
||||
if (!Constructor->isInvalidDecl())
|
||||
Owner->addDecl(Constructor);
|
||||
return Constructor;
|
||||
}
|
||||
|
||||
Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
|
||||
llvm::SmallVector<ParmVarDecl *, 16> Params;
|
||||
QualType T = InstantiateFunctionType(D, Params);
|
||||
|
|
|
@ -41,9 +41,23 @@ void test_ovl_bad() {
|
|||
|
||||
template<typename T>
|
||||
class HasDestructor {
|
||||
public:
|
||||
virtual ~HasDestructor() = 0;
|
||||
};
|
||||
|
||||
int i = sizeof(HasDestructor<int>); // FIXME: forces instantiation, but
|
||||
// the code below should probably instantiate by itself.
|
||||
int abstract_destructor[__is_abstract(HasDestructor<int>)? 1 : -1];
|
||||
|
||||
|
||||
template<typename T>
|
||||
class Constructors {
|
||||
public:
|
||||
Constructors(const T&);
|
||||
Constructors(const Constructors &other);
|
||||
};
|
||||
|
||||
void test_constructors() {
|
||||
Constructors<int> ci1(17);
|
||||
Constructors<int> ci2 = ci1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue