void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCContainerDecl *D);
void migrateProtocolConformance(ASTContext &Ctx,
const ObjCImplementationDecl *ImpDecl);
+ void CacheObjCNSIntegerTypedefed(const TypedefDecl *TypedefDcl);
bool migrateNSEnumDecl(ASTContext &Ctx, const EnumDecl *EnumDcl,
const TypedefDecl *TypedefDcl);
void migrateAllMethodInstaceType(ASTContext &Ctx, ObjCContainerDecl *CDecl);
std::string MigrateDir;
unsigned ASTMigrateActions;
unsigned FileId;
+ const TypedefDecl *NSIntegerTypedefed;
+ const TypedefDecl *NSUIntegerTypedefed;
OwningPtr<NSAPI> NSAPIObj;
OwningPtr<edit::EditedSource> Editor;
FileRemapper &Remapper;
bool isOutputFile = false)
: MigrateDir(migrateDir),
ASTMigrateActions(astMigrateActions),
- FileId(0), Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
+ FileId(0), NSIntegerTypedefed(0), NSUIntegerTypedefed(0),
+ Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
IsOutputFile(isOutputFile) { }
protected:
ClassString += ')';
SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart());
commit.replace(R, ClassString);
- SourceLocation EndOfTypedefLoc = TypedefDcl->getLocEnd();
- EndOfTypedefLoc = trans::findLocationAfterSemi(EndOfTypedefLoc, NS.getASTContext(),
+ SourceLocation EndOfEnumDclLoc = EnumDcl->getLocEnd();
+ EndOfEnumDclLoc = trans::findSemiAfterLocation(EndOfEnumDclLoc,
+ NS.getASTContext(), /*IsDecl*/true);
+ if (!EndOfEnumDclLoc.isInvalid()) {
+ SourceRange EnumDclRange(EnumDcl->getLocStart(), EndOfEnumDclLoc);
+ commit.insertFromRange(TypedefDcl->getLocStart(), EnumDclRange);
+ }
+ else
+ return false;
+
+ SourceLocation EndTypedefDclLoc = TypedefDcl->getLocEnd();
+ EndTypedefDclLoc = trans::findSemiAfterLocation(EndTypedefDclLoc,
+ NS.getASTContext(), /*IsDecl*/true);
+ if (!EndTypedefDclLoc.isInvalid()) {
+ SourceRange TDRange(TypedefDcl->getLocStart(), EndTypedefDclLoc);
+ commit.remove(TDRange);
+ }
+ else
+ return false;
+
+ EndOfEnumDclLoc = trans::findLocationAfterSemi(EnumDcl->getLocEnd(), NS.getASTContext(),
/*IsDecl*/true);
- SourceLocation BeginOfTypedefLoc = TypedefDcl->getLocStart();
- if (!EndOfTypedefLoc.isInvalid()) {
- // FIXME. This assumes that typedef decl; is immediately preceeded by eoln.
- // It is trying to remove the typedef decl. line entirely.
- BeginOfTypedefLoc = BeginOfTypedefLoc.getLocWithOffset(-1);
- commit.remove(SourceRange(BeginOfTypedefLoc, EndOfTypedefLoc));
+ if (!EndOfEnumDclLoc.isInvalid()) {
+ SourceLocation BeginOfEnumDclLoc = EnumDcl->getLocStart();
+ // FIXME. This assumes that enum decl; is immediately preceeded by eoln.
+ // It is trying to remove the enum decl. lines entirely.
+ BeginOfEnumDclLoc = BeginOfEnumDclLoc.getLocWithOffset(-1);
+ commit.remove(SourceRange(BeginOfEnumDclLoc, EndOfEnumDclLoc));
return true;
}
return false;
Editor->commit(commit);
}
+void ObjCMigrateASTConsumer::CacheObjCNSIntegerTypedefed(
+ const TypedefDecl *TypedefDcl) {
+
+ QualType qt = TypedefDcl->getTypeSourceInfo()->getType();
+ if (NSAPIObj->isObjCNSIntegerType(qt))
+ NSIntegerTypedefed = TypedefDcl;
+ else if (NSAPIObj->isObjCNSUIntegerType(qt))
+ NSUIntegerTypedefed = TypedefDcl;
+}
+
bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
const EnumDecl *EnumDcl,
const TypedefDecl *TypedefDcl) {
if (!EnumDcl->isCompleteDefinition() || EnumDcl->getIdentifier() ||
- !TypedefDcl->getIdentifier() ||
- EnumDcl->isDeprecated() || TypedefDcl->isDeprecated())
+ EnumDcl->isDeprecated())
+ return false;
+ if (!TypedefDcl) {
+ if (NSIntegerTypedefed) {
+ TypedefDcl = NSIntegerTypedefed;
+ NSIntegerTypedefed = 0;
+ }
+ else if (NSUIntegerTypedefed) {
+ TypedefDcl = NSUIntegerTypedefed;
+ NSUIntegerTypedefed = 0;
+ }
+ else
+ return false;
+ unsigned FileIdOfTypedefDcl =
+ PP.getSourceManager().getFileID(TypedefDcl->getLocation()).getHashValue();
+ unsigned FileIdOfEnumDcl =
+ PP.getSourceManager().getFileID(EnumDcl->getLocation()).getHashValue();
+ if (FileIdOfTypedefDcl != FileIdOfEnumDcl)
+ return false;
+ }
+ if (TypedefDcl->isDeprecated())
return false;
QualType qt = TypedefDcl->getTypeSourceInfo()->getType();
if (IsNSUIntegerType && !Ctx.Idents.get("NS_OPTIONS").hasMacroDefinition())
return false;
edit::Commit commit(*Editor);
- rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit, IsNSIntegerType, NSOptions);
+ bool Res = rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj,
+ commit, IsNSIntegerType, NSOptions);
Editor->commit(commit);
- return true;
+ return Res;
}
static void ReplaceWithInstancetype(const ObjCMigrateASTConsumer &ASTC,
migrateProtocolConformance(Ctx, ImpDecl);
}
else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) {
+ if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros))
+ continue;
DeclContext::decl_iterator N = D;
- ++N;
- if (N != DEnd)
- if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N)) {
- if (ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros) {
- if (migrateNSEnumDecl(Ctx, ED, TD))
- D++;
- }
- }
+ if (++N != DEnd) {
+ const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N);
+ if (migrateNSEnumDecl(Ctx, ED, TD) && TD)
+ D++;
+ }
+ else
+ migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */0);
}
else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*D)) {
- DeclContext::decl_iterator N = D;
- ++N;
- if (N != DEnd)
- if (const EnumDecl *ED = dyn_cast<EnumDecl>(*N)) {
- if (ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros) {
- if (migrateNSEnumDecl(Ctx, ED, TD))
+ if (ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros) {
+ DeclContext::decl_iterator N = D;
+ if (++N != DEnd)
+ if (const EnumDecl *ED = dyn_cast<EnumDecl>(*N)) {
+ if (migrateNSEnumDecl(Ctx, ED, TD)) {
++D;
+ continue;
+ }
}
- }
+ CacheObjCNSIntegerTypedefed(TD);
+ }
}
else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*D)) {
if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)