bool ForwardDecl:1; // declared with @class.
bool InternalInterface:1; // true - no @interface for @implementation
-
+
+ /// \brief Indicates that the contents of this Objective-C class will be
+ /// completed by the external AST source when required.
+ mutable bool ExternallyCompleted : 1;
+
SourceLocation ClassLoc; // location of the class identifier.
SourceLocation SuperClassLoc; // location of the super class identifier.
SourceLocation EndLoc; // marks the '>', '}', or identifier.
ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
SourceLocation CLoc, bool FD, bool isInternal);
+ void LoadExternalDefinition() const;
public:
static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation atLoc,
SourceLocation ClassLoc = SourceLocation(),
bool ForwardDecl = false,
bool isInternal = false);
+
+ /// \brief Indicate that this Objective-C class is complete, but that
+ /// the external AST source will be responsible for filling in its contents
+ /// when a complete class is required.
+ void setExternallyCompleted();
+
const ObjCProtocolList &getReferencedProtocols() const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
return ReferencedProtocols;
}
typedef ObjCProtocolList::iterator protocol_iterator;
protocol_iterator protocol_begin() const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
return ReferencedProtocols.begin();
}
protocol_iterator protocol_end() const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
return ReferencedProtocols.end();
}
typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
protocol_loc_iterator protocol_loc_begin() const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
return ReferencedProtocols.loc_begin();
}
protocol_loc_iterator protocol_loc_end() const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
return ReferencedProtocols.loc_end();
}
typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
all_protocol_iterator all_referenced_protocol_begin() const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
return AllReferencedProtocols.empty() ? protocol_begin()
: AllReferencedProtocols.begin();
}
all_protocol_iterator all_referenced_protocol_end() const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
return AllReferencedProtocols.empty() ? protocol_end()
: AllReferencedProtocols.end();
}
bool isForwardDecl() const { return ForwardDecl; }
void setForwardDecl(bool val) { ForwardDecl = val; }
- ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
+ ObjCInterfaceDecl *getSuperClass() const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
+ return SuperClass;
+ }
+
void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
- ObjCCategoryDecl* getCategoryList() const { return CategoryList; }
+ ObjCCategoryDecl* getCategoryList() const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
+ return CategoryList;
+ }
+
void setCategoryList(ObjCCategoryDecl *category) {
CategoryList = category;
}
ObjCPropertyDecl *
ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
IdentifierInfo *PropertyId) const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
if (ObjCPropertyDecl *PD =
ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
return PD;
ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
ASTContext &C)
{
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
if (AllReferencedProtocols.empty() && ReferencedProtocols.empty()) {
AllReferencedProtocols.set(ExtList, ExtNum, C);
return;
const ObjCInterfaceDecl* ClassDecl = this;
ObjCMethodDecl *MethodDecl = 0;
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
while (ClassDecl != NULL) {
if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
return MethodDecl;
: ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
TypeForDecl(0), SuperClass(0),
CategoryList(0), IvarList(0),
- ForwardDecl(FD), InternalInterface(isInternal),
+ ForwardDecl(FD), InternalInterface(isInternal), ExternallyCompleted(false),
ClassLoc(CLoc) {
}
+void ObjCInterfaceDecl::LoadExternalDefinition() const {
+ assert(ExternallyCompleted && "Class is not externally completed");
+ ExternallyCompleted = false;
+ getASTContext().getExternalSource()->CompleteType(
+ const_cast<ObjCInterfaceDecl *>(this));
+}
+
+void ObjCInterfaceDecl::setExternallyCompleted() {
+ assert(getASTContext().getExternalSource() &&
+ "Class can't be externally completed without an external source");
+ assert(!ForwardDecl &&
+ "Forward declarations can't be externally completed");
+ ExternallyCompleted = true;
+}
+
ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
return getASTContext().getObjCImplementation(
const_cast<ObjCInterfaceDecl*>(this));
}
///
ObjCCategoryDecl *
ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
+ if (ExternallyCompleted)
+ LoadExternalDefinition();
+
for (ObjCCategoryDecl *Category = getCategoryList();
Category; Category = Category->getNextClassCategory())
if (Category->getIdentifier() == CategoryId)