Modern objective-c translator. rewriting ivars of aggregate type.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151662 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fariborz Jahanian 2012-02-28 22:45:07 +00:00
Родитель e7e0168f62
Коммит 15f87771ca
2 изменённых файлов: 167 добавлений и 15 удалений

Просмотреть файл

@ -108,6 +108,7 @@ namespace {
llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
llvm::SmallPtrSet<TagDecl*, 8> TagsDefinedInIvarDecls;
SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
SmallVector<Stmt *, 32> Stmts;
SmallVector<int, 8> ObjCBcLabelNo;
@ -333,6 +334,8 @@ namespace {
void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
std::string &Result);
void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result);
void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
std::string &Result);
@ -3165,6 +3168,78 @@ bool RewriteModernObjC::BufferContainsPPDirectives(const char *startBuf,
return false;
}
/// RewriteObjCFieldDecl - This routine rewrites a field into the buffer.
/// It handles elaborated types, as well as enum types in the process.
void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl,
std::string &Result) {
QualType Type = fieldDecl->getType();
std::string Name = fieldDecl->getNameAsString();
if (Type->isRecordType()) {
RecordDecl *RD = Type->getAs<RecordType>()->getDecl();
if (RD->isCompleteDefinition()) {
if (RD->isStruct())
Result += "\n\tstruct ";
else if (RD->isUnion())
Result += "\n\tunion ";
else
assert(false && "class not allowed as an ivar type");
Result += RD->getName();
if (TagsDefinedInIvarDecls.count(RD)) {
// This struct is already defined. Do not write its definition again.
Result += " "; Result += Name; Result += ";\n";
return;
}
TagsDefinedInIvarDecls.insert(RD);
Result += " {\n";
for (RecordDecl::field_iterator i = RD->field_begin(),
e = RD->field_end(); i != e; ++i) {
FieldDecl *FD = *i;
RewriteObjCFieldDecl(FD, Result);
}
Result += "\t} ";
Result += Name; Result += ";\n";
return;
}
}
else if (Type->isEnumeralType()) {
EnumDecl *ED = Type->getAs<EnumType>()->getDecl();
if (ED->isCompleteDefinition()) {
Result += "\n\tenum ";
Result += ED->getName();
if (TagsDefinedInIvarDecls.count(ED)) {
// This enum is already defined. Do not write its definition again.
Result += " "; Result += Name; Result += ";\n";
return;
}
TagsDefinedInIvarDecls.insert(ED);
Result += " {\n";
for (EnumDecl::enumerator_iterator EC = ED->enumerator_begin(),
ECEnd = ED->enumerator_end(); EC != ECEnd; ++EC) {
Result += "\t"; Result += EC->getName(); Result += " = ";
llvm::APSInt Val = EC->getInitVal();
Result += Val.toString(10);
Result += ",\n";
}
Result += "\t} ";
Result += Name; Result += ";\n";
return;
}
}
Result += "\t";
convertObjCTypeToCStyleType(Type);
Type.getAsStringInternal(Name, Context->getPrintingPolicy());
Result += Name;
if (fieldDecl->isBitField()) {
Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context));
}
Result += ";\n";
}
/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
/// an objective-c class with ivars.
void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
@ -3205,22 +3280,10 @@ void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
Result += "_IMPL "; Result += RCDecl->getNameAsString();
Result += "_IVARS;\n";
}
TagsDefinedInIvarDecls.clear();
for (unsigned i = 0, e = IVars.size(); i < e; i++)
RewriteObjCFieldDecl(IVars[i], Result);
for (unsigned i = 0, e = IVars.size(); i < e; i++) {
ObjCIvarDecl *IvarDecl = IVars[i];
QualType Type = IvarDecl->getType();
std::string Name = IvarDecl->getNameAsString();
Result += "\t";
convertObjCTypeToCStyleType(Type);
Type.getAsStringInternal(Name, Context->getPrintingPolicy());
Result += Name;
if (IvarDecl->isBitField()) {
Result += " : "; Result += utostr(IvarDecl->getBitWidthValue(*Context));
}
Result += ";\n";
}
Result += "};\n";
endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
ReplaceText(LocStart, endBuf-startBuf, Result);

Просмотреть файл

@ -0,0 +1,89 @@
// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
@interface NSCheapMutableString {
@private
struct S s0;
union {
char *fat;
unsigned char *thin;
} contents;
struct {
unsigned int isFat:1;
unsigned int freeWhenDone:1;
unsigned int refs:30;
} flags;
struct S {
int iS1;
double dS1;
} others;
union U {
int iU1;
double dU1;
} u_others;
enum {
One, Two
} E1;
enum e {
Yes = 1,
No = 0
} BoOl;
struct S s1;
enum e E2;
union {
char *fat;
unsigned char *thin;
} Last_contents;
struct {
unsigned int isFat:1;
unsigned int freeWhenDone:1;
unsigned int refs:30;
} Last_flags;
}
@end
@interface III {
@private
struct S s0;
union {
char *fat;
unsigned char *thin;
} contents;
struct {
unsigned int isFat:1;
unsigned int freeWhenDone:1;
unsigned int refs:30;
} flags;
enum {
One1 = 1000, Two1, Three1
} E1;
struct S s1;
enum e E2;
union {
char *fat;
unsigned char *thin;
} Last_contents;
struct {
unsigned int isFat:1;
unsigned int freeWhenDone:1;
unsigned int refs:30;
} Last_flags;
}
@end