forked from OSchip/llvm-project
Modern objective-c translation: Fixing couple of bugs
related to laying out ivar structs and accessing non-fragile-ivar in more compilated cases. // rdar://11323187 llvm-svn: 156004
This commit is contained in:
parent
377f99bc68
commit
d7c6777d50
|
@ -3523,6 +3523,11 @@ bool RewriteModernObjC::IsTagDefinedInsideClass(ObjCContainerDecl *IDecl,
|
|||
/// It handles elaborated types, as well as enum types in the process.
|
||||
bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type,
|
||||
std::string &Result) {
|
||||
if (isa<TypedefType>(Type)) {
|
||||
Result += "\t";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Type->isArrayType()) {
|
||||
QualType ElemTy = Context->getBaseElementType(Type);
|
||||
return RewriteObjCFieldDeclType(ElemTy, Result);
|
||||
|
@ -3618,6 +3623,8 @@ void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl,
|
|||
void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl,
|
||||
std::string &Result) {
|
||||
QualType Type = fieldDecl->getType();
|
||||
if (isa<TypedefType>(Type))
|
||||
return;
|
||||
if (Type->isArrayType())
|
||||
Type = Context->getBaseElementType(Type);
|
||||
ObjCContainerDecl *IDecl =
|
||||
|
@ -7308,12 +7315,17 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
|
|||
addExpr);
|
||||
QualType IvarT = D->getType();
|
||||
|
||||
if (IvarT->isRecordType()) {
|
||||
if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
|
||||
RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
|
||||
RD = RD->getDefinition();
|
||||
if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
|
||||
// decltype(((Foo_IMPL*)0)->bar) *
|
||||
std::string RecName = iFaceDecl->getDecl()->getName();
|
||||
ObjCContainerDecl *CDecl =
|
||||
dyn_cast<ObjCContainerDecl>(D->getDeclContext());
|
||||
// ivar in class extensions requires special treatment.
|
||||
if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
|
||||
CDecl = CatDecl->getClassInterface();
|
||||
std::string RecName = CDecl->getName();
|
||||
RecName += "_IMPL";
|
||||
RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
|
||||
SourceLocation(), SourceLocation(),
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// RUN: %clang_cc1 -fblocks -rewrite-objc -fms-extensions %s -o %t-rw.cpp
|
||||
// RUN: %clang_cc1 -Werror -fsyntax-only -Wno-address-of-temporary -Wno-c++11-narrowing -std=c++11 -D"Class=void*" -D"id=void*" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp
|
||||
// rdar://11323187
|
||||
|
||||
typedef unsigned long NSUInteger;
|
||||
|
||||
typedef struct _NSRange {
|
||||
NSUInteger location;
|
||||
NSUInteger length;
|
||||
} NSRange;
|
||||
|
||||
typedef struct {
|
||||
NSUInteger _capacity;
|
||||
NSRange _ranges[0];
|
||||
} _NSRangeInfo;
|
||||
|
||||
@interface Foo{
|
||||
@protected
|
||||
struct _bar {
|
||||
int x:1;
|
||||
int y:1;
|
||||
} bar;
|
||||
union {
|
||||
struct {
|
||||
NSRange _range;
|
||||
} _singleRange;
|
||||
struct {
|
||||
void * _data;
|
||||
void *_reserved;
|
||||
} _multipleRanges;
|
||||
} _internal;
|
||||
}
|
||||
@end
|
||||
@implementation Foo
|
||||
- (void)x:(Foo *)other {
|
||||
bar.x = 0;
|
||||
bar.y = 1;
|
||||
self->_internal._singleRange._range = (( other ->bar.x) ? &( other ->_internal._singleRange._range) : ((NSRange *)(&(((_NSRangeInfo *)( other ->_internal._multipleRanges._data))->_ranges))))[0];
|
||||
}
|
||||
@end
|
||||
@interface FooS : Foo
|
||||
@end
|
||||
@implementation FooS
|
||||
- (void)y {
|
||||
|
||||
NSUInteger asdf = (( self ->bar.x) ? 1 : ((_NSRangeInfo *)( self ->_internal._multipleRanges._data))->_capacity );
|
||||
}
|
||||
@end
|
Loading…
Reference in New Issue