From 2ec4d7ba07bb205b72320b37fd531703cb8e7753 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 16 Aug 2013 23:35:05 +0000 Subject: [PATCH] ObjectiveC migrator: Add some more routines for future work. No change otherwise. llvm-svn: 188591 --- clang/lib/ARCMigrate/ObjCMT.cpp | 73 ++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp index b6ea448a04be..496ef7d44694 100644 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/lib/ARCMigrate/ObjCMT.cpp @@ -48,8 +48,11 @@ class ObjCMigrateASTConsumer : public ASTConsumer { ObjCMethodDecl *OM, ObjCInstanceTypeFamily OIT_Family = OIT_None); - void migrateFunctionDeclAnnotation(ASTContext &Ctx, - const FunctionDecl *FuncDecl); + void migrateCFFunctions(ASTContext &Ctx, + const FunctionDecl *FuncDecl); + + bool migrateAddFunctionAnnotation(ASTContext &Ctx, + const FunctionDecl *FuncDecl); void migrateObjCMethodDeclAnnotation(ASTContext &Ctx, const ObjCMethodDecl *MethodDecl); @@ -66,6 +69,7 @@ public: Preprocessor &PP; bool IsOutputFile; llvm::SmallPtrSet ObjCProtocolDecls; + llvm::SmallVector CFFunctionIBCandidates; ObjCMigrateASTConsumer(StringRef migrateDir, bool migrateLiterals, @@ -756,35 +760,82 @@ void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx, ReplaceWithInstancetype(*this, OM); } -void ObjCMigrateASTConsumer::migrateFunctionDeclAnnotation( +static bool IsVoidStarType(QualType Ty) { + if (!Ty->isPointerType()) + return false; + + while (const TypedefType *TD = dyn_cast(Ty.getTypePtr())) + Ty = TD->getDecl()->getUnderlyingType(); + + // Is the type void*? + const PointerType* PT = Ty->getAs(); + if (PT->getPointeeType().getUnqualifiedType()->isVoidType()) + return true; + return IsVoidStarType(PT->getPointeeType()); +} + + +static bool +IsCFFunctionImplicitBridingingCandidate(ASTContext &Ctx, + const FunctionDecl *FuncDecl) { + CallEffects CE = CallEffects::getEffect(FuncDecl); + + RetEffect Ret = CE.getReturnValue(); + if (Ret.getObjKind() == RetEffect::CF) + // Still a candidate; + ; + else if (Ret.getObjKind() == RetEffect::AnyObj && + (Ret.getKind() == RetEffect::NoRet || Ret.getKind() == RetEffect::NoRetHard)) { + // This is a candidate as long as it is not of "void *" variety + if (IsVoidStarType(FuncDecl->getResultType())) + return false; + } + + // FIXME. Check on the arguments too. + + // FIXME. Always false for now. + return false; +} + +void ObjCMigrateASTConsumer::migrateCFFunctions( + ASTContext &Ctx, + const FunctionDecl *FuncDecl) { + // Finction must be annotated first. + bool Annotated = migrateAddFunctionAnnotation(Ctx, FuncDecl); + if (Annotated && IsCFFunctionImplicitBridingingCandidate(Ctx, FuncDecl)) + CFFunctionIBCandidates.push_back(FuncDecl); +} + +bool ObjCMigrateASTConsumer::migrateAddFunctionAnnotation( ASTContext &Ctx, const FunctionDecl *FuncDecl) { if (FuncDecl->hasAttr() || FuncDecl->getAttr() || - FuncDecl->getAttr() || - FuncDecl->hasBody()) - return; - + FuncDecl->getAttr()) + return true; + if (FuncDecl->hasBody()) + return false; CallEffects CE = CallEffects::getEffect(FuncDecl); RetEffect Ret = CE.getReturnValue(); const char *AnnotationString = 0; if (Ret.getObjKind() == RetEffect::CF && Ret.isOwned()) { if (!Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition()) - return; + return false; AnnotationString = " CF_RETURNS_RETAINED"; } else if (Ret.getObjKind() == RetEffect::CF && !Ret.isOwned()) { if (!Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition()) - return; + return false; AnnotationString = " CF_RETURNS_NOT_RETAINED"; } else - return; + return false; edit::Commit commit(*Editor); commit.insertAfterToken(FuncDecl->getLocEnd(), AnnotationString); Editor->commit(commit); + return true; } void ObjCMigrateASTConsumer::migrateObjCMethodDeclAnnotation( @@ -836,7 +887,7 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { migrateNSEnumDecl(Ctx, ED, TD); } else if (const FunctionDecl *FD = dyn_cast(*D)) - migrateFunctionDeclAnnotation(Ctx, FD); + migrateCFFunctions(Ctx, FD); else if (const ObjCMethodDecl *MD = dyn_cast(*D)) migrateObjCMethodDeclAnnotation(Ctx, MD);