diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-12-01 23:49:52 +0000 | 
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-12-01 23:49:52 +0000 | 
| commit | 73693023f0ad317deee8eeabac4dc0f7e8903b0f (patch) | |
| tree | 16911b45fe184745e215bb5d1fcd5563615433bc /clang/lib/AST | |
| parent | 560befce3863eadaa1345dc0ee1bf0202fcb3489 (diff) | |
| download | bcm5719-llvm-73693023f0ad317deee8eeabac4dc0f7e8903b0f.tar.gz bcm5719-llvm-73693023f0ad317deee8eeabac4dc0f7e8903b0f.zip  | |
Extend ExternalASTSource with the ability to lazily complete the
definition of an Objective-C class. Unlike with C/C++ classes, we
don't have a well-defined point in Sema where Objective-C classes are
checked for completeness, nor do we need to involve Sema when
completing a class. Therefore, we take the appropriate of having the
external AST source mark a particular Objective-C class as having an
external declaration; when using one of the accessors of an
Objective-C class that has an external declaration, we request that
the external AST source fill in the Objective-C class definition.
llvm-svn: 120627
Diffstat (limited to 'clang/lib/AST')
| -rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 32 | 
1 files changed, 31 insertions, 1 deletions
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 5e57cf87b9e..ea8fd4ae89d 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -153,6 +153,9 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {  ObjCPropertyDecl *  ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(                                              IdentifierInfo *PropertyId) const { +  if (ExternallyCompleted) +    LoadExternalDefinition(); +    if (ObjCPropertyDecl *PD =        ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))      return PD; @@ -171,6 +174,9 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList(                                ObjCProtocolDecl *const* ExtList, unsigned ExtNum,                                ASTContext &C)  { +  if (ExternallyCompleted) +    LoadExternalDefinition(); +    if (AllReferencedProtocols.empty() && ReferencedProtocols.empty()) {      AllReferencedProtocols.set(ExtList, ExtNum, C);      return; @@ -270,6 +276,9 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,    const ObjCInterfaceDecl* ClassDecl = this;    ObjCMethodDecl *MethodDecl = 0; +  if (ExternallyCompleted) +    LoadExternalDefinition(); +    while (ClassDecl != NULL) {      if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))        return MethodDecl; @@ -443,11 +452,29 @@ ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,    : 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));  } @@ -506,6 +533,9 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {  ///  ObjCCategoryDecl *  ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const { +  if (ExternallyCompleted) +    LoadExternalDefinition(); +    for (ObjCCategoryDecl *Category = getCategoryList();         Category; Category = Category->getNextClassCategory())      if (Category->getIdentifier() == CategoryId)  | 

