[cfe-commits] r138772 - in /cfe/trunk: lib/Rewrite/RewriteObjC.cpp test/Rewriter/rewrite-forward-class.mm
Fariborz Jahanian
fjahanian at apple.com
Mon Aug 29 15:21:46 PDT 2011
Author: fjahanian
Date: Mon Aug 29 17:21:46 2011
New Revision: 138772
URL: http://llvm.org/viewvc/llvm-project?rev=138772&view=rev
Log:
Fix a rewriter bug caused by recent changes in objc's
group decls.
Added:
cfe/trunk/test/Rewriter/rewrite-forward-class.mm
Modified:
cfe/trunk/lib/Rewrite/RewriteObjC.cpp
Modified: cfe/trunk/lib/Rewrite/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteObjC.cpp?rev=138772&r1=138771&r2=138772&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteObjC.cpp Mon Aug 29 17:21:46 2011
@@ -247,6 +247,10 @@
// Syntactic Rewriting.
void RewriteInclude();
void RewriteForwardClassDecl(DeclGroupRef D);
+ void RewriteForwardClassDecl(const llvm::SmallVector<Decl*, 8> &DG);
+ void RewriteForwardClassEpilogue(ObjCClassDecl *ClassDecl,
+ const std::string &typedefString);
+
void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
ObjCImplementationDecl *IMD,
ObjCCategoryImplDecl *CID);
@@ -722,8 +726,23 @@
// Recurse into linkage specifications
for (DeclContext::decl_iterator DI = LSD->decls_begin(),
DIEnd = LSD->decls_end();
- DI != DIEnd; ++DI)
+ DI != DIEnd; ) {
+ if (isa<ObjCClassDecl>((*DI))) {
+ SmallVector<Decl *, 8> DG;
+ Decl *D = (*DI);
+ SourceLocation Loc = D->getLocation();
+ while (DI != DIEnd &&
+ isa<ObjCClassDecl>(D) && D->getLocation() == Loc) {
+ DG.push_back(D);
+ ++DI;
+ D = (*DI);
+ }
+ RewriteForwardClassDecl(DG);
+ continue;
+ }
HandleTopLevelSingleDecl(*DI);
+ ++DI;
+ }
}
// If we have a decl in the main file, see if we should rewrite it.
if (SM->isFromMainFile(Loc))
@@ -891,41 +910,61 @@
InsertText(onePastSemiLoc, Setr);
}
+static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
+ std::string &typedefString) {
+ typedefString += "#ifndef _REWRITER_typedef_";
+ typedefString += ForwardDecl->getNameAsString();
+ typedefString += "\n";
+ typedefString += "#define _REWRITER_typedef_";
+ typedefString += ForwardDecl->getNameAsString();
+ typedefString += "\n";
+ typedefString += "typedef struct objc_object ";
+ typedefString += ForwardDecl->getNameAsString();
+ typedefString += ";\n#endif\n";
+}
+
+void RewriteObjC::RewriteForwardClassEpilogue(ObjCClassDecl *ClassDecl,
+ const std::string &typedefString) {
+ SourceLocation startLoc = ClassDecl->getLocation();
+ const char *startBuf = SM->getCharacterData(startLoc);
+ const char *semiPtr = strchr(startBuf, ';');
+ // Replace the @class with typedefs corresponding to the classes.
+ ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
+}
+
void RewriteObjC::RewriteForwardClassDecl(DeclGroupRef D) {
- SourceLocation startLoc;
std::string typedefString;
- const char *startBuf = 0;
- const char *semiPtr = 0;
for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
ObjCClassDecl *ClassDecl = cast<ObjCClassDecl>(*I);
ObjCInterfaceDecl *ForwardDecl = ClassDecl->getForwardInterfaceDecl();
if (I == D.begin()) {
- // Get the start location and compute the semi location.
- startLoc = ClassDecl->getLocation();
- startBuf = SM->getCharacterData(startLoc);
- semiPtr = strchr(startBuf, ';');
+ // Translate to typedef's that forward reference structs with the same name
+ // as the class. As a convenience, we include the original declaration
+ // as a comment.
typedefString += "// @class ";
typedefString += ForwardDecl->getNameAsString();
typedefString += ";\n";
}
- // Translate to typedef's that forward reference structs with the same name
- // as the class. As a convenience, we include the original declaration
- // as a comment.
-
-
- typedefString += "#ifndef _REWRITER_typedef_";
- typedefString += ForwardDecl->getNameAsString();
- typedefString += "\n";
- typedefString += "#define _REWRITER_typedef_";
- typedefString += ForwardDecl->getNameAsString();
- typedefString += "\n";
- typedefString += "typedef struct objc_object ";
- typedefString += ForwardDecl->getNameAsString();
- typedefString += ";\n#endif\n";
+ RewriteOneForwardClassDecl(ForwardDecl, typedefString);
}
+ DeclGroupRef::iterator I = D.begin();
+ RewriteForwardClassEpilogue(cast<ObjCClassDecl>(*I), typedefString);
+}
- // Replace the @class with typedefs corresponding to the classes.
- ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
+void RewriteObjC::RewriteForwardClassDecl(
+ const llvm::SmallVector<Decl*, 8> &D) {
+ std::string typedefString;
+ for (unsigned i = 0; i < D.size(); i++) {
+ ObjCClassDecl *ClassDecl = cast<ObjCClassDecl>(D[i]);
+ ObjCInterfaceDecl *ForwardDecl = ClassDecl->getForwardInterfaceDecl();
+ if (i == 0) {
+ typedefString += "// @class ";
+ typedefString += ForwardDecl->getNameAsString();
+ typedefString += ";\n";
+ }
+ RewriteOneForwardClassDecl(ForwardDecl, typedefString);
+ }
+ RewriteForwardClassEpilogue(cast<ObjCClassDecl>(D[0]), typedefString);
}
void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
Added: cfe/trunk/test/Rewriter/rewrite-forward-class.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-forward-class.mm?rev=138772&view=auto
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-forward-class.mm (added)
+++ cfe/trunk/test/Rewriter/rewrite-forward-class.mm Mon Aug 29 17:21:46 2011
@@ -0,0 +1,44 @@
+// 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"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+
+extern "C" {
+ at class XX;
+ at class YY, ZZ, QQ;
+ at class ISyncClient, SMSession, ISyncManager, ISyncSession, SMDataclassInfo, SMClientInfo,
+ DMCConfiguration, DMCStatusEntry;
+
+ at interface QQ
+
+ at end
+
+ at interface SMDataclassInfo : QQ
+- (XX*) Meth;
+- (DMCStatusEntry*)Meth2;
+ at end
+
+ at implementation SMDataclassInfo
+- (XX*) Meth { return 0; }
+- (DMCStatusEntry*)Meth2 { return 0; }
+ at end
+
+ at interface YY
+{
+ ISyncClient *p1;
+ ISyncSession *p2;
+}
+ at property (copy) ISyncClient *p1;
+ at end
+
+ at implementation YY
+ at synthesize p1;
+ at end
+
+extern "C" {
+ at class CCC;
+ at class Protocol, P , Q;
+int I,J,K;
+};
+
+};
+
+
More information about the cfe-commits
mailing list