summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/ASTContext.h5
-rw-r--r--clang/include/clang/AST/DeclObjC.h16
-rw-r--r--clang/lib/AST/ASTContext.cpp21
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp4
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp2
-rw-r--r--clang/lib/Frontend/PCHReaderDecl.cpp1
-rw-r--r--clang/lib/Frontend/RewriteObjC.cpp6
-rw-r--r--clang/lib/Sema/SemaDecl.cpp1
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp5
-rw-r--r--clang/test/CodeGenObjC/stand-alone-implementation.m16
10 files changed, 47 insertions, 30 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 2ed9fd70801..ec3fa2343e0 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -882,9 +882,8 @@ public:
llvm::SmallVectorImpl<FieldDecl*> &Fields);
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
- llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars,
- bool CollectSynthesized = true);
- void CollectSynthesizedIvars(const ObjCInterfaceDecl *OI,
+ llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+ void CollectNonClassIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
void CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index e562d352e07..686c1eb2f8b 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -494,11 +494,13 @@ public:
}
unsigned protocol_size() const { return ReferencedProtocols.size(); }
- typedef ObjCList<ObjCIvarDecl>::iterator ivar_iterator;
- ivar_iterator ivar_begin() const { return IVars.begin(); }
- ivar_iterator ivar_end() const { return IVars.end(); }
- unsigned ivar_size() const { return IVars.size(); }
- bool ivar_empty() const { return IVars.empty(); }
+ typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); }
+ ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); }
+ unsigned ivar_size() const {
+ return std::distance(ivar_begin(), ivar_end());
+ }
+ bool ivar_empty() const { return ivar_begin() == ivar_end(); }
/// setProtocolList - Set the list of protocols that this interface
/// implements.
@@ -514,10 +516,6 @@ public:
const SourceLocation *Locs,
ASTContext &C);
- void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) {
- IVars.set(List, Num, C);
- }
-
bool isForwardDecl() const { return ForwardDecl; }
void setForwardDecl(bool val) { ForwardDecl = val; }
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c23babb9a4a..74212fe785d 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -872,14 +872,13 @@ void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI,
/// Collect all ivars, including those synthesized, in the current class.
///
void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
- llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars,
- bool CollectSynthesized) {
+ llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
E = OI->ivar_end(); I != E; ++I) {
Ivars.push_back(*I);
}
- if (CollectSynthesized)
- CollectSynthesizedIvars(OI, Ivars);
+
+ CollectNonClassIvars(OI, Ivars);
}
void ASTContext::CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD,
@@ -895,10 +894,11 @@ void ASTContext::CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD,
CollectProtocolSynthesizedIvars(*P, Ivars);
}
-/// CollectSynthesizedIvars -
-/// This routine collect synthesized ivars for the designated class.
+/// CollectNonClassIvars -
+/// This routine collects all other ivars which are not declared in the class.
+/// This includes synthesized ivars and those in class's implementation.
///
-void ASTContext::CollectSynthesizedIvars(const ObjCInterfaceDecl *OI,
+void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(),
E = OI->prop_end(); I != E; ++I) {
@@ -912,6 +912,13 @@ void ASTContext::CollectSynthesizedIvars(const ObjCInterfaceDecl *OI,
ObjCProtocolDecl *PD = (*P);
CollectProtocolSynthesizedIvars(PD, Ivars);
}
+
+ // Also add any ivar defined in this class's implementation
+ if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) {
+ for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
+ E = ImplDecl->ivar_end(); I != E; ++I)
+ Ivars.push_back(*I);
+ }
}
/// CollectInheritedProtocols - Collect all protocols in current class and
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 50acd15fde0..10c5089f225 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -487,6 +487,7 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
FinishLayout();
}
+// FIXME. Impl is no longer needed.
void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl) {
if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
@@ -508,10 +509,9 @@ void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D,
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
UpdateAlignment(AA->getMaxAlignment());
-
// Layout each ivar sequentially.
llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
- Ctx.ShallowCollectObjCIvars(D, Ivars, Impl);
+ Ctx.ShallowCollectObjCIvars(D, Ivars);
for (unsigned i = 0, e = Ivars.size(); i != e; ++i)
LayoutField(Ivars[i]);
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index b16a510f98f..5f9c51813ad 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -3293,7 +3293,7 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
// Add this implementations synthesized ivars.
llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
- CGM.getContext().CollectSynthesizedIvars(OI, Ivars);
+ CGM.getContext().CollectNonClassIvars(OI, Ivars);
for (unsigned k = 0, e = Ivars.size(); k != e; ++k)
RecFields.push_back(cast<FieldDecl>(Ivars[k]));
diff --git a/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp
index cadc5427658..af69664fe1f 100644
--- a/clang/lib/Frontend/PCHReaderDecl.cpp
+++ b/clang/lib/Frontend/PCHReaderDecl.cpp
@@ -235,7 +235,6 @@ void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
IVars.reserve(NumIvars);
for (unsigned I = 0; I != NumIvars; ++I)
IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
- ID->setIVarList(IVars.data(), NumIvars, *Reader.getContext());
ID->setCategoryList(
cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
ID->setForwardDecl(Record[Idx++]);
diff --git a/clang/lib/Frontend/RewriteObjC.cpp b/clang/lib/Frontend/RewriteObjC.cpp
index 5d99491cd6a..fff8b54ba6c 100644
--- a/clang/lib/Frontend/RewriteObjC.cpp
+++ b/clang/lib/Frontend/RewriteObjC.cpp
@@ -3534,12 +3534,12 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
ObjCInterfaceDecl::ivar_iterator IVI, IVE;
llvm::SmallVector<ObjCIvarDecl *, 8> IVars;
if (!IDecl->ivar_empty()) {
- for (ObjCImplementationDecl::ivar_iterator
+ for (ObjCInterfaceDecl::ivar_iterator
IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end();
IV != IVEnd; ++IV)
IVars.push_back(*IV);
- IVI = IVars.begin();
- IVE = IVars.end();
+ IVI = IDecl->ivar_begin();
+ IVE = IDecl->ivar_end();
} else {
IVI = CDecl->ivar_begin();
IVE = CDecl->ivar_end();
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 949669aa572..847602d8027 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5641,7 +5641,6 @@ void Sema::ActOnFields(Scope* S,
ObjCIvarDecl **ClsFields =
reinterpret_cast<ObjCIvarDecl**>(RecFields.data());
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl)) {
- ID->setIVarList(ClsFields, RecFields.size(), Context);
ID->setLocEnd(RBrac);
// Add ivar's to class's DeclContext.
for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index a7e0145a521..cd64e664816 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -821,12 +821,12 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
/// (legacy objective-c @implementation decl without an @interface decl).
/// Add implementations's ivar to the synthesize class's ivar list.
if (IDecl->isImplicitInterfaceDecl()) {
- IDecl->setIVarList(ivars, numIvars, Context);
IDecl->setLocEnd(RBrace);
// Add ivar's to class's DeclContext.
for (unsigned i = 0, e = numIvars; i != e; ++i) {
ivars[i]->setLexicalDeclContext(ImpDecl);
IDecl->makeDeclVisibleInContext(ivars[i], false);
+ ImpDecl->addDecl(ivars[i]);
}
return;
@@ -2446,8 +2446,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
PropertyIvar, PropType, /*Dinfo=*/0,
ObjCIvarDecl::Public,
(Expr *)0);
- Ivar->setLexicalDeclContext(IDecl);
- IDecl->addDecl(Ivar);
+ IDecl->makeDeclVisibleInContext(Ivar, false);
property->setPropertyIvarDecl(Ivar);
if (!getLangOptions().ObjCNonFragileABI)
Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId;
diff --git a/clang/test/CodeGenObjC/stand-alone-implementation.m b/clang/test/CodeGenObjC/stand-alone-implementation.m
new file mode 100644
index 00000000000..a51949578b3
--- /dev/null
+++ b/clang/test/CodeGenObjC/stand-alone-implementation.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-X86-64 %s
+
+// radar 7547942
+// Allow injection of ivars into implementation's implicit class.
+
+@implementation INTFSTANDALONE // expected-warning {{cannot find interface declaration for 'INTFSTANDALONE'}}
+{
+ id IVAR1;
+ id IVAR2;
+}
+- (id) Meth { return IVAR1; }
+@end
+
+// CHECK-X86-64: @"OBJC_IVAR_$_INTFSTANDALONE.IVAR1"
+// CHECK-X86-64: @"OBJC_IVAR_$_INTFSTANDALONE.IVAR2"
+
OpenPOWER on IntegriCloud