Keep track of all declarations of an Objective-C class (both forward
declarations and definitions) as ObjCInterfaceDecls within the same
redeclaration chain. This new representation matches what we do for
C/C++ variables/functions/classes/templates/etc., and makes it
possible to answer the query "where are all of the declarations of
this class?"
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146679 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp
index 8635ed4..b8b1497 100644
--- a/lib/Rewrite/RewriteObjC.cpp
+++ b/lib/Rewrite/RewriteObjC.cpp
@@ -653,8 +653,9 @@
ConstantStringClassReference = FVD;
return;
}
- } else if (ObjCInterfaceDecl *MD = dyn_cast<ObjCInterfaceDecl>(D)) {
- RewriteInterfaceDecl(MD);
+ } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+ if (ID->isThisDeclarationADefinition())
+ RewriteInterfaceDecl(ID);
} else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
RewriteCategoryDecl(CD);
} else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
@@ -673,9 +674,18 @@
SourceLocation Loc = D->getLocation();
while (DI != DIEnd &&
isa<ObjCClassDecl>(D) && D->getLocation() == Loc) {
+ ObjCClassDecl *Class = cast<ObjCClassDecl>(D);
DG.push_back(D);
++DI;
D = (*DI);
+
+ // Following the ObjCClassDecl, we should have the corresponding
+ // ObjCInterfaceDecl. Skip over it.
+ if (DI != DIEnd && isa<ObjCInterfaceDecl>(D) &&
+ Class->getForwardInterfaceDecl() == D) {
+ ++DI;
+ D = (*DI);
+ }
}
RewriteForwardClassDecl(DG);
continue;
@@ -1179,7 +1189,7 @@
void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
std::string ResultStr;
- if (!ObjCForwardDecls.count(ClassDecl)) {
+ if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) {
// we haven't seen a forward decl - generate a typedef.
ResultStr = "#ifndef _REWRITER_typedef_";
ResultStr += ClassDecl->getNameAsString();
@@ -1191,7 +1201,7 @@
ResultStr += ClassDecl->getNameAsString();
ResultStr += ";\n#endif\n";
// Mark this typedef as having been generated.
- ObjCForwardDecls.insert(ClassDecl);
+ ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl());
}
RewriteObjCInternalStruct(ClassDecl, ResultStr);
@@ -3130,7 +3140,7 @@
// If no ivars and no root or if its root, directly or indirectly,
// have no ivars (thus not synthesized) then no need to synthesize this class.
- if ((CDecl->isForwardDecl() || NumIvars == 0) &&
+ if ((!CDecl->isThisDeclarationADefinition() || NumIvars == 0) &&
(!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
ReplaceText(LocStart, endBuf-startBuf, Result);
@@ -5357,7 +5367,7 @@
// Explicitly declared @interface's are already synthesized.
if (CDecl->isImplicitInterfaceDecl()) {
- // FIXME: Implementation of a class with no @interface (legacy) doese not
+ // FIXME: Implementation of a class with no @interface (legacy) does not
// produce correct synthesis as yet.
RewriteObjCInternalStruct(CDecl, Result);
}