diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTConsumer.cpp | 3 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 30 | ||||
-rw-r--r-- | lib/AST/ASTImporter.cpp | 14 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 26 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 13 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 11 |
6 files changed, 78 insertions, 19 deletions
diff --git a/lib/AST/ASTConsumer.cpp b/lib/AST/ASTConsumer.cpp index f37cbdea54..04a084a06a 100644 --- a/lib/AST/ASTConsumer.cpp +++ b/lib/AST/ASTConsumer.cpp @@ -17,3 +17,6 @@ using namespace clang; void ASTConsumer::HandleTopLevelDecl(DeclGroupRef D) {} +void ASTConsumer::HandleInterestingDecl(DeclGroupRef D) { + HandleTopLevelDecl(D); +} diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 7d159269c1..83cee5cc78 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -872,7 +872,7 @@ void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI, /// CollectNonClassIvars - /// This routine collects all other ivars which are not declared in the class. /// This includes synthesized ivars (via @synthesize) and those in -// class's @implementation. +/// class's @implementation. /// void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI, llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) { @@ -2212,18 +2212,24 @@ QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) { return QualType(QType, 0); } -/// getObjCInterfaceType - Return the unique reference to the type for the -/// specified ObjC interface decl. The list of protocols is optional. -QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) { - if (Decl->TypeForDecl) - return QualType(Decl->TypeForDecl, 0); +QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl, + const ObjCInterfaceDecl *PrevDecl) { + assert(Decl && "Passed null for Decl param"); - // FIXME: redeclarations? - void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment); - ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl); - Decl->TypeForDecl = T; - Types.push_back(T); - return QualType(T, 0); + if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); + + if (PrevDecl) { + assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl"); + Decl->TypeForDecl = PrevDecl->TypeForDecl; + return QualType(PrevDecl->TypeForDecl, 0); + } + + assert(!Decl->getPreviousDeclaration() && + "interface has previous declaration"); + + Decl->TypeForDecl = new (*this, TypeAlignment) ObjCInterfaceType(Decl); + Types.push_back(Decl->TypeForDecl); + return QualType(Decl->TypeForDecl, 0); } /// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 5e8586f2a0..6242d40041 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -2467,6 +2467,18 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) { } Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { + // If this interface has a definition in the translation unit we're coming + // from, but this particular declaration is not that definition, import the + // definition and map to that. + ObjCInterfaceDecl *Definition = D->getDefinition(); + if (Definition && Definition != D) { + Decl *ImportedDef = Importer.Import(Definition); + if (!ImportedDef) + return 0; + + return Importer.Imported(D, ImportedDef); + } + // Import the major distinguishing characteristics of an @interface. DeclContext *DC, *LexicalDC; DeclarationName Name; @@ -2491,7 +2503,7 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC, Loc, Name.getAsIdentifierInfo(), - Importer.Import(D->getClassLoc()), + Importer.Import(D->getClassLoc()), 0, D->isForwardDecl(), D->isImplicitInterfaceDecl()); ToIface->setForwardDecl(D->isForwardDecl()); diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 32f9433d9a..0720b203d6 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -45,6 +45,14 @@ void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts, // ObjCInterfaceDecl //===----------------------------------------------------------------------===// +ObjCInterfaceDecl *ObjCInterfaceDecl::getDefinition() { + for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) { + if (I->isDefinition()) + return *I; + } + return 0; +} + /// getIvarDecl - This method looks up an ivar in this ContextDecl. /// ObjCIvarDecl * @@ -432,18 +440,30 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, SourceLocation atLoc, IdentifierInfo *Id, SourceLocation ClassLoc, + ObjCInterfaceDecl *PrevDecl, bool ForwardDecl, bool isInternal){ - return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl, - isInternal); + ObjCInterfaceDecl *D = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, + PrevDecl, ForwardDecl, + isInternal); + C.getObjCInterfaceType(D, PrevDecl); + return D; +} + +ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, EmptyShell) { + return new (C) ObjCInterfaceDecl(0, SourceLocation(), 0, SourceLocation(), + 0, false, false); } ObjCInterfaceDecl:: ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, - SourceLocation CLoc, bool FD, bool isInternal) + SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, + bool FD, bool isInternal) : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id), TypeForDecl(0), SuperClass(0), CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal), ClassLoc(CLoc) { + if (PrevDecl) + setPreviousDeclaration(PrevDecl); } ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const { diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index fae1e724a1..d3ebc8f508 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -727,12 +727,19 @@ void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) { void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) { std::string I = OID->getNameAsString(); + + if (OID->isForwardDecl()) { + // These shouldn't be directly visited, but in case they are, write them + // as an @class declaration. + Out << "@class " << I; + return; + } + ObjCInterfaceDecl *SID = OID->getSuperClass(); + Out << "@interface " << I; if (SID) - Out << "@interface " << I << " : " << SID; - else - Out << "@interface " << I; + Out << " : " << SID; // Protocols? const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols(); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 31af6fb661..4f884989ae 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -360,6 +360,17 @@ const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const { return 0; } +ObjCInterfaceDecl *ObjCInterfaceType::getDecl() const { + for (ObjCInterfaceDecl::redecl_iterator I = Decl->redecls_begin(), + E = Decl->redecls_end(); + I != E; ++I) { + if (I->isDefinition()) + return *I; + } + // If we can't find a definition, return whatever we have. + return Decl; +} + const CXXRecordDecl *Type::getCXXRecordDeclForPointerType() const { if (const PointerType *PT = getAs<PointerType>()) if (const RecordType *RT = PT->getPointeeType()->getAs<RecordType>()) |