summaryrefslogtreecommitdiffstats
path: root/lib/AST/DeclObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/DeclObjC.cpp')
-rw-r--r--lib/AST/DeclObjC.cpp183
1 files changed, 89 insertions, 94 deletions
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index adb0e7d..d952cc3 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -21,14 +21,8 @@ using namespace clang;
// ObjCListBase
//===----------------------------------------------------------------------===//
-void ObjCListBase::Destroy(ASTContext &Ctx) {
- Ctx.Deallocate(List);
- NumElts = 0;
- List = 0;
-}
-
void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
- assert(List == 0 && "Elements already set!");
+ List = 0;
if (Elts == 0) return; // Setting to an empty list is a noop.
@@ -47,12 +41,6 @@ void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
set(InList, Elts, Ctx);
}
-void ObjCProtocolList::Destroy(ASTContext &Ctx) {
- Ctx.Deallocate(Locations);
- Locations = 0;
- ObjCList<ObjCProtocolDecl>::Destroy(Ctx);
-}
-
//===----------------------------------------------------------------------===//
// ObjCInterfaceDecl
//===----------------------------------------------------------------------===//
@@ -132,8 +120,9 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
return P;
// Look through protocols.
- for (ObjCInterfaceDecl::protocol_iterator
- I = OID->protocol_begin(), E = OID->protocol_end(); I != E; ++I)
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ I = OID->all_referenced_protocol_begin(),
+ E = OID->all_referenced_protocol_end(); I != E; ++I)
if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
return P;
@@ -169,8 +158,9 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
return PD;
// Look through protocols.
- for (ObjCInterfaceDecl::protocol_iterator
- I = protocol_begin(), E = protocol_end(); I != E; ++I)
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ I = all_referenced_protocol_begin(),
+ E = all_referenced_protocol_end(); I != E; ++I)
if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
return P;
@@ -179,23 +169,23 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
- const SourceLocation *Locs,
ASTContext &C)
{
- if (ReferencedProtocols.empty()) {
- ReferencedProtocols.set(ExtList, ExtNum, Locs, C);
+ if (AllReferencedProtocols.empty() && ReferencedProtocols.empty()) {
+ AllReferencedProtocols.set(ExtList, ExtNum, C);
return;
}
+
// Check for duplicate protocol in class's protocol list.
- // This is (O)2. But it is extremely rare and number of protocols in
+ // This is O(n*m). But it is extremely rare and number of protocols in
// class or its extension are very few.
llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
- llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
for (unsigned i = 0; i < ExtNum; i++) {
bool protocolExists = false;
ObjCProtocolDecl *ProtoInExtension = ExtList[i];
- for (protocol_iterator p = protocol_begin(), e = protocol_end();
- p != e; p++) {
+ for (all_protocol_iterator
+ p = all_referenced_protocol_begin(),
+ e = all_referenced_protocol_end(); p != e; ++p) {
ObjCProtocolDecl *Proto = (*p);
if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
protocolExists = true;
@@ -204,23 +194,20 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
}
// Do we want to warn on a protocol in extension class which
// already exist in the class? Probably not.
- if (!protocolExists) {
+ if (!protocolExists)
ProtocolRefs.push_back(ProtoInExtension);
- ProtocolLocs.push_back(Locs[i]);
- }
}
+
if (ProtocolRefs.empty())
return;
+
// Merge ProtocolRefs into class's protocol list;
- protocol_loc_iterator pl = protocol_loc_begin();
- for (protocol_iterator p = protocol_begin(), e = protocol_end();
- p != e; ++p, ++pl) {
+ for (all_protocol_iterator p = all_referenced_protocol_begin(),
+ e = all_referenced_protocol_end(); p != e; ++p) {
ProtocolRefs.push_back(*p);
- ProtocolLocs.push_back(*pl);
}
- ReferencedProtocols.Destroy(C);
- unsigned NumProtoRefs = ProtocolRefs.size();
- setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C);
+
+ AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(), C);
}
/// getFirstClassExtension - Find first class extension of the given class.
@@ -339,27 +326,17 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
bool isInstance,
bool isVariadic,
bool isSynthesized,
+ bool isDefined,
ImplementationControl impControl,
unsigned numSelectorArgs) {
return new (C) ObjCMethodDecl(beginLoc, endLoc,
SelInfo, T, ResultTInfo, contextDecl,
isInstance,
- isVariadic, isSynthesized, impControl,
+ isVariadic, isSynthesized, isDefined,
+ impControl,
numSelectorArgs);
}
-void ObjCMethodDecl::Destroy(ASTContext &C) {
- if (Body) Body->Destroy(C);
- if (SelfDecl) SelfDecl->Destroy(C);
-
- for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
- if (*I) (*I)->Destroy(C);
-
- ParamInfo.Destroy(C);
-
- Decl::Destroy(C);
-}
-
/// \brief A definition will return its interface declaration.
/// An interface declaration will return its definition.
/// Otherwise it will return itself.
@@ -465,22 +442,11 @@ ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
SourceLocation CLoc, bool FD, bool isInternal)
: ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
TypeForDecl(0), SuperClass(0),
- CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
+ CategoryList(0), IvarList(0),
+ ForwardDecl(FD), InternalInterface(isInternal),
ClassLoc(CLoc) {
}
-void ObjCInterfaceDecl::Destroy(ASTContext &C) {
- for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
- if (*I) (*I)->Destroy(C);
-
- // FIXME: CategoryList?
-
- // FIXME: Because there is no clear ownership
- // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
- // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
- Decl::Destroy(C);
-}
-
ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
return getASTContext().getObjCImplementation(
const_cast<ObjCInterfaceDecl*>(this));
@@ -490,6 +456,49 @@ void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
getASTContext().setObjCImplementation(this, ImplD);
}
+/// all_declared_ivar_begin - return first ivar declared in this class,
+/// its extensions and its implementation. Lazily build the list on first
+/// access.
+ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
+ if (IvarList)
+ return IvarList;
+
+ ObjCIvarDecl *curIvar = 0;
+ if (!ivar_empty()) {
+ ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
+ IvarList = (*I); ++I;
+ for (curIvar = IvarList; I != E; curIvar = *I, ++I)
+ curIvar->setNextIvar(*I);
+ }
+
+ for (const ObjCCategoryDecl *CDecl = getFirstClassExtension(); CDecl;
+ CDecl = CDecl->getNextClassExtension()) {
+ if (!CDecl->ivar_empty()) {
+ ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
+ E = CDecl->ivar_end();
+ if (!IvarList) {
+ IvarList = (*I); ++I;
+ curIvar = IvarList;
+ }
+ for ( ;I != E; curIvar = *I, ++I)
+ curIvar->setNextIvar(*I);
+ }
+ }
+
+ if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
+ if (!ImplDecl->ivar_empty()) {
+ ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
+ E = ImplDecl->ivar_end();
+ if (!IvarList) {
+ IvarList = (*I); ++I;
+ curIvar = IvarList;
+ }
+ for ( ;I != E; curIvar = *I, ++I)
+ curIvar->setNextIvar(*I);
+ }
+ }
+ return IvarList;
+}
/// FindCategoryDeclaration - Finds category declaration in the list of
/// categories for this class and returns it. Name of the category is passed
@@ -575,7 +584,8 @@ bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
- AccessControl ac, Expr *BW) {
+ AccessControl ac, Expr *BW,
+ bool synthesized) {
if (DC) {
// Ivar's can only appear in interfaces, implementations (via synthesized
// properties), and class extensions (via direct declaration, or synthesized
@@ -590,9 +600,26 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
isa<ObjCCategoryDecl>(DC)) &&
"Invalid ivar decl context!");
+ // Once a new ivar is created in any of class/class-extension/implementation
+ // decl contexts, the previously built IvarList must be rebuilt.
+ ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
+ if (!ID) {
+ if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC)) {
+ ID = IM->getClassInterface();
+ if (BW)
+ IM->setHasSynthBitfield(true);
+ }
+ else {
+ ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
+ ID = CD->getClassInterface();
+ if (BW)
+ CD->setHasSynthBitfield(true);
+ }
+ }
+ ID->setIvarList(0);
}
- return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
+ return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW, synthesized);
}
const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
@@ -630,11 +657,6 @@ ObjCAtDefsFieldDecl
return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
}
-void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
- this->~ObjCAtDefsFieldDecl();
- C.Deallocate((void *)this);
-}
-
//===----------------------------------------------------------------------===//
// ObjCProtocolDecl
//===----------------------------------------------------------------------===//
@@ -645,11 +667,6 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) ObjCProtocolDecl(DC, L, Id);
}
-void ObjCProtocolDecl::Destroy(ASTContext &C) {
- ReferencedProtocols.Destroy(C);
- ObjCContainerDecl::Destroy(C);
-}
-
ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
ObjCProtocolDecl *PDecl = this;
@@ -709,23 +726,6 @@ ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C);
}
-void ObjCClassDecl::Destroy(ASTContext &C) {
- // ObjCInterfaceDecls registered with a DeclContext will get destroyed
- // when the DeclContext is destroyed. For those created only by a forward
- // declaration, the first @class that created the ObjCInterfaceDecl gets
- // to destroy it.
- // FIXME: Note that this ownership role is very brittle; a better
- // polict is surely need in the future.
- for (iterator I = begin(), E = end(); I !=E ; ++I) {
- ObjCInterfaceDecl *ID = I->getInterface();
- if (ID->isForwardDecl() && ID->getLocStart() == getLocStart())
- ID->Destroy(C);
- }
-
- C.Deallocate(ForwardDecls);
- Decl::Destroy(C);
-}
-
SourceRange ObjCClassDecl::getSourceRange() const {
// FIXME: We should include the semicolon
assert(NumDecls);
@@ -754,11 +754,6 @@ ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C);
}
-void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
- ReferencedProtocols.Destroy(C);
- Decl::Destroy(C);
-}
-
//===----------------------------------------------------------------------===//
// ObjCCategoryDecl
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud