summaryrefslogtreecommitdiffstats
path: root/lib/AST/DeclCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/DeclCXX.cpp')
-rw-r--r--lib/AST/DeclCXX.cpp94
1 files changed, 68 insertions, 26 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index ed26c52..a6d9d41 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -209,7 +209,7 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
// Now go through all virtual bases of this base and add them.
for (const auto &VBase : BaseClassDecl->vbases()) {
// Add this base if it's not already in the list.
- if (SeenVBaseTypes.insert(C.getCanonicalType(VBase.getType()))) {
+ if (SeenVBaseTypes.insert(C.getCanonicalType(VBase.getType())).second) {
VBases.push_back(&VBase);
// C++11 [class.copy]p8:
@@ -225,7 +225,7 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
if (Base->isVirtual()) {
// Add this base if it's not already in the list.
- if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)))
+ if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)).second)
VBases.push_back(Base);
// C++0x [meta.unary.prop] is_empty:
@@ -677,17 +677,24 @@ void CXXRecordDecl::addedMember(Decl *D) {
//
// Automatic Reference Counting: the presence of a member of Objective-C pointer type
// that does not explicitly have no lifetime makes the class a non-POD.
- // However, we delay setting PlainOldData to false in this case so that
- // Sema has a chance to diagnostic causes where the same class will be
- // non-POD with Automatic Reference Counting but a POD without ARC.
- // In this case, the class will become a non-POD class when we complete
- // the definition.
ASTContext &Context = getASTContext();
QualType T = Context.getBaseElementType(Field->getType());
if (T->isObjCRetainableType() || T.isObjCGCStrong()) {
- if (!Context.getLangOpts().ObjCAutoRefCount ||
- T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone)
+ if (!Context.getLangOpts().ObjCAutoRefCount) {
setHasObjectMember(true);
+ } else if (T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {
+ // Objective-C Automatic Reference Counting:
+ // If a class has a non-static data member of Objective-C pointer
+ // type (or array thereof), it is a non-POD type and its
+ // default constructor (if any), copy constructor, move constructor,
+ // copy assignment operator, move assignment operator, and destructor are
+ // non-trivial.
+ setHasObjectMember(true);
+ struct DefinitionData &Data = data();
+ Data.PlainOldData = false;
+ Data.HasTrivialSpecialMembers = 0;
+ Data.HasIrrelevantDestructor = false;
+ }
} else if (!T.isCXX98PODType(Context))
data().PlainOldData = false;
@@ -720,7 +727,7 @@ void CXXRecordDecl::addedMember(Decl *D) {
// brace-or-equal-initializers for non-static data members.
//
// This rule was removed in C++1y.
- if (!getASTContext().getLangOpts().CPlusPlus1y)
+ if (!getASTContext().getLangOpts().CPlusPlus14)
data().Aggregate = false;
// C++11 [class]p10:
@@ -1254,6 +1261,44 @@ CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
llvm_unreachable("Not a class template or member class specialization");
}
+const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const {
+ // If it's a class template specialization, find the template or partial
+ // specialization from which it was instantiated.
+ if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
+ auto From = TD->getInstantiatedFrom();
+ if (auto *CTD = From.dyn_cast<ClassTemplateDecl *>()) {
+ while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
+ if (NewCTD->isMemberSpecialization())
+ break;
+ CTD = NewCTD;
+ }
+ return CTD->getTemplatedDecl();
+ }
+ if (auto *CTPSD =
+ From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
+ while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) {
+ if (NewCTPSD->isMemberSpecialization())
+ break;
+ CTPSD = NewCTPSD;
+ }
+ return CTPSD;
+ }
+ }
+
+ if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
+ if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) {
+ const CXXRecordDecl *RD = this;
+ while (auto *NewRD = RD->getInstantiatedFromMemberClass())
+ RD = NewRD;
+ return RD;
+ }
+ }
+
+ assert(!isTemplateInstantiation(this->getTemplateSpecializationKind()) &&
+ "couldn't find pattern for class template instantiation");
+ return nullptr;
+}
+
CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
ASTContext &Context = getASTContext();
QualType ClassType = Context.getTypeDeclType(this);
@@ -1277,19 +1322,6 @@ void CXXRecordDecl::completeDefinition() {
void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
RecordDecl::completeDefinition();
- if (hasObjectMember() && getASTContext().getLangOpts().ObjCAutoRefCount) {
- // Objective-C Automatic Reference Counting:
- // If a class has a non-static data member of Objective-C pointer
- // type (or array thereof), it is a non-POD type and its
- // default constructor (if any), copy constructor, move constructor,
- // copy assignment operator, move assignment operator, and destructor are
- // non-trivial.
- struct DefinitionData &Data = data();
- Data.PlainOldData = false;
- Data.HasTrivialSpecialMembers = 0;
- Data.HasIrrelevantDestructor = false;
- }
-
// If the class may be abstract (but hasn't been marked as such), check for
// any pure final overriders.
if (mayBeAbstract()) {
@@ -1799,7 +1831,6 @@ bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {
bool CXXConstructorDecl::isSpecializationCopyingObject() const {
if ((getNumParams() < 1) ||
(getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
- (getPrimaryTemplate() == nullptr) ||
(getDescribedFunctionTemplate() != nullptr))
return false;
@@ -1970,6 +2001,16 @@ NamespaceDecl *NamespaceDecl::getMostRecentDeclImpl() {
void NamespaceAliasDecl::anchor() { }
+NamespaceAliasDecl *NamespaceAliasDecl::getNextRedeclarationImpl() {
+ return getNextRedeclaration();
+}
+NamespaceAliasDecl *NamespaceAliasDecl::getPreviousDeclImpl() {
+ return getPreviousDecl();
+}
+NamespaceAliasDecl *NamespaceAliasDecl::getMostRecentDeclImpl() {
+ return getMostRecentDecl();
+}
+
NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation UsingLoc,
SourceLocation AliasLoc,
@@ -1977,15 +2018,16 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation IdentLoc,
NamedDecl *Namespace) {
+ // FIXME: Preserve the aliased namespace as written.
if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
Namespace = NS->getOriginalNamespace();
- return new (C, DC) NamespaceAliasDecl(DC, UsingLoc, AliasLoc, Alias,
+ return new (C, DC) NamespaceAliasDecl(C, DC, UsingLoc, AliasLoc, Alias,
QualifierLoc, IdentLoc, Namespace);
}
NamespaceAliasDecl *
NamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- return new (C, ID) NamespaceAliasDecl(nullptr, SourceLocation(),
+ return new (C, ID) NamespaceAliasDecl(C, nullptr, SourceLocation(),
SourceLocation(), nullptr,
NestedNameSpecifierLoc(),
SourceLocation(), nullptr);
OpenPOWER on IntegriCloud