Objective-C SDK modernization. When modernizing to

use NS_ENUM/NS_OPTIONS macros, add an import of
Foundation.h (or its module) as necessary.
rdar://18498550

llvm-svn: 219225
This commit is contained in:
Fariborz Jahanian 2014-10-07 19:01:46 +00:00
parent 0cb3c9bb24
commit 80ebf8da7e
3 changed files with 73 additions and 7 deletions

View File

@ -81,6 +81,8 @@ class ObjCMigrateASTConsumer : public ASTConsumer {
void inferDesignatedInitializers(ASTContext &Ctx,
const ObjCImplementationDecl *ImplD);
bool InsertFoundation(ASTContext &Ctx, SourceLocation Loc);
public:
std::string MigrateDir;
@ -95,6 +97,7 @@ public:
const PPConditionalDirectiveRecord *PPRec;
Preprocessor &PP;
bool IsOutputFile;
bool FoundationIncluded;
llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ObjCProtocolDecls;
llvm::SmallVector<const Decl *, 8> CFFunctionIBCandidates;
llvm::StringMap<char> WhiteListFilenames;
@ -111,7 +114,8 @@ public:
ASTMigrateActions(astMigrateActions),
NSIntegerTypedefed(nullptr), NSUIntegerTypedefed(nullptr),
Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
IsOutputFile(isOutputFile) {
IsOutputFile(isOutputFile),
FoundationIncluded(false){
for (ArrayRef<std::string>::iterator
I = WhiteList.begin(), E = WhiteList.end(); I != E; ++I) {
@ -809,11 +813,8 @@ bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
if (const EnumType *EnumTy = qt->getAs<EnumType>()) {
if (EnumTy->getDecl() == EnumDcl) {
bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl);
if (NSOptions) {
if (!Ctx.Idents.get("NS_OPTIONS").hasMacroDefinition())
return false;
}
else if (!Ctx.Idents.get("NS_ENUM").hasMacroDefinition())
if (!Ctx.Idents.get("NS_ENUM").hasMacroDefinition() &&
!InsertFoundation(Ctx, TypedefDcl->getLocStart()))
return false;
edit::Commit commit(*Editor);
rewriteToNSMacroDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit, !NSOptions);
@ -827,7 +828,8 @@ bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
// We may still use NS_OPTIONS based on what we find in the enumertor list.
bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl);
// For sanity check, see if macro NS_ENUM can be seen.
if (!Ctx.Idents.get("NS_ENUM").hasMacroDefinition())
if (!Ctx.Idents.get("NS_ENUM").hasMacroDefinition()
&& !InsertFoundation(Ctx, TypedefDcl->getLocStart()))
return false;
edit::Commit commit(*Editor);
bool Res = rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj,
@ -1612,6 +1614,22 @@ void ObjCMigrateASTConsumer::inferDesignatedInitializers(
}
}
bool ObjCMigrateASTConsumer::InsertFoundation(ASTContext &Ctx,
SourceLocation Loc) {
if (FoundationIncluded)
return true;
if (Loc.isInvalid())
return false;
edit::Commit commit(*Editor);
if (Ctx.getLangOpts().Modules)
commit.insert(Loc, "@import Foundation;\n");
else
commit.insert(Loc, "#import <Foundation/Foundation.h>\n");
Editor->commit(commit);
FoundationIncluded = true;
return true;
}
namespace {
class RewritesReceiver : public edit::EditsReceiver {

View File

@ -0,0 +1,24 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -objcmt-migrate-ns-macros -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11
// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
// rdar://18498550
typedef long NSInteger;
enum {
UIViewNone = 0x0,
UIViewMargin = 0x1,
UIViewWidth = 0x2,
UIViewRightMargin = 0x3,
UIViewBottomMargin = 0xbadbeef
};
typedef NSInteger UITableStyle;
typedef
enum { two = 1 } NumericEnum2;
typedef enum { three = 1 } NumericEnum3;
typedef enum { four = 1 } NumericEnum4;

View File

@ -0,0 +1,24 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -objcmt-migrate-ns-macros -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11
// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
// rdar://18498550
typedef long NSInteger;
@import Foundation;
typedef NS_OPTIONS(NSUInteger, UITableStyle) {
UIViewNone = 0x0,
UIViewMargin = 0x1,
UIViewWidth = 0x2,
UIViewRightMargin = 0x3,
UIViewBottomMargin = 0xbadbeef
};
typedef
NS_ENUM(NSInteger, NumericEnum2) { two = 1 };
typedef NS_ENUM(NSInteger, NumericEnum3) { three = 1 };
typedef NS_ENUM(NSInteger, NumericEnum4) { four = 1 };