diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 11 | ||||
-rw-r--r-- | clang/include/clang/Frontend/PCHBitCodes.h | 2 | ||||
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHReader.cpp | 31 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHWriter.cpp | 27 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 8 | ||||
-rw-r--r-- | clang/test/PCH/methods.h | 6 | ||||
-rw-r--r-- | clang/test/PCH/methods.m | 11 |
8 files changed, 94 insertions, 12 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 119b3c890a3..7ee7c7b91b1 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -177,6 +177,7 @@ public: // Location information, modeled after the Stmt API. SourceLocation getLocStart() const { return getLocation(); } SourceLocation getLocEnd() const { return EndLoc; } + void setEndLoc(SourceLocation Loc) { EndLoc = Loc; } SourceRange getSourceRange() const { return SourceRange(getLocation(), EndLoc); } @@ -189,6 +190,7 @@ public: Selector getSelector() const { return getDeclName().getObjCSelector(); } unsigned getSynthesizedMethodSize() const; QualType getResultType() const { return MethodDeclType; } + void setResultType(QualType T) { MethodDeclType = T; } // Iterator access to formal parameters. unsigned param_size() const { return ParamInfo.size(); } @@ -196,8 +198,7 @@ public: param_iterator param_begin() const { return ParamInfo.begin(); } param_iterator param_end() const { return ParamInfo.end(); } - void setMethodParams(ParmVarDecl *const *List, unsigned Num, - ASTContext &C) { + void setMethodParams(ASTContext &C, ParmVarDecl *const *List, unsigned Num) { ParamInfo.set(List, Num, C); } @@ -219,15 +220,19 @@ public: void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID); ImplicitParamDecl * getSelfDecl() const { return SelfDecl; } + void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; } ImplicitParamDecl * getCmdDecl() const { return CmdDecl; } + void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; } bool isInstanceMethod() const { return IsInstance; } + void setInstanceMethod(bool isInst) { IsInstance = isInst; } bool isVariadic() const { return IsVariadic; } + void setVariadic(bool isVar) { IsVariadic = isVar; } bool isClassMethod() const { return !IsInstance; } bool isSynthesized() const { return IsSynthesized; } - void setIsSynthesized() { IsSynthesized = true; } + void setSynthesized(bool isSynth) { IsSynthesized = isSynth; } // Related to protocols declared in @protocol void setDeclImplementation(ImplementationControl ic) { diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index 97227ceadb0..c1e6a8f493c 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -354,6 +354,8 @@ namespace clang { DECL_ENUM_CONSTANT, /// \brief A FunctionDecl record. DECL_FUNCTION, + /// \brief A ObjCMethodDecl record. + DECL_OBJC_METHOD, /// \brief A FieldDecl record. DECL_FIELD, /// \brief A VarDecl record. diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 4a3c4d4f30e..9cc22912caf 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -285,12 +285,12 @@ void ObjCMethodDecl::createImplicitParams(ASTContext &Context, } else // we have a factory method. selfTy = Context.getObjCClassType(); - SelfDecl = ImplicitParamDecl::Create(Context, this, SourceLocation(), - &Context.Idents.get("self"), selfTy); + setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(), + &Context.Idents.get("self"), selfTy)); - CmdDecl = ImplicitParamDecl::Create(Context, this, SourceLocation(), - &Context.Idents.get("_cmd"), - Context.getObjCSelType()); + setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(), + &Context.Idents.get("_cmd"), + Context.getObjCSelType())); } diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 9af75aef2b4..391937b9234 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -67,6 +67,7 @@ namespace { void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD); void VisitBlockDecl(BlockDecl *BD); std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC); + void VisitObjCMethodDecl(ObjCMethodDecl *D); }; } @@ -159,6 +160,30 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setParams(Reader.getContext(), &Params[0], NumParams); } +void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { + VisitNamedDecl(MD); + if (Record[Idx++]) { + // In practice, this won't be executed (since method definitions + // don't occur in header files). + MD->setBody(cast<CompoundStmt>(Reader.GetStmt(Record[Idx++]))); + MD->setSelfDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++]))); + MD->setCmdDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++]))); + } + MD->setInstanceMethod(Record[Idx++]); + MD->setVariadic(Record[Idx++]); + MD->setSynthesized(Record[Idx++]); + MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]); + MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]); + MD->setResultType(Reader.GetType(Record[Idx++])); + MD->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + unsigned NumParams = Record[Idx++]; + llvm::SmallVector<ParmVarDecl *, 16> Params; + Params.reserve(NumParams); + for (unsigned I = 0; I != NumParams; ++I) + Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++]))); + MD->setMethodParams(Reader.getContext(), &Params[0], NumParams); +} + void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) { VisitValueDecl(FD); FD->setMutable(Record[Idx++]); @@ -1770,6 +1795,12 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) { break; } + case pch::DECL_OBJC_METHOD: { + D = ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(), + Selector(), QualType(), 0); + break; + } + case pch::DECL_FIELD: { D = FieldDecl::Create(Context, 0, SourceLocation(), 0, QualType(), 0, false); diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 9f22f13134b..6aea7a53727 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -270,6 +270,7 @@ namespace { void VisitBlockDecl(BlockDecl *D); void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, uint64_t VisibleOffset); + void VisitObjCMethodDecl(ObjCMethodDecl *D); }; } @@ -359,6 +360,32 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Code = pch::DECL_FUNCTION; } +void PCHDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) { + VisitNamedDecl(D); + // FIXME: convert to LazyStmtPtr? + // Unlike C/C++, method bodies will never be in header files. + Record.push_back(D->getBody() != 0); + if (D->getBody() != 0) { + Writer.AddStmt(D->getBody(Context)); + Writer.AddDeclRef(D->getSelfDecl(), Record); + Writer.AddDeclRef(D->getCmdDecl(), Record); + } + Record.push_back(D->isInstanceMethod()); + Record.push_back(D->isVariadic()); + Record.push_back(D->isSynthesized()); + // FIXME: stable encoding for @required/@optional + Record.push_back(D->getImplementationControl()); + // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway + Record.push_back(D->getObjCDeclQualifier()); + Writer.AddTypeRef(D->getResultType(), Record); + Writer.AddSourceLocation(D->getLocEnd(), Record); + Record.push_back(D->param_size()); + for (ObjCMethodDecl::param_iterator P = D->param_begin(), + PEnd = D->param_end(); P != PEnd; ++P) + Writer.AddDeclRef(*P, Record); + Code = pch::DECL_OBJC_METHOD; +} + void PCHDeclWriter::VisitFieldDecl(FieldDecl *D) { VisitValueDecl(D); Record.push_back(D->isMutable()); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index db81cacc2b6..b813e085eea 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1226,7 +1226,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, } else // A user declared getter will be synthesize when @synthesize of // the property with the same name is seen in the @implementation - GetterMethod->setIsSynthesized(); + GetterMethod->setSynthesized(true); property->setGetterMethodDecl(GetterMethod); // Skip setter if property is read-only. @@ -1252,12 +1252,12 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, property->getType(), VarDecl::None, 0); - SetterMethod->setMethodParams(&Argument, 1, Context); + SetterMethod->setMethodParams(Context, &Argument, 1); CD->addDecl(Context, SetterMethod); } else // A user declared setter will be synthesize when @synthesize of // the property with the same name is seen in the @implementation - SetterMethod->setIsSynthesized(); + SetterMethod->setSynthesized(true); property->setSetterMethodDecl(SetterMethod); } // Add any synthesized methods to the global pool. This allows us to @@ -1506,7 +1506,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration( Params.push_back(Param); } - ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs(), Context); + ObjCMethod->setMethodParams(Context, &Params[0], Sel.getNumArgs()); ObjCMethod->setObjCDeclQualifier( CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier())); const ObjCMethodDecl *PrevMethod = 0; diff --git a/clang/test/PCH/methods.h b/clang/test/PCH/methods.h new file mode 100644 index 00000000000..97617be2931 --- /dev/null +++ b/clang/test/PCH/methods.h @@ -0,0 +1,6 @@ +/* For use with the methods.m test */ + +@interface TestPCH ++ alloc; +- (void)instMethod; +@end diff --git a/clang/test/PCH/methods.m b/clang/test/PCH/methods.m new file mode 100644 index 00000000000..49137ea6716 --- /dev/null +++ b/clang/test/PCH/methods.m @@ -0,0 +1,11 @@ +// Test this without pch. +// FIXME: clang-cc -include %S/methods.h -fsyntax-only -verify %s && + +// Test with pch. +// FIXME: clang-cc -x=objective-c -emit-pch -o %t %S/methods.h && +// FIXME: clang-cc -include-pch %t -fsyntax-only -verify %s + +void func() { + TestPCH *xx = [TestPCH alloc]; + [xx instMethod]; +} |