From 30833f8d77c08f8f16371776fde85a9fde3d9b6e Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Tue, 21 Apr 2009 15:12:33 +0000 Subject: [PATCH] Add pch reader/writer support for most of DeclObjC.h. Very close to reading/writing all ObjC AST nodes that we will encounter in header files (still a few FIXME's). Once selector support is in place, we should be able to take this for a spin (and add test cases). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69674 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/DeclObjC.h | 35 +++++-- include/clang/Frontend/PCHBitCodes.h | 24 ++++- lib/Frontend/PCHReader.cpp | 147 ++++++++++++++++++++++++++- lib/Frontend/PCHWriter.cpp | 96 ++++++++++++++++- tools/clang-cc/ASTConsumers.cpp | 5 +- 5 files changed, 289 insertions(+), 18 deletions(-) diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index ac227decb4..60bbd6fe14 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -599,7 +599,6 @@ class ObjCProtocolDecl : public ObjCContainerDecl { bool isForwardProtoDecl; // declared with @protocol. SourceLocation EndLoc; // marks the '>' or identifier. - SourceLocation AtEndLoc; // marks the end of the entire interface. ObjCProtocolDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id) : ObjCContainerDecl(ObjCProtocol, DC, L, Id), @@ -621,6 +620,7 @@ public: typedef ObjCList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } + unsigned protocol_size() const { return ReferencedProtocols.size(); } /// setProtocolList - Set the list of protocols that this interface /// implements. @@ -664,11 +664,18 @@ public: virtual void Destroy(ASTContext& C); static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - ObjCInterfaceDecl *const *Elts, unsigned nElts); + ObjCInterfaceDecl *const *Elts = 0, + unsigned nElts = 0); typedef ObjCList::iterator iterator; iterator begin() const { return ForwardDecls.begin(); } iterator end() const { return ForwardDecls.end(); } + unsigned size() const { return ForwardDecls.size(); } + + /// setClassList - Set the list of forward classes. + void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, unsigned Num) { + ForwardDecls.set(List, Num, C); + } static bool classof(const Decl *D) { return D->getKind() == ObjCClass; } static bool classof(const ObjCClassDecl *D) { return true; } @@ -690,16 +697,22 @@ class ObjCForwardProtocolDecl : public Decl { public: static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - ObjCProtocolDecl *const *Elts, - unsigned Num); + ObjCProtocolDecl *const *Elts = 0, + unsigned Num = 0); /// Destroy - Call destructors and release memory. virtual void Destroy(ASTContext& C); - typedef ObjCList::iterator iterator; - iterator begin() const { return ReferencedProtocols.begin(); } - iterator end() const { return ReferencedProtocols.end(); } - + typedef ObjCList::iterator protocol_iterator; + protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} + protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } + unsigned protocol_size() const { return ReferencedProtocols.size(); } + + /// setProtocolList - Set the list of forward protocols. + void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, + ASTContext &C) { + ReferencedProtocols.set(List, Num, C); + } static bool classof(const Decl *D) { return D->getKind() == ObjCForwardProtocol; } @@ -763,8 +776,12 @@ public: typedef ObjCList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } + unsigned protocol_size() const { return ReferencedProtocols.size(); } ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } + void setNextClassCategory(ObjCCategoryDecl *Cat) { + NextClassCategory = Cat; + } void insertNextClassCategory() { NextClassCategory = ClassInterface->getCategoryList(); ClassInterface->setCategoryList(this); @@ -845,7 +862,6 @@ public: classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); } classmeth_iterator classmeth_end() const { return ClassMethods.end(); } - // Location information, modeled after the Stmt API. SourceLocation getLocStart() const { return getLocation(); } SourceLocation getLocEnd() const { return EndLoc; } @@ -1002,6 +1018,7 @@ public: const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } + void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; } static bool classof(const Decl *D) { return D->getKind() == ObjCCompatibleAlias; diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index ad07e2ae6b..32f94852b2 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -357,9 +357,29 @@ namespace clang { /// \brief A ObjCMethodDecl record. DECL_OBJC_METHOD, /// \brief A ObjCInterfaceDecl record. - DECL_OBJC_INTERFACE_DECL, + DECL_OBJC_INTERFACE, + /// \brief A ObjCProtocolDecl record. + DECL_OBJC_PROTOCOL, /// \brief A ObjCIvarDecl record. - DECL_OBJC_IVAR_DECL, + DECL_OBJC_IVAR, + /// \brief A ObjCAtDefsFieldDecl record. + DECL_OBJC_AT_DEFS_FIELD, + /// \brief A ObjCClassDecl record. + DECL_OBJC_CLASS, + /// \brief A ObjCForwardProtocolDecl record. + DECL_OBJC_FORWARD_PROTOCOL, + /// \brief A ObjCCategoryDecl record. + DECL_OBJC_CATEGORY, + /// \brief A ObjCCategoryImplDecl record. + DECL_OBJC_CATEGORY_IMPL, + /// \brief A ObjCImplementationDecl record. + DECL_OBJC_IMPLEMENTATION, + /// \brief A ObjCCompatibleAliasDecl record. + DECL_OBJC_COMPATIBLE_ALIAS, + /// \brief A ObjCPropertyDecl record. + DECL_OBJC_PROPERTY, + /// \brief A ObjCPropertyImplDecl record. + DECL_OBJC_PROPERTY_IMPL, /// \brief A FieldDecl record. DECL_FIELD, /// \brief A VarDecl record. diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index e694a140d1..abdb24f0ca 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -71,6 +71,17 @@ namespace { void VisitObjCContainerDecl(ObjCContainerDecl *D); void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); void VisitObjCIvarDecl(ObjCIvarDecl *D); + void VisitObjCProtocolDecl(ObjCProtocolDecl *D); + void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D); + void VisitObjCClassDecl(ObjCClassDecl *D); + void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); + void VisitObjCCategoryDecl(ObjCCategoryDecl *D); + void VisitObjCImplDecl(ObjCImplDecl *D); + void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); + void VisitObjCImplementationDecl(ObjCImplementationDecl *D); + void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D); + void VisitObjCPropertyDecl(ObjCPropertyDecl *D); + void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); }; } @@ -207,7 +218,6 @@ void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { ID->setImplicitInterfaceDecl(Record[Idx++]); ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); ID->setSuperClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - ID->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++])); // FIXME: add protocols, categories. } @@ -216,6 +226,86 @@ void PCHDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) { IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]); } +void PCHDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { + VisitObjCContainerDecl(PD); + PD->setForwardDecl(Record[Idx++]); + PD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++])); + unsigned NumProtoRefs = Record[Idx++]; + llvm::SmallVector ProtoRefs; + ProtoRefs.reserve(NumProtoRefs); + for (unsigned I = 0; I != NumProtoRefs; ++I) + ProtoRefs.push_back(cast(Reader.GetDecl(Record[Idx++]))); + PD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext()); +} + +void PCHDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) { + VisitFieldDecl(FD); +} + +void PCHDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) { + VisitDecl(CD); + unsigned NumClassRefs = Record[Idx++]; + llvm::SmallVector ClassRefs; + ClassRefs.reserve(NumClassRefs); + for (unsigned I = 0; I != NumClassRefs; ++I) + ClassRefs.push_back(cast(Reader.GetDecl(Record[Idx++]))); + CD->setClassList(Reader.getContext(), &ClassRefs[0], NumClassRefs); +} + +void PCHDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) { + VisitDecl(FPD); + unsigned NumProtoRefs = Record[Idx++]; + llvm::SmallVector ProtoRefs; + ProtoRefs.reserve(NumProtoRefs); + for (unsigned I = 0; I != NumProtoRefs; ++I) + ProtoRefs.push_back(cast(Reader.GetDecl(Record[Idx++]))); + FPD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext()); +} + +void PCHDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) { + VisitObjCContainerDecl(CD); + CD->setClassInterface(cast(Reader.GetDecl(Record[Idx++]))); + unsigned NumProtoRefs = Record[Idx++]; + llvm::SmallVector ProtoRefs; + ProtoRefs.reserve(NumProtoRefs); + for (unsigned I = 0; I != NumProtoRefs; ++I) + ProtoRefs.push_back(cast(Reader.GetDecl(Record[Idx++]))); + CD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext()); + CD->setNextClassCategory(cast(Reader.GetDecl(Record[Idx++]))); + CD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++])); +} + +void PCHDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) { + VisitNamedDecl(CAD); + CAD->setClassInterface(cast(Reader.GetDecl(Record[Idx++]))); +} + +void PCHDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { + VisitNamedDecl(D); + // FIXME: Implement. +} + +void PCHDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) { + VisitDecl(D); + // FIXME: Implement. +} + +void PCHDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { + VisitObjCImplDecl(D); + // FIXME: Implement. +} + +void PCHDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { + VisitObjCImplDecl(D); + // FIXME: Implement. +} + + +void PCHDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { + VisitDecl(D); + // FIXME: Implement. +} + void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) { VisitValueDecl(FD); FD->setMutable(Record[Idx++]); @@ -1833,17 +1923,68 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) { break; } - case pch::DECL_OBJC_INTERFACE_DECL: { + case pch::DECL_OBJC_INTERFACE: { D = ObjCInterfaceDecl::Create(Context, 0, SourceLocation(), 0); break; } - case pch::DECL_OBJC_IVAR_DECL: { + case pch::DECL_OBJC_IVAR: { D = ObjCIvarDecl::Create(Context, 0, SourceLocation(), 0, QualType(), ObjCIvarDecl::None); break; } + case pch::DECL_OBJC_PROTOCOL: { + D = ObjCProtocolDecl::Create(Context, 0, SourceLocation(), 0); + break; + } + + case pch::DECL_OBJC_AT_DEFS_FIELD: { + D = ObjCAtDefsFieldDecl::Create(Context, 0, SourceLocation(), 0, + QualType(), 0); + break; + } + + case pch::DECL_OBJC_CLASS: { + D = ObjCClassDecl::Create(Context, 0, SourceLocation()); + break; + } + + case pch::DECL_OBJC_FORWARD_PROTOCOL: { + D = ObjCForwardProtocolDecl::Create(Context, 0, SourceLocation()); + break; + } + + case pch::DECL_OBJC_CATEGORY: { + D = ObjCCategoryDecl::Create(Context, 0, SourceLocation(), 0); + break; + } + + case pch::DECL_OBJC_CATEGORY_IMPL: { + // FIXME: Implement. + break; + } + + case pch::DECL_OBJC_IMPLEMENTATION: { + // FIXME: Implement. + break; + } + + case pch::DECL_OBJC_COMPATIBLE_ALIAS: { + // FIXME: Implement. + break; + } + + case pch::DECL_OBJC_PROPERTY: { + // FIXME: Implement. + break; + } + + case pch::DECL_OBJC_PROPERTY_IMPL: { + // FIXME: Implement. + break; + } + case pch::DECL_FIELD: { D = FieldDecl::Create(Context, 0, SourceLocation(), 0, QualType(), 0, false); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 643b8dbf7a..16eaf982fe 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -277,6 +277,17 @@ namespace { void VisitObjCContainerDecl(ObjCContainerDecl *D); void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); void VisitObjCIvarDecl(ObjCIvarDecl *D); + void VisitObjCProtocolDecl(ObjCProtocolDecl *D); + void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D); + void VisitObjCClassDecl(ObjCClassDecl *D); + void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); + void VisitObjCCategoryDecl(ObjCCategoryDecl *D); + void VisitObjCImplDecl(ObjCImplDecl *D); + void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); + void VisitObjCImplementationDecl(ObjCImplementationDecl *D); + void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D); + void VisitObjCPropertyDecl(ObjCPropertyDecl *D); + void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); }; } @@ -412,14 +423,95 @@ void PCHDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { Writer.AddSourceLocation(D->getSuperClassLoc(), Record); Writer.AddSourceLocation(D->getLocEnd(), Record); // FIXME: add protocols, categories. - Code = pch::DECL_OBJC_INTERFACE_DECL; + Code = pch::DECL_OBJC_INTERFACE; } void PCHDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) { VisitFieldDecl(D); // FIXME: stable encoding for @public/@private/@protected/@package Record.push_back(D->getAccessControl()); - Code = pch::DECL_OBJC_IVAR_DECL; + Code = pch::DECL_OBJC_IVAR; +} + +void PCHDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) { + VisitObjCContainerDecl(D); + Record.push_back(D->isForwardDecl()); + Writer.AddSourceLocation(D->getLocEnd(), Record); + Record.push_back(D->protocol_size()); + for (ObjCProtocolDecl::protocol_iterator + I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I) + Writer.AddDeclRef(*I, Record); + Code = pch::DECL_OBJC_PROTOCOL; +} + +void PCHDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) { + VisitFieldDecl(D); + Code = pch::DECL_OBJC_AT_DEFS_FIELD; +} + +void PCHDeclWriter::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, Record); + Code = pch::DECL_OBJC_CLASS; +} + +void PCHDeclWriter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { + VisitDecl(D); + Record.push_back(D->protocol_size()); + for (ObjCProtocolDecl::protocol_iterator + I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I) + Writer.AddDeclRef(*I, Record); + Code = pch::DECL_OBJC_FORWARD_PROTOCOL; +} + +void PCHDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) { + VisitObjCContainerDecl(D); + Writer.AddDeclRef(D->getClassInterface(), Record); + Record.push_back(D->protocol_size()); + for (ObjCProtocolDecl::protocol_iterator + I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I) + Writer.AddDeclRef(*I, Record); + Writer.AddDeclRef(D->getNextClassCategory(), Record); + Writer.AddSourceLocation(D->getLocEnd(), Record); + Code = pch::DECL_OBJC_CATEGORY; +} + +void PCHDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) { + VisitNamedDecl(D); + Writer.AddDeclRef(D->getClassInterface(), Record); + Code = pch::DECL_OBJC_COMPATIBLE_ALIAS; +} + +void PCHDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { + VisitNamedDecl(D); + // FIXME: Implement. + Code = pch::DECL_OBJC_PROPERTY; +} + +void PCHDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) { + VisitDecl(D); + // FIXME: Implement. + // Abstract class (no need to define a stable pch::DECL code). +} + +void PCHDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { + VisitObjCImplDecl(D); + // FIXME: Implement. + Code = pch::DECL_OBJC_CATEGORY_IMPL; +} + +void PCHDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { + VisitObjCImplDecl(D); + // FIXME: Implement. + Code = pch::DECL_OBJC_IMPLEMENTATION; +} + +void PCHDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { + VisitDecl(D); + // FIXME: Implement. + Code = pch::DECL_OBJC_PROPERTY_IMPL; } void PCHDeclWriter::VisitFieldDecl(FieldDecl *D) { diff --git a/tools/clang-cc/ASTConsumers.cpp b/tools/clang-cc/ASTConsumers.cpp index aabbf2ab4a..52aafd35c0 100644 --- a/tools/clang-cc/ASTConsumers.cpp +++ b/tools/clang-cc/ASTConsumers.cpp @@ -98,9 +98,10 @@ void DeclPrinter:: PrintDecl(Decl *D) { } else if (ObjCForwardProtocolDecl *OFPD = dyn_cast(D)) { Out << "@protocol "; - for (ObjCForwardProtocolDecl::iterator I = OFPD->begin(), E = OFPD->end(); + for (ObjCForwardProtocolDecl::protocol_iterator I = OFPD->protocol_begin(), + E = OFPD->protocol_end(); I != E; ++I) { - if (I != OFPD->begin()) Out << ", "; + if (I != OFPD->protocol_begin()) Out << ", "; Out << (*I)->getNameAsString(); } Out << ";\n"; -- 2.50.1