/// \brief Set the kind of specialization or template instantiation this is.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
-
- /// getDefaultConstructor - Returns the default constructor for this class
- CXXConstructorDecl *getDefaultConstructor();
/// getDestructor - Returns the destructor decl for this class.
CXXDestructorDecl *getDestructor() const;
assert(false && "Not a class template or member class specialization");
}
-CXXConstructorDecl *
-CXXRecordDecl::getDefaultConstructor() {
- ASTContext &Context = getASTContext();
- QualType ClassType = Context.getTypeDeclType(this);
- DeclarationName ConstructorName
- = Context.DeclarationNames.getCXXConstructorName(
- Context.getCanonicalType(ClassType.getUnqualifiedType()));
-
- DeclContext::lookup_const_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd) = lookup(ConstructorName);
- Con != ConEnd; ++Con) {
- // FIXME: In C++0x, a constructor template can be a default constructor.
- if (isa<FunctionTemplateDecl>(*Con))
- continue;
-
- CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
- if (Constructor->isDefaultConstructor())
- return Constructor;
- }
- return 0;
-}
-
CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
ASTContext &Context = getASTContext();
QualType ClassType = Context.getTypeDeclType(this);
};
}
+static CXXConstructorDecl *getDefaultConstructorUnsafe(Sema &Self,
+ CXXRecordDecl *D) {
+ ASTContext &Context = Self.Context;
+ QualType ClassType = Context.getTypeDeclType(D);
+ DeclarationName ConstructorName
+ = Context.DeclarationNames.getCXXConstructorName(
+ Context.getCanonicalType(ClassType.getUnqualifiedType()));
+
+ DeclContext::lookup_const_iterator Con, ConEnd;
+ for (llvm::tie(Con, ConEnd) = D->lookup(ConstructorName);
+ Con != ConEnd; ++Con) {
+ // FIXME: In C++0x, a constructor template can be a default constructor.
+ if (isa<FunctionTemplateDecl>(*Con))
+ continue;
+
+ CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
+ if (Constructor->isDefaultConstructor())
+ return Constructor;
+ }
+ return 0;
+}
+
CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
CXXRecordDecl *ClassDecl) {
// C++ [class.ctor]p5:
CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
if (!BaseClassDecl->hasDeclaredDefaultConstructor())
ExceptSpec.CalledDecl(DeclareImplicitDefaultConstructor(BaseClassDecl));
- else if (CXXConstructorDecl *Constructor
- = BaseClassDecl->getDefaultConstructor())
+ else if (CXXConstructorDecl *Constructor
+ = getDefaultConstructorUnsafe(*this, BaseClassDecl))
ExceptSpec.CalledDecl(Constructor);
}
}
if (!BaseClassDecl->hasDeclaredDefaultConstructor())
ExceptSpec.CalledDecl(DeclareImplicitDefaultConstructor(BaseClassDecl));
else if (CXXConstructorDecl *Constructor
- = BaseClassDecl->getDefaultConstructor())
+ = getDefaultConstructorUnsafe(*this, BaseClassDecl))
ExceptSpec.CalledDecl(Constructor);
}
}
ExceptSpec.CalledDecl(
DeclareImplicitDefaultConstructor(FieldClassDecl));
else if (CXXConstructorDecl *Constructor
- = FieldClassDecl->getDefaultConstructor())
+ = getDefaultConstructorUnsafe(*this, FieldClassDecl))
ExceptSpec.CalledDecl(Constructor);
}
}
bool FoundConstructor = false;
bool AllNoThrow = true;
unsigned FoundTQs;
- DeclarationName ConstructorName
- = C.DeclarationNames.getCXXConstructorName(C.getCanonicalType(T));
DeclContext::lookup_const_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd) = Self.LookupConstructors(RD);
Con != ConEnd; ++Con) {
FoundConstructor = true;
const FunctionProtoType *CPT
= Constructor->getType()->getAs<FunctionProtoType>();
- if (!CPT->hasEmptyExceptionSpec()) {
+ // TODO: check whether evaluating default arguments can throw.
+ // For now, we'll be conservative and assume that they can throw.
+ if (!CPT->hasEmptyExceptionSpec() || CPT->getNumArgs() > 1) {
AllNoThrow = false;
break;
}
if (RD->hasTrivialConstructor())
return true;
- if (CXXConstructorDecl *Constructor = RD->getDefaultConstructor()) {
- const FunctionProtoType *CPT
- = Constructor->getType()->getAs<FunctionProtoType>();
- // TODO: check whether evaluating default arguments can throw.
- // For now, we'll be conservative and assume that they can throw.
- if (CPT->hasEmptyExceptionSpec() && CPT->getNumArgs() == 0)
- return true;
+ DeclContext::lookup_const_iterator Con, ConEnd;
+ for (llvm::tie(Con, ConEnd) = Self.LookupConstructors(RD);
+ Con != ConEnd; ++Con) {
+ CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
+ if (Constructor->isDefaultConstructor()) {
+ const FunctionProtoType *CPT
+ = Constructor->getType()->getAs<FunctionProtoType>();
+ // TODO: check whether evaluating default arguments can throw.
+ // For now, we'll be conservative and assume that they can throw.
+ return CPT->hasEmptyExceptionSpec() && CPT->getNumArgs() == 0;
+ }
}
}
return false;
int t20[F(__has_nothrow_constructor(HasNoThrowConstructorWithArgs))];
int t21[F(__has_nothrow_constructor(void))];
int t22[F(__has_nothrow_constructor(cvoid))];
+ int t23[T(__has_nothrow_constructor(HasVirtDest))];
}
void has_virtual_destructor() {