[cfe-commits] r151662 - in /cfe/trunk: lib/Rewrite/RewriteModernObjC.cpp test/Rewriter/rewrite-modern-ivars-1.mm
Fariborz Jahanian
fjahanian at apple.com
Tue Feb 28 14:45:07 PST 2012
Author: fjahanian
Date: Tue Feb 28 16:45:07 2012
New Revision: 151662
URL: http://llvm.org/viewvc/llvm-project?rev=151662&view=rev
Log:
Modern objective-c translator. rewriting ivars of aggregate type.
Added:
cfe/trunk/test/Rewriter/rewrite-modern-ivars-1.mm
Modified:
cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
Modified: cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp?rev=151662&r1=151661&r2=151662&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp Tue Feb 28 16:45:07 2012
@@ -108,6 +108,7 @@
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 @@
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 @@
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 @@
Result += "_IMPL "; Result += RCDecl->getNameAsString();
Result += "_IVARS;\n";
}
-
- for (unsigned i = 0, e = IVars.size(); i < e; i++) {
- ObjCIvarDecl *IvarDecl = IVars[i];
- QualType Type = IvarDecl->getType();
- std::string Name = IvarDecl->getNameAsString();
+ TagsDefinedInIvarDecls.clear();
+ for (unsigned i = 0, e = IVars.size(); i < e; i++)
+ RewriteObjCFieldDecl(IVars[i], Result);
- 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);
Added: cfe/trunk/test/Rewriter/rewrite-modern-ivars-1.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-modern-ivars-1.mm?rev=151662&view=auto
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-modern-ivars-1.mm (added)
+++ cfe/trunk/test/Rewriter/rewrite-modern-ivars-1.mm Tue Feb 28 16:45:07 2012
@@ -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
+
+ at interface NSCheapMutableString {
+ at 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;
+}
+ at end
+
+ at interface III {
+ at 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;
+}
+ at end
+
More information about the cfe-commits
mailing list