From 3a039e339f1fc8a134b1d55cd6c4c6d387a81967 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 27 Aug 2011 20:50:59 +0000 Subject: [PATCH] objective-c: Treat top-level objective-c declarations , such as list of forward @class decls, in a DeclGroup node. Deal with its consequence throught clang. This is in preparation for more Sema work ahead. // rdar://8843851. Feel free to reverse if it breaks something important and I am unavailable. llvm-svn: 138709 --- clang/include/clang/AST/DeclObjC.h | 26 ++++------ clang/include/clang/Parse/Parser.h | 4 +- clang/include/clang/Sema/Sema.h | 2 +- clang/lib/AST/ASTImporter.cpp | 25 +++------- clang/lib/AST/DeclBase.cpp | 6 +-- clang/lib/AST/DeclObjC.cpp | 35 ++++++-------- clang/lib/AST/DeclPrinter.cpp | 6 +-- clang/lib/AST/DumpXML.cpp | 3 +- clang/lib/Frontend/ASTUnit.cpp | 4 +- clang/lib/Parse/ParseObjc.cpp | 38 ++++++++++----- clang/lib/Parse/Parser.cpp | 5 +- clang/lib/Rewrite/RewriteObjC.cpp | 53 +++++++++++---------- clang/lib/Sema/SemaCodeComplete.cpp | 11 ++--- clang/lib/Sema/SemaDeclObjC.cpp | 22 ++++----- clang/lib/Sema/SemaLookup.cpp | 5 +- clang/lib/Serialization/ASTReaderDecl.cpp | 22 +++------ clang/lib/Serialization/ASTWriterDecl.cpp | 15 +++--- clang/test/Rewriter/rewrite-forward-class.m | 29 ++++++++++- clang/tools/libclang/CIndex.cpp | 13 ++--- 19 files changed, 155 insertions(+), 169 deletions(-) diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 6f034434c428..e639606afbe2 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -918,29 +918,23 @@ public: ObjCInterfaceDecl *getInterface() const { return ID; } }; private: - ObjCClassRef *ForwardDecls; - unsigned NumDecls; + ObjCClassRef *ForwardDecl; ObjCClassDecl(DeclContext *DC, SourceLocation L, - ObjCInterfaceDecl *const *Elts, const SourceLocation *Locs, - unsigned nElts, ASTContext &C); + ObjCInterfaceDecl *const Elt, const SourceLocation Loc, + ASTContext &C); public: static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - ObjCInterfaceDecl *const *Elts = 0, - const SourceLocation *Locs = 0, - unsigned nElts = 0); + ObjCInterfaceDecl *const Elt = 0, + const SourceLocation Locs = SourceLocation()); + + ObjCInterfaceDecl *getForwardInterfaceDecl() { return ForwardDecl->getInterface(); } + ObjCClassRef *getForwardDecl() { return ForwardDecl; } + void setClass(ASTContext &C, ObjCInterfaceDecl*const Cls, + const SourceLocation Locs); virtual SourceRange getSourceRange() const; - typedef const ObjCClassRef* iterator; - iterator begin() const { return ForwardDecls; } - iterator end() const { return ForwardDecls + NumDecls; } - unsigned size() const { return NumDecls; } - - /// setClassList - Set the list of forward classes. - void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, - const SourceLocation *Locs, unsigned Num); - static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const ObjCClassDecl *D) { return true; } static bool classofKind(Kind K) { return K == ObjCClass; } diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index e5a129beb3cc..f74a1e48d755 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1060,8 +1060,8 @@ private: ExprResult ParseAsmStringLiteral(); // Objective-C External Declarations - Decl *ParseObjCAtDirectives(); - Decl *ParseObjCAtClassDeclaration(SourceLocation atLoc); + Parser::DeclGroupPtrTy ParseObjCAtDirectives(); + Parser::DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc); Decl *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc, ParsedAttributes &prefixAttrs); void ParseObjCClassInstanceVariables(Decl *interfaceDecl, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 2e49840d0ec6..299480399b3d 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -5010,7 +5010,7 @@ public: IdentifierInfo *CatName, SourceLocation CatLoc); - Decl *ActOnForwardClassDeclaration(SourceLocation Loc, + DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, unsigned NumElts); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 8b8308a0f4bb..b6e3e621d567 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3529,25 +3529,14 @@ Decl *ASTNodeImporter::VisitObjCClassDecl(ObjCClassDecl *D) { // Import the location of this declaration. SourceLocation Loc = Importer.Import(D->getLocation()); - - SmallVector Interfaces; - SmallVector Locations; - for (ObjCClassDecl::iterator From = D->begin(), FromEnd = D->end(); - From != FromEnd; ++From) { - ObjCInterfaceDecl *ToIface - = cast_or_null(Importer.Import(From->getInterface())); - if (!ToIface) - continue; - - Interfaces.push_back(ToIface); - Locations.push_back(Importer.Import(From->getLocation())); - } - + ObjCClassDecl::ObjCClassRef *From = D->getForwardDecl(); + ObjCInterfaceDecl *ToIface + = cast_or_null(Importer.Import(From->getInterface())); ObjCClassDecl *ToClass = ObjCClassDecl::Create(Importer.getToContext(), DC, - Loc, - Interfaces.data(), - Locations.data(), - Interfaces.size()); + Loc, + ToIface, + Importer.Import(From->getLocation())); + ToClass->setLexicalDeclContext(LexicalDC); LexicalDC->addDecl(ToClass); Importer.Imported(D, ToClass); diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index cb5846fc838f..27e437c4a3e0 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -1030,12 +1030,10 @@ void DeclContext::buildLookup(DeclContext *DCtx) { if (D->getDeclContext() == DCtx) makeDeclVisibleInContextImpl(ND); - // Insert any forward-declared Objective-C interfaces into the lookup + // Insert any forward-declared Objective-C interface into the lookup // data structure. if (ObjCClassDecl *Class = dyn_cast(*D)) - for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end(); - I != IEnd; ++I) - makeDeclVisibleInContextImpl(I->getInterface()); + makeDeclVisibleInContextImpl(Class->getForwardInterfaceDecl()); // If this declaration is itself a transparent declaration context or // inline namespace, add its members (recursively). diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 813501f1ac99..367e6a66a432 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -851,36 +851,31 @@ ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel, //===----------------------------------------------------------------------===// ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L, - ObjCInterfaceDecl *const *Elts, - const SourceLocation *Locs, - unsigned nElts, + ObjCInterfaceDecl *const Elt, + const SourceLocation Loc, ASTContext &C) : Decl(ObjCClass, DC, L) { - setClassList(C, Elts, Locs, nElts); -} - -void ObjCClassDecl::setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, - const SourceLocation *Locs, unsigned Num) { - ForwardDecls = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef)*Num, - llvm::alignOf()); - for (unsigned i = 0; i < Num; ++i) - new (&ForwardDecls[i]) ObjCClassRef(List[i], Locs[i]); - - NumDecls = Num; + setClass(C, Elt, Loc); } ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, - ObjCInterfaceDecl *const *Elts, - const SourceLocation *Locs, - unsigned nElts) { - return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C); + ObjCInterfaceDecl *const Elt, + const SourceLocation Loc) { + return new (C) ObjCClassDecl(DC, L, Elt, Loc, C); } +void ObjCClassDecl::setClass(ASTContext &C, ObjCInterfaceDecl*const Cls, + const SourceLocation Loc) { + + ForwardDecl = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef), + llvm::alignOf()); + new (ForwardDecl) ObjCClassRef(Cls, Loc); +} + SourceRange ObjCClassDecl::getSourceRange() const { // FIXME: We should include the semicolon - assert(NumDecls); - return SourceRange(getLocation(), ForwardDecls[NumDecls-1].getLocation()); + return SourceRange(getLocation(), ForwardDecl->getLocation()); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index a1aff5d411c2..3a95d1342f71 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -812,11 +812,7 @@ void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) { void DeclPrinter::VisitObjCClassDecl(ObjCClassDecl *D) { Out << "@class "; - for (ObjCClassDecl::iterator I = D->begin(), E = D->end(); - I != E; ++I) { - if (I != D->begin()) Out << ", "; - Out << I->getInterface(); - } + Out << D->getForwardInterfaceDecl(); } void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) { diff --git a/clang/lib/AST/DumpXML.cpp b/clang/lib/AST/DumpXML.cpp index dd0147c5a344..2568adaa5a44 100644 --- a/clang/lib/AST/DumpXML.cpp +++ b/clang/lib/AST/DumpXML.cpp @@ -742,8 +742,7 @@ struct XMLDumper : public XMLDeclVisitor, // ObjCClassDecl void visitObjCClassDeclChildren(ObjCClassDecl *D) { - for (ObjCClassDecl::iterator I = D->begin(), E = D->end(); I != E; ++I) - visitDeclRef(I->getInterface()); + visitDeclRef(D->getForwardInterfaceDecl()); } // ObjCInterfaceDecl diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 7f25a0045e75..cc96d486b10b 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -707,9 +707,7 @@ void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) { } if (ObjCClassDecl *Class = dyn_cast(D)) { - for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end(); - I != IEnd; ++I) - AddTopLevelDeclarationToHash(I->getInterface(), Hash); + AddTopLevelDeclarationToHash(Class->getForwardInterfaceDecl(), Hash); return; } } diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 684d8edf8919..17c962e2b572 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -29,47 +29,59 @@ using namespace clang; /// [OBJC] objc-protocol-definition /// [OBJC] objc-method-definition /// [OBJC] '@' 'end' -Decl *Parser::ParseObjCAtDirectives() { +Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() { SourceLocation AtLoc = ConsumeToken(); // the "@" if (Tok.is(tok::code_completion)) { Actions.CodeCompleteObjCAtDirective(getCurScope()); ConsumeCodeCompletionToken(); } - + + Decl *SingleDecl = 0; switch (Tok.getObjCKeywordID()) { case tok::objc_class: return ParseObjCAtClassDeclaration(AtLoc); + break; case tok::objc_interface: { ParsedAttributes attrs(AttrFactory); - return ParseObjCAtInterfaceDeclaration(AtLoc, attrs); + SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, attrs); + break; } case tok::objc_protocol: { ParsedAttributes attrs(AttrFactory); - return ParseObjCAtProtocolDeclaration(AtLoc, attrs); + SingleDecl = ParseObjCAtProtocolDeclaration(AtLoc, attrs); + break; } case tok::objc_implementation: - return ParseObjCAtImplementationDeclaration(AtLoc); + SingleDecl = ParseObjCAtImplementationDeclaration(AtLoc); + break; case tok::objc_end: - return ParseObjCAtEndDeclaration(AtLoc); + SingleDecl = ParseObjCAtEndDeclaration(AtLoc); + break; case tok::objc_compatibility_alias: - return ParseObjCAtAliasDeclaration(AtLoc); + SingleDecl = ParseObjCAtAliasDeclaration(AtLoc); + break; case tok::objc_synthesize: - return ParseObjCPropertySynthesize(AtLoc); + SingleDecl = ParseObjCPropertySynthesize(AtLoc); + break; case tok::objc_dynamic: - return ParseObjCPropertyDynamic(AtLoc); + SingleDecl = ParseObjCPropertyDynamic(AtLoc); + break; default: Diag(AtLoc, diag::err_unexpected_at); SkipUntil(tok::semi); - return 0; + SingleDecl = 0; + break; } + return Actions.ConvertDeclToDeclGroup(SingleDecl); } /// /// objc-class-declaration: /// '@' 'class' identifier-list ';' /// -Decl *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { +Parser::DeclGroupPtrTy +Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { ConsumeToken(); // the identifier "class" SmallVector ClassNames; SmallVector ClassLocs; @@ -79,7 +91,7 @@ Decl *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); SkipUntil(tok::semi); - return 0; + return Actions.ConvertDeclToDeclGroup(0); } ClassNames.push_back(Tok.getIdentifierInfo()); ClassLocs.push_back(Tok.getLocation()); @@ -93,7 +105,7 @@ Decl *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { // Consume the ';'. if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class")) - return 0; + return Actions.ConvertDeclToDeclGroup(0); return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(), ClassLocs.data(), diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 39edab191162..43e0f034e829 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -593,10 +593,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, break; } case tok::at: - // @ is not a legal token unless objc is enabled, no need to check for ObjC. - /// FIXME: ParseObjCAtDirectives should return a DeclGroup for things like - /// @class foo, bar; - SingleDecl = ParseObjCAtDirectives(); + return ParseObjCAtDirectives(); break; case tok::minus: case tok::plus: diff --git a/clang/lib/Rewrite/RewriteObjC.cpp b/clang/lib/Rewrite/RewriteObjC.cpp index 3ba7e90dac92..ba518069eb85 100644 --- a/clang/lib/Rewrite/RewriteObjC.cpp +++ b/clang/lib/Rewrite/RewriteObjC.cpp @@ -161,8 +161,13 @@ namespace { // Top Level Driver code. virtual void HandleTopLevelDecl(DeclGroupRef D) { - for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) + for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { + if (isa((*I))) { + RewriteForwardClassDecl(D); + break; + } HandleTopLevelSingleDecl(*I); + } } void HandleTopLevelSingleDecl(Decl *D); void HandleDeclInMainFile(Decl *D); @@ -241,7 +246,7 @@ namespace { // Syntactic Rewriting. void RewriteInclude(); - void RewriteForwardClassDecl(ObjCClassDecl *Dcl); + void RewriteForwardClassDecl(DeclGroupRef D); void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, ObjCImplementationDecl *IMD, ObjCCategoryImplDecl *CID); @@ -886,30 +891,28 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, InsertText(onePastSemiLoc, Setr); } -void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) { - // Get the start location and compute the semi location. - SourceLocation startLoc = ClassDecl->getLocation(); - const char *startBuf = SM->getCharacterData(startLoc); - const char *semiPtr = strchr(startBuf, ';'); - - // Translate to typedef's that forward reference structs with the same name - // as the class. As a convenience, we include the original declaration - // as a comment. +void RewriteObjC::RewriteForwardClassDecl(DeclGroupRef D) { + SourceLocation startLoc; std::string typedefString; - typedefString += "// @class "; - for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end(); - I != E; ++I) { - ObjCInterfaceDecl *ForwardDecl = I->getInterface(); - typedefString += ForwardDecl->getNameAsString(); - if (I+1 != E) - typedefString += ", "; - else + const char *startBuf = 0; + const char *semiPtr = 0; + for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { + ObjCClassDecl *ClassDecl = cast(*I); + ObjCInterfaceDecl *ForwardDecl = ClassDecl->getForwardInterfaceDecl(); + if (I == D.begin()) { + // Get the start location and compute the semi location. + startLoc = ClassDecl->getLocation(); + startBuf = SM->getCharacterData(startLoc); + semiPtr = strchr(startBuf, ';'); + typedefString += "// @class "; + typedefString += ForwardDecl->getNameAsString(); typedefString += ";\n"; - } + } + // Translate to typedef's that forward reference structs with the same name + // as the class. As a convenience, we include the original declaration + // as a comment. + - for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end(); - I != E; ++I) { - ObjCInterfaceDecl *ForwardDecl = I->getInterface(); typedefString += "#ifndef _REWRITER_typedef_"; typedefString += ForwardDecl->getNameAsString(); typedefString += "\n"; @@ -5887,8 +5890,8 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) { ClassImplementation.push_back(CI); else if (ObjCCategoryImplDecl *CI = dyn_cast(D)) CategoryImplementation.push_back(CI); - else if (ObjCClassDecl *CD = dyn_cast(D)) - RewriteForwardClassDecl(CD); + else if (isa(D)) + assert(false && "RewriteObjC::HandleDeclInMainFile - ObjCClassDecl"); else if (VarDecl *VD = dyn_cast(D)) { RewriteObjCQualifiedInterfaceTypes(VD); if (isTopLevelBlockPointerType(VD->getType())) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index ef54fbcad889..5e19148c38d2 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -5405,12 +5405,11 @@ static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext, // Record any forward-declared interfaces we find. if (ObjCClassDecl *Forward = dyn_cast(*D)) { - for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end(); - C != CEnd; ++C) - if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) && - (!OnlyUnimplemented || !C->getInterface()->getImplementation())) - Results.AddResult(Result(C->getInterface(), 0), CurContext, - 0, false); + ObjCInterfaceDecl *IDecl = Forward->getForwardInterfaceDecl(); + if ((!OnlyForwardDeclarations || IDecl->isForwardDecl()) && + (!OnlyUnimplemented || !IDecl->getImplementation())) + Results.AddResult(Result(IDecl, 0), CurContext, + 0, false); } } } diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index af14aa4f84f2..c7d3590fb855 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1657,13 +1657,12 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, } /// ActOnForwardClassDeclaration - -Decl * +Sema::DeclGroupPtrTy Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, unsigned NumElts) { - SmallVector Interfaces; - + SmallVector DeclsInGroup; for (unsigned i = 0; i != NumElts; ++i) { // Check for another declaration kind with the same name. NamedDecl *PrevDecl @@ -1708,17 +1707,14 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, PushOnScopeChains(IDecl, TUScope, false); CurContext->makeDeclVisibleInContext(IDecl, true); } - - Interfaces.push_back(IDecl); + ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc, + IDecl, IdentLocs[i]); + CurContext->addDecl(CDecl); + CheckObjCDeclScope(CDecl); + DeclsInGroup.push_back(CDecl); } - - assert(Interfaces.size() == NumElts); - ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc, - Interfaces.data(), IdentLocs, - Interfaces.size()); - CurContext->addDecl(CDecl); - CheckObjCDeclScope(CDecl); - return CDecl; + + return BuildDeclaratorGroup(DeclsInGroup.data(), DeclsInGroup.size(), false); } static bool tryMatchRecordTypes(ASTContext &Context, diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 240eb5f1bf7b..7df049815a53 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -2670,14 +2670,11 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, } } } else if (ObjCClassDecl *Class = dyn_cast(*D)) { - for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end(); - I != IEnd; ++I) { - ObjCInterfaceDecl *IFace = I->getInterface(); + ObjCInterfaceDecl *IFace = Class->getForwardInterfaceDecl(); if (Result.isAcceptableDecl(IFace)) { Consumer.FoundDecl(IFace, Visited.checkHidden(IFace), InBaseClass); Visited.add(IFace); } - } } // Visit transparent contexts and inline namespaces inside this context. diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 6e7cbbf9b0c2..4fa9b2c85753 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -123,8 +123,8 @@ namespace clang { ClassTemplateSpecializationDecl *D); void VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D); - void VisitClassScopeFunctionSpecializationDecl( - ClassScopeFunctionSpecializationDecl *D); + void VisitClassScopeFunctionSpecializationDecl( + ClassScopeFunctionSpecializationDecl *D); void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); void VisitValueDecl(ValueDecl *VD); void VisitEnumConstantDecl(EnumConstantDecl *ECD); @@ -573,17 +573,9 @@ void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) { void ASTDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) { VisitDecl(CD); - unsigned NumClassRefs = Record[Idx++]; - SmallVector ClassRefs; - ClassRefs.reserve(NumClassRefs); - for (unsigned I = 0; I != NumClassRefs; ++I) - ClassRefs.push_back(ReadDeclAs(Record, Idx)); - SmallVector SLocs; - SLocs.reserve(NumClassRefs); - for (unsigned I = 0; I != NumClassRefs; ++I) - SLocs.push_back(ReadSourceLocation(Record, Idx)); - CD->setClassList(*Reader.getContext(), ClassRefs.data(), SLocs.data(), - NumClassRefs); + ObjCInterfaceDecl *ClassRef = ReadDeclAs(Record, Idx); + SourceLocation SLoc = ReadSourceLocation(Record, Idx); + CD->setClass(*Reader.getContext(), ClassRef, SLoc); } void ASTDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) { @@ -1211,8 +1203,8 @@ void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl( } } -void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl( - ClassScopeFunctionSpecializationDecl *D) { +void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl( + ClassScopeFunctionSpecializationDecl *D) { VisitDecl(D); D->Specialization = ReadDeclAs(Record, Idx); } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index a0f7da20e67e..b5d4d8f3132e 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -65,8 +65,8 @@ namespace clang { ClassTemplateSpecializationDecl *D); void VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D); - void VisitClassScopeFunctionSpecializationDecl( - ClassScopeFunctionSpecializationDecl *D); + void VisitClassScopeFunctionSpecializationDecl( + ClassScopeFunctionSpecializationDecl *D); void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); void VisitValueDecl(ValueDecl *D); void VisitEnumConstantDecl(EnumConstantDecl *D); @@ -503,11 +503,8 @@ void ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) { void ASTDeclWriter::VisitObjCClassDecl(ObjCClassDecl *D) { VisitDecl(D); - Record.push_back(D->size()); - for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I) - Writer.AddDeclRef(I->getInterface(), Record); - for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I) - Writer.AddSourceLocation(I->getLocation(), Record); + Writer.AddDeclRef(D->getForwardInterfaceDecl(), Record); + Writer.AddSourceLocation(D->getForwardDecl()->getLocation(), Record); Code = serialization::DECL_OBJC_CLASS; } @@ -1107,8 +1104,8 @@ void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl( Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION; } -void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl( - ClassScopeFunctionSpecializationDecl *D) { +void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl( + ClassScopeFunctionSpecializationDecl *D) { VisitDecl(D); Writer.AddDeclRef(D->getSpecialization(), Record); Code = serialization::DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION; diff --git a/clang/test/Rewriter/rewrite-forward-class.m b/clang/test/Rewriter/rewrite-forward-class.m index 5a50f53a480f..1d3af6f366c3 100644 --- a/clang/test/Rewriter/rewrite-forward-class.m +++ b/clang/test/Rewriter/rewrite-forward-class.m @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -rewrite-objc -o - %s +// RUN: %clang_cc1 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp +// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp // rdar://6969189 @class XX; @@ -6,3 +7,29 @@ @class ISyncClient, SMSession, ISyncManager, ISyncSession, SMDataclassInfo, SMClientInfo, DMCConfiguration, DMCStatusEntry; +@interface QQ + +@end + +@interface SMDataclassInfo : QQ +- (XX*) Meth; +- (DMCStatusEntry*)Meth2; +@end + +@implementation SMDataclassInfo +- (XX*) Meth { return 0; } +- (DMCStatusEntry*)Meth2 { return 0; } +@end + +@interface YY +{ + ISyncClient *p1; + ISyncSession *p2; +} +@property (copy) ISyncClient *p1; +@end + +@implementation YY +@synthesize p1; +@end + diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index c7e492e074ae..c9b1fa8dbe66 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -1100,10 +1100,9 @@ bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { } bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) { - for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C) - if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU))) + if (Visit(MakeCursorObjCClassRef(D->getForwardInterfaceDecl(), + D->getForwardDecl()->getLocation(), TU))) return true; - return false; } @@ -4219,8 +4218,8 @@ unsigned clang_getNumOverloadedDecls(CXCursor C) { Decl *D = Storage.get(); if (UsingDecl *Using = dyn_cast(D)) return Using->shadow_size(); - if (ObjCClassDecl *Classes = dyn_cast(D)) - return Classes->size(); + if (isa(D)) + return 1; if (ObjCForwardProtocolDecl *Protocols =dyn_cast(D)) return Protocols->protocol_size(); @@ -4250,10 +4249,8 @@ CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) { std::advance(Pos, index); return MakeCXCursor(cast(*Pos)->getTargetDecl(), TU); } - if (ObjCClassDecl *Classes = dyn_cast(D)) - return MakeCXCursor(Classes->begin()[index].getInterface(), TU); - + return MakeCXCursor(Classes->getForwardInterfaceDecl(), TU); if (ObjCForwardProtocolDecl *Protocols = dyn_cast(D)) return MakeCXCursor(Protocols->protocol_begin()[index], TU);