forked from OSchip/llvm-project
Support for IRGen of synthesize bitfield ivars in
objc-nonfragile-abi2 (radar 7824380). llvm-svn: 111823
This commit is contained in:
parent
99e9d6ffbf
commit
bf9294fb65
|
@ -1269,6 +1269,10 @@ public:
|
|||
/// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9)
|
||||
/// and returns the result type of that conversion.
|
||||
QualType UsualArithmeticConversionsType(QualType lhs, QualType rhs);
|
||||
|
||||
void ResetObjCLayout(const ObjCContainerDecl *CD) {
|
||||
ObjCLayouts[CD] = 0;
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Integer Predicates
|
||||
|
@ -1409,7 +1413,7 @@ private:
|
|||
|
||||
const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
|
||||
const ObjCImplementationDecl *Impl);
|
||||
|
||||
|
||||
private:
|
||||
/// \brief A set of deallocations that should be performed when the
|
||||
/// ASTContext is destroyed.
|
||||
|
|
|
@ -919,6 +919,9 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
|
|||
/// FIXME: this should not be a singly-linked list. Move storage elsewhere.
|
||||
ObjCCategoryDecl *NextClassCategory;
|
||||
|
||||
/// true of class extension has at least one bitfield ivar.
|
||||
bool HasSynthBitfield : 1;
|
||||
|
||||
/// \brief The location of the '@' in '@interface'
|
||||
SourceLocation AtLoc;
|
||||
|
||||
|
@ -929,8 +932,8 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
|
|||
SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
|
||||
IdentifierInfo *Id)
|
||||
: ObjCContainerDecl(ObjCCategory, DC, ClassNameLoc, Id),
|
||||
ClassInterface(0), NextClassCategory(0), AtLoc(AtLoc),
|
||||
CategoryNameLoc(CategoryNameLoc) {
|
||||
ClassInterface(0), NextClassCategory(0), HasSynthBitfield(false),
|
||||
AtLoc(AtLoc), CategoryNameLoc(CategoryNameLoc) {
|
||||
}
|
||||
public:
|
||||
|
||||
|
@ -982,6 +985,9 @@ public:
|
|||
bool IsClassExtension() const { return getIdentifier() == 0; }
|
||||
const ObjCCategoryDecl *getNextClassExtension() const;
|
||||
|
||||
bool hasSynthBitfield() const { return HasSynthBitfield; }
|
||||
void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
|
||||
|
||||
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
|
||||
ivar_iterator ivar_begin() const {
|
||||
return ivar_iterator(decls_begin());
|
||||
|
@ -1154,11 +1160,15 @@ class ObjCImplementationDecl : public ObjCImplDecl {
|
|||
CXXBaseOrMemberInitializer **IvarInitializers;
|
||||
unsigned NumIvarInitializers;
|
||||
|
||||
/// true of class extension has at least one bitfield ivar.
|
||||
bool HasSynthBitfield : 1;
|
||||
|
||||
ObjCImplementationDecl(DeclContext *DC, SourceLocation L,
|
||||
ObjCInterfaceDecl *classInterface,
|
||||
ObjCInterfaceDecl *superDecl)
|
||||
: ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
|
||||
SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0) {}
|
||||
SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0),
|
||||
HasSynthBitfield(false) {}
|
||||
public:
|
||||
static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
|
@ -1196,6 +1206,9 @@ public:
|
|||
void setIvarInitializers(ASTContext &C,
|
||||
CXXBaseOrMemberInitializer ** initializers,
|
||||
unsigned numInitializers);
|
||||
|
||||
bool hasSynthBitfield() const { return HasSynthBitfield; }
|
||||
void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
|
||||
|
||||
/// getIdentifier - Get the identifier that names the class
|
||||
/// interface associated with this implementation.
|
||||
|
|
|
@ -604,10 +604,17 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
|
|||
// decl contexts, the previously built IvarList must be rebuilt.
|
||||
ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
|
||||
if (!ID) {
|
||||
if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC))
|
||||
if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC)) {
|
||||
ID = IM->getClassInterface();
|
||||
else
|
||||
ID = (cast<ObjCCategoryDecl>(DC))->getClassInterface();
|
||||
if (BW)
|
||||
IM->setHasSynthBitfield(true);
|
||||
}
|
||||
else {
|
||||
ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
|
||||
ID = CD->getClassInterface();
|
||||
if (BW)
|
||||
CD->setHasSynthBitfield(true);
|
||||
}
|
||||
}
|
||||
ID->setIvarList(0);
|
||||
}
|
||||
|
|
|
@ -1940,9 +1940,16 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
|
|||
// Forward declarations, no (immediate) code generation.
|
||||
case Decl::ObjCClass:
|
||||
case Decl::ObjCForwardProtocol:
|
||||
case Decl::ObjCCategory:
|
||||
case Decl::ObjCInterface:
|
||||
break;
|
||||
|
||||
case Decl::ObjCCategory: {
|
||||
ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
|
||||
if (CD->IsClassExtension() && CD->hasSynthBitfield())
|
||||
Context.ResetObjCLayout(CD->getClassInterface());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case Decl::ObjCProtocol:
|
||||
Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
|
||||
|
@ -1956,6 +1963,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
|
|||
|
||||
case Decl::ObjCImplementation: {
|
||||
ObjCImplementationDecl *OMD = cast<ObjCImplementationDecl>(D);
|
||||
if (Features.ObjCNonFragileABI2 && OMD->hasSynthBitfield())
|
||||
Context.ResetObjCLayout(OMD->getClassInterface());
|
||||
EmitObjCPropertyImplementations(OMD);
|
||||
EmitObjCIvarInitializations(OMD);
|
||||
Runtime->GenerateClass(OMD);
|
||||
|
|
|
@ -6349,9 +6349,13 @@ Decl *Sema::ActOnIvar(Scope *S,
|
|||
ObjCContainerDecl *EnclosingContext;
|
||||
if (ObjCImplementationDecl *IMPDecl =
|
||||
dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
|
||||
if (!LangOpts.ObjCNonFragileABI2) {
|
||||
// Case of ivar declared in an implementation. Context is that of its class.
|
||||
EnclosingContext = IMPDecl->getClassInterface();
|
||||
assert(EnclosingContext && "Implementation has no class interface!");
|
||||
EnclosingContext = IMPDecl->getClassInterface();
|
||||
assert(EnclosingContext && "Implementation has no class interface!");
|
||||
}
|
||||
else
|
||||
EnclosingContext = EnclosingDecl;
|
||||
} else {
|
||||
if (ObjCCategoryDecl *CDecl =
|
||||
dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
|
||||
|
|
|
@ -476,6 +476,7 @@ void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
|
|||
CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
|
||||
*Reader.getContext());
|
||||
CD->setNextClassCategory(cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
CD->setHasSynthBitfield(Record[Idx++]);
|
||||
CD->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
CD->setCategoryNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
}
|
||||
|
@ -524,6 +525,7 @@ void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
|
|||
cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
llvm::tie(D->IvarInitializers, D->NumIvarInitializers)
|
||||
= Reader.ReadCXXBaseOrMemberInitializers(Cursor, Record, Idx);
|
||||
D->setHasSynthBitfield(Record[Idx++]);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -428,6 +428,7 @@ void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
|
|||
PL != PLEnd; ++PL)
|
||||
Writer.AddSourceLocation(*PL, Record);
|
||||
Writer.AddDeclRef(D->getNextClassCategory(), Record);
|
||||
Record.push_back(D->hasSynthBitfield());
|
||||
Writer.AddSourceLocation(D->getAtLoc(), Record);
|
||||
Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
|
||||
Code = serialization::DECL_OBJC_CATEGORY;
|
||||
|
@ -473,6 +474,7 @@ void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
|
|||
Writer.AddDeclRef(D->getSuperClass(), Record);
|
||||
Writer.AddCXXBaseOrMemberInitializers(D->IvarInitializers,
|
||||
D->NumIvarInitializers, Record);
|
||||
Record.push_back(D->hasSynthBitfield());
|
||||
Code = serialization::DECL_OBJC_IMPLEMENTATION;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi2 -emit-llvm -o %t %s
|
||||
// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi2 -emit-llvm -o %t %s
|
||||
// rdar: // 7824380
|
||||
|
||||
@interface Super {
|
||||
int ivar_super_a : 5;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface A : Super {
|
||||
@public
|
||||
int ivar_a : 5;
|
||||
}
|
||||
@end
|
||||
|
||||
int f0(A *a) {
|
||||
return a->ivar_a;
|
||||
}
|
||||
|
||||
@interface A () {
|
||||
@public
|
||||
int ivar_ext_a : 5;
|
||||
int ivar_ext_b : 5;
|
||||
}@end
|
||||
|
||||
int f1(A *a) {
|
||||
return a->ivar_ext_a + a->ivar_a;
|
||||
}
|
||||
|
||||
@interface A () {
|
||||
@public
|
||||
int ivar_ext2_a : 5;
|
||||
int ivar_ext2_b : 5;
|
||||
}@end
|
||||
|
||||
int f2(A* a) {
|
||||
return a->ivar_ext2_a + a->ivar_ext_a + a->ivar_a;
|
||||
}
|
||||
|
||||
@implementation A {
|
||||
@public
|
||||
int ivar_b : 5;
|
||||
int ivar_c : 5;
|
||||
int ivar_d : 5;
|
||||
}
|
||||
@end
|
||||
|
||||
int f3(A *a) {
|
||||
return a->ivar_d + a->ivar_ext2_a + a->ivar_ext_a + a->ivar_a;
|
||||
}
|
||||
|
Loading…
Reference in New Issue