forked from OSchip/llvm-project
Support ObjC implementation decls for PCH.
Strictly speaking, implementations don't go in headers but there's no law against it. llvm-svn: 110567
This commit is contained in:
parent
5b6a03f490
commit
13257c5527
|
@ -1238,6 +1238,9 @@ public:
|
|||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classof(const ObjCImplementationDecl *D) { return true; }
|
||||
static bool classofKind(Kind K) { return K == ObjCImplementation; }
|
||||
|
||||
friend class PCHDeclReader;
|
||||
friend class PCHDeclWriter;
|
||||
};
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
|
||||
|
|
|
@ -937,6 +937,8 @@ protected:
|
|||
/// name. The return value has type char *.
|
||||
llvm::Constant *GetClassName(IdentifierInfo *Ident);
|
||||
|
||||
llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
|
||||
|
||||
/// BuildIvarLayout - Builds ivar layout bitmap for the class
|
||||
/// implementation for the __strong or __weak case.
|
||||
///
|
||||
|
@ -2538,8 +2540,7 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
|
|||
/// given method if it has been defined. The result is null if the
|
||||
/// method has not been defined. The return value has type MethodPtrTy.
|
||||
llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
|
||||
// FIXME: Use DenseMap::lookup
|
||||
llvm::Function *Fn = MethodDefinitions[MD];
|
||||
llvm::Function *Fn = GetMethodDefinition(MD);
|
||||
if (!Fn)
|
||||
return 0;
|
||||
|
||||
|
@ -3571,6 +3572,22 @@ llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
|
|||
return getConstantGEP(VMContext, Entry, 0, 0);
|
||||
}
|
||||
|
||||
llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
|
||||
llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
|
||||
I = MethodDefinitions.find(MD);
|
||||
if (I != MethodDefinitions.end())
|
||||
return I->second;
|
||||
|
||||
if (MD->hasBody() && MD->getPCHLevel() > 0) {
|
||||
// MD isn't emitted yet because it comes from PCH.
|
||||
CGM.EmitTopLevelDecl(const_cast<ObjCMethodDecl*>(MD));
|
||||
assert(MethodDefinitions[MD] && "EmitTopLevelDecl didn't emit the method!");
|
||||
return MethodDefinitions[MD];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// GetIvarLayoutName - Returns a unique constant for the given
|
||||
/// ivar layout bitmap.
|
||||
llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
|
||||
|
@ -5162,8 +5179,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
|
|||
/// method has not been defined. The return value has type MethodPtrTy.
|
||||
llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
|
||||
const ObjCMethodDecl *MD) {
|
||||
// FIXME: Use DenseMap::lookup
|
||||
llvm::Function *Fn = MethodDefinitions[MD];
|
||||
llvm::Function *Fn = GetMethodDefinition(MD);
|
||||
if (!Fn)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -514,7 +514,8 @@ void PCHDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
|
|||
VisitObjCImplDecl(D);
|
||||
D->setSuperClass(
|
||||
cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
// FIXME. Add reading of IvarInitializers and NumIvarInitializers.
|
||||
llvm::tie(D->IvarInitializers, D->NumIvarInitializers)
|
||||
= Reader.ReadCXXBaseOrMemberInitializers(Cursor, Record, Idx);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1298,7 +1299,7 @@ static bool isConsumerInterestedIn(Decl *D) {
|
|||
Var->isThisDeclarationADefinition() == VarDecl::Definition;
|
||||
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D))
|
||||
return Func->isThisDeclarationADefinition();
|
||||
return isa<ObjCProtocolDecl>(D);
|
||||
return isa<ObjCProtocolDecl>(D) || isa<ObjCImplementationDecl>(D);
|
||||
}
|
||||
|
||||
/// \brief Get the correct cursor and offset for loading a type.
|
||||
|
|
|
@ -468,7 +468,8 @@ void PCHDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
|
|||
void PCHDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
|
||||
VisitObjCImplDecl(D);
|
||||
Writer.AddDeclRef(D->getSuperClass(), Record);
|
||||
// FIXME add writing of IvarInitializers and NumIvarInitializers.
|
||||
Writer.AddCXXBaseOrMemberInitializers(D->IvarInitializers,
|
||||
D->NumIvarInitializers, Record);
|
||||
Code = pch::DECL_OBJC_IMPLEMENTATION;
|
||||
}
|
||||
|
||||
|
@ -1096,8 +1097,8 @@ void PCHWriter::WriteDeclsBlockAbbrevs() {
|
|||
/// relatively painless since they would presumably only do it for top-level
|
||||
/// decls.
|
||||
static bool isRequiredDecl(const Decl *D, ASTContext &Context) {
|
||||
// File scoped assembly must be seen.
|
||||
if (isa<FileScopeAsmDecl>(D))
|
||||
// File scoped assembly or obj-c implementation must be seen.
|
||||
if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplementationDecl>(D))
|
||||
return true;
|
||||
|
||||
return Context.DeclMustBeEmitted(D);
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
struct S {
|
||||
S();
|
||||
};
|
||||
|
||||
@interface C {
|
||||
S s;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation C
|
||||
@end
|
|
@ -0,0 +1,9 @@
|
|||
// Test this without pch.
|
||||
// RUN: %clang_cc1 -include %S/objcxx-ivar-class.h -verify %s -emit-llvm -o - | FileCheck %s
|
||||
|
||||
// Test with pch.
|
||||
// RUN: %clang_cc1 -x objective-c++-header -emit-pch -o %t %S/objcxx-ivar-class.h
|
||||
// RUN: %clang_cc1 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
|
||||
|
||||
// CHECK: [C .cxx_destruct]
|
||||
// CHECK: [C .cxx_construct]
|
Loading…
Reference in New Issue