diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-05-20 02:24:22 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-05-20 02:24:22 +0000 |
| commit | 527786ea3a6a9baf88efbd188fe1cc258e5bda48 (patch) | |
| tree | 18e77e0548e3ce7f772297b28e0b0fc7f0481f09 /clang/lib | |
| parent | bd7b3ccbf8d5e6c3ff210c0eedf0a913a5ed90f8 (diff) | |
| download | bcm5719-llvm-527786ea3a6a9baf88efbd188fe1cc258e5bda48.tar.gz bcm5719-llvm-527786ea3a6a9baf88efbd188fe1cc258e5bda48.zip | |
Various small fixes for construction/destruction of Objective-C++
instance variables:
- Use isRecordType() rather than isa<RecordType>(), so that we see
through typedefs in ivar types.
- Mark the destructor as referenced
- Perform C++ access control on the destructor
llvm-svn: 104206
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 17 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 10 |
3 files changed, 28 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 6682c661167..8cbe92af404 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -6190,6 +6190,9 @@ void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit; for (unsigned i = 0; i < ivars.size(); i++) { FieldDecl *Field = ivars[i]; + if (Field->isInvalidDecl()) + continue; + CXXBaseOrMemberInitializer *Member; InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field); InitializationKind InitKind = @@ -6212,6 +6215,20 @@ void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { MemberInit.takeAs<Expr>(), SourceLocation()); AllToInit.push_back(Member); + + // Be sure that the destructor is accessible and is marked as referenced. + if (const RecordType *RecordTy + = Context.getBaseElementType(Field->getType()) + ->getAs<RecordType>()) { + CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); + if (CXXDestructorDecl *Destructor + = const_cast<CXXDestructorDecl*>(RD->getDestructor(Context))) { + MarkDeclarationReferenced(Field->getLocation(), Destructor); + CheckDestructorAccess(Field->getLocation(), Destructor, + PDiag(diag::err_access_dtor_ivar) + << Context.getBaseElementType(Field->getType())); + } + } } ObjCImplementation->setIvarInitializers(Context, AllToInit.data(), AllToInit.size()); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index b166d873404..ef43c051f7b 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1812,7 +1812,7 @@ void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI, E = OI->ivar_end(); I != E; ++I) { ObjCIvarDecl *Iv = (*I); QualType QT = Context.getBaseElementType(Iv->getType()); - if (isa<RecordType>(QT)) + if (QT->isRecordType()) Ivars.push_back(*I); } @@ -1822,7 +1822,7 @@ void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI, E = CDecl->ivar_end(); I != E; ++I) { ObjCIvarDecl *Iv = (*I); QualType QT = Context.getBaseElementType(Iv->getType()); - if (isa<RecordType>(QT)) + if (QT->isRecordType()) Ivars.push_back(*I); } } @@ -1834,7 +1834,7 @@ void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI, E = ImplDecl->ivar_end(); I != E; ++I) { ObjCIvarDecl *Iv = (*I); QualType QT = Context.getBaseElementType(Iv->getType()); - if (isa<RecordType>(QT)) + if (QT->isRecordType()) Ivars.push_back(*I); } } diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 774a82b7c74..d876e6047e7 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1626,15 +1626,21 @@ addAssociatedClassesAndNamespaces(QualType T, // member, if any; and its direct and indirect base // classes. Its associated namespaces are the namespaces in // which its associated classes are defined. - if (const RecordType *ClassType = T->getAs<RecordType>()) + if (const RecordType *ClassType = T->getAs<RecordType>()) { if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(ClassType->getDecl())) { + // The __builtin_va_list type does not participate in ADL. + if (ClassDecl->getIdentifier() && + ClassDecl->getIdentifier()->isStr("__va_list_tag")) + return; + addAssociatedClassesAndNamespaces(ClassDecl, Context, AssociatedNamespaces, AssociatedClasses); return; } - + } + // -- If T is an enumeration type, its associated namespace is // the namespace in which it is defined. If it is class // member, its associated class is the member’s class; else |

