diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 27e8095534a65c..7050746e3a0380 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -432,20 +432,11 @@ if(NOT LLVM_STATIC_LINK_CXX_STDLIB) set(HAVE_CLANG_REPL_SUPPORT ON) endif() -option(CLANG_ENABLE_ARCMT "Build ARCMT." ON) option(CLANG_ENABLE_STATIC_ANALYZER "Include static analyzer in clang binary." ON) option(CLANG_ENABLE_PROTO_FUZZER "Build Clang protobuf fuzzer." OFF) -if(NOT CLANG_ENABLE_STATIC_ANALYZER AND CLANG_ENABLE_ARCMT) - message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT or Z3") -endif() - -if(CLANG_ENABLE_ARCMT) - set(CLANG_ENABLE_OBJC_REWRITER ON) -endif() - # This option is a stop-gap, we should commit to removing this as # soon as possible. See discussion: # https://discourse.llvm.org/t/rationale-for-removing-versioned-libclang-middle-ground-to-keep-it-behind-option/ diff --git a/clang/cmake/caches/Android.cmake b/clang/cmake/caches/Android.cmake index d5ca6b50d4ada7..c89e31f67cc9b1 100644 --- a/clang/cmake/caches/Android.cmake +++ b/clang/cmake/caches/Android.cmake @@ -2,7 +2,6 @@ set(LLVM_TARGETS_TO_BUILD X86 CACHE STRING "") -set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") set(CLANG_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") set(CLANG_TIDY_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") set(CLANG_VENDOR Android CACHE STRING "") diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index 784a883a3bf916..3db19c36acc581 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -44,7 +44,6 @@ set(CLANG_DEFAULT_LINKER lld CACHE STRING "") set(CLANG_DEFAULT_OBJCOPY llvm-objcopy CACHE STRING "") set(CLANG_DEFAULT_RTLIB compiler-rt CACHE STRING "") set(CLANG_DEFAULT_UNWINDLIB libunwind CACHE STRING "") -set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") set(CLANG_ENABLE_STATIC_ANALYZER ON CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") diff --git a/clang/cmake/caches/Fuchsia.cmake b/clang/cmake/caches/Fuchsia.cmake index 07637cd0ed08f0..83336589da305d 100644 --- a/clang/cmake/caches/Fuchsia.cmake +++ b/clang/cmake/caches/Fuchsia.cmake @@ -84,7 +84,6 @@ set(CLANG_DEFAULT_LINKER lld CACHE STRING "") set(CLANG_DEFAULT_OBJCOPY llvm-objcopy CACHE STRING "") set(CLANG_DEFAULT_RTLIB compiler-rt CACHE STRING "") set(CLANG_DEFAULT_UNWINDLIB libunwind CACHE STRING "") -set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") set(CLANG_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3f58e64cf0ccbc..c168606af609ed 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -58,6 +58,8 @@ code bases. containing strict-aliasing violations. The new default behavior can be disabled using ``-fno-pointer-tbaa``. +- The Objective-C ARC migrator (ARCMigrate) has been removed. + C/C++ Language Potentially Breaking Changes ------------------------------------------- diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 8fc06328f0bcef..ee9e159b6dad76 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -5850,66 +5850,6 @@ CINDEX_LINKAGE const char *clang_EvalResult_getAsStr(CXEvalResult E); * Disposes the created Eval memory. */ CINDEX_LINKAGE void clang_EvalResult_dispose(CXEvalResult E); -/** - * @} - */ - -/** \defgroup CINDEX_REMAPPING Remapping functions - * - * @{ - */ - -/** - * A remapping of original source files and their translated files. - */ -typedef void *CXRemapping; - -/** - * Retrieve a remapping. - * - * \param path the path that contains metadata about remappings. - * - * \returns the requested remapping. This remapping must be freed - * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred. - */ -CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *path); - -/** - * Retrieve a remapping. - * - * \param filePaths pointer to an array of file paths containing remapping info. - * - * \param numFiles number of file paths. - * - * \returns the requested remapping. This remapping must be freed - * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred. - */ -CINDEX_LINKAGE -CXRemapping clang_getRemappingsFromFileList(const char **filePaths, - unsigned numFiles); - -/** - * Determine the number of remappings. - */ -CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping); - -/** - * Get the original and the associated filename from the remapping. - * - * \param original If non-NULL, will be set to the original filename. - * - * \param transformed If non-NULL, will be set to the filename that the original - * is associated with. - */ -CINDEX_LINKAGE void clang_remap_getFilenames(CXRemapping, unsigned index, - CXString *original, - CXString *transformed); - -/** - * Dispose the remapping. - */ -CINDEX_LINKAGE void clang_remap_dispose(CXRemapping); - /** * @} */ diff --git a/clang/include/clang/ARCMigrate/ARCMT.h b/clang/include/clang/ARCMigrate/ARCMT.h deleted file mode 100644 index 2b950e3d2cc2bf..00000000000000 --- a/clang/include/clang/ARCMigrate/ARCMT.h +++ /dev/null @@ -1,130 +0,0 @@ -//===-- ARCMT.h - ARC Migration Rewriter ------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_H -#define LLVM_CLANG_ARCMIGRATE_ARCMT_H - -#include "clang/ARCMigrate/FileRemapper.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Frontend/CompilerInvocation.h" - -namespace clang { - class ASTContext; - class DiagnosticConsumer; - class PCHContainerOperations; - -namespace arcmt { - class MigrationPass; - -/// Creates an AST with the provided CompilerInvocation but with these -/// changes: -/// -if a PCH/PTH is set, the original header is used instead -/// -Automatic Reference Counting mode is enabled -/// -/// It then checks the AST and produces errors/warning for ARC migration issues -/// that the user needs to handle manually. -/// -/// \param emitPremigrationARCErrors if true all ARC errors will get emitted -/// even if the migrator can fix them, but the function will still return false -/// if all ARC errors can be fixed. -/// -/// \param plistOut if non-empty, it is the file path to store the plist with -/// the pre-migration ARC diagnostics. -/// -/// \returns false if no error is produced, true otherwise. -bool -checkForManualIssues(CompilerInvocation &CI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient, - bool emitPremigrationARCErrors = false, - StringRef plistOut = StringRef()); - -/// Works similar to checkForManualIssues but instead of checking, it -/// applies automatic modifications to source files to conform to ARC. -/// -/// \returns false if no error is produced, true otherwise. -bool -applyTransformations(CompilerInvocation &origCI, - const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient); - -/// Applies automatic modifications and produces temporary files -/// and metadata into the \p outputDir path. -/// -/// \param emitPremigrationARCErrors if true all ARC errors will get emitted -/// even if the migrator can fix them, but the function will still return false -/// if all ARC errors can be fixed. -/// -/// \param plistOut if non-empty, it is the file path to store the plist with -/// the pre-migration ARC diagnostics. -/// -/// \returns false if no error is produced, true otherwise. -bool migrateWithTemporaryFiles( - CompilerInvocation &origCI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient, StringRef outputDir, - bool emitPremigrationARCErrors, StringRef plistOut); - -/// Get the set of file remappings from the \p outputDir path that -/// migrateWithTemporaryFiles produced. -/// -/// \returns false if no error is produced, true otherwise. -bool getFileRemappings(std::vector > &remap, - StringRef outputDir, - DiagnosticConsumer *DiagClient); - -/// Get the set of file remappings from a list of files with remapping -/// info. -/// -/// \returns false if no error is produced, true otherwise. -bool getFileRemappingsFromFileList( - std::vector > &remap, - ArrayRef remapFiles, - DiagnosticConsumer *DiagClient); - -typedef void (*TransformFn)(MigrationPass &pass); - -std::vector getAllTransformations(LangOptions::GCMode OrigGCMode, - bool NoFinalizeRemoval); - -class MigrationProcess { - CompilerInvocation OrigCI; - std::shared_ptr PCHContainerOps; - DiagnosticConsumer *DiagClient; - FileRemapper Remapper; - -public: - bool HadARCErrors; - - MigrationProcess(CompilerInvocation &CI, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *diagClient, - StringRef outputDir = StringRef()); - - class RewriteListener { - public: - virtual ~RewriteListener(); - - virtual void start(ASTContext &Ctx) { } - virtual void finish() { } - - virtual void insert(SourceLocation loc, StringRef text) { } - virtual void remove(CharSourceRange range) { } - }; - - bool applyTransform(TransformFn trans, RewriteListener *listener = nullptr); - - FileRemapper &getRemapper() { return Remapper; } -}; - -} // end namespace arcmt - -} // end namespace clang - -#endif diff --git a/clang/include/clang/ARCMigrate/ARCMTActions.h b/clang/include/clang/ARCMigrate/ARCMTActions.h deleted file mode 100644 index 714f4b33db446b..00000000000000 --- a/clang/include/clang/ARCMigrate/ARCMTActions.h +++ /dev/null @@ -1,76 +0,0 @@ -//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ARCMIGRATE_ARCMTACTIONS_H -#define LLVM_CLANG_ARCMIGRATE_ARCMTACTIONS_H - -#include "clang/ARCMigrate/FileRemapper.h" -#include "clang/Frontend/FrontendAction.h" -#include - -namespace clang { -namespace arcmt { - -class CheckAction : public WrapperFrontendAction { -protected: - bool BeginInvocation(CompilerInstance &CI) override; - -public: - CheckAction(std::unique_ptr WrappedAction); -}; - -class ModifyAction : public WrapperFrontendAction { -protected: - bool BeginInvocation(CompilerInstance &CI) override; - -public: - ModifyAction(std::unique_ptr WrappedAction); -}; - -class MigrateSourceAction : public ASTFrontendAction { - FileRemapper Remapper; -protected: - bool BeginInvocation(CompilerInstance &CI) override; - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override; -}; - -class MigrateAction : public WrapperFrontendAction { - std::string MigrateDir; - std::string PlistOut; - bool EmitPremigrationARCErrors; -protected: - bool BeginInvocation(CompilerInstance &CI) override; - -public: - MigrateAction(std::unique_ptr WrappedAction, - StringRef migrateDir, - StringRef plistOut, - bool emitPremigrationARCErrors); -}; - -/// Migrates to modern ObjC syntax. -class ObjCMigrateAction : public WrapperFrontendAction { - std::string MigrateDir; - unsigned ObjCMigAction; - FileRemapper Remapper; - CompilerInstance *CompInst; -public: - ObjCMigrateAction(std::unique_ptr WrappedAction, - StringRef migrateDir, unsigned migrateAction); - -protected: - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override; - bool BeginInvocation(CompilerInstance &CI) override; -}; - -} -} - -#endif diff --git a/clang/include/clang/ARCMigrate/FileRemapper.h b/clang/include/clang/ARCMigrate/FileRemapper.h deleted file mode 100644 index afcee363516a21..00000000000000 --- a/clang/include/clang/ARCMigrate/FileRemapper.h +++ /dev/null @@ -1,84 +0,0 @@ -//===-- FileRemapper.h - File Remapping Helper ------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H -#define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H - -#include "clang/Basic/FileEntry.h" -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" -#include -#include - -namespace llvm { - class MemoryBuffer; - class MemoryBufferRef; -} - -namespace clang { - class FileManager; - class DiagnosticsEngine; - class PreprocessorOptions; - -namespace arcmt { - -class FileRemapper { - // FIXME: Reuse the same FileManager for multiple ASTContexts. - std::unique_ptr FileMgr; - - using Target = std::variant; - using MappingsTy = llvm::DenseMap; - MappingsTy FromToMappings; - - llvm::DenseMap ToFromMappings; - -public: - FileRemapper(); - ~FileRemapper(); - - bool initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag, - bool ignoreIfFilesChanged); - bool initFromFile(StringRef filePath, DiagnosticsEngine &Diag, - bool ignoreIfFilesChanged); - bool flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag); - bool flushToFile(StringRef outputPath, DiagnosticsEngine &Diag); - - bool overwriteOriginal(DiagnosticsEngine &Diag, - StringRef outputDir = StringRef()); - - void remap(StringRef filePath, std::unique_ptr memBuf); - - void applyMappings(PreprocessorOptions &PPOpts) const; - - /// Iterate through all the mappings. - void forEachMapping( - llvm::function_ref CaptureFile, - llvm::function_ref - CaptureBuffer) const; - - void clear(StringRef outputDir = StringRef()); - -private: - void remap(FileEntryRef file, std::unique_ptr memBuf); - void remap(FileEntryRef file, FileEntryRef newfile); - - OptionalFileEntryRef getOriginalFile(StringRef filePath); - void resetTarget(Target &targ); - - bool report(const Twine &err, DiagnosticsEngine &Diag); - - std::string getRemapInfoFile(StringRef outputDir); -}; - -} // end namespace arcmt - -} // end namespace clang - -#endif diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index f4a155bb00bb37..f26c906b46447a 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -402,16 +402,6 @@ def note_file_misc_sloc_usage : Note< def err_module_format_unhandled : Error< "no handler registered for module format '%0'">, DefaultFatal; -// TransformActions -// TODO: Use a custom category name to distinguish rewriter errors. -def err_mt_message : Error<"[rewriter] %0">, SuppressInSystemHeader; -def warn_mt_message : Warning<"[rewriter] %0">; -def note_mt_message : Note<"[rewriter] %0">; - -// ARCMigrate -def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">; -def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">; - // API notes def err_apinotes_message : Error<"%0">; def warn_apinotes_message : Warning<"%0">, InGroup>; diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake index 27ed69e21562bf..805721237609b1 100644 --- a/clang/include/clang/Config/config.h.cmake +++ b/clang/include/clang/Config/config.h.cmake @@ -76,8 +76,6 @@ #cmakedefine01 PPC_LINUX_DEFAULT_IEEELONGDOUBLE /* Enable each functionality of modules */ -#cmakedefine01 CLANG_ENABLE_ARCMT -#cmakedefine01 CLANG_ENABLE_OBJC_REWRITER #cmakedefine01 CLANG_ENABLE_STATIC_ANALYZER /* Spawn a new process clang.exe for the CC1 tool invocation, when necessary */ diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h index 04fa8b01b418f8..bb9444d2e9ccdc 100644 --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -60,7 +60,6 @@ class Action { PrecompileJobClass, ExtractAPIJobClass, AnalyzeJobClass, - MigrateJobClass, CompileJobClass, BackendJobClass, AssembleJobClass, @@ -459,17 +458,6 @@ class AnalyzeJobAction : public JobAction { } }; -class MigrateJobAction : public JobAction { - void anchor() override; - -public: - MigrateJobAction(Action *Input, types::ID OutputType); - - static bool classof(const Action *A) { - return A->getKind() == MigrateJobClass; - } -}; - class CompileJobAction : public JobAction { void anchor() override; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index a89a4e8f8ec985..642d2a1268a002 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -692,20 +692,6 @@ def ccc_print_phases : Flag<["-"], "ccc-print-phases">, def ccc_print_bindings : Flag<["-"], "ccc-print-bindings">, InternalDebugOpt, HelpText<"Show bindings of tools to actions">; -def ccc_arcmt_check : Flag<["-"], "ccc-arcmt-check">, InternalDriverOpt, - HelpText<"Check for ARC migration issues that need manual handling">; -def ccc_arcmt_modify : Flag<["-"], "ccc-arcmt-modify">, InternalDriverOpt, - HelpText<"Apply modifications to files to conform to ARC">; -def ccc_arcmt_migrate : Separate<["-"], "ccc-arcmt-migrate">, InternalDriverOpt, - HelpText<"Apply modifications and produces temporary files that conform to ARC">; -def arcmt_migrate_report_output : Separate<["-"], "arcmt-migrate-report-output">, - HelpText<"Output path for the plist report">, - Visibility<[ClangOption, CC1Option]>, - MarshallingInfoString>; -def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">, - HelpText<"Emit ARC errors even if the migrator can fix them">, - Visibility<[ClangOption, CC1Option]>, - MarshallingInfoFlag>; def gen_reproducer_eq: Joined<["-"], "gen-reproducer=">, Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CLOption, DXCOption]>, HelpText<"Emit reproducer on (option: off, crash (default), error, always)">; @@ -721,87 +707,6 @@ def no_round_trip_args : Flag<["-"], "no-round-trip-args">, Visibility<[CC1Option]>, HelpText<"Disable command line arguments round-trip.">; -def _migrate : Flag<["--"], "migrate">, Flags<[NoXarchOption]>, - HelpText<"Run the migrator">; -def ccc_objcmt_migrate : Separate<["-"], "ccc-objcmt-migrate">, - InternalDriverOpt, - HelpText<"Apply modifications and produces temporary files to migrate to " - "modern ObjC syntax">; - -def objcmt_migrate_literals : Flag<["-"], "objcmt-migrate-literals">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC literals">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_Literals">; -def objcmt_migrate_subscripting : Flag<["-"], "objcmt-migrate-subscripting">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC subscripting">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_Subscripting">; -def objcmt_migrate_property : Flag<["-"], "objcmt-migrate-property">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC property">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_Property">; -def objcmt_migrate_all : Flag<["-"], "objcmt-migrate-all">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_MigrateDecls">; -def objcmt_migrate_readonly_property : Flag<["-"], "objcmt-migrate-readonly-property">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC readonly property">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_ReadonlyProperty">; -def objcmt_migrate_readwrite_property : Flag<["-"], "objcmt-migrate-readwrite-property">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC readwrite property">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_ReadwriteProperty">; -def objcmt_migrate_property_dot_syntax : Flag<["-"], "objcmt-migrate-property-dot-syntax">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration of setter/getter messages to property-dot syntax">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_PropertyDotSyntax">; -def objcmt_migrate_annotation : Flag<["-"], "objcmt-migrate-annotation">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to property and method annotations">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_Annotation">; -def objcmt_migrate_instancetype : Flag<["-"], "objcmt-migrate-instancetype">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to infer instancetype for method result type">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_Instancetype">; -def objcmt_migrate_nsmacros : Flag<["-"], "objcmt-migrate-ns-macros">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to NS_ENUM/NS_OPTIONS macros">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_NsMacros">; -def objcmt_migrate_protocol_conformance : Flag<["-"], "objcmt-migrate-protocol-conformance">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to add protocol conformance on classes">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_ProtocolConformance">; -def objcmt_atomic_property : Flag<["-"], "objcmt-atomic-property">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Make migration to 'atomic' properties">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_AtomicProperty">; -def objcmt_returns_innerpointer_property : Flag<["-"], "objcmt-returns-innerpointer-property">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_ReturnsInnerPointerProperty">; -def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty">; -def objcmt_migrate_designated_init : Flag<["-"], "objcmt-migrate-designated-init">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_DesignatedInitializer">; - -def objcmt_allowlist_dir_path: Joined<["-"], "objcmt-allowlist-dir-path=">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Only modify files with a filename contained in the provided directory path">, - MarshallingInfoString>; -def : Joined<["-"], "objcmt-whitelist-dir-path=">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Alias for -objcmt-allowlist-dir-path">, - Alias; -// The misspelt "white-list" [sic] alias is due for removal. -def : Joined<["-"], "objcmt-white-list-dir-path=">, - Visibility<[ClangOption, CC1Option]>, - Alias; - // Make sure all other -ccc- options are rejected. def ccc_ : Joined<["-"], "ccc-">, Group, Flags<[Unsupported]>; @@ -7388,7 +7293,7 @@ def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfie def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">, HelpText<"Turn off Type Based Alias Analysis">, MarshallingInfoFlag>; -defm pointer_tbaa: BoolOption<"", "pointer-tbaa", CodeGenOpts<"PointerTBAA">, +defm pointer_tbaa: BoolOption<"", "pointer-tbaa", CodeGenOpts<"PointerTBAA">, DefaultTrue, PosFlag, NegFlag, @@ -7899,8 +7804,6 @@ def rewrite_test : Flag<["-"], "rewrite-test">, HelpText<"Rewriter playground">; def rewrite_macros : Flag<["-"], "rewrite-macros">, HelpText<"Expand macros without full preprocessing">; -def migrate : Flag<["-"], "migrate">, - HelpText<"Migrate source code">; def compiler_options_dump : Flag<["-"], "compiler-options-dump">, HelpText<"Dump the compiler configuration options">; def print_dependency_directives_minimized_source : Flag<["-"], @@ -7914,17 +7817,6 @@ defm emit_llvm_uselists : BoolOption<"", "emit-llvm-uselists", NegFlag, BothFlags<[], [ClangOption], " order of LLVM use-lists when serializing">>; -def mt_migrate_directory : Separate<["-"], "mt-migrate-directory">, - HelpText<"Directory for temporary files produced during ARC or ObjC migration">, - MarshallingInfoString>; - -def arcmt_action_EQ : Joined<["-"], "arcmt-action=">, Visibility<[CC1Option]>, - HelpText<"The ARC migration action to take">, - Values<"check,modify,migrate">, - NormalizedValuesScope<"FrontendOptions">, - NormalizedValues<["ARCMT_Check", "ARCMT_Modify", "ARCMT_Migrate"]>, - MarshallingInfoEnum, "ARCMT_None">; - def print_stats : Flag<["-"], "print-stats">, HelpText<"Print performance metrics and statistics">, MarshallingInfoFlag>; diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 8241925c984763..fcab424057a744 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -129,9 +129,6 @@ enum ActionKind { /// Expand macros but not \#includes. RewriteMacros, - /// ObjC->C Rewriter. - RewriteObjC, - /// Rewriter playground RewriteTest, @@ -141,9 +138,6 @@ enum ActionKind { /// Dump template instantiations TemplightDump, - /// Run migrator. - MigrateSource, - /// Just lex, no output. RunPreprocessorOnly, @@ -330,10 +324,6 @@ class FrontendOptions { LLVM_PREFERRED_TYPE(bool) unsigned FixToTemporaries : 1; - /// Emit ARC errors even if the migrator can fix them. - LLVM_PREFERRED_TYPE(bool) - unsigned ARCMTMigrateEmitARCErrors : 1; - /// Skip over function bodies to speed up parsing in cases you do not need /// them (e.g. with code completion). LLVM_PREFERRED_TYPE(bool) @@ -424,72 +414,6 @@ class FrontendOptions { /// Specifies the output format of the AST. ASTDumpOutputFormat ASTDumpFormat = ADOF_Default; - enum { - ARCMT_None, - ARCMT_Check, - ARCMT_Modify, - ARCMT_Migrate - } ARCMTAction = ARCMT_None; - - enum { - ObjCMT_None = 0, - - /// Enable migration to modern ObjC literals. - ObjCMT_Literals = 0x1, - - /// Enable migration to modern ObjC subscripting. - ObjCMT_Subscripting = 0x2, - - /// Enable migration to modern ObjC readonly property. - ObjCMT_ReadonlyProperty = 0x4, - - /// Enable migration to modern ObjC readwrite property. - ObjCMT_ReadwriteProperty = 0x8, - - /// Enable migration to modern ObjC property. - ObjCMT_Property = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty), - - /// Enable annotation of ObjCMethods of all kinds. - ObjCMT_Annotation = 0x10, - - /// Enable migration of ObjC methods to 'instancetype'. - ObjCMT_Instancetype = 0x20, - - /// Enable migration to NS_ENUM/NS_OPTIONS macros. - ObjCMT_NsMacros = 0x40, - - /// Enable migration to add conforming protocols. - ObjCMT_ProtocolConformance = 0x80, - - /// prefer 'atomic' property over 'nonatomic'. - ObjCMT_AtomicProperty = 0x100, - - /// annotate property with NS_RETURNS_INNER_POINTER - ObjCMT_ReturnsInnerPointerProperty = 0x200, - - /// use NS_NONATOMIC_IOSONLY for property 'atomic' attribute - ObjCMT_NsAtomicIOSOnlyProperty = 0x400, - - /// Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods. - ObjCMT_DesignatedInitializer = 0x800, - - /// Enable converting setter/getter expressions to property-dot syntx. - ObjCMT_PropertyDotSyntax = 0x1000, - - ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty | - ObjCMT_Annotation | ObjCMT_Instancetype | - ObjCMT_NsMacros | ObjCMT_ProtocolConformance | - ObjCMT_NsAtomicIOSOnlyProperty | - ObjCMT_DesignatedInitializer), - ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | - ObjCMT_MigrateDecls | ObjCMT_PropertyDotSyntax) - }; - unsigned ObjCMTAction = ObjCMT_None; - std::string ObjCMTAllowListPath; - - std::string MTMigrateDir; - std::string ARCMTMigrateReportOut; - /// The input kind, either specified via -x argument or deduced from the input /// file name. InputKind DashX; @@ -596,14 +520,14 @@ class FrontendOptions { : DisableFree(false), RelocatablePCH(false), ShowHelp(false), ShowStats(false), AppendStats(false), ShowVersion(false), FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false), - FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false), - SkipFunctionBodies(false), UseGlobalModuleIndex(true), - GenerateGlobalModuleIndex(true), ASTDumpDecls(false), - ASTDumpLookups(false), BuildingImplicitModule(false), - BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false), - IncludeTimestamps(true), UseTemporary(true), - AllowPCMWithCompilerErrors(false), ModulesShareFileManager(true), - EmitSymbolGraph(false), EmitExtensionSymbolGraphs(false), + FixToTemporaries(false), SkipFunctionBodies(false), + UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true), + ASTDumpDecls(false), ASTDumpLookups(false), + BuildingImplicitModule(false), BuildingImplicitModuleUsesLock(true), + ModulesEmbedAllFiles(false), IncludeTimestamps(true), + UseTemporary(true), AllowPCMWithCompilerErrors(false), + ModulesShareFileManager(true), EmitSymbolGraph(false), + EmitExtensionSymbolGraphs(false), EmitSymbolGraphSymbolLabelsForTesting(false), EmitPrettySymbolGraphs(false), GenReducedBMI(false), UseClangIRPipeline(false), TimeTraceGranularity(500), diff --git a/clang/include/clang/Rewrite/Frontend/FrontendActions.h b/clang/include/clang/Rewrite/Frontend/FrontendActions.h index 4e9d1941bce083..bbc21c38064144 100644 --- a/clang/include/clang/Rewrite/Frontend/FrontendActions.h +++ b/clang/include/clang/Rewrite/Frontend/FrontendActions.h @@ -56,12 +56,6 @@ class FixItRecompile : public WrapperFrontendAction { bool BeginInvocation(CompilerInstance &CI) override; }; -class RewriteObjCAction : public ASTFrontendAction { -protected: - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override; -}; - class RewriteMacrosAction : public PreprocessorFrontendAction { protected: void ExecuteAction() override; diff --git a/clang/lib/ARCMigrate/ARCMT.cpp b/clang/lib/ARCMigrate/ARCMT.cpp deleted file mode 100644 index 1a8a200f2fc194..00000000000000 --- a/clang/lib/ARCMigrate/ARCMT.cpp +++ /dev/null @@ -1,616 +0,0 @@ -//===--- ARCMT.cpp - Migration to ARC mode --------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "clang/ARCMigrate/ARCMT.h" -#include "Internals.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/Basic/DiagnosticCategories.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendAction.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Frontend/Utils.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Lex/PreprocessorOptions.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "clang/Serialization/ASTReader.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/TargetParser/Triple.h" -#include -using namespace clang; -using namespace arcmt; - -bool CapturedDiagList::clearDiagnostic(ArrayRef IDs, - SourceRange range) { - if (range.isInvalid()) - return false; - - bool cleared = false; - ListTy::iterator I = List.begin(); - while (I != List.end()) { - FullSourceLoc diagLoc = I->getLocation(); - if ((IDs.empty() || // empty means clear all diagnostics in the range. - llvm::is_contained(IDs, I->getID())) && - !diagLoc.isBeforeInTranslationUnitThan(range.getBegin()) && - (diagLoc == range.getEnd() || - diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) { - cleared = true; - ListTy::iterator eraseS = I++; - if (eraseS->getLevel() != DiagnosticsEngine::Note) - while (I != List.end() && I->getLevel() == DiagnosticsEngine::Note) - ++I; - // Clear the diagnostic and any notes following it. - I = List.erase(eraseS, I); - continue; - } - - ++I; - } - - return cleared; -} - -bool CapturedDiagList::hasDiagnostic(ArrayRef IDs, - SourceRange range) const { - if (range.isInvalid()) - return false; - - ListTy::const_iterator I = List.begin(); - while (I != List.end()) { - FullSourceLoc diagLoc = I->getLocation(); - if ((IDs.empty() || // empty means any diagnostic in the range. - llvm::is_contained(IDs, I->getID())) && - !diagLoc.isBeforeInTranslationUnitThan(range.getBegin()) && - (diagLoc == range.getEnd() || - diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) { - return true; - } - - ++I; - } - - return false; -} - -void CapturedDiagList::reportDiagnostics(DiagnosticsEngine &Diags) const { - for (ListTy::const_iterator I = List.begin(), E = List.end(); I != E; ++I) - Diags.Report(*I); -} - -bool CapturedDiagList::hasErrors() const { - for (ListTy::const_iterator I = List.begin(), E = List.end(); I != E; ++I) - if (I->getLevel() >= DiagnosticsEngine::Error) - return true; - - return false; -} - -namespace { - -class CaptureDiagnosticConsumer : public DiagnosticConsumer { - DiagnosticsEngine &Diags; - DiagnosticConsumer &DiagClient; - CapturedDiagList &CapturedDiags; - bool HasBegunSourceFile; -public: - CaptureDiagnosticConsumer(DiagnosticsEngine &diags, - DiagnosticConsumer &client, - CapturedDiagList &capturedDiags) - : Diags(diags), DiagClient(client), CapturedDiags(capturedDiags), - HasBegunSourceFile(false) { } - - void BeginSourceFile(const LangOptions &Opts, - const Preprocessor *PP) override { - // Pass BeginSourceFile message onto DiagClient on first call. - // The corresponding EndSourceFile call will be made from an - // explicit call to FinishCapture. - if (!HasBegunSourceFile) { - DiagClient.BeginSourceFile(Opts, PP); - HasBegunSourceFile = true; - } - } - - void FinishCapture() { - // Call EndSourceFile on DiagClient on completion of capture to - // enable VerifyDiagnosticConsumer to check diagnostics *after* - // it has received the diagnostic list. - if (HasBegunSourceFile) { - DiagClient.EndSourceFile(); - HasBegunSourceFile = false; - } - } - - ~CaptureDiagnosticConsumer() override { - assert(!HasBegunSourceFile && "FinishCapture not called!"); - } - - void HandleDiagnostic(DiagnosticsEngine::Level level, - const Diagnostic &Info) override { - if (DiagnosticIDs::isARCDiagnostic(Info.getID()) || - level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) { - if (Info.getLocation().isValid()) - CapturedDiags.push_back(StoredDiagnostic(level, Info)); - return; - } - - // Non-ARC warnings are ignored. - Diags.setLastDiagnosticIgnored(true); - } -}; - -} // end anonymous namespace - -static bool HasARCRuntime(CompilerInvocation &origCI) { - // This duplicates some functionality from Darwin::AddDeploymentTarget - // but this function is well defined, so keep it decoupled from the driver - // and avoid unrelated complications. - llvm::Triple triple(origCI.getTargetOpts().Triple); - - if (triple.isiOS()) - return triple.getOSMajorVersion() >= 5; - - if (triple.isWatchOS()) - return true; - - if (triple.getOS() == llvm::Triple::Darwin) - return triple.getOSMajorVersion() >= 11; - - if (triple.getOS() == llvm::Triple::MacOSX) { - return triple.getOSVersion() >= VersionTuple(10, 7); - } - - return false; -} - -static CompilerInvocation * -createInvocationForMigration(CompilerInvocation &origCI, - const PCHContainerReader &PCHContainerRdr) { - std::unique_ptr CInvok; - CInvok.reset(new CompilerInvocation(origCI)); - PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts(); - if (!PPOpts.ImplicitPCHInclude.empty()) { - // We can't use a PCH because it was likely built in non-ARC mode and we - // want to parse in ARC. Include the original header. - FileManager FileMgr(origCI.getFileSystemOpts()); - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(), - new IgnoringDiagConsumer())); - std::string OriginalFile = ASTReader::getOriginalSourceFile( - PPOpts.ImplicitPCHInclude, FileMgr, PCHContainerRdr, *Diags); - if (!OriginalFile.empty()) - PPOpts.Includes.insert(PPOpts.Includes.begin(), OriginalFile); - PPOpts.ImplicitPCHInclude.clear(); - } - std::string define = std::string(getARCMTMacroName()); - define += '='; - CInvok->getPreprocessorOpts().addMacroDef(define); - CInvok->getLangOpts().ObjCAutoRefCount = true; - CInvok->getLangOpts().setGC(LangOptions::NonGC); - CInvok->getDiagnosticOpts().ErrorLimit = 0; - CInvok->getDiagnosticOpts().PedanticErrors = 0; - - // Ignore -Werror flags when migrating. - std::vector WarnOpts; - for (std::vector::iterator - I = CInvok->getDiagnosticOpts().Warnings.begin(), - E = CInvok->getDiagnosticOpts().Warnings.end(); I != E; ++I) { - if (!StringRef(*I).starts_with("error")) - WarnOpts.push_back(*I); - } - WarnOpts.push_back("error=arc-unsafe-retained-assign"); - CInvok->getDiagnosticOpts().Warnings = std::move(WarnOpts); - - CInvok->getLangOpts().ObjCWeakRuntime = HasARCRuntime(origCI); - CInvok->getLangOpts().ObjCWeak = CInvok->getLangOpts().ObjCWeakRuntime; - - return CInvok.release(); -} - -static void emitPremigrationErrors(const CapturedDiagList &arcDiags, - DiagnosticOptions *diagOpts, - Preprocessor &PP) { - TextDiagnosticPrinter printer(llvm::errs(), diagOpts); - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, diagOpts, &printer, - /*ShouldOwnClient=*/false)); - Diags->setSourceManager(&PP.getSourceManager()); - - printer.BeginSourceFile(PP.getLangOpts(), &PP); - arcDiags.reportDiagnostics(*Diags); - printer.EndSourceFile(); -} - -//===----------------------------------------------------------------------===// -// checkForManualIssues. -//===----------------------------------------------------------------------===// - -bool arcmt::checkForManualIssues( - CompilerInvocation &origCI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient, bool emitPremigrationARCErrors, - StringRef plistOut) { - if (!origCI.getLangOpts().ObjC) - return false; - - LangOptions::GCMode OrigGCMode = origCI.getLangOpts().getGC(); - bool NoNSAllocReallocError = origCI.getMigratorOpts().NoNSAllocReallocError; - bool NoFinalizeRemoval = origCI.getMigratorOpts().NoFinalizeRemoval; - - std::vector transforms = arcmt::getAllTransformations(OrigGCMode, - NoFinalizeRemoval); - assert(!transforms.empty()); - - std::unique_ptr CInvok; - CInvok.reset( - createInvocationForMigration(origCI, PCHContainerOps->getRawReader())); - CInvok->getFrontendOpts().Inputs.clear(); - CInvok->getFrontendOpts().Inputs.push_back(Input); - - CapturedDiagList capturedDiags; - - assert(DiagClient); - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(), - DiagClient, /*ShouldOwnClient=*/false)); - - // Filter of all diagnostics. - CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags); - Diags->setClient(&errRec, /*ShouldOwnClient=*/false); - - std::unique_ptr Unit(ASTUnit::LoadFromCompilerInvocationAction( - std::move(CInvok), PCHContainerOps, Diags)); - if (!Unit) { - errRec.FinishCapture(); - return true; - } - - // Don't filter diagnostics anymore. - Diags->setClient(DiagClient, /*ShouldOwnClient=*/false); - - ASTContext &Ctx = Unit->getASTContext(); - - if (Diags->hasFatalErrorOccurred()) { - Diags->Reset(); - DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); - capturedDiags.reportDiagnostics(*Diags); - DiagClient->EndSourceFile(); - errRec.FinishCapture(); - return true; - } - - if (emitPremigrationARCErrors) - emitPremigrationErrors(capturedDiags, &origCI.getDiagnosticOpts(), - Unit->getPreprocessor()); - if (!plistOut.empty()) { - SmallVector arcDiags; - for (CapturedDiagList::iterator - I = capturedDiags.begin(), E = capturedDiags.end(); I != E; ++I) - arcDiags.push_back(*I); - writeARCDiagsToPlist(std::string(plistOut), arcDiags, - Ctx.getSourceManager(), Ctx.getLangOpts()); - } - - // After parsing of source files ended, we want to reuse the - // diagnostics objects to emit further diagnostics. - // We call BeginSourceFile because DiagnosticConsumer requires that - // diagnostics with source range information are emitted only in between - // BeginSourceFile() and EndSourceFile(). - DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); - - // No macros will be added since we are just checking and we won't modify - // source code. - std::vector ARCMTMacroLocs; - - TransformActions testAct(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); - MigrationPass pass(Ctx, OrigGCMode, Unit->getSema(), testAct, capturedDiags, - ARCMTMacroLocs); - pass.setNoFinalizeRemoval(NoFinalizeRemoval); - if (!NoNSAllocReallocError) - Diags->setSeverity(diag::warn_arcmt_nsalloc_realloc, diag::Severity::Error, - SourceLocation()); - - for (unsigned i=0, e = transforms.size(); i != e; ++i) - transforms[i](pass); - - capturedDiags.reportDiagnostics(*Diags); - - DiagClient->EndSourceFile(); - errRec.FinishCapture(); - - return capturedDiags.hasErrors() || testAct.hasReportedErrors(); -} - -//===----------------------------------------------------------------------===// -// applyTransformations. -//===----------------------------------------------------------------------===// - -static bool -applyTransforms(CompilerInvocation &origCI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient, StringRef outputDir, - bool emitPremigrationARCErrors, StringRef plistOut) { - if (!origCI.getLangOpts().ObjC) - return false; - - LangOptions::GCMode OrigGCMode = origCI.getLangOpts().getGC(); - - // Make sure checking is successful first. - CompilerInvocation CInvokForCheck(origCI); - if (arcmt::checkForManualIssues(CInvokForCheck, Input, PCHContainerOps, - DiagClient, emitPremigrationARCErrors, - plistOut)) - return true; - - CompilerInvocation CInvok(origCI); - CInvok.getFrontendOpts().Inputs.clear(); - CInvok.getFrontendOpts().Inputs.push_back(Input); - - MigrationProcess migration(CInvok, PCHContainerOps, DiagClient, outputDir); - bool NoFinalizeRemoval = origCI.getMigratorOpts().NoFinalizeRemoval; - - std::vector transforms = arcmt::getAllTransformations(OrigGCMode, - NoFinalizeRemoval); - assert(!transforms.empty()); - - for (unsigned i=0, e = transforms.size(); i != e; ++i) { - bool err = migration.applyTransform(transforms[i]); - if (err) return true; - } - - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(), - DiagClient, /*ShouldOwnClient=*/false)); - - if (outputDir.empty()) { - origCI.getLangOpts().ObjCAutoRefCount = true; - return migration.getRemapper().overwriteOriginal(*Diags); - } else { - return migration.getRemapper().flushToDisk(outputDir, *Diags); - } -} - -bool arcmt::applyTransformations( - CompilerInvocation &origCI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient) { - return applyTransforms(origCI, Input, PCHContainerOps, DiagClient, - StringRef(), false, StringRef()); -} - -bool arcmt::migrateWithTemporaryFiles( - CompilerInvocation &origCI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient, StringRef outputDir, - bool emitPremigrationARCErrors, StringRef plistOut) { - assert(!outputDir.empty() && "Expected output directory path"); - return applyTransforms(origCI, Input, PCHContainerOps, DiagClient, outputDir, - emitPremigrationARCErrors, plistOut); -} - -bool arcmt::getFileRemappings(std::vector > & - remap, - StringRef outputDir, - DiagnosticConsumer *DiagClient) { - assert(!outputDir.empty()); - - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, new DiagnosticOptions, - DiagClient, /*ShouldOwnClient=*/false)); - - FileRemapper remapper; - bool err = remapper.initFromDisk(outputDir, *Diags, - /*ignoreIfFilesChanged=*/true); - if (err) - return true; - - remapper.forEachMapping( - [&](StringRef From, StringRef To) { - remap.push_back(std::make_pair(From.str(), To.str())); - }, - [](StringRef, const llvm::MemoryBufferRef &) {}); - - return false; -} - - -//===----------------------------------------------------------------------===// -// CollectTransformActions. -//===----------------------------------------------------------------------===// - -namespace { - -class ARCMTMacroTrackerPPCallbacks : public PPCallbacks { - std::vector &ARCMTMacroLocs; - -public: - ARCMTMacroTrackerPPCallbacks(std::vector &ARCMTMacroLocs) - : ARCMTMacroLocs(ARCMTMacroLocs) { } - - void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, - SourceRange Range, const MacroArgs *Args) override { - if (MacroNameTok.getIdentifierInfo()->getName() == getARCMTMacroName()) - ARCMTMacroLocs.push_back(MacroNameTok.getLocation()); - } -}; - -class ARCMTMacroTrackerAction : public ASTFrontendAction { - std::vector &ARCMTMacroLocs; - -public: - ARCMTMacroTrackerAction(std::vector &ARCMTMacroLocs) - : ARCMTMacroLocs(ARCMTMacroLocs) { } - - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override { - CI.getPreprocessor().addPPCallbacks( - std::make_unique(ARCMTMacroLocs)); - return std::make_unique(); - } -}; - -class RewritesApplicator : public TransformActions::RewriteReceiver { - Rewriter &rewriter; - MigrationProcess::RewriteListener *Listener; - -public: - RewritesApplicator(Rewriter &rewriter, ASTContext &ctx, - MigrationProcess::RewriteListener *listener) - : rewriter(rewriter), Listener(listener) { - if (Listener) - Listener->start(ctx); - } - ~RewritesApplicator() override { - if (Listener) - Listener->finish(); - } - - void insert(SourceLocation loc, StringRef text) override { - bool err = rewriter.InsertText(loc, text, /*InsertAfter=*/true, - /*indentNewLines=*/true); - if (!err && Listener) - Listener->insert(loc, text); - } - - void remove(CharSourceRange range) override { - Rewriter::RewriteOptions removeOpts; - removeOpts.IncludeInsertsAtBeginOfRange = false; - removeOpts.IncludeInsertsAtEndOfRange = false; - removeOpts.RemoveLineIfEmpty = true; - - bool err = rewriter.RemoveText(range, removeOpts); - if (!err && Listener) - Listener->remove(range); - } - - void increaseIndentation(CharSourceRange range, - SourceLocation parentIndent) override { - rewriter.IncreaseIndentation(range, parentIndent); - } -}; - -} // end anonymous namespace. - -/// Anchor for VTable. -MigrationProcess::RewriteListener::~RewriteListener() { } - -MigrationProcess::MigrationProcess( - CompilerInvocation &CI, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *diagClient, StringRef outputDir) - : OrigCI(CI), PCHContainerOps(std::move(PCHContainerOps)), - DiagClient(diagClient), HadARCErrors(false) { - if (!outputDir.empty()) { - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), - DiagClient, /*ShouldOwnClient=*/false)); - Remapper.initFromDisk(outputDir, *Diags, /*ignoreIfFilesChanged=*/true); - } -} - -bool MigrationProcess::applyTransform(TransformFn trans, - RewriteListener *listener) { - std::unique_ptr CInvok; - CInvok.reset( - createInvocationForMigration(OrigCI, PCHContainerOps->getRawReader())); - CInvok->getDiagnosticOpts().IgnoreWarnings = true; - - Remapper.applyMappings(CInvok->getPreprocessorOpts()); - - CapturedDiagList capturedDiags; - std::vector ARCMTMacroLocs; - - assert(DiagClient); - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, new DiagnosticOptions, - DiagClient, /*ShouldOwnClient=*/false)); - - // Filter of all diagnostics. - CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags); - Diags->setClient(&errRec, /*ShouldOwnClient=*/false); - - std::unique_ptr ASTAction; - ASTAction.reset(new ARCMTMacroTrackerAction(ARCMTMacroLocs)); - - std::unique_ptr Unit(ASTUnit::LoadFromCompilerInvocationAction( - std::move(CInvok), PCHContainerOps, Diags, ASTAction.get())); - if (!Unit) { - errRec.FinishCapture(); - return true; - } - Unit->setOwnsRemappedFileBuffers(false); // FileRemapper manages that. - - HadARCErrors = HadARCErrors || capturedDiags.hasErrors(); - - // Don't filter diagnostics anymore. - Diags->setClient(DiagClient, /*ShouldOwnClient=*/false); - - ASTContext &Ctx = Unit->getASTContext(); - - if (Diags->hasFatalErrorOccurred()) { - Diags->Reset(); - DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); - capturedDiags.reportDiagnostics(*Diags); - DiagClient->EndSourceFile(); - errRec.FinishCapture(); - return true; - } - - // After parsing of source files ended, we want to reuse the - // diagnostics objects to emit further diagnostics. - // We call BeginSourceFile because DiagnosticConsumer requires that - // diagnostics with source range information are emitted only in between - // BeginSourceFile() and EndSourceFile(). - DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); - - Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); - TransformActions TA(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); - MigrationPass pass(Ctx, OrigCI.getLangOpts().getGC(), - Unit->getSema(), TA, capturedDiags, ARCMTMacroLocs); - - trans(pass); - - { - RewritesApplicator applicator(rewriter, Ctx, listener); - TA.applyRewrites(applicator); - } - - DiagClient->EndSourceFile(); - errRec.FinishCapture(); - - if (DiagClient->getNumErrors()) - return true; - - for (Rewriter::buffer_iterator - I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) { - FileID FID = I->first; - llvm::RewriteBuffer &buf = I->second; - OptionalFileEntryRef file = - Ctx.getSourceManager().getFileEntryRefForID(FID); - assert(file); - std::string newFname = std::string(file->getName()); - newFname += "-trans"; - SmallString<512> newText; - llvm::raw_svector_ostream vecOS(newText); - buf.write(vecOS); - std::unique_ptr memBuf( - llvm::MemoryBuffer::getMemBufferCopy(newText.str(), newFname)); - SmallString<64> filePath(file->getName()); - Unit->getFileManager().FixupRelativePath(filePath); - Remapper.remap(filePath.str(), std::move(memBuf)); - } - - return false; -} diff --git a/clang/lib/ARCMigrate/ARCMTActions.cpp b/clang/lib/ARCMigrate/ARCMTActions.cpp deleted file mode 100644 index 0805d90d25aa62..00000000000000 --- a/clang/lib/ARCMigrate/ARCMTActions.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//===--- ARCMTActions.cpp - ARC Migrate Tool Frontend Actions ---*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "clang/ARCMigrate/ARCMTActions.h" -#include "clang/ARCMigrate/ARCMT.h" -#include "clang/Frontend/CompilerInstance.h" - -using namespace clang; -using namespace arcmt; - -bool CheckAction::BeginInvocation(CompilerInstance &CI) { - if (arcmt::checkForManualIssues(CI.getInvocation(), getCurrentInput(), - CI.getPCHContainerOperations(), - CI.getDiagnostics().getClient())) - return false; // errors, stop the action. - - // We only want to see warnings reported from arcmt::checkForManualIssues. - CI.getDiagnostics().setIgnoreAllWarnings(true); - return true; -} - -CheckAction::CheckAction(std::unique_ptr WrappedAction) - : WrapperFrontendAction(std::move(WrappedAction)) {} - -bool ModifyAction::BeginInvocation(CompilerInstance &CI) { - return !arcmt::applyTransformations(CI.getInvocation(), getCurrentInput(), - CI.getPCHContainerOperations(), - CI.getDiagnostics().getClient()); -} - -ModifyAction::ModifyAction(std::unique_ptr WrappedAction) - : WrapperFrontendAction(std::move(WrappedAction)) {} - -bool MigrateAction::BeginInvocation(CompilerInstance &CI) { - if (arcmt::migrateWithTemporaryFiles( - CI.getInvocation(), getCurrentInput(), CI.getPCHContainerOperations(), - CI.getDiagnostics().getClient(), MigrateDir, EmitPremigrationARCErrors, - PlistOut)) - return false; // errors, stop the action. - - // We only want to see diagnostics emitted by migrateWithTemporaryFiles. - CI.getDiagnostics().setIgnoreAllWarnings(true); - return true; -} - -MigrateAction::MigrateAction(std::unique_ptr WrappedAction, - StringRef migrateDir, - StringRef plistOut, - bool emitPremigrationARCErrors) - : WrapperFrontendAction(std::move(WrappedAction)), MigrateDir(migrateDir), - PlistOut(plistOut), EmitPremigrationARCErrors(emitPremigrationARCErrors) { - if (MigrateDir.empty()) - MigrateDir = "."; // user current directory if none is given. -} diff --git a/clang/lib/ARCMigrate/CMakeLists.txt b/clang/lib/ARCMigrate/CMakeLists.txt deleted file mode 100644 index 515d0960920afc..00000000000000 --- a/clang/lib/ARCMigrate/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -set(LLVM_LINK_COMPONENTS - Support - TargetParser - ) - -# By default MSVC has a 2^16 limit on the number of sections in an object -# file, and Transforms.cpp needs more than that. -if (MSVC) - set_source_files_properties(Transforms.cpp PROPERTIES COMPILE_FLAGS /bigobj) -endif() - -add_clang_library(clangARCMigrate - ARCMT.cpp - ARCMTActions.cpp - FileRemapper.cpp - ObjCMT.cpp - PlistReporter.cpp - TransAPIUses.cpp - TransARCAssign.cpp - TransAutoreleasePool.cpp - TransBlockObjCVariable.cpp - TransEmptyStatementsAndDealloc.cpp - TransGCAttrs.cpp - TransGCCalls.cpp - TransProperties.cpp - TransProtectedScope.cpp - TransRetainReleaseDealloc.cpp - TransUnbridgedCasts.cpp - TransUnusedInitDelegate.cpp - TransZeroOutPropsInDealloc.cpp - TransformActions.cpp - Transforms.cpp - - LINK_LIBS - clangAST - clangAnalysis - clangBasic - clangEdit - clangFrontend - clangLex - clangRewrite - clangSema - clangSerialization - - DEPENDS - omp_gen - ClangDriverOptions - ) diff --git a/clang/lib/ARCMigrate/FileRemapper.cpp b/clang/lib/ARCMigrate/FileRemapper.cpp deleted file mode 100644 index 84024c3bafdca0..00000000000000 --- a/clang/lib/ARCMigrate/FileRemapper.cpp +++ /dev/null @@ -1,274 +0,0 @@ -//===--- FileRemapper.cpp - File Remapping Helper -------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "clang/ARCMigrate/FileRemapper.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/FileManager.h" -#include "clang/Lex/PreprocessorOptions.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" -#include - -using namespace clang; -using namespace arcmt; - -FileRemapper::FileRemapper() { - FileMgr.reset(new FileManager(FileSystemOptions())); -} - -FileRemapper::~FileRemapper() { - clear(); -} - -void FileRemapper::clear(StringRef outputDir) { - for (MappingsTy::iterator - I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) - resetTarget(I->second); - FromToMappings.clear(); - assert(ToFromMappings.empty()); - if (!outputDir.empty()) { - std::string infoFile = getRemapInfoFile(outputDir); - llvm::sys::fs::remove(infoFile); - } -} - -std::string FileRemapper::getRemapInfoFile(StringRef outputDir) { - assert(!outputDir.empty()); - SmallString<128> InfoFile = outputDir; - llvm::sys::path::append(InfoFile, "remap"); - return std::string(InfoFile); -} - -bool FileRemapper::initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag, - bool ignoreIfFilesChanged) { - std::string infoFile = getRemapInfoFile(outputDir); - return initFromFile(infoFile, Diag, ignoreIfFilesChanged); -} - -bool FileRemapper::initFromFile(StringRef filePath, DiagnosticsEngine &Diag, - bool ignoreIfFilesChanged) { - assert(FromToMappings.empty() && - "initFromDisk should be called before any remap calls"); - std::string infoFile = std::string(filePath); - if (!llvm::sys::fs::exists(infoFile)) - return false; - - std::vector> pairs; - - llvm::ErrorOr> fileBuf = - llvm::MemoryBuffer::getFile(infoFile, /*IsText=*/true); - if (!fileBuf) - return report("Error opening file: " + infoFile, Diag); - - SmallVector lines; - fileBuf.get()->getBuffer().split(lines, "\n"); - - for (unsigned idx = 0; idx+3 <= lines.size(); idx += 3) { - StringRef fromFilename = lines[idx]; - unsigned long long timeModified; - if (lines[idx+1].getAsInteger(10, timeModified)) - return report("Invalid file data: '" + lines[idx+1] + "' not a number", - Diag); - StringRef toFilename = lines[idx+2]; - - auto origFE = FileMgr->getOptionalFileRef(fromFilename); - if (!origFE) { - if (ignoreIfFilesChanged) - continue; - return report("File does not exist: " + fromFilename, Diag); - } - auto newFE = FileMgr->getOptionalFileRef(toFilename); - if (!newFE) { - if (ignoreIfFilesChanged) - continue; - return report("File does not exist: " + toFilename, Diag); - } - - if ((uint64_t)origFE->getModificationTime() != timeModified) { - if (ignoreIfFilesChanged) - continue; - return report("File was modified: " + fromFilename, Diag); - } - - pairs.push_back(std::make_pair(*origFE, *newFE)); - } - - for (unsigned i = 0, e = pairs.size(); i != e; ++i) - remap(pairs[i].first, pairs[i].second); - - return false; -} - -bool FileRemapper::flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag) { - using namespace llvm::sys; - - if (fs::create_directory(outputDir)) - return report("Could not create directory: " + outputDir, Diag); - - std::string infoFile = getRemapInfoFile(outputDir); - return flushToFile(infoFile, Diag); -} - -bool FileRemapper::flushToFile(StringRef outputPath, DiagnosticsEngine &Diag) { - using namespace llvm::sys; - - std::error_code EC; - std::string infoFile = std::string(outputPath); - llvm::raw_fd_ostream infoOut(infoFile, EC, llvm::sys::fs::OF_Text); - if (EC) - return report(EC.message(), Diag); - - for (MappingsTy::iterator - I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) { - - FileEntryRef origFE = I->first; - SmallString<200> origPath = StringRef(origFE.getName()); - fs::make_absolute(origPath); - infoOut << origPath << '\n'; - infoOut << (uint64_t)origFE.getModificationTime() << '\n'; - - if (const auto *FE = std::get_if(&I->second)) { - SmallString<200> newPath = StringRef(FE->getName()); - fs::make_absolute(newPath); - infoOut << newPath << '\n'; - } else { - - SmallString<64> tempPath; - int fd; - if (fs::createTemporaryFile( - path::filename(origFE.getName()), - path::extension(origFE.getName()).drop_front(), fd, tempPath, - llvm::sys::fs::OF_Text)) - return report("Could not create file: " + tempPath.str(), Diag); - - llvm::raw_fd_ostream newOut(fd, /*shouldClose=*/true); - llvm::MemoryBuffer *mem = std::get(I->second); - newOut.write(mem->getBufferStart(), mem->getBufferSize()); - newOut.close(); - - auto newE = FileMgr->getOptionalFileRef(tempPath); - if (newE) { - remap(origFE, *newE); - infoOut << newE->getName() << '\n'; - } - } - } - - infoOut.close(); - return false; -} - -bool FileRemapper::overwriteOriginal(DiagnosticsEngine &Diag, - StringRef outputDir) { - using namespace llvm::sys; - - for (MappingsTy::iterator - I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) { - FileEntryRef origFE = I->first; - assert(std::holds_alternative(I->second)); - if (!fs::exists(origFE.getName())) - return report(StringRef("File does not exist: ") + origFE.getName(), - Diag); - - std::error_code EC; - llvm::raw_fd_ostream Out(origFE.getName(), EC, llvm::sys::fs::OF_None); - if (EC) - return report(EC.message(), Diag); - - llvm::MemoryBuffer *mem = std::get(I->second); - Out.write(mem->getBufferStart(), mem->getBufferSize()); - Out.close(); - } - - clear(outputDir); - return false; -} - -void FileRemapper::forEachMapping( - llvm::function_ref CaptureFile, - llvm::function_ref - CaptureBuffer) const { - for (auto &Mapping : FromToMappings) { - if (const auto *FE = std::get_if(&Mapping.second)) { - CaptureFile(Mapping.first.getName(), FE->getName()); - continue; - } - CaptureBuffer( - Mapping.first.getName(), - std::get(Mapping.second)->getMemBufferRef()); - } -} - -void FileRemapper::applyMappings(PreprocessorOptions &PPOpts) const { - for (MappingsTy::const_iterator - I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) { - if (const auto *FE = std::get_if(&I->second)) { - PPOpts.addRemappedFile(I->first.getName(), FE->getName()); - } else { - llvm::MemoryBuffer *mem = std::get(I->second); - PPOpts.addRemappedFile(I->first.getName(), mem); - } - } - - PPOpts.RetainRemappedFileBuffers = true; -} - -void FileRemapper::remap(StringRef filePath, - std::unique_ptr memBuf) { - OptionalFileEntryRef File = getOriginalFile(filePath); - assert(File); - remap(*File, std::move(memBuf)); -} - -void FileRemapper::remap(FileEntryRef File, - std::unique_ptr MemBuf) { - auto [It, New] = FromToMappings.insert({File, nullptr}); - if (!New) - resetTarget(It->second); - It->second = MemBuf.release(); -} - -void FileRemapper::remap(FileEntryRef File, FileEntryRef NewFile) { - auto [It, New] = FromToMappings.insert({File, nullptr}); - if (!New) - resetTarget(It->second); - It->second = NewFile; - ToFromMappings.insert({NewFile, File}); -} - -OptionalFileEntryRef FileRemapper::getOriginalFile(StringRef filePath) { - OptionalFileEntryRef File = FileMgr->getOptionalFileRef(filePath); - if (!File) - return std::nullopt; - // If we are updating a file that overridden an original file, - // actually update the original file. - auto I = ToFromMappings.find(*File); - if (I != ToFromMappings.end()) { - *File = I->second; - assert(FromToMappings.contains(*File) && "Original file not in mappings!"); - } - return File; -} - -void FileRemapper::resetTarget(Target &targ) { - if (std::holds_alternative(targ)) { - llvm::MemoryBuffer *oldmem = std::get(targ); - delete oldmem; - } else { - FileEntryRef toFE = std::get(targ); - ToFromMappings.erase(toFE); - } -} - -bool FileRemapper::report(const Twine &err, DiagnosticsEngine &Diag) { - Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0")) - << err.str(); - return true; -} diff --git a/clang/lib/ARCMigrate/Internals.h b/clang/lib/ARCMigrate/Internals.h deleted file mode 100644 index de6ebdce1bea16..00000000000000 --- a/clang/lib/ARCMigrate/Internals.h +++ /dev/null @@ -1,180 +0,0 @@ -//===-- Internals.h - Implementation Details---------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_ARCMIGRATE_INTERNALS_H -#define LLVM_CLANG_LIB_ARCMIGRATE_INTERNALS_H - -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Frontend/MigratorOptions.h" -#include "llvm/ADT/ArrayRef.h" -#include -#include - -namespace clang { - class ASTContext; - class Sema; - class Stmt; - -namespace arcmt { - -class CapturedDiagList { - typedef std::list ListTy; - ListTy List; - -public: - void push_back(const StoredDiagnostic &diag) { List.push_back(diag); } - - bool clearDiagnostic(ArrayRef IDs, SourceRange range); - bool hasDiagnostic(ArrayRef IDs, SourceRange range) const; - - void reportDiagnostics(DiagnosticsEngine &diags) const; - - bool hasErrors() const; - - typedef ListTy::const_iterator iterator; - iterator begin() const { return List.begin(); } - iterator end() const { return List.end(); } -}; - -void writeARCDiagsToPlist(const std::string &outPath, - ArrayRef diags, - SourceManager &SM, const LangOptions &LangOpts); - -class TransformActions { - DiagnosticsEngine &Diags; - CapturedDiagList &CapturedDiags; - void *Impl; // TransformActionsImpl. - -public: - TransformActions(DiagnosticsEngine &diag, CapturedDiagList &capturedDiags, - ASTContext &ctx, Preprocessor &PP); - ~TransformActions(); - - void startTransaction(); - bool commitTransaction(); - void abortTransaction(); - - void insert(SourceLocation loc, StringRef text); - void insertAfterToken(SourceLocation loc, StringRef text); - void remove(SourceRange range); - void removeStmt(Stmt *S); - void replace(SourceRange range, StringRef text); - void replace(SourceRange range, SourceRange replacementRange); - void replaceStmt(Stmt *S, StringRef text); - void replaceText(SourceLocation loc, StringRef text, - StringRef replacementText); - void increaseIndentation(SourceRange range, - SourceLocation parentIndent); - - bool clearDiagnostic(ArrayRef IDs, SourceRange range); - bool clearAllDiagnostics(SourceRange range) { - return clearDiagnostic({}, range); - } - bool clearDiagnostic(unsigned ID1, unsigned ID2, SourceRange range) { - unsigned IDs[] = { ID1, ID2 }; - return clearDiagnostic(IDs, range); - } - bool clearDiagnostic(unsigned ID1, unsigned ID2, unsigned ID3, - SourceRange range) { - unsigned IDs[] = { ID1, ID2, ID3 }; - return clearDiagnostic(IDs, range); - } - - bool hasDiagnostic(unsigned ID, SourceRange range) { - return CapturedDiags.hasDiagnostic(ID, range); - } - - bool hasDiagnostic(unsigned ID1, unsigned ID2, SourceRange range) { - unsigned IDs[] = { ID1, ID2 }; - return CapturedDiags.hasDiagnostic(IDs, range); - } - - DiagnosticBuilder report(SourceLocation loc, unsigned diagId, - SourceRange range = SourceRange()); - void reportError(StringRef error, SourceLocation loc, - SourceRange range = SourceRange()); - void reportWarning(StringRef warning, SourceLocation loc, - SourceRange range = SourceRange()); - void reportNote(StringRef note, SourceLocation loc, - SourceRange range = SourceRange()); - - bool hasReportedErrors() const { - return Diags.hasUnrecoverableErrorOccurred(); - } - - class RewriteReceiver { - public: - virtual ~RewriteReceiver(); - - virtual void insert(SourceLocation loc, StringRef text) = 0; - virtual void remove(CharSourceRange range) = 0; - virtual void increaseIndentation(CharSourceRange range, - SourceLocation parentIndent) = 0; - }; - - void applyRewrites(RewriteReceiver &receiver); -}; - -class Transaction { - TransformActions &TA; - bool Aborted; - -public: - Transaction(TransformActions &TA) : TA(TA), Aborted(false) { - TA.startTransaction(); - } - - ~Transaction() { - if (!isAborted()) - TA.commitTransaction(); - } - - void abort() { - TA.abortTransaction(); - Aborted = true; - } - - bool isAborted() const { return Aborted; } -}; - -class MigrationPass { -public: - ASTContext &Ctx; - LangOptions::GCMode OrigGCMode; - MigratorOptions MigOptions; - Sema &SemaRef; - TransformActions &TA; - const CapturedDiagList &CapturedDiags; - std::vector &ARCMTMacroLocs; - std::optional EnableCFBridgeFns; - - MigrationPass(ASTContext &Ctx, LangOptions::GCMode OrigGCMode, Sema &sema, - TransformActions &TA, const CapturedDiagList &capturedDiags, - std::vector &ARCMTMacroLocs) - : Ctx(Ctx), OrigGCMode(OrigGCMode), SemaRef(sema), TA(TA), - CapturedDiags(capturedDiags), ARCMTMacroLocs(ARCMTMacroLocs) {} - - const CapturedDiagList &getDiags() const { return CapturedDiags; } - - bool isGCMigration() const { return OrigGCMode != LangOptions::NonGC; } - bool noFinalizeRemoval() const { return MigOptions.NoFinalizeRemoval; } - void setNoFinalizeRemoval(bool val) {MigOptions.NoFinalizeRemoval = val; } - - bool CFBridgingFunctionsDefined(); -}; - -static inline StringRef getARCMTMacroName() { - return "__IMPL_ARCMT_REMOVED_EXPR__"; -} - -} // end namespace arcmt - -} // end namespace clang - -#endif diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp deleted file mode 100644 index c1bc7c762088f2..00000000000000 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ /dev/null @@ -1,2262 +0,0 @@ -//===--- ObjCMT.cpp - ObjC Migrate Tool -----------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "clang/Analysis/RetainSummaryManager.h" -#include "clang/ARCMigrate/ARCMT.h" -#include "clang/ARCMigrate/ARCMTActions.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Attr.h" -#include "clang/AST/NSAPI.h" -#include "clang/AST/ParentMap.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/Analysis/DomainSpecific/CocoaConventions.h" -#include "clang/Basic/FileManager.h" -#include "clang/Edit/Commit.h" -#include "clang/Edit/EditedSource.h" -#include "clang/Edit/EditsReceiver.h" -#include "clang/Edit/Rewriters.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/MultiplexConsumer.h" -#include "clang/Lex/PPConditionalDirectiveRecord.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/YAMLParser.h" - -using namespace clang; -using namespace arcmt; -using namespace ento; -using llvm::RewriteBuffer; - -namespace { - -class ObjCMigrateASTConsumer : public ASTConsumer { - enum CF_BRIDGING_KIND { - CF_BRIDGING_NONE, - CF_BRIDGING_ENABLE, - CF_BRIDGING_MAY_INCLUDE - }; - - void migrateDecl(Decl *D); - void migrateObjCContainerDecl(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); - void migrateMethodInstanceType(ASTContext &Ctx, ObjCContainerDecl *CDecl, - ObjCMethodDecl *OM); - bool migrateProperty(ASTContext &Ctx, ObjCContainerDecl *D, ObjCMethodDecl *OM); - void migrateNsReturnsInnerPointer(ASTContext &Ctx, ObjCMethodDecl *OM); - void migratePropertyNsReturnsInnerPointer(ASTContext &Ctx, ObjCPropertyDecl *P); - void migrateFactoryMethod(ASTContext &Ctx, ObjCContainerDecl *CDecl, - ObjCMethodDecl *OM, - ObjCInstanceTypeFamily OIT_Family = OIT_None); - - void migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl); - void AddCFAnnotations(ASTContext &Ctx, - const RetainSummary *RS, - const FunctionDecl *FuncDecl, bool ResultAnnotated); - void AddCFAnnotations(ASTContext &Ctx, - const RetainSummary *RS, - const ObjCMethodDecl *MethodDecl, bool ResultAnnotated); - - void AnnotateImplicitBridging(ASTContext &Ctx); - - CF_BRIDGING_KIND migrateAddFunctionAnnotation(ASTContext &Ctx, - const FunctionDecl *FuncDecl); - - void migrateARCSafeAnnotation(ASTContext &Ctx, ObjCContainerDecl *CDecl); - - void migrateAddMethodAnnotation(ASTContext &Ctx, - const ObjCMethodDecl *MethodDecl); - - void inferDesignatedInitializers(ASTContext &Ctx, - const ObjCImplementationDecl *ImplD); - - bool InsertFoundation(ASTContext &Ctx, SourceLocation Loc); - - std::unique_ptr Summaries; - -public: - std::string MigrateDir; - unsigned ASTMigrateActions; - FileID FileId; - const TypedefDecl *NSIntegerTypedefed; - const TypedefDecl *NSUIntegerTypedefed; - std::unique_ptr NSAPIObj; - std::unique_ptr Editor; - FileRemapper &Remapper; - FileManager &FileMgr; - const PPConditionalDirectiveRecord *PPRec; - Preprocessor &PP; - bool IsOutputFile; - bool FoundationIncluded; - llvm::SmallPtrSet ObjCProtocolDecls; - llvm::SmallVector CFFunctionIBCandidates; - llvm::StringSet<> AllowListFilenames; - - RetainSummaryManager &getSummaryManager(ASTContext &Ctx) { - if (!Summaries) - Summaries.reset(new RetainSummaryManager(Ctx, - /*TrackNSCFObjects=*/true, - /*trackOSObjects=*/false)); - return *Summaries; - } - - ObjCMigrateASTConsumer(StringRef migrateDir, unsigned astMigrateActions, - FileRemapper &remapper, FileManager &fileMgr, - const PPConditionalDirectiveRecord *PPRec, - Preprocessor &PP, bool isOutputFile, - ArrayRef AllowList) - : MigrateDir(migrateDir), ASTMigrateActions(astMigrateActions), - NSIntegerTypedefed(nullptr), NSUIntegerTypedefed(nullptr), - Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP), - IsOutputFile(isOutputFile), FoundationIncluded(false) { - AllowListFilenames.insert(AllowList.begin(), AllowList.end()); - } - -protected: - void Initialize(ASTContext &Context) override { - NSAPIObj.reset(new NSAPI(Context)); - Editor.reset(new edit::EditedSource(Context.getSourceManager(), - Context.getLangOpts(), - PPRec)); - } - - bool HandleTopLevelDecl(DeclGroupRef DG) override { - for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) - migrateDecl(*I); - return true; - } - void HandleInterestingDecl(DeclGroupRef DG) override { - // Ignore decls from the PCH. - } - void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override { - ObjCMigrateASTConsumer::HandleTopLevelDecl(DG); - } - - void HandleTranslationUnit(ASTContext &Ctx) override; - - bool canModifyFile(StringRef Path) { - if (AllowListFilenames.empty()) - return true; - return AllowListFilenames.contains(llvm::sys::path::filename(Path)); - } - bool canModifyFile(OptionalFileEntryRef FE) { - if (!FE) - return false; - return canModifyFile(FE->getName()); - } - bool canModifyFile(FileID FID) { - if (FID.isInvalid()) - return false; - return canModifyFile(PP.getSourceManager().getFileEntryRefForID(FID)); - } - - bool canModify(const Decl *D) { - if (!D) - return false; - if (const ObjCCategoryImplDecl *CatImpl = dyn_cast(D)) - return canModify(CatImpl->getCategoryDecl()); - if (const ObjCImplementationDecl *Impl = dyn_cast(D)) - return canModify(Impl->getClassInterface()); - if (const ObjCMethodDecl *MD = dyn_cast(D)) - return canModify(cast(MD->getDeclContext())); - - FileID FID = PP.getSourceManager().getFileID(D->getLocation()); - return canModifyFile(FID); - } -}; - -} // end anonymous namespace - -ObjCMigrateAction::ObjCMigrateAction( - std::unique_ptr WrappedAction, StringRef migrateDir, - unsigned migrateAction) - : WrapperFrontendAction(std::move(WrappedAction)), MigrateDir(migrateDir), - ObjCMigAction(migrateAction), CompInst(nullptr) { - if (MigrateDir.empty()) - MigrateDir = "."; // user current directory if none is given. -} - -std::unique_ptr -ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - PPConditionalDirectiveRecord * - PPRec = new PPConditionalDirectiveRecord(CompInst->getSourceManager()); - CI.getPreprocessor().addPPCallbacks(std::unique_ptr(PPRec)); - std::vector> Consumers; - Consumers.push_back(WrapperFrontendAction::CreateASTConsumer(CI, InFile)); - Consumers.push_back(std::make_unique( - MigrateDir, ObjCMigAction, Remapper, CompInst->getFileManager(), PPRec, - CompInst->getPreprocessor(), false, std::nullopt)); - return std::make_unique(std::move(Consumers)); -} - -bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) { - Remapper.initFromDisk(MigrateDir, CI.getDiagnostics(), - /*ignoreIfFilesChanged=*/true); - CompInst = &CI; - CI.getDiagnostics().setIgnoreAllWarnings(true); - return true; -} - -namespace { - // FIXME. This duplicates one in RewriteObjCFoundationAPI.cpp - bool subscriptOperatorNeedsParens(const Expr *FullExpr) { - const Expr* Expr = FullExpr->IgnoreImpCasts(); - return !(isa(Expr) || isa(Expr) || - isa(Expr) || isa(Expr) || - isa(Expr) || isa(Expr) || - isa(Expr) || - isa(Expr) || - isa(Expr) || isa(Expr) || - isa(Expr) || isa(Expr) || - isa(Expr) || isa(FullExpr) || - isa(Expr) || isa(Expr)); - } - - /// - Rewrite message expression for Objective-C setter and getters into - /// property-dot syntax. - bool rewriteToPropertyDotSyntax(const ObjCMessageExpr *Msg, - Preprocessor &PP, - const NSAPI &NS, edit::Commit &commit, - const ParentMap *PMap) { - if (!Msg || Msg->isImplicit() || - (Msg->getReceiverKind() != ObjCMessageExpr::Instance && - Msg->getReceiverKind() != ObjCMessageExpr::SuperInstance)) - return false; - if (const Expr *Receiver = Msg->getInstanceReceiver()) - if (Receiver->getType()->isObjCBuiltinType()) - return false; - - const ObjCMethodDecl *Method = Msg->getMethodDecl(); - if (!Method) - return false; - if (!Method->isPropertyAccessor()) - return false; - - const ObjCPropertyDecl *Prop = Method->findPropertyDecl(); - if (!Prop) - return false; - - SourceRange MsgRange = Msg->getSourceRange(); - bool ReceiverIsSuper = - (Msg->getReceiverKind() == ObjCMessageExpr::SuperInstance); - // for 'super' receiver is nullptr. - const Expr *receiver = Msg->getInstanceReceiver(); - bool NeedsParen = - ReceiverIsSuper ? false : subscriptOperatorNeedsParens(receiver); - bool IsGetter = (Msg->getNumArgs() == 0); - if (IsGetter) { - // Find space location range between receiver expression and getter method. - SourceLocation BegLoc = - ReceiverIsSuper ? Msg->getSuperLoc() : receiver->getEndLoc(); - BegLoc = PP.getLocForEndOfToken(BegLoc); - SourceLocation EndLoc = Msg->getSelectorLoc(0); - SourceRange SpaceRange(BegLoc, EndLoc); - std::string PropertyDotString; - // rewrite getter method expression into: receiver.property or - // (receiver).property - if (NeedsParen) { - commit.insertBefore(receiver->getBeginLoc(), "("); - PropertyDotString = ")."; - } - else - PropertyDotString = "."; - PropertyDotString += Prop->getName(); - commit.replace(SpaceRange, PropertyDotString); - - // remove '[' ']' - commit.replace(SourceRange(MsgRange.getBegin(), MsgRange.getBegin()), ""); - commit.replace(SourceRange(MsgRange.getEnd(), MsgRange.getEnd()), ""); - } else { - if (NeedsParen) - commit.insertWrap("(", receiver->getSourceRange(), ")"); - std::string PropertyDotString = "."; - PropertyDotString += Prop->getName(); - PropertyDotString += " ="; - const Expr*const* Args = Msg->getArgs(); - const Expr *RHS = Args[0]; - if (!RHS) - return false; - SourceLocation BegLoc = - ReceiverIsSuper ? Msg->getSuperLoc() : receiver->getEndLoc(); - BegLoc = PP.getLocForEndOfToken(BegLoc); - SourceLocation EndLoc = RHS->getBeginLoc(); - EndLoc = EndLoc.getLocWithOffset(-1); - const char *colon = PP.getSourceManager().getCharacterData(EndLoc); - // Add a space after '=' if there is no space between RHS and '=' - if (colon && colon[0] == ':') - PropertyDotString += " "; - SourceRange Range(BegLoc, EndLoc); - commit.replace(Range, PropertyDotString); - // remove '[' ']' - commit.replace(SourceRange(MsgRange.getBegin(), MsgRange.getBegin()), ""); - commit.replace(SourceRange(MsgRange.getEnd(), MsgRange.getEnd()), ""); - } - return true; - } - -class ObjCMigrator : public RecursiveASTVisitor { - ObjCMigrateASTConsumer &Consumer; - ParentMap &PMap; - -public: - ObjCMigrator(ObjCMigrateASTConsumer &consumer, ParentMap &PMap) - : Consumer(consumer), PMap(PMap) { } - - bool shouldVisitTemplateInstantiations() const { return false; } - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Literals) { - edit::Commit commit(*Consumer.Editor); - edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit, &PMap); - Consumer.Editor->commit(commit); - } - - if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Subscripting) { - edit::Commit commit(*Consumer.Editor); - edit::rewriteToObjCSubscriptSyntax(E, *Consumer.NSAPIObj, commit); - Consumer.Editor->commit(commit); - } - - if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_PropertyDotSyntax) { - edit::Commit commit(*Consumer.Editor); - rewriteToPropertyDotSyntax(E, Consumer.PP, *Consumer.NSAPIObj, - commit, &PMap); - Consumer.Editor->commit(commit); - } - - return true; - } - - bool TraverseObjCMessageExpr(ObjCMessageExpr *E) { - // Do depth first; we want to rewrite the subexpressions first so that if - // we have to move expressions we will move them already rewritten. - for (Stmt *SubStmt : E->children()) - if (!TraverseStmt(SubStmt)) - return false; - - return WalkUpFromObjCMessageExpr(E); - } -}; - -class BodyMigrator : public RecursiveASTVisitor { - ObjCMigrateASTConsumer &Consumer; - std::unique_ptr PMap; - -public: - BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { } - - bool shouldVisitTemplateInstantiations() const { return false; } - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool TraverseStmt(Stmt *S) { - PMap.reset(new ParentMap(S)); - ObjCMigrator(Consumer, *PMap).TraverseStmt(S); - return true; - } -}; -} // end anonymous namespace - -void ObjCMigrateASTConsumer::migrateDecl(Decl *D) { - if (!D) - return; - if (isa(D)) - return; // Wait for the ObjC container declaration. - - BodyMigrator(*this).TraverseDecl(D); -} - -static void append_attr(std::string &PropertyString, const char *attr, - bool &LParenAdded) { - if (!LParenAdded) { - PropertyString += "("; - LParenAdded = true; - } - else - PropertyString += ", "; - PropertyString += attr; -} - -static -void MigrateBlockOrFunctionPointerTypeVariable(std::string & PropertyString, - const std::string& TypeString, - const char *name) { - const char *argPtr = TypeString.c_str(); - int paren = 0; - while (*argPtr) { - switch (*argPtr) { - case '(': - PropertyString += *argPtr; - paren++; - break; - case ')': - PropertyString += *argPtr; - paren--; - break; - case '^': - case '*': - PropertyString += (*argPtr); - if (paren == 1) { - PropertyString += name; - name = ""; - } - break; - default: - PropertyString += *argPtr; - break; - } - argPtr++; - } -} - -static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType) { - Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime(); - bool RetainableObject = ArgType->isObjCRetainableType(); - if (RetainableObject && - (propertyLifetime == Qualifiers::OCL_Strong - || propertyLifetime == Qualifiers::OCL_None)) { - if (const ObjCObjectPointerType *ObjPtrTy = - ArgType->getAs()) { - ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface(); - if (IDecl && - IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying"))) - return "copy"; - else - return "strong"; - } - else if (ArgType->isBlockPointerType()) - return "copy"; - } else if (propertyLifetime == Qualifiers::OCL_Weak) - // TODO. More precise determination of 'weak' attribute requires - // looking into setter's implementation for backing weak ivar. - return "weak"; - else if (RetainableObject) - return ArgType->isBlockPointerType() ? "copy" : "strong"; - return nullptr; -} - -static void rewriteToObjCProperty(const ObjCMethodDecl *Getter, - const ObjCMethodDecl *Setter, - const NSAPI &NS, edit::Commit &commit, - unsigned LengthOfPrefix, - bool Atomic, bool UseNsIosOnlyMacro, - bool AvailabilityArgsMatch) { - ASTContext &Context = NS.getASTContext(); - bool LParenAdded = false; - std::string PropertyString = "@property "; - if (UseNsIosOnlyMacro && NS.isMacroDefined("NS_NONATOMIC_IOSONLY")) { - PropertyString += "(NS_NONATOMIC_IOSONLY"; - LParenAdded = true; - } else if (!Atomic) { - PropertyString += "(nonatomic"; - LParenAdded = true; - } - - std::string PropertyNameString = Getter->getNameAsString(); - StringRef PropertyName(PropertyNameString); - if (LengthOfPrefix > 0) { - if (!LParenAdded) { - PropertyString += "(getter="; - LParenAdded = true; - } - else - PropertyString += ", getter="; - PropertyString += PropertyNameString; - } - // Property with no setter may be suggested as a 'readonly' property. - if (!Setter) - append_attr(PropertyString, "readonly", LParenAdded); - - - // Short circuit 'delegate' properties that contain the name "delegate" or - // "dataSource", or have exact name "target" to have 'assign' attribute. - if (PropertyName == "target" || PropertyName.contains("delegate") || - PropertyName.contains("dataSource")) { - QualType QT = Getter->getReturnType(); - if (!QT->isRealType()) - append_attr(PropertyString, "assign", LParenAdded); - } else if (!Setter) { - QualType ResType = Context.getCanonicalType(Getter->getReturnType()); - if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ResType)) - append_attr(PropertyString, MemoryManagementAttr, LParenAdded); - } else { - const ParmVarDecl *argDecl = *Setter->param_begin(); - QualType ArgType = Context.getCanonicalType(argDecl->getType()); - if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ArgType)) - append_attr(PropertyString, MemoryManagementAttr, LParenAdded); - } - if (LParenAdded) - PropertyString += ')'; - QualType RT = Getter->getReturnType(); - if (!RT->getAs()) { - // strip off any ARC lifetime qualifier. - QualType CanResultTy = Context.getCanonicalType(RT); - if (CanResultTy.getQualifiers().hasObjCLifetime()) { - Qualifiers Qs = CanResultTy.getQualifiers(); - Qs.removeObjCLifetime(); - RT = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs); - } - } - PropertyString += " "; - PrintingPolicy SubPolicy(Context.getPrintingPolicy()); - SubPolicy.SuppressStrongLifetime = true; - SubPolicy.SuppressLifetimeQualifiers = true; - std::string TypeString = RT.getAsString(SubPolicy); - if (LengthOfPrefix > 0) { - // property name must strip off "is" and lower case the first character - // after that; e.g. isContinuous will become continuous. - StringRef PropertyNameStringRef(PropertyNameString); - PropertyNameStringRef = PropertyNameStringRef.drop_front(LengthOfPrefix); - PropertyNameString = std::string(PropertyNameStringRef); - bool NoLowering = (isUppercase(PropertyNameString[0]) && - PropertyNameString.size() > 1 && - isUppercase(PropertyNameString[1])); - if (!NoLowering) - PropertyNameString[0] = toLowercase(PropertyNameString[0]); - } - if (RT->isBlockPointerType() || RT->isFunctionPointerType()) - MigrateBlockOrFunctionPointerTypeVariable(PropertyString, - TypeString, - PropertyNameString.c_str()); - else { - char LastChar = TypeString[TypeString.size()-1]; - PropertyString += TypeString; - if (LastChar != '*') - PropertyString += ' '; - PropertyString += PropertyNameString; - } - SourceLocation StartGetterSelectorLoc = Getter->getSelectorStartLoc(); - Selector GetterSelector = Getter->getSelector(); - - SourceLocation EndGetterSelectorLoc = - StartGetterSelectorLoc.getLocWithOffset(GetterSelector.getNameForSlot(0).size()); - commit.replace(CharSourceRange::getCharRange(Getter->getBeginLoc(), - EndGetterSelectorLoc), - PropertyString); - if (Setter && AvailabilityArgsMatch) { - SourceLocation EndLoc = Setter->getDeclaratorEndLoc(); - // Get location past ';' - EndLoc = EndLoc.getLocWithOffset(1); - SourceLocation BeginOfSetterDclLoc = Setter->getBeginLoc(); - // FIXME. This assumes that setter decl; is immediately preceded by eoln. - // It is trying to remove the setter method decl. line entirely. - BeginOfSetterDclLoc = BeginOfSetterDclLoc.getLocWithOffset(-1); - commit.remove(SourceRange(BeginOfSetterDclLoc, EndLoc)); - } -} - -static bool IsCategoryNameWithDeprecatedSuffix(ObjCContainerDecl *D) { - if (ObjCCategoryDecl *CatDecl = dyn_cast(D)) { - StringRef Name = CatDecl->getName(); - return Name.ends_with("Deprecated"); - } - return false; -} - -void ObjCMigrateASTConsumer::migrateObjCContainerDecl(ASTContext &Ctx, - ObjCContainerDecl *D) { - if (D->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(D)) - return; - - for (auto *Method : D->methods()) { - if (Method->isDeprecated()) - continue; - bool PropertyInferred = migrateProperty(Ctx, D, Method); - // If a property is inferred, do not attempt to attach NS_RETURNS_INNER_POINTER to - // the getter method as it ends up on the property itself which we don't want - // to do unless -objcmt-returns-innerpointer-property option is on. - if (!PropertyInferred || - (ASTMigrateActions & FrontendOptions::ObjCMT_ReturnsInnerPointerProperty)) - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) - migrateNsReturnsInnerPointer(Ctx, Method); - } - if (!(ASTMigrateActions & FrontendOptions::ObjCMT_ReturnsInnerPointerProperty)) - return; - - for (auto *Prop : D->instance_properties()) { - if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && - !Prop->isDeprecated()) - migratePropertyNsReturnsInnerPointer(Ctx, Prop); - } -} - -static bool -ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, - const ObjCImplementationDecl *ImpDecl, - const ObjCInterfaceDecl *IDecl, - ObjCProtocolDecl *Protocol) { - // In auto-synthesis, protocol properties are not synthesized. So, - // a conforming protocol must have its required properties declared - // in class interface. - bool HasAtleastOneRequiredProperty = false; - if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) - for (const auto *Property : PDecl->instance_properties()) { - if (Property->getPropertyImplementation() == ObjCPropertyDecl::Optional) - continue; - HasAtleastOneRequiredProperty = true; - DeclContext::lookup_result R = IDecl->lookup(Property->getDeclName()); - if (R.empty()) { - // Relax the rule and look into class's implementation for a synthesize - // or dynamic declaration. Class is implementing a property coming from - // another protocol. This still makes the target protocol as conforming. - if (!ImpDecl->FindPropertyImplDecl( - Property->getDeclName().getAsIdentifierInfo(), - Property->getQueryKind())) - return false; - } else if (auto *ClassProperty = R.find_first()) { - if ((ClassProperty->getPropertyAttributes() != - Property->getPropertyAttributes()) || - !Ctx.hasSameType(ClassProperty->getType(), Property->getType())) - return false; - } else - return false; - } - - // At this point, all required properties in this protocol conform to those - // declared in the class. - // Check that class implements the required methods of the protocol too. - bool HasAtleastOneRequiredMethod = false; - if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) { - if (PDecl->meth_begin() == PDecl->meth_end()) - return HasAtleastOneRequiredProperty; - for (const auto *MD : PDecl->methods()) { - if (MD->isImplicit()) - continue; - if (MD->getImplementationControl() == ObjCImplementationControl::Optional) - continue; - DeclContext::lookup_result R = ImpDecl->lookup(MD->getDeclName()); - if (R.empty()) - return false; - bool match = false; - HasAtleastOneRequiredMethod = true; - for (NamedDecl *ND : R) - if (ObjCMethodDecl *ImpMD = dyn_cast(ND)) - if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) { - match = true; - break; - } - if (!match) - return false; - } - } - return HasAtleastOneRequiredProperty || HasAtleastOneRequiredMethod; -} - -static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl, - llvm::SmallVectorImpl &ConformingProtocols, - const NSAPI &NS, edit::Commit &commit) { - const ObjCList &Protocols = IDecl->getReferencedProtocols(); - std::string ClassString; - SourceLocation EndLoc = - IDecl->getSuperClass() ? IDecl->getSuperClassLoc() : IDecl->getLocation(); - - if (Protocols.empty()) { - ClassString = '<'; - for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { - ClassString += ConformingProtocols[i]->getNameAsString(); - if (i != (e-1)) - ClassString += ", "; - } - ClassString += "> "; - } - else { - ClassString = ", "; - for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { - ClassString += ConformingProtocols[i]->getNameAsString(); - if (i != (e-1)) - ClassString += ", "; - } - ObjCInterfaceDecl::protocol_loc_iterator PL = IDecl->protocol_loc_end() - 1; - EndLoc = *PL; - } - - commit.insertAfterToken(EndLoc, ClassString); - return true; -} - -static StringRef GetUnsignedName(StringRef NSIntegerName) { - StringRef UnsignedName = llvm::StringSwitch(NSIntegerName) - .Case("int8_t", "uint8_t") - .Case("int16_t", "uint16_t") - .Case("int32_t", "uint32_t") - .Case("NSInteger", "NSUInteger") - .Case("int64_t", "uint64_t") - .Default(NSIntegerName); - return UnsignedName; -} - -static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl, - const TypedefDecl *TypedefDcl, - const NSAPI &NS, edit::Commit &commit, - StringRef NSIntegerName, - bool NSOptions) { - std::string ClassString; - if (NSOptions) { - ClassString = "typedef NS_OPTIONS("; - ClassString += GetUnsignedName(NSIntegerName); - } - else { - ClassString = "typedef NS_ENUM("; - ClassString += NSIntegerName; - } - ClassString += ", "; - - ClassString += TypedefDcl->getIdentifier()->getName(); - ClassString += ')'; - SourceRange R(EnumDcl->getBeginLoc(), EnumDcl->getBeginLoc()); - commit.replace(R, ClassString); - SourceLocation EndOfEnumDclLoc = EnumDcl->getEndLoc(); - EndOfEnumDclLoc = trans::findSemiAfterLocation(EndOfEnumDclLoc, - NS.getASTContext(), /*IsDecl*/true); - if (EndOfEnumDclLoc.isValid()) { - SourceRange EnumDclRange(EnumDcl->getBeginLoc(), EndOfEnumDclLoc); - commit.insertFromRange(TypedefDcl->getBeginLoc(), EnumDclRange); - } - else - return false; - - SourceLocation EndTypedefDclLoc = TypedefDcl->getEndLoc(); - EndTypedefDclLoc = trans::findSemiAfterLocation(EndTypedefDclLoc, - NS.getASTContext(), /*IsDecl*/true); - if (EndTypedefDclLoc.isValid()) { - SourceRange TDRange(TypedefDcl->getBeginLoc(), EndTypedefDclLoc); - commit.remove(TDRange); - } - else - return false; - - EndOfEnumDclLoc = - trans::findLocationAfterSemi(EnumDcl->getEndLoc(), NS.getASTContext(), - /*IsDecl*/ true); - if (EndOfEnumDclLoc.isValid()) { - SourceLocation BeginOfEnumDclLoc = EnumDcl->getBeginLoc(); - // FIXME. This assumes that enum decl; is immediately preceded 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; -} - -static void rewriteToNSMacroDecl(ASTContext &Ctx, - const EnumDecl *EnumDcl, - const TypedefDecl *TypedefDcl, - const NSAPI &NS, edit::Commit &commit, - bool IsNSIntegerType) { - QualType DesignatedEnumType = EnumDcl->getIntegerType(); - assert(!DesignatedEnumType.isNull() - && "rewriteToNSMacroDecl - underlying enum type is null"); - - PrintingPolicy Policy(Ctx.getPrintingPolicy()); - std::string TypeString = DesignatedEnumType.getAsString(Policy); - std::string ClassString = IsNSIntegerType ? "NS_ENUM(" : "NS_OPTIONS("; - ClassString += TypeString; - ClassString += ", "; - - ClassString += TypedefDcl->getIdentifier()->getName(); - ClassString += ") "; - SourceLocation EndLoc = EnumDcl->getBraceRange().getBegin(); - if (EndLoc.isInvalid()) - return; - CharSourceRange R = - CharSourceRange::getCharRange(EnumDcl->getBeginLoc(), EndLoc); - commit.replace(R, ClassString); - // This is to remove spaces between '}' and typedef name. - SourceLocation StartTypedefLoc = EnumDcl->getEndLoc(); - StartTypedefLoc = StartTypedefLoc.getLocWithOffset(+1); - SourceLocation EndTypedefLoc = TypedefDcl->getEndLoc(); - - commit.remove(SourceRange(StartTypedefLoc, EndTypedefLoc)); -} - -static bool UseNSOptionsMacro(Preprocessor &PP, ASTContext &Ctx, - const EnumDecl *EnumDcl) { - bool PowerOfTwo = true; - bool AllHexdecimalEnumerator = true; - uint64_t MaxPowerOfTwoVal = 0; - for (auto *Enumerator : EnumDcl->enumerators()) { - const Expr *InitExpr = Enumerator->getInitExpr(); - if (!InitExpr) { - PowerOfTwo = false; - AllHexdecimalEnumerator = false; - continue; - } - InitExpr = InitExpr->IgnoreParenCasts(); - if (const BinaryOperator *BO = dyn_cast(InitExpr)) - if (BO->isShiftOp() || BO->isBitwiseOp()) - return true; - - uint64_t EnumVal = Enumerator->getInitVal().getZExtValue(); - if (PowerOfTwo && EnumVal) { - if (!llvm::isPowerOf2_64(EnumVal)) - PowerOfTwo = false; - else if (EnumVal > MaxPowerOfTwoVal) - MaxPowerOfTwoVal = EnumVal; - } - if (AllHexdecimalEnumerator && EnumVal) { - bool FoundHexdecimalEnumerator = false; - SourceLocation EndLoc = Enumerator->getEndLoc(); - Token Tok; - if (!PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true)) - if (Tok.isLiteral() && Tok.getLength() > 2) { - if (const char *StringLit = Tok.getLiteralData()) - FoundHexdecimalEnumerator = - (StringLit[0] == '0' && (toLowercase(StringLit[1]) == 'x')); - } - if (!FoundHexdecimalEnumerator) - AllHexdecimalEnumerator = false; - } - } - return AllHexdecimalEnumerator || (PowerOfTwo && (MaxPowerOfTwoVal > 2)); -} - -void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx, - const ObjCImplementationDecl *ImpDecl) { - const ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface(); - if (!IDecl || ObjCProtocolDecls.empty() || IDecl->isDeprecated()) - return; - // Find all implicit conforming protocols for this class - // and make them explicit. - llvm::SmallPtrSet ExplicitProtocols; - Ctx.CollectInheritedProtocols(IDecl, ExplicitProtocols); - llvm::SmallVector PotentialImplicitProtocols; - - for (ObjCProtocolDecl *ProtDecl : ObjCProtocolDecls) - if (!ExplicitProtocols.count(ProtDecl)) - PotentialImplicitProtocols.push_back(ProtDecl); - - if (PotentialImplicitProtocols.empty()) - return; - - // go through list of non-optional methods and properties in each protocol - // in the PotentialImplicitProtocols list. If class implements every one of the - // methods and properties, then this class conforms to this protocol. - llvm::SmallVector ConformingProtocols; - for (unsigned i = 0, e = PotentialImplicitProtocols.size(); i != e; i++) - if (ClassImplementsAllMethodsAndProperties(Ctx, ImpDecl, IDecl, - PotentialImplicitProtocols[i])) - ConformingProtocols.push_back(PotentialImplicitProtocols[i]); - - if (ConformingProtocols.empty()) - return; - - // Further reduce number of conforming protocols. If protocol P1 is in the list - // protocol P2 (P2), No need to include P1. - llvm::SmallVector MinimalConformingProtocols; - for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { - bool DropIt = false; - ObjCProtocolDecl *TargetPDecl = ConformingProtocols[i]; - for (unsigned i1 = 0, e1 = ConformingProtocols.size(); i1 != e1; i1++) { - ObjCProtocolDecl *PDecl = ConformingProtocols[i1]; - if (PDecl == TargetPDecl) - continue; - if (PDecl->lookupProtocolNamed( - TargetPDecl->getDeclName().getAsIdentifierInfo())) { - DropIt = true; - break; - } - } - if (!DropIt) - MinimalConformingProtocols.push_back(TargetPDecl); - } - if (MinimalConformingProtocols.empty()) - return; - edit::Commit commit(*Editor); - rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols, - *NSAPIObj, commit); - 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() || - EnumDcl->isDeprecated()) - return false; - if (!TypedefDcl) { - if (NSIntegerTypedefed) { - TypedefDcl = NSIntegerTypedefed; - NSIntegerTypedefed = nullptr; - } - else if (NSUIntegerTypedefed) { - TypedefDcl = NSUIntegerTypedefed; - NSUIntegerTypedefed = nullptr; - } - else - return false; - FileID FileIdOfTypedefDcl = - PP.getSourceManager().getFileID(TypedefDcl->getLocation()); - FileID FileIdOfEnumDcl = - PP.getSourceManager().getFileID(EnumDcl->getLocation()); - if (FileIdOfTypedefDcl != FileIdOfEnumDcl) - return false; - } - if (TypedefDcl->isDeprecated()) - return false; - - QualType qt = TypedefDcl->getTypeSourceInfo()->getType(); - StringRef NSIntegerName = NSAPIObj->GetNSIntegralKind(qt); - - if (NSIntegerName.empty()) { - // Also check for typedef enum {...} TD; - if (const EnumType *EnumTy = qt->getAs()) { - if (EnumTy->getDecl() == EnumDcl) { - bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl); - if (!InsertFoundation(Ctx, TypedefDcl->getBeginLoc())) - return false; - edit::Commit commit(*Editor); - rewriteToNSMacroDecl(Ctx, EnumDcl, TypedefDcl, *NSAPIObj, commit, !NSOptions); - Editor->commit(commit); - return true; - } - } - return false; - } - - // We may still use NS_OPTIONS based on what we find in the enumertor list. - bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl); - if (!InsertFoundation(Ctx, TypedefDcl->getBeginLoc())) - return false; - edit::Commit commit(*Editor); - bool Res = rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, - commit, NSIntegerName, NSOptions); - Editor->commit(commit); - return Res; -} - -static void ReplaceWithInstancetype(ASTContext &Ctx, - const ObjCMigrateASTConsumer &ASTC, - ObjCMethodDecl *OM) { - if (OM->getReturnType() == Ctx.getObjCInstanceType()) - return; // already has instancetype. - - SourceRange R; - std::string ClassString; - if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) { - TypeLoc TL = TSInfo->getTypeLoc(); - R = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); - ClassString = "instancetype"; - } - else { - R = SourceRange(OM->getBeginLoc(), OM->getBeginLoc()); - ClassString = OM->isInstanceMethod() ? '-' : '+'; - ClassString += " (instancetype)"; - } - edit::Commit commit(*ASTC.Editor); - commit.replace(R, ClassString); - ASTC.Editor->commit(commit); -} - -static void ReplaceWithClasstype(const ObjCMigrateASTConsumer &ASTC, - ObjCMethodDecl *OM) { - ObjCInterfaceDecl *IDecl = OM->getClassInterface(); - SourceRange R; - std::string ClassString; - if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) { - TypeLoc TL = TSInfo->getTypeLoc(); - R = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); { - ClassString = std::string(IDecl->getName()); - ClassString += "*"; - } - } - else { - R = SourceRange(OM->getBeginLoc(), OM->getBeginLoc()); - ClassString = "+ ("; - ClassString += IDecl->getName(); ClassString += "*)"; - } - edit::Commit commit(*ASTC.Editor); - commit.replace(R, ClassString); - ASTC.Editor->commit(commit); -} - -void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx, - ObjCContainerDecl *CDecl, - ObjCMethodDecl *OM) { - ObjCInstanceTypeFamily OIT_Family = - Selector::getInstTypeMethodFamily(OM->getSelector()); - - std::string ClassName; - switch (OIT_Family) { - case OIT_None: - migrateFactoryMethod(Ctx, CDecl, OM); - return; - case OIT_Array: - ClassName = "NSArray"; - break; - case OIT_Dictionary: - ClassName = "NSDictionary"; - break; - case OIT_Singleton: - migrateFactoryMethod(Ctx, CDecl, OM, OIT_Singleton); - return; - case OIT_Init: - if (OM->getReturnType()->isObjCIdType()) - ReplaceWithInstancetype(Ctx, *this, OM); - return; - case OIT_ReturnsSelf: - migrateFactoryMethod(Ctx, CDecl, OM, OIT_ReturnsSelf); - return; - } - if (!OM->getReturnType()->isObjCIdType()) - return; - - ObjCInterfaceDecl *IDecl = dyn_cast(CDecl); - if (!IDecl) { - if (ObjCCategoryDecl *CatDecl = dyn_cast(CDecl)) - IDecl = CatDecl->getClassInterface(); - else if (ObjCImplDecl *ImpDecl = dyn_cast(CDecl)) - IDecl = ImpDecl->getClassInterface(); - } - if (!IDecl || - !IDecl->lookupInheritedClass(&Ctx.Idents.get(ClassName))) { - migrateFactoryMethod(Ctx, CDecl, OM); - return; - } - ReplaceWithInstancetype(Ctx, *this, OM); -} - -static bool TypeIsInnerPointer(QualType T) { - if (!T->isAnyPointerType()) - return false; - if (T->isObjCObjectPointerType() || T->isObjCBuiltinType() || - T->isBlockPointerType() || T->isFunctionPointerType() || - ento::coreFoundation::isCFObjectRef(T)) - return false; - // Also, typedef-of-pointer-to-incomplete-struct is something that we assume - // is not an innter pointer type. - QualType OrigT = T; - while (const auto *TD = T->getAs()) - T = TD->getDecl()->getUnderlyingType(); - if (OrigT == T || !T->isPointerType()) - return true; - const PointerType* PT = T->getAs(); - QualType UPointeeT = PT->getPointeeType().getUnqualifiedType(); - if (UPointeeT->isRecordType()) { - const RecordType *RecordTy = UPointeeT->getAs(); - if (!RecordTy->getDecl()->isCompleteDefinition()) - return false; - } - return true; -} - -/// Check whether the two versions match. -static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y) { - return (X == Y); -} - -/// AvailabilityAttrsMatch - This routine checks that if comparing two -/// availability attributes, all their components match. It returns -/// true, if not dealing with availability or when all components of -/// availability attributes match. This routine is only called when -/// the attributes are of the same kind. -static bool AvailabilityAttrsMatch(Attr *At1, Attr *At2) { - const AvailabilityAttr *AA1 = dyn_cast(At1); - if (!AA1) - return true; - const AvailabilityAttr *AA2 = cast(At2); - - VersionTuple Introduced1 = AA1->getIntroduced(); - VersionTuple Deprecated1 = AA1->getDeprecated(); - VersionTuple Obsoleted1 = AA1->getObsoleted(); - bool IsUnavailable1 = AA1->getUnavailable(); - VersionTuple Introduced2 = AA2->getIntroduced(); - VersionTuple Deprecated2 = AA2->getDeprecated(); - VersionTuple Obsoleted2 = AA2->getObsoleted(); - bool IsUnavailable2 = AA2->getUnavailable(); - return (versionsMatch(Introduced1, Introduced2) && - versionsMatch(Deprecated1, Deprecated2) && - versionsMatch(Obsoleted1, Obsoleted2) && - IsUnavailable1 == IsUnavailable2); -} - -static bool MatchTwoAttributeLists(const AttrVec &Attrs1, const AttrVec &Attrs2, - bool &AvailabilityArgsMatch) { - // This list is very small, so this need not be optimized. - for (unsigned i = 0, e = Attrs1.size(); i != e; i++) { - bool match = false; - for (unsigned j = 0, f = Attrs2.size(); j != f; j++) { - // Matching attribute kind only. Except for Availability attributes, - // we are not getting into details of the attributes. For all practical purposes - // this is sufficient. - if (Attrs1[i]->getKind() == Attrs2[j]->getKind()) { - if (AvailabilityArgsMatch) - AvailabilityArgsMatch = AvailabilityAttrsMatch(Attrs1[i], Attrs2[j]); - match = true; - break; - } - } - if (!match) - return false; - } - return true; -} - -/// AttributesMatch - This routine checks list of attributes for two -/// decls. It returns false, if there is a mismatch in kind of -/// attributes seen in the decls. It returns true if the two decls -/// have list of same kind of attributes. Furthermore, when there -/// are availability attributes in the two decls, it sets the -/// AvailabilityArgsMatch to false if availability attributes have -/// different versions, etc. -static bool AttributesMatch(const Decl *Decl1, const Decl *Decl2, - bool &AvailabilityArgsMatch) { - if (!Decl1->hasAttrs() || !Decl2->hasAttrs()) { - AvailabilityArgsMatch = (Decl1->hasAttrs() == Decl2->hasAttrs()); - return true; - } - AvailabilityArgsMatch = true; - const AttrVec &Attrs1 = Decl1->getAttrs(); - const AttrVec &Attrs2 = Decl2->getAttrs(); - bool match = MatchTwoAttributeLists(Attrs1, Attrs2, AvailabilityArgsMatch); - if (match && (Attrs2.size() > Attrs1.size())) - return MatchTwoAttributeLists(Attrs2, Attrs1, AvailabilityArgsMatch); - return match; -} - -static bool IsValidIdentifier(ASTContext &Ctx, - const char *Name) { - if (!isAsciiIdentifierStart(Name[0])) - return false; - std::string NameString = Name; - NameString[0] = toLowercase(NameString[0]); - const IdentifierInfo *II = &Ctx.Idents.get(NameString); - return II->getTokenID() == tok::identifier; -} - -bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx, - ObjCContainerDecl *D, - ObjCMethodDecl *Method) { - if (Method->isPropertyAccessor() || !Method->isInstanceMethod() || - Method->param_size() != 0) - return false; - // Is this method candidate to be a getter? - QualType GRT = Method->getReturnType(); - if (GRT->isVoidType()) - return false; - - Selector GetterSelector = Method->getSelector(); - ObjCInstanceTypeFamily OIT_Family = - Selector::getInstTypeMethodFamily(GetterSelector); - - if (OIT_Family != OIT_None) - return false; - - const IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0); - Selector SetterSelector = - SelectorTable::constructSetterSelector(PP.getIdentifierTable(), - PP.getSelectorTable(), - getterName); - ObjCMethodDecl *SetterMethod = D->getInstanceMethod(SetterSelector); - unsigned LengthOfPrefix = 0; - if (!SetterMethod) { - // try a different naming convention for getter: isXxxxx - StringRef getterNameString = getterName->getName(); - bool IsPrefix = getterNameString.starts_with("is"); - // Note that we don't want to change an isXXX method of retainable object - // type to property (readonly or otherwise). - if (IsPrefix && GRT->isObjCRetainableType()) - return false; - if (IsPrefix || getterNameString.starts_with("get")) { - LengthOfPrefix = (IsPrefix ? 2 : 3); - const char *CGetterName = getterNameString.data() + LengthOfPrefix; - // Make sure that first character after "is" or "get" prefix can - // start an identifier. - if (!IsValidIdentifier(Ctx, CGetterName)) - return false; - if (CGetterName[0] && isUppercase(CGetterName[0])) { - getterName = &Ctx.Idents.get(CGetterName); - SetterSelector = - SelectorTable::constructSetterSelector(PP.getIdentifierTable(), - PP.getSelectorTable(), - getterName); - SetterMethod = D->getInstanceMethod(SetterSelector); - } - } - } - - if (SetterMethod) { - if ((ASTMigrateActions & FrontendOptions::ObjCMT_ReadwriteProperty) == 0) - return false; - bool AvailabilityArgsMatch; - if (SetterMethod->isDeprecated() || - !AttributesMatch(Method, SetterMethod, AvailabilityArgsMatch)) - return false; - - // Is this a valid setter, matching the target getter? - QualType SRT = SetterMethod->getReturnType(); - if (!SRT->isVoidType()) - return false; - const ParmVarDecl *argDecl = *SetterMethod->param_begin(); - QualType ArgType = argDecl->getType(); - if (!Ctx.hasSameUnqualifiedType(ArgType, GRT)) - return false; - edit::Commit commit(*Editor); - rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit, - LengthOfPrefix, - (ASTMigrateActions & - FrontendOptions::ObjCMT_AtomicProperty) != 0, - (ASTMigrateActions & - FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty) != 0, - AvailabilityArgsMatch); - Editor->commit(commit); - return true; - } - else if (ASTMigrateActions & FrontendOptions::ObjCMT_ReadonlyProperty) { - // Try a non-void method with no argument (and no setter or property of same name - // as a 'readonly' property. - edit::Commit commit(*Editor); - rewriteToObjCProperty(Method, nullptr /*SetterMethod*/, *NSAPIObj, commit, - LengthOfPrefix, - (ASTMigrateActions & - FrontendOptions::ObjCMT_AtomicProperty) != 0, - (ASTMigrateActions & - FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty) != 0, - /*AvailabilityArgsMatch*/false); - Editor->commit(commit); - return true; - } - return false; -} - -void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx, - ObjCMethodDecl *OM) { - if (OM->isImplicit() || - !OM->isInstanceMethod() || - OM->hasAttr()) - return; - - QualType RT = OM->getReturnType(); - if (!TypeIsInnerPointer(RT) || - !NSAPIObj->isMacroDefined("NS_RETURNS_INNER_POINTER")) - return; - - edit::Commit commit(*Editor); - commit.insertBefore(OM->getEndLoc(), " NS_RETURNS_INNER_POINTER"); - Editor->commit(commit); -} - -void ObjCMigrateASTConsumer::migratePropertyNsReturnsInnerPointer(ASTContext &Ctx, - ObjCPropertyDecl *P) { - QualType T = P->getType(); - - if (!TypeIsInnerPointer(T) || - !NSAPIObj->isMacroDefined("NS_RETURNS_INNER_POINTER")) - return; - edit::Commit commit(*Editor); - commit.insertBefore(P->getEndLoc(), " NS_RETURNS_INNER_POINTER "); - Editor->commit(commit); -} - -void ObjCMigrateASTConsumer::migrateAllMethodInstaceType(ASTContext &Ctx, - ObjCContainerDecl *CDecl) { - if (CDecl->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(CDecl)) - return; - - // migrate methods which can have instancetype as their result type. - for (auto *Method : CDecl->methods()) { - if (Method->isDeprecated()) - continue; - migrateMethodInstanceType(Ctx, CDecl, Method); - } -} - -void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx, - ObjCContainerDecl *CDecl, - ObjCMethodDecl *OM, - ObjCInstanceTypeFamily OIT_Family) { - if (OM->isInstanceMethod() || - OM->getReturnType() == Ctx.getObjCInstanceType() || - !OM->getReturnType()->isObjCIdType()) - return; - - // Candidate factory methods are + (id) NaMeXXX : ... which belong to a class - // NSYYYNamE with matching names be at least 3 characters long. - ObjCInterfaceDecl *IDecl = dyn_cast(CDecl); - if (!IDecl) { - if (ObjCCategoryDecl *CatDecl = dyn_cast(CDecl)) - IDecl = CatDecl->getClassInterface(); - else if (ObjCImplDecl *ImpDecl = dyn_cast(CDecl)) - IDecl = ImpDecl->getClassInterface(); - } - if (!IDecl) - return; - - std::string StringClassName = std::string(IDecl->getName()); - StringRef LoweredClassName(StringClassName); - std::string StringLoweredClassName = LoweredClassName.lower(); - LoweredClassName = StringLoweredClassName; - - const IdentifierInfo *MethodIdName = - OM->getSelector().getIdentifierInfoForSlot(0); - // Handle method with no name at its first selector slot; e.g. + (id):(int)x. - if (!MethodIdName) - return; - - std::string MethodName = std::string(MethodIdName->getName()); - if (OIT_Family == OIT_Singleton || OIT_Family == OIT_ReturnsSelf) { - StringRef STRefMethodName(MethodName); - size_t len = 0; - if (STRefMethodName.starts_with("standard")) - len = strlen("standard"); - else if (STRefMethodName.starts_with("shared")) - len = strlen("shared"); - else if (STRefMethodName.starts_with("default")) - len = strlen("default"); - else - return; - MethodName = std::string(STRefMethodName.substr(len)); - } - std::string MethodNameSubStr = MethodName.substr(0, 3); - StringRef MethodNamePrefix(MethodNameSubStr); - std::string StringLoweredMethodNamePrefix = MethodNamePrefix.lower(); - MethodNamePrefix = StringLoweredMethodNamePrefix; - size_t Ix = LoweredClassName.rfind(MethodNamePrefix); - if (Ix == StringRef::npos) - return; - std::string ClassNamePostfix = std::string(LoweredClassName.substr(Ix)); - StringRef LoweredMethodName(MethodName); - std::string StringLoweredMethodName = LoweredMethodName.lower(); - LoweredMethodName = StringLoweredMethodName; - if (!LoweredMethodName.starts_with(ClassNamePostfix)) - return; - if (OIT_Family == OIT_ReturnsSelf) - ReplaceWithClasstype(*this, OM); - else - ReplaceWithInstancetype(Ctx, *this, OM); -} - -static bool IsVoidStarType(QualType Ty) { - if (!Ty->isPointerType()) - return false; - - // Is the type void*? - const PointerType* PT = Ty->castAs(); - if (PT->getPointeeType().getUnqualifiedType()->isVoidType()) - return true; - return IsVoidStarType(PT->getPointeeType()); -} - -/// AuditedType - This routine audits the type AT and returns false if it is one of known -/// CF object types or of the "void *" variety. It returns true if we don't care about the type -/// such as a non-pointer or pointers which have no ownership issues (such as "int *"). -static bool AuditedType (QualType AT) { - if (!AT->isAnyPointerType() && !AT->isBlockPointerType()) - return true; - // FIXME. There isn't much we can say about CF pointer type; or is there? - if (ento::coreFoundation::isCFObjectRef(AT) || - IsVoidStarType(AT) || - // If an ObjC object is type, assuming that it is not a CF function and - // that it is an un-audited function. - AT->isObjCObjectPointerType() || AT->isObjCBuiltinType()) - return false; - // All other pointers are assumed audited as harmless. - return true; -} - -void ObjCMigrateASTConsumer::AnnotateImplicitBridging(ASTContext &Ctx) { - if (CFFunctionIBCandidates.empty()) - return; - if (!NSAPIObj->isMacroDefined("CF_IMPLICIT_BRIDGING_ENABLED")) { - CFFunctionIBCandidates.clear(); - FileId = FileID(); - return; - } - // Insert CF_IMPLICIT_BRIDGING_ENABLE/CF_IMPLICIT_BRIDGING_DISABLED - const Decl *FirstFD = CFFunctionIBCandidates[0]; - const Decl *LastFD = - CFFunctionIBCandidates[CFFunctionIBCandidates.size()-1]; - const char *PragmaString = "\nCF_IMPLICIT_BRIDGING_ENABLED\n\n"; - edit::Commit commit(*Editor); - commit.insertBefore(FirstFD->getBeginLoc(), PragmaString); - PragmaString = "\n\nCF_IMPLICIT_BRIDGING_DISABLED\n"; - SourceLocation EndLoc = LastFD->getEndLoc(); - // get location just past end of function location. - EndLoc = PP.getLocForEndOfToken(EndLoc); - if (isa(LastFD)) { - // For Methods, EndLoc points to the ending semcolon. So, - // not of these extra work is needed. - Token Tok; - // get locaiton of token that comes after end of function. - bool Failed = PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true); - if (!Failed) - EndLoc = Tok.getLocation(); - } - commit.insertAfterToken(EndLoc, PragmaString); - Editor->commit(commit); - FileId = FileID(); - CFFunctionIBCandidates.clear(); -} - -void ObjCMigrateASTConsumer::migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl) { - if (Decl->isDeprecated()) - return; - - if (Decl->hasAttr()) { - assert(CFFunctionIBCandidates.empty() && - "Cannot have audited functions/methods inside user " - "provided CF_IMPLICIT_BRIDGING_ENABLE"); - return; - } - - // Finction must be annotated first. - if (const FunctionDecl *FuncDecl = dyn_cast(Decl)) { - CF_BRIDGING_KIND AuditKind = migrateAddFunctionAnnotation(Ctx, FuncDecl); - if (AuditKind == CF_BRIDGING_ENABLE) { - CFFunctionIBCandidates.push_back(Decl); - if (FileId.isInvalid()) - FileId = PP.getSourceManager().getFileID(Decl->getLocation()); - } - else if (AuditKind == CF_BRIDGING_MAY_INCLUDE) { - if (!CFFunctionIBCandidates.empty()) { - CFFunctionIBCandidates.push_back(Decl); - if (FileId.isInvalid()) - FileId = PP.getSourceManager().getFileID(Decl->getLocation()); - } - } - else - AnnotateImplicitBridging(Ctx); - } - else { - migrateAddMethodAnnotation(Ctx, cast(Decl)); - AnnotateImplicitBridging(Ctx); - } -} - -void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, - const RetainSummary *RS, - const FunctionDecl *FuncDecl, - bool ResultAnnotated) { - // Annotate function. - if (!ResultAnnotated) { - RetEffect Ret = RS->getRetEffect(); - const char *AnnotationString = nullptr; - if (Ret.getObjKind() == ObjKind::CF) { - if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED")) - AnnotationString = " CF_RETURNS_RETAINED"; - else if (Ret.notOwned() && - NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED")) - AnnotationString = " CF_RETURNS_NOT_RETAINED"; - } - else if (Ret.getObjKind() == ObjKind::ObjC) { - if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED")) - AnnotationString = " NS_RETURNS_RETAINED"; - } - - if (AnnotationString) { - edit::Commit commit(*Editor); - commit.insertAfterToken(FuncDecl->getEndLoc(), AnnotationString); - Editor->commit(commit); - } - } - unsigned i = 0; - for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(), - pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) { - const ParmVarDecl *pd = *pi; - ArgEffect AE = RS->getArg(i); - if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::CF && - !pd->hasAttr() && - NSAPIObj->isMacroDefined("CF_CONSUMED")) { - edit::Commit commit(*Editor); - commit.insertBefore(pd->getLocation(), "CF_CONSUMED "); - Editor->commit(commit); - } else if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::ObjC && - !pd->hasAttr() && - NSAPIObj->isMacroDefined("NS_CONSUMED")) { - edit::Commit commit(*Editor); - commit.insertBefore(pd->getLocation(), "NS_CONSUMED "); - Editor->commit(commit); - } - } -} - -ObjCMigrateASTConsumer::CF_BRIDGING_KIND - ObjCMigrateASTConsumer::migrateAddFunctionAnnotation( - ASTContext &Ctx, - const FunctionDecl *FuncDecl) { - if (FuncDecl->hasBody()) - return CF_BRIDGING_NONE; - - const RetainSummary *RS = - getSummaryManager(Ctx).getSummary(AnyCall(FuncDecl)); - bool FuncIsReturnAnnotated = (FuncDecl->hasAttr() || - FuncDecl->hasAttr() || - FuncDecl->hasAttr() || - FuncDecl->hasAttr() || - FuncDecl->hasAttr()); - - // Trivial case of when function is annotated and has no argument. - if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0) - return CF_BRIDGING_NONE; - - bool ReturnCFAudited = false; - if (!FuncIsReturnAnnotated) { - RetEffect Ret = RS->getRetEffect(); - if (Ret.getObjKind() == ObjKind::CF && - (Ret.isOwned() || Ret.notOwned())) - ReturnCFAudited = true; - else if (!AuditedType(FuncDecl->getReturnType())) - return CF_BRIDGING_NONE; - } - - // At this point result type is audited for potential inclusion. - unsigned i = 0; - bool ArgCFAudited = false; - for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(), - pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) { - const ParmVarDecl *pd = *pi; - ArgEffect AE = RS->getArg(i); - if ((AE.getKind() == DecRef /*CFConsumed annotated*/ || - AE.getKind() == IncRef) && AE.getObjKind() == ObjKind::CF) { - if (AE.getKind() == DecRef && !pd->hasAttr()) - ArgCFAudited = true; - else if (AE.getKind() == IncRef) - ArgCFAudited = true; - } else { - QualType AT = pd->getType(); - if (!AuditedType(AT)) { - AddCFAnnotations(Ctx, RS, FuncDecl, FuncIsReturnAnnotated); - return CF_BRIDGING_NONE; - } - } - } - if (ReturnCFAudited || ArgCFAudited) - return CF_BRIDGING_ENABLE; - - return CF_BRIDGING_MAY_INCLUDE; -} - -void ObjCMigrateASTConsumer::migrateARCSafeAnnotation(ASTContext &Ctx, - ObjCContainerDecl *CDecl) { - if (!isa(CDecl) || CDecl->isDeprecated()) - return; - - // migrate methods which can have instancetype as their result type. - for (const auto *Method : CDecl->methods()) - migrateCFAnnotation(Ctx, Method); -} - -void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, - const RetainSummary *RS, - const ObjCMethodDecl *MethodDecl, - bool ResultAnnotated) { - // Annotate function. - if (!ResultAnnotated) { - RetEffect Ret = RS->getRetEffect(); - const char *AnnotationString = nullptr; - if (Ret.getObjKind() == ObjKind::CF) { - if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED")) - AnnotationString = " CF_RETURNS_RETAINED"; - else if (Ret.notOwned() && - NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED")) - AnnotationString = " CF_RETURNS_NOT_RETAINED"; - } - else if (Ret.getObjKind() == ObjKind::ObjC) { - ObjCMethodFamily OMF = MethodDecl->getMethodFamily(); - switch (OMF) { - case clang::OMF_alloc: - case clang::OMF_new: - case clang::OMF_copy: - case clang::OMF_init: - case clang::OMF_mutableCopy: - break; - - default: - if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED")) - AnnotationString = " NS_RETURNS_RETAINED"; - break; - } - } - - if (AnnotationString) { - edit::Commit commit(*Editor); - commit.insertBefore(MethodDecl->getEndLoc(), AnnotationString); - Editor->commit(commit); - } - } - unsigned i = 0; - for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(), - pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) { - const ParmVarDecl *pd = *pi; - ArgEffect AE = RS->getArg(i); - if (AE.getKind() == DecRef - && AE.getObjKind() == ObjKind::CF - && !pd->hasAttr() && - NSAPIObj->isMacroDefined("CF_CONSUMED")) { - edit::Commit commit(*Editor); - commit.insertBefore(pd->getLocation(), "CF_CONSUMED "); - Editor->commit(commit); - } - } -} - -void ObjCMigrateASTConsumer::migrateAddMethodAnnotation( - ASTContext &Ctx, - const ObjCMethodDecl *MethodDecl) { - if (MethodDecl->hasBody() || MethodDecl->isImplicit()) - return; - - const RetainSummary *RS = - getSummaryManager(Ctx).getSummary(AnyCall(MethodDecl)); - - bool MethodIsReturnAnnotated = - (MethodDecl->hasAttr() || - MethodDecl->hasAttr() || - MethodDecl->hasAttr() || - MethodDecl->hasAttr() || - MethodDecl->hasAttr()); - - if (RS->getReceiverEffect().getKind() == DecRef && - !MethodDecl->hasAttr() && - MethodDecl->getMethodFamily() != OMF_init && - MethodDecl->getMethodFamily() != OMF_release && - NSAPIObj->isMacroDefined("NS_CONSUMES_SELF")) { - edit::Commit commit(*Editor); - commit.insertBefore(MethodDecl->getEndLoc(), " NS_CONSUMES_SELF"); - Editor->commit(commit); - } - - // Trivial case of when function is annotated and has no argument. - if (MethodIsReturnAnnotated && - (MethodDecl->param_begin() == MethodDecl->param_end())) - return; - - if (!MethodIsReturnAnnotated) { - RetEffect Ret = RS->getRetEffect(); - if ((Ret.getObjKind() == ObjKind::CF || - Ret.getObjKind() == ObjKind::ObjC) && - (Ret.isOwned() || Ret.notOwned())) { - AddCFAnnotations(Ctx, RS, MethodDecl, false); - return; - } else if (!AuditedType(MethodDecl->getReturnType())) - return; - } - - // At this point result type is either annotated or audited. - unsigned i = 0; - for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(), - pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) { - const ParmVarDecl *pd = *pi; - ArgEffect AE = RS->getArg(i); - if ((AE.getKind() == DecRef && !pd->hasAttr()) || - AE.getKind() == IncRef || !AuditedType(pd->getType())) { - AddCFAnnotations(Ctx, RS, MethodDecl, MethodIsReturnAnnotated); - return; - } - } -} - -namespace { -class SuperInitChecker : public RecursiveASTVisitor { -public: - bool shouldVisitTemplateInstantiations() const { return false; } - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) { - if (E->getMethodFamily() == OMF_init) - return false; - } - return true; - } -}; -} // end anonymous namespace - -static bool hasSuperInitCall(const ObjCMethodDecl *MD) { - return !SuperInitChecker().TraverseStmt(MD->getBody()); -} - -void ObjCMigrateASTConsumer::inferDesignatedInitializers( - ASTContext &Ctx, - const ObjCImplementationDecl *ImplD) { - - const ObjCInterfaceDecl *IFace = ImplD->getClassInterface(); - if (!IFace || IFace->hasDesignatedInitializers()) - return; - if (!NSAPIObj->isMacroDefined("NS_DESIGNATED_INITIALIZER")) - return; - - for (const auto *MD : ImplD->instance_methods()) { - if (MD->isDeprecated() || - MD->getMethodFamily() != OMF_init || - MD->isDesignatedInitializerForTheInterface()) - continue; - const ObjCMethodDecl *IFaceM = IFace->getMethod(MD->getSelector(), - /*isInstance=*/true); - if (!IFaceM) - continue; - if (hasSuperInitCall(MD)) { - edit::Commit commit(*Editor); - commit.insert(IFaceM->getEndLoc(), " NS_DESIGNATED_INITIALIZER"); - Editor->commit(commit); - } - } -} - -bool ObjCMigrateASTConsumer::InsertFoundation(ASTContext &Ctx, - SourceLocation Loc) { - if (FoundationIncluded) - return true; - if (Loc.isInvalid()) - return false; - auto *nsEnumId = &Ctx.Idents.get("NS_ENUM"); - if (PP.getMacroDefinitionAtLoc(nsEnumId, Loc)) { - FoundationIncluded = true; - return true; - } - edit::Commit commit(*Editor); - if (Ctx.getLangOpts().Modules) - commit.insert(Loc, "#ifndef NS_ENUM\n@import Foundation;\n#endif\n"); - else - commit.insert(Loc, "#ifndef NS_ENUM\n#import \n#endif\n"); - Editor->commit(commit); - FoundationIncluded = true; - return true; -} - -namespace { - -class RewritesReceiver : public edit::EditsReceiver { - Rewriter &Rewrite; - -public: - RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { } - - void insert(SourceLocation loc, StringRef text) override { - Rewrite.InsertText(loc, text); - } - void replace(CharSourceRange range, StringRef text) override { - Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text); - } -}; - -class JSONEditWriter : public edit::EditsReceiver { - SourceManager &SourceMgr; - llvm::raw_ostream &OS; - -public: - JSONEditWriter(SourceManager &SM, llvm::raw_ostream &OS) - : SourceMgr(SM), OS(OS) { - OS << "[\n"; - } - ~JSONEditWriter() override { OS << "]\n"; } - -private: - struct EntryWriter { - SourceManager &SourceMgr; - llvm::raw_ostream &OS; - - EntryWriter(SourceManager &SM, llvm::raw_ostream &OS) - : SourceMgr(SM), OS(OS) { - OS << " {\n"; - } - ~EntryWriter() { - OS << " },\n"; - } - - void writeLoc(SourceLocation Loc) { - FileID FID; - unsigned Offset; - std::tie(FID, Offset) = SourceMgr.getDecomposedLoc(Loc); - assert(FID.isValid()); - SmallString<200> Path = - StringRef(SourceMgr.getFileEntryRefForID(FID)->getName()); - llvm::sys::fs::make_absolute(Path); - OS << " \"file\": \""; - OS.write_escaped(Path.str()) << "\",\n"; - OS << " \"offset\": " << Offset << ",\n"; - } - - void writeRemove(CharSourceRange Range) { - assert(Range.isCharRange()); - std::pair Begin = - SourceMgr.getDecomposedLoc(Range.getBegin()); - std::pair End = - SourceMgr.getDecomposedLoc(Range.getEnd()); - assert(Begin.first == End.first); - assert(Begin.second <= End.second); - unsigned Length = End.second - Begin.second; - - OS << " \"remove\": " << Length << ",\n"; - } - - void writeText(StringRef Text) { - OS << " \"text\": \""; - OS.write_escaped(Text) << "\",\n"; - } - }; - - void insert(SourceLocation Loc, StringRef Text) override { - EntryWriter Writer(SourceMgr, OS); - Writer.writeLoc(Loc); - Writer.writeText(Text); - } - - void replace(CharSourceRange Range, StringRef Text) override { - EntryWriter Writer(SourceMgr, OS); - Writer.writeLoc(Range.getBegin()); - Writer.writeRemove(Range); - Writer.writeText(Text); - } - - void remove(CharSourceRange Range) override { - EntryWriter Writer(SourceMgr, OS); - Writer.writeLoc(Range.getBegin()); - Writer.writeRemove(Range); - } -}; - -} // end anonymous namespace - -void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { - - TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl(); - if (ASTMigrateActions & FrontendOptions::ObjCMT_MigrateDecls) { - for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end(); - D != DEnd; ++D) { - FileID FID = PP.getSourceManager().getFileID((*D)->getLocation()); - if (FID.isValid()) - if (FileId.isValid() && FileId != FID) { - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) - AnnotateImplicitBridging(Ctx); - } - - if (ObjCInterfaceDecl *CDecl = dyn_cast(*D)) - if (canModify(CDecl)) - migrateObjCContainerDecl(Ctx, CDecl); - if (ObjCCategoryDecl *CatDecl = dyn_cast(*D)) { - if (canModify(CatDecl)) - migrateObjCContainerDecl(Ctx, CatDecl); - } - else if (ObjCProtocolDecl *PDecl = dyn_cast(*D)) { - ObjCProtocolDecls.insert(PDecl->getCanonicalDecl()); - if (canModify(PDecl)) - migrateObjCContainerDecl(Ctx, PDecl); - } - else if (const ObjCImplementationDecl *ImpDecl = - dyn_cast(*D)) { - if ((ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) && - canModify(ImpDecl)) - migrateProtocolConformance(Ctx, ImpDecl); - } - else if (const EnumDecl *ED = dyn_cast(*D)) { - if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros)) - continue; - if (!canModify(ED)) - continue; - DeclContext::decl_iterator N = D; - if (++N != DEnd) { - const TypedefDecl *TD = dyn_cast(*N); - if (migrateNSEnumDecl(Ctx, ED, TD) && TD) - D++; - } - else - migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */nullptr); - } - else if (const TypedefDecl *TD = dyn_cast(*D)) { - if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros)) - continue; - if (!canModify(TD)) - continue; - DeclContext::decl_iterator N = D; - if (++N == DEnd) - continue; - if (const EnumDecl *ED = dyn_cast(*N)) { - if (canModify(ED)) { - if (++N != DEnd) - if (const TypedefDecl *TDF = dyn_cast(*N)) { - // prefer typedef-follows-enum to enum-follows-typedef pattern. - if (migrateNSEnumDecl(Ctx, ED, TDF)) { - ++D; ++D; - CacheObjCNSIntegerTypedefed(TD); - continue; - } - } - if (migrateNSEnumDecl(Ctx, ED, TD)) { - ++D; - continue; - } - } - } - CacheObjCNSIntegerTypedefed(TD); - } - else if (const FunctionDecl *FD = dyn_cast(*D)) { - if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && - canModify(FD)) - migrateCFAnnotation(Ctx, FD); - } - - if (ObjCContainerDecl *CDecl = dyn_cast(*D)) { - bool CanModify = canModify(CDecl); - // migrate methods which can have instancetype as their result type. - if ((ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype) && - CanModify) - migrateAllMethodInstaceType(Ctx, CDecl); - // annotate methods with CF annotations. - if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && - CanModify) - migrateARCSafeAnnotation(Ctx, CDecl); - } - - if (const ObjCImplementationDecl * - ImplD = dyn_cast(*D)) { - if ((ASTMigrateActions & FrontendOptions::ObjCMT_DesignatedInitializer) && - canModify(ImplD)) - inferDesignatedInitializers(Ctx, ImplD); - } - } - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) - AnnotateImplicitBridging(Ctx); - } - - if (IsOutputFile) { - std::error_code EC; - llvm::raw_fd_ostream OS(MigrateDir, EC, llvm::sys::fs::OF_None); - if (EC) { - DiagnosticsEngine &Diags = Ctx.getDiagnostics(); - Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0")) - << EC.message(); - return; - } - - JSONEditWriter Writer(Ctx.getSourceManager(), OS); - Editor->applyRewrites(Writer); - return; - } - - Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); - RewritesReceiver Rec(rewriter); - Editor->applyRewrites(Rec); - - for (Rewriter::buffer_iterator - I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) { - FileID FID = I->first; - RewriteBuffer &buf = I->second; - OptionalFileEntryRef file = - Ctx.getSourceManager().getFileEntryRefForID(FID); - assert(file); - SmallString<512> newText; - llvm::raw_svector_ostream vecOS(newText); - buf.write(vecOS); - std::unique_ptr memBuf( - llvm::MemoryBuffer::getMemBufferCopy(newText.str(), file->getName())); - SmallString<64> filePath(file->getName()); - FileMgr.FixupRelativePath(filePath); - Remapper.remap(filePath.str(), std::move(memBuf)); - } - - if (IsOutputFile) { - Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics()); - } else { - Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics()); - } -} - -bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) { - CI.getDiagnostics().setIgnoreAllWarnings(true); - return true; -} - -static std::vector getAllowListFilenames(StringRef DirPath) { - using namespace llvm::sys::fs; - using namespace llvm::sys::path; - - std::vector Filenames; - if (DirPath.empty() || !is_directory(DirPath)) - return Filenames; - - std::error_code EC; - directory_iterator DI = directory_iterator(DirPath, EC); - directory_iterator DE; - for (; !EC && DI != DE; DI = DI.increment(EC)) { - if (is_regular_file(DI->path())) - Filenames.push_back(std::string(filename(DI->path()))); - } - - return Filenames; -} - -std::unique_ptr -MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - PPConditionalDirectiveRecord * - PPRec = new PPConditionalDirectiveRecord(CI.getSourceManager()); - unsigned ObjCMTAction = CI.getFrontendOpts().ObjCMTAction; - unsigned ObjCMTOpts = ObjCMTAction; - // These are companion flags, they do not enable transformations. - ObjCMTOpts &= ~(FrontendOptions::ObjCMT_AtomicProperty | - FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty); - if (ObjCMTOpts == FrontendOptions::ObjCMT_None) { - // If no specific option was given, enable literals+subscripting transforms - // by default. - ObjCMTAction |= - FrontendOptions::ObjCMT_Literals | FrontendOptions::ObjCMT_Subscripting; - } - CI.getPreprocessor().addPPCallbacks(std::unique_ptr(PPRec)); - std::vector AllowList = - getAllowListFilenames(CI.getFrontendOpts().ObjCMTAllowListPath); - return std::make_unique( - CI.getFrontendOpts().OutputFile, ObjCMTAction, Remapper, - CI.getFileManager(), PPRec, CI.getPreprocessor(), - /*isOutputFile=*/true, AllowList); -} - -namespace { -struct EditEntry { - OptionalFileEntryRef File; - unsigned Offset = 0; - unsigned RemoveLen = 0; - std::string Text; -}; -} // end anonymous namespace - -namespace llvm { -template<> struct DenseMapInfo { - static inline EditEntry getEmptyKey() { - EditEntry Entry; - Entry.Offset = unsigned(-1); - return Entry; - } - static inline EditEntry getTombstoneKey() { - EditEntry Entry; - Entry.Offset = unsigned(-2); - return Entry; - } - static unsigned getHashValue(const EditEntry& Val) { - return (unsigned)llvm::hash_combine(Val.File, Val.Offset, Val.RemoveLen, - Val.Text); - } - static bool isEqual(const EditEntry &LHS, const EditEntry &RHS) { - return LHS.File == RHS.File && - LHS.Offset == RHS.Offset && - LHS.RemoveLen == RHS.RemoveLen && - LHS.Text == RHS.Text; - } -}; -} // end namespace llvm - -namespace { -class RemapFileParser { - FileManager &FileMgr; - -public: - RemapFileParser(FileManager &FileMgr) : FileMgr(FileMgr) { } - - bool parse(StringRef File, SmallVectorImpl &Entries) { - using namespace llvm::yaml; - - llvm::ErrorOr> FileBufOrErr = - llvm::MemoryBuffer::getFile(File); - if (!FileBufOrErr) - return true; - - llvm::SourceMgr SM; - Stream YAMLStream(FileBufOrErr.get()->getMemBufferRef(), SM); - document_iterator I = YAMLStream.begin(); - if (I == YAMLStream.end()) - return true; - Node *Root = I->getRoot(); - if (!Root) - return true; - - SequenceNode *SeqNode = dyn_cast(Root); - if (!SeqNode) - return true; - - for (SequenceNode::iterator - AI = SeqNode->begin(), AE = SeqNode->end(); AI != AE; ++AI) { - MappingNode *MapNode = dyn_cast(&*AI); - if (!MapNode) - continue; - parseEdit(MapNode, Entries); - } - - return false; - } - -private: - void parseEdit(llvm::yaml::MappingNode *Node, - SmallVectorImpl &Entries) { - using namespace llvm::yaml; - EditEntry Entry; - bool Ignore = false; - - for (MappingNode::iterator - KVI = Node->begin(), KVE = Node->end(); KVI != KVE; ++KVI) { - ScalarNode *KeyString = dyn_cast((*KVI).getKey()); - if (!KeyString) - continue; - SmallString<10> KeyStorage; - StringRef Key = KeyString->getValue(KeyStorage); - - ScalarNode *ValueString = dyn_cast((*KVI).getValue()); - if (!ValueString) - continue; - SmallString<64> ValueStorage; - StringRef Val = ValueString->getValue(ValueStorage); - - if (Key == "file") { - if (auto File = FileMgr.getOptionalFileRef(Val)) - Entry.File = File; - else - Ignore = true; - } else if (Key == "offset") { - if (Val.getAsInteger(10, Entry.Offset)) - Ignore = true; - } else if (Key == "remove") { - if (Val.getAsInteger(10, Entry.RemoveLen)) - Ignore = true; - } else if (Key == "text") { - Entry.Text = std::string(Val); - } - } - - if (!Ignore) - Entries.push_back(Entry); - } -}; -} // end anonymous namespace - -static bool reportDiag(const Twine &Err, DiagnosticsEngine &Diag) { - Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0")) - << Err.str(); - return true; -} - -static std::string applyEditsToTemp(FileEntryRef FE, - ArrayRef Edits, - FileManager &FileMgr, - DiagnosticsEngine &Diag) { - using namespace llvm::sys; - - SourceManager SM(Diag, FileMgr); - FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User); - LangOptions LangOpts; - edit::EditedSource Editor(SM, LangOpts); - for (ArrayRef::iterator - I = Edits.begin(), E = Edits.end(); I != E; ++I) { - const EditEntry &Entry = *I; - assert(Entry.File == FE); - SourceLocation Loc = - SM.getLocForStartOfFile(FID).getLocWithOffset(Entry.Offset); - CharSourceRange Range; - if (Entry.RemoveLen != 0) { - Range = CharSourceRange::getCharRange(Loc, - Loc.getLocWithOffset(Entry.RemoveLen)); - } - - edit::Commit commit(Editor); - if (Range.isInvalid()) { - commit.insert(Loc, Entry.Text); - } else if (Entry.Text.empty()) { - commit.remove(Range); - } else { - commit.replace(Range, Entry.Text); - } - Editor.commit(commit); - } - - Rewriter rewriter(SM, LangOpts); - RewritesReceiver Rec(rewriter); - Editor.applyRewrites(Rec, /*adjustRemovals=*/false); - - const RewriteBuffer *Buf = rewriter.getRewriteBufferFor(FID); - SmallString<512> NewText; - llvm::raw_svector_ostream OS(NewText); - Buf->write(OS); - - SmallString<64> TempPath; - int FD; - if (fs::createTemporaryFile(path::filename(FE.getName()), - path::extension(FE.getName()).drop_front(), FD, - TempPath)) { - reportDiag("Could not create file: " + TempPath.str(), Diag); - return std::string(); - } - - llvm::raw_fd_ostream TmpOut(FD, /*shouldClose=*/true); - TmpOut.write(NewText.data(), NewText.size()); - TmpOut.close(); - - return std::string(TempPath); -} - -bool arcmt::getFileRemappingsFromFileList( - std::vector > &remap, - ArrayRef remapFiles, - DiagnosticConsumer *DiagClient) { - bool hasErrorOccurred = false; - - FileSystemOptions FSOpts; - FileManager FileMgr(FSOpts); - RemapFileParser Parser(FileMgr); - - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, new DiagnosticOptions, - DiagClient, /*ShouldOwnClient=*/false)); - - typedef llvm::DenseMap > - FileEditEntriesTy; - FileEditEntriesTy FileEditEntries; - - llvm::DenseSet EntriesSet; - - for (ArrayRef::iterator - I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) { - SmallVector Entries; - if (Parser.parse(*I, Entries)) - continue; - - for (SmallVectorImpl::iterator - EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) { - EditEntry &Entry = *EI; - if (!Entry.File) - continue; - std::pair::iterator, bool> - Insert = EntriesSet.insert(Entry); - if (!Insert.second) - continue; - - FileEditEntries[*Entry.File].push_back(Entry); - } - } - - for (FileEditEntriesTy::iterator - I = FileEditEntries.begin(), E = FileEditEntries.end(); I != E; ++I) { - std::string TempFile = applyEditsToTemp(I->first, I->second, - FileMgr, *Diags); - if (TempFile.empty()) { - hasErrorOccurred = true; - continue; - } - - remap.emplace_back(std::string(I->first.getName()), TempFile); - } - - return hasErrorOccurred; -} diff --git a/clang/lib/ARCMigrate/PlistReporter.cpp b/clang/lib/ARCMigrate/PlistReporter.cpp deleted file mode 100644 index f78ca5e1c9bdd9..00000000000000 --- a/clang/lib/ARCMigrate/PlistReporter.cpp +++ /dev/null @@ -1,124 +0,0 @@ -//===--- PlistReporter.cpp - ARC Migrate Tool Plist Reporter ----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Internals.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/PlistSupport.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" -using namespace clang; -using namespace arcmt; -using namespace markup; - -static StringRef getLevelName(DiagnosticsEngine::Level Level) { - switch (Level) { - case DiagnosticsEngine::Ignored: - llvm_unreachable("ignored"); - case DiagnosticsEngine::Note: - return "note"; - case DiagnosticsEngine::Remark: - case DiagnosticsEngine::Warning: - return "warning"; - case DiagnosticsEngine::Fatal: - case DiagnosticsEngine::Error: - return "error"; - } - llvm_unreachable("Invalid DiagnosticsEngine level!"); -} - -void arcmt::writeARCDiagsToPlist(const std::string &outPath, - ArrayRef diags, - SourceManager &SM, - const LangOptions &LangOpts) { - DiagnosticIDs DiagIDs; - - // Build up a set of FIDs that we use by scanning the locations and - // ranges of the diagnostics. - FIDMap FM; - SmallVector Fids; - - for (ArrayRef::iterator - I = diags.begin(), E = diags.end(); I != E; ++I) { - const StoredDiagnostic &D = *I; - - AddFID(FM, Fids, SM, D.getLocation()); - - for (StoredDiagnostic::range_iterator - RI = D.range_begin(), RE = D.range_end(); RI != RE; ++RI) { - AddFID(FM, Fids, SM, RI->getBegin()); - AddFID(FM, Fids, SM, RI->getEnd()); - } - } - - std::error_code EC; - llvm::raw_fd_ostream o(outPath, EC, llvm::sys::fs::OF_TextWithCRLF); - if (EC) { - llvm::errs() << "error: could not create file: " << outPath << '\n'; - return; - } - - EmitPlistHeader(o); - - // Write the root object: a containing... - // - "files", an mapping from FIDs to file names - // - "diagnostics", an containing the diagnostics - o << "\n" - " files\n" - " \n"; - - for (FileID FID : Fids) - EmitString(o << " ", SM.getFileEntryRefForID(FID)->getName()) << '\n'; - - o << " \n" - " diagnostics\n" - " \n"; - - for (ArrayRef::iterator - DI = diags.begin(), DE = diags.end(); DI != DE; ++DI) { - - const StoredDiagnostic &D = *DI; - - if (D.getLevel() == DiagnosticsEngine::Ignored) - continue; - - o << " \n"; - - // Output the diagnostic. - o << " description"; - EmitString(o, D.getMessage()) << '\n'; - o << " category"; - EmitString(o, DiagIDs.getCategoryNameFromID( - DiagIDs.getCategoryNumberForDiag(D.getID()))) << '\n'; - o << " type"; - EmitString(o, getLevelName(D.getLevel())) << '\n'; - - // Output the location of the bug. - o << " location\n"; - EmitLocation(o, SM, D.getLocation(), FM, 2); - - // Output the ranges (if any). - if (!D.getRanges().empty()) { - o << " ranges\n"; - o << " \n"; - for (auto &R : D.getRanges()) { - CharSourceRange ExpansionRange = SM.getExpansionRange(R); - EmitRange(o, SM, Lexer::getAsCharRange(ExpansionRange, SM, LangOpts), - FM, 4); - } - o << " \n"; - } - - // Close up the entry. - o << " \n"; - } - - o << " \n"; - - // Finish. - o << "\n\n"; -} diff --git a/clang/lib/ARCMigrate/TransAPIUses.cpp b/clang/lib/ARCMigrate/TransAPIUses.cpp deleted file mode 100644 index 8f5d4f4bde06ca..00000000000000 --- a/clang/lib/ARCMigrate/TransAPIUses.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//===--- TransAPIUses.cpp - Transformations to ARC mode -------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// checkAPIUses: -// -// Emits error/fix with some API uses that are obsolete or not safe in ARC mode: -// -// - NSInvocation's [get/set]ReturnValue and [get/set]Argument are only safe -// with __unsafe_unretained objects. -// - Calling -zone gets replaced with 'nil'. -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Sema/SemaDiagnostic.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class APIChecker : public RecursiveASTVisitor { - MigrationPass &Pass; - - Selector getReturnValueSel, setReturnValueSel; - Selector getArgumentSel, setArgumentSel; - - Selector zoneSel; -public: - APIChecker(MigrationPass &pass) : Pass(pass) { - SelectorTable &sels = Pass.Ctx.Selectors; - IdentifierTable &ids = Pass.Ctx.Idents; - getReturnValueSel = sels.getUnarySelector(&ids.get("getReturnValue")); - setReturnValueSel = sels.getUnarySelector(&ids.get("setReturnValue")); - - const IdentifierInfo *selIds[2]; - selIds[0] = &ids.get("getArgument"); - selIds[1] = &ids.get("atIndex"); - getArgumentSel = sels.getSelector(2, selIds); - selIds[0] = &ids.get("setArgument"); - setArgumentSel = sels.getSelector(2, selIds); - - zoneSel = sels.getNullarySelector(&ids.get("zone")); - } - - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - // NSInvocation. - if (E->isInstanceMessage() && - E->getReceiverInterface() && - E->getReceiverInterface()->getName() == "NSInvocation") { - StringRef selName; - if (E->getSelector() == getReturnValueSel) - selName = "getReturnValue"; - else if (E->getSelector() == setReturnValueSel) - selName = "setReturnValue"; - else if (E->getSelector() == getArgumentSel) - selName = "getArgument"; - else if (E->getSelector() == setArgumentSel) - selName = "setArgument"; - else - return true; - - Expr *parm = E->getArg(0)->IgnoreParenCasts(); - QualType pointee = parm->getType()->getPointeeType(); - if (pointee.isNull()) - return true; - - if (pointee.getObjCLifetime() > Qualifiers::OCL_ExplicitNone) - Pass.TA.report(parm->getBeginLoc(), - diag::err_arcmt_nsinvocation_ownership, - parm->getSourceRange()) - << selName; - - return true; - } - - // -zone. - if (E->isInstanceMessage() && - E->getInstanceReceiver() && - E->getSelector() == zoneSel && - Pass.TA.hasDiagnostic(diag::err_unavailable, - diag::err_unavailable_message, - E->getSelectorLoc(0))) { - // Calling -zone is meaningless in ARC, change it to nil. - Transaction Trans(Pass.TA); - Pass.TA.clearDiagnostic(diag::err_unavailable, - diag::err_unavailable_message, - E->getSelectorLoc(0)); - Pass.TA.replace(E->getSourceRange(), getNilString(Pass)); - } - return true; - } -}; - -} // anonymous namespace - -void trans::checkAPIUses(MigrationPass &pass) { - APIChecker(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransARCAssign.cpp b/clang/lib/ARCMigrate/TransARCAssign.cpp deleted file mode 100644 index d1d5b9e014b17a..00000000000000 --- a/clang/lib/ARCMigrate/TransARCAssign.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//===--- TransARCAssign.cpp - Transformations to ARC mode -----------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// makeAssignARCSafe: -// -// Add '__strong' where appropriate. -// -// for (id x in collection) { -// x = 0; -// } -// ----> -// for (__strong id x in collection) { -// x = 0; -// } -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Sema/SemaDiagnostic.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class ARCAssignChecker : public RecursiveASTVisitor { - MigrationPass &Pass; - llvm::DenseSet ModifiedVars; - -public: - ARCAssignChecker(MigrationPass &pass) : Pass(pass) { } - - bool VisitBinaryOperator(BinaryOperator *Exp) { - if (Exp->getType()->isDependentType()) - return true; - - Expr *E = Exp->getLHS(); - SourceLocation OrigLoc = E->getExprLoc(); - SourceLocation Loc = OrigLoc; - DeclRefExpr *declRef = dyn_cast(E->IgnoreParenCasts()); - if (declRef && isa(declRef->getDecl())) { - ASTContext &Ctx = Pass.Ctx; - Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(Ctx, &Loc); - if (IsLV != Expr::MLV_ConstQualified) - return true; - VarDecl *var = cast(declRef->getDecl()); - if (var->isARCPseudoStrong()) { - Transaction Trans(Pass.TA); - if (Pass.TA.clearDiagnostic(diag::err_typecheck_arr_assign_enumeration, - Exp->getOperatorLoc())) { - if (!ModifiedVars.count(var)) { - TypeLoc TLoc = var->getTypeSourceInfo()->getTypeLoc(); - Pass.TA.insert(TLoc.getBeginLoc(), "__strong "); - ModifiedVars.insert(var); - } - } - } - } - - return true; - } -}; - -} // anonymous namespace - -void trans::makeAssignARCSafe(MigrationPass &pass) { - ARCAssignChecker assignCheck(pass); - assignCheck.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransAutoreleasePool.cpp b/clang/lib/ARCMigrate/TransAutoreleasePool.cpp deleted file mode 100644 index 6d501228e712b2..00000000000000 --- a/clang/lib/ARCMigrate/TransAutoreleasePool.cpp +++ /dev/null @@ -1,435 +0,0 @@ -//===--- TransAutoreleasePool.cpp - Transformations to ARC mode -----------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// rewriteAutoreleasePool: -// -// Calls to NSAutoreleasePools will be rewritten as an @autorelease scope. -// -// NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; -// ... -// [pool release]; -// ----> -// @autorelease { -// ... -// } -// -// An NSAutoreleasePool will not be touched if: -// - There is not a corresponding -release/-drain in the same scope -// - Not all references of the NSAutoreleasePool variable can be removed -// - There is a variable that is declared inside the intended @autorelease scope -// which is also used outside it. -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Sema/SemaDiagnostic.h" -#include - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class ReleaseCollector : public RecursiveASTVisitor { - Decl *Dcl; - SmallVectorImpl &Releases; - -public: - ReleaseCollector(Decl *D, SmallVectorImpl &releases) - : Dcl(D), Releases(releases) { } - - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - if (!E->isInstanceMessage()) - return true; - if (E->getMethodFamily() != OMF_release) - return true; - Expr *instance = E->getInstanceReceiver()->IgnoreParenCasts(); - if (DeclRefExpr *DE = dyn_cast(instance)) { - if (DE->getDecl() == Dcl) - Releases.push_back(E); - } - return true; - } -}; - -} - -namespace { - -class AutoreleasePoolRewriter - : public RecursiveASTVisitor { -public: - AutoreleasePoolRewriter(MigrationPass &pass) - : Body(nullptr), Pass(pass) { - PoolII = &pass.Ctx.Idents.get("NSAutoreleasePool"); - DrainSel = pass.Ctx.Selectors.getNullarySelector( - &pass.Ctx.Idents.get("drain")); - } - - void transformBody(Stmt *body, Decl *ParentD) { - Body = body; - TraverseStmt(body); - } - - ~AutoreleasePoolRewriter() { - SmallVector VarsToHandle; - - for (std::map::iterator - I = PoolVars.begin(), E = PoolVars.end(); I != E; ++I) { - VarDecl *var = I->first; - PoolVarInfo &info = I->second; - - // Check that we can handle/rewrite all references of the pool. - - clearRefsIn(info.Dcl, info.Refs); - for (SmallVectorImpl::iterator - scpI = info.Scopes.begin(), - scpE = info.Scopes.end(); scpI != scpE; ++scpI) { - PoolScope &scope = *scpI; - clearRefsIn(*scope.Begin, info.Refs); - clearRefsIn(*scope.End, info.Refs); - clearRefsIn(scope.Releases.begin(), scope.Releases.end(), info.Refs); - } - - // Even if one reference is not handled we will not do anything about that - // pool variable. - if (info.Refs.empty()) - VarsToHandle.push_back(var); - } - - for (unsigned i = 0, e = VarsToHandle.size(); i != e; ++i) { - PoolVarInfo &info = PoolVars[VarsToHandle[i]]; - - Transaction Trans(Pass.TA); - - clearUnavailableDiags(info.Dcl); - Pass.TA.removeStmt(info.Dcl); - - // Add "@autoreleasepool { }" - for (SmallVectorImpl::iterator - scpI = info.Scopes.begin(), - scpE = info.Scopes.end(); scpI != scpE; ++scpI) { - PoolScope &scope = *scpI; - clearUnavailableDiags(*scope.Begin); - clearUnavailableDiags(*scope.End); - if (scope.IsFollowedBySimpleReturnStmt) { - // Include the return in the scope. - Pass.TA.replaceStmt(*scope.Begin, "@autoreleasepool {"); - Pass.TA.removeStmt(*scope.End); - Stmt::child_iterator retI = scope.End; - ++retI; - SourceLocation afterSemi = - findLocationAfterSemi((*retI)->getEndLoc(), Pass.Ctx); - assert(afterSemi.isValid() && - "Didn't we check before setting IsFollowedBySimpleReturnStmt " - "to true?"); - Pass.TA.insertAfterToken(afterSemi, "\n}"); - Pass.TA.increaseIndentation( - SourceRange(scope.getIndentedRange().getBegin(), - (*retI)->getEndLoc()), - scope.CompoundParent->getBeginLoc()); - } else { - Pass.TA.replaceStmt(*scope.Begin, "@autoreleasepool {"); - Pass.TA.replaceStmt(*scope.End, "}"); - Pass.TA.increaseIndentation(scope.getIndentedRange(), - scope.CompoundParent->getBeginLoc()); - } - } - - // Remove rest of pool var references. - for (SmallVectorImpl::iterator - scpI = info.Scopes.begin(), - scpE = info.Scopes.end(); scpI != scpE; ++scpI) { - PoolScope &scope = *scpI; - for (SmallVectorImpl::iterator - relI = scope.Releases.begin(), - relE = scope.Releases.end(); relI != relE; ++relI) { - clearUnavailableDiags(*relI); - Pass.TA.removeStmt(*relI); - } - } - } - } - - bool VisitCompoundStmt(CompoundStmt *S) { - SmallVector Scopes; - - for (Stmt::child_iterator - I = S->body_begin(), E = S->body_end(); I != E; ++I) { - Stmt *child = getEssential(*I); - if (DeclStmt *DclS = dyn_cast(child)) { - if (DclS->isSingleDecl()) { - if (VarDecl *VD = dyn_cast(DclS->getSingleDecl())) { - if (isNSAutoreleasePool(VD->getType())) { - PoolVarInfo &info = PoolVars[VD]; - info.Dcl = DclS; - collectRefs(VD, S, info.Refs); - // Does this statement follow the pattern: - // NSAutoreleasePool * pool = [NSAutoreleasePool new]; - if (isPoolCreation(VD->getInit())) { - Scopes.push_back(PoolScope()); - Scopes.back().PoolVar = VD; - Scopes.back().CompoundParent = S; - Scopes.back().Begin = I; - } - } - } - } - } else if (BinaryOperator *bop = dyn_cast(child)) { - if (DeclRefExpr *dref = dyn_cast(bop->getLHS())) { - if (VarDecl *VD = dyn_cast(dref->getDecl())) { - // Does this statement follow the pattern: - // pool = [NSAutoreleasePool new]; - if (isNSAutoreleasePool(VD->getType()) && - isPoolCreation(bop->getRHS())) { - Scopes.push_back(PoolScope()); - Scopes.back().PoolVar = VD; - Scopes.back().CompoundParent = S; - Scopes.back().Begin = I; - } - } - } - } - - if (Scopes.empty()) - continue; - - if (isPoolDrain(Scopes.back().PoolVar, child)) { - PoolScope &scope = Scopes.back(); - scope.End = I; - handlePoolScope(scope, S); - Scopes.pop_back(); - } - } - return true; - } - -private: - void clearUnavailableDiags(Stmt *S) { - if (S) - Pass.TA.clearDiagnostic(diag::err_unavailable, - diag::err_unavailable_message, - S->getSourceRange()); - } - - struct PoolScope { - VarDecl *PoolVar; - CompoundStmt *CompoundParent; - Stmt::child_iterator Begin; - Stmt::child_iterator End; - bool IsFollowedBySimpleReturnStmt; - SmallVector Releases; - - PoolScope() - : PoolVar(nullptr), CompoundParent(nullptr), - IsFollowedBySimpleReturnStmt(false) {} - - SourceRange getIndentedRange() const { - Stmt::child_iterator rangeS = Begin; - ++rangeS; - if (rangeS == End) - return SourceRange(); - Stmt::child_iterator rangeE = Begin; - for (Stmt::child_iterator I = rangeS; I != End; ++I) - ++rangeE; - return SourceRange((*rangeS)->getBeginLoc(), (*rangeE)->getEndLoc()); - } - }; - - class NameReferenceChecker : public RecursiveASTVisitor{ - ASTContext &Ctx; - SourceRange ScopeRange; - SourceLocation &referenceLoc, &declarationLoc; - - public: - NameReferenceChecker(ASTContext &ctx, PoolScope &scope, - SourceLocation &referenceLoc, - SourceLocation &declarationLoc) - : Ctx(ctx), referenceLoc(referenceLoc), - declarationLoc(declarationLoc) { - ScopeRange = SourceRange((*scope.Begin)->getBeginLoc(), - (*scope.End)->getBeginLoc()); - } - - bool VisitDeclRefExpr(DeclRefExpr *E) { - return checkRef(E->getLocation(), E->getDecl()->getLocation()); - } - - bool VisitTypedefTypeLoc(TypedefTypeLoc TL) { - return checkRef(TL.getBeginLoc(), TL.getTypedefNameDecl()->getLocation()); - } - - bool VisitTagTypeLoc(TagTypeLoc TL) { - return checkRef(TL.getBeginLoc(), TL.getDecl()->getLocation()); - } - - private: - bool checkRef(SourceLocation refLoc, SourceLocation declLoc) { - if (isInScope(declLoc)) { - referenceLoc = refLoc; - declarationLoc = declLoc; - return false; - } - return true; - } - - bool isInScope(SourceLocation loc) { - if (loc.isInvalid()) - return false; - - SourceManager &SM = Ctx.getSourceManager(); - if (SM.isBeforeInTranslationUnit(loc, ScopeRange.getBegin())) - return false; - return SM.isBeforeInTranslationUnit(loc, ScopeRange.getEnd()); - } - }; - - void handlePoolScope(PoolScope &scope, CompoundStmt *compoundS) { - // Check that all names declared inside the scope are not used - // outside the scope. - { - bool nameUsedOutsideScope = false; - SourceLocation referenceLoc, declarationLoc; - Stmt::child_iterator SI = scope.End, SE = compoundS->body_end(); - ++SI; - // Check if the autoreleasepool scope is followed by a simple return - // statement, in which case we will include the return in the scope. - if (SI != SE) - if (ReturnStmt *retS = dyn_cast(*SI)) - if ((retS->getRetValue() == nullptr || - isa(retS->getRetValue()->IgnoreParenCasts())) && - findLocationAfterSemi(retS->getEndLoc(), Pass.Ctx).isValid()) { - scope.IsFollowedBySimpleReturnStmt = true; - ++SI; // the return will be included in scope, don't check it. - } - - for (; SI != SE; ++SI) { - nameUsedOutsideScope = !NameReferenceChecker(Pass.Ctx, scope, - referenceLoc, - declarationLoc).TraverseStmt(*SI); - if (nameUsedOutsideScope) - break; - } - - // If not all references were cleared it means some variables/typenames/etc - // declared inside the pool scope are used outside of it. - // We won't try to rewrite the pool. - if (nameUsedOutsideScope) { - Pass.TA.reportError("a name is referenced outside the " - "NSAutoreleasePool scope that it was declared in", referenceLoc); - Pass.TA.reportNote("name declared here", declarationLoc); - Pass.TA.reportNote("intended @autoreleasepool scope begins here", - (*scope.Begin)->getBeginLoc()); - Pass.TA.reportNote("intended @autoreleasepool scope ends here", - (*scope.End)->getBeginLoc()); - return; - } - } - - // Collect all releases of the pool; they will be removed. - { - ReleaseCollector releaseColl(scope.PoolVar, scope.Releases); - Stmt::child_iterator I = scope.Begin; - ++I; - for (; I != scope.End; ++I) - releaseColl.TraverseStmt(*I); - } - - PoolVars[scope.PoolVar].Scopes.push_back(scope); - } - - bool isPoolCreation(Expr *E) { - if (!E) return false; - E = getEssential(E); - ObjCMessageExpr *ME = dyn_cast(E); - if (!ME) return false; - if (ME->getMethodFamily() == OMF_new && - ME->getReceiverKind() == ObjCMessageExpr::Class && - isNSAutoreleasePool(ME->getReceiverInterface())) - return true; - if (ME->getReceiverKind() == ObjCMessageExpr::Instance && - ME->getMethodFamily() == OMF_init) { - Expr *rec = getEssential(ME->getInstanceReceiver()); - if (ObjCMessageExpr *recME = dyn_cast_or_null(rec)) { - if (recME->getMethodFamily() == OMF_alloc && - recME->getReceiverKind() == ObjCMessageExpr::Class && - isNSAutoreleasePool(recME->getReceiverInterface())) - return true; - } - } - - return false; - } - - bool isPoolDrain(VarDecl *poolVar, Stmt *S) { - if (!S) return false; - S = getEssential(S); - ObjCMessageExpr *ME = dyn_cast(S); - if (!ME) return false; - if (ME->getReceiverKind() == ObjCMessageExpr::Instance) { - Expr *rec = getEssential(ME->getInstanceReceiver()); - if (DeclRefExpr *dref = dyn_cast(rec)) - if (dref->getDecl() == poolVar) - return ME->getMethodFamily() == OMF_release || - ME->getSelector() == DrainSel; - } - - return false; - } - - bool isNSAutoreleasePool(ObjCInterfaceDecl *IDecl) { - return IDecl && IDecl->getIdentifier() == PoolII; - } - - bool isNSAutoreleasePool(QualType Ty) { - QualType pointee = Ty->getPointeeType(); - if (pointee.isNull()) - return false; - if (const ObjCInterfaceType *interT = pointee->getAs()) - return isNSAutoreleasePool(interT->getDecl()); - return false; - } - - static Expr *getEssential(Expr *E) { - return cast(getEssential((Stmt*)E)); - } - static Stmt *getEssential(Stmt *S) { - if (FullExpr *FE = dyn_cast(S)) - S = FE->getSubExpr(); - if (Expr *E = dyn_cast(S)) - S = E->IgnoreParenCasts(); - return S; - } - - Stmt *Body; - MigrationPass &Pass; - - IdentifierInfo *PoolII; - Selector DrainSel; - - struct PoolVarInfo { - DeclStmt *Dcl = nullptr; - ExprSet Refs; - SmallVector Scopes; - - PoolVarInfo() = default; - }; - - std::map PoolVars; -}; - -} // anonymous namespace - -void trans::rewriteAutoreleasePool(MigrationPass &pass) { - BodyTransform trans(pass); - trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp b/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp deleted file mode 100644 index 1e4db33135b6a1..00000000000000 --- a/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp +++ /dev/null @@ -1,146 +0,0 @@ -//===--- TransBlockObjCVariable.cpp - Transformations to ARC mode ---------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// rewriteBlockObjCVariable: -// -// Adding __block to an obj-c variable could be either because the variable -// is used for output storage or the user wanted to break a retain cycle. -// This transformation checks whether a reference of the variable for the block -// is actually needed (it is assigned to or its address is taken) or not. -// If the reference is not needed it will assume __block was added to break a -// cycle so it will remove '__block' and add __weak/__unsafe_unretained. -// e.g -// -// __block Foo *x; -// bar(^ { [x cake]; }); -// ----> -// __weak Foo *x; -// bar(^ { [x cake]; }); -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Attr.h" -#include "clang/Basic/SourceManager.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class RootBlockObjCVarRewriter : - public RecursiveASTVisitor { - llvm::DenseSet &VarsToChange; - - class BlockVarChecker : public RecursiveASTVisitor { - VarDecl *Var; - - typedef RecursiveASTVisitor base; - public: - BlockVarChecker(VarDecl *var) : Var(var) { } - - bool TraverseImplicitCastExpr(ImplicitCastExpr *castE) { - if (DeclRefExpr * - ref = dyn_cast(castE->getSubExpr())) { - if (ref->getDecl() == Var) { - if (castE->getCastKind() == CK_LValueToRValue) - return true; // Using the value of the variable. - if (castE->getCastKind() == CK_NoOp && castE->isLValue() && - Var->getASTContext().getLangOpts().CPlusPlus) - return true; // Binding to const C++ reference. - } - } - - return base::TraverseImplicitCastExpr(castE); - } - - bool VisitDeclRefExpr(DeclRefExpr *E) { - if (E->getDecl() == Var) - return false; // The reference of the variable, and not just its value, - // is needed. - return true; - } - }; - -public: - RootBlockObjCVarRewriter(llvm::DenseSet &VarsToChange) - : VarsToChange(VarsToChange) { } - - bool VisitBlockDecl(BlockDecl *block) { - SmallVector BlockVars; - - for (const auto &I : block->captures()) { - VarDecl *var = I.getVariable(); - if (I.isByRef() && - var->getType()->isObjCObjectPointerType() && - isImplicitStrong(var->getType())) { - BlockVars.push_back(var); - } - } - - for (unsigned i = 0, e = BlockVars.size(); i != e; ++i) { - VarDecl *var = BlockVars[i]; - - BlockVarChecker checker(var); - bool onlyValueOfVarIsNeeded = checker.TraverseStmt(block->getBody()); - if (onlyValueOfVarIsNeeded) - VarsToChange.insert(var); - else - VarsToChange.erase(var); - } - - return true; - } - -private: - bool isImplicitStrong(QualType ty) { - if (isa(ty.getTypePtr())) - return false; - return ty.getLocalQualifiers().getObjCLifetime() == Qualifiers::OCL_Strong; - } -}; - -class BlockObjCVarRewriter : public RecursiveASTVisitor { - llvm::DenseSet &VarsToChange; - -public: - BlockObjCVarRewriter(llvm::DenseSet &VarsToChange) - : VarsToChange(VarsToChange) { } - - bool TraverseBlockDecl(BlockDecl *block) { - RootBlockObjCVarRewriter(VarsToChange).TraverseDecl(block); - return true; - } -}; - -} // anonymous namespace - -void BlockObjCVariableTraverser::traverseBody(BodyContext &BodyCtx) { - MigrationPass &Pass = BodyCtx.getMigrationContext().Pass; - llvm::DenseSet VarsToChange; - - BlockObjCVarRewriter trans(VarsToChange); - trans.TraverseStmt(BodyCtx.getTopStmt()); - - for (llvm::DenseSet::iterator - I = VarsToChange.begin(), E = VarsToChange.end(); I != E; ++I) { - VarDecl *var = *I; - BlocksAttr *attr = var->getAttr(); - if(!attr) - continue; - bool useWeak = canApplyWeak(Pass.Ctx, var->getType()); - SourceManager &SM = Pass.Ctx.getSourceManager(); - Transaction Trans(Pass.TA); - Pass.TA.replaceText(SM.getExpansionLoc(attr->getLocation()), - "__block", - useWeak ? "__weak" : "__unsafe_unretained"); - } -} diff --git a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp deleted file mode 100644 index e9c21b8106d7dd..00000000000000 --- a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp +++ /dev/null @@ -1,249 +0,0 @@ -//===-- TransEmptyStatementsAndDealloc.cpp - Transformations to ARC mode --===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// removeEmptyStatementsAndDealloc: -// -// Removes empty statements that are leftovers from previous transformations. -// e.g for -// -// [x retain]; -// -// removeRetainReleaseDealloc will leave an empty ";" that removeEmptyStatements -// will remove. -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/StmtVisitor.h" -#include "clang/Basic/SourceManager.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -static bool isEmptyARCMTMacroStatement(NullStmt *S, - std::vector &MacroLocs, - ASTContext &Ctx) { - if (!S->hasLeadingEmptyMacro()) - return false; - - SourceLocation SemiLoc = S->getSemiLoc(); - if (SemiLoc.isInvalid() || SemiLoc.isMacroID()) - return false; - - if (MacroLocs.empty()) - return false; - - SourceManager &SM = Ctx.getSourceManager(); - std::vector::iterator I = llvm::upper_bound( - MacroLocs, SemiLoc, BeforeThanCompare(SM)); - --I; - SourceLocation - AfterMacroLoc = I->getLocWithOffset(getARCMTMacroName().size()); - assert(AfterMacroLoc.isFileID()); - - if (AfterMacroLoc == SemiLoc) - return true; - - SourceLocation::IntTy RelOffs = 0; - if (!SM.isInSameSLocAddrSpace(AfterMacroLoc, SemiLoc, &RelOffs)) - return false; - if (RelOffs < 0) - return false; - - // We make the reasonable assumption that a semicolon after 100 characters - // means that it is not the next token after our macro. If this assumption - // fails it is not critical, we will just fail to clear out, e.g., an empty - // 'if'. - if (RelOffs - getARCMTMacroName().size() > 100) - return false; - - SourceLocation AfterMacroSemiLoc = findSemiAfterLocation(AfterMacroLoc, Ctx); - return AfterMacroSemiLoc == SemiLoc; -} - -namespace { - -/// Returns true if the statement became empty due to previous -/// transformations. -class EmptyChecker : public StmtVisitor { - ASTContext &Ctx; - std::vector &MacroLocs; - -public: - EmptyChecker(ASTContext &ctx, std::vector ¯oLocs) - : Ctx(ctx), MacroLocs(macroLocs) { } - - bool VisitNullStmt(NullStmt *S) { - return isEmptyARCMTMacroStatement(S, MacroLocs, Ctx); - } - bool VisitCompoundStmt(CompoundStmt *S) { - if (S->body_empty()) - return false; // was already empty, not because of transformations. - for (auto *I : S->body()) - if (!Visit(I)) - return false; - return true; - } - bool VisitIfStmt(IfStmt *S) { - if (S->getConditionVariable()) - return false; - Expr *condE = S->getCond(); - if (!condE) - return false; - if (hasSideEffects(condE, Ctx)) - return false; - if (!S->getThen() || !Visit(S->getThen())) - return false; - return !S->getElse() || Visit(S->getElse()); - } - bool VisitWhileStmt(WhileStmt *S) { - if (S->getConditionVariable()) - return false; - Expr *condE = S->getCond(); - if (!condE) - return false; - if (hasSideEffects(condE, Ctx)) - return false; - if (!S->getBody()) - return false; - return Visit(S->getBody()); - } - bool VisitDoStmt(DoStmt *S) { - Expr *condE = S->getCond(); - if (!condE) - return false; - if (hasSideEffects(condE, Ctx)) - return false; - if (!S->getBody()) - return false; - return Visit(S->getBody()); - } - bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { - Expr *Exp = S->getCollection(); - if (!Exp) - return false; - if (hasSideEffects(Exp, Ctx)) - return false; - if (!S->getBody()) - return false; - return Visit(S->getBody()); - } - bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { - if (!S->getSubStmt()) - return false; - return Visit(S->getSubStmt()); - } -}; - -class EmptyStatementsRemover : - public RecursiveASTVisitor { - MigrationPass &Pass; - -public: - EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) { } - - bool TraverseStmtExpr(StmtExpr *E) { - CompoundStmt *S = E->getSubStmt(); - for (CompoundStmt::body_iterator - I = S->body_begin(), E = S->body_end(); I != E; ++I) { - if (I != E - 1) - check(*I); - TraverseStmt(*I); - } - return true; - } - - bool VisitCompoundStmt(CompoundStmt *S) { - for (auto *I : S->body()) - check(I); - return true; - } - - ASTContext &getContext() { return Pass.Ctx; } - -private: - void check(Stmt *S) { - if (!S) return; - if (EmptyChecker(Pass.Ctx, Pass.ARCMTMacroLocs).Visit(S)) { - Transaction Trans(Pass.TA); - Pass.TA.removeStmt(S); - } - } -}; - -} // anonymous namespace - -static bool isBodyEmpty(CompoundStmt *body, ASTContext &Ctx, - std::vector &MacroLocs) { - for (auto *I : body->body()) - if (!EmptyChecker(Ctx, MacroLocs).Visit(I)) - return false; - - return true; -} - -static void cleanupDeallocOrFinalize(MigrationPass &pass) { - ASTContext &Ctx = pass.Ctx; - TransformActions &TA = pass.TA; - DeclContext *DC = Ctx.getTranslationUnitDecl(); - Selector FinalizeSel = - Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); - - typedef DeclContext::specific_decl_iterator - impl_iterator; - for (impl_iterator I = impl_iterator(DC->decls_begin()), - E = impl_iterator(DC->decls_end()); I != E; ++I) { - ObjCMethodDecl *DeallocM = nullptr; - ObjCMethodDecl *FinalizeM = nullptr; - for (auto *MD : I->instance_methods()) { - if (!MD->hasBody()) - continue; - - if (MD->getMethodFamily() == OMF_dealloc) { - DeallocM = MD; - } else if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { - FinalizeM = MD; - } - } - - if (DeallocM) { - if (isBodyEmpty(DeallocM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { - Transaction Trans(TA); - TA.remove(DeallocM->getSourceRange()); - } - - if (FinalizeM) { - Transaction Trans(TA); - TA.remove(FinalizeM->getSourceRange()); - } - - } else if (FinalizeM) { - if (isBodyEmpty(FinalizeM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { - Transaction Trans(TA); - TA.remove(FinalizeM->getSourceRange()); - } else { - Transaction Trans(TA); - TA.replaceText(FinalizeM->getSelectorStartLoc(), "finalize", "dealloc"); - } - } - } -} - -void trans::removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass) { - EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl()); - - cleanupDeallocOrFinalize(pass); - - for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) { - Transaction Trans(pass.TA); - pass.TA.remove(pass.ARCMTMacroLocs[i]); - } -} diff --git a/clang/lib/ARCMigrate/TransGCAttrs.cpp b/clang/lib/ARCMigrate/TransGCAttrs.cpp deleted file mode 100644 index 85e3fe77660b5c..00000000000000 --- a/clang/lib/ARCMigrate/TransGCAttrs.cpp +++ /dev/null @@ -1,350 +0,0 @@ -//===--- TransGCAttrs.cpp - Transformations to ARC mode -------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/TinyPtrVector.h" -#include "llvm/Support/SaveAndRestore.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -/// Collects all the places where GC attributes __strong/__weak occur. -class GCAttrsCollector : public RecursiveASTVisitor { - MigrationContext &MigrateCtx; - bool FullyMigratable; - std::vector &AllProps; - - typedef RecursiveASTVisitor base; -public: - GCAttrsCollector(MigrationContext &ctx, - std::vector &AllProps) - : MigrateCtx(ctx), FullyMigratable(false), - AllProps(AllProps) { } - - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool VisitAttributedTypeLoc(AttributedTypeLoc TL) { - handleAttr(TL); - return true; - } - - bool TraverseDecl(Decl *D) { - if (!D || D->isImplicit()) - return true; - - SaveAndRestore Save(FullyMigratable, isMigratable(D)); - - if (ObjCPropertyDecl *PropD = dyn_cast(D)) { - lookForAttribute(PropD, PropD->getTypeSourceInfo()); - AllProps.push_back(PropD); - } else if (DeclaratorDecl *DD = dyn_cast(D)) { - lookForAttribute(DD, DD->getTypeSourceInfo()); - } - return base::TraverseDecl(D); - } - - void lookForAttribute(Decl *D, TypeSourceInfo *TInfo) { - if (!TInfo) - return; - TypeLoc TL = TInfo->getTypeLoc(); - while (TL) { - if (QualifiedTypeLoc QL = TL.getAs()) { - TL = QL.getUnqualifiedLoc(); - } else if (AttributedTypeLoc Attr = TL.getAs()) { - if (handleAttr(Attr, D)) - break; - TL = Attr.getModifiedLoc(); - } else if (MacroQualifiedTypeLoc MDTL = - TL.getAs()) { - TL = MDTL.getInnerLoc(); - } else if (ArrayTypeLoc Arr = TL.getAs()) { - TL = Arr.getElementLoc(); - } else if (PointerTypeLoc PT = TL.getAs()) { - TL = PT.getPointeeLoc(); - } else if (ReferenceTypeLoc RT = TL.getAs()) - TL = RT.getPointeeLoc(); - else - break; - } - } - - bool handleAttr(AttributedTypeLoc TL, Decl *D = nullptr) { - auto *OwnershipAttr = TL.getAttrAs(); - if (!OwnershipAttr) - return false; - - SourceLocation Loc = OwnershipAttr->getLocation(); - SourceLocation OrigLoc = Loc; - if (MigrateCtx.AttrSet.count(OrigLoc)) - return true; - - ASTContext &Ctx = MigrateCtx.Pass.Ctx; - SourceManager &SM = Ctx.getSourceManager(); - if (Loc.isMacroID()) - Loc = SM.getImmediateExpansionRange(Loc).getBegin(); - StringRef Spell = OwnershipAttr->getKind()->getName(); - MigrationContext::GCAttrOccurrence::AttrKind Kind; - if (Spell == "strong") - Kind = MigrationContext::GCAttrOccurrence::Strong; - else if (Spell == "weak") - Kind = MigrationContext::GCAttrOccurrence::Weak; - else - return false; - - MigrateCtx.AttrSet.insert(OrigLoc); - MigrateCtx.GCAttrs.push_back(MigrationContext::GCAttrOccurrence()); - MigrationContext::GCAttrOccurrence &Attr = MigrateCtx.GCAttrs.back(); - - Attr.Kind = Kind; - Attr.Loc = Loc; - Attr.ModifiedType = TL.getModifiedLoc().getType(); - Attr.Dcl = D; - Attr.FullyMigratable = FullyMigratable; - return true; - } - - bool isMigratable(Decl *D) { - if (isa(D)) - return false; - - if (isInMainFile(D)) - return true; - - if (FunctionDecl *FD = dyn_cast(D)) - return FD->hasBody(); - - if (ObjCContainerDecl *ContD = dyn_cast(D)) - return hasObjCImpl(ContD); - - if (CXXRecordDecl *RD = dyn_cast(D)) { - for (const auto *MI : RD->methods()) { - if (MI->isOutOfLine()) - return true; - } - return false; - } - - return isMigratable(cast(D->getDeclContext())); - } - - static bool hasObjCImpl(Decl *D) { - if (!D) - return false; - if (ObjCContainerDecl *ContD = dyn_cast(D)) { - if (ObjCInterfaceDecl *ID = dyn_cast(ContD)) - return ID->getImplementation() != nullptr; - if (ObjCCategoryDecl *CD = dyn_cast(ContD)) - return CD->getImplementation() != nullptr; - return isa(ContD); - } - return false; - } - - bool isInMainFile(Decl *D) { - if (!D) - return false; - - for (auto *I : D->redecls()) - if (!isInMainFile(I->getLocation())) - return false; - - return true; - } - - bool isInMainFile(SourceLocation Loc) { - if (Loc.isInvalid()) - return false; - - SourceManager &SM = MigrateCtx.Pass.Ctx.getSourceManager(); - return SM.isInFileID(SM.getExpansionLoc(Loc), SM.getMainFileID()); - } -}; - -} // anonymous namespace - -static void errorForGCAttrsOnNonObjC(MigrationContext &MigrateCtx) { - TransformActions &TA = MigrateCtx.Pass.TA; - - for (unsigned i = 0, e = MigrateCtx.GCAttrs.size(); i != e; ++i) { - MigrationContext::GCAttrOccurrence &Attr = MigrateCtx.GCAttrs[i]; - if (Attr.FullyMigratable && Attr.Dcl) { - if (Attr.ModifiedType.isNull()) - continue; - if (!Attr.ModifiedType->isObjCRetainableType()) { - TA.reportError("GC managed memory will become unmanaged in ARC", - Attr.Loc); - } - } - } -} - -static void checkWeakGCAttrs(MigrationContext &MigrateCtx) { - TransformActions &TA = MigrateCtx.Pass.TA; - - for (unsigned i = 0, e = MigrateCtx.GCAttrs.size(); i != e; ++i) { - MigrationContext::GCAttrOccurrence &Attr = MigrateCtx.GCAttrs[i]; - if (Attr.Kind == MigrationContext::GCAttrOccurrence::Weak) { - if (Attr.ModifiedType.isNull() || - !Attr.ModifiedType->isObjCRetainableType()) - continue; - if (!canApplyWeak(MigrateCtx.Pass.Ctx, Attr.ModifiedType, - /*AllowOnUnknownClass=*/true)) { - Transaction Trans(TA); - if (!MigrateCtx.RemovedAttrSet.count(Attr.Loc)) - TA.replaceText(Attr.Loc, "__weak", "__unsafe_unretained"); - TA.clearDiagnostic(diag::err_arc_weak_no_runtime, - diag::err_arc_unsupported_weak_class, - Attr.Loc); - } - } - } -} - -typedef llvm::TinyPtrVector IndivPropsTy; - -static void checkAllAtProps(MigrationContext &MigrateCtx, - SourceLocation AtLoc, - IndivPropsTy &IndProps) { - if (IndProps.empty()) - return; - - for (IndivPropsTy::iterator - PI = IndProps.begin(), PE = IndProps.end(); PI != PE; ++PI) { - QualType T = (*PI)->getType(); - if (T.isNull() || !T->isObjCRetainableType()) - return; - } - - SmallVector, 4> ATLs; - bool hasWeak = false, hasStrong = false; - ObjCPropertyAttribute::Kind Attrs = ObjCPropertyAttribute::kind_noattr; - for (IndivPropsTy::iterator - PI = IndProps.begin(), PE = IndProps.end(); PI != PE; ++PI) { - ObjCPropertyDecl *PD = *PI; - Attrs = PD->getPropertyAttributesAsWritten(); - TypeSourceInfo *TInfo = PD->getTypeSourceInfo(); - if (!TInfo) - return; - TypeLoc TL = TInfo->getTypeLoc(); - if (AttributedTypeLoc ATL = - TL.getAs()) { - ATLs.push_back(std::make_pair(ATL, PD)); - if (TInfo->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { - hasWeak = true; - } else if (TInfo->getType().getObjCLifetime() == Qualifiers::OCL_Strong) - hasStrong = true; - else - return; - } - } - if (ATLs.empty()) - return; - if (hasWeak && hasStrong) - return; - - TransformActions &TA = MigrateCtx.Pass.TA; - Transaction Trans(TA); - - if (GCAttrsCollector::hasObjCImpl( - cast(IndProps.front()->getDeclContext()))) { - if (hasWeak) - MigrateCtx.AtPropsWeak.insert(AtLoc); - - } else { - StringRef toAttr = "strong"; - if (hasWeak) { - if (canApplyWeak(MigrateCtx.Pass.Ctx, IndProps.front()->getType(), - /*AllowOnUnknownClass=*/true)) - toAttr = "weak"; - else - toAttr = "unsafe_unretained"; - } - if (Attrs & ObjCPropertyAttribute::kind_assign) - MigrateCtx.rewritePropertyAttribute("assign", toAttr, AtLoc); - else - MigrateCtx.addPropertyAttribute(toAttr, AtLoc); - } - - for (unsigned i = 0, e = ATLs.size(); i != e; ++i) { - SourceLocation Loc = ATLs[i].first.getAttr()->getLocation(); - if (Loc.isMacroID()) - Loc = MigrateCtx.Pass.Ctx.getSourceManager() - .getImmediateExpansionRange(Loc) - .getBegin(); - TA.remove(Loc); - TA.clearDiagnostic(diag::err_objc_property_attr_mutually_exclusive, AtLoc); - TA.clearDiagnostic(diag::err_arc_inconsistent_property_ownership, - ATLs[i].second->getLocation()); - MigrateCtx.RemovedAttrSet.insert(Loc); - } -} - -static void checkAllProps(MigrationContext &MigrateCtx, - std::vector &AllProps) { - typedef llvm::TinyPtrVector IndivPropsTy; - llvm::DenseMap AtProps; - - for (unsigned i = 0, e = AllProps.size(); i != e; ++i) { - ObjCPropertyDecl *PD = AllProps[i]; - if (PD->getPropertyAttributesAsWritten() & - (ObjCPropertyAttribute::kind_assign | - ObjCPropertyAttribute::kind_readonly)) { - SourceLocation AtLoc = PD->getAtLoc(); - if (AtLoc.isInvalid()) - continue; - AtProps[AtLoc].push_back(PD); - } - } - - for (auto I = AtProps.begin(), E = AtProps.end(); I != E; ++I) { - SourceLocation AtLoc = I->first; - IndivPropsTy &IndProps = I->second; - checkAllAtProps(MigrateCtx, AtLoc, IndProps); - } -} - -void GCAttrsTraverser::traverseTU(MigrationContext &MigrateCtx) { - std::vector AllProps; - GCAttrsCollector(MigrateCtx, AllProps).TraverseDecl( - MigrateCtx.Pass.Ctx.getTranslationUnitDecl()); - - errorForGCAttrsOnNonObjC(MigrateCtx); - checkAllProps(MigrateCtx, AllProps); - checkWeakGCAttrs(MigrateCtx); -} - -void MigrationContext::dumpGCAttrs() { - llvm::errs() << "\n################\n"; - for (unsigned i = 0, e = GCAttrs.size(); i != e; ++i) { - GCAttrOccurrence &Attr = GCAttrs[i]; - llvm::errs() << "KIND: " - << (Attr.Kind == GCAttrOccurrence::Strong ? "strong" : "weak"); - llvm::errs() << "\nLOC: "; - Attr.Loc.print(llvm::errs(), Pass.Ctx.getSourceManager()); - llvm::errs() << "\nTYPE: "; - Attr.ModifiedType.dump(); - if (Attr.Dcl) { - llvm::errs() << "DECL:\n"; - Attr.Dcl->dump(); - } else { - llvm::errs() << "DECL: NONE"; - } - llvm::errs() << "\nMIGRATABLE: " << Attr.FullyMigratable; - llvm::errs() << "\n----------------\n"; - } - llvm::errs() << "\n################\n"; -} diff --git a/clang/lib/ARCMigrate/TransGCCalls.cpp b/clang/lib/ARCMigrate/TransGCCalls.cpp deleted file mode 100644 index 43233e2d0b456a..00000000000000 --- a/clang/lib/ARCMigrate/TransGCCalls.cpp +++ /dev/null @@ -1,76 +0,0 @@ -//===--- TransGCCalls.cpp - Transformations to ARC mode -------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Sema/SemaDiagnostic.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class GCCollectableCallsChecker : - public RecursiveASTVisitor { - MigrationContext &MigrateCtx; - IdentifierInfo *NSMakeCollectableII; - IdentifierInfo *CFMakeCollectableII; - -public: - GCCollectableCallsChecker(MigrationContext &ctx) - : MigrateCtx(ctx) { - IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents; - NSMakeCollectableII = &Ids.get("NSMakeCollectable"); - CFMakeCollectableII = &Ids.get("CFMakeCollectable"); - } - - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool VisitCallExpr(CallExpr *E) { - TransformActions &TA = MigrateCtx.Pass.TA; - - if (MigrateCtx.isGCOwnedNonObjC(E->getType())) { - TA.report(E->getBeginLoc(), diag::warn_arcmt_nsalloc_realloc, - E->getSourceRange()); - return true; - } - - Expr *CEE = E->getCallee()->IgnoreParenImpCasts(); - if (DeclRefExpr *DRE = dyn_cast(CEE)) { - if (FunctionDecl *FD = dyn_cast_or_null(DRE->getDecl())) { - if (!FD->getDeclContext()->getRedeclContext()->isFileContext()) - return true; - - if (FD->getIdentifier() == NSMakeCollectableII) { - Transaction Trans(TA); - TA.clearDiagnostic(diag::err_unavailable, - diag::err_unavailable_message, - diag::err_ovl_deleted_call, // ObjC++ - DRE->getSourceRange()); - TA.replace(DRE->getSourceRange(), "CFBridgingRelease"); - - } else if (FD->getIdentifier() == CFMakeCollectableII) { - TA.reportError("CFMakeCollectable will leak the object that it " - "receives in ARC", DRE->getLocation(), - DRE->getSourceRange()); - } - } - } - - return true; - } -}; - -} // anonymous namespace - -void GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) { - GCCollectableCallsChecker(BodyCtx.getMigrationContext()) - .TraverseStmt(BodyCtx.getTopStmt()); -} diff --git a/clang/lib/ARCMigrate/TransProperties.cpp b/clang/lib/ARCMigrate/TransProperties.cpp deleted file mode 100644 index 6d1d950821a07c..00000000000000 --- a/clang/lib/ARCMigrate/TransProperties.cpp +++ /dev/null @@ -1,379 +0,0 @@ -//===--- TransProperties.cpp - Transformations to ARC mode ----------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// rewriteProperties: -// -// - Adds strong/weak/unsafe_unretained ownership specifier to properties that -// are missing one. -// - Migrates properties from (retain) to (strong) and (assign) to -// (unsafe_unretained/weak). -// - If a property is synthesized, adds the ownership specifier in the ivar -// backing the property. -// -// @interface Foo : NSObject { -// NSObject *x; -// } -// @property (assign) id x; -// @end -// ----> -// @interface Foo : NSObject { -// NSObject *__weak x; -// } -// @property (weak) id x; -// @end -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" -#include "clang/Sema/SemaDiagnostic.h" -#include - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class PropertiesRewriter { - MigrationContext &MigrateCtx; - MigrationPass &Pass; - ObjCImplementationDecl *CurImplD = nullptr; - - enum PropActionKind { - PropAction_None, - PropAction_RetainReplacedWithStrong, - PropAction_AssignRemoved, - PropAction_AssignRewritten, - PropAction_MaybeAddWeakOrUnsafe - }; - - struct PropData { - ObjCPropertyDecl *PropD; - ObjCIvarDecl *IvarD; - ObjCPropertyImplDecl *ImplD; - - PropData(ObjCPropertyDecl *propD) - : PropD(propD), IvarD(nullptr), ImplD(nullptr) {} - }; - - typedef SmallVector PropsTy; - typedef std::map AtPropDeclsTy; - AtPropDeclsTy AtProps; - llvm::DenseMap ActionOnProp; - -public: - explicit PropertiesRewriter(MigrationContext &MigrateCtx) - : MigrateCtx(MigrateCtx), Pass(MigrateCtx.Pass) { } - - static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps, - AtPropDeclsTy *PrevAtProps = nullptr) { - for (auto *Prop : D->instance_properties()) { - SourceLocation Loc = Prop->getAtLoc(); - if (Loc.isInvalid()) - continue; - if (PrevAtProps) - if (PrevAtProps->find(Loc) != PrevAtProps->end()) - continue; - PropsTy &props = AtProps[Loc]; - props.push_back(Prop); - } - } - - void doTransform(ObjCImplementationDecl *D) { - CurImplD = D; - ObjCInterfaceDecl *iface = D->getClassInterface(); - if (!iface) - return; - - collectProperties(iface, AtProps); - - // Look through extensions. - for (auto *Ext : iface->visible_extensions()) - collectProperties(Ext, AtProps); - - typedef DeclContext::specific_decl_iterator - prop_impl_iterator; - for (prop_impl_iterator - I = prop_impl_iterator(D->decls_begin()), - E = prop_impl_iterator(D->decls_end()); I != E; ++I) { - ObjCPropertyImplDecl *implD = *I; - if (implD->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) - continue; - ObjCPropertyDecl *propD = implD->getPropertyDecl(); - if (!propD || propD->isInvalidDecl()) - continue; - ObjCIvarDecl *ivarD = implD->getPropertyIvarDecl(); - if (!ivarD || ivarD->isInvalidDecl()) - continue; - AtPropDeclsTy::iterator findAtLoc = AtProps.find(propD->getAtLoc()); - if (findAtLoc == AtProps.end()) - continue; - - PropsTy &props = findAtLoc->second; - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - if (I->PropD == propD) { - I->IvarD = ivarD; - I->ImplD = implD; - break; - } - } - } - - for (AtPropDeclsTy::iterator - I = AtProps.begin(), E = AtProps.end(); I != E; ++I) { - SourceLocation atLoc = I->first; - PropsTy &props = I->second; - if (!getPropertyType(props)->isObjCRetainableType()) - continue; - if (hasIvarWithExplicitARCOwnership(props)) - continue; - - Transaction Trans(Pass.TA); - rewriteProperty(props, atLoc); - } - } - -private: - void doPropAction(PropActionKind kind, - PropsTy &props, SourceLocation atLoc, - bool markAction = true) { - if (markAction) - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) - ActionOnProp[I->PropD->getIdentifier()] = kind; - - switch (kind) { - case PropAction_None: - return; - case PropAction_RetainReplacedWithStrong: { - StringRef toAttr = "strong"; - MigrateCtx.rewritePropertyAttribute("retain", toAttr, atLoc); - return; - } - case PropAction_AssignRemoved: - return removeAssignForDefaultStrong(props, atLoc); - case PropAction_AssignRewritten: - return rewriteAssign(props, atLoc); - case PropAction_MaybeAddWeakOrUnsafe: - return maybeAddWeakOrUnsafeUnretainedAttr(props, atLoc); - } - } - - void rewriteProperty(PropsTy &props, SourceLocation atLoc) { - ObjCPropertyAttribute::Kind propAttrs = getPropertyAttrs(props); - - if (propAttrs & - (ObjCPropertyAttribute::kind_copy | - ObjCPropertyAttribute::kind_unsafe_unretained | - ObjCPropertyAttribute::kind_strong | ObjCPropertyAttribute::kind_weak)) - return; - - if (propAttrs & ObjCPropertyAttribute::kind_retain) { - // strong is the default. - return doPropAction(PropAction_RetainReplacedWithStrong, props, atLoc); - } - - bool HasIvarAssignedAPlusOneObject = hasIvarAssignedAPlusOneObject(props); - - if (propAttrs & ObjCPropertyAttribute::kind_assign) { - if (HasIvarAssignedAPlusOneObject) - return doPropAction(PropAction_AssignRemoved, props, atLoc); - return doPropAction(PropAction_AssignRewritten, props, atLoc); - } - - if (HasIvarAssignedAPlusOneObject || - (Pass.isGCMigration() && !hasGCWeak(props, atLoc))) - return; // 'strong' by default. - - return doPropAction(PropAction_MaybeAddWeakOrUnsafe, props, atLoc); - } - - void removeAssignForDefaultStrong(PropsTy &props, - SourceLocation atLoc) const { - removeAttribute("retain", atLoc); - if (!removeAttribute("assign", atLoc)) - return; - - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - if (I->ImplD) - Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, - diag::err_arc_assign_property_ownership, - diag::err_arc_inconsistent_property_ownership, - I->IvarD->getLocation()); - } - } - - void rewriteAssign(PropsTy &props, SourceLocation atLoc) const { - bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), - /*AllowOnUnknownClass=*/Pass.isGCMigration()); - const char *toWhich = - (Pass.isGCMigration() && !hasGCWeak(props, atLoc)) ? "strong" : - (canUseWeak ? "weak" : "unsafe_unretained"); - - bool rewroteAttr = rewriteAttribute("assign", toWhich, atLoc); - if (!rewroteAttr) - canUseWeak = false; - - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - if (isUserDeclared(I->IvarD)) { - if (I->IvarD && - I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) { - const char *toWhich = - (Pass.isGCMigration() && !hasGCWeak(props, atLoc)) ? "__strong " : - (canUseWeak ? "__weak " : "__unsafe_unretained "); - Pass.TA.insert(I->IvarD->getLocation(), toWhich); - } - } - if (I->ImplD) - Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, - diag::err_arc_assign_property_ownership, - diag::err_arc_inconsistent_property_ownership, - I->IvarD->getLocation()); - } - } - - void maybeAddWeakOrUnsafeUnretainedAttr(PropsTy &props, - SourceLocation atLoc) const { - bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), - /*AllowOnUnknownClass=*/Pass.isGCMigration()); - - bool addedAttr = addAttribute(canUseWeak ? "weak" : "unsafe_unretained", - atLoc); - if (!addedAttr) - canUseWeak = false; - - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - if (isUserDeclared(I->IvarD)) { - if (I->IvarD && - I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) - Pass.TA.insert(I->IvarD->getLocation(), - canUseWeak ? "__weak " : "__unsafe_unretained "); - } - if (I->ImplD) { - Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, - diag::err_arc_assign_property_ownership, - diag::err_arc_inconsistent_property_ownership, - I->IvarD->getLocation()); - Pass.TA.clearDiagnostic( - diag::err_arc_objc_property_default_assign_on_object, - I->ImplD->getLocation()); - } - } - } - - bool removeAttribute(StringRef fromAttr, SourceLocation atLoc) const { - return MigrateCtx.removePropertyAttribute(fromAttr, atLoc); - } - - bool rewriteAttribute(StringRef fromAttr, StringRef toAttr, - SourceLocation atLoc) const { - return MigrateCtx.rewritePropertyAttribute(fromAttr, toAttr, atLoc); - } - - bool addAttribute(StringRef attr, SourceLocation atLoc) const { - return MigrateCtx.addPropertyAttribute(attr, atLoc); - } - - class PlusOneAssign : public RecursiveASTVisitor { - ObjCIvarDecl *Ivar; - public: - PlusOneAssign(ObjCIvarDecl *D) : Ivar(D) {} - - bool VisitBinaryOperator(BinaryOperator *E) { - if (E->getOpcode() != BO_Assign) - return true; - - Expr *lhs = E->getLHS()->IgnoreParenImpCasts(); - if (ObjCIvarRefExpr *RE = dyn_cast(lhs)) { - if (RE->getDecl() != Ivar) - return true; - - if (isPlusOneAssign(E)) - return false; - } - - return true; - } - }; - - bool hasIvarAssignedAPlusOneObject(PropsTy &props) const { - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - PlusOneAssign oneAssign(I->IvarD); - bool notFound = oneAssign.TraverseDecl(CurImplD); - if (!notFound) - return true; - } - - return false; - } - - bool hasIvarWithExplicitARCOwnership(PropsTy &props) const { - if (Pass.isGCMigration()) - return false; - - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - if (isUserDeclared(I->IvarD)) { - if (isa(I->IvarD->getType())) - return true; - if (I->IvarD->getType().getLocalQualifiers().getObjCLifetime() - != Qualifiers::OCL_Strong) - return true; - } - } - - return false; - } - - // Returns true if all declarations in the @property have GC __weak. - bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const { - if (!Pass.isGCMigration()) - return false; - if (props.empty()) - return false; - return MigrateCtx.AtPropsWeak.count(atLoc); - } - - bool isUserDeclared(ObjCIvarDecl *ivarD) const { - return ivarD && !ivarD->getSynthesize(); - } - - QualType getPropertyType(PropsTy &props) const { - assert(!props.empty()); - QualType ty = props[0].PropD->getType().getUnqualifiedType(); - -#ifndef NDEBUG - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) - assert(ty == I->PropD->getType().getUnqualifiedType()); -#endif - - return ty; - } - - ObjCPropertyAttribute::Kind getPropertyAttrs(PropsTy &props) const { - assert(!props.empty()); - ObjCPropertyAttribute::Kind attrs = - props[0].PropD->getPropertyAttributesAsWritten(); - -#ifndef NDEBUG - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) - assert(attrs == I->PropD->getPropertyAttributesAsWritten()); -#endif - - return attrs; - } -}; - -} // anonymous namespace - -void PropertyRewriteTraverser::traverseObjCImplementation( - ObjCImplementationContext &ImplCtx) { - PropertiesRewriter(ImplCtx.getMigrationContext()) - .doTransform(ImplCtx.getImplementationDecl()); -} diff --git a/clang/lib/ARCMigrate/TransProtectedScope.cpp b/clang/lib/ARCMigrate/TransProtectedScope.cpp deleted file mode 100644 index 154e0b54800f99..00000000000000 --- a/clang/lib/ARCMigrate/TransProtectedScope.cpp +++ /dev/null @@ -1,203 +0,0 @@ -//===--- TransProtectedScope.cpp - Transformations to ARC mode ------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Adds brackets in case statements that "contain" initialization of retaining -// variable, thus emitting the "switch case is in protected scope" error. -// -//===----------------------------------------------------------------------===// - -#include "Internals.h" -#include "Transforms.h" -#include "clang/AST/ASTContext.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Sema/SemaDiagnostic.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class LocalRefsCollector : public RecursiveASTVisitor { - SmallVectorImpl &Refs; - -public: - LocalRefsCollector(SmallVectorImpl &refs) - : Refs(refs) { } - - bool VisitDeclRefExpr(DeclRefExpr *E) { - if (ValueDecl *D = E->getDecl()) - if (D->getDeclContext()->getRedeclContext()->isFunctionOrMethod()) - Refs.push_back(E); - return true; - } -}; - -struct CaseInfo { - SwitchCase *SC; - SourceRange Range; - enum { - St_Unchecked, - St_CannotFix, - St_Fixed - } State; - - CaseInfo() : SC(nullptr), State(St_Unchecked) {} - CaseInfo(SwitchCase *S, SourceRange Range) - : SC(S), Range(Range), State(St_Unchecked) {} -}; - -class CaseCollector : public RecursiveASTVisitor { - ParentMap &PMap; - SmallVectorImpl &Cases; - -public: - CaseCollector(ParentMap &PMap, SmallVectorImpl &Cases) - : PMap(PMap), Cases(Cases) { } - - bool VisitSwitchStmt(SwitchStmt *S) { - SwitchCase *Curr = S->getSwitchCaseList(); - if (!Curr) - return true; - Stmt *Parent = getCaseParent(Curr); - Curr = Curr->getNextSwitchCase(); - // Make sure all case statements are in the same scope. - while (Curr) { - if (getCaseParent(Curr) != Parent) - return true; - Curr = Curr->getNextSwitchCase(); - } - - SourceLocation NextLoc = S->getEndLoc(); - Curr = S->getSwitchCaseList(); - // We iterate over case statements in reverse source-order. - while (Curr) { - Cases.push_back( - CaseInfo(Curr, SourceRange(Curr->getBeginLoc(), NextLoc))); - NextLoc = Curr->getBeginLoc(); - Curr = Curr->getNextSwitchCase(); - } - return true; - } - - Stmt *getCaseParent(SwitchCase *S) { - Stmt *Parent = PMap.getParent(S); - while (Parent && (isa(Parent) || isa(Parent))) - Parent = PMap.getParent(Parent); - return Parent; - } -}; - -class ProtectedScopeFixer { - MigrationPass &Pass; - SourceManager &SM; - SmallVector Cases; - SmallVector LocalRefs; - -public: - ProtectedScopeFixer(BodyContext &BodyCtx) - : Pass(BodyCtx.getMigrationContext().Pass), - SM(Pass.Ctx.getSourceManager()) { - - CaseCollector(BodyCtx.getParentMap(), Cases) - .TraverseStmt(BodyCtx.getTopStmt()); - LocalRefsCollector(LocalRefs).TraverseStmt(BodyCtx.getTopStmt()); - - SourceRange BodyRange = BodyCtx.getTopStmt()->getSourceRange(); - const CapturedDiagList &DiagList = Pass.getDiags(); - // Copy the diagnostics so we don't have to worry about invaliding iterators - // from the diagnostic list. - SmallVector StoredDiags; - StoredDiags.append(DiagList.begin(), DiagList.end()); - SmallVectorImpl::iterator - I = StoredDiags.begin(), E = StoredDiags.end(); - while (I != E) { - if (I->getID() == diag::err_switch_into_protected_scope && - isInRange(I->getLocation(), BodyRange)) { - handleProtectedScopeError(I, E); - continue; - } - ++I; - } - } - - void handleProtectedScopeError( - SmallVectorImpl::iterator &DiagI, - SmallVectorImpl::iterator DiagE){ - Transaction Trans(Pass.TA); - assert(DiagI->getID() == diag::err_switch_into_protected_scope); - SourceLocation ErrLoc = DiagI->getLocation(); - bool handledAllNotes = true; - ++DiagI; - for (; DiagI != DiagE && DiagI->getLevel() == DiagnosticsEngine::Note; - ++DiagI) { - if (!handleProtectedNote(*DiagI)) - handledAllNotes = false; - } - - if (handledAllNotes) - Pass.TA.clearDiagnostic(diag::err_switch_into_protected_scope, ErrLoc); - } - - bool handleProtectedNote(const StoredDiagnostic &Diag) { - assert(Diag.getLevel() == DiagnosticsEngine::Note); - - for (unsigned i = 0; i != Cases.size(); i++) { - CaseInfo &info = Cases[i]; - if (isInRange(Diag.getLocation(), info.Range)) { - - if (info.State == CaseInfo::St_Unchecked) - tryFixing(info); - assert(info.State != CaseInfo::St_Unchecked); - - if (info.State == CaseInfo::St_Fixed) { - Pass.TA.clearDiagnostic(Diag.getID(), Diag.getLocation()); - return true; - } - return false; - } - } - - return false; - } - - void tryFixing(CaseInfo &info) { - assert(info.State == CaseInfo::St_Unchecked); - if (hasVarReferencedOutside(info)) { - info.State = CaseInfo::St_CannotFix; - return; - } - - Pass.TA.insertAfterToken(info.SC->getColonLoc(), " {"); - Pass.TA.insert(info.Range.getEnd(), "}\n"); - info.State = CaseInfo::St_Fixed; - } - - bool hasVarReferencedOutside(CaseInfo &info) { - for (unsigned i = 0, e = LocalRefs.size(); i != e; ++i) { - DeclRefExpr *DRE = LocalRefs[i]; - if (isInRange(DRE->getDecl()->getLocation(), info.Range) && - !isInRange(DRE->getLocation(), info.Range)) - return true; - } - return false; - } - - bool isInRange(SourceLocation Loc, SourceRange R) { - if (Loc.isInvalid()) - return false; - return !SM.isBeforeInTranslationUnit(Loc, R.getBegin()) && - SM.isBeforeInTranslationUnit(Loc, R.getEnd()); - } -}; - -} // anonymous namespace - -void ProtectedScopeTraverser::traverseBody(BodyContext &BodyCtx) { - ProtectedScopeFixer Fix(BodyCtx); -} diff --git a/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp deleted file mode 100644 index baa503d8a39dc1..00000000000000 --- a/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp +++ /dev/null @@ -1,459 +0,0 @@ -//===--- TransRetainReleaseDealloc.cpp - Transformations to ARC mode ------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// removeRetainReleaseDealloc: -// -// Removes retain/release/autorelease/dealloc messages. -// -// return [[foo retain] autorelease]; -// ----> -// return foo; -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/ParentMap.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "llvm/ADT/StringSwitch.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class RetainReleaseDeallocRemover : - public RecursiveASTVisitor { - Stmt *Body; - MigrationPass &Pass; - - ExprSet Removables; - std::unique_ptr StmtMap; - - Selector DelegateSel, FinalizeSel; - -public: - RetainReleaseDeallocRemover(MigrationPass &pass) - : Body(nullptr), Pass(pass) { - DelegateSel = - Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("delegate")); - FinalizeSel = - Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize")); - } - - void transformBody(Stmt *body, Decl *ParentD) { - Body = body; - collectRemovables(body, Removables); - StmtMap.reset(new ParentMap(body)); - TraverseStmt(body); - } - - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - switch (E->getMethodFamily()) { - default: - if (E->isInstanceMessage() && E->getSelector() == FinalizeSel) - break; - return true; - case OMF_autorelease: - if (isRemovable(E)) { - if (!isCommonUnusedAutorelease(E)) { - // An unused autorelease is badness. If we remove it the receiver - // will likely die immediately while previously it was kept alive - // by the autorelease pool. This is bad practice in general, leave it - // and emit an error to force the user to restructure their code. - Pass.TA.reportError( - "it is not safe to remove an unused 'autorelease' " - "message; its receiver may be destroyed immediately", - E->getBeginLoc(), E->getSourceRange()); - return true; - } - } - // Pass through. - [[fallthrough]]; - case OMF_retain: - case OMF_release: - if (E->getReceiverKind() == ObjCMessageExpr::Instance) - if (Expr *rec = E->getInstanceReceiver()) { - rec = rec->IgnoreParenImpCasts(); - if (rec->getType().getObjCLifetime() == Qualifiers::OCL_ExplicitNone && - (E->getMethodFamily() != OMF_retain || isRemovable(E))) { - std::string err = "it is not safe to remove '"; - err += E->getSelector().getAsString() + "' message on " - "an __unsafe_unretained type"; - Pass.TA.reportError(err, rec->getBeginLoc()); - return true; - } - - if (isGlobalVar(rec) && - (E->getMethodFamily() != OMF_retain || isRemovable(E))) { - std::string err = "it is not safe to remove '"; - err += E->getSelector().getAsString() + "' message on " - "a global variable"; - Pass.TA.reportError(err, rec->getBeginLoc()); - return true; - } - - if (E->getMethodFamily() == OMF_release && isDelegateMessage(rec)) { - Pass.TA.reportError( - "it is not safe to remove 'retain' " - "message on the result of a 'delegate' message; " - "the object that was passed to 'setDelegate:' may not be " - "properly retained", - rec->getBeginLoc()); - return true; - } - } - break; - case OMF_dealloc: - break; - } - - switch (E->getReceiverKind()) { - default: - return true; - case ObjCMessageExpr::SuperInstance: { - Transaction Trans(Pass.TA); - clearDiagnostics(E->getSelectorLoc(0)); - if (tryRemoving(E)) - return true; - Pass.TA.replace(E->getSourceRange(), "self"); - return true; - } - case ObjCMessageExpr::Instance: - break; - } - - Expr *rec = E->getInstanceReceiver(); - if (!rec) return true; - - Transaction Trans(Pass.TA); - clearDiagnostics(E->getSelectorLoc(0)); - - ObjCMessageExpr *Msg = E; - Expr *RecContainer = Msg; - SourceRange RecRange = rec->getSourceRange(); - checkForGCDOrXPC(Msg, RecContainer, rec, RecRange); - - if (Msg->getMethodFamily() == OMF_release && - isRemovable(RecContainer) && isInAtFinally(RecContainer)) { - // Change the -release to "receiver = nil" in a finally to avoid a leak - // when an exception is thrown. - Pass.TA.replace(RecContainer->getSourceRange(), RecRange); - std::string str = " = "; - str += getNilString(Pass); - Pass.TA.insertAfterToken(RecRange.getEnd(), str); - return true; - } - - if (hasSideEffects(rec, Pass.Ctx) || !tryRemoving(RecContainer)) - Pass.TA.replace(RecContainer->getSourceRange(), RecRange); - - return true; - } - -private: - /// Checks for idioms where an unused -autorelease is common. - /// - /// Returns true for this idiom which is common in property - /// setters: - /// - /// [backingValue autorelease]; - /// backingValue = [newValue retain]; // in general a +1 assign - /// - /// For these as well: - /// - /// [[var retain] autorelease]; - /// return var; - /// - bool isCommonUnusedAutorelease(ObjCMessageExpr *E) { - return isPlusOneAssignBeforeOrAfterAutorelease(E) || - isReturnedAfterAutorelease(E); - } - - bool isReturnedAfterAutorelease(ObjCMessageExpr *E) { - Expr *Rec = E->getInstanceReceiver(); - if (!Rec) - return false; - - Decl *RefD = getReferencedDecl(Rec); - if (!RefD) - return false; - - Stmt *nextStmt = getNextStmt(E); - if (!nextStmt) - return false; - - // Check for "return ;". - - if (ReturnStmt *RetS = dyn_cast(nextStmt)) - return RefD == getReferencedDecl(RetS->getRetValue()); - - return false; - } - - bool isPlusOneAssignBeforeOrAfterAutorelease(ObjCMessageExpr *E) { - Expr *Rec = E->getInstanceReceiver(); - if (!Rec) - return false; - - Decl *RefD = getReferencedDecl(Rec); - if (!RefD) - return false; - - Stmt *prevStmt, *nextStmt; - std::tie(prevStmt, nextStmt) = getPreviousAndNextStmt(E); - - return isPlusOneAssignToVar(prevStmt, RefD) || - isPlusOneAssignToVar(nextStmt, RefD); - } - - bool isPlusOneAssignToVar(Stmt *S, Decl *RefD) { - if (!S) - return false; - - // Check for "RefD = [+1 retained object];". - - if (BinaryOperator *Bop = dyn_cast(S)) { - return (RefD == getReferencedDecl(Bop->getLHS())) && isPlusOneAssign(Bop); - } - - if (DeclStmt *DS = dyn_cast(S)) { - if (DS->isSingleDecl() && DS->getSingleDecl() == RefD) { - if (VarDecl *VD = dyn_cast(RefD)) - return isPlusOne(VD->getInit()); - } - return false; - } - - return false; - } - - Stmt *getNextStmt(Expr *E) { - return getPreviousAndNextStmt(E).second; - } - - std::pair getPreviousAndNextStmt(Expr *E) { - Stmt *prevStmt = nullptr, *nextStmt = nullptr; - if (!E) - return std::make_pair(prevStmt, nextStmt); - - Stmt *OuterS = E, *InnerS; - do { - InnerS = OuterS; - OuterS = StmtMap->getParent(InnerS); - } - while (OuterS && (isa(OuterS) || - isa(OuterS) || - isa(OuterS))); - - if (!OuterS) - return std::make_pair(prevStmt, nextStmt); - - Stmt::child_iterator currChildS = OuterS->child_begin(); - Stmt::child_iterator childE = OuterS->child_end(); - Stmt::child_iterator prevChildS = childE; - for (; currChildS != childE; ++currChildS) { - if (*currChildS == InnerS) - break; - prevChildS = currChildS; - } - - if (prevChildS != childE) { - prevStmt = *prevChildS; - if (auto *E = dyn_cast_or_null(prevStmt)) - prevStmt = E->IgnoreImplicit(); - } - - if (currChildS == childE) - return std::make_pair(prevStmt, nextStmt); - ++currChildS; - if (currChildS == childE) - return std::make_pair(prevStmt, nextStmt); - - nextStmt = *currChildS; - if (auto *E = dyn_cast_or_null(nextStmt)) - nextStmt = E->IgnoreImplicit(); - - return std::make_pair(prevStmt, nextStmt); - } - - Decl *getReferencedDecl(Expr *E) { - if (!E) - return nullptr; - - E = E->IgnoreParenCasts(); - if (ObjCMessageExpr *ME = dyn_cast(E)) { - switch (ME->getMethodFamily()) { - case OMF_copy: - case OMF_autorelease: - case OMF_release: - case OMF_retain: - return getReferencedDecl(ME->getInstanceReceiver()); - default: - return nullptr; - } - } - if (DeclRefExpr *DRE = dyn_cast(E)) - return DRE->getDecl(); - if (MemberExpr *ME = dyn_cast(E)) - return ME->getMemberDecl(); - if (ObjCIvarRefExpr *IRE = dyn_cast(E)) - return IRE->getDecl(); - - return nullptr; - } - - /// Check if the retain/release is due to a GCD/XPC macro that are - /// defined as: - /// - /// #define dispatch_retain(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); (void)[_o retain]; }) - /// #define dispatch_release(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); [_o release]; }) - /// #define xpc_retain(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o retain]; }) - /// #define xpc_release(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o release]; }) - /// - /// and return the top container which is the StmtExpr and the macro argument - /// expression. - void checkForGCDOrXPC(ObjCMessageExpr *Msg, Expr *&RecContainer, - Expr *&Rec, SourceRange &RecRange) { - SourceLocation Loc = Msg->getExprLoc(); - if (!Loc.isMacroID()) - return; - SourceManager &SM = Pass.Ctx.getSourceManager(); - StringRef MacroName = Lexer::getImmediateMacroName(Loc, SM, - Pass.Ctx.getLangOpts()); - bool isGCDOrXPC = llvm::StringSwitch(MacroName) - .Case("dispatch_retain", true) - .Case("dispatch_release", true) - .Case("xpc_retain", true) - .Case("xpc_release", true) - .Default(false); - if (!isGCDOrXPC) - return; - - StmtExpr *StmtE = nullptr; - Stmt *S = Msg; - while (S) { - if (StmtExpr *SE = dyn_cast(S)) { - StmtE = SE; - break; - } - S = StmtMap->getParent(S); - } - - if (!StmtE) - return; - - Stmt::child_range StmtExprChild = StmtE->children(); - if (StmtExprChild.begin() == StmtExprChild.end()) - return; - auto *CompS = dyn_cast_or_null(*StmtExprChild.begin()); - if (!CompS) - return; - - Stmt::child_range CompStmtChild = CompS->children(); - if (CompStmtChild.begin() == CompStmtChild.end()) - return; - auto *DeclS = dyn_cast_or_null(*CompStmtChild.begin()); - if (!DeclS) - return; - if (!DeclS->isSingleDecl()) - return; - VarDecl *VD = dyn_cast_or_null(DeclS->getSingleDecl()); - if (!VD) - return; - Expr *Init = VD->getInit(); - if (!Init) - return; - - RecContainer = StmtE; - Rec = Init->IgnoreParenImpCasts(); - if (FullExpr *FE = dyn_cast(Rec)) - Rec = FE->getSubExpr()->IgnoreParenImpCasts(); - RecRange = Rec->getSourceRange(); - if (SM.isMacroArgExpansion(RecRange.getBegin())) - RecRange.setBegin(SM.getImmediateSpellingLoc(RecRange.getBegin())); - if (SM.isMacroArgExpansion(RecRange.getEnd())) - RecRange.setEnd(SM.getImmediateSpellingLoc(RecRange.getEnd())); - } - - void clearDiagnostics(SourceLocation loc) const { - Pass.TA.clearDiagnostic(diag::err_arc_illegal_explicit_message, - diag::err_unavailable, - diag::err_unavailable_message, - loc); - } - - bool isDelegateMessage(Expr *E) const { - if (!E) return false; - - E = E->IgnoreParenCasts(); - - // Also look through property-getter sugar. - if (PseudoObjectExpr *pseudoOp = dyn_cast(E)) - E = pseudoOp->getResultExpr()->IgnoreImplicit(); - - if (ObjCMessageExpr *ME = dyn_cast(E)) - return (ME->isInstanceMessage() && ME->getSelector() == DelegateSel); - - return false; - } - - bool isInAtFinally(Expr *E) const { - assert(E); - Stmt *S = E; - while (S) { - if (isa(S)) - return true; - S = StmtMap->getParent(S); - } - - return false; - } - - bool isRemovable(Expr *E) const { - return Removables.count(E); - } - - bool tryRemoving(Expr *E) const { - if (isRemovable(E)) { - Pass.TA.removeStmt(E); - return true; - } - - Stmt *parent = StmtMap->getParent(E); - - if (ImplicitCastExpr *castE = dyn_cast_or_null(parent)) - return tryRemoving(castE); - - if (ParenExpr *parenE = dyn_cast_or_null(parent)) - return tryRemoving(parenE); - - if (BinaryOperator * - bopE = dyn_cast_or_null(parent)) { - if (bopE->getOpcode() == BO_Comma && bopE->getLHS() == E && - isRemovable(bopE)) { - Pass.TA.replace(bopE->getSourceRange(), bopE->getRHS()->getSourceRange()); - return true; - } - } - - return false; - } - -}; - -} // anonymous namespace - -void trans::removeRetainReleaseDeallocFinalize(MigrationPass &pass) { - BodyTransform trans(pass); - trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp b/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp deleted file mode 100644 index 7390ea17c8a4b6..00000000000000 --- a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp +++ /dev/null @@ -1,466 +0,0 @@ -//===--- TransUnbridgedCasts.cpp - Transformations to ARC mode ------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// rewriteUnbridgedCasts: -// -// A cast of non-objc pointer to an objc one is checked. If the non-objc pointer -// is from a file-level variable, __bridge cast is used to convert it. -// For the result of a function call that we know is +1/+0, -// __bridge/CFBridgingRelease is used. -// -// NSString *str = (NSString *)kUTTypePlainText; -// str = b ? kUTTypeRTF : kUTTypePlainText; -// NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, -// _uuid); -// ----> -// NSString *str = (__bridge NSString *)kUTTypePlainText; -// str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText); -// NSString *_uuidString = (NSString *) -// CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid)); -// -// For a C pointer to ObjC, for casting 'self', __bridge is used. -// -// CFStringRef str = (CFStringRef)self; -// ----> -// CFStringRef str = (__bridge CFStringRef)self; -// -// Uses of Block_copy/Block_release macros are rewritten: -// -// c = Block_copy(b); -// Block_release(c); -// ----> -// c = [b copy]; -// -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Attr.h" -#include "clang/AST/ParentMap.h" -#include "clang/Analysis/DomainSpecific/CocoaConventions.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "llvm/ADT/SmallString.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class UnbridgedCastRewriter : public RecursiveASTVisitor{ - MigrationPass &Pass; - IdentifierInfo *SelfII; - std::unique_ptr StmtMap; - Decl *ParentD; - Stmt *Body; - mutable std::unique_ptr Removables; - -public: - UnbridgedCastRewriter(MigrationPass &pass) - : Pass(pass), ParentD(nullptr), Body(nullptr) { - SelfII = &Pass.Ctx.Idents.get("self"); - } - - void transformBody(Stmt *body, Decl *ParentD) { - this->ParentD = ParentD; - Body = body; - StmtMap.reset(new ParentMap(body)); - TraverseStmt(body); - } - - bool TraverseBlockDecl(BlockDecl *D) { - // ParentMap does not enter into a BlockDecl to record its stmts, so use a - // new UnbridgedCastRewriter to handle the block. - UnbridgedCastRewriter(Pass).transformBody(D->getBody(), D); - return true; - } - - bool VisitCastExpr(CastExpr *E) { - if (E->getCastKind() != CK_CPointerToObjCPointerCast && - E->getCastKind() != CK_BitCast && - E->getCastKind() != CK_AnyPointerToBlockPointerCast) - return true; - - QualType castType = E->getType(); - Expr *castExpr = E->getSubExpr(); - QualType castExprType = castExpr->getType(); - - if (castType->isObjCRetainableType() == castExprType->isObjCRetainableType()) - return true; - - bool exprRetainable = castExprType->isObjCIndirectLifetimeType(); - bool castRetainable = castType->isObjCIndirectLifetimeType(); - if (exprRetainable == castRetainable) return true; - - if (castExpr->isNullPointerConstant(Pass.Ctx, - Expr::NPC_ValueDependentIsNull)) - return true; - - SourceLocation loc = castExpr->getExprLoc(); - if (loc.isValid() && Pass.Ctx.getSourceManager().isInSystemHeader(loc)) - return true; - - if (castType->isObjCRetainableType()) - transformNonObjCToObjCCast(E); - else - transformObjCToNonObjCCast(E); - - return true; - } - -private: - void transformNonObjCToObjCCast(CastExpr *E) { - if (!E) return; - - // Global vars are assumed that are cast as unretained. - if (isGlobalVar(E)) - if (E->getSubExpr()->getType()->isPointerType()) { - castToObjCObject(E, /*retained=*/false); - return; - } - - // If the cast is directly over the result of a Core Foundation function - // try to figure out whether it should be cast as retained or unretained. - Expr *inner = E->IgnoreParenCasts(); - if (CallExpr *callE = dyn_cast(inner)) { - if (FunctionDecl *FD = callE->getDirectCallee()) { - if (FD->hasAttr()) { - castToObjCObject(E, /*retained=*/true); - return; - } - if (FD->hasAttr()) { - castToObjCObject(E, /*retained=*/false); - return; - } - if (FD->isGlobal() && - FD->getIdentifier() && - ento::cocoa::isRefType(E->getSubExpr()->getType(), "CF", - FD->getIdentifier()->getName())) { - StringRef fname = FD->getIdentifier()->getName(); - if (fname.ends_with("Retain") || fname.contains("Create") || - fname.contains("Copy")) { - // Do not migrate to couple of bridge transfer casts which - // cancel each other out. Leave it unchanged so error gets user - // attention instead. - if (FD->getName() == "CFRetain" && - FD->getNumParams() == 1 && - FD->getParent()->isTranslationUnit() && - FD->isExternallyVisible()) { - Expr *Arg = callE->getArg(0); - if (const ImplicitCastExpr *ICE = dyn_cast(Arg)) { - const Expr *sub = ICE->getSubExpr(); - QualType T = sub->getType(); - if (T->isObjCObjectPointerType()) - return; - } - } - castToObjCObject(E, /*retained=*/true); - return; - } - - if (fname.contains("Get")) { - castToObjCObject(E, /*retained=*/false); - return; - } - } - } - } - - // If returning an ivar or a member of an ivar from a +0 method, use - // a __bridge cast. - Expr *base = inner->IgnoreParenImpCasts(); - while (isa(base)) - base = cast(base)->getBase()->IgnoreParenImpCasts(); - if (isa(base) && - isa(StmtMap->getParentIgnoreParenCasts(E))) { - if (ObjCMethodDecl *method = dyn_cast_or_null(ParentD)) { - if (!method->hasAttr()) { - castToObjCObject(E, /*retained=*/false); - return; - } - } - } - } - - void castToObjCObject(CastExpr *E, bool retained) { - rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge); - } - - void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) { - Transaction Trans(Pass.TA); - rewriteToBridgedCast(E, Kind, Trans); - } - - void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind, - Transaction &Trans) { - TransformActions &TA = Pass.TA; - - // We will remove the compiler diagnostic. - if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast, - diag::err_arc_cast_requires_bridge, - E->getBeginLoc())) { - Trans.abort(); - return; - } - - StringRef bridge; - switch(Kind) { - case OBC_Bridge: - bridge = "__bridge "; break; - case OBC_BridgeTransfer: - bridge = "__bridge_transfer "; break; - case OBC_BridgeRetained: - bridge = "__bridge_retained "; break; - } - - TA.clearDiagnostic(diag::err_arc_mismatched_cast, - diag::err_arc_cast_requires_bridge, E->getBeginLoc()); - if (Kind == OBC_Bridge || !Pass.CFBridgingFunctionsDefined()) { - if (CStyleCastExpr *CCE = dyn_cast(E)) { - TA.insertAfterToken(CCE->getLParenLoc(), bridge); - } else { - SourceLocation insertLoc = E->getSubExpr()->getBeginLoc(); - SmallString<128> newCast; - newCast += '('; - newCast += bridge; - newCast += E->getType().getAsString(Pass.Ctx.getPrintingPolicy()); - newCast += ')'; - - if (isa(E->getSubExpr())) { - TA.insert(insertLoc, newCast.str()); - } else { - newCast += '('; - TA.insert(insertLoc, newCast.str()); - TA.insertAfterToken(E->getEndLoc(), ")"); - } - } - } else { - assert(Kind == OBC_BridgeTransfer || Kind == OBC_BridgeRetained); - SmallString<32> BridgeCall; - - Expr *WrapE = E->getSubExpr(); - SourceLocation InsertLoc = WrapE->getBeginLoc(); - - SourceManager &SM = Pass.Ctx.getSourceManager(); - char PrevChar = *SM.getCharacterData(InsertLoc.getLocWithOffset(-1)); - if (Lexer::isAsciiIdentifierContinueChar(PrevChar, - Pass.Ctx.getLangOpts())) - BridgeCall += ' '; - - if (Kind == OBC_BridgeTransfer) - BridgeCall += "CFBridgingRelease"; - else - BridgeCall += "CFBridgingRetain"; - - if (isa(WrapE)) { - TA.insert(InsertLoc, BridgeCall); - } else { - BridgeCall += '('; - TA.insert(InsertLoc, BridgeCall); - TA.insertAfterToken(WrapE->getEndLoc(), ")"); - } - } - } - - void rewriteCastForCFRetain(CastExpr *castE, CallExpr *callE) { - Transaction Trans(Pass.TA); - Pass.TA.replace(callE->getSourceRange(), callE->getArg(0)->getSourceRange()); - rewriteToBridgedCast(castE, OBC_BridgeRetained, Trans); - } - - void getBlockMacroRanges(CastExpr *E, SourceRange &Outer, SourceRange &Inner) { - SourceManager &SM = Pass.Ctx.getSourceManager(); - SourceLocation Loc = E->getExprLoc(); - assert(Loc.isMacroID()); - CharSourceRange MacroRange = SM.getImmediateExpansionRange(Loc); - SourceRange SubRange = E->getSubExpr()->IgnoreParenImpCasts()->getSourceRange(); - SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin()); - SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd()); - - Outer = MacroRange.getAsRange(); - Inner = SourceRange(InnerBegin, InnerEnd); - } - - void rewriteBlockCopyMacro(CastExpr *E) { - SourceRange OuterRange, InnerRange; - getBlockMacroRanges(E, OuterRange, InnerRange); - - Transaction Trans(Pass.TA); - Pass.TA.replace(OuterRange, InnerRange); - Pass.TA.insert(InnerRange.getBegin(), "["); - Pass.TA.insertAfterToken(InnerRange.getEnd(), " copy]"); - Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast, - diag::err_arc_cast_requires_bridge, - OuterRange); - } - - void removeBlockReleaseMacro(CastExpr *E) { - SourceRange OuterRange, InnerRange; - getBlockMacroRanges(E, OuterRange, InnerRange); - - Transaction Trans(Pass.TA); - Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast, - diag::err_arc_cast_requires_bridge, - OuterRange); - if (!hasSideEffects(E, Pass.Ctx)) { - if (tryRemoving(cast(StmtMap->getParentIgnoreParenCasts(E)))) - return; - } - Pass.TA.replace(OuterRange, InnerRange); - } - - bool tryRemoving(Expr *E) const { - if (!Removables) { - Removables.reset(new ExprSet); - collectRemovables(Body, *Removables); - } - - if (Removables->count(E)) { - Pass.TA.removeStmt(E); - return true; - } - - return false; - } - - void transformObjCToNonObjCCast(CastExpr *E) { - SourceLocation CastLoc = E->getExprLoc(); - if (CastLoc.isMacroID()) { - StringRef MacroName = Lexer::getImmediateMacroName(CastLoc, - Pass.Ctx.getSourceManager(), - Pass.Ctx.getLangOpts()); - if (MacroName == "Block_copy") { - rewriteBlockCopyMacro(E); - return; - } - if (MacroName == "Block_release") { - removeBlockReleaseMacro(E); - return; - } - } - - if (isSelf(E->getSubExpr())) - return rewriteToBridgedCast(E, OBC_Bridge); - - CallExpr *callE; - if (isPassedToCFRetain(E, callE)) - return rewriteCastForCFRetain(E, callE); - - ObjCMethodFamily family = getFamilyOfMessage(E->getSubExpr()); - if (family == OMF_retain) - return rewriteToBridgedCast(E, OBC_BridgeRetained); - - if (family == OMF_autorelease || family == OMF_release) { - std::string err = "it is not safe to cast to '"; - err += E->getType().getAsString(Pass.Ctx.getPrintingPolicy()); - err += "' the result of '"; - err += family == OMF_autorelease ? "autorelease" : "release"; - err += "' message; a __bridge cast may result in a pointer to a " - "destroyed object and a __bridge_retained may leak the object"; - Pass.TA.reportError(err, E->getBeginLoc(), - E->getSubExpr()->getSourceRange()); - Stmt *parent = E; - do { - parent = StmtMap->getParentIgnoreParenImpCasts(parent); - } while (isa_and_nonnull(parent)); - - if (ReturnStmt *retS = dyn_cast_or_null(parent)) { - std::string note = "remove the cast and change return type of function " - "to '"; - note += E->getSubExpr()->getType().getAsString(Pass.Ctx.getPrintingPolicy()); - note += "' to have the object automatically autoreleased"; - Pass.TA.reportNote(note, retS->getBeginLoc()); - } - } - - Expr *subExpr = E->getSubExpr(); - - // Look through pseudo-object expressions. - if (PseudoObjectExpr *pseudo = dyn_cast(subExpr)) { - subExpr = pseudo->getResultExpr(); - assert(subExpr && "no result for pseudo-object of non-void type?"); - } - - if (ImplicitCastExpr *implCE = dyn_cast(subExpr)) { - if (implCE->getCastKind() == CK_ARCConsumeObject) - return rewriteToBridgedCast(E, OBC_BridgeRetained); - if (implCE->getCastKind() == CK_ARCReclaimReturnedObject) - return rewriteToBridgedCast(E, OBC_Bridge); - } - - bool isConsumed = false; - if (isPassedToCParamWithKnownOwnership(E, isConsumed)) - return rewriteToBridgedCast(E, isConsumed ? OBC_BridgeRetained - : OBC_Bridge); - } - - static ObjCMethodFamily getFamilyOfMessage(Expr *E) { - E = E->IgnoreParenCasts(); - if (ObjCMessageExpr *ME = dyn_cast(E)) - return ME->getMethodFamily(); - - return OMF_None; - } - - bool isPassedToCFRetain(Expr *E, CallExpr *&callE) const { - if ((callE = dyn_cast_or_null( - StmtMap->getParentIgnoreParenImpCasts(E)))) - if (FunctionDecl * - FD = dyn_cast_or_null(callE->getCalleeDecl())) - if (FD->getName() == "CFRetain" && FD->getNumParams() == 1 && - FD->getParent()->isTranslationUnit() && - FD->isExternallyVisible()) - return true; - - return false; - } - - bool isPassedToCParamWithKnownOwnership(Expr *E, bool &isConsumed) const { - if (CallExpr *callE = dyn_cast_or_null( - StmtMap->getParentIgnoreParenImpCasts(E))) - if (FunctionDecl * - FD = dyn_cast_or_null(callE->getCalleeDecl())) { - unsigned i = 0; - for (unsigned e = callE->getNumArgs(); i != e; ++i) { - Expr *arg = callE->getArg(i); - if (arg == E || arg->IgnoreParenImpCasts() == E) - break; - } - if (i < callE->getNumArgs() && i < FD->getNumParams()) { - ParmVarDecl *PD = FD->getParamDecl(i); - if (PD->hasAttr()) { - isConsumed = true; - return true; - } - } - } - - return false; - } - - bool isSelf(Expr *E) const { - E = E->IgnoreParenLValueCasts(); - if (DeclRefExpr *DRE = dyn_cast(E)) - if (ImplicitParamDecl *IPD = dyn_cast(DRE->getDecl())) - if (IPD->getIdentifier() == SelfII) - return true; - - return false; - } -}; - -} // end anonymous namespace - -void trans::rewriteUnbridgedCasts(MigrationPass &pass) { - BodyTransform trans(pass); - trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp deleted file mode 100644 index bac8dfac9b415f..00000000000000 --- a/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//===--- TransUnusedInitDelegate.cpp - Transformations to ARC mode --------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// Transformations: -//===----------------------------------------------------------------------===// -// -// rewriteUnusedInitDelegate: -// -// Rewrites an unused result of calling a delegate initialization, to assigning -// the result to self. -// e.g -// [self init]; -// ----> -// self = [self init]; -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Sema/SemaDiagnostic.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class UnusedInitRewriter : public RecursiveASTVisitor { - Stmt *Body; - MigrationPass &Pass; - - ExprSet Removables; - -public: - UnusedInitRewriter(MigrationPass &pass) - : Body(nullptr), Pass(pass) { } - - void transformBody(Stmt *body, Decl *ParentD) { - Body = body; - collectRemovables(body, Removables); - TraverseStmt(body); - } - - bool VisitObjCMessageExpr(ObjCMessageExpr *ME) { - if (ME->isDelegateInitCall() && - isRemovable(ME) && - Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message, - ME->getExprLoc())) { - Transaction Trans(Pass.TA); - Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message, - ME->getExprLoc()); - SourceRange ExprRange = ME->getSourceRange(); - Pass.TA.insert(ExprRange.getBegin(), "if (!(self = "); - std::string retStr = ")) return "; - retStr += getNilString(Pass); - Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr); - } - return true; - } - -private: - bool isRemovable(Expr *E) const { - return Removables.count(E); - } -}; - -} // anonymous namespace - -void trans::rewriteUnusedInitDelegate(MigrationPass &pass) { - BodyTransform trans(pass); - trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp deleted file mode 100644 index 81e67628fb1f46..00000000000000 --- a/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp +++ /dev/null @@ -1,224 +0,0 @@ -//===--- TransZeroOutPropsInDealloc.cpp - Transformations to ARC mode -----===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// removeZeroOutPropsInDealloc: -// -// Removes zero'ing out "strong" @synthesized properties in a -dealloc method. -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class ZeroOutInDeallocRemover : - public RecursiveASTVisitor { - typedef RecursiveASTVisitor base; - - MigrationPass &Pass; - - llvm::DenseMap SynthesizedProperties; - ImplicitParamDecl *SelfD; - ExprSet Removables; - Selector FinalizeSel; - -public: - ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(nullptr) { - FinalizeSel = - Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize")); - } - - bool VisitObjCMessageExpr(ObjCMessageExpr *ME) { - ASTContext &Ctx = Pass.Ctx; - TransformActions &TA = Pass.TA; - - if (ME->getReceiverKind() != ObjCMessageExpr::Instance) - return true; - Expr *receiver = ME->getInstanceReceiver(); - if (!receiver) - return true; - - DeclRefExpr *refE = dyn_cast(receiver->IgnoreParenCasts()); - if (!refE || refE->getDecl() != SelfD) - return true; - - bool BackedBySynthesizeSetter = false; - for (llvm::DenseMap::iterator - P = SynthesizedProperties.begin(), - E = SynthesizedProperties.end(); P != E; ++P) { - ObjCPropertyDecl *PropDecl = P->first; - if (PropDecl->getSetterName() == ME->getSelector()) { - BackedBySynthesizeSetter = true; - break; - } - } - if (!BackedBySynthesizeSetter) - return true; - - // Remove the setter message if RHS is null - Transaction Trans(TA); - Expr *RHS = ME->getArg(0); - bool RHSIsNull = - RHS->isNullPointerConstant(Ctx, - Expr::NPC_ValueDependentIsNull); - if (RHSIsNull && isRemovable(ME)) - TA.removeStmt(ME); - - return true; - } - - bool VisitPseudoObjectExpr(PseudoObjectExpr *POE) { - if (isZeroingPropIvar(POE) && isRemovable(POE)) { - Transaction Trans(Pass.TA); - Pass.TA.removeStmt(POE); - } - - return true; - } - - bool VisitBinaryOperator(BinaryOperator *BOE) { - if (isZeroingPropIvar(BOE) && isRemovable(BOE)) { - Transaction Trans(Pass.TA); - Pass.TA.removeStmt(BOE); - } - - return true; - } - - bool TraverseObjCMethodDecl(ObjCMethodDecl *D) { - if (D->getMethodFamily() != OMF_dealloc && - !(D->isInstanceMethod() && D->getSelector() == FinalizeSel)) - return true; - if (!D->hasBody()) - return true; - - ObjCImplDecl *IMD = dyn_cast(D->getDeclContext()); - if (!IMD) - return true; - - SelfD = D->getSelfDecl(); - collectRemovables(D->getBody(), Removables); - - // For a 'dealloc' method use, find all property implementations in - // this class implementation. - for (auto *PID : IMD->property_impls()) { - if (PID->getPropertyImplementation() == - ObjCPropertyImplDecl::Synthesize) { - ObjCPropertyDecl *PD = PID->getPropertyDecl(); - ObjCMethodDecl *setterM = PD->getSetterMethodDecl(); - if (!(setterM && setterM->isDefined())) { - ObjCPropertyAttribute::Kind AttrKind = PD->getPropertyAttributes(); - if (AttrKind & (ObjCPropertyAttribute::kind_retain | - ObjCPropertyAttribute::kind_copy | - ObjCPropertyAttribute::kind_strong)) - SynthesizedProperties[PD] = PID; - } - } - } - - // Now, remove all zeroing of ivars etc. - base::TraverseObjCMethodDecl(D); - - // clear out for next method. - SynthesizedProperties.clear(); - SelfD = nullptr; - Removables.clear(); - return true; - } - - bool TraverseFunctionDecl(FunctionDecl *D) { return true; } - bool TraverseBlockDecl(BlockDecl *block) { return true; } - bool TraverseBlockExpr(BlockExpr *block) { return true; } - -private: - bool isRemovable(Expr *E) const { - return Removables.count(E); - } - - bool isZeroingPropIvar(Expr *E) { - E = E->IgnoreParens(); - if (BinaryOperator *BO = dyn_cast(E)) - return isZeroingPropIvar(BO); - if (PseudoObjectExpr *PO = dyn_cast(E)) - return isZeroingPropIvar(PO); - return false; - } - - bool isZeroingPropIvar(BinaryOperator *BOE) { - if (BOE->getOpcode() == BO_Comma) - return isZeroingPropIvar(BOE->getLHS()) && - isZeroingPropIvar(BOE->getRHS()); - - if (BOE->getOpcode() != BO_Assign) - return false; - - Expr *LHS = BOE->getLHS(); - if (ObjCIvarRefExpr *IV = dyn_cast(LHS)) { - ObjCIvarDecl *IVDecl = IV->getDecl(); - if (!IVDecl->getType()->isObjCObjectPointerType()) - return false; - bool IvarBacksPropertySynthesis = false; - for (llvm::DenseMap::iterator - P = SynthesizedProperties.begin(), - E = SynthesizedProperties.end(); P != E; ++P) { - ObjCPropertyImplDecl *PropImpDecl = P->second; - if (PropImpDecl && PropImpDecl->getPropertyIvarDecl() == IVDecl) { - IvarBacksPropertySynthesis = true; - break; - } - } - if (!IvarBacksPropertySynthesis) - return false; - } - else - return false; - - return isZero(BOE->getRHS()); - } - - bool isZeroingPropIvar(PseudoObjectExpr *PO) { - BinaryOperator *BO = dyn_cast(PO->getSyntacticForm()); - if (!BO) return false; - if (BO->getOpcode() != BO_Assign) return false; - - ObjCPropertyRefExpr *PropRefExp = - dyn_cast(BO->getLHS()->IgnoreParens()); - if (!PropRefExp) return false; - - // TODO: Using implicit property decl. - if (PropRefExp->isImplicitProperty()) - return false; - - if (ObjCPropertyDecl *PDecl = PropRefExp->getExplicitProperty()) { - if (!SynthesizedProperties.count(PDecl)) - return false; - } - - return isZero(cast(BO->getRHS())->getSourceExpr()); - } - - bool isZero(Expr *E) { - if (E->isNullPointerConstant(Pass.Ctx, Expr::NPC_ValueDependentIsNull)) - return true; - - return isZeroingPropIvar(E); - } -}; - -} // anonymous namespace - -void trans::removeZeroOutPropsInDeallocFinalize(MigrationPass &pass) { - ZeroOutInDeallocRemover trans(pass); - trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransformActions.cpp b/clang/lib/ARCMigrate/TransformActions.cpp deleted file mode 100644 index 6bc6fed1a90320..00000000000000 --- a/clang/lib/ARCMigrate/TransformActions.cpp +++ /dev/null @@ -1,700 +0,0 @@ -//===-- TransformActions.cpp - Migration to ARC mode ----------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Expr.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Preprocessor.h" -#include "llvm/ADT/DenseSet.h" -#include -using namespace clang; -using namespace arcmt; - -namespace { - -/// Collects transformations and merges them before applying them with -/// with applyRewrites(). E.g. if the same source range -/// is requested to be removed twice, only one rewriter remove will be invoked. -/// Rewrites happen in "transactions"; if one rewrite in the transaction cannot -/// be done (e.g. it resides in a macro) all rewrites in the transaction are -/// aborted. -/// FIXME: "Transactional" rewrites support should be baked in the Rewriter. -class TransformActionsImpl { - CapturedDiagList &CapturedDiags; - ASTContext &Ctx; - Preprocessor &PP; - - bool IsInTransaction; - - enum ActionKind { - Act_Insert, Act_InsertAfterToken, - Act_Remove, Act_RemoveStmt, - Act_Replace, Act_ReplaceText, - Act_IncreaseIndentation, - Act_ClearDiagnostic - }; - - struct ActionData { - ActionKind Kind; - SourceLocation Loc; - SourceRange R1, R2; - StringRef Text1, Text2; - Stmt *S; - SmallVector DiagIDs; - }; - - std::vector CachedActions; - - enum RangeComparison { - Range_Before, - Range_After, - Range_Contains, - Range_Contained, - Range_ExtendsBegin, - Range_ExtendsEnd - }; - - /// A range to remove. It is a character range. - struct CharRange { - FullSourceLoc Begin, End; - - CharRange(CharSourceRange range, SourceManager &srcMgr, Preprocessor &PP) { - SourceLocation beginLoc = range.getBegin(), endLoc = range.getEnd(); - assert(beginLoc.isValid() && endLoc.isValid()); - if (range.isTokenRange()) { - Begin = FullSourceLoc(srcMgr.getExpansionLoc(beginLoc), srcMgr); - End = FullSourceLoc(getLocForEndOfToken(endLoc, srcMgr, PP), srcMgr); - } else { - Begin = FullSourceLoc(srcMgr.getExpansionLoc(beginLoc), srcMgr); - End = FullSourceLoc(srcMgr.getExpansionLoc(endLoc), srcMgr); - } - assert(Begin.isValid() && End.isValid()); - } - - RangeComparison compareWith(const CharRange &RHS) const { - if (End.isBeforeInTranslationUnitThan(RHS.Begin)) - return Range_Before; - if (RHS.End.isBeforeInTranslationUnitThan(Begin)) - return Range_After; - if (!Begin.isBeforeInTranslationUnitThan(RHS.Begin) && - !RHS.End.isBeforeInTranslationUnitThan(End)) - return Range_Contained; - if (Begin.isBeforeInTranslationUnitThan(RHS.Begin) && - RHS.End.isBeforeInTranslationUnitThan(End)) - return Range_Contains; - if (Begin.isBeforeInTranslationUnitThan(RHS.Begin)) - return Range_ExtendsBegin; - else - return Range_ExtendsEnd; - } - - static RangeComparison compare(SourceRange LHS, SourceRange RHS, - SourceManager &SrcMgr, Preprocessor &PP) { - return CharRange(CharSourceRange::getTokenRange(LHS), SrcMgr, PP) - .compareWith(CharRange(CharSourceRange::getTokenRange(RHS), - SrcMgr, PP)); - } - }; - - typedef SmallVector TextsVec; - typedef std::map - InsertsMap; - InsertsMap Inserts; - /// A list of ranges to remove. They are always sorted and they never - /// intersect with each other. - std::list Removals; - - llvm::DenseSet StmtRemovals; - - std::vector > IndentationRanges; - - /// Keeps text passed to transformation methods. - llvm::StringMap UniqueText; - -public: - TransformActionsImpl(CapturedDiagList &capturedDiags, - ASTContext &ctx, Preprocessor &PP) - : CapturedDiags(capturedDiags), Ctx(ctx), PP(PP), IsInTransaction(false) { } - - ASTContext &getASTContext() { return Ctx; } - - void startTransaction(); - bool commitTransaction(); - void abortTransaction(); - - bool isInTransaction() const { return IsInTransaction; } - - void insert(SourceLocation loc, StringRef text); - void insertAfterToken(SourceLocation loc, StringRef text); - void remove(SourceRange range); - void removeStmt(Stmt *S); - void replace(SourceRange range, StringRef text); - void replace(SourceRange range, SourceRange replacementRange); - void replaceStmt(Stmt *S, StringRef text); - void replaceText(SourceLocation loc, StringRef text, - StringRef replacementText); - void increaseIndentation(SourceRange range, - SourceLocation parentIndent); - - bool clearDiagnostic(ArrayRef IDs, SourceRange range); - - void applyRewrites(TransformActions::RewriteReceiver &receiver); - -private: - bool canInsert(SourceLocation loc); - bool canInsertAfterToken(SourceLocation loc); - bool canRemoveRange(SourceRange range); - bool canReplaceRange(SourceRange range, SourceRange replacementRange); - bool canReplaceText(SourceLocation loc, StringRef text); - - void commitInsert(SourceLocation loc, StringRef text); - void commitInsertAfterToken(SourceLocation loc, StringRef text); - void commitRemove(SourceRange range); - void commitRemoveStmt(Stmt *S); - void commitReplace(SourceRange range, SourceRange replacementRange); - void commitReplaceText(SourceLocation loc, StringRef text, - StringRef replacementText); - void commitIncreaseIndentation(SourceRange range,SourceLocation parentIndent); - void commitClearDiagnostic(ArrayRef IDs, SourceRange range); - - void addRemoval(CharSourceRange range); - void addInsertion(SourceLocation loc, StringRef text); - - /// Stores text passed to the transformation methods to keep the string - /// "alive". Since the vast majority of text will be the same, we also unique - /// the strings using a StringMap. - StringRef getUniqueText(StringRef text); - - /// Computes the source location just past the end of the token at - /// the given source location. If the location points at a macro, the whole - /// macro expansion is skipped. - static SourceLocation getLocForEndOfToken(SourceLocation loc, - SourceManager &SM,Preprocessor &PP); -}; - -} // anonymous namespace - -void TransformActionsImpl::startTransaction() { - assert(!IsInTransaction && - "Cannot start a transaction in the middle of another one"); - IsInTransaction = true; -} - -bool TransformActionsImpl::commitTransaction() { - assert(IsInTransaction && "No transaction started"); - - if (CachedActions.empty()) { - IsInTransaction = false; - return false; - } - - // Verify that all actions are possible otherwise abort the whole transaction. - bool AllActionsPossible = true; - for (unsigned i = 0, e = CachedActions.size(); i != e; ++i) { - ActionData &act = CachedActions[i]; - switch (act.Kind) { - case Act_Insert: - if (!canInsert(act.Loc)) - AllActionsPossible = false; - break; - case Act_InsertAfterToken: - if (!canInsertAfterToken(act.Loc)) - AllActionsPossible = false; - break; - case Act_Remove: - if (!canRemoveRange(act.R1)) - AllActionsPossible = false; - break; - case Act_RemoveStmt: - assert(act.S); - if (!canRemoveRange(act.S->getSourceRange())) - AllActionsPossible = false; - break; - case Act_Replace: - if (!canReplaceRange(act.R1, act.R2)) - AllActionsPossible = false; - break; - case Act_ReplaceText: - if (!canReplaceText(act.Loc, act.Text1)) - AllActionsPossible = false; - break; - case Act_IncreaseIndentation: - // This is not important, we don't care if it will fail. - break; - case Act_ClearDiagnostic: - // We are just checking source rewrites. - break; - } - if (!AllActionsPossible) - break; - } - - if (!AllActionsPossible) { - abortTransaction(); - return true; - } - - for (unsigned i = 0, e = CachedActions.size(); i != e; ++i) { - ActionData &act = CachedActions[i]; - switch (act.Kind) { - case Act_Insert: - commitInsert(act.Loc, act.Text1); - break; - case Act_InsertAfterToken: - commitInsertAfterToken(act.Loc, act.Text1); - break; - case Act_Remove: - commitRemove(act.R1); - break; - case Act_RemoveStmt: - commitRemoveStmt(act.S); - break; - case Act_Replace: - commitReplace(act.R1, act.R2); - break; - case Act_ReplaceText: - commitReplaceText(act.Loc, act.Text1, act.Text2); - break; - case Act_IncreaseIndentation: - commitIncreaseIndentation(act.R1, act.Loc); - break; - case Act_ClearDiagnostic: - commitClearDiagnostic(act.DiagIDs, act.R1); - break; - } - } - - CachedActions.clear(); - IsInTransaction = false; - return false; -} - -void TransformActionsImpl::abortTransaction() { - assert(IsInTransaction && "No transaction started"); - CachedActions.clear(); - IsInTransaction = false; -} - -void TransformActionsImpl::insert(SourceLocation loc, StringRef text) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - text = getUniqueText(text); - ActionData data; - data.Kind = Act_Insert; - data.Loc = loc; - data.Text1 = text; - CachedActions.push_back(data); -} - -void TransformActionsImpl::insertAfterToken(SourceLocation loc, StringRef text) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - text = getUniqueText(text); - ActionData data; - data.Kind = Act_InsertAfterToken; - data.Loc = loc; - data.Text1 = text; - CachedActions.push_back(data); -} - -void TransformActionsImpl::remove(SourceRange range) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - ActionData data; - data.Kind = Act_Remove; - data.R1 = range; - CachedActions.push_back(data); -} - -void TransformActionsImpl::removeStmt(Stmt *S) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - ActionData data; - data.Kind = Act_RemoveStmt; - if (auto *E = dyn_cast(S)) - S = E->IgnoreImplicit(); // important for uniquing - data.S = S; - CachedActions.push_back(data); -} - -void TransformActionsImpl::replace(SourceRange range, StringRef text) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - text = getUniqueText(text); - remove(range); - insert(range.getBegin(), text); -} - -void TransformActionsImpl::replace(SourceRange range, - SourceRange replacementRange) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - ActionData data; - data.Kind = Act_Replace; - data.R1 = range; - data.R2 = replacementRange; - CachedActions.push_back(data); -} - -void TransformActionsImpl::replaceText(SourceLocation loc, StringRef text, - StringRef replacementText) { - text = getUniqueText(text); - replacementText = getUniqueText(replacementText); - ActionData data; - data.Kind = Act_ReplaceText; - data.Loc = loc; - data.Text1 = text; - data.Text2 = replacementText; - CachedActions.push_back(data); -} - -void TransformActionsImpl::replaceStmt(Stmt *S, StringRef text) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - text = getUniqueText(text); - insert(S->getBeginLoc(), text); - removeStmt(S); -} - -void TransformActionsImpl::increaseIndentation(SourceRange range, - SourceLocation parentIndent) { - if (range.isInvalid()) return; - assert(IsInTransaction && "Actions only allowed during a transaction"); - ActionData data; - data.Kind = Act_IncreaseIndentation; - data.R1 = range; - data.Loc = parentIndent; - CachedActions.push_back(data); -} - -bool TransformActionsImpl::clearDiagnostic(ArrayRef IDs, - SourceRange range) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - if (!CapturedDiags.hasDiagnostic(IDs, range)) - return false; - - ActionData data; - data.Kind = Act_ClearDiagnostic; - data.R1 = range; - data.DiagIDs.append(IDs.begin(), IDs.end()); - CachedActions.push_back(data); - return true; -} - -bool TransformActionsImpl::canInsert(SourceLocation loc) { - if (loc.isInvalid()) - return false; - - SourceManager &SM = Ctx.getSourceManager(); - if (SM.isInSystemHeader(SM.getExpansionLoc(loc))) - return false; - - if (loc.isFileID()) - return true; - return PP.isAtStartOfMacroExpansion(loc); -} - -bool TransformActionsImpl::canInsertAfterToken(SourceLocation loc) { - if (loc.isInvalid()) - return false; - - SourceManager &SM = Ctx.getSourceManager(); - if (SM.isInSystemHeader(SM.getExpansionLoc(loc))) - return false; - - if (loc.isFileID()) - return true; - return PP.isAtEndOfMacroExpansion(loc); -} - -bool TransformActionsImpl::canRemoveRange(SourceRange range) { - return canInsert(range.getBegin()) && canInsertAfterToken(range.getEnd()); -} - -bool TransformActionsImpl::canReplaceRange(SourceRange range, - SourceRange replacementRange) { - return canRemoveRange(range) && canRemoveRange(replacementRange); -} - -bool TransformActionsImpl::canReplaceText(SourceLocation loc, StringRef text) { - if (!canInsert(loc)) - return false; - - SourceManager &SM = Ctx.getSourceManager(); - loc = SM.getExpansionLoc(loc); - - // Break down the source location. - std::pair locInfo = SM.getDecomposedLoc(loc); - - // Try to load the file buffer. - bool invalidTemp = false; - StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); - if (invalidTemp) - return false; - - return file.substr(locInfo.second).starts_with(text); -} - -void TransformActionsImpl::commitInsert(SourceLocation loc, StringRef text) { - addInsertion(loc, text); -} - -void TransformActionsImpl::commitInsertAfterToken(SourceLocation loc, - StringRef text) { - addInsertion(getLocForEndOfToken(loc, Ctx.getSourceManager(), PP), text); -} - -void TransformActionsImpl::commitRemove(SourceRange range) { - addRemoval(CharSourceRange::getTokenRange(range)); -} - -void TransformActionsImpl::commitRemoveStmt(Stmt *S) { - assert(S); - if (StmtRemovals.count(S)) - return; // already removed. - - if (Expr *E = dyn_cast(S)) { - commitRemove(E->getSourceRange()); - commitInsert(E->getSourceRange().getBegin(), getARCMTMacroName()); - } else - commitRemove(S->getSourceRange()); - - StmtRemovals.insert(S); -} - -void TransformActionsImpl::commitReplace(SourceRange range, - SourceRange replacementRange) { - RangeComparison comp = CharRange::compare(replacementRange, range, - Ctx.getSourceManager(), PP); - assert(comp == Range_Contained); - if (comp != Range_Contained) - return; // Although we asserted, be extra safe for release build. - if (range.getBegin() != replacementRange.getBegin()) - addRemoval(CharSourceRange::getCharRange(range.getBegin(), - replacementRange.getBegin())); - if (replacementRange.getEnd() != range.getEnd()) - addRemoval(CharSourceRange::getTokenRange( - getLocForEndOfToken(replacementRange.getEnd(), - Ctx.getSourceManager(), PP), - range.getEnd())); -} -void TransformActionsImpl::commitReplaceText(SourceLocation loc, - StringRef text, - StringRef replacementText) { - SourceManager &SM = Ctx.getSourceManager(); - loc = SM.getExpansionLoc(loc); - // canReplaceText already checked if loc points at text. - SourceLocation afterText = loc.getLocWithOffset(text.size()); - - addRemoval(CharSourceRange::getCharRange(loc, afterText)); - commitInsert(loc, replacementText); -} - -void TransformActionsImpl::commitIncreaseIndentation(SourceRange range, - SourceLocation parentIndent) { - SourceManager &SM = Ctx.getSourceManager(); - IndentationRanges.push_back( - std::make_pair(CharRange(CharSourceRange::getTokenRange(range), - SM, PP), - SM.getExpansionLoc(parentIndent))); -} - -void TransformActionsImpl::commitClearDiagnostic(ArrayRef IDs, - SourceRange range) { - CapturedDiags.clearDiagnostic(IDs, range); -} - -void TransformActionsImpl::addInsertion(SourceLocation loc, StringRef text) { - SourceManager &SM = Ctx.getSourceManager(); - loc = SM.getExpansionLoc(loc); - for (const CharRange &I : llvm::reverse(Removals)) { - if (!SM.isBeforeInTranslationUnit(loc, I.End)) - break; - if (I.Begin.isBeforeInTranslationUnitThan(loc)) - return; - } - - Inserts[FullSourceLoc(loc, SM)].push_back(text); -} - -void TransformActionsImpl::addRemoval(CharSourceRange range) { - CharRange newRange(range, Ctx.getSourceManager(), PP); - if (newRange.Begin == newRange.End) - return; - - Inserts.erase(Inserts.upper_bound(newRange.Begin), - Inserts.lower_bound(newRange.End)); - - std::list::iterator I = Removals.end(); - while (I != Removals.begin()) { - std::list::iterator RI = I; - --RI; - RangeComparison comp = newRange.compareWith(*RI); - switch (comp) { - case Range_Before: - --I; - break; - case Range_After: - Removals.insert(I, newRange); - return; - case Range_Contained: - return; - case Range_Contains: - RI->End = newRange.End; - [[fallthrough]]; - case Range_ExtendsBegin: - newRange.End = RI->End; - Removals.erase(RI); - break; - case Range_ExtendsEnd: - RI->End = newRange.End; - return; - } - } - - Removals.insert(Removals.begin(), newRange); -} - -void TransformActionsImpl::applyRewrites( - TransformActions::RewriteReceiver &receiver) { - for (InsertsMap::iterator I = Inserts.begin(), E = Inserts.end(); I!=E; ++I) { - SourceLocation loc = I->first; - for (TextsVec::iterator - TI = I->second.begin(), TE = I->second.end(); TI != TE; ++TI) { - receiver.insert(loc, *TI); - } - } - - for (std::vector >::iterator - I = IndentationRanges.begin(), E = IndentationRanges.end(); I!=E; ++I) { - CharSourceRange range = CharSourceRange::getCharRange(I->first.Begin, - I->first.End); - receiver.increaseIndentation(range, I->second); - } - - for (std::list::iterator - I = Removals.begin(), E = Removals.end(); I != E; ++I) { - CharSourceRange range = CharSourceRange::getCharRange(I->Begin, I->End); - receiver.remove(range); - } -} - -/// Stores text passed to the transformation methods to keep the string -/// "alive". Since the vast majority of text will be the same, we also unique -/// the strings using a StringMap. -StringRef TransformActionsImpl::getUniqueText(StringRef text) { - return UniqueText.insert(std::make_pair(text, false)).first->first(); -} - -/// Computes the source location just past the end of the token at -/// the given source location. If the location points at a macro, the whole -/// macro expansion is skipped. -SourceLocation TransformActionsImpl::getLocForEndOfToken(SourceLocation loc, - SourceManager &SM, - Preprocessor &PP) { - if (loc.isMacroID()) { - CharSourceRange Exp = SM.getExpansionRange(loc); - if (Exp.isCharRange()) - return Exp.getEnd(); - loc = Exp.getEnd(); - } - return PP.getLocForEndOfToken(loc); -} - -TransformActions::RewriteReceiver::~RewriteReceiver() { } - -TransformActions::TransformActions(DiagnosticsEngine &diag, - CapturedDiagList &capturedDiags, - ASTContext &ctx, Preprocessor &PP) - : Diags(diag), CapturedDiags(capturedDiags) { - Impl = new TransformActionsImpl(capturedDiags, ctx, PP); -} - -TransformActions::~TransformActions() { - delete static_cast(Impl); -} - -void TransformActions::startTransaction() { - static_cast(Impl)->startTransaction(); -} - -bool TransformActions::commitTransaction() { - return static_cast(Impl)->commitTransaction(); -} - -void TransformActions::abortTransaction() { - static_cast(Impl)->abortTransaction(); -} - - -void TransformActions::insert(SourceLocation loc, StringRef text) { - static_cast(Impl)->insert(loc, text); -} - -void TransformActions::insertAfterToken(SourceLocation loc, - StringRef text) { - static_cast(Impl)->insertAfterToken(loc, text); -} - -void TransformActions::remove(SourceRange range) { - static_cast(Impl)->remove(range); -} - -void TransformActions::removeStmt(Stmt *S) { - static_cast(Impl)->removeStmt(S); -} - -void TransformActions::replace(SourceRange range, StringRef text) { - static_cast(Impl)->replace(range, text); -} - -void TransformActions::replace(SourceRange range, - SourceRange replacementRange) { - static_cast(Impl)->replace(range, replacementRange); -} - -void TransformActions::replaceStmt(Stmt *S, StringRef text) { - static_cast(Impl)->replaceStmt(S, text); -} - -void TransformActions::replaceText(SourceLocation loc, StringRef text, - StringRef replacementText) { - static_cast(Impl)->replaceText(loc, text, - replacementText); -} - -void TransformActions::increaseIndentation(SourceRange range, - SourceLocation parentIndent) { - static_cast(Impl)->increaseIndentation(range, - parentIndent); -} - -bool TransformActions::clearDiagnostic(ArrayRef IDs, - SourceRange range) { - return static_cast(Impl)->clearDiagnostic(IDs, range); -} - -void TransformActions::applyRewrites(RewriteReceiver &receiver) { - static_cast(Impl)->applyRewrites(receiver); -} - -DiagnosticBuilder TransformActions::report(SourceLocation loc, unsigned diagId, - SourceRange range) { - assert(!static_cast(Impl)->isInTransaction() && - "Errors should be emitted out of a transaction"); - return Diags.Report(loc, diagId) << range; -} - -void TransformActions::reportError(StringRef message, SourceLocation loc, - SourceRange range) { - report(loc, diag::err_mt_message, range) << message; -} - -void TransformActions::reportWarning(StringRef message, SourceLocation loc, - SourceRange range) { - report(loc, diag::warn_mt_message, range) << message; -} - -void TransformActions::reportNote(StringRef message, SourceLocation loc, - SourceRange range) { - report(loc, diag::note_mt_message, range) << message; -} diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp deleted file mode 100644 index fda0e1c932fc0e..00000000000000 --- a/clang/lib/ARCMigrate/Transforms.cpp +++ /dev/null @@ -1,594 +0,0 @@ -//===--- Transforms.cpp - Transformations to ARC mode ---------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/ARCMigrate/ARCMT.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/Analysis/DomainSpecific/CocoaConventions.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Lex/Lexer.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Sema/Sema.h" -#include "clang/Sema/SemaObjC.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -ASTTraverser::~ASTTraverser() { } - -bool MigrationPass::CFBridgingFunctionsDefined() { - if (!EnableCFBridgeFns) - EnableCFBridgeFns = SemaRef.ObjC().isKnownName("CFBridgingRetain") && - SemaRef.ObjC().isKnownName("CFBridgingRelease"); - return *EnableCFBridgeFns; -} - -//===----------------------------------------------------------------------===// -// Helpers. -//===----------------------------------------------------------------------===// - -bool trans::canApplyWeak(ASTContext &Ctx, QualType type, - bool AllowOnUnknownClass) { - if (!Ctx.getLangOpts().ObjCWeakRuntime) - return false; - - QualType T = type; - if (T.isNull()) - return false; - - // iOS is always safe to use 'weak'. - if (Ctx.getTargetInfo().getTriple().isiOS() || - Ctx.getTargetInfo().getTriple().isWatchOS()) - AllowOnUnknownClass = true; - - while (const PointerType *ptr = T->getAs()) - T = ptr->getPointeeType(); - if (const ObjCObjectPointerType *ObjT = T->getAs()) { - ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl(); - if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject")) - return false; // id/NSObject is not safe for weak. - if (!AllowOnUnknownClass && !Class->hasDefinition()) - return false; // forward classes are not verifiable, therefore not safe. - if (Class && Class->isArcWeakrefUnavailable()) - return false; - } - - return true; -} - -bool trans::isPlusOneAssign(const BinaryOperator *E) { - if (E->getOpcode() != BO_Assign) - return false; - - return isPlusOne(E->getRHS()); -} - -bool trans::isPlusOne(const Expr *E) { - if (!E) - return false; - if (const FullExpr *FE = dyn_cast(E)) - E = FE->getSubExpr(); - - if (const ObjCMessageExpr * - ME = dyn_cast(E->IgnoreParenCasts())) - if (ME->getMethodFamily() == OMF_retain) - return true; - - if (const CallExpr * - callE = dyn_cast(E->IgnoreParenCasts())) { - if (const FunctionDecl *FD = callE->getDirectCallee()) { - if (FD->hasAttr()) - return true; - - if (FD->isGlobal() && - FD->getIdentifier() && - FD->getParent()->isTranslationUnit() && - FD->isExternallyVisible() && - ento::cocoa::isRefType(callE->getType(), "CF", - FD->getIdentifier()->getName())) { - StringRef fname = FD->getIdentifier()->getName(); - if (fname.ends_with("Retain") || fname.contains("Create") || - fname.contains("Copy")) - return true; - } - } - } - - const ImplicitCastExpr *implCE = dyn_cast(E); - while (implCE && implCE->getCastKind() == CK_BitCast) - implCE = dyn_cast(implCE->getSubExpr()); - - return implCE && implCE->getCastKind() == CK_ARCConsumeObject; -} - -/// 'Loc' is the end of a statement range. This returns the location -/// immediately after the semicolon following the statement. -/// If no semicolon is found or the location is inside a macro, the returned -/// source location will be invalid. -SourceLocation trans::findLocationAfterSemi(SourceLocation loc, - ASTContext &Ctx, bool IsDecl) { - SourceLocation SemiLoc = findSemiAfterLocation(loc, Ctx, IsDecl); - if (SemiLoc.isInvalid()) - return SourceLocation(); - return SemiLoc.getLocWithOffset(1); -} - -/// \arg Loc is the end of a statement range. This returns the location -/// of the semicolon following the statement. -/// If no semicolon is found or the location is inside a macro, the returned -/// source location will be invalid. -SourceLocation trans::findSemiAfterLocation(SourceLocation loc, - ASTContext &Ctx, - bool IsDecl) { - SourceManager &SM = Ctx.getSourceManager(); - if (loc.isMacroID()) { - if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOpts(), &loc)) - return SourceLocation(); - } - loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOpts()); - - // Break down the source location. - std::pair locInfo = SM.getDecomposedLoc(loc); - - // Try to load the file buffer. - bool invalidTemp = false; - StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); - if (invalidTemp) - return SourceLocation(); - - const char *tokenBegin = file.data() + locInfo.second; - - // Lex from the start of the given location. - Lexer lexer(SM.getLocForStartOfFile(locInfo.first), - Ctx.getLangOpts(), - file.begin(), tokenBegin, file.end()); - Token tok; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::semi)) { - if (!IsDecl) - return SourceLocation(); - // Declaration may be followed with other tokens; such as an __attribute, - // before ending with a semicolon. - return findSemiAfterLocation(tok.getLocation(), Ctx, /*IsDecl*/true); - } - - return tok.getLocation(); -} - -bool trans::hasSideEffects(Expr *E, ASTContext &Ctx) { - if (!E || !E->HasSideEffects(Ctx)) - return false; - - E = E->IgnoreParenCasts(); - ObjCMessageExpr *ME = dyn_cast(E); - if (!ME) - return true; - switch (ME->getMethodFamily()) { - case OMF_autorelease: - case OMF_dealloc: - case OMF_release: - case OMF_retain: - switch (ME->getReceiverKind()) { - case ObjCMessageExpr::SuperInstance: - return false; - case ObjCMessageExpr::Instance: - return hasSideEffects(ME->getInstanceReceiver(), Ctx); - default: - break; - } - break; - default: - break; - } - - return true; -} - -bool trans::isGlobalVar(Expr *E) { - E = E->IgnoreParenCasts(); - if (DeclRefExpr *DRE = dyn_cast(E)) - return DRE->getDecl()->getDeclContext()->isFileContext() && - DRE->getDecl()->isExternallyVisible(); - if (ConditionalOperator *condOp = dyn_cast(E)) - return isGlobalVar(condOp->getTrueExpr()) && - isGlobalVar(condOp->getFalseExpr()); - - return false; -} - -StringRef trans::getNilString(MigrationPass &Pass) { - return Pass.SemaRef.PP.isMacroDefined("nil") ? "nil" : "0"; -} - -namespace { - -class ReferenceClear : public RecursiveASTVisitor { - ExprSet &Refs; -public: - ReferenceClear(ExprSet &refs) : Refs(refs) { } - bool VisitDeclRefExpr(DeclRefExpr *E) { Refs.erase(E); return true; } -}; - -class ReferenceCollector : public RecursiveASTVisitor { - ValueDecl *Dcl; - ExprSet &Refs; - -public: - ReferenceCollector(ValueDecl *D, ExprSet &refs) - : Dcl(D), Refs(refs) { } - - bool VisitDeclRefExpr(DeclRefExpr *E) { - if (E->getDecl() == Dcl) - Refs.insert(E); - return true; - } -}; - -class RemovablesCollector : public RecursiveASTVisitor { - ExprSet &Removables; - -public: - RemovablesCollector(ExprSet &removables) - : Removables(removables) { } - - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool TraverseStmtExpr(StmtExpr *E) { - CompoundStmt *S = E->getSubStmt(); - for (CompoundStmt::body_iterator - I = S->body_begin(), E = S->body_end(); I != E; ++I) { - if (I != E - 1) - mark(*I); - TraverseStmt(*I); - } - return true; - } - - bool VisitCompoundStmt(CompoundStmt *S) { - for (auto *I : S->body()) - mark(I); - return true; - } - - bool VisitIfStmt(IfStmt *S) { - mark(S->getThen()); - mark(S->getElse()); - return true; - } - - bool VisitWhileStmt(WhileStmt *S) { - mark(S->getBody()); - return true; - } - - bool VisitDoStmt(DoStmt *S) { - mark(S->getBody()); - return true; - } - - bool VisitForStmt(ForStmt *S) { - mark(S->getInit()); - mark(S->getInc()); - mark(S->getBody()); - return true; - } - -private: - void mark(Stmt *S) { - if (!S) return; - - while (auto *Label = dyn_cast(S)) - S = Label->getSubStmt(); - if (auto *E = dyn_cast(S)) - S = E->IgnoreImplicit(); - if (auto *E = dyn_cast(S)) - Removables.insert(E); - } -}; - -} // end anonymous namespace - -void trans::clearRefsIn(Stmt *S, ExprSet &refs) { - ReferenceClear(refs).TraverseStmt(S); -} - -void trans::collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs) { - ReferenceCollector(D, refs).TraverseStmt(S); -} - -void trans::collectRemovables(Stmt *S, ExprSet &exprs) { - RemovablesCollector(exprs).TraverseStmt(S); -} - -//===----------------------------------------------------------------------===// -// MigrationContext -//===----------------------------------------------------------------------===// - -namespace { - -class ASTTransform : public RecursiveASTVisitor { - MigrationContext &MigrateCtx; - typedef RecursiveASTVisitor base; - -public: - ASTTransform(MigrationContext &MigrateCtx) : MigrateCtx(MigrateCtx) { } - - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) { - ObjCImplementationContext ImplCtx(MigrateCtx, D); - for (MigrationContext::traverser_iterator - I = MigrateCtx.traversers_begin(), - E = MigrateCtx.traversers_end(); I != E; ++I) - (*I)->traverseObjCImplementation(ImplCtx); - - return base::TraverseObjCImplementationDecl(D); - } - - bool TraverseStmt(Stmt *rootS) { - if (!rootS) - return true; - - BodyContext BodyCtx(MigrateCtx, rootS); - for (MigrationContext::traverser_iterator - I = MigrateCtx.traversers_begin(), - E = MigrateCtx.traversers_end(); I != E; ++I) - (*I)->traverseBody(BodyCtx); - - return true; - } -}; - -} - -MigrationContext::~MigrationContext() { - for (traverser_iterator - I = traversers_begin(), E = traversers_end(); I != E; ++I) - delete *I; -} - -bool MigrationContext::isGCOwnedNonObjC(QualType T) { - while (!T.isNull()) { - if (const AttributedType *AttrT = T->getAs()) { - if (AttrT->getAttrKind() == attr::ObjCOwnership) - return !AttrT->getModifiedType()->isObjCRetainableType(); - } - - if (T->isArrayType()) - T = Pass.Ctx.getBaseElementType(T); - else if (const PointerType *PT = T->getAs()) - T = PT->getPointeeType(); - else if (const ReferenceType *RT = T->getAs()) - T = RT->getPointeeType(); - else - break; - } - - return false; -} - -bool MigrationContext::rewritePropertyAttribute(StringRef fromAttr, - StringRef toAttr, - SourceLocation atLoc) { - if (atLoc.isMacroID()) - return false; - - SourceManager &SM = Pass.Ctx.getSourceManager(); - - // Break down the source location. - std::pair locInfo = SM.getDecomposedLoc(atLoc); - - // Try to load the file buffer. - bool invalidTemp = false; - StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); - if (invalidTemp) - return false; - - const char *tokenBegin = file.data() + locInfo.second; - - // Lex from the start of the given location. - Lexer lexer(SM.getLocForStartOfFile(locInfo.first), - Pass.Ctx.getLangOpts(), - file.begin(), tokenBegin, file.end()); - Token tok; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::at)) return false; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::raw_identifier)) return false; - if (tok.getRawIdentifier() != "property") - return false; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::l_paren)) return false; - - Token BeforeTok = tok; - Token AfterTok; - AfterTok.startToken(); - SourceLocation AttrLoc; - - lexer.LexFromRawLexer(tok); - if (tok.is(tok::r_paren)) - return false; - - while (true) { - if (tok.isNot(tok::raw_identifier)) return false; - if (tok.getRawIdentifier() == fromAttr) { - if (!toAttr.empty()) { - Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr); - return true; - } - // We want to remove the attribute. - AttrLoc = tok.getLocation(); - } - - do { - lexer.LexFromRawLexer(tok); - if (AttrLoc.isValid() && AfterTok.is(tok::unknown)) - AfterTok = tok; - } while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren)); - if (tok.is(tok::r_paren)) - break; - if (AttrLoc.isInvalid()) - BeforeTok = tok; - lexer.LexFromRawLexer(tok); - } - - if (toAttr.empty() && AttrLoc.isValid() && AfterTok.isNot(tok::unknown)) { - // We want to remove the attribute. - if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::r_paren)) { - Pass.TA.remove(SourceRange(BeforeTok.getLocation(), - AfterTok.getLocation())); - } else if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::comma)) { - Pass.TA.remove(SourceRange(AttrLoc, AfterTok.getLocation())); - } else { - Pass.TA.remove(SourceRange(BeforeTok.getLocation(), AttrLoc)); - } - - return true; - } - - return false; -} - -bool MigrationContext::addPropertyAttribute(StringRef attr, - SourceLocation atLoc) { - if (atLoc.isMacroID()) - return false; - - SourceManager &SM = Pass.Ctx.getSourceManager(); - - // Break down the source location. - std::pair locInfo = SM.getDecomposedLoc(atLoc); - - // Try to load the file buffer. - bool invalidTemp = false; - StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); - if (invalidTemp) - return false; - - const char *tokenBegin = file.data() + locInfo.second; - - // Lex from the start of the given location. - Lexer lexer(SM.getLocForStartOfFile(locInfo.first), - Pass.Ctx.getLangOpts(), - file.begin(), tokenBegin, file.end()); - Token tok; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::at)) return false; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::raw_identifier)) return false; - if (tok.getRawIdentifier() != "property") - return false; - lexer.LexFromRawLexer(tok); - - if (tok.isNot(tok::l_paren)) { - Pass.TA.insert(tok.getLocation(), std::string("(") + attr.str() + ") "); - return true; - } - - lexer.LexFromRawLexer(tok); - if (tok.is(tok::r_paren)) { - Pass.TA.insert(tok.getLocation(), attr); - return true; - } - - if (tok.isNot(tok::raw_identifier)) return false; - - Pass.TA.insert(tok.getLocation(), std::string(attr) + ", "); - return true; -} - -void MigrationContext::traverse(TranslationUnitDecl *TU) { - for (traverser_iterator - I = traversers_begin(), E = traversers_end(); I != E; ++I) - (*I)->traverseTU(*this); - - ASTTransform(*this).TraverseDecl(TU); -} - -static void GCRewriteFinalize(MigrationPass &pass) { - ASTContext &Ctx = pass.Ctx; - TransformActions &TA = pass.TA; - DeclContext *DC = Ctx.getTranslationUnitDecl(); - Selector FinalizeSel = - Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); - - typedef DeclContext::specific_decl_iterator - impl_iterator; - for (impl_iterator I = impl_iterator(DC->decls_begin()), - E = impl_iterator(DC->decls_end()); I != E; ++I) { - for (const auto *MD : I->instance_methods()) { - if (!MD->hasBody()) - continue; - - if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { - const ObjCMethodDecl *FinalizeM = MD; - Transaction Trans(TA); - TA.insert(FinalizeM->getSourceRange().getBegin(), - "#if !__has_feature(objc_arc)\n"); - CharSourceRange::getTokenRange(FinalizeM->getSourceRange()); - const SourceManager &SM = pass.Ctx.getSourceManager(); - const LangOptions &LangOpts = pass.Ctx.getLangOpts(); - bool Invalid; - std::string str = "\n#endif\n"; - str += Lexer::getSourceText( - CharSourceRange::getTokenRange(FinalizeM->getSourceRange()), - SM, LangOpts, &Invalid); - TA.insertAfterToken(FinalizeM->getSourceRange().getEnd(), str); - - break; - } - } - } -} - -//===----------------------------------------------------------------------===// -// getAllTransformations. -//===----------------------------------------------------------------------===// - -static void traverseAST(MigrationPass &pass) { - MigrationContext MigrateCtx(pass); - - if (pass.isGCMigration()) { - MigrateCtx.addTraverser(new GCCollectableCallsTraverser); - MigrateCtx.addTraverser(new GCAttrsTraverser()); - } - MigrateCtx.addTraverser(new PropertyRewriteTraverser()); - MigrateCtx.addTraverser(new BlockObjCVariableTraverser()); - MigrateCtx.addTraverser(new ProtectedScopeTraverser()); - - MigrateCtx.traverse(pass.Ctx.getTranslationUnitDecl()); -} - -static void independentTransforms(MigrationPass &pass) { - rewriteAutoreleasePool(pass); - removeRetainReleaseDeallocFinalize(pass); - rewriteUnusedInitDelegate(pass); - removeZeroOutPropsInDeallocFinalize(pass); - makeAssignARCSafe(pass); - rewriteUnbridgedCasts(pass); - checkAPIUses(pass); - traverseAST(pass); -} - -std::vector arcmt::getAllTransformations( - LangOptions::GCMode OrigGCMode, - bool NoFinalizeRemoval) { - std::vector transforms; - - if (OrigGCMode == LangOptions::GCOnly && NoFinalizeRemoval) - transforms.push_back(GCRewriteFinalize); - transforms.push_back(independentTransforms); - // This depends on previous transformations removing various expressions. - transforms.push_back(removeEmptyStatementsAndDeallocFinalize); - - return transforms; -} diff --git a/clang/lib/ARCMigrate/Transforms.h b/clang/lib/ARCMigrate/Transforms.h deleted file mode 100644 index 37e2d6b2a7e12f..00000000000000 --- a/clang/lib/ARCMigrate/Transforms.h +++ /dev/null @@ -1,224 +0,0 @@ -//===-- Transforms.h - Transformations to ARC mode --------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H -#define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H - -#include "clang/AST/ParentMap.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/Support/SaveAndRestore.h" - -namespace clang { - class Decl; - class Stmt; - class BlockDecl; - class ObjCMethodDecl; - class FunctionDecl; - -namespace arcmt { - class MigrationPass; - -namespace trans { - - class MigrationContext; - -//===----------------------------------------------------------------------===// -// Transformations. -//===----------------------------------------------------------------------===// - -void rewriteAutoreleasePool(MigrationPass &pass); -void rewriteUnbridgedCasts(MigrationPass &pass); -void makeAssignARCSafe(MigrationPass &pass); -void removeRetainReleaseDeallocFinalize(MigrationPass &pass); -void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass); -void rewriteUnusedInitDelegate(MigrationPass &pass); -void checkAPIUses(MigrationPass &pass); - -void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass); - -class BodyContext { - MigrationContext &MigrateCtx; - ParentMap PMap; - Stmt *TopStmt; - -public: - BodyContext(MigrationContext &MigrateCtx, Stmt *S) - : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {} - - MigrationContext &getMigrationContext() { return MigrateCtx; } - ParentMap &getParentMap() { return PMap; } - Stmt *getTopStmt() { return TopStmt; } -}; - -class ObjCImplementationContext { - MigrationContext &MigrateCtx; - ObjCImplementationDecl *ImpD; - -public: - ObjCImplementationContext(MigrationContext &MigrateCtx, - ObjCImplementationDecl *D) - : MigrateCtx(MigrateCtx), ImpD(D) {} - - MigrationContext &getMigrationContext() { return MigrateCtx; } - ObjCImplementationDecl *getImplementationDecl() { return ImpD; } -}; - -class ASTTraverser { -public: - virtual ~ASTTraverser(); - virtual void traverseTU(MigrationContext &MigrateCtx) { } - virtual void traverseBody(BodyContext &BodyCtx) { } - virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) {} -}; - -class MigrationContext { - std::vector Traversers; - -public: - MigrationPass &Pass; - - struct GCAttrOccurrence { - enum AttrKind { Weak, Strong } Kind; - SourceLocation Loc; - QualType ModifiedType; - Decl *Dcl; - /// true if the attribute is owned, e.g. it is in a body and not just - /// in an interface. - bool FullyMigratable; - }; - std::vector GCAttrs; - llvm::DenseSet AttrSet; - llvm::DenseSet RemovedAttrSet; - - /// Set of raw '@' locations for 'assign' properties group that contain - /// GC __weak. - llvm::DenseSet AtPropsWeak; - - explicit MigrationContext(MigrationPass &pass) : Pass(pass) {} - ~MigrationContext(); - - typedef std::vector::iterator traverser_iterator; - traverser_iterator traversers_begin() { return Traversers.begin(); } - traverser_iterator traversers_end() { return Traversers.end(); } - - void addTraverser(ASTTraverser *traverser) { - Traversers.push_back(traverser); - } - - bool isGCOwnedNonObjC(QualType T); - bool removePropertyAttribute(StringRef fromAttr, SourceLocation atLoc) { - return rewritePropertyAttribute(fromAttr, StringRef(), atLoc); - } - bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr, - SourceLocation atLoc); - bool addPropertyAttribute(StringRef attr, SourceLocation atLoc); - - void traverse(TranslationUnitDecl *TU); - - void dumpGCAttrs(); -}; - -class PropertyRewriteTraverser : public ASTTraverser { -public: - void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) override; -}; - -class BlockObjCVariableTraverser : public ASTTraverser { -public: - void traverseBody(BodyContext &BodyCtx) override; -}; - -class ProtectedScopeTraverser : public ASTTraverser { -public: - void traverseBody(BodyContext &BodyCtx) override; -}; - -// GC transformations - -class GCAttrsTraverser : public ASTTraverser { -public: - void traverseTU(MigrationContext &MigrateCtx) override; -}; - -class GCCollectableCallsTraverser : public ASTTraverser { -public: - void traverseBody(BodyContext &BodyCtx) override; -}; - -//===----------------------------------------------------------------------===// -// Helpers. -//===----------------------------------------------------------------------===// - -/// Determine whether we can add weak to the given type. -bool canApplyWeak(ASTContext &Ctx, QualType type, - bool AllowOnUnknownClass = false); - -bool isPlusOneAssign(const BinaryOperator *E); -bool isPlusOne(const Expr *E); - -/// 'Loc' is the end of a statement range. This returns the location -/// immediately after the semicolon following the statement. -/// If no semicolon is found or the location is inside a macro, the returned -/// source location will be invalid. -SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx, - bool IsDecl = false); - -/// 'Loc' is the end of a statement range. This returns the location -/// of the semicolon following the statement. -/// If no semicolon is found or the location is inside a macro, the returned -/// source location will be invalid. -SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx, - bool IsDecl = false); - -bool hasSideEffects(Expr *E, ASTContext &Ctx); -bool isGlobalVar(Expr *E); -/// Returns "nil" or "0" if 'nil' macro is not actually defined. -StringRef getNilString(MigrationPass &Pass); - -template -class BodyTransform : public RecursiveASTVisitor > { - MigrationPass &Pass; - Decl *ParentD; - - typedef RecursiveASTVisitor > base; -public: - BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(nullptr) { } - - bool TraverseStmt(Stmt *rootS) { - if (rootS) - BODY_TRANS(Pass).transformBody(rootS, ParentD); - return true; - } - - bool TraverseObjCMethodDecl(ObjCMethodDecl *D) { - SaveAndRestore SetParent(ParentD, D); - return base::TraverseObjCMethodDecl(D); - } -}; - -typedef llvm::DenseSet ExprSet; - -void clearRefsIn(Stmt *S, ExprSet &refs); -template -void clearRefsIn(iterator begin, iterator end, ExprSet &refs) { - for (; begin != end; ++begin) - clearRefsIn(*begin, refs); -} - -void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs); - -void collectRemovables(Stmt *S, ExprSet &exprs); - -} // end namespace trans - -} // end namespace arcmt - -} // end namespace clang - -#endif diff --git a/clang/lib/CMakeLists.txt b/clang/lib/CMakeLists.txt index 14ba55360fe050..4f2218b583e414 100644 --- a/clang/lib/CMakeLists.txt +++ b/clang/lib/CMakeLists.txt @@ -12,9 +12,6 @@ add_subdirectory(Analysis) add_subdirectory(Edit) add_subdirectory(ExtractAPI) add_subdirectory(Rewrite) -if(CLANG_ENABLE_ARCMT) - add_subdirectory(ARCMigrate) -endif() add_subdirectory(Driver) add_subdirectory(Serialization) add_subdirectory(Frontend) diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp index 849bf6035ebd2e..77ce5db106d621 100644 --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -27,8 +27,8 @@ const char *Action::getClassName(ActionClass AC) { case PrecompileJobClass: return "precompiler"; case ExtractAPIJobClass: return "api-extractor"; - case AnalyzeJobClass: return "analyzer"; - case MigrateJobClass: return "migrator"; + case AnalyzeJobClass: + return "analyzer"; case CompileJobClass: return "compiler"; case BackendJobClass: return "backend"; case AssembleJobClass: return "assembler"; @@ -367,11 +367,6 @@ void AnalyzeJobAction::anchor() {} AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType) : JobAction(AnalyzeJobClass, Input, OutputType) {} -void MigrateJobAction::anchor() {} - -MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType) - : JobAction(MigrateJobClass, Input, OutputType) {} - void CompileJobAction::anchor() {} CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 7de8341b8d2d61..231187c0371436 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -366,12 +366,12 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler. } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || - (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) || + (PhaseArg = + DAL.getLastArg(options::OPT_print_enabled_extensions)) || (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) || - (PhaseArg = DAL.getLastArg(options::OPT__migrate)) || (PhaseArg = DAL.getLastArg(options::OPT__analyze)) || (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) || (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) { @@ -4856,8 +4856,6 @@ Action *Driver::ConstructPhaseAction( types::TY_RewrittenLegacyObjC); if (Args.hasArg(options::OPT__analyze)) return C.MakeAction(Input, types::TY_Plist); - if (Args.hasArg(options::OPT__migrate)) - return C.MakeAction(Input, types::TY_Remap); if (Args.hasArg(options::OPT_emit_ast)) return C.MakeAction(Input, types::TY_AST); if (Args.hasArg(options::OPT_emit_cir)) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 0d426a467e9a3b..a56f145df4d128 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -634,7 +634,6 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { case Action::PreprocessJobClass: case Action::ExtractAPIJobClass: case Action::AnalyzeJobClass: - case Action::MigrateJobClass: case Action::VerifyPCHJobClass: case Action::BackendJobClass: return getClang(); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 7ef55a33547c50..0be6b23fe7ca54 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3938,78 +3938,6 @@ static void RenderOpenACCOptions(const Driver &D, const ArgList &Args, } } -static void RenderARCMigrateToolOptions(const Driver &D, const ArgList &Args, - ArgStringList &CmdArgs) { - bool ARCMTEnabled = false; - if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) { - if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check, - options::OPT_ccc_arcmt_modify, - options::OPT_ccc_arcmt_migrate)) { - ARCMTEnabled = true; - switch (A->getOption().getID()) { - default: llvm_unreachable("missed a case"); - case options::OPT_ccc_arcmt_check: - CmdArgs.push_back("-arcmt-action=check"); - break; - case options::OPT_ccc_arcmt_modify: - CmdArgs.push_back("-arcmt-action=modify"); - break; - case options::OPT_ccc_arcmt_migrate: - CmdArgs.push_back("-arcmt-action=migrate"); - CmdArgs.push_back("-mt-migrate-directory"); - CmdArgs.push_back(A->getValue()); - - Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output); - Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors); - break; - } - } - } else { - Args.ClaimAllArgs(options::OPT_ccc_arcmt_check); - Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify); - Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate); - } - - if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) { - if (ARCMTEnabled) - D.Diag(diag::err_drv_argument_not_allowed_with) - << A->getAsString(Args) << "-ccc-arcmt-migrate"; - - CmdArgs.push_back("-mt-migrate-directory"); - CmdArgs.push_back(A->getValue()); - - if (!Args.hasArg(options::OPT_objcmt_migrate_literals, - options::OPT_objcmt_migrate_subscripting, - options::OPT_objcmt_migrate_property)) { - // None specified, means enable them all. - CmdArgs.push_back("-objcmt-migrate-literals"); - CmdArgs.push_back("-objcmt-migrate-subscripting"); - CmdArgs.push_back("-objcmt-migrate-property"); - } else { - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property); - } - } else { - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property_dot_syntax); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_designated_init); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_allowlist_dir_path); - } -} - static void RenderBuiltinOptions(const ToolChain &TC, const llvm::Triple &T, const ArgList &Args, ArgStringList &CmdArgs) { // -fbuiltin is default unless -mkernel is used. @@ -5271,8 +5199,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (isa(JA)) { assert(JA.getType() == types::TY_Plist && "Invalid output type."); CmdArgs.push_back("-analyze"); - } else if (isa(JA)) { - CmdArgs.push_back("-migrate"); } else if (isa(JA)) { if (Output.getType() == types::TY_Dependencies) CmdArgs.push_back("-Eonly"); @@ -6397,8 +6323,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_working_directory); - RenderARCMigrateToolOptions(D, Args, CmdArgs); - // Add preprocessing options like -I, -D, etc. if we are using the // preprocessor. // diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 87380869f6fdab..4b3cacaa513c5c 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -584,20 +584,6 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, // more information. ArgStringList CmdArgs; - /// Hack(tm) to ignore linking errors when we are doing ARC migration. - if (Args.hasArg(options::OPT_ccc_arcmt_check, - options::OPT_ccc_arcmt_migrate)) { - for (const auto &Arg : Args) - Arg->claim(); - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("touch")); - CmdArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique(JA, *this, - ResponseFileSupport::None(), Exec, - CmdArgs, std::nullopt, Output)); - return; - } - VersionTuple Version = getMachOToolChain().getLinkerVersion(Args); bool LinkerIsLLD; diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index fbfc305ca06a04..a45458f96bb30a 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1031,10 +1031,6 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { if (!createTarget()) return false; - // rewriter project will change target built-in bool type from its default. - if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) - getTarget().noSignedCharForObjCBool(); - // Validate/process some options. if (getHeaderSearchOpts().Verbose) OS << "clang -cc1 version " CLANG_VERSION_STRING << " based upon LLVM " diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 98136b7a455d9c..3d3726294dfc58 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2685,10 +2685,8 @@ static const auto &getFrontendActionTable() { {frontend::PrintPreprocessedInput, OPT_E}, {frontend::TemplightDump, OPT_templight_dump}, {frontend::RewriteMacros, OPT_rewrite_macros}, - {frontend::RewriteObjC, OPT_rewrite_objc}, {frontend::RewriteTest, OPT_rewrite_test}, {frontend::RunAnalysis, OPT_analyze}, - {frontend::MigrateSource, OPT_migrate}, {frontend::RunPreprocessorOnly, OPT_Eonly}, {frontend::PrintDependencyDirectivesSourceMinimizerOutput, OPT_print_dependency_directives_minimized_source}, @@ -3031,12 +3029,6 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, if (Args.hasArg(OPT_aux_target_feature)) Opts.AuxTargetFeatures = Args.getAllArgValues(OPT_aux_target_feature); - if (Opts.ARCMTAction != FrontendOptions::ARCMT_None && - Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) { - Diags.Report(diag::err_drv_argument_not_allowed_with) - << "ARC migration" << "ObjC migration"; - } - InputKind DashX(Language::Unknown); if (const Arg *A = Args.getLastArg(OPT_x)) { StringRef XValue = A->getValue(); @@ -4561,11 +4553,9 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::ModuleFileInfo: case frontend::VerifyPCH: case frontend::PluginAction: - case frontend::RewriteObjC: case frontend::RewriteTest: case frontend::RunAnalysis: case frontend::TemplightDump: - case frontend::MigrateSource: return false; case frontend::DumpCompilerOptions: @@ -4895,9 +4885,6 @@ bool CompilerInvocation::CreateFromArgsImpl( ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes, Diags); - if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC) - LangOpts.ObjCExceptions = 1; - for (auto Warning : Res.getDiagnosticOpts().Warnings) { if (Warning == "misexpect" && !Diags.isIgnored(diag::warn_profile_data_misexpect, SourceLocation())) { diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index e20feedb840b51..233b064e6ac880 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1409,8 +1409,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (LangOpts.FastRelaxedMath) Builder.defineMacro("__FAST_RELAXED_MATH__"); - if (FEOpts.ProgramAction == frontend::RewriteObjC || - LangOpts.getGC() != LangOptions::NonGC) { + if (LangOpts.getGC() != LangOptions::NonGC) { Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))"); Builder.defineMacro("__autoreleasing", ""); diff --git a/clang/lib/Frontend/Rewrite/CMakeLists.txt b/clang/lib/Frontend/Rewrite/CMakeLists.txt index 64aa651394dff1..d8d8773a8f9818 100644 --- a/clang/lib/Frontend/Rewrite/CMakeLists.txt +++ b/clang/lib/Frontend/Rewrite/CMakeLists.txt @@ -8,8 +8,6 @@ add_clang_library(clangRewriteFrontend HTMLPrint.cpp InclusionRewriter.cpp RewriteMacros.cpp - RewriteModernObjC.cpp - RewriteObjC.cpp RewriteTest.cpp LINK_LIBS diff --git a/clang/lib/Frontend/Rewrite/FrontendActions.cpp b/clang/lib/Frontend/Rewrite/FrontendActions.cpp index 5d2e1d78770959..577ca33c8b6d22 100644 --- a/clang/lib/Frontend/Rewrite/FrontendActions.cpp +++ b/clang/lib/Frontend/Rewrite/FrontendActions.cpp @@ -158,27 +158,6 @@ bool FixItRecompile::BeginInvocation(CompilerInstance &CI) { return true; } -#if CLANG_ENABLE_OBJC_REWRITER - -std::unique_ptr -RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - if (std::unique_ptr OS = - CI.createDefaultOutputFile(false, InFile, "cpp")) { - if (CI.getLangOpts().ObjCRuntime.isNonFragile()) - return CreateModernObjCRewriter(std::string(InFile), std::move(OS), - CI.getDiagnostics(), CI.getLangOpts(), - CI.getDiagnosticOpts().NoRewriteMacros, - (CI.getCodeGenOpts().getDebugInfo() != - llvm::codegenoptions::NoDebugInfo)); - return CreateObjCRewriter(std::string(InFile), std::move(OS), - CI.getDiagnostics(), CI.getLangOpts(), - CI.getDiagnosticOpts().NoRewriteMacros); - } - return nullptr; -} - -#endif - //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp deleted file mode 100644 index 8cdb463e2c99f2..00000000000000 --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ /dev/null @@ -1,7531 +0,0 @@ -//===-- RewriteModernObjC.cpp - Playground for the code rewriter ----------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Hacks and fun related to the code rewriter. -// -//===----------------------------------------------------------------------===// - -#include "clang/AST/AST.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/Attr.h" -#include "clang/AST/ParentMap.h" -#include "clang/Basic/CharInfo.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Config/config.h" -#include "clang/Lex/Lexer.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "clang/Rewrite/Frontend/ASTConsumers.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include - -#if CLANG_ENABLE_OBJC_REWRITER - -using namespace clang; -using llvm::RewriteBuffer; -using llvm::utostr; - -namespace { - class RewriteModernObjC : public ASTConsumer { - protected: - - enum { - BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), - block, ... */ - BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ - BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the - __block variable */ - BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy - helpers */ - BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose - support routines */ - BLOCK_BYREF_CURRENT_MAX = 256 - }; - - enum { - BLOCK_NEEDS_FREE = (1 << 24), - BLOCK_HAS_COPY_DISPOSE = (1 << 25), - BLOCK_HAS_CXX_OBJ = (1 << 26), - BLOCK_IS_GC = (1 << 27), - BLOCK_IS_GLOBAL = (1 << 28), - BLOCK_HAS_DESCRIPTOR = (1 << 29) - }; - - Rewriter Rewrite; - DiagnosticsEngine &Diags; - const LangOptions &LangOpts; - ASTContext *Context; - SourceManager *SM; - TranslationUnitDecl *TUDecl; - FileID MainFileID; - const char *MainFileStart, *MainFileEnd; - Stmt *CurrentBody; - ParentMap *PropParentMap; // created lazily. - std::string InFileName; - std::unique_ptr OutFile; - std::string Preamble; - - TypeDecl *ProtocolTypeDecl; - VarDecl *GlobalVarDecl; - Expr *GlobalConstructionExp; - unsigned RewriteFailedDiag; - unsigned GlobalBlockRewriteFailedDiag; - // ObjC string constant support. - unsigned NumObjCStringLiterals; - VarDecl *ConstantStringClassReference; - RecordDecl *NSStringRecord; - - // ObjC foreach break/continue generation support. - int BcLabelCount; - - unsigned TryFinallyContainsReturnDiag; - // Needed for super. - ObjCMethodDecl *CurMethodDef; - RecordDecl *SuperStructDecl; - RecordDecl *ConstantStringDecl; - - FunctionDecl *MsgSendFunctionDecl; - FunctionDecl *MsgSendSuperFunctionDecl; - FunctionDecl *MsgSendStretFunctionDecl; - FunctionDecl *MsgSendSuperStretFunctionDecl; - FunctionDecl *MsgSendFpretFunctionDecl; - FunctionDecl *GetClassFunctionDecl; - FunctionDecl *GetMetaClassFunctionDecl; - FunctionDecl *GetSuperClassFunctionDecl; - FunctionDecl *SelGetUidFunctionDecl; - FunctionDecl *CFStringFunctionDecl; - FunctionDecl *SuperConstructorFunctionDecl; - FunctionDecl *CurFunctionDef; - - /* Misc. containers needed for meta-data rewrite. */ - SmallVector ClassImplementation; - SmallVector CategoryImplementation; - llvm::SmallPtrSet ObjCSynthesizedStructs; - llvm::SmallPtrSet ObjCSynthesizedProtocols; - llvm::SmallPtrSet ObjCWrittenInterfaces; - llvm::SmallPtrSet GlobalDefinedTags; - SmallVector ObjCInterfacesSeen; - /// DefinedNonLazyClasses - List of defined "non-lazy" classes. - SmallVector DefinedNonLazyClasses; - - /// DefinedNonLazyCategories - List of defined "non-lazy" categories. - SmallVector DefinedNonLazyCategories; - - SmallVector Stmts; - SmallVector ObjCBcLabelNo; - // Remember all the @protocol() expressions. - llvm::SmallPtrSet ProtocolExprDecls; - - llvm::DenseSet CopyDestroyCache; - - // Block expressions. - SmallVector Blocks; - SmallVector InnerDeclRefsCount; - SmallVector InnerDeclRefs; - - SmallVector BlockDeclRefs; - - // Block related declarations. - llvm::SmallSetVector BlockByCopyDecls; - llvm::SmallSetVector BlockByRefDecls; - llvm::DenseMap BlockByRefDeclNo; - llvm::SmallPtrSet ImportedBlockDecls; - llvm::SmallPtrSet ImportedLocalExternalDecls; - - llvm::DenseMap RewrittenBlockExprs; - llvm::DenseMap > ReferencedIvars; - - // ivar bitfield grouping containers - llvm::DenseSet ObjCInterefaceHasBitfieldGroups; - llvm::DenseMap IvarGroupNumber; - // This container maps an tuple to the type - // of the struct where the bitfield belongs. - llvm::DenseMap, QualType> GroupRecordType; - SmallVector FunctionDefinitionsSeen; - - // This maps an original source AST to it's rewritten form. This allows - // us to avoid rewriting the same node twice (which is very uncommon). - // This is needed to support some of the exotic property rewriting. - llvm::DenseMap ReplacedNodes; - - // Needed for header files being rewritten - bool IsHeader; - bool SilenceRewriteMacroWarning; - bool GenerateLineInfo; - bool objc_impl_method; - - bool DisableReplaceStmt; - class DisableReplaceStmtScope { - RewriteModernObjC &R; - bool SavedValue; - - public: - DisableReplaceStmtScope(RewriteModernObjC &R) - : R(R), SavedValue(R.DisableReplaceStmt) { - R.DisableReplaceStmt = true; - } - ~DisableReplaceStmtScope() { - R.DisableReplaceStmt = SavedValue; - } - }; - void InitializeCommon(ASTContext &context); - - public: - llvm::DenseMap MethodInternalNames; - - // Top Level Driver code. - bool HandleTopLevelDecl(DeclGroupRef D) override { - for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { - if (ObjCInterfaceDecl *Class = dyn_cast(*I)) { - if (!Class->isThisDeclarationADefinition()) { - RewriteForwardClassDecl(D); - break; - } else { - // Keep track of all interface declarations seen. - ObjCInterfacesSeen.push_back(Class); - break; - } - } - - if (ObjCProtocolDecl *Proto = dyn_cast(*I)) { - if (!Proto->isThisDeclarationADefinition()) { - RewriteForwardProtocolDecl(D); - break; - } - } - - if (FunctionDecl *FDecl = dyn_cast(*I)) { - // Under modern abi, we cannot translate body of the function - // yet until all class extensions and its implementation is seen. - // This is because they may introduce new bitfields which must go - // into their grouping struct. - if (FDecl->isThisDeclarationADefinition() && - // Not c functions defined inside an objc container. - !FDecl->isTopLevelDeclInObjCContainer()) { - FunctionDefinitionsSeen.push_back(FDecl); - break; - } - } - HandleTopLevelSingleDecl(*I); - } - return true; - } - - void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override { - for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { - if (TypedefNameDecl *TD = dyn_cast(*I)) { - if (isTopLevelBlockPointerType(TD->getUnderlyingType())) - RewriteBlockPointerDecl(TD); - else if (TD->getUnderlyingType()->isFunctionPointerType()) - CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); - else - RewriteObjCQualifiedInterfaceTypes(TD); - } - } - } - - void HandleTopLevelSingleDecl(Decl *D); - void HandleDeclInMainFile(Decl *D); - RewriteModernObjC(std::string inFile, std::unique_ptr OS, - DiagnosticsEngine &D, const LangOptions &LOpts, - bool silenceMacroWarn, bool LineInfo); - - ~RewriteModernObjC() override {} - - void HandleTranslationUnit(ASTContext &C) override; - - void ReplaceStmt(Stmt *Old, Stmt *New) { - ReplaceStmtWithRange(Old, New, Old->getSourceRange()); - } - - void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) { - assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's"); - - Stmt *ReplacingStmt = ReplacedNodes[Old]; - if (ReplacingStmt) - return; // We can't rewrite the same node twice. - - if (DisableReplaceStmt) - return; - - // Measure the old text. - int Size = Rewrite.getRangeSize(SrcRange); - if (Size == -1) { - Diags.Report(Context->getFullLoc(Old->getBeginLoc()), RewriteFailedDiag) - << Old->getSourceRange(); - return; - } - // Get the new text. - std::string SStr; - llvm::raw_string_ostream S(SStr); - New->printPretty(S, nullptr, PrintingPolicy(LangOpts)); - - // If replacement succeeded or warning disabled return with no warning. - if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, SStr)) { - ReplacedNodes[Old] = New; - return; - } - if (SilenceRewriteMacroWarning) - return; - Diags.Report(Context->getFullLoc(Old->getBeginLoc()), RewriteFailedDiag) - << Old->getSourceRange(); - } - - void InsertText(SourceLocation Loc, StringRef Str, - bool InsertAfter = true) { - // If insertion succeeded or warning disabled return with no warning. - if (!Rewrite.InsertText(Loc, Str, InsertAfter) || - SilenceRewriteMacroWarning) - return; - - Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag); - } - - void ReplaceText(SourceLocation Start, unsigned OrigLength, - StringRef Str) { - // If removal succeeded or warning disabled return with no warning. - if (!Rewrite.ReplaceText(Start, OrigLength, Str) || - SilenceRewriteMacroWarning) - return; - - Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag); - } - - // Syntactic Rewriting. - void RewriteRecordBody(RecordDecl *RD); - void RewriteInclude(); - void RewriteLineDirective(const Decl *D); - void ConvertSourceLocationToLineDirective(SourceLocation Loc, - std::string &LineString); - void RewriteForwardClassDecl(DeclGroupRef D); - void RewriteForwardClassDecl(const SmallVectorImpl &DG); - void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, - const std::string &typedefString); - void RewriteImplementations(); - void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, - ObjCImplementationDecl *IMD, - ObjCCategoryImplDecl *CID); - void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl); - void RewriteImplementationDecl(Decl *Dcl); - void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, - ObjCMethodDecl *MDecl, std::string &ResultStr); - void RewriteTypeIntoString(QualType T, std::string &ResultStr, - const FunctionType *&FPRetType); - void RewriteByRefString(std::string &ResultStr, const std::string &Name, - ValueDecl *VD, bool def=false); - void RewriteCategoryDecl(ObjCCategoryDecl *Dcl); - void RewriteProtocolDecl(ObjCProtocolDecl *Dcl); - void RewriteForwardProtocolDecl(DeclGroupRef D); - void RewriteForwardProtocolDecl(const SmallVectorImpl &DG); - void RewriteMethodDeclaration(ObjCMethodDecl *Method); - void RewriteProperty(ObjCPropertyDecl *prop); - void RewriteFunctionDecl(FunctionDecl *FD); - void RewriteBlockPointerType(std::string& Str, QualType Type); - void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD); - void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD); - void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl); - void RewriteTypeOfDecl(VarDecl *VD); - void RewriteObjCQualifiedInterfaceTypes(Expr *E); - - std::string getIvarAccessString(ObjCIvarDecl *D); - - // Expression Rewriting. - Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S); - Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp); - Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo); - Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo); - Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp); - Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp); - Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp); - Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp); - Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp); - Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp); - Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp); - Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp); - Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S); - Stmt *RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S); - Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S); - Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S); - Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, - SourceLocation OrigEnd); - Stmt *RewriteBreakStmt(BreakStmt *S); - Stmt *RewriteContinueStmt(ContinueStmt *S); - void RewriteCastExpr(CStyleCastExpr *CE); - void RewriteImplicitCastObjCExpr(CastExpr *IE); - - // Computes ivar bitfield group no. - unsigned ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV); - // Names field decl. for ivar bitfield group. - void ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, std::string &Result); - // Names struct type for ivar bitfield group. - void ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, std::string &Result); - // Names symbol for ivar bitfield group field offset. - void ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV, std::string &Result); - // Given an ivar bitfield, it builds (or finds) its group record type. - QualType GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV); - QualType SynthesizeBitfieldGroupStructType( - ObjCIvarDecl *IV, - SmallVectorImpl &IVars); - - // Block rewriting. - void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D); - - // Block specific rewrite rules. - void RewriteBlockPointerDecl(NamedDecl *VD); - void RewriteByRefVar(VarDecl *VD, bool firstDecl, bool lastDecl); - Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD); - Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE); - void RewriteBlockPointerFunctionArgs(FunctionDecl *FD); - - void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, - std::string &Result); - - void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result); - bool IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, TagDecl *Tag, - bool &IsNamedDefinition); - void RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, - std::string &Result); - - bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result); - - void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl, - std::string &Result); - - void Initialize(ASTContext &context) override; - - // Misc. AST transformation routines. Sometimes they end up calling - // rewriting routines on the new ASTs. - CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, - ArrayRef Args, - SourceLocation StartLoc=SourceLocation(), - SourceLocation EndLoc=SourceLocation()); - - Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, - QualType returnType, - SmallVectorImpl &ArgTypes, - SmallVectorImpl &MsgExprs, - ObjCMethodDecl *Method); - - Stmt *SynthMessageExpr(ObjCMessageExpr *Exp, - SourceLocation StartLoc=SourceLocation(), - SourceLocation EndLoc=SourceLocation()); - - void SynthCountByEnumWithState(std::string &buf); - void SynthMsgSendFunctionDecl(); - void SynthMsgSendSuperFunctionDecl(); - void SynthMsgSendStretFunctionDecl(); - void SynthMsgSendFpretFunctionDecl(); - void SynthMsgSendSuperStretFunctionDecl(); - void SynthGetClassFunctionDecl(); - void SynthGetMetaClassFunctionDecl(); - void SynthGetSuperClassFunctionDecl(); - void SynthSelGetUidFunctionDecl(); - void SynthSuperConstructorFunctionDecl(); - - // Rewriting metadata - template - void RewriteObjCMethodsMetaData(MethodIterator MethodBegin, - MethodIterator MethodEnd, - bool IsInstanceMethod, - StringRef prefix, - StringRef ClassName, - std::string &Result); - void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, - std::string &Result); - void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, - std::string &Result); - void RewriteClassSetupInitHook(std::string &Result); - - void RewriteMetaDataIntoBuffer(std::string &Result); - void WriteImageInfo(std::string &Result); - void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, - std::string &Result); - void RewriteCategorySetupInitHook(std::string &Result); - - // Rewriting ivar - void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, - std::string &Result); - Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV); - - - std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag); - std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, - StringRef funcName, - const std::string &Tag); - std::string SynthesizeBlockFunc(BlockExpr *CE, int i, StringRef funcName, - const std::string &Tag); - std::string SynthesizeBlockImpl(BlockExpr *CE, const std::string &Tag, - const std::string &Desc); - std::string SynthesizeBlockDescriptor(const std::string &DescTag, - const std::string &ImplTag, int i, - StringRef funcName, unsigned hasCopy); - Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); - void SynthesizeBlockLiterals(SourceLocation FunLocStart, - StringRef FunName); - FunctionDecl *SynthBlockInitFunctionDecl(StringRef name); - Stmt *SynthBlockInitExpr(BlockExpr *Exp, - const SmallVectorImpl &InnerBlockDeclRefs); - - // Misc. helper routines. - QualType getProtocolType(); - void WarnAboutReturnGotoStmts(Stmt *S); - void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND); - void InsertBlockLiteralsWithinFunction(FunctionDecl *FD); - void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD); - - bool IsDeclStmtInForeachHeader(DeclStmt *DS); - void CollectBlockDeclRefInfo(BlockExpr *Exp); - void GetBlockDeclRefExprs(Stmt *S); - void GetInnerBlockDeclRefExprs(Stmt *S, - SmallVectorImpl &InnerBlockDeclRefs, - llvm::SmallPtrSetImpl &InnerContexts); - - // We avoid calling Type::isBlockPointerType(), since it operates on the - // canonical type. We only care if the top-level type is a closure pointer. - bool isTopLevelBlockPointerType(QualType T) { - return isa(T); - } - - /// convertBlockPointerToFunctionPointer - Converts a block-pointer type - /// to a function pointer type and upon success, returns true; false - /// otherwise. - bool convertBlockPointerToFunctionPointer(QualType &T) { - if (isTopLevelBlockPointerType(T)) { - const auto *BPT = T->castAs(); - T = Context->getPointerType(BPT->getPointeeType()); - return true; - } - return false; - } - - bool convertObjCTypeToCStyleType(QualType &T); - - bool needToScanForQualifiers(QualType T); - QualType getSuperStructType(); - QualType getConstantStringStructType(); - QualType convertFunctionTypeOfBlocks(const FunctionType *FT); - - void convertToUnqualifiedObjCType(QualType &T) { - if (T->isObjCQualifiedIdType()) { - bool isConst = T.isConstQualified(); - T = isConst ? Context->getObjCIdType().withConst() - : Context->getObjCIdType(); - } - else if (T->isObjCQualifiedClassType()) - T = Context->getObjCClassType(); - else if (T->isObjCObjectPointerType() && - T->getPointeeType()->isObjCQualifiedInterfaceType()) { - if (const ObjCObjectPointerType * OBJPT = - T->getAsObjCInterfacePointerType()) { - const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType(); - T = QualType(IFaceT, 0); - T = Context->getPointerType(T); - } - } - } - - // FIXME: This predicate seems like it would be useful to add to ASTContext. - bool isObjCType(QualType T) { - if (!LangOpts.ObjC) - return false; - - QualType OCT = Context->getCanonicalType(T).getUnqualifiedType(); - - if (OCT == Context->getCanonicalType(Context->getObjCIdType()) || - OCT == Context->getCanonicalType(Context->getObjCClassType())) - return true; - - if (const PointerType *PT = OCT->getAs()) { - if (isa(PT->getPointeeType()) || - PT->getPointeeType()->isObjCQualifiedIdType()) - return true; - } - return false; - } - - bool PointerTypeTakesAnyBlockArguments(QualType QT); - bool PointerTypeTakesAnyObjCQualifiedType(QualType QT); - void GetExtentOfArgList(const char *Name, const char *&LParen, - const char *&RParen); - - void QuoteDoublequotes(std::string &From, std::string &To) { - for (unsigned i = 0; i < From.length(); i++) { - if (From[i] == '"') - To += "\\\""; - else - To += From[i]; - } - } - - QualType getSimpleFunctionType(QualType result, - ArrayRef args, - bool variadic = false) { - if (result == Context->getObjCInstanceType()) - result = Context->getObjCIdType(); - FunctionProtoType::ExtProtoInfo fpi; - fpi.Variadic = variadic; - return Context->getFunctionType(result, args, fpi); - } - - // Helper function: create a CStyleCastExpr with trivial type source info. - CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty, - CastKind Kind, Expr *E) { - TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation()); - return CStyleCastExpr::Create(*Ctx, Ty, VK_PRValue, Kind, E, nullptr, - FPOptionsOverride(), TInfo, - SourceLocation(), SourceLocation()); - } - - bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const { - const IdentifierInfo *II = &Context->Idents.get("load"); - Selector LoadSel = Context->Selectors.getSelector(0, &II); - return OD->getClassMethod(LoadSel) != nullptr; - } - - StringLiteral *getStringLiteral(StringRef Str) { - QualType StrType = Context->getConstantArrayType( - Context->CharTy, llvm::APInt(32, Str.size() + 1), nullptr, - ArraySizeModifier::Normal, 0); - return StringLiteral::Create(*Context, Str, StringLiteralKind::Ordinary, - /*Pascal=*/false, StrType, SourceLocation()); - } - }; -} // end anonymous namespace - -void RewriteModernObjC::RewriteBlocksInFunctionProtoType(QualType funcType, - NamedDecl *D) { - if (const FunctionProtoType *fproto - = dyn_cast(funcType.IgnoreParens())) { - for (const auto &I : fproto->param_types()) - if (isTopLevelBlockPointerType(I)) { - // All the args are checked/rewritten. Don't call twice! - RewriteBlockPointerDecl(D); - break; - } - } -} - -void RewriteModernObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) { - const PointerType *PT = funcType->getAs(); - if (PT && PointerTypeTakesAnyBlockArguments(funcType)) - RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND); -} - -static bool IsHeaderFile(const std::string &Filename) { - std::string::size_type DotPos = Filename.rfind('.'); - - if (DotPos == std::string::npos) { - // no file extension - return false; - } - - std::string Ext = Filename.substr(DotPos + 1); - // C header: .h - // C++ header: .hh or .H; - return Ext == "h" || Ext == "hh" || Ext == "H"; -} - -RewriteModernObjC::RewriteModernObjC(std::string inFile, - std::unique_ptr OS, - DiagnosticsEngine &D, - const LangOptions &LOpts, - bool silenceMacroWarn, bool LineInfo) - : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)), - SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) { - IsHeader = IsHeaderFile(inFile); - RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, - "rewriting sub-expression within a macro (may not be correct)"); - // FIXME. This should be an error. But if block is not called, it is OK. And it - // may break including some headers. - GlobalBlockRewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, - "rewriting block literal declared in global scope is not implemented"); - - TryFinallyContainsReturnDiag = Diags.getCustomDiagID( - DiagnosticsEngine::Warning, - "rewriter doesn't support user-specified control flow semantics " - "for @try/@finally (code may not execute properly)"); -} - -std::unique_ptr clang::CreateModernObjCRewriter( - const std::string &InFile, std::unique_ptr OS, - DiagnosticsEngine &Diags, const LangOptions &LOpts, - bool SilenceRewriteMacroWarning, bool LineInfo) { - return std::make_unique(InFile, std::move(OS), Diags, - LOpts, SilenceRewriteMacroWarning, - LineInfo); -} - -void RewriteModernObjC::InitializeCommon(ASTContext &context) { - Context = &context; - SM = &Context->getSourceManager(); - TUDecl = Context->getTranslationUnitDecl(); - MsgSendFunctionDecl = nullptr; - MsgSendSuperFunctionDecl = nullptr; - MsgSendStretFunctionDecl = nullptr; - MsgSendSuperStretFunctionDecl = nullptr; - MsgSendFpretFunctionDecl = nullptr; - GetClassFunctionDecl = nullptr; - GetMetaClassFunctionDecl = nullptr; - GetSuperClassFunctionDecl = nullptr; - SelGetUidFunctionDecl = nullptr; - CFStringFunctionDecl = nullptr; - ConstantStringClassReference = nullptr; - NSStringRecord = nullptr; - CurMethodDef = nullptr; - CurFunctionDef = nullptr; - GlobalVarDecl = nullptr; - GlobalConstructionExp = nullptr; - SuperStructDecl = nullptr; - ProtocolTypeDecl = nullptr; - ConstantStringDecl = nullptr; - BcLabelCount = 0; - SuperConstructorFunctionDecl = nullptr; - NumObjCStringLiterals = 0; - PropParentMap = nullptr; - CurrentBody = nullptr; - DisableReplaceStmt = false; - objc_impl_method = false; - - // Get the ID and start/end of the main file. - MainFileID = SM->getMainFileID(); - llvm::MemoryBufferRef MainBuf = SM->getBufferOrFake(MainFileID); - MainFileStart = MainBuf.getBufferStart(); - MainFileEnd = MainBuf.getBufferEnd(); - - Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts()); -} - -//===----------------------------------------------------------------------===// -// Top Level Driver Code -//===----------------------------------------------------------------------===// - -void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) { - if (Diags.hasErrorOccurred()) - return; - - // Two cases: either the decl could be in the main file, or it could be in a - // #included file. If the former, rewrite it now. If the later, check to see - // if we rewrote the #include/#import. - SourceLocation Loc = D->getLocation(); - Loc = SM->getExpansionLoc(Loc); - - // If this is for a builtin, ignore it. - if (Loc.isInvalid()) return; - - // Look for built-in declarations that we need to refer during the rewrite. - if (FunctionDecl *FD = dyn_cast(D)) { - RewriteFunctionDecl(FD); - } else if (VarDecl *FVD = dyn_cast(D)) { - // declared in - if (FVD->getName() == "_NSConstantStringClassReference") { - ConstantStringClassReference = FVD; - return; - } - } else if (ObjCCategoryDecl *CD = dyn_cast(D)) { - RewriteCategoryDecl(CD); - } else if (ObjCProtocolDecl *PD = dyn_cast(D)) { - if (PD->isThisDeclarationADefinition()) - RewriteProtocolDecl(PD); - } else if (LinkageSpecDecl *LSD = dyn_cast(D)) { - // Recurse into linkage specifications - for (DeclContext::decl_iterator DI = LSD->decls_begin(), - DIEnd = LSD->decls_end(); - DI != DIEnd; ) { - if (ObjCInterfaceDecl *IFace = dyn_cast((*DI))) { - if (!IFace->isThisDeclarationADefinition()) { - SmallVector DG; - SourceLocation StartLoc = IFace->getBeginLoc(); - do { - if (isa(*DI) && - !cast(*DI)->isThisDeclarationADefinition() && - StartLoc == (*DI)->getBeginLoc()) - DG.push_back(*DI); - else - break; - - ++DI; - } while (DI != DIEnd); - RewriteForwardClassDecl(DG); - continue; - } - else { - // Keep track of all interface declarations seen. - ObjCInterfacesSeen.push_back(IFace); - ++DI; - continue; - } - } - - if (ObjCProtocolDecl *Proto = dyn_cast((*DI))) { - if (!Proto->isThisDeclarationADefinition()) { - SmallVector DG; - SourceLocation StartLoc = Proto->getBeginLoc(); - do { - if (isa(*DI) && - !cast(*DI)->isThisDeclarationADefinition() && - StartLoc == (*DI)->getBeginLoc()) - DG.push_back(*DI); - else - break; - - ++DI; - } while (DI != DIEnd); - RewriteForwardProtocolDecl(DG); - continue; - } - } - - HandleTopLevelSingleDecl(*DI); - ++DI; - } - } - // If we have a decl in the main file, see if we should rewrite it. - if (SM->isWrittenInMainFile(Loc)) - return HandleDeclInMainFile(D); -} - -//===----------------------------------------------------------------------===// -// Syntactic (non-AST) Rewriting Code -//===----------------------------------------------------------------------===// - -void RewriteModernObjC::RewriteInclude() { - SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID); - StringRef MainBuf = SM->getBufferData(MainFileID); - const char *MainBufStart = MainBuf.begin(); - const char *MainBufEnd = MainBuf.end(); - size_t ImportLen = strlen("import"); - - // Loop over the whole file, looking for includes. - for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) { - if (*BufPtr == '#') { - if (++BufPtr == MainBufEnd) - return; - while (*BufPtr == ' ' || *BufPtr == '\t') - if (++BufPtr == MainBufEnd) - return; - if (!strncmp(BufPtr, "import", ImportLen)) { - // replace import with include - SourceLocation ImportLoc = - LocStart.getLocWithOffset(BufPtr-MainBufStart); - ReplaceText(ImportLoc, ImportLen, "include"); - BufPtr += ImportLen; - } - } - } -} - -static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl, - ObjCIvarDecl *IvarDecl, std::string &Result) { - Result += "OBJC_IVAR_$_"; - Result += IDecl->getName(); - Result += "$"; - Result += IvarDecl->getName(); -} - -std::string -RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) { - const ObjCInterfaceDecl *ClassDecl = D->getContainingInterface(); - - // Build name of symbol holding ivar offset. - std::string IvarOffsetName; - if (D->isBitField()) - ObjCIvarBitfieldGroupOffset(D, IvarOffsetName); - else - WriteInternalIvarName(ClassDecl, D, IvarOffsetName); - - std::string S = "(*("; - QualType IvarT = D->getType(); - if (D->isBitField()) - IvarT = GetGroupRecordTypeForObjCIvarBitfield(D); - - if (!IvarT->getAs() && IvarT->isRecordType()) { - RecordDecl *RD = IvarT->castAs()->getDecl(); - RD = RD->getDefinition(); - if (RD && !RD->getDeclName().getAsIdentifierInfo()) { - // decltype(((Foo_IMPL*)0)->bar) * - auto *CDecl = cast(D->getDeclContext()); - // ivar in class extensions requires special treatment. - if (ObjCCategoryDecl *CatDecl = dyn_cast(CDecl)) - CDecl = CatDecl->getClassInterface(); - std::string RecName = std::string(CDecl->getName()); - RecName += "_IMPL"; - RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl, - SourceLocation(), SourceLocation(), - &Context->Idents.get(RecName)); - QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD)); - unsigned UnsignedIntSize = - static_cast(Context->getTypeSize(Context->UnsignedIntTy)); - Expr *Zero = IntegerLiteral::Create(*Context, - llvm::APInt(UnsignedIntSize, 0), - Context->UnsignedIntTy, SourceLocation()); - Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero); - ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), - Zero); - FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), - SourceLocation(), - &Context->Idents.get(D->getNameAsString()), - IvarT, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - MemberExpr *ME = MemberExpr::CreateImplicit( - *Context, PE, true, FD, FD->getType(), VK_LValue, OK_Ordinary); - IvarT = Context->getDecltypeType(ME, ME->getType()); - } - } - convertObjCTypeToCStyleType(IvarT); - QualType castT = Context->getPointerType(IvarT); - std::string TypeString(castT.getAsString(Context->getPrintingPolicy())); - S += TypeString; - S += ")"; - - // ((char *)self + IVAR_OFFSET_SYMBOL_NAME) - S += "((char *)self + "; - S += IvarOffsetName; - S += "))"; - if (D->isBitField()) { - S += "."; - S += D->getNameAsString(); - } - ReferencedIvars[const_cast(ClassDecl)].insert(D); - return S; -} - -/// mustSynthesizeSetterGetterMethod - returns true if setter or getter has not -/// been found in the class implementation. In this case, it must be synthesized. -static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP, - ObjCPropertyDecl *PD, - bool getter) { - auto *OMD = IMP->getInstanceMethod(getter ? PD->getGetterName() - : PD->getSetterName()); - return !OMD || OMD->isSynthesizedAccessorStub(); -} - -void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, - ObjCImplementationDecl *IMD, - ObjCCategoryImplDecl *CID) { - static bool objcGetPropertyDefined = false; - static bool objcSetPropertyDefined = false; - SourceLocation startGetterSetterLoc; - - if (PID->getBeginLoc().isValid()) { - SourceLocation startLoc = PID->getBeginLoc(); - InsertText(startLoc, "// "); - const char *startBuf = SM->getCharacterData(startLoc); - assert((*startBuf == '@') && "bogus @synthesize location"); - const char *semiBuf = strchr(startBuf, ';'); - assert((*semiBuf == ';') && "@synthesize: can't find ';'"); - startGetterSetterLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); - } else - startGetterSetterLoc = IMD ? IMD->getEndLoc() : CID->getEndLoc(); - - if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) - return; // FIXME: is this correct? - - // Generate the 'getter' function. - ObjCPropertyDecl *PD = PID->getPropertyDecl(); - ObjCIvarDecl *OID = PID->getPropertyIvarDecl(); - assert(IMD && OID && "Synthesized ivars must be attached to @implementation"); - - unsigned Attributes = PD->getPropertyAttributes(); - if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) { - bool GenGetProperty = - !(Attributes & ObjCPropertyAttribute::kind_nonatomic) && - (Attributes & (ObjCPropertyAttribute::kind_retain | - ObjCPropertyAttribute::kind_copy)); - std::string Getr; - if (GenGetProperty && !objcGetPropertyDefined) { - objcGetPropertyDefined = true; - // FIXME. Is this attribute correct in all cases? - Getr = "\nextern \"C\" __declspec(dllimport) " - "id objc_getProperty(id, SEL, long, bool);\n"; - } - RewriteObjCMethodDecl(OID->getContainingInterface(), - PID->getGetterMethodDecl(), Getr); - Getr += "{ "; - // Synthesize an explicit cast to gain access to the ivar. - // See objc-act.c:objc_synthesize_new_getter() for details. - if (GenGetProperty) { - // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1) - Getr += "typedef "; - const FunctionType *FPRetType = nullptr; - RewriteTypeIntoString(PID->getGetterMethodDecl()->getReturnType(), Getr, - FPRetType); - Getr += " _TYPE"; - if (FPRetType) { - Getr += ")"; // close the precedence "scope" for "*". - - // Now, emit the argument types (if any). - if (const FunctionProtoType *FT = dyn_cast(FPRetType)){ - Getr += "("; - for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { - if (i) Getr += ", "; - std::string ParamStr = - FT->getParamType(i).getAsString(Context->getPrintingPolicy()); - Getr += ParamStr; - } - if (FT->isVariadic()) { - if (FT->getNumParams()) - Getr += ", "; - Getr += "..."; - } - Getr += ")"; - } else - Getr += "()"; - } - Getr += ";\n"; - Getr += "return (_TYPE)"; - Getr += "objc_getProperty(self, _cmd, "; - RewriteIvarOffsetComputation(OID, Getr); - Getr += ", 1)"; - } - else - Getr += "return " + getIvarAccessString(OID); - Getr += "; }"; - InsertText(startGetterSetterLoc, Getr); - } - - if (PD->isReadOnly() || - !mustSynthesizeSetterGetterMethod(IMD, PD, false /*setter*/)) - return; - - // Generate the 'setter' function. - std::string Setr; - bool GenSetProperty = Attributes & (ObjCPropertyAttribute::kind_retain | - ObjCPropertyAttribute::kind_copy); - if (GenSetProperty && !objcSetPropertyDefined) { - objcSetPropertyDefined = true; - // FIXME. Is this attribute correct in all cases? - Setr = "\nextern \"C\" __declspec(dllimport) " - "void objc_setProperty (id, SEL, long, id, bool, bool);\n"; - } - - RewriteObjCMethodDecl(OID->getContainingInterface(), - PID->getSetterMethodDecl(), Setr); - Setr += "{ "; - // Synthesize an explicit cast to initialize the ivar. - // See objc-act.c:objc_synthesize_new_setter() for details. - if (GenSetProperty) { - Setr += "objc_setProperty (self, _cmd, "; - RewriteIvarOffsetComputation(OID, Setr); - Setr += ", (id)"; - Setr += PD->getName(); - Setr += ", "; - if (Attributes & ObjCPropertyAttribute::kind_nonatomic) - Setr += "0, "; - else - Setr += "1, "; - if (Attributes & ObjCPropertyAttribute::kind_copy) - Setr += "1)"; - else - Setr += "0)"; - } - else { - Setr += getIvarAccessString(OID) + " = "; - Setr += PD->getName(); - } - Setr += "; }\n"; - InsertText(startGetterSetterLoc, Setr); -} - -static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, - std::string &typedefString) { - typedefString += "\n#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(); - // typedef struct { } _objc_exc_Classname; - typedefString += ";\ntypedef struct {} _objc_exc_"; - typedefString += ForwardDecl->getNameAsString(); - typedefString += ";\n#endif\n"; -} - -void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, - const std::string &typedefString) { - SourceLocation startLoc = ClassDecl->getBeginLoc(); - 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 RewriteModernObjC::RewriteForwardClassDecl(DeclGroupRef D) { - std::string typedefString; - for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { - if (ObjCInterfaceDecl *ForwardDecl = dyn_cast(*I)) { - if (I == D.begin()) { - // 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 += ";"; - } - RewriteOneForwardClassDecl(ForwardDecl, typedefString); - } - else - HandleTopLevelSingleDecl(*I); - } - DeclGroupRef::iterator I = D.begin(); - RewriteForwardClassEpilogue(cast(*I), typedefString); -} - -void RewriteModernObjC::RewriteForwardClassDecl( - const SmallVectorImpl &D) { - std::string typedefString; - for (unsigned i = 0; i < D.size(); i++) { - ObjCInterfaceDecl *ForwardDecl = cast(D[i]); - if (i == 0) { - typedefString += "// @class "; - typedefString += ForwardDecl->getNameAsString(); - typedefString += ";"; - } - RewriteOneForwardClassDecl(ForwardDecl, typedefString); - } - RewriteForwardClassEpilogue(cast(D[0]), typedefString); -} - -void RewriteModernObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) { - // When method is a synthesized one, such as a getter/setter there is - // nothing to rewrite. - if (Method->isImplicit()) - return; - SourceLocation LocStart = Method->getBeginLoc(); - SourceLocation LocEnd = Method->getEndLoc(); - - if (SM->getExpansionLineNumber(LocEnd) > - SM->getExpansionLineNumber(LocStart)) { - InsertText(LocStart, "#if 0\n"); - ReplaceText(LocEnd, 1, ";\n#endif\n"); - } else { - InsertText(LocStart, "// "); - } -} - -void RewriteModernObjC::RewriteProperty(ObjCPropertyDecl *prop) { - SourceLocation Loc = prop->getAtLoc(); - - ReplaceText(Loc, 0, "// "); - // FIXME: handle properties that are declared across multiple lines. -} - -void RewriteModernObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) { - SourceLocation LocStart = CatDecl->getBeginLoc(); - - // FIXME: handle category headers that are declared across multiple lines. - if (CatDecl->getIvarRBraceLoc().isValid()) { - ReplaceText(LocStart, 1, "/** "); - ReplaceText(CatDecl->getIvarRBraceLoc(), 1, "**/ "); - } - else { - ReplaceText(LocStart, 0, "// "); - } - - for (auto *I : CatDecl->instance_properties()) - RewriteProperty(I); - - for (auto *I : CatDecl->instance_methods()) - RewriteMethodDeclaration(I); - for (auto *I : CatDecl->class_methods()) - RewriteMethodDeclaration(I); - - // Lastly, comment out the @end. - ReplaceText(CatDecl->getAtEndRange().getBegin(), - strlen("@end"), "/* @end */\n"); -} - -void RewriteModernObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) { - SourceLocation LocStart = PDecl->getBeginLoc(); - assert(PDecl->isThisDeclarationADefinition()); - - // FIXME: handle protocol headers that are declared across multiple lines. - ReplaceText(LocStart, 0, "// "); - - for (auto *I : PDecl->instance_methods()) - RewriteMethodDeclaration(I); - for (auto *I : PDecl->class_methods()) - RewriteMethodDeclaration(I); - for (auto *I : PDecl->instance_properties()) - RewriteProperty(I); - - // Lastly, comment out the @end. - SourceLocation LocEnd = PDecl->getAtEndRange().getBegin(); - ReplaceText(LocEnd, strlen("@end"), "/* @end */\n"); - - // Must comment out @optional/@required - const char *startBuf = SM->getCharacterData(LocStart); - const char *endBuf = SM->getCharacterData(LocEnd); - for (const char *p = startBuf; p < endBuf; p++) { - if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) { - SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); - ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */"); - - } - else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) { - SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); - ReplaceText(OptionalLoc, strlen("@required"), "/* @required */"); - - } - } -} - -void RewriteModernObjC::RewriteForwardProtocolDecl(DeclGroupRef D) { - SourceLocation LocStart = (*D.begin())->getBeginLoc(); - if (LocStart.isInvalid()) - llvm_unreachable("Invalid SourceLocation"); - // FIXME: handle forward protocol that are declared across multiple lines. - ReplaceText(LocStart, 0, "// "); -} - -void -RewriteModernObjC::RewriteForwardProtocolDecl(const SmallVectorImpl &DG) { - SourceLocation LocStart = DG[0]->getBeginLoc(); - if (LocStart.isInvalid()) - llvm_unreachable("Invalid SourceLocation"); - // FIXME: handle forward protocol that are declared across multiple lines. - ReplaceText(LocStart, 0, "// "); -} - -void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr, - const FunctionType *&FPRetType) { - if (T->isObjCQualifiedIdType()) - ResultStr += "id"; - else if (T->isFunctionPointerType() || - T->isBlockPointerType()) { - // needs special handling, since pointer-to-functions have special - // syntax (where a decaration models use). - QualType retType = T; - QualType PointeeTy; - if (const PointerType* PT = retType->getAs()) - PointeeTy = PT->getPointeeType(); - else if (const BlockPointerType *BPT = retType->getAs()) - PointeeTy = BPT->getPointeeType(); - if ((FPRetType = PointeeTy->getAs())) { - ResultStr += - FPRetType->getReturnType().getAsString(Context->getPrintingPolicy()); - ResultStr += "(*"; - } - } else - ResultStr += T.getAsString(Context->getPrintingPolicy()); -} - -void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, - ObjCMethodDecl *OMD, - std::string &ResultStr) { - //fprintf(stderr,"In RewriteObjCMethodDecl\n"); - const FunctionType *FPRetType = nullptr; - ResultStr += "\nstatic "; - RewriteTypeIntoString(OMD->getReturnType(), ResultStr, FPRetType); - ResultStr += " "; - - // Unique method name - std::string NameStr; - - if (OMD->isInstanceMethod()) - NameStr += "_I_"; - else - NameStr += "_C_"; - - NameStr += IDecl->getNameAsString(); - NameStr += "_"; - - if (ObjCCategoryImplDecl *CID = - dyn_cast(OMD->getDeclContext())) { - NameStr += CID->getNameAsString(); - NameStr += "_"; - } - // Append selector names, replacing ':' with '_' - { - std::string selString = OMD->getSelector().getAsString(); - int len = selString.size(); - for (int i = 0; i < len; i++) - if (selString[i] == ':') - selString[i] = '_'; - NameStr += selString; - } - // Remember this name for metadata emission - MethodInternalNames[OMD] = NameStr; - ResultStr += NameStr; - - // Rewrite arguments - ResultStr += "("; - - // invisible arguments - if (OMD->isInstanceMethod()) { - QualType selfTy = Context->getObjCInterfaceType(IDecl); - selfTy = Context->getPointerType(selfTy); - if (!LangOpts.MicrosoftExt) { - if (ObjCSynthesizedStructs.count(const_cast(IDecl))) - ResultStr += "struct "; - } - // When rewriting for Microsoft, explicitly omit the structure name. - ResultStr += IDecl->getNameAsString(); - ResultStr += " *"; - } - else - ResultStr += Context->getObjCClassType().getAsString( - Context->getPrintingPolicy()); - - ResultStr += " self, "; - ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy()); - ResultStr += " _cmd"; - - // Method arguments. - for (const auto *PDecl : OMD->parameters()) { - ResultStr += ", "; - if (PDecl->getType()->isObjCQualifiedIdType()) { - ResultStr += "id "; - ResultStr += PDecl->getNameAsString(); - } else { - std::string Name = PDecl->getNameAsString(); - QualType QT = PDecl->getType(); - // Make sure we convert "t (^)(...)" to "t (*)(...)". - (void)convertBlockPointerToFunctionPointer(QT); - QT.getAsStringInternal(Name, Context->getPrintingPolicy()); - ResultStr += Name; - } - } - if (OMD->isVariadic()) - ResultStr += ", ..."; - ResultStr += ") "; - - if (FPRetType) { - ResultStr += ")"; // close the precedence "scope" for "*". - - // Now, emit the argument types (if any). - if (const FunctionProtoType *FT = dyn_cast(FPRetType)) { - ResultStr += "("; - for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { - if (i) ResultStr += ", "; - std::string ParamStr = - FT->getParamType(i).getAsString(Context->getPrintingPolicy()); - ResultStr += ParamStr; - } - if (FT->isVariadic()) { - if (FT->getNumParams()) - ResultStr += ", "; - ResultStr += "..."; - } - ResultStr += ")"; - } else { - ResultStr += "()"; - } - } -} - -void RewriteModernObjC::RewriteImplementationDecl(Decl *OID) { - ObjCImplementationDecl *IMD = dyn_cast(OID); - ObjCCategoryImplDecl *CID = dyn_cast(OID); - assert((IMD || CID) && "Unknown implementation type"); - - if (IMD) { - if (IMD->getIvarRBraceLoc().isValid()) { - ReplaceText(IMD->getBeginLoc(), 1, "/** "); - ReplaceText(IMD->getIvarRBraceLoc(), 1, "**/ "); - } - else { - InsertText(IMD->getBeginLoc(), "// "); - } - } - else - InsertText(CID->getBeginLoc(), "// "); - - for (auto *OMD : IMD ? IMD->instance_methods() : CID->instance_methods()) { - if (!OMD->getBody()) - continue; - std::string ResultStr; - RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); - SourceLocation LocStart = OMD->getBeginLoc(); - SourceLocation LocEnd = OMD->getCompoundBody()->getBeginLoc(); - - const char *startBuf = SM->getCharacterData(LocStart); - const char *endBuf = SM->getCharacterData(LocEnd); - ReplaceText(LocStart, endBuf-startBuf, ResultStr); - } - - for (auto *OMD : IMD ? IMD->class_methods() : CID->class_methods()) { - if (!OMD->getBody()) - continue; - std::string ResultStr; - RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); - SourceLocation LocStart = OMD->getBeginLoc(); - SourceLocation LocEnd = OMD->getCompoundBody()->getBeginLoc(); - - const char *startBuf = SM->getCharacterData(LocStart); - const char *endBuf = SM->getCharacterData(LocEnd); - ReplaceText(LocStart, endBuf-startBuf, ResultStr); - } - for (auto *I : IMD ? IMD->property_impls() : CID->property_impls()) - RewritePropertyImplDecl(I, IMD, CID); - - InsertText(IMD ? IMD->getEndLoc() : CID->getEndLoc(), "// "); -} - -void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { - // Do not synthesize more than once. - if (ObjCSynthesizedStructs.count(ClassDecl)) - return; - // Make sure super class's are written before current class is written. - ObjCInterfaceDecl *SuperClass = ClassDecl->getSuperClass(); - while (SuperClass) { - RewriteInterfaceDecl(SuperClass); - SuperClass = SuperClass->getSuperClass(); - } - std::string ResultStr; - if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) { - // we haven't seen a forward decl - generate a typedef. - RewriteOneForwardClassDecl(ClassDecl, ResultStr); - RewriteIvarOffsetSymbols(ClassDecl, ResultStr); - - RewriteObjCInternalStruct(ClassDecl, ResultStr); - // Mark this typedef as having been written into its c++ equivalent. - ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl()); - - for (auto *I : ClassDecl->instance_properties()) - RewriteProperty(I); - for (auto *I : ClassDecl->instance_methods()) - RewriteMethodDeclaration(I); - for (auto *I : ClassDecl->class_methods()) - RewriteMethodDeclaration(I); - - // Lastly, comment out the @end. - ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), - "/* @end */\n"); - } -} - -Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) { - SourceRange OldRange = PseudoOp->getSourceRange(); - - // We just magically know some things about the structure of this - // expression. - ObjCMessageExpr *OldMsg = - cast(PseudoOp->getSemanticExpr( - PseudoOp->getNumSemanticExprs() - 1)); - - // Because the rewriter doesn't allow us to rewrite rewritten code, - // we need to suppress rewriting the sub-statements. - Expr *Base; - SmallVector Args; - { - DisableReplaceStmtScope S(*this); - - // Rebuild the base expression if we have one. - Base = nullptr; - if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { - Base = OldMsg->getInstanceReceiver(); - Base = cast(Base)->getSourceExpr(); - Base = cast(RewriteFunctionBodyOrGlobalInitializer(Base)); - } - - unsigned numArgs = OldMsg->getNumArgs(); - for (unsigned i = 0; i < numArgs; i++) { - Expr *Arg = OldMsg->getArg(i); - if (isa(Arg)) - Arg = cast(Arg)->getSourceExpr(); - Arg = cast(RewriteFunctionBodyOrGlobalInitializer(Arg)); - Args.push_back(Arg); - } - } - - // TODO: avoid this copy. - SmallVector SelLocs; - OldMsg->getSelectorLocs(SelLocs); - - ObjCMessageExpr *NewMsg = nullptr; - switch (OldMsg->getReceiverKind()) { - case ObjCMessageExpr::Class: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - OldMsg->getClassReceiverTypeInfo(), - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - Args, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - - case ObjCMessageExpr::Instance: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - Base, - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - Args, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - - case ObjCMessageExpr::SuperClass: - case ObjCMessageExpr::SuperInstance: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - OldMsg->getSuperLoc(), - OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, - OldMsg->getSuperType(), - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - Args, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - } - - Stmt *Replacement = SynthMessageExpr(NewMsg); - ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); - return Replacement; -} - -Stmt *RewriteModernObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) { - SourceRange OldRange = PseudoOp->getSourceRange(); - - // We just magically know some things about the structure of this - // expression. - ObjCMessageExpr *OldMsg = - cast(PseudoOp->getResultExpr()->IgnoreImplicit()); - - // Because the rewriter doesn't allow us to rewrite rewritten code, - // we need to suppress rewriting the sub-statements. - Expr *Base = nullptr; - SmallVector Args; - { - DisableReplaceStmtScope S(*this); - // Rebuild the base expression if we have one. - if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { - Base = OldMsg->getInstanceReceiver(); - Base = cast(Base)->getSourceExpr(); - Base = cast(RewriteFunctionBodyOrGlobalInitializer(Base)); - } - unsigned numArgs = OldMsg->getNumArgs(); - for (unsigned i = 0; i < numArgs; i++) { - Expr *Arg = OldMsg->getArg(i); - if (isa(Arg)) - Arg = cast(Arg)->getSourceExpr(); - Arg = cast(RewriteFunctionBodyOrGlobalInitializer(Arg)); - Args.push_back(Arg); - } - } - - // Intentionally empty. - SmallVector SelLocs; - - ObjCMessageExpr *NewMsg = nullptr; - switch (OldMsg->getReceiverKind()) { - case ObjCMessageExpr::Class: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - OldMsg->getClassReceiverTypeInfo(), - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - Args, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - - case ObjCMessageExpr::Instance: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - Base, - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - Args, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - - case ObjCMessageExpr::SuperClass: - case ObjCMessageExpr::SuperInstance: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - OldMsg->getSuperLoc(), - OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, - OldMsg->getSuperType(), - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - Args, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - } - - Stmt *Replacement = SynthMessageExpr(NewMsg); - ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); - return Replacement; -} - -/// SynthCountByEnumWithState - To print: -/// ((NSUInteger (*) -/// (id, SEL, struct __objcFastEnumerationState *, id *, NSUInteger)) -/// (void *)objc_msgSend)((id)l_collection, -/// sel_registerName( -/// "countByEnumeratingWithState:objects:count:"), -/// &enumState, -/// (id *)__rw_items, (NSUInteger)16) -/// -void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) { - buf += "((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, " - "id *, _WIN_NSUInteger))(void *)objc_msgSend)"; - buf += "\n\t\t"; - buf += "((id)l_collection,\n\t\t"; - buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),"; - buf += "\n\t\t"; - buf += "&enumState, " - "(id *)__rw_items, (_WIN_NSUInteger)16)"; -} - -/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach -/// statement to exit to its outer synthesized loop. -/// -Stmt *RewriteModernObjC::RewriteBreakStmt(BreakStmt *S) { - if (Stmts.empty() || !isa(Stmts.back())) - return S; - // replace break with goto __break_label - std::string buf; - - SourceLocation startLoc = S->getBeginLoc(); - buf = "goto __break_label_"; - buf += utostr(ObjCBcLabelNo.back()); - ReplaceText(startLoc, strlen("break"), buf); - - return nullptr; -} - -void RewriteModernObjC::ConvertSourceLocationToLineDirective( - SourceLocation Loc, - std::string &LineString) { - if (Loc.isFileID() && GenerateLineInfo) { - LineString += "\n#line "; - PresumedLoc PLoc = SM->getPresumedLoc(Loc); - LineString += utostr(PLoc.getLine()); - LineString += " \""; - LineString += Lexer::Stringify(PLoc.getFilename()); - LineString += "\"\n"; - } -} - -/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach -/// statement to continue with its inner synthesized loop. -/// -Stmt *RewriteModernObjC::RewriteContinueStmt(ContinueStmt *S) { - if (Stmts.empty() || !isa(Stmts.back())) - return S; - // replace continue with goto __continue_label - std::string buf; - - SourceLocation startLoc = S->getBeginLoc(); - buf = "goto __continue_label_"; - buf += utostr(ObjCBcLabelNo.back()); - ReplaceText(startLoc, strlen("continue"), buf); - - return nullptr; -} - -/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement. -/// It rewrites: -/// for ( type elem in collection) { stmts; } - -/// Into: -/// { -/// type elem; -/// struct __objcFastEnumerationState enumState = { 0 }; -/// id __rw_items[16]; -/// id l_collection = (id)collection; -/// NSUInteger limit = [l_collection countByEnumeratingWithState:&enumState -/// objects:__rw_items count:16]; -/// if (limit) { -/// unsigned long startMutations = *enumState.mutationsPtr; -/// do { -/// unsigned long counter = 0; -/// do { -/// if (startMutations != *enumState.mutationsPtr) -/// objc_enumerationMutation(l_collection); -/// elem = (type)enumState.itemsPtr[counter++]; -/// stmts; -/// __continue_label: ; -/// } while (counter < limit); -/// } while ((limit = [l_collection countByEnumeratingWithState:&enumState -/// objects:__rw_items count:16])); -/// elem = nil; -/// __break_label: ; -/// } -/// else -/// elem = nil; -/// } -/// -Stmt *RewriteModernObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, - SourceLocation OrigEnd) { - assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty"); - assert(isa(Stmts.back()) && - "ObjCForCollectionStmt Statement stack mismatch"); - assert(!ObjCBcLabelNo.empty() && - "ObjCForCollectionStmt - Label No stack empty"); - - SourceLocation startLoc = S->getBeginLoc(); - const char *startBuf = SM->getCharacterData(startLoc); - StringRef elementName; - std::string elementTypeAsString; - std::string buf; - // line directive first. - SourceLocation ForEachLoc = S->getForLoc(); - ConvertSourceLocationToLineDirective(ForEachLoc, buf); - buf += "{\n\t"; - if (DeclStmt *DS = dyn_cast(S->getElement())) { - // type elem; - NamedDecl* D = cast(DS->getSingleDecl()); - QualType ElementType = cast(D)->getType(); - if (ElementType->isObjCQualifiedIdType() || - ElementType->isObjCQualifiedInterfaceType()) - // Simply use 'id' for all qualified types. - elementTypeAsString = "id"; - else - elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy()); - buf += elementTypeAsString; - buf += " "; - elementName = D->getName(); - buf += elementName; - buf += ";\n\t"; - } - else { - DeclRefExpr *DR = cast(S->getElement()); - elementName = DR->getDecl()->getName(); - ValueDecl *VD = DR->getDecl(); - if (VD->getType()->isObjCQualifiedIdType() || - VD->getType()->isObjCQualifiedInterfaceType()) - // Simply use 'id' for all qualified types. - elementTypeAsString = "id"; - else - elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy()); - } - - // struct __objcFastEnumerationState enumState = { 0 }; - buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t"; - // id __rw_items[16]; - buf += "id __rw_items[16];\n\t"; - // id l_collection = (id) - buf += "id l_collection = (id)"; - // Find start location of 'collection' the hard way! - const char *startCollectionBuf = startBuf; - startCollectionBuf += 3; // skip 'for' - startCollectionBuf = strchr(startCollectionBuf, '('); - startCollectionBuf++; // skip '(' - // find 'in' and skip it. - while (*startCollectionBuf != ' ' || - *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' || - (*(startCollectionBuf+3) != ' ' && - *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '(')) - startCollectionBuf++; - startCollectionBuf += 3; - - // Replace: "for (type element in" with string constructed thus far. - ReplaceText(startLoc, startCollectionBuf - startBuf, buf); - // Replace ')' in for '(' type elem in collection ')' with ';' - SourceLocation rightParenLoc = S->getRParenLoc(); - const char *rparenBuf = SM->getCharacterData(rightParenLoc); - SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf); - buf = ";\n\t"; - - // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState - // objects:__rw_items count:16]; - // which is synthesized into: - // NSUInteger limit = - // ((NSUInteger (*) - // (id, SEL, struct __objcFastEnumerationState *, id *, NSUInteger)) - // (void *)objc_msgSend)((id)l_collection, - // sel_registerName( - // "countByEnumeratingWithState:objects:count:"), - // (struct __objcFastEnumerationState *)&state, - // (id *)__rw_items, (NSUInteger)16); - buf += "_WIN_NSUInteger limit =\n\t\t"; - SynthCountByEnumWithState(buf); - buf += ";\n\t"; - /// if (limit) { - /// unsigned long startMutations = *enumState.mutationsPtr; - /// do { - /// unsigned long counter = 0; - /// do { - /// if (startMutations != *enumState.mutationsPtr) - /// objc_enumerationMutation(l_collection); - /// elem = (type)enumState.itemsPtr[counter++]; - buf += "if (limit) {\n\t"; - buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t"; - buf += "do {\n\t\t"; - buf += "unsigned long counter = 0;\n\t\t"; - buf += "do {\n\t\t\t"; - buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t"; - buf += "objc_enumerationMutation(l_collection);\n\t\t\t"; - buf += elementName; - buf += " = ("; - buf += elementTypeAsString; - buf += ")enumState.itemsPtr[counter++];"; - // Replace ')' in for '(' type elem in collection ')' with all of these. - ReplaceText(lparenLoc, 1, buf); - - /// __continue_label: ; - /// } while (counter < limit); - /// } while ((limit = [l_collection countByEnumeratingWithState:&enumState - /// objects:__rw_items count:16])); - /// elem = nil; - /// __break_label: ; - /// } - /// else - /// elem = nil; - /// } - /// - buf = ";\n\t"; - buf += "__continue_label_"; - buf += utostr(ObjCBcLabelNo.back()); - buf += ": ;"; - buf += "\n\t\t"; - buf += "} while (counter < limit);\n\t"; - buf += "} while ((limit = "; - SynthCountByEnumWithState(buf); - buf += "));\n\t"; - buf += elementName; - buf += " = (("; - buf += elementTypeAsString; - buf += ")0);\n\t"; - buf += "__break_label_"; - buf += utostr(ObjCBcLabelNo.back()); - buf += ": ;\n\t"; - buf += "}\n\t"; - buf += "else\n\t\t"; - buf += elementName; - buf += " = (("; - buf += elementTypeAsString; - buf += ")0);\n\t"; - buf += "}\n"; - - // Insert all these *after* the statement body. - // FIXME: If this should support Obj-C++, support CXXTryStmt - if (isa(S->getBody())) { - SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1); - InsertText(endBodyLoc, buf); - } else { - /* Need to treat single statements specially. For example: - * - * for (A *a in b) if (stuff()) break; - * for (A *a in b) xxxyy; - * - * The following code simply scans ahead to the semi to find the actual end. - */ - const char *stmtBuf = SM->getCharacterData(OrigEnd); - const char *semiBuf = strchr(stmtBuf, ';'); - assert(semiBuf && "Can't find ';'"); - SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1); - InsertText(endBodyLoc, buf); - } - Stmts.pop_back(); - ObjCBcLabelNo.pop_back(); - return nullptr; -} - -static void Write_RethrowObject(std::string &buf) { - buf += "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n"; - buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n"; - buf += "\tid rethrow;\n"; - buf += "\t} _fin_force_rethow(_rethrow);"; -} - -/// RewriteObjCSynchronizedStmt - -/// This routine rewrites @synchronized(expr) stmt; -/// into: -/// objc_sync_enter(expr); -/// @try stmt @finally { objc_sync_exit(expr); } -/// -Stmt *RewriteModernObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) { - // Get the start location and compute the semi location. - SourceLocation startLoc = S->getBeginLoc(); - const char *startBuf = SM->getCharacterData(startLoc); - - assert((*startBuf == '@') && "bogus @synchronized location"); - - std::string buf; - SourceLocation SynchLoc = S->getAtSynchronizedLoc(); - ConvertSourceLocationToLineDirective(SynchLoc, buf); - buf += "{ id _rethrow = 0; id _sync_obj = (id)"; - - const char *lparenBuf = startBuf; - while (*lparenBuf != '(') lparenBuf++; - ReplaceText(startLoc, lparenBuf-startBuf+1, buf); - - buf = "; objc_sync_enter(_sync_obj);\n"; - buf += "try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}"; - buf += "\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}"; - buf += "\n\tid sync_exit;"; - buf += "\n\t} _sync_exit(_sync_obj);\n"; - - // We can't use S->getSynchExpr()->getEndLoc() to find the end location, since - // the sync expression is typically a message expression that's already - // been rewritten! (which implies the SourceLocation's are invalid). - SourceLocation RParenExprLoc = S->getSynchBody()->getBeginLoc(); - const char *RParenExprLocBuf = SM->getCharacterData(RParenExprLoc); - while (*RParenExprLocBuf != ')') RParenExprLocBuf--; - RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf); - - SourceLocation LBranceLoc = S->getSynchBody()->getBeginLoc(); - const char *LBraceLocBuf = SM->getCharacterData(LBranceLoc); - assert (*LBraceLocBuf == '{'); - ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->getCharacterData(RParenExprLoc) + 1), buf); - - SourceLocation startRBraceLoc = S->getSynchBody()->getEndLoc(); - assert((*SM->getCharacterData(startRBraceLoc) == '}') && - "bogus @synchronized block"); - - buf = "} catch (id e) {_rethrow = e;}\n"; - Write_RethrowObject(buf); - buf += "}\n"; - buf += "}\n"; - - ReplaceText(startRBraceLoc, 1, buf); - - return nullptr; -} - -void RewriteModernObjC::WarnAboutReturnGotoStmts(Stmt *S) -{ - // Perform a bottom up traversal of all children. - for (Stmt *SubStmt : S->children()) - if (SubStmt) - WarnAboutReturnGotoStmts(SubStmt); - - if (isa(S) || isa(S)) { - Diags.Report(Context->getFullLoc(S->getBeginLoc()), - TryFinallyContainsReturnDiag); - } -} - -Stmt *RewriteModernObjC::RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { - SourceLocation startLoc = S->getAtLoc(); - ReplaceText(startLoc, strlen("@autoreleasepool"), "/* @autoreleasepool */"); - ReplaceText(S->getSubStmt()->getBeginLoc(), 1, - "{ __AtAutoreleasePool __autoreleasepool; "); - - return nullptr; -} - -Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { - ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt(); - bool noCatch = S->getNumCatchStmts() == 0; - std::string buf; - SourceLocation TryLocation = S->getAtTryLoc(); - ConvertSourceLocationToLineDirective(TryLocation, buf); - - if (finalStmt) { - if (noCatch) - buf += "{ id volatile _rethrow = 0;\n"; - else { - buf += "{ id volatile _rethrow = 0;\ntry {\n"; - } - } - // Get the start location and compute the semi location. - SourceLocation startLoc = S->getBeginLoc(); - const char *startBuf = SM->getCharacterData(startLoc); - - assert((*startBuf == '@') && "bogus @try location"); - if (finalStmt) - ReplaceText(startLoc, 1, buf); - else - // @try -> try - ReplaceText(startLoc, 1, ""); - - for (ObjCAtCatchStmt *Catch : S->catch_stmts()) { - VarDecl *catchDecl = Catch->getCatchParamDecl(); - - startLoc = Catch->getBeginLoc(); - bool AtRemoved = false; - if (catchDecl) { - QualType t = catchDecl->getType(); - if (const ObjCObjectPointerType *Ptr = - t->getAs()) { - // Should be a pointer to a class. - ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface(); - if (IDecl) { - std::string Result; - ConvertSourceLocationToLineDirective(Catch->getBeginLoc(), Result); - - startBuf = SM->getCharacterData(startLoc); - assert((*startBuf == '@') && "bogus @catch location"); - SourceLocation rParenLoc = Catch->getRParenLoc(); - const char *rParenBuf = SM->getCharacterData(rParenLoc); - - // _objc_exc_Foo *_e as argument to catch. - Result += "catch (_objc_exc_"; Result += IDecl->getNameAsString(); - Result += " *_"; Result += catchDecl->getNameAsString(); - Result += ")"; - ReplaceText(startLoc, rParenBuf-startBuf+1, Result); - // Foo *e = (Foo *)_e; - Result.clear(); - Result = "{ "; - Result += IDecl->getNameAsString(); - Result += " *"; Result += catchDecl->getNameAsString(); - Result += " = ("; Result += IDecl->getNameAsString(); Result += "*)"; - Result += "_"; Result += catchDecl->getNameAsString(); - - Result += "; "; - SourceLocation lBraceLoc = Catch->getCatchBody()->getBeginLoc(); - ReplaceText(lBraceLoc, 1, Result); - AtRemoved = true; - } - } - } - if (!AtRemoved) - // @catch -> catch - ReplaceText(startLoc, 1, ""); - - } - if (finalStmt) { - buf.clear(); - SourceLocation FinallyLoc = finalStmt->getBeginLoc(); - - if (noCatch) { - ConvertSourceLocationToLineDirective(FinallyLoc, buf); - buf += "catch (id e) {_rethrow = e;}\n"; - } - else { - buf += "}\n"; - ConvertSourceLocationToLineDirective(FinallyLoc, buf); - buf += "catch (id e) {_rethrow = e;}\n"; - } - - SourceLocation startFinalLoc = finalStmt->getBeginLoc(); - ReplaceText(startFinalLoc, 8, buf); - Stmt *body = finalStmt->getFinallyBody(); - SourceLocation startFinalBodyLoc = body->getBeginLoc(); - buf.clear(); - Write_RethrowObject(buf); - ReplaceText(startFinalBodyLoc, 1, buf); - - SourceLocation endFinalBodyLoc = body->getEndLoc(); - ReplaceText(endFinalBodyLoc, 1, "}\n}"); - // Now check for any return/continue/go statements within the @try. - WarnAboutReturnGotoStmts(S->getTryBody()); - } - - return nullptr; -} - -// This can't be done with ReplaceStmt(S, ThrowExpr), since -// the throw expression is typically a message expression that's already -// been rewritten! (which implies the SourceLocation's are invalid). -Stmt *RewriteModernObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) { - // Get the start location and compute the semi location. - SourceLocation startLoc = S->getBeginLoc(); - const char *startBuf = SM->getCharacterData(startLoc); - - assert((*startBuf == '@') && "bogus @throw location"); - - std::string buf; - /* void objc_exception_throw(id) __attribute__((noreturn)); */ - if (S->getThrowExpr()) - buf = "objc_exception_throw("; - else - buf = "throw"; - - // handle "@ throw" correctly. - const char *wBuf = strchr(startBuf, 'w'); - assert((*wBuf == 'w') && "@throw: can't find 'w'"); - ReplaceText(startLoc, wBuf-startBuf+1, buf); - - SourceLocation endLoc = S->getEndLoc(); - const char *endBuf = SM->getCharacterData(endLoc); - const char *semiBuf = strchr(endBuf, ';'); - assert((*semiBuf == ';') && "@throw: can't find ';'"); - SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf); - if (S->getThrowExpr()) - ReplaceText(semiLoc, 1, ");"); - return nullptr; -} - -Stmt *RewriteModernObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) { - // Create a new string expression. - std::string StrEncoding; - Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding); - Expr *Replacement = getStringLiteral(StrEncoding); - ReplaceStmt(Exp, Replacement); - - // Replace this subexpr in the parent. - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return Replacement; -} - -Stmt *RewriteModernObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) { - if (!SelGetUidFunctionDecl) - SynthSelGetUidFunctionDecl(); - assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl"); - // Create a call to sel_registerName("selName"). - SmallVector SelExprs; - SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString())); - CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, - SelExprs); - ReplaceStmt(Exp, SelExp); - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return SelExp; -} - -CallExpr * -RewriteModernObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD, - ArrayRef Args, - SourceLocation StartLoc, - SourceLocation EndLoc) { - // Get the type, we will need to reference it in a couple spots. - QualType msgSendType = FD->getType(); - - // Create a reference to the objc_msgSend() declaration. - DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, FD, false, msgSendType, - VK_LValue, SourceLocation()); - - // Now, we cast the reference to a pointer to the objc_msgSend type. - QualType pToFunc = Context->getPointerType(msgSendType); - ImplicitCastExpr *ICE = - ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay, - DRE, nullptr, VK_PRValue, FPOptionsOverride()); - - const auto *FT = msgSendType->castAs(); - CallExpr *Exp = - CallExpr::Create(*Context, ICE, Args, FT->getCallResultType(*Context), - VK_PRValue, EndLoc, FPOptionsOverride()); - return Exp; -} - -static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, - const char *&startRef, const char *&endRef) { - while (startBuf < endBuf) { - if (*startBuf == '<') - startRef = startBuf; // mark the start. - if (*startBuf == '>') { - if (startRef && *startRef == '<') { - endRef = startBuf; // mark the end. - return true; - } - return false; - } - startBuf++; - } - return false; -} - -static void scanToNextArgument(const char *&argRef) { - int angle = 0; - while (*argRef != ')' && (*argRef != ',' || angle > 0)) { - if (*argRef == '<') - angle++; - else if (*argRef == '>') - angle--; - argRef++; - } - assert(angle == 0 && "scanToNextArgument - bad protocol type syntax"); -} - -bool RewriteModernObjC::needToScanForQualifiers(QualType T) { - if (T->isObjCQualifiedIdType()) - return true; - if (const PointerType *PT = T->getAs()) { - if (PT->getPointeeType()->isObjCQualifiedIdType()) - return true; - } - if (T->isObjCObjectPointerType()) { - T = T->getPointeeType(); - return T->isObjCQualifiedInterfaceType(); - } - if (T->isArrayType()) { - QualType ElemTy = Context->getBaseElementType(T); - return needToScanForQualifiers(ElemTy); - } - return false; -} - -void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) { - QualType Type = E->getType(); - if (needToScanForQualifiers(Type)) { - SourceLocation Loc, EndLoc; - - if (const CStyleCastExpr *ECE = dyn_cast(E)) { - Loc = ECE->getLParenLoc(); - EndLoc = ECE->getRParenLoc(); - } else { - Loc = E->getBeginLoc(); - EndLoc = E->getEndLoc(); - } - // This will defend against trying to rewrite synthesized expressions. - if (Loc.isInvalid() || EndLoc.isInvalid()) - return; - - const char *startBuf = SM->getCharacterData(Loc); - const char *endBuf = SM->getCharacterData(EndLoc); - const char *startRef = nullptr, *endRef = nullptr; - if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { - // Get the locations of the startRef, endRef. - SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf); - SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1); - // Comment out the protocol references. - InsertText(LessLoc, "/*"); - InsertText(GreaterLoc, "*/"); - } - } -} - -void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) { - SourceLocation Loc; - QualType Type; - const FunctionProtoType *proto = nullptr; - if (VarDecl *VD = dyn_cast(Dcl)) { - Loc = VD->getLocation(); - Type = VD->getType(); - } - else if (FunctionDecl *FD = dyn_cast(Dcl)) { - Loc = FD->getLocation(); - // Check for ObjC 'id' and class types that have been adorned with protocol - // information (id

, C

*). The protocol references need to be rewritten! - const FunctionType *funcType = FD->getType()->getAs(); - assert(funcType && "missing function type"); - proto = dyn_cast(funcType); - if (!proto) - return; - Type = proto->getReturnType(); - } - else if (FieldDecl *FD = dyn_cast(Dcl)) { - Loc = FD->getLocation(); - Type = FD->getType(); - } - else if (TypedefNameDecl *TD = dyn_cast(Dcl)) { - Loc = TD->getLocation(); - Type = TD->getUnderlyingType(); - } - else - return; - - if (needToScanForQualifiers(Type)) { - // Since types are unique, we need to scan the buffer. - - const char *endBuf = SM->getCharacterData(Loc); - const char *startBuf = endBuf; - while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart) - startBuf--; // scan backward (from the decl location) for return type. - const char *startRef = nullptr, *endRef = nullptr; - if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { - // Get the locations of the startRef, endRef. - SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf); - SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1); - // Comment out the protocol references. - InsertText(LessLoc, "/*"); - InsertText(GreaterLoc, "*/"); - } - } - if (!proto) - return; // most likely, was a variable - // Now check arguments. - const char *startBuf = SM->getCharacterData(Loc); - const char *startFuncBuf = startBuf; - for (unsigned i = 0; i < proto->getNumParams(); i++) { - if (needToScanForQualifiers(proto->getParamType(i))) { - // Since types are unique, we need to scan the buffer. - - const char *endBuf = startBuf; - // scan forward (from the decl location) for argument types. - scanToNextArgument(endBuf); - const char *startRef = nullptr, *endRef = nullptr; - if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { - // Get the locations of the startRef, endRef. - SourceLocation LessLoc = - Loc.getLocWithOffset(startRef-startFuncBuf); - SourceLocation GreaterLoc = - Loc.getLocWithOffset(endRef-startFuncBuf+1); - // Comment out the protocol references. - InsertText(LessLoc, "/*"); - InsertText(GreaterLoc, "*/"); - } - startBuf = ++endBuf; - } - else { - // If the function name is derived from a macro expansion, then the - // argument buffer will not follow the name. Need to speak with Chris. - while (*startBuf && *startBuf != ')' && *startBuf != ',') - startBuf++; // scan forward (from the decl location) for argument types. - startBuf++; - } - } -} - -void RewriteModernObjC::RewriteTypeOfDecl(VarDecl *ND) { - QualType QT = ND->getType(); - const Type* TypePtr = QT->getAs(); - if (!isa(TypePtr)) - return; - while (isa(TypePtr)) { - const TypeOfExprType *TypeOfExprTypePtr = cast(TypePtr); - QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); - TypePtr = QT->getAs(); - } - // FIXME. This will not work for multiple declarators; as in: - // __typeof__(a) b,c,d; - std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy())); - SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); - const char *startBuf = SM->getCharacterData(DeclLoc); - if (ND->getInit()) { - std::string Name(ND->getNameAsString()); - TypeAsString += " " + Name + " = "; - Expr *E = ND->getInit(); - SourceLocation startLoc; - if (const CStyleCastExpr *ECE = dyn_cast(E)) - startLoc = ECE->getLParenLoc(); - else - startLoc = E->getBeginLoc(); - startLoc = SM->getExpansionLoc(startLoc); - const char *endBuf = SM->getCharacterData(startLoc); - ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); - } - else { - SourceLocation X = ND->getEndLoc(); - X = SM->getExpansionLoc(X); - const char *endBuf = SM->getCharacterData(X); - ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); - } -} - -// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str); -void RewriteModernObjC::SynthSelGetUidFunctionDecl() { - IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName"); - SmallVector ArgTys; - ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); - QualType getFuncType = - getSimpleFunctionType(Context->getObjCSelType(), ArgTys); - SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - SelGetUidIdent, getFuncType, - nullptr, SC_Extern); -} - -void RewriteModernObjC::RewriteFunctionDecl(FunctionDecl *FD) { - // declared in - if (FD->getIdentifier() && - FD->getName() == "sel_registerName") { - SelGetUidFunctionDecl = FD; - return; - } - RewriteObjCQualifiedInterfaceTypes(FD); -} - -void RewriteModernObjC::RewriteBlockPointerType(std::string& Str, QualType Type) { - std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); - const char *argPtr = TypeString.c_str(); - if (!strchr(argPtr, '^')) { - Str += TypeString; - return; - } - while (*argPtr) { - Str += (*argPtr == '^' ? '*' : *argPtr); - argPtr++; - } -} - -// FIXME. Consolidate this routine with RewriteBlockPointerType. -void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str, - ValueDecl *VD) { - QualType Type = VD->getType(); - std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); - const char *argPtr = TypeString.c_str(); - int paren = 0; - while (*argPtr) { - switch (*argPtr) { - case '(': - Str += *argPtr; - paren++; - break; - case ')': - Str += *argPtr; - paren--; - break; - case '^': - Str += '*'; - if (paren == 1) - Str += VD->getNameAsString(); - break; - default: - Str += *argPtr; - break; - } - argPtr++; - } -} - -void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { - SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); - const FunctionType *funcType = FD->getType()->getAs(); - const FunctionProtoType *proto = dyn_cast(funcType); - if (!proto) - return; - QualType Type = proto->getReturnType(); - std::string FdStr = Type.getAsString(Context->getPrintingPolicy()); - FdStr += " "; - FdStr += FD->getName(); - FdStr += "("; - unsigned numArgs = proto->getNumParams(); - for (unsigned i = 0; i < numArgs; i++) { - QualType ArgType = proto->getParamType(i); - RewriteBlockPointerType(FdStr, ArgType); - if (i+1 < numArgs) - FdStr += ", "; - } - if (FD->isVariadic()) { - FdStr += (numArgs > 0) ? ", ...);\n" : "...);\n"; - } - else - FdStr += ");\n"; - InsertText(FunLocStart, FdStr); -} - -// SynthSuperConstructorFunctionDecl - id __rw_objc_super(id obj, id super); -void RewriteModernObjC::SynthSuperConstructorFunctionDecl() { - if (SuperConstructorFunctionDecl) - return; - IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super"); - SmallVector ArgTys; - QualType argT = Context->getObjCIdType(); - assert(!argT.isNull() && "Can't find 'id' type"); - ArgTys.push_back(argT); - ArgTys.push_back(argT); - QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys); - SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, msgSendType, - nullptr, SC_Extern); -} - -// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); -void RewriteModernObjC::SynthMsgSendFunctionDecl() { - IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend"); - SmallVector ArgTys; - QualType argT = Context->getObjCIdType(); - assert(!argT.isNull() && "Can't find 'id' type"); - ArgTys.push_back(argT); - argT = Context->getObjCSelType(); - assert(!argT.isNull() && "Can't find 'SEL' type"); - ArgTys.push_back(argT); - QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys, /*variadic=*/true); - MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, msgSendType, nullptr, - SC_Extern); -} - -// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(void); -void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() { - IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); - SmallVector ArgTys; - ArgTys.push_back(Context->VoidTy); - QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys, /*variadic=*/true); - MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, msgSendType, - nullptr, SC_Extern); -} - -// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...); -void RewriteModernObjC::SynthMsgSendStretFunctionDecl() { - IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret"); - SmallVector ArgTys; - QualType argT = Context->getObjCIdType(); - assert(!argT.isNull() && "Can't find 'id' type"); - ArgTys.push_back(argT); - argT = Context->getObjCSelType(); - assert(!argT.isNull() && "Can't find 'SEL' type"); - ArgTys.push_back(argT); - QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys, /*variadic=*/true); - MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, msgSendType, - nullptr, SC_Extern); -} - -// SynthMsgSendSuperStretFunctionDecl - -// id objc_msgSendSuper_stret(void); -void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() { - IdentifierInfo *msgSendIdent = - &Context->Idents.get("objc_msgSendSuper_stret"); - SmallVector ArgTys; - ArgTys.push_back(Context->VoidTy); - QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys, /*variadic=*/true); - MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, - msgSendType, nullptr, - SC_Extern); -} - -// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...); -void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() { - IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret"); - SmallVector ArgTys; - QualType argT = Context->getObjCIdType(); - assert(!argT.isNull() && "Can't find 'id' type"); - ArgTys.push_back(argT); - argT = Context->getObjCSelType(); - assert(!argT.isNull() && "Can't find 'SEL' type"); - ArgTys.push_back(argT); - QualType msgSendType = getSimpleFunctionType(Context->DoubleTy, - ArgTys, /*variadic=*/true); - MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, msgSendType, - nullptr, SC_Extern); -} - -// SynthGetClassFunctionDecl - Class objc_getClass(const char *name); -void RewriteModernObjC::SynthGetClassFunctionDecl() { - IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass"); - SmallVector ArgTys; - ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); - QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), - ArgTys); - GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - getClassIdent, getClassType, - nullptr, SC_Extern); -} - -// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls); -void RewriteModernObjC::SynthGetSuperClassFunctionDecl() { - IdentifierInfo *getSuperClassIdent = - &Context->Idents.get("class_getSuperclass"); - SmallVector ArgTys; - ArgTys.push_back(Context->getObjCClassType()); - QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), - ArgTys); - GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - getSuperClassIdent, - getClassType, nullptr, - SC_Extern); -} - -// SynthGetMetaClassFunctionDecl - Class objc_getMetaClass(const char *name); -void RewriteModernObjC::SynthGetMetaClassFunctionDecl() { - IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass"); - SmallVector ArgTys; - ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); - QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), - ArgTys); - GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - getClassIdent, getClassType, - nullptr, SC_Extern); -} - -Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { - assert (Exp != nullptr && "Expected non-null ObjCStringLiteral"); - QualType strType = getConstantStringStructType(); - - std::string S = "__NSConstantStringImpl_"; - - std::string tmpName = InFileName; - unsigned i; - for (i=0; i < tmpName.length(); i++) { - char c = tmpName.at(i); - // replace any non-alphanumeric characters with '_'. - if (!isAlphanumeric(c)) - tmpName[i] = '_'; - } - S += tmpName; - S += "_"; - S += utostr(NumObjCStringLiterals++); - - Preamble += "static __NSConstantStringImpl " + S; - Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,"; - Preamble += "0x000007c8,"; // utf8_str - // The pretty printer for StringLiteral handles escape characters properly. - std::string prettyBufS; - llvm::raw_string_ostream prettyBuf(prettyBufS); - Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts)); - Preamble += prettyBufS; - Preamble += ","; - Preamble += utostr(Exp->getString()->getByteLength()) + "};\n"; - - VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), - SourceLocation(), &Context->Idents.get(S), - strType, nullptr, SC_Static); - DeclRefExpr *DRE = new (Context) - DeclRefExpr(*Context, NewVD, false, strType, VK_LValue, SourceLocation()); - Expr *Unop = UnaryOperator::Create( - const_cast(*Context), DRE, UO_AddrOf, - Context->getPointerType(DRE->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - // cast to NSConstantString * - CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), - CK_CPointerToObjCPointerCast, Unop); - ReplaceStmt(Exp, cast); - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return cast; -} - -Stmt *RewriteModernObjC::RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp) { - unsigned IntSize = - static_cast(Context->getTypeSize(Context->IntTy)); - - Expr *FlagExp = IntegerLiteral::Create(*Context, - llvm::APInt(IntSize, Exp->getValue()), - Context->IntTy, Exp->getLocation()); - CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy, - CK_BitCast, FlagExp); - ParenExpr *PE = new (Context) ParenExpr(Exp->getLocation(), Exp->getExprLoc(), - cast); - ReplaceStmt(Exp, PE); - return PE; -} - -Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) { - // synthesize declaration of helper functions needed in this routine. - if (!SelGetUidFunctionDecl) - SynthSelGetUidFunctionDecl(); - // use objc_msgSend() for all. - if (!MsgSendFunctionDecl) - SynthMsgSendFunctionDecl(); - if (!GetClassFunctionDecl) - SynthGetClassFunctionDecl(); - - FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; - SourceLocation StartLoc = Exp->getBeginLoc(); - SourceLocation EndLoc = Exp->getEndLoc(); - - // Synthesize a call to objc_msgSend(). - SmallVector MsgExprs; - SmallVector ClsExprs; - - // Create a call to objc_getClass(""). It will be the 1st argument. - ObjCMethodDecl *BoxingMethod = Exp->getBoxingMethod(); - ObjCInterfaceDecl *BoxingClass = BoxingMethod->getClassInterface(); - - IdentifierInfo *clsName = BoxingClass->getIdentifier(); - ClsExprs.push_back(getStringLiteral(clsName->getName())); - CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - MsgExprs.push_back(Cls); - - // Create a call to sel_registerName(":"), etc. - // it will be the 2nd argument. - SmallVector SelExprs; - SelExprs.push_back( - getStringLiteral(BoxingMethod->getSelector().getAsString())); - CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, - SelExprs, StartLoc, EndLoc); - MsgExprs.push_back(SelExp); - - // User provided sub-expression is the 3rd, and last, argument. - Expr *subExpr = Exp->getSubExpr(); - if (ImplicitCastExpr *ICE = dyn_cast(subExpr)) { - QualType type = ICE->getType(); - const Expr *SubExpr = ICE->IgnoreParenImpCasts(); - CastKind CK = CK_BitCast; - if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType()) - CK = CK_IntegralToBoolean; - subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr); - } - MsgExprs.push_back(subExpr); - - SmallVector ArgTypes; - ArgTypes.push_back(Context->getObjCClassType()); - ArgTypes.push_back(Context->getObjCSelType()); - for (const auto PI : BoxingMethod->parameters()) - ArgTypes.push_back(PI->getType()); - - QualType returnType = Exp->getType(); - // Get the type, we will need to reference it in a couple spots. - QualType msgSendType = MsgSendFlavor->getType(); - - // Create a reference to the objc_msgSend() declaration. - DeclRefExpr *DRE = new (Context) DeclRefExpr( - *Context, MsgSendFlavor, false, msgSendType, VK_LValue, SourceLocation()); - - CastExpr *cast = NoTypeInfoCStyleCastExpr( - Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE); - - // Now do the "normal" pointer to function cast. - QualType castType = - getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->isVariadic()); - castType = Context->getPointerType(castType); - cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, - cast); - - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); - - auto *FT = msgSendType->castAs(); - CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(), - VK_PRValue, EndLoc, FPOptionsOverride()); - ReplaceStmt(Exp, CE); - return CE; -} - -Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) { - // synthesize declaration of helper functions needed in this routine. - if (!SelGetUidFunctionDecl) - SynthSelGetUidFunctionDecl(); - // use objc_msgSend() for all. - if (!MsgSendFunctionDecl) - SynthMsgSendFunctionDecl(); - if (!GetClassFunctionDecl) - SynthGetClassFunctionDecl(); - - FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; - SourceLocation StartLoc = Exp->getBeginLoc(); - SourceLocation EndLoc = Exp->getEndLoc(); - - // Build the expression: __NSContainer_literal(int, ...).arr - QualType IntQT = Context->IntTy; - QualType NSArrayFType = - getSimpleFunctionType(Context->VoidTy, IntQT, true); - std::string NSArrayFName("__NSContainer_literal"); - FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName); - DeclRefExpr *NSArrayDRE = new (Context) DeclRefExpr( - *Context, NSArrayFD, false, NSArrayFType, VK_PRValue, SourceLocation()); - - SmallVector InitExprs; - unsigned NumElements = Exp->getNumElements(); - unsigned UnsignedIntSize = - static_cast(Context->getTypeSize(Context->UnsignedIntTy)); - Expr *count = IntegerLiteral::Create(*Context, - llvm::APInt(UnsignedIntSize, NumElements), - Context->UnsignedIntTy, SourceLocation()); - InitExprs.push_back(count); - for (unsigned i = 0; i < NumElements; i++) - InitExprs.push_back(Exp->getElement(i)); - Expr *NSArrayCallExpr = - CallExpr::Create(*Context, NSArrayDRE, InitExprs, NSArrayFType, VK_LValue, - SourceLocation(), FPOptionsOverride()); - - FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(), - SourceLocation(), - &Context->Idents.get("arr"), - Context->getPointerType(Context->VoidPtrTy), - nullptr, /*BitWidth=*/nullptr, - /*Mutable=*/true, ICIS_NoInit); - MemberExpr *ArrayLiteralME = - MemberExpr::CreateImplicit(*Context, NSArrayCallExpr, false, ARRFD, - ARRFD->getType(), VK_LValue, OK_Ordinary); - QualType ConstIdT = Context->getObjCIdType().withConst(); - CStyleCastExpr * ArrayLiteralObjects = - NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(ConstIdT), - CK_BitCast, - ArrayLiteralME); - - // Synthesize a call to objc_msgSend(). - SmallVector MsgExprs; - SmallVector ClsExprs; - QualType expType = Exp->getType(); - - // Create a call to objc_getClass("NSArray"). It will be th 1st argument. - ObjCInterfaceDecl *Class = - expType->getPointeeType()->castAs()->getInterface(); - - IdentifierInfo *clsName = Class->getIdentifier(); - ClsExprs.push_back(getStringLiteral(clsName->getName())); - CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - MsgExprs.push_back(Cls); - - // Create a call to sel_registerName("arrayWithObjects:count:"). - // it will be the 2nd argument. - SmallVector SelExprs; - ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod(); - SelExprs.push_back( - getStringLiteral(ArrayMethod->getSelector().getAsString())); - CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, - SelExprs, StartLoc, EndLoc); - MsgExprs.push_back(SelExp); - - // (const id [])objects - MsgExprs.push_back(ArrayLiteralObjects); - - // (NSUInteger)cnt - Expr *cnt = IntegerLiteral::Create(*Context, - llvm::APInt(UnsignedIntSize, NumElements), - Context->UnsignedIntTy, SourceLocation()); - MsgExprs.push_back(cnt); - - SmallVector ArgTypes; - ArgTypes.push_back(Context->getObjCClassType()); - ArgTypes.push_back(Context->getObjCSelType()); - for (const auto *PI : ArrayMethod->parameters()) - ArgTypes.push_back(PI->getType()); - - QualType returnType = Exp->getType(); - // Get the type, we will need to reference it in a couple spots. - QualType msgSendType = MsgSendFlavor->getType(); - - // Create a reference to the objc_msgSend() declaration. - DeclRefExpr *DRE = new (Context) DeclRefExpr( - *Context, MsgSendFlavor, false, msgSendType, VK_LValue, SourceLocation()); - - CastExpr *cast = NoTypeInfoCStyleCastExpr( - Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE); - - // Now do the "normal" pointer to function cast. - QualType castType = - getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->isVariadic()); - castType = Context->getPointerType(castType); - cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, - cast); - - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); - - const FunctionType *FT = msgSendType->castAs(); - CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(), - VK_PRValue, EndLoc, FPOptionsOverride()); - ReplaceStmt(Exp, CE); - return CE; -} - -Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp) { - // synthesize declaration of helper functions needed in this routine. - if (!SelGetUidFunctionDecl) - SynthSelGetUidFunctionDecl(); - // use objc_msgSend() for all. - if (!MsgSendFunctionDecl) - SynthMsgSendFunctionDecl(); - if (!GetClassFunctionDecl) - SynthGetClassFunctionDecl(); - - FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; - SourceLocation StartLoc = Exp->getBeginLoc(); - SourceLocation EndLoc = Exp->getEndLoc(); - - // Build the expression: __NSContainer_literal(int, ...).arr - QualType IntQT = Context->IntTy; - QualType NSDictFType = - getSimpleFunctionType(Context->VoidTy, IntQT, true); - std::string NSDictFName("__NSContainer_literal"); - FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName); - DeclRefExpr *NSDictDRE = new (Context) DeclRefExpr( - *Context, NSDictFD, false, NSDictFType, VK_PRValue, SourceLocation()); - - SmallVector KeyExprs; - SmallVector ValueExprs; - - unsigned NumElements = Exp->getNumElements(); - unsigned UnsignedIntSize = - static_cast(Context->getTypeSize(Context->UnsignedIntTy)); - Expr *count = IntegerLiteral::Create(*Context, - llvm::APInt(UnsignedIntSize, NumElements), - Context->UnsignedIntTy, SourceLocation()); - KeyExprs.push_back(count); - ValueExprs.push_back(count); - for (unsigned i = 0; i < NumElements; i++) { - ObjCDictionaryElement Element = Exp->getKeyValueElement(i); - KeyExprs.push_back(Element.Key); - ValueExprs.push_back(Element.Value); - } - - // (const id [])objects - Expr *NSValueCallExpr = - CallExpr::Create(*Context, NSDictDRE, ValueExprs, NSDictFType, VK_LValue, - SourceLocation(), FPOptionsOverride()); - - FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(), - SourceLocation(), - &Context->Idents.get("arr"), - Context->getPointerType(Context->VoidPtrTy), - nullptr, /*BitWidth=*/nullptr, - /*Mutable=*/true, ICIS_NoInit); - MemberExpr *DictLiteralValueME = - MemberExpr::CreateImplicit(*Context, NSValueCallExpr, false, ARRFD, - ARRFD->getType(), VK_LValue, OK_Ordinary); - QualType ConstIdT = Context->getObjCIdType().withConst(); - CStyleCastExpr * DictValueObjects = - NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(ConstIdT), - CK_BitCast, - DictLiteralValueME); - // (const id [])keys - Expr *NSKeyCallExpr = - CallExpr::Create(*Context, NSDictDRE, KeyExprs, NSDictFType, VK_LValue, - SourceLocation(), FPOptionsOverride()); - - MemberExpr *DictLiteralKeyME = - MemberExpr::CreateImplicit(*Context, NSKeyCallExpr, false, ARRFD, - ARRFD->getType(), VK_LValue, OK_Ordinary); - - CStyleCastExpr * DictKeyObjects = - NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(ConstIdT), - CK_BitCast, - DictLiteralKeyME); - - // Synthesize a call to objc_msgSend(). - SmallVector MsgExprs; - SmallVector ClsExprs; - QualType expType = Exp->getType(); - - // Create a call to objc_getClass("NSArray"). It will be th 1st argument. - ObjCInterfaceDecl *Class = - expType->getPointeeType()->castAs()->getInterface(); - - IdentifierInfo *clsName = Class->getIdentifier(); - ClsExprs.push_back(getStringLiteral(clsName->getName())); - CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - MsgExprs.push_back(Cls); - - // Create a call to sel_registerName("arrayWithObjects:count:"). - // it will be the 2nd argument. - SmallVector SelExprs; - ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod(); - SelExprs.push_back(getStringLiteral(DictMethod->getSelector().getAsString())); - CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, - SelExprs, StartLoc, EndLoc); - MsgExprs.push_back(SelExp); - - // (const id [])objects - MsgExprs.push_back(DictValueObjects); - - // (const id [])keys - MsgExprs.push_back(DictKeyObjects); - - // (NSUInteger)cnt - Expr *cnt = IntegerLiteral::Create(*Context, - llvm::APInt(UnsignedIntSize, NumElements), - Context->UnsignedIntTy, SourceLocation()); - MsgExprs.push_back(cnt); - - SmallVector ArgTypes; - ArgTypes.push_back(Context->getObjCClassType()); - ArgTypes.push_back(Context->getObjCSelType()); - for (const auto *PI : DictMethod->parameters()) { - QualType T = PI->getType(); - if (const PointerType* PT = T->getAs()) { - QualType PointeeTy = PT->getPointeeType(); - convertToUnqualifiedObjCType(PointeeTy); - T = Context->getPointerType(PointeeTy); - } - ArgTypes.push_back(T); - } - - QualType returnType = Exp->getType(); - // Get the type, we will need to reference it in a couple spots. - QualType msgSendType = MsgSendFlavor->getType(); - - // Create a reference to the objc_msgSend() declaration. - DeclRefExpr *DRE = new (Context) DeclRefExpr( - *Context, MsgSendFlavor, false, msgSendType, VK_LValue, SourceLocation()); - - CastExpr *cast = NoTypeInfoCStyleCastExpr( - Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE); - - // Now do the "normal" pointer to function cast. - QualType castType = - getSimpleFunctionType(returnType, ArgTypes, DictMethod->isVariadic()); - castType = Context->getPointerType(castType); - cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, - cast); - - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); - - const FunctionType *FT = msgSendType->castAs(); - CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(), - VK_PRValue, EndLoc, FPOptionsOverride()); - ReplaceStmt(Exp, CE); - return CE; -} - -// struct __rw_objc_super { -// struct objc_object *object; struct objc_object *superClass; -// }; -QualType RewriteModernObjC::getSuperStructType() { - if (!SuperStructDecl) { - SuperStructDecl = RecordDecl::Create( - *Context, TagTypeKind::Struct, TUDecl, SourceLocation(), - SourceLocation(), &Context->Idents.get("__rw_objc_super")); - QualType FieldTypes[2]; - - // struct objc_object *object; - FieldTypes[0] = Context->getObjCIdType(); - // struct objc_object *superClass; - FieldTypes[1] = Context->getObjCIdType(); - - // Create fields - for (unsigned i = 0; i < 2; ++i) { - SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl, - SourceLocation(), - SourceLocation(), nullptr, - FieldTypes[i], nullptr, - /*BitWidth=*/nullptr, - /*Mutable=*/false, - ICIS_NoInit)); - } - - SuperStructDecl->completeDefinition(); - } - return Context->getTagDeclType(SuperStructDecl); -} - -QualType RewriteModernObjC::getConstantStringStructType() { - if (!ConstantStringDecl) { - ConstantStringDecl = RecordDecl::Create( - *Context, TagTypeKind::Struct, TUDecl, SourceLocation(), - SourceLocation(), &Context->Idents.get("__NSConstantStringImpl")); - QualType FieldTypes[4]; - - // struct objc_object *receiver; - FieldTypes[0] = Context->getObjCIdType(); - // int flags; - FieldTypes[1] = Context->IntTy; - // char *str; - FieldTypes[2] = Context->getPointerType(Context->CharTy); - // long length; - FieldTypes[3] = Context->LongTy; - - // Create fields - for (unsigned i = 0; i < 4; ++i) { - ConstantStringDecl->addDecl(FieldDecl::Create(*Context, - ConstantStringDecl, - SourceLocation(), - SourceLocation(), nullptr, - FieldTypes[i], nullptr, - /*BitWidth=*/nullptr, - /*Mutable=*/true, - ICIS_NoInit)); - } - - ConstantStringDecl->completeDefinition(); - } - return Context->getTagDeclType(ConstantStringDecl); -} - -/// getFunctionSourceLocation - returns start location of a function -/// definition. Complication arises when function has declared as -/// extern "C" or extern "C" {...} -static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R, - FunctionDecl *FD) { - if (FD->isExternC() && !FD->isMain()) { - const DeclContext *DC = FD->getDeclContext(); - if (const LinkageSpecDecl *LSD = dyn_cast(DC)) - // if it is extern "C" {...}, return function decl's own location. - if (!LSD->getRBraceLoc().isValid()) - return LSD->getExternLoc(); - } - if (FD->getStorageClass() != SC_None) - R.RewriteBlockLiteralFunctionDecl(FD); - return FD->getTypeSpecStartLoc(); -} - -void RewriteModernObjC::RewriteLineDirective(const Decl *D) { - - SourceLocation Location = D->getLocation(); - - if (Location.isFileID() && GenerateLineInfo) { - std::string LineString("\n#line "); - PresumedLoc PLoc = SM->getPresumedLoc(Location); - LineString += utostr(PLoc.getLine()); - LineString += " \""; - LineString += Lexer::Stringify(PLoc.getFilename()); - if (isa(D)) - LineString += "\""; - else LineString += "\"\n"; - - Location = D->getBeginLoc(); - if (const FunctionDecl *FD = dyn_cast(D)) { - if (FD->isExternC() && !FD->isMain()) { - const DeclContext *DC = FD->getDeclContext(); - if (const LinkageSpecDecl *LSD = dyn_cast(DC)) - // if it is extern "C" {...}, return function decl's own location. - if (!LSD->getRBraceLoc().isValid()) - Location = LSD->getExternLoc(); - } - } - InsertText(Location, LineString); - } -} - -/// SynthMsgSendStretCallExpr - This routine translates message expression -/// into a call to objc_msgSend_stret() entry point. Tricky part is that -/// nil check on receiver must be performed before calling objc_msgSend_stret. -/// MsgSendStretFlavor - function declaration objc_msgSend_stret(...) -/// msgSendType - function type of objc_msgSend_stret(...) -/// returnType - Result type of the method being synthesized. -/// ArgTypes - type of the arguments passed to objc_msgSend_stret, starting with receiver type. -/// MsgExprs - list of argument expressions being passed to objc_msgSend_stret, -/// starting with receiver. -/// Method - Method being rewritten. -Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, - QualType returnType, - SmallVectorImpl &ArgTypes, - SmallVectorImpl &MsgExprs, - ObjCMethodDecl *Method) { - // Now do the "normal" pointer to function cast. - QualType FuncType = getSimpleFunctionType( - returnType, ArgTypes, Method ? Method->isVariadic() : false); - QualType castType = Context->getPointerType(FuncType); - - // build type for containing the objc_msgSend_stret object. - static unsigned stretCount=0; - std::string name = "__Stret"; name += utostr(stretCount); - std::string str = - "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n"; - str += "namespace {\n"; - str += "struct "; str += name; - str += " {\n\t"; - str += name; - str += "(id receiver, SEL sel"; - for (unsigned i = 2; i < ArgTypes.size(); i++) { - std::string ArgName = "arg"; ArgName += utostr(i); - ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy()); - str += ", "; str += ArgName; - } - // could be vararg. - for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) { - std::string ArgName = "arg"; ArgName += utostr(i); - MsgExprs[i]->getType().getAsStringInternal(ArgName, - Context->getPrintingPolicy()); - str += ", "; str += ArgName; - } - - str += ") {\n"; - str += "\t unsigned size = sizeof("; - str += returnType.getAsString(Context->getPrintingPolicy()); str += ");\n"; - - str += "\t if (size == 1 || size == 2 || size == 4 || size == 8)\n"; - - str += "\t s = (("; str += castType.getAsString(Context->getPrintingPolicy()); - str += ")(void *)objc_msgSend)(receiver, sel"; - for (unsigned i = 2; i < ArgTypes.size(); i++) { - str += ", arg"; str += utostr(i); - } - // could be vararg. - for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) { - str += ", arg"; str += utostr(i); - } - str+= ");\n"; - - str += "\t else if (receiver == 0)\n"; - str += "\t memset((void*)&s, 0, sizeof(s));\n"; - str += "\t else\n"; - - str += "\t s = (("; str += castType.getAsString(Context->getPrintingPolicy()); - str += ")(void *)objc_msgSend_stret)(receiver, sel"; - for (unsigned i = 2; i < ArgTypes.size(); i++) { - str += ", arg"; str += utostr(i); - } - // could be vararg. - for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) { - str += ", arg"; str += utostr(i); - } - str += ");\n"; - - str += "\t}\n"; - str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy()); - str += " s;\n"; - str += "};\n};\n\n"; - SourceLocation FunLocStart; - if (CurFunctionDef) - FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef); - else { - assert(CurMethodDef && "SynthMsgSendStretCallExpr - CurMethodDef is null"); - FunLocStart = CurMethodDef->getBeginLoc(); - } - - InsertText(FunLocStart, str); - ++stretCount; - - // AST for __Stretn(receiver, args).s; - IdentifierInfo *ID = &Context->Idents.get(name); - FunctionDecl *FD = - FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(), - ID, FuncType, nullptr, SC_Extern, false, false); - DeclRefExpr *DRE = new (Context) - DeclRefExpr(*Context, FD, false, castType, VK_PRValue, SourceLocation()); - CallExpr *STCE = - CallExpr::Create(*Context, DRE, MsgExprs, castType, VK_LValue, - SourceLocation(), FPOptionsOverride()); - - FieldDecl *FieldD = FieldDecl::Create(*Context, nullptr, SourceLocation(), - SourceLocation(), - &Context->Idents.get("s"), - returnType, nullptr, - /*BitWidth=*/nullptr, - /*Mutable=*/true, ICIS_NoInit); - MemberExpr *ME = MemberExpr::CreateImplicit( - *Context, STCE, false, FieldD, FieldD->getType(), VK_LValue, OK_Ordinary); - - return ME; -} - -Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, - SourceLocation StartLoc, - SourceLocation EndLoc) { - if (!SelGetUidFunctionDecl) - SynthSelGetUidFunctionDecl(); - if (!MsgSendFunctionDecl) - SynthMsgSendFunctionDecl(); - if (!MsgSendSuperFunctionDecl) - SynthMsgSendSuperFunctionDecl(); - if (!MsgSendStretFunctionDecl) - SynthMsgSendStretFunctionDecl(); - if (!MsgSendSuperStretFunctionDecl) - SynthMsgSendSuperStretFunctionDecl(); - if (!MsgSendFpretFunctionDecl) - SynthMsgSendFpretFunctionDecl(); - if (!GetClassFunctionDecl) - SynthGetClassFunctionDecl(); - if (!GetSuperClassFunctionDecl) - SynthGetSuperClassFunctionDecl(); - if (!GetMetaClassFunctionDecl) - SynthGetMetaClassFunctionDecl(); - - // default to objc_msgSend(). - FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; - // May need to use objc_msgSend_stret() as well. - FunctionDecl *MsgSendStretFlavor = nullptr; - if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) { - QualType resultType = mDecl->getReturnType(); - if (resultType->isRecordType()) - MsgSendStretFlavor = MsgSendStretFunctionDecl; - else if (resultType->isRealFloatingType()) - MsgSendFlavor = MsgSendFpretFunctionDecl; - } - - // Synthesize a call to objc_msgSend(). - SmallVector MsgExprs; - switch (Exp->getReceiverKind()) { - case ObjCMessageExpr::SuperClass: { - MsgSendFlavor = MsgSendSuperFunctionDecl; - if (MsgSendStretFlavor) - MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; - assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); - - ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); - - SmallVector InitExprs; - - // set the receiver to self, the first argument to all methods. - InitExprs.push_back(NoTypeInfoCStyleCastExpr( - Context, Context->getObjCIdType(), CK_BitCast, - new (Context) DeclRefExpr(*Context, CurMethodDef->getSelfDecl(), false, - Context->getObjCIdType(), VK_PRValue, - SourceLocation()))); // set the 'receiver'. - - // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) - SmallVector ClsExprs; - ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName())); - // (Class)objc_getClass("CurrentClass") - CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl, - ClsExprs, StartLoc, EndLoc); - ClsExprs.clear(); - ClsExprs.push_back(Cls); - Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - - // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) - // To turn off a warning, type-cast to 'id' - InitExprs.push_back( // set 'super class', using class_getSuperclass(). - NoTypeInfoCStyleCastExpr(Context, - Context->getObjCIdType(), - CK_BitCast, Cls)); - // struct __rw_objc_super - QualType superType = getSuperStructType(); - Expr *SuperRep; - - if (LangOpts.MicrosoftExt) { - SynthSuperConstructorFunctionDecl(); - // Simulate a constructor call... - DeclRefExpr *DRE = new (Context) - DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType, - VK_LValue, SourceLocation()); - SuperRep = - CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue, - SourceLocation(), FPOptionsOverride()); - // The code for super is a little tricky to prevent collision with - // the structure definition in the header. The rewriter has it's own - // internal definition (__rw_objc_super) that is uses. This is why - // we need the cast below. For example: - // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) - // - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - SuperRep = NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(superType), - CK_BitCast, SuperRep); - } else { - // (struct __rw_objc_super) { } - InitListExpr *ILE = - new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, - SourceLocation()); - TypeSourceInfo *superTInfo - = Context->getTrivialTypeSourceInfo(superType); - SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, - superType, VK_LValue, - ILE, false); - // struct __rw_objc_super * - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - } - MsgExprs.push_back(SuperRep); - break; - } - - case ObjCMessageExpr::Class: { - SmallVector ClsExprs; - ObjCInterfaceDecl *Class - = Exp->getClassReceiver()->castAs()->getInterface(); - IdentifierInfo *clsName = Class->getIdentifier(); - ClsExprs.push_back(getStringLiteral(clsName->getName())); - CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, - Context->getObjCIdType(), - CK_BitCast, Cls); - MsgExprs.push_back(ArgExpr); - break; - } - - case ObjCMessageExpr::SuperInstance:{ - MsgSendFlavor = MsgSendSuperFunctionDecl; - if (MsgSendStretFlavor) - MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; - assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); - ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); - SmallVector InitExprs; - - InitExprs.push_back(NoTypeInfoCStyleCastExpr( - Context, Context->getObjCIdType(), CK_BitCast, - new (Context) DeclRefExpr(*Context, CurMethodDef->getSelfDecl(), false, - Context->getObjCIdType(), VK_PRValue, - SourceLocation()))); // set the 'receiver'. - - // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) - SmallVector ClsExprs; - ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName())); - // (Class)objc_getClass("CurrentClass") - CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - ClsExprs.clear(); - ClsExprs.push_back(Cls); - Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - - // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) - // To turn off a warning, type-cast to 'id' - InitExprs.push_back( - // set 'super class', using class_getSuperclass(). - NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), - CK_BitCast, Cls)); - // struct __rw_objc_super - QualType superType = getSuperStructType(); - Expr *SuperRep; - - if (LangOpts.MicrosoftExt) { - SynthSuperConstructorFunctionDecl(); - // Simulate a constructor call... - DeclRefExpr *DRE = new (Context) - DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType, - VK_LValue, SourceLocation()); - SuperRep = - CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue, - SourceLocation(), FPOptionsOverride()); - // The code for super is a little tricky to prevent collision with - // the structure definition in the header. The rewriter has it's own - // internal definition (__rw_objc_super) that is uses. This is why - // we need the cast below. For example: - // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) - // - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - SuperRep = NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(superType), - CK_BitCast, SuperRep); - } else { - // (struct __rw_objc_super) { } - InitListExpr *ILE = - new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, - SourceLocation()); - TypeSourceInfo *superTInfo - = Context->getTrivialTypeSourceInfo(superType); - SuperRep = new (Context) CompoundLiteralExpr( - SourceLocation(), superTInfo, superType, VK_PRValue, ILE, false); - } - MsgExprs.push_back(SuperRep); - break; - } - - case ObjCMessageExpr::Instance: { - // Remove all type-casts because it may contain objc-style types; e.g. - // Foo *. - Expr *recExpr = Exp->getInstanceReceiver(); - while (CStyleCastExpr *CE = dyn_cast(recExpr)) - recExpr = CE->getSubExpr(); - CastKind CK = recExpr->getType()->isObjCObjectPointerType() - ? CK_BitCast : recExpr->getType()->isBlockPointerType() - ? CK_BlockPointerToObjCPointerCast - : CK_CPointerToObjCPointerCast; - - recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), - CK, recExpr); - MsgExprs.push_back(recExpr); - break; - } - } - - // Create a call to sel_registerName("selName"), it will be the 2nd argument. - SmallVector SelExprs; - SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString())); - CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, - SelExprs, StartLoc, EndLoc); - MsgExprs.push_back(SelExp); - - // Now push any user supplied arguments. - for (unsigned i = 0; i < Exp->getNumArgs(); i++) { - Expr *userExpr = Exp->getArg(i); - // Make all implicit casts explicit...ICE comes in handy:-) - if (ImplicitCastExpr *ICE = dyn_cast(userExpr)) { - // Reuse the ICE type, it is exactly what the doctor ordered. - QualType type = ICE->getType(); - if (needToScanForQualifiers(type)) - type = Context->getObjCIdType(); - // Make sure we convert "type (^)(...)" to "type (*)(...)". - (void)convertBlockPointerToFunctionPointer(type); - const Expr *SubExpr = ICE->IgnoreParenImpCasts(); - CastKind CK; - if (SubExpr->getType()->isIntegralType(*Context) && - type->isBooleanType()) { - CK = CK_IntegralToBoolean; - } else if (type->isObjCObjectPointerType()) { - if (SubExpr->getType()->isBlockPointerType()) { - CK = CK_BlockPointerToObjCPointerCast; - } else if (SubExpr->getType()->isPointerType()) { - CK = CK_CPointerToObjCPointerCast; - } else { - CK = CK_BitCast; - } - } else { - CK = CK_BitCast; - } - - userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr); - } - // Make id cast into an 'id' cast. - else if (CStyleCastExpr *CE = dyn_cast(userExpr)) { - if (CE->getType()->isObjCQualifiedIdType()) { - while ((CE = dyn_cast(userExpr))) - userExpr = CE->getSubExpr(); - CastKind CK; - if (userExpr->getType()->isIntegralType(*Context)) { - CK = CK_IntegralToPointer; - } else if (userExpr->getType()->isBlockPointerType()) { - CK = CK_BlockPointerToObjCPointerCast; - } else if (userExpr->getType()->isPointerType()) { - CK = CK_CPointerToObjCPointerCast; - } else { - CK = CK_BitCast; - } - userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), - CK, userExpr); - } - } - MsgExprs.push_back(userExpr); - // We've transferred the ownership to MsgExprs. For now, we *don't* null - // out the argument in the original expression (since we aren't deleting - // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info. - //Exp->setArg(i, 0); - } - // Generate the funky cast. - CastExpr *cast; - SmallVector ArgTypes; - QualType returnType; - - // Push 'id' and 'SEL', the 2 implicit arguments. - if (MsgSendFlavor == MsgSendSuperFunctionDecl) - ArgTypes.push_back(Context->getPointerType(getSuperStructType())); - else - ArgTypes.push_back(Context->getObjCIdType()); - ArgTypes.push_back(Context->getObjCSelType()); - if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) { - // Push any user argument types. - for (const auto *PI : OMD->parameters()) { - QualType t = PI->getType()->isObjCQualifiedIdType() - ? Context->getObjCIdType() - : PI->getType(); - // Make sure we convert "t (^)(...)" to "t (*)(...)". - (void)convertBlockPointerToFunctionPointer(t); - ArgTypes.push_back(t); - } - returnType = Exp->getType(); - convertToUnqualifiedObjCType(returnType); - (void)convertBlockPointerToFunctionPointer(returnType); - } else { - returnType = Context->getObjCIdType(); - } - // Get the type, we will need to reference it in a couple spots. - QualType msgSendType = MsgSendFlavor->getType(); - - // Create a reference to the objc_msgSend() declaration. - DeclRefExpr *DRE = new (Context) DeclRefExpr( - *Context, MsgSendFlavor, false, msgSendType, VK_LValue, SourceLocation()); - - // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). - // If we don't do this cast, we get the following bizarre warning/note: - // xx.m:13: warning: function called through a non-compatible type - // xx.m:13: note: if this code is reached, the program will abort - cast = NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(Context->VoidTy), - CK_BitCast, DRE); - - // Now do the "normal" pointer to function cast. - // If we don't have a method decl, force a variadic cast. - const ObjCMethodDecl *MD = Exp->getMethodDecl(); - QualType castType = - getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true); - castType = Context->getPointerType(castType); - cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, - cast); - - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); - - const FunctionType *FT = msgSendType->castAs(); - CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(), - VK_PRValue, EndLoc, FPOptionsOverride()); - Stmt *ReplacingStmt = CE; - if (MsgSendStretFlavor) { - // We have the method which returns a struct/union. Must also generate - // call to objc_msgSend_stret and hang both varieties on a conditional - // expression which dictate which one to envoke depending on size of - // method's return type. - - Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor, - returnType, - ArgTypes, MsgExprs, - Exp->getMethodDecl()); - ReplacingStmt = STCE; - } - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return ReplacingStmt; -} - -Stmt *RewriteModernObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) { - Stmt *ReplacingStmt = - SynthMessageExpr(Exp, Exp->getBeginLoc(), Exp->getEndLoc()); - - // Now do the actual rewrite. - ReplaceStmt(Exp, ReplacingStmt); - - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return ReplacingStmt; -} - -// typedef struct objc_object Protocol; -QualType RewriteModernObjC::getProtocolType() { - if (!ProtocolTypeDecl) { - TypeSourceInfo *TInfo - = Context->getTrivialTypeSourceInfo(Context->getObjCIdType()); - ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl, - SourceLocation(), SourceLocation(), - &Context->Idents.get("Protocol"), - TInfo); - } - return Context->getTypeDeclType(ProtocolTypeDecl); -} - -/// RewriteObjCProtocolExpr - Rewrite a protocol expression into -/// a synthesized/forward data reference (to the protocol's metadata). -/// The forward references (and metadata) are generated in -/// RewriteModernObjC::HandleTranslationUnit(). -Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { - std::string Name = "_OBJC_PROTOCOL_REFERENCE_$_" + - Exp->getProtocol()->getNameAsString(); - IdentifierInfo *ID = &Context->Idents.get(Name); - VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), - SourceLocation(), ID, getProtocolType(), - nullptr, SC_Extern); - DeclRefExpr *DRE = new (Context) DeclRefExpr( - *Context, VD, false, getProtocolType(), VK_LValue, SourceLocation()); - CastExpr *castExpr = NoTypeInfoCStyleCastExpr( - Context, Context->getPointerType(DRE->getType()), CK_BitCast, DRE); - ReplaceStmt(Exp, castExpr); - ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl()); - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return castExpr; -} - -/// IsTagDefinedInsideClass - This routine checks that a named tagged type -/// is defined inside an objective-c class. If so, it returns true. -bool RewriteModernObjC::IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, - TagDecl *Tag, - bool &IsNamedDefinition) { - if (!IDecl) - return false; - SourceLocation TagLocation; - if (RecordDecl *RD = dyn_cast(Tag)) { - RD = RD->getDefinition(); - if (!RD || !RD->getDeclName().getAsIdentifierInfo()) - return false; - IsNamedDefinition = true; - TagLocation = RD->getLocation(); - return Context->getSourceManager().isBeforeInTranslationUnit( - IDecl->getLocation(), TagLocation); - } - if (EnumDecl *ED = dyn_cast(Tag)) { - if (!ED || !ED->getDeclName().getAsIdentifierInfo()) - return false; - IsNamedDefinition = true; - TagLocation = ED->getLocation(); - return Context->getSourceManager().isBeforeInTranslationUnit( - IDecl->getLocation(), TagLocation); - } - return false; -} - -/// RewriteObjCFieldDeclType - This routine rewrites a type into the buffer. -/// It handles elaborated types, as well as enum types in the process. -bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, - std::string &Result) { - if (Type->getAs()) { - Result += "\t"; - return false; - } - - if (Type->isArrayType()) { - QualType ElemTy = Context->getBaseElementType(Type); - return RewriteObjCFieldDeclType(ElemTy, Result); - } - else if (Type->isRecordType()) { - RecordDecl *RD = Type->castAs()->getDecl(); - if (RD->isCompleteDefinition()) { - if (RD->isStruct()) - Result += "\n\tstruct "; - else if (RD->isUnion()) - Result += "\n\tunion "; - else - assert(false && "class not allowed as an ivar type"); - - Result += RD->getName(); - if (GlobalDefinedTags.count(RD)) { - // struct/union is defined globally, use it. - Result += " "; - return true; - } - Result += " {\n"; - for (auto *FD : RD->fields()) - RewriteObjCFieldDecl(FD, Result); - Result += "\t} "; - return true; - } - } - else if (Type->isEnumeralType()) { - EnumDecl *ED = Type->castAs()->getDecl(); - if (ED->isCompleteDefinition()) { - Result += "\n\tenum "; - Result += ED->getName(); - if (GlobalDefinedTags.count(ED)) { - // Enum is globall defined, use it. - Result += " "; - return true; - } - - Result += " {\n"; - for (const auto *EC : ED->enumerators()) { - Result += "\t"; Result += EC->getName(); Result += " = "; - Result += toString(EC->getInitVal(), 10); - Result += ",\n"; - } - Result += "\t} "; - return true; - } - } - - Result += "\t"; - convertObjCTypeToCStyleType(Type); - return false; -} - - -/// RewriteObjCFieldDecl - This routine rewrites a field into the buffer. -/// It handles elaborated types, as well as enum types in the process. -void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, - std::string &Result) { - QualType Type = fieldDecl->getType(); - std::string Name = fieldDecl->getNameAsString(); - - bool EleboratedType = RewriteObjCFieldDeclType(Type, Result); - if (!EleboratedType) - Type.getAsStringInternal(Name, Context->getPrintingPolicy()); - Result += Name; - if (fieldDecl->isBitField()) { - Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context)); - } - else if (EleboratedType && Type->isArrayType()) { - const ArrayType *AT = Context->getAsArrayType(Type); - do { - if (const ConstantArrayType *CAT = dyn_cast(AT)) { - Result += "["; - llvm::APInt Dim = CAT->getSize(); - Result += utostr(Dim.getZExtValue()); - Result += "]"; - } - AT = Context->getAsArrayType(AT->getElementType()); - } while (AT); - } - - Result += ";\n"; -} - -/// RewriteLocallyDefinedNamedAggregates - This routine rewrites locally defined -/// named aggregate types into the input buffer. -void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, - std::string &Result) { - QualType Type = fieldDecl->getType(); - if (Type->getAs()) - return; - if (Type->isArrayType()) - Type = Context->getBaseElementType(Type); - - auto *IDecl = dyn_cast(fieldDecl->getDeclContext()); - - TagDecl *TD = nullptr; - if (Type->isRecordType()) { - TD = Type->castAs()->getDecl(); - } - else if (Type->isEnumeralType()) { - TD = Type->castAs()->getDecl(); - } - - if (TD) { - if (GlobalDefinedTags.count(TD)) - return; - - bool IsNamedDefinition = false; - if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) { - RewriteObjCFieldDeclType(Type, Result); - Result += ";"; - } - if (IsNamedDefinition) - GlobalDefinedTags.insert(TD); - } -} - -unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV) { - const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); - if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) { - return IvarGroupNumber[IV]; - } - unsigned GroupNo = 0; - SmallVector IVars; - for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); - IVD; IVD = IVD->getNextIvar()) - IVars.push_back(IVD); - - for (unsigned i = 0, e = IVars.size(); i < e; i++) - if (IVars[i]->isBitField()) { - IvarGroupNumber[IVars[i++]] = ++GroupNo; - while (i < e && IVars[i]->isBitField()) - IvarGroupNumber[IVars[i++]] = GroupNo; - if (i < e) - --i; - } - - ObjCInterefaceHasBitfieldGroups.insert(CDecl); - return IvarGroupNumber[IV]; -} - -QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType( - ObjCIvarDecl *IV, - SmallVectorImpl &IVars) { - std::string StructTagName; - ObjCIvarBitfieldGroupType(IV, StructTagName); - RecordDecl *RD = RecordDecl::Create( - *Context, TagTypeKind::Struct, Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), &Context->Idents.get(StructTagName)); - for (unsigned i=0, e = IVars.size(); i < e; i++) { - ObjCIvarDecl *Ivar = IVars[i]; - RD->addDecl(FieldDecl::Create(*Context, RD, SourceLocation(), SourceLocation(), - &Context->Idents.get(Ivar->getName()), - Ivar->getType(), - nullptr, /*Expr *BW */Ivar->getBitWidth(), - false, ICIS_NoInit)); - } - RD->completeDefinition(); - return Context->getTagDeclType(RD); -} - -QualType RewriteModernObjC::GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV) { - const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); - unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); - std::pair tuple = std::make_pair(CDecl, GroupNo); - if (GroupRecordType.count(tuple)) - return GroupRecordType[tuple]; - - SmallVector IVars; - for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); - IVD; IVD = IVD->getNextIvar()) { - if (IVD->isBitField()) - IVars.push_back(const_cast(IVD)); - else { - if (!IVars.empty()) { - unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]); - // Generate the struct type for this group of bitfield ivars. - GroupRecordType[std::make_pair(CDecl, GroupNo)] = - SynthesizeBitfieldGroupStructType(IVars[0], IVars); - IVars.clear(); - } - } - } - if (!IVars.empty()) { - // Do the last one. - unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]); - GroupRecordType[std::make_pair(CDecl, GroupNo)] = - SynthesizeBitfieldGroupStructType(IVars[0], IVars); - } - QualType RetQT = GroupRecordType[tuple]; - assert(!RetQT.isNull() && "GetGroupRecordTypeForObjCIvarBitfield struct type is NULL"); - - return RetQT; -} - -/// ObjCIvarBitfieldGroupDecl - Names field decl. for ivar bitfield group. -/// Name would be: classname__GRBF_n where n is the group number for this ivar. -void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, - std::string &Result) { - const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); - Result += CDecl->getName(); - Result += "__GRBF_"; - unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); - Result += utostr(GroupNo); -} - -/// ObjCIvarBitfieldGroupType - Names struct type for ivar bitfield group. -/// Name of the struct would be: classname__T_n where n is the group number for -/// this ivar. -void RewriteModernObjC::ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, - std::string &Result) { - const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); - Result += CDecl->getName(); - Result += "__T_"; - unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); - Result += utostr(GroupNo); -} - -/// ObjCIvarBitfieldGroupOffset - Names symbol for ivar bitfield group field offset. -/// Name would be: OBJC_IVAR_$_classname__GRBF_n where n is the group number for -/// this ivar. -void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV, - std::string &Result) { - Result += "OBJC_IVAR_$_"; - ObjCIvarBitfieldGroupDecl(IV, Result); -} - -#define SKIP_BITFIELDS(IX, ENDIX, VEC) { \ - while ((IX < ENDIX) && VEC[IX]->isBitField()) \ - ++IX; \ - if (IX < ENDIX) \ - --IX; \ -} - -/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to -/// an objective-c class with ivars. -void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, - std::string &Result) { - assert(CDecl && "Class missing in SynthesizeObjCInternalStruct"); - assert(CDecl->getName() != "" && - "Name missing in SynthesizeObjCInternalStruct"); - ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass(); - SmallVector IVars; - for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); - IVD; IVD = IVD->getNextIvar()) - IVars.push_back(IVD); - - SourceLocation LocStart = CDecl->getBeginLoc(); - SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc(); - - const char *startBuf = SM->getCharacterData(LocStart); - const char *endBuf = SM->getCharacterData(LocEnd); - - // 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->isThisDeclarationADefinition() || IVars.size() == 0) && - (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) { - endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); - ReplaceText(LocStart, endBuf-startBuf, Result); - return; - } - - // Insert named struct/union definitions inside class to - // outer scope. This follows semantics of locally defined - // struct/unions in objective-c classes. - for (unsigned i = 0, e = IVars.size(); i < e; i++) - RewriteLocallyDefinedNamedAggregates(IVars[i], Result); - - // Insert named structs which are syntheized to group ivar bitfields - // to outer scope as well. - for (unsigned i = 0, e = IVars.size(); i < e; i++) - if (IVars[i]->isBitField()) { - ObjCIvarDecl *IV = IVars[i]; - QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV); - RewriteObjCFieldDeclType(QT, Result); - Result += ";"; - // skip over ivar bitfields in this group. - SKIP_BITFIELDS(i , e, IVars); - } - - Result += "\nstruct "; - Result += CDecl->getNameAsString(); - Result += "_IMPL {\n"; - - if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) { - Result += "\tstruct "; Result += RCDecl->getNameAsString(); - Result += "_IMPL "; Result += RCDecl->getNameAsString(); - Result += "_IVARS;\n"; - } - - for (unsigned i = 0, e = IVars.size(); i < e; i++) { - if (IVars[i]->isBitField()) { - ObjCIvarDecl *IV = IVars[i]; - Result += "\tstruct "; - ObjCIvarBitfieldGroupType(IV, Result); Result += " "; - ObjCIvarBitfieldGroupDecl(IV, Result); Result += ";\n"; - // skip over ivar bitfields in this group. - SKIP_BITFIELDS(i , e, IVars); - } - else - RewriteObjCFieldDecl(IVars[i], Result); - } - - Result += "};\n"; - endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); - ReplaceText(LocStart, endBuf-startBuf, Result); - // Mark this struct as having been generated. - if (!ObjCSynthesizedStructs.insert(CDecl).second) - llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct"); -} - -/// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which -/// have been referenced in an ivar access expression. -void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl, - std::string &Result) { - // write out ivar offset symbols which have been referenced in an ivar - // access expression. - llvm::SmallSetVector Ivars = ReferencedIvars[CDecl]; - - if (Ivars.empty()) - return; - - llvm::DenseSet > GroupSymbolOutput; - for (ObjCIvarDecl *IvarDecl : Ivars) { - const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface(); - unsigned GroupNo = 0; - if (IvarDecl->isBitField()) { - GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl); - if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo))) - continue; - } - Result += "\n"; - if (LangOpts.MicrosoftExt) - Result += "__declspec(allocate(\".objc_ivar$B\")) "; - Result += "extern \"C\" "; - if (LangOpts.MicrosoftExt && - IvarDecl->getAccessControl() != ObjCIvarDecl::Private && - IvarDecl->getAccessControl() != ObjCIvarDecl::Package) - Result += "__declspec(dllimport) "; - - Result += "unsigned long "; - if (IvarDecl->isBitField()) { - ObjCIvarBitfieldGroupOffset(IvarDecl, Result); - GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo)); - } - else - WriteInternalIvarName(CDecl, IvarDecl, Result); - Result += ";"; - } -} - -//===----------------------------------------------------------------------===// -// Meta Data Emission -//===----------------------------------------------------------------------===// - -/// RewriteImplementations - This routine rewrites all method implementations -/// and emits meta-data. - -void RewriteModernObjC::RewriteImplementations() { - int ClsDefCount = ClassImplementation.size(); - int CatDefCount = CategoryImplementation.size(); - - // Rewrite implemented methods - for (int i = 0; i < ClsDefCount; i++) { - ObjCImplementationDecl *OIMP = ClassImplementation[i]; - ObjCInterfaceDecl *CDecl = OIMP->getClassInterface(); - if (CDecl->isImplicitInterfaceDecl()) - assert(false && - "Legacy implicit interface rewriting not supported in moder abi"); - RewriteImplementationDecl(OIMP); - } - - for (int i = 0; i < CatDefCount; i++) { - ObjCCategoryImplDecl *CIMP = CategoryImplementation[i]; - ObjCInterfaceDecl *CDecl = CIMP->getClassInterface(); - if (CDecl->isImplicitInterfaceDecl()) - assert(false && - "Legacy implicit interface rewriting not supported in moder abi"); - RewriteImplementationDecl(CIMP); - } -} - -void RewriteModernObjC::RewriteByRefString(std::string &ResultStr, - const std::string &Name, - ValueDecl *VD, bool def) { - assert(BlockByRefDeclNo.count(VD) && - "RewriteByRefString: ByRef decl missing"); - if (def) - ResultStr += "struct "; - ResultStr += "__Block_byref_" + Name + - "_" + utostr(BlockByRefDeclNo[VD]) ; -} - -static bool HasLocalVariableExternalStorage(ValueDecl *VD) { - if (VarDecl *Var = dyn_cast(VD)) - return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage()); - return false; -} - -std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, - StringRef funcName, - const std::string &Tag) { - const FunctionType *AFT = CE->getFunctionType(); - QualType RT = AFT->getReturnType(); - std::string StructRef = "struct " + Tag; - SourceLocation BlockLoc = CE->getExprLoc(); - std::string S; - ConvertSourceLocationToLineDirective(BlockLoc, S); - - S += "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" + - funcName.str() + "_block_func_" + utostr(i); - - BlockDecl *BD = CE->getBlockDecl(); - - if (isa(AFT)) { - // No user-supplied arguments. Still need to pass in a pointer to the - // block (to reference imported block decl refs). - S += "(" + StructRef + " *__cself)"; - } else if (BD->param_empty()) { - S += "(" + StructRef + " *__cself)"; - } else { - const FunctionProtoType *FT = cast(AFT); - assert(FT && "SynthesizeBlockFunc: No function proto"); - S += '('; - // first add the implicit argument. - S += StructRef + " *__cself, "; - std::string ParamStr; - for (BlockDecl::param_iterator AI = BD->param_begin(), - E = BD->param_end(); AI != E; ++AI) { - if (AI != BD->param_begin()) S += ", "; - ParamStr = (*AI)->getNameAsString(); - QualType QT = (*AI)->getType(); - (void)convertBlockPointerToFunctionPointer(QT); - QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy()); - S += ParamStr; - } - if (FT->isVariadic()) { - if (!BD->param_empty()) S += ", "; - S += "..."; - } - S += ')'; - } - S += " {\n"; - - // Create local declarations to avoid rewriting all closure decl ref exprs. - // First, emit a declaration for all "by ref" decls. - for (ValueDecl *VD : BlockByRefDecls) { - S += " "; - std::string Name = VD->getNameAsString(); - std::string TypeString; - RewriteByRefString(TypeString, Name, VD); - TypeString += " *"; - Name = TypeString + Name; - S += Name + " = __cself->" + VD->getNameAsString() + "; // bound by ref\n"; - } - // Next, emit a declaration for all "by copy" declarations. - for (ValueDecl *VD : BlockByCopyDecls) { - S += " "; - // Handle nested closure invocation. For example: - // - // void (^myImportedClosure)(void); - // myImportedClosure = ^(void) { setGlobalInt(x + y); }; - // - // void (^anotherClosure)(void); - // anotherClosure = ^(void) { - // myImportedClosure(); // import and invoke the closure - // }; - // - if (isTopLevelBlockPointerType(VD->getType())) { - RewriteBlockPointerTypeVariable(S, VD); - S += " = ("; - RewriteBlockPointerType(S, VD->getType()); - S += ")"; - S += "__cself->" + VD->getNameAsString() + "; // bound by copy\n"; - } else { - std::string Name = VD->getNameAsString(); - QualType QT = VD->getType(); - if (HasLocalVariableExternalStorage(VD)) - QT = Context->getPointerType(QT); - QT.getAsStringInternal(Name, Context->getPrintingPolicy()); - S += Name + " = __cself->" + VD->getNameAsString() + - "; // bound by copy\n"; - } - } - std::string RewrittenStr = RewrittenBlockExprs[CE]; - const char *cstr = RewrittenStr.c_str(); - while (*cstr++ != '{') ; - S += cstr; - S += "\n"; - return S; -} - -std::string RewriteModernObjC::SynthesizeBlockHelperFuncs( - BlockExpr *CE, int i, StringRef funcName, const std::string &Tag) { - std::string StructRef = "struct " + Tag; - std::string S = "static void __"; - - S += funcName; - S += "_block_copy_" + utostr(i); - S += "(" + StructRef; - S += "*dst, " + StructRef; - S += "*src) {"; - for (ValueDecl *VD : ImportedBlockDecls) { - S += "_Block_object_assign((void*)&dst->"; - S += VD->getNameAsString(); - S += ", (void*)src->"; - S += VD->getNameAsString(); - if (BlockByRefDecls.count(VD)) - S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; - else if (VD->getType()->isBlockPointerType()) - S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; - else - S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; - } - S += "}\n"; - - S += "\nstatic void __"; - S += funcName; - S += "_block_dispose_" + utostr(i); - S += "(" + StructRef; - S += "*src) {"; - for (ValueDecl *VD : ImportedBlockDecls) { - S += "_Block_object_dispose((void*)src->"; - S += VD->getNameAsString(); - if (BlockByRefDecls.count(VD)) - S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; - else if (VD->getType()->isBlockPointerType()) - S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; - else - S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; - } - S += "}\n"; - return S; -} - -std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, - const std::string &Tag, - const std::string &Desc) { - std::string S = "\nstruct " + Tag; - std::string Constructor = " " + Tag; - - S += " {\n struct __block_impl impl;\n"; - S += " struct " + Desc; - S += "* Desc;\n"; - - Constructor += "(void *fp, "; // Invoke function pointer. - Constructor += "struct " + Desc; // Descriptor pointer. - Constructor += " *desc"; - - if (BlockDeclRefs.size()) { - // Output all "by copy" declarations. - for (ValueDecl *VD : BlockByCopyDecls) { - S += " "; - std::string FieldName = VD->getNameAsString(); - std::string ArgName = "_" + FieldName; - // Handle nested closure invocation. For example: - // - // void (^myImportedBlock)(void); - // myImportedBlock = ^(void) { setGlobalInt(x + y); }; - // - // void (^anotherBlock)(void); - // anotherBlock = ^(void) { - // myImportedBlock(); // import and invoke the closure - // }; - // - if (isTopLevelBlockPointerType(VD->getType())) { - S += "struct __block_impl *"; - Constructor += ", void *" + ArgName; - } else { - QualType QT = VD->getType(); - if (HasLocalVariableExternalStorage(VD)) - QT = Context->getPointerType(QT); - QT.getAsStringInternal(FieldName, Context->getPrintingPolicy()); - QT.getAsStringInternal(ArgName, Context->getPrintingPolicy()); - Constructor += ", " + ArgName; - } - S += FieldName + ";\n"; - } - // Output all "by ref" declarations. - for (ValueDecl *VD : BlockByRefDecls) { - S += " "; - std::string FieldName = VD->getNameAsString(); - std::string ArgName = "_" + FieldName; - { - std::string TypeString; - RewriteByRefString(TypeString, FieldName, VD); - TypeString += " *"; - FieldName = TypeString + FieldName; - ArgName = TypeString + ArgName; - Constructor += ", " + ArgName; - } - S += FieldName + "; // by ref\n"; - } - // Finish writing the constructor. - Constructor += ", int flags=0)"; - // Initialize all "by copy" arguments. - bool firsTime = true; - for (const ValueDecl *VD : BlockByCopyDecls) { - std::string Name = VD->getNameAsString(); - if (firsTime) { - Constructor += " : "; - firsTime = false; - } else - Constructor += ", "; - if (isTopLevelBlockPointerType(VD->getType())) - Constructor += Name + "((struct __block_impl *)_" + Name + ")"; - else - Constructor += Name + "(_" + Name + ")"; - } - // Initialize all "by ref" arguments. - for (const ValueDecl *VD : BlockByRefDecls) { - std::string Name = VD->getNameAsString(); - if (firsTime) { - Constructor += " : "; - firsTime = false; - } - else - Constructor += ", "; - Constructor += Name + "(_" + Name + "->__forwarding)"; - } - - Constructor += " {\n"; - if (GlobalVarDecl) - Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; - else - Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; - Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; - - Constructor += " Desc = desc;\n"; - } else { - // Finish writing the constructor. - Constructor += ", int flags=0) {\n"; - if (GlobalVarDecl) - Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; - else - Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; - Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; - Constructor += " Desc = desc;\n"; - } - Constructor += " "; - Constructor += "}\n"; - S += Constructor; - S += "};\n"; - return S; -} - -std::string RewriteModernObjC::SynthesizeBlockDescriptor( - const std::string &DescTag, const std::string &ImplTag, int i, - StringRef FunName, unsigned hasCopy) { - std::string S = "\nstatic struct " + DescTag; - - S += " {\n size_t reserved;\n"; - S += " size_t Block_size;\n"; - if (hasCopy) { - S += " void (*copy)(struct "; - S += ImplTag; S += "*, struct "; - S += ImplTag; S += "*);\n"; - - S += " void (*dispose)(struct "; - S += ImplTag; S += "*);\n"; - } - S += "} "; - - S += DescTag + "_DATA = { 0, sizeof(struct "; - S += ImplTag + ")"; - if (hasCopy) { - S += ", __" + FunName.str() + "_block_copy_" + utostr(i); - S += ", __" + FunName.str() + "_block_dispose_" + utostr(i); - } - S += "};\n"; - return S; -} - -void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, - StringRef FunName) { - bool RewriteSC = (GlobalVarDecl && - !Blocks.empty() && - GlobalVarDecl->getStorageClass() == SC_Static && - GlobalVarDecl->getType().getCVRQualifiers()); - if (RewriteSC) { - std::string SC(" void __"); - SC += GlobalVarDecl->getNameAsString(); - SC += "() {}"; - InsertText(FunLocStart, SC); - } - - // Insert closures that were part of the function. - for (unsigned i = 0, count=0; i < Blocks.size(); i++) { - CollectBlockDeclRefInfo(Blocks[i]); - // Need to copy-in the inner copied-in variables not actually used in this - // block. - for (int j = 0; j < InnerDeclRefsCount[i]; j++) { - DeclRefExpr *Exp = InnerDeclRefs[count++]; - ValueDecl *VD = Exp->getDecl(); - BlockDeclRefs.push_back(Exp); - if (!VD->hasAttr()) { - BlockByCopyDecls.insert(VD); - continue; - } - - BlockByRefDecls.insert(VD); - - // imported objects in the inner blocks not used in the outer - // blocks must be copied/disposed in the outer block as well. - if (VD->getType()->isObjCObjectPointerType() || - VD->getType()->isBlockPointerType()) - ImportedBlockDecls.insert(VD); - } - - std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i); - std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i); - - std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag); - - InsertText(FunLocStart, CI); - - std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag); - - InsertText(FunLocStart, CF); - - if (ImportedBlockDecls.size()) { - std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag); - InsertText(FunLocStart, HF); - } - std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName, - ImportedBlockDecls.size() > 0); - InsertText(FunLocStart, BD); - - BlockDeclRefs.clear(); - BlockByRefDecls.clear(); - BlockByCopyDecls.clear(); - ImportedBlockDecls.clear(); - } - if (RewriteSC) { - // Must insert any 'const/volatile/static here. Since it has been - // removed as result of rewriting of block literals. - std::string SC; - if (GlobalVarDecl->getStorageClass() == SC_Static) - SC = "static "; - if (GlobalVarDecl->getType().isConstQualified()) - SC += "const "; - if (GlobalVarDecl->getType().isVolatileQualified()) - SC += "volatile "; - if (GlobalVarDecl->getType().isRestrictQualified()) - SC += "restrict "; - InsertText(FunLocStart, SC); - } - if (GlobalConstructionExp) { - // extra fancy dance for global literal expression. - - // Always the latest block expression on the block stack. - std::string Tag = "__"; - Tag += FunName; - Tag += "_block_impl_"; - Tag += utostr(Blocks.size()-1); - std::string globalBuf = "static "; - globalBuf += Tag; globalBuf += " "; - std::string SStr; - - llvm::raw_string_ostream constructorExprBuf(SStr); - GlobalConstructionExp->printPretty(constructorExprBuf, nullptr, - PrintingPolicy(LangOpts)); - globalBuf += SStr; - globalBuf += ";\n"; - InsertText(FunLocStart, globalBuf); - GlobalConstructionExp = nullptr; - } - - Blocks.clear(); - InnerDeclRefsCount.clear(); - InnerDeclRefs.clear(); - RewrittenBlockExprs.clear(); -} - -void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { - SourceLocation FunLocStart = - (!Blocks.empty()) ? getFunctionSourceLocation(*this, FD) - : FD->getTypeSpecStartLoc(); - StringRef FuncName = FD->getName(); - - SynthesizeBlockLiterals(FunLocStart, FuncName); -} - -static void BuildUniqueMethodName(std::string &Name, - ObjCMethodDecl *MD) { - ObjCInterfaceDecl *IFace = MD->getClassInterface(); - Name = std::string(IFace->getName()); - Name += "__" + MD->getSelector().getAsString(); - // Convert colons to underscores. - std::string::size_type loc = 0; - while ((loc = Name.find(':', loc)) != std::string::npos) - Name.replace(loc, 1, "_"); -} - -void RewriteModernObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) { - // fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n"); - // SourceLocation FunLocStart = MD->getBeginLoc(); - SourceLocation FunLocStart = MD->getBeginLoc(); - std::string FuncName; - BuildUniqueMethodName(FuncName, MD); - SynthesizeBlockLiterals(FunLocStart, FuncName); -} - -void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) { - for (Stmt *SubStmt : S->children()) - if (SubStmt) { - if (BlockExpr *CBE = dyn_cast(SubStmt)) - GetBlockDeclRefExprs(CBE->getBody()); - else - GetBlockDeclRefExprs(SubStmt); - } - // Handle specific things. - if (DeclRefExpr *DRE = dyn_cast(S)) - if (DRE->refersToEnclosingVariableOrCapture() || - HasLocalVariableExternalStorage(DRE->getDecl())) - // FIXME: Handle enums. - BlockDeclRefs.push_back(DRE); -} - -void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S, - SmallVectorImpl &InnerBlockDeclRefs, - llvm::SmallPtrSetImpl &InnerContexts) { - for (Stmt *SubStmt : S->children()) - if (SubStmt) { - if (BlockExpr *CBE = dyn_cast(SubStmt)) { - InnerContexts.insert(cast(CBE->getBlockDecl())); - GetInnerBlockDeclRefExprs(CBE->getBody(), - InnerBlockDeclRefs, - InnerContexts); - } - else - GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts); - } - // Handle specific things. - if (DeclRefExpr *DRE = dyn_cast(S)) { - if (DRE->refersToEnclosingVariableOrCapture() || - HasLocalVariableExternalStorage(DRE->getDecl())) { - if (!InnerContexts.count(DRE->getDecl()->getDeclContext())) - InnerBlockDeclRefs.push_back(DRE); - if (VarDecl *Var = cast(DRE->getDecl())) - if (Var->isFunctionOrMethodVarDecl()) - ImportedLocalExternalDecls.insert(Var); - } - } -} - -/// convertObjCTypeToCStyleType - This routine converts such objc types -/// as qualified objects, and blocks to their closest c/c++ types that -/// it can. It returns true if input type was modified. -bool RewriteModernObjC::convertObjCTypeToCStyleType(QualType &T) { - QualType oldT = T; - convertBlockPointerToFunctionPointer(T); - if (T->isFunctionPointerType()) { - QualType PointeeTy; - if (const PointerType* PT = T->getAs()) { - PointeeTy = PT->getPointeeType(); - if (const FunctionType *FT = PointeeTy->getAs()) { - T = convertFunctionTypeOfBlocks(FT); - T = Context->getPointerType(T); - } - } - } - - convertToUnqualifiedObjCType(T); - return T != oldT; -} - -/// convertFunctionTypeOfBlocks - This routine converts a function type -/// whose result type may be a block pointer or whose argument type(s) -/// might be block pointers to an equivalent function type replacing -/// all block pointers to function pointers. -QualType RewriteModernObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) { - const FunctionProtoType *FTP = dyn_cast(FT); - // FTP will be null for closures that don't take arguments. - // Generate a funky cast. - SmallVector ArgTypes; - QualType Res = FT->getReturnType(); - bool modified = convertObjCTypeToCStyleType(Res); - - if (FTP) { - for (auto &I : FTP->param_types()) { - QualType t = I; - // Make sure we convert "t (^)(...)" to "t (*)(...)". - if (convertObjCTypeToCStyleType(t)) - modified = true; - ArgTypes.push_back(t); - } - } - QualType FuncType; - if (modified) - FuncType = getSimpleFunctionType(Res, ArgTypes); - else FuncType = QualType(FT, 0); - return FuncType; -} - -Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { - // Navigate to relevant type information. - const BlockPointerType *CPT = nullptr; - - if (const DeclRefExpr *DRE = dyn_cast(BlockExp)) { - CPT = DRE->getType()->getAs(); - } else if (const MemberExpr *MExpr = dyn_cast(BlockExp)) { - CPT = MExpr->getType()->getAs(); - } - else if (const ParenExpr *PRE = dyn_cast(BlockExp)) { - return SynthesizeBlockCall(Exp, PRE->getSubExpr()); - } - else if (const ImplicitCastExpr *IEXPR = dyn_cast(BlockExp)) - CPT = IEXPR->getType()->getAs(); - else if (const ConditionalOperator *CEXPR = - dyn_cast(BlockExp)) { - Expr *LHSExp = CEXPR->getLHS(); - Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp); - Expr *RHSExp = CEXPR->getRHS(); - Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp); - Expr *CONDExp = CEXPR->getCond(); - ConditionalOperator *CondExpr = new (Context) ConditionalOperator( - CONDExp, SourceLocation(), cast(LHSStmt), SourceLocation(), - cast(RHSStmt), Exp->getType(), VK_PRValue, OK_Ordinary); - return CondExpr; - } else if (const ObjCIvarRefExpr *IRE = dyn_cast(BlockExp)) { - CPT = IRE->getType()->getAs(); - } else if (const PseudoObjectExpr *POE - = dyn_cast(BlockExp)) { - CPT = POE->getType()->castAs(); - } else { - assert(false && "RewriteBlockClass: Bad type"); - } - assert(CPT && "RewriteBlockClass: Bad type"); - const FunctionType *FT = CPT->getPointeeType()->getAs(); - assert(FT && "RewriteBlockClass: Bad type"); - const FunctionProtoType *FTP = dyn_cast(FT); - // FTP will be null for closures that don't take arguments. - - RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl, - SourceLocation(), SourceLocation(), - &Context->Idents.get("__block_impl")); - QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); - - // Generate a funky cast. - SmallVector ArgTypes; - - // Push the block argument type. - ArgTypes.push_back(PtrBlock); - if (FTP) { - for (auto &I : FTP->param_types()) { - QualType t = I; - // Make sure we convert "t (^)(...)" to "t (*)(...)". - if (!convertBlockPointerToFunctionPointer(t)) - convertToUnqualifiedObjCType(t); - ArgTypes.push_back(t); - } - } - // Now do the pointer to function cast. - QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes); - - PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); - - CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock, - CK_BitCast, - const_cast(BlockExp)); - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), - BlkCast); - //PE->dump(); - - FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), - SourceLocation(), - &Context->Idents.get("FuncPtr"), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - MemberExpr *ME = MemberExpr::CreateImplicit( - *Context, PE, true, FD, FD->getType(), VK_LValue, OK_Ordinary); - - CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, - CK_BitCast, ME); - PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); - - SmallVector BlkExprs; - // Add the implicit argument. - BlkExprs.push_back(BlkCast); - // Add the user arguments. - for (CallExpr::arg_iterator I = Exp->arg_begin(), - E = Exp->arg_end(); I != E; ++I) { - BlkExprs.push_back(*I); - } - CallExpr *CE = - CallExpr::Create(*Context, PE, BlkExprs, Exp->getType(), VK_PRValue, - SourceLocation(), FPOptionsOverride()); - return CE; -} - -// We need to return the rewritten expression to handle cases where the -// DeclRefExpr is embedded in another expression being rewritten. -// For example: -// -// int main() { -// __block Foo *f; -// __block int i; -// -// void (^myblock)() = ^() { -// [f test]; // f is a DeclRefExpr embedded in a message (which is being rewritten). -// i = 77; -// }; -//} -Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { - // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR - // for each DeclRefExp where BYREFVAR is name of the variable. - ValueDecl *VD = DeclRefExp->getDecl(); - bool isArrow = DeclRefExp->refersToEnclosingVariableOrCapture() || - HasLocalVariableExternalStorage(DeclRefExp->getDecl()); - - FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), - SourceLocation(), - &Context->Idents.get("__forwarding"), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - MemberExpr *ME = MemberExpr::CreateImplicit( - *Context, DeclRefExp, isArrow, FD, FD->getType(), VK_LValue, OK_Ordinary); - - StringRef Name = VD->getName(); - FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), - &Context->Idents.get(Name), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - ME = MemberExpr::CreateImplicit(*Context, ME, true, FD, DeclRefExp->getType(), - VK_LValue, OK_Ordinary); - - // Need parens to enforce precedence. - ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), - DeclRefExp->getExprLoc(), - ME); - ReplaceStmt(DeclRefExp, PE); - return PE; -} - -// Rewrites the imported local variable V with external storage -// (static, extern, etc.) as *V -// -Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { - ValueDecl *VD = DRE->getDecl(); - if (VarDecl *Var = dyn_cast(VD)) - if (!ImportedLocalExternalDecls.count(Var)) - return DRE; - Expr *Exp = UnaryOperator::Create( - const_cast(*Context), DRE, UO_Deref, DRE->getType(), - VK_LValue, OK_Ordinary, DRE->getLocation(), false, FPOptionsOverride()); - // Need parens to enforce precedence. - ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), - Exp); - ReplaceStmt(DRE, PE); - return PE; -} - -void RewriteModernObjC::RewriteCastExpr(CStyleCastExpr *CE) { - SourceLocation LocStart = CE->getLParenLoc(); - SourceLocation LocEnd = CE->getRParenLoc(); - - // Need to avoid trying to rewrite synthesized casts. - if (LocStart.isInvalid()) - return; - // Need to avoid trying to rewrite casts contained in macros. - if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd)) - return; - - const char *startBuf = SM->getCharacterData(LocStart); - const char *endBuf = SM->getCharacterData(LocEnd); - QualType QT = CE->getType(); - const Type* TypePtr = QT->getAs(); - if (isa(TypePtr)) { - const TypeOfExprType *TypeOfExprTypePtr = cast(TypePtr); - QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); - std::string TypeAsString = "("; - RewriteBlockPointerType(TypeAsString, QT); - TypeAsString += ")"; - ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString); - return; - } - // advance the location to startArgList. - const char *argPtr = startBuf; - - while (*argPtr++ && (argPtr < endBuf)) { - switch (*argPtr) { - case '^': - // Replace the '^' with '*'. - LocStart = LocStart.getLocWithOffset(argPtr-startBuf); - ReplaceText(LocStart, 1, "*"); - break; - } - } -} - -void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) { - CastKind CastKind = IC->getCastKind(); - if (CastKind != CK_BlockPointerToObjCPointerCast && - CastKind != CK_AnyPointerToBlockPointerCast) - return; - - QualType QT = IC->getType(); - (void)convertBlockPointerToFunctionPointer(QT); - std::string TypeString(QT.getAsString(Context->getPrintingPolicy())); - std::string Str = "("; - Str += TypeString; - Str += ")"; - InsertText(IC->getSubExpr()->getBeginLoc(), Str); -} - -void RewriteModernObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { - SourceLocation DeclLoc = FD->getLocation(); - unsigned parenCount = 0; - - // We have 1 or more arguments that have closure pointers. - const char *startBuf = SM->getCharacterData(DeclLoc); - const char *startArgList = strchr(startBuf, '('); - - assert((*startArgList == '(') && "Rewriter fuzzy parser confused"); - - parenCount++; - // advance the location to startArgList. - DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf); - assert((DeclLoc.isValid()) && "Invalid DeclLoc"); - - const char *argPtr = startArgList; - - while (*argPtr++ && parenCount) { - switch (*argPtr) { - case '^': - // Replace the '^' with '*'. - DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList); - ReplaceText(DeclLoc, 1, "*"); - break; - case '(': - parenCount++; - break; - case ')': - parenCount--; - break; - } - } -} - -bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { - const FunctionProtoType *FTP; - const PointerType *PT = QT->getAs(); - if (PT) { - FTP = PT->getPointeeType()->getAs(); - } else { - const BlockPointerType *BPT = QT->getAs(); - assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); - FTP = BPT->getPointeeType()->getAs(); - } - if (FTP) { - for (const auto &I : FTP->param_types()) - if (isTopLevelBlockPointerType(I)) - return true; - } - return false; -} - -bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) { - const FunctionProtoType *FTP; - const PointerType *PT = QT->getAs(); - if (PT) { - FTP = PT->getPointeeType()->getAs(); - } else { - const BlockPointerType *BPT = QT->getAs(); - assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); - FTP = BPT->getPointeeType()->getAs(); - } - if (FTP) { - for (const auto &I : FTP->param_types()) { - if (I->isObjCQualifiedIdType()) - return true; - if (I->isObjCObjectPointerType() && - I->getPointeeType()->isObjCQualifiedInterfaceType()) - return true; - } - - } - return false; -} - -void RewriteModernObjC::GetExtentOfArgList(const char *Name, const char *&LParen, - const char *&RParen) { - const char *argPtr = strchr(Name, '('); - assert((*argPtr == '(') && "Rewriter fuzzy parser confused"); - - LParen = argPtr; // output the start. - argPtr++; // skip past the left paren. - unsigned parenCount = 1; - - while (*argPtr && parenCount) { - switch (*argPtr) { - case '(': parenCount++; break; - case ')': parenCount--; break; - default: break; - } - if (parenCount) argPtr++; - } - assert((*argPtr == ')') && "Rewriter fuzzy parser confused"); - RParen = argPtr; // output the end -} - -void RewriteModernObjC::RewriteBlockPointerDecl(NamedDecl *ND) { - if (FunctionDecl *FD = dyn_cast(ND)) { - RewriteBlockPointerFunctionArgs(FD); - return; - } - // Handle Variables and Typedefs. - SourceLocation DeclLoc = ND->getLocation(); - QualType DeclT; - if (VarDecl *VD = dyn_cast(ND)) - DeclT = VD->getType(); - else if (TypedefNameDecl *TDD = dyn_cast(ND)) - DeclT = TDD->getUnderlyingType(); - else if (FieldDecl *FD = dyn_cast(ND)) - DeclT = FD->getType(); - else - llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled"); - - const char *startBuf = SM->getCharacterData(DeclLoc); - const char *endBuf = startBuf; - // scan backward (from the decl location) for the end of the previous decl. - while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart) - startBuf--; - SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf); - std::string buf; - unsigned OrigLength=0; - // *startBuf != '^' if we are dealing with a pointer to function that - // may take block argument types (which will be handled below). - if (*startBuf == '^') { - // Replace the '^' with '*', computing a negative offset. - buf = '*'; - startBuf++; - OrigLength++; - } - while (*startBuf != ')') { - buf += *startBuf; - startBuf++; - OrigLength++; - } - buf += ')'; - OrigLength++; - - if (PointerTypeTakesAnyBlockArguments(DeclT) || - PointerTypeTakesAnyObjCQualifiedType(DeclT)) { - // Replace the '^' with '*' for arguments. - // Replace id

with id/*<>*/ - DeclLoc = ND->getLocation(); - startBuf = SM->getCharacterData(DeclLoc); - const char *argListBegin, *argListEnd; - GetExtentOfArgList(startBuf, argListBegin, argListEnd); - while (argListBegin < argListEnd) { - if (*argListBegin == '^') - buf += '*'; - else if (*argListBegin == '<') { - buf += "/*"; - buf += *argListBegin++; - OrigLength++; - while (*argListBegin != '>') { - buf += *argListBegin++; - OrigLength++; - } - buf += *argListBegin; - buf += "*/"; - } - else - buf += *argListBegin; - argListBegin++; - OrigLength++; - } - buf += ')'; - OrigLength++; - } - ReplaceText(Start, OrigLength, buf); -} - -/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: -/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, -/// struct Block_byref_id_object *src) { -/// _Block_object_assign (&_dest->object, _src->object, -/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT -/// [|BLOCK_FIELD_IS_WEAK]) // object -/// _Block_object_assign(&_dest->object, _src->object, -/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK -/// [|BLOCK_FIELD_IS_WEAK]) // block -/// } -/// And: -/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { -/// _Block_object_dispose(_src->object, -/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT -/// [|BLOCK_FIELD_IS_WEAK]) // object -/// _Block_object_dispose(_src->object, -/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK -/// [|BLOCK_FIELD_IS_WEAK]) // block -/// } - -std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, - int flag) { - std::string S; - if (CopyDestroyCache.count(flag)) - return S; - CopyDestroyCache.insert(flag); - S = "static void __Block_byref_id_object_copy_"; - S += utostr(flag); - S += "(void *dst, void *src) {\n"; - - // offset into the object pointer is computed as: - // void * + void* + int + int + void* + void * - unsigned IntSize = - static_cast(Context->getTypeSize(Context->IntTy)); - unsigned VoidPtrSize = - static_cast(Context->getTypeSize(Context->VoidPtrTy)); - - unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth(); - S += " _Block_object_assign((char*)dst + "; - S += utostr(offset); - S += ", *(void * *) ((char*)src + "; - S += utostr(offset); - S += "), "; - S += utostr(flag); - S += ");\n}\n"; - - S += "static void __Block_byref_id_object_dispose_"; - S += utostr(flag); - S += "(void *src) {\n"; - S += " _Block_object_dispose(*(void * *) ((char*)src + "; - S += utostr(offset); - S += "), "; - S += utostr(flag); - S += ");\n}\n"; - return S; -} - -/// RewriteByRefVar - For each __block typex ND variable this routine transforms -/// the declaration into: -/// struct __Block_byref_ND { -/// void *__isa; // NULL for everything except __weak pointers -/// struct __Block_byref_ND *__forwarding; -/// int32_t __flags; -/// int32_t __size; -/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object -/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object -/// typex ND; -/// }; -/// -/// It then replaces declaration of ND variable with: -/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, -/// __size=sizeof(struct __Block_byref_ND), -/// ND=initializer-if-any}; -/// -/// -void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl, - bool lastDecl) { - int flag = 0; - int isa = 0; - SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); - if (DeclLoc.isInvalid()) - // If type location is missing, it is because of missing type (a warning). - // Use variable's location which is good for this case. - DeclLoc = ND->getLocation(); - const char *startBuf = SM->getCharacterData(DeclLoc); - SourceLocation X = ND->getEndLoc(); - X = SM->getExpansionLoc(X); - const char *endBuf = SM->getCharacterData(X); - std::string Name(ND->getNameAsString()); - std::string ByrefType; - RewriteByRefString(ByrefType, Name, ND, true); - ByrefType += " {\n"; - ByrefType += " void *__isa;\n"; - RewriteByRefString(ByrefType, Name, ND); - ByrefType += " *__forwarding;\n"; - ByrefType += " int __flags;\n"; - ByrefType += " int __size;\n"; - // Add void *__Block_byref_id_object_copy; - // void *__Block_byref_id_object_dispose; if needed. - QualType Ty = ND->getType(); - bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND); - if (HasCopyAndDispose) { - ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n"; - ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n"; - } - - QualType T = Ty; - (void)convertBlockPointerToFunctionPointer(T); - T.getAsStringInternal(Name, Context->getPrintingPolicy()); - - ByrefType += " " + Name + ";\n"; - ByrefType += "};\n"; - // Insert this type in global scope. It is needed by helper function. - SourceLocation FunLocStart; - if (CurFunctionDef) - FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef); - else { - assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null"); - FunLocStart = CurMethodDef->getBeginLoc(); - } - InsertText(FunLocStart, ByrefType); - - if (Ty.isObjCGCWeak()) { - flag |= BLOCK_FIELD_IS_WEAK; - isa = 1; - } - if (HasCopyAndDispose) { - flag = BLOCK_BYREF_CALLER; - QualType Ty = ND->getType(); - // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well. - if (Ty->isBlockPointerType()) - flag |= BLOCK_FIELD_IS_BLOCK; - else - flag |= BLOCK_FIELD_IS_OBJECT; - std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag); - if (!HF.empty()) - Preamble += HF; - } - - // struct __Block_byref_ND ND = - // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), - // initializer-if-any}; - bool hasInit = (ND->getInit() != nullptr); - // FIXME. rewriter does not support __block c++ objects which - // require construction. - if (hasInit) - if (CXXConstructExpr *CExp = dyn_cast(ND->getInit())) { - CXXConstructorDecl *CXXDecl = CExp->getConstructor(); - if (CXXDecl && CXXDecl->isDefaultConstructor()) - hasInit = false; - } - - unsigned flags = 0; - if (HasCopyAndDispose) - flags |= BLOCK_HAS_COPY_DISPOSE; - Name = ND->getNameAsString(); - ByrefType.clear(); - RewriteByRefString(ByrefType, Name, ND); - std::string ForwardingCastType("("); - ForwardingCastType += ByrefType + " *)"; - ByrefType += " " + Name + " = {(void*)"; - ByrefType += utostr(isa); - ByrefType += "," + ForwardingCastType + "&" + Name + ", "; - ByrefType += utostr(flags); - ByrefType += ", "; - ByrefType += "sizeof("; - RewriteByRefString(ByrefType, Name, ND); - ByrefType += ")"; - if (HasCopyAndDispose) { - ByrefType += ", __Block_byref_id_object_copy_"; - ByrefType += utostr(flag); - ByrefType += ", __Block_byref_id_object_dispose_"; - ByrefType += utostr(flag); - } - - if (!firstDecl) { - // In multiple __block declarations, and for all but 1st declaration, - // find location of the separating comma. This would be start location - // where new text is to be inserted. - DeclLoc = ND->getLocation(); - const char *startDeclBuf = SM->getCharacterData(DeclLoc); - const char *commaBuf = startDeclBuf; - while (*commaBuf != ',') - commaBuf--; - assert((*commaBuf == ',') && "RewriteByRefVar: can't find ','"); - DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf); - startBuf = commaBuf; - } - - if (!hasInit) { - ByrefType += "};\n"; - unsigned nameSize = Name.size(); - // for block or function pointer declaration. Name is already - // part of the declaration. - if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) - nameSize = 1; - ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType); - } - else { - ByrefType += ", "; - SourceLocation startLoc; - Expr *E = ND->getInit(); - if (const CStyleCastExpr *ECE = dyn_cast(E)) - startLoc = ECE->getLParenLoc(); - else - startLoc = E->getBeginLoc(); - startLoc = SM->getExpansionLoc(startLoc); - endBuf = SM->getCharacterData(startLoc); - ReplaceText(DeclLoc, endBuf-startBuf, ByrefType); - - const char separator = lastDecl ? ';' : ','; - const char *startInitializerBuf = SM->getCharacterData(startLoc); - const char *separatorBuf = strchr(startInitializerBuf, separator); - assert((*separatorBuf == separator) && - "RewriteByRefVar: can't find ';' or ','"); - SourceLocation separatorLoc = - startLoc.getLocWithOffset(separatorBuf-startInitializerBuf); - - InsertText(separatorLoc, lastDecl ? "}" : "};\n"); - } -} - -void RewriteModernObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { - // Add initializers for any closure decl refs. - GetBlockDeclRefExprs(Exp->getBody()); - if (BlockDeclRefs.size()) { - // Unique all "by copy" declarations. - for (unsigned i = 0; i < BlockDeclRefs.size(); i++) - if (!BlockDeclRefs[i]->getDecl()->hasAttr()) - BlockByCopyDecls.insert(BlockDeclRefs[i]->getDecl()); - // Unique all "by ref" declarations. - for (unsigned i = 0; i < BlockDeclRefs.size(); i++) - if (BlockDeclRefs[i]->getDecl()->hasAttr()) - BlockByRefDecls.insert(BlockDeclRefs[i]->getDecl()); - // Find any imported blocks...they will need special attention. - for (unsigned i = 0; i < BlockDeclRefs.size(); i++) - if (BlockDeclRefs[i]->getDecl()->hasAttr() || - BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || - BlockDeclRefs[i]->getType()->isBlockPointerType()) - ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl()); - } -} - -FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) { - IdentifierInfo *ID = &Context->Idents.get(name); - QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); - return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), - SourceLocation(), ID, FType, nullptr, SC_Extern, - false, false); -} - -Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, - const SmallVectorImpl &InnerBlockDeclRefs) { - const BlockDecl *block = Exp->getBlockDecl(); - - Blocks.push_back(Exp); - - CollectBlockDeclRefInfo(Exp); - - // Add inner imported variables now used in current block. - int countOfInnerDecls = 0; - if (!InnerBlockDeclRefs.empty()) { - for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { - DeclRefExpr *Exp = InnerBlockDeclRefs[i]; - ValueDecl *VD = Exp->getDecl(); - if (!VD->hasAttr() && BlockByCopyDecls.insert(VD)) { - // We need to save the copied-in variables in nested - // blocks because it is needed at the end for some of the API - // generations. See SynthesizeBlockLiterals routine. - InnerDeclRefs.push_back(Exp); countOfInnerDecls++; - BlockDeclRefs.push_back(Exp); - } - if (VD->hasAttr() && BlockByRefDecls.insert(VD)) { - InnerDeclRefs.push_back(Exp); countOfInnerDecls++; - BlockDeclRefs.push_back(Exp); - } - } - // Find any imported blocks...they will need special attention. - for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) - if (InnerBlockDeclRefs[i]->getDecl()->hasAttr() || - InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || - InnerBlockDeclRefs[i]->getType()->isBlockPointerType()) - ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl()); - } - InnerDeclRefsCount.push_back(countOfInnerDecls); - - std::string FuncName; - - if (CurFunctionDef) - FuncName = CurFunctionDef->getNameAsString(); - else if (CurMethodDef) - BuildUniqueMethodName(FuncName, CurMethodDef); - else if (GlobalVarDecl) - FuncName = std::string(GlobalVarDecl->getNameAsString()); - - bool GlobalBlockExpr = - block->getDeclContext()->getRedeclContext()->isFileContext(); - - if (GlobalBlockExpr && !GlobalVarDecl) { - Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag); - GlobalBlockExpr = false; - } - - std::string BlockNumber = utostr(Blocks.size()-1); - - std::string Func = "__" + FuncName + "_block_func_" + BlockNumber; - - // Get a pointer to the function type so we can cast appropriately. - QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType()); - QualType FType = Context->getPointerType(BFT); - - FunctionDecl *FD; - Expr *NewRep; - - // Simulate a constructor call... - std::string Tag; - - if (GlobalBlockExpr) - Tag = "__global_"; - else - Tag = "__"; - Tag += FuncName + "_block_impl_" + BlockNumber; - - FD = SynthBlockInitFunctionDecl(Tag); - DeclRefExpr *DRE = new (Context) - DeclRefExpr(*Context, FD, false, FType, VK_PRValue, SourceLocation()); - - SmallVector InitExprs; - - // Initialize the block function. - FD = SynthBlockInitFunctionDecl(Func); - DeclRefExpr *Arg = new (Context) DeclRefExpr( - *Context, FD, false, FD->getType(), VK_LValue, SourceLocation()); - CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, - CK_BitCast, Arg); - InitExprs.push_back(castExpr); - - // Initialize the block descriptor. - std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA"; - - VarDecl *NewVD = VarDecl::Create( - *Context, TUDecl, SourceLocation(), SourceLocation(), - &Context->Idents.get(DescData), Context->VoidPtrTy, nullptr, SC_Static); - UnaryOperator *DescRefExpr = UnaryOperator::Create( - const_cast(*Context), - new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy, - VK_LValue, SourceLocation()), - UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_PRValue, - OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); - InitExprs.push_back(DescRefExpr); - - // Add initializers for any closure decl refs. - if (BlockDeclRefs.size()) { - Expr *Exp; - // Output all "by copy" declarations. - for (ValueDecl *VD : BlockByCopyDecls) { - if (isObjCType(VD->getType())) { - // FIXME: Conform to ABI ([[obj retain] autorelease]). - FD = SynthBlockInitFunctionDecl(VD->getName()); - Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(), - VK_LValue, SourceLocation()); - if (HasLocalVariableExternalStorage(VD)) { - QualType QT = VD->getType(); - QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_PRValue, OK_Ordinary, - SourceLocation(), false, - FPOptionsOverride()); - } - } else if (isTopLevelBlockPointerType(VD->getType())) { - FD = SynthBlockInitFunctionDecl(VD->getName()); - Arg = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(), - VK_LValue, SourceLocation()); - Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, - CK_BitCast, Arg); - } else { - FD = SynthBlockInitFunctionDecl(VD->getName()); - Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(), - VK_LValue, SourceLocation()); - if (HasLocalVariableExternalStorage(VD)) { - QualType QT = VD->getType(); - QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_PRValue, OK_Ordinary, - SourceLocation(), false, - FPOptionsOverride()); - } - } - InitExprs.push_back(Exp); - } - // Output all "by ref" declarations. - for (ValueDecl *ND : BlockByRefDecls) { - std::string Name(ND->getNameAsString()); - std::string RecName; - RewriteByRefString(RecName, Name, ND, true); - IdentifierInfo *II = &Context->Idents.get(RecName.c_str() - + sizeof("struct")); - RecordDecl *RD = - RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl, - SourceLocation(), SourceLocation(), II); - assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); - QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); - - FD = SynthBlockInitFunctionDecl(ND->getName()); - Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(), - VK_LValue, SourceLocation()); - bool isNestedCapturedVar = false; - for (const auto &CI : block->captures()) { - const VarDecl *variable = CI.getVariable(); - if (variable == ND && CI.isNested()) { - assert(CI.isByRef() && - "SynthBlockInitExpr - captured block variable is not byref"); - isNestedCapturedVar = true; - break; - } - } - // captured nested byref variable has its address passed. Do not take - // its address again. - if (!isNestedCapturedVar) - Exp = UnaryOperator::Create( - const_cast(*Context), Exp, UO_AddrOf, - Context->getPointerType(Exp->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); - InitExprs.push_back(Exp); - } - } - if (ImportedBlockDecls.size()) { - // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR - int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR); - unsigned IntSize = - static_cast(Context->getTypeSize(Context->IntTy)); - Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), - Context->IntTy, SourceLocation()); - InitExprs.push_back(FlagExp); - } - NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue, - SourceLocation(), FPOptionsOverride()); - - if (GlobalBlockExpr) { - assert (!GlobalConstructionExp && - "SynthBlockInitExpr - GlobalConstructionExp must be null"); - GlobalConstructionExp = NewRep; - NewRep = DRE; - } - - NewRep = UnaryOperator::Create( - const_cast(*Context), NewRep, UO_AddrOf, - Context->getPointerType(NewRep->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, - NewRep); - // Put Paren around the call. - NewRep = new (Context) ParenExpr(SourceLocation(), SourceLocation(), - NewRep); - - BlockDeclRefs.clear(); - BlockByRefDecls.clear(); - BlockByCopyDecls.clear(); - ImportedBlockDecls.clear(); - return NewRep; -} - -bool RewriteModernObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) { - if (const ObjCForCollectionStmt * CS = - dyn_cast(Stmts.back())) - return CS->getElement() == DS; - return false; -} - -//===----------------------------------------------------------------------===// -// Function Body / Expression rewriting -//===----------------------------------------------------------------------===// - -Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { - if (isa(S) || isa(S) || - isa(S) || isa(S)) - Stmts.push_back(S); - else if (isa(S)) { - Stmts.push_back(S); - ObjCBcLabelNo.push_back(++BcLabelCount); - } - - // Pseudo-object operations and ivar references need special - // treatment because we're going to recursively rewrite them. - if (PseudoObjectExpr *PseudoOp = dyn_cast(S)) { - if (isa(PseudoOp->getSyntacticForm())) { - return RewritePropertyOrImplicitSetter(PseudoOp); - } else { - return RewritePropertyOrImplicitGetter(PseudoOp); - } - } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast(S)) { - return RewriteObjCIvarRefExpr(IvarRefExpr); - } - else if (isa(S)) - S = cast(S)->getSourceExpr(); - - SourceRange OrigStmtRange = S->getSourceRange(); - - // Perform a bottom up rewrite of all children. - for (Stmt *&childStmt : S->children()) - if (childStmt) { - Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt); - if (newStmt) { - childStmt = newStmt; - } - } - - if (BlockExpr *BE = dyn_cast(S)) { - SmallVector InnerBlockDeclRefs; - llvm::SmallPtrSet InnerContexts; - InnerContexts.insert(BE->getBlockDecl()); - ImportedLocalExternalDecls.clear(); - GetInnerBlockDeclRefExprs(BE->getBody(), - InnerBlockDeclRefs, InnerContexts); - // Rewrite the block body in place. - Stmt *SaveCurrentBody = CurrentBody; - CurrentBody = BE->getBody(); - PropParentMap = nullptr; - // block literal on rhs of a property-dot-sytax assignment - // must be replaced by its synthesize ast so getRewrittenText - // works as expected. In this case, what actually ends up on RHS - // is the blockTranscribed which is the helper function for the - // block literal; as in: self.c = ^() {[ace ARR];}; - bool saveDisableReplaceStmt = DisableReplaceStmt; - DisableReplaceStmt = false; - RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); - DisableReplaceStmt = saveDisableReplaceStmt; - CurrentBody = SaveCurrentBody; - PropParentMap = nullptr; - ImportedLocalExternalDecls.clear(); - // Now we snarf the rewritten text and stash it away for later use. - std::string Str = Rewrite.getRewrittenText(BE->getSourceRange()); - RewrittenBlockExprs[BE] = Str; - - Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); - - //blockTranscribed->dump(); - ReplaceStmt(S, blockTranscribed); - return blockTranscribed; - } - // Handle specific things. - if (ObjCEncodeExpr *AtEncode = dyn_cast(S)) - return RewriteAtEncode(AtEncode); - - if (ObjCSelectorExpr *AtSelector = dyn_cast(S)) - return RewriteAtSelector(AtSelector); - - if (ObjCStringLiteral *AtString = dyn_cast(S)) - return RewriteObjCStringLiteral(AtString); - - if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast(S)) - return RewriteObjCBoolLiteralExpr(BoolLitExpr); - - if (ObjCBoxedExpr *BoxedExpr = dyn_cast(S)) - return RewriteObjCBoxedExpr(BoxedExpr); - - if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast(S)) - return RewriteObjCArrayLiteralExpr(ArrayLitExpr); - - if (ObjCDictionaryLiteral *DictionaryLitExpr = - dyn_cast(S)) - return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr); - - if (ObjCMessageExpr *MessExpr = dyn_cast(S)) { -#if 0 - // Before we rewrite it, put the original message expression in a comment. - SourceLocation startLoc = MessExpr->getBeginLoc(); - SourceLocation endLoc = MessExpr->getEndLoc(); - - const char *startBuf = SM->getCharacterData(startLoc); - const char *endBuf = SM->getCharacterData(endLoc); - - std::string messString; - messString += "// "; - messString.append(startBuf, endBuf-startBuf+1); - messString += "\n"; - - // FIXME: Missing definition of - // InsertText(clang::SourceLocation, char const*, unsigned int). - // InsertText(startLoc, messString); - // Tried this, but it didn't work either... - // ReplaceText(startLoc, 0, messString.c_str(), messString.size()); -#endif - return RewriteMessageExpr(MessExpr); - } - - if (ObjCAutoreleasePoolStmt *StmtAutoRelease = - dyn_cast(S)) { - return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease); - } - - if (ObjCAtTryStmt *StmtTry = dyn_cast(S)) - return RewriteObjCTryStmt(StmtTry); - - if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast(S)) - return RewriteObjCSynchronizedStmt(StmtTry); - - if (ObjCAtThrowStmt *StmtThrow = dyn_cast(S)) - return RewriteObjCThrowStmt(StmtThrow); - - if (ObjCProtocolExpr *ProtocolExp = dyn_cast(S)) - return RewriteObjCProtocolExpr(ProtocolExp); - - if (ObjCForCollectionStmt *StmtForCollection = - dyn_cast(S)) - return RewriteObjCForCollectionStmt(StmtForCollection, - OrigStmtRange.getEnd()); - if (BreakStmt *StmtBreakStmt = - dyn_cast(S)) - return RewriteBreakStmt(StmtBreakStmt); - if (ContinueStmt *StmtContinueStmt = - dyn_cast(S)) - return RewriteContinueStmt(StmtContinueStmt); - - // Need to check for protocol refs (id

, Foo

*) in variable decls - // and cast exprs. - if (DeclStmt *DS = dyn_cast(S)) { - // FIXME: What we're doing here is modifying the type-specifier that - // precedes the first Decl. In the future the DeclGroup should have - // a separate type-specifier that we can rewrite. - // NOTE: We need to avoid rewriting the DeclStmt if it is within - // the context of an ObjCForCollectionStmt. For example: - // NSArray *someArray; - // for (id index in someArray) ; - // This is because RewriteObjCForCollectionStmt() does textual rewriting - // and it depends on the original text locations/positions. - if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS)) - RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin()); - - // Blocks rewrite rules. - for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end(); - DI != DE; ++DI) { - Decl *SD = *DI; - if (ValueDecl *ND = dyn_cast(SD)) { - if (isTopLevelBlockPointerType(ND->getType())) - RewriteBlockPointerDecl(ND); - else if (ND->getType()->isFunctionPointerType()) - CheckFunctionPointerDecl(ND->getType(), ND); - if (VarDecl *VD = dyn_cast(SD)) { - if (VD->hasAttr()) { - static unsigned uniqueByrefDeclCount = 0; - assert(!BlockByRefDeclNo.count(ND) && - "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl"); - BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; - RewriteByRefVar(VD, (DI == DS->decl_begin()), ((DI+1) == DE)); - } - else - RewriteTypeOfDecl(VD); - } - } - if (TypedefNameDecl *TD = dyn_cast(SD)) { - if (isTopLevelBlockPointerType(TD->getUnderlyingType())) - RewriteBlockPointerDecl(TD); - else if (TD->getUnderlyingType()->isFunctionPointerType()) - CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); - } - } - } - - if (CStyleCastExpr *CE = dyn_cast(S)) - RewriteObjCQualifiedInterfaceTypes(CE); - - if (isa(S) || isa(S) || - isa(S) || isa(S)) { - assert(!Stmts.empty() && "Statement stack is empty"); - assert ((isa(Stmts.back()) || isa(Stmts.back()) || - isa(Stmts.back()) || isa(Stmts.back())) - && "Statement stack mismatch"); - Stmts.pop_back(); - } - // Handle blocks rewriting. - if (DeclRefExpr *DRE = dyn_cast(S)) { - ValueDecl *VD = DRE->getDecl(); - if (VD->hasAttr()) - return RewriteBlockDeclRefExpr(DRE); - if (HasLocalVariableExternalStorage(VD)) - return RewriteLocalVariableExternalStorage(DRE); - } - - if (CallExpr *CE = dyn_cast(S)) { - if (CE->getCallee()->getType()->isBlockPointerType()) { - Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee()); - ReplaceStmt(S, BlockCall); - return BlockCall; - } - } - if (CStyleCastExpr *CE = dyn_cast(S)) { - RewriteCastExpr(CE); - } - if (ImplicitCastExpr *ICE = dyn_cast(S)) { - RewriteImplicitCastObjCExpr(ICE); - } -#if 0 - - if (ImplicitCastExpr *ICE = dyn_cast(S)) { - CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), - ICE->getSubExpr(), - SourceLocation()); - // Get the new text. - std::string SStr; - llvm::raw_string_ostream Buf(SStr); - Replacement->printPretty(Buf); - const std::string &Str = Buf.str(); - - printf("CAST = %s\n", &Str[0]); - InsertText(ICE->getSubExpr()->getBeginLoc(), Str); - delete S; - return Replacement; - } -#endif - // Return this stmt unmodified. - return S; -} - -void RewriteModernObjC::RewriteRecordBody(RecordDecl *RD) { - for (auto *FD : RD->fields()) { - if (isTopLevelBlockPointerType(FD->getType())) - RewriteBlockPointerDecl(FD); - if (FD->getType()->isObjCQualifiedIdType() || - FD->getType()->isObjCQualifiedInterfaceType()) - RewriteObjCQualifiedInterfaceTypes(FD); - } -} - -/// HandleDeclInMainFile - This is called for each top-level decl defined in the -/// main file of the input. -void RewriteModernObjC::HandleDeclInMainFile(Decl *D) { - switch (D->getKind()) { - case Decl::Function: { - FunctionDecl *FD = cast(D); - if (FD->isOverloadedOperator()) - return; - - // Since function prototypes don't have ParmDecl's, we check the function - // prototype. This enables us to rewrite function declarations and - // definitions using the same code. - RewriteBlocksInFunctionProtoType(FD->getType(), FD); - - if (!FD->isThisDeclarationADefinition()) - break; - - // FIXME: If this should support Obj-C++, support CXXTryStmt - if (CompoundStmt *Body = dyn_cast_or_null(FD->getBody())) { - CurFunctionDef = FD; - CurrentBody = Body; - Body = - cast_or_null(RewriteFunctionBodyOrGlobalInitializer(Body)); - FD->setBody(Body); - CurrentBody = nullptr; - if (PropParentMap) { - delete PropParentMap; - PropParentMap = nullptr; - } - // This synthesizes and inserts the block "impl" struct, invoke function, - // and any copy/dispose helper functions. - InsertBlockLiteralsWithinFunction(FD); - RewriteLineDirective(D); - CurFunctionDef = nullptr; - } - break; - } - case Decl::ObjCMethod: { - ObjCMethodDecl *MD = cast(D); - if (CompoundStmt *Body = MD->getCompoundBody()) { - CurMethodDef = MD; - CurrentBody = Body; - Body = - cast_or_null(RewriteFunctionBodyOrGlobalInitializer(Body)); - MD->setBody(Body); - CurrentBody = nullptr; - if (PropParentMap) { - delete PropParentMap; - PropParentMap = nullptr; - } - InsertBlockLiteralsWithinMethod(MD); - RewriteLineDirective(D); - CurMethodDef = nullptr; - } - break; - } - case Decl::ObjCImplementation: { - ObjCImplementationDecl *CI = cast(D); - ClassImplementation.push_back(CI); - break; - } - case Decl::ObjCCategoryImpl: { - ObjCCategoryImplDecl *CI = cast(D); - CategoryImplementation.push_back(CI); - break; - } - case Decl::Var: { - VarDecl *VD = cast(D); - RewriteObjCQualifiedInterfaceTypes(VD); - if (isTopLevelBlockPointerType(VD->getType())) - RewriteBlockPointerDecl(VD); - else if (VD->getType()->isFunctionPointerType()) { - CheckFunctionPointerDecl(VD->getType(), VD); - if (VD->getInit()) { - if (CStyleCastExpr *CE = dyn_cast(VD->getInit())) { - RewriteCastExpr(CE); - } - } - } else if (VD->getType()->isRecordType()) { - RecordDecl *RD = VD->getType()->castAs()->getDecl(); - if (RD->isCompleteDefinition()) - RewriteRecordBody(RD); - } - if (VD->getInit()) { - GlobalVarDecl = VD; - CurrentBody = VD->getInit(); - RewriteFunctionBodyOrGlobalInitializer(VD->getInit()); - CurrentBody = nullptr; - if (PropParentMap) { - delete PropParentMap; - PropParentMap = nullptr; - } - SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName()); - GlobalVarDecl = nullptr; - - // This is needed for blocks. - if (CStyleCastExpr *CE = dyn_cast(VD->getInit())) { - RewriteCastExpr(CE); - } - } - break; - } - case Decl::TypeAlias: - case Decl::Typedef: { - if (TypedefNameDecl *TD = dyn_cast(D)) { - if (isTopLevelBlockPointerType(TD->getUnderlyingType())) - RewriteBlockPointerDecl(TD); - else if (TD->getUnderlyingType()->isFunctionPointerType()) - CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); - else - RewriteObjCQualifiedInterfaceTypes(TD); - } - break; - } - case Decl::CXXRecord: - case Decl::Record: { - RecordDecl *RD = cast(D); - if (RD->isCompleteDefinition()) - RewriteRecordBody(RD); - break; - } - default: - break; - } - // Nothing yet. -} - -/// Write_ProtocolExprReferencedMetadata - This routine writer out the -/// protocol reference symbols in the for of: -/// struct _protocol_t *PROTOCOL_REF = &PROTOCOL_METADATA. -static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, - ObjCProtocolDecl *PDecl, - std::string &Result) { - // Also output .objc_protorefs$B section and its meta-data. - if (Context->getLangOpts().MicrosoftExt) - Result += "static "; - Result += "struct _protocol_t *"; - Result += "_OBJC_PROTOCOL_REFERENCE_$_"; - Result += PDecl->getNameAsString(); - Result += " = &"; - Result += "_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString(); - Result += ";\n"; -} - -void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) { - if (Diags.hasErrorOccurred()) - return; - - RewriteInclude(); - - for (unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) { - // translation of function bodies were postponed until all class and - // their extensions and implementations are seen. This is because, we - // cannot build grouping structs for bitfields until they are all seen. - FunctionDecl *FDecl = FunctionDefinitionsSeen[i]; - HandleTopLevelSingleDecl(FDecl); - } - - // Here's a great place to add any extra declarations that may be needed. - // Write out meta data for each @protocol(). - for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) { - RewriteObjCProtocolMetaData(ProtDecl, Preamble); - Write_ProtocolExprReferencedMetadata(Context, ProtDecl, Preamble); - } - - InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); - - if (ClassImplementation.size() || CategoryImplementation.size()) - RewriteImplementations(); - - for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) { - ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i]; - // Write struct declaration for the class matching its ivar declarations. - // Note that for modern abi, this is postponed until the end of TU - // because class extensions and the implementation might declare their own - // private ivars. - RewriteInterfaceDecl(CDecl); - } - - // Get the buffer corresponding to MainFileID. If we haven't changed it, then - // we are done. - if (const RewriteBuffer *RewriteBuf = - Rewrite.getRewriteBufferFor(MainFileID)) { - //printf("Changed:\n"); - *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); - } else { - llvm::errs() << "No changes\n"; - } - - if (ClassImplementation.size() || CategoryImplementation.size() || - ProtocolExprDecls.size()) { - // Rewrite Objective-c meta data* - std::string ResultStr; - RewriteMetaDataIntoBuffer(ResultStr); - // Emit metadata. - *OutFile << ResultStr; - } - // Emit ImageInfo; - { - std::string ResultStr; - WriteImageInfo(ResultStr); - *OutFile << ResultStr; - } - OutFile->flush(); -} - -void RewriteModernObjC::Initialize(ASTContext &context) { - InitializeCommon(context); - - Preamble += "#ifndef __OBJC2__\n"; - Preamble += "#define __OBJC2__\n"; - Preamble += "#endif\n"; - - // declaring objc_selector outside the parameter list removes a silly - // scope related warning... - if (IsHeader) - Preamble = "#pragma once\n"; - Preamble += "struct objc_selector; struct objc_class;\n"; - Preamble += "struct __rw_objc_super { \n\tstruct objc_object *object; "; - Preamble += "\n\tstruct objc_object *superClass; "; - // Add a constructor for creating temporary objects. - Preamble += "\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) "; - Preamble += ": object(o), superClass(s) {} "; - Preamble += "\n};\n"; - - if (LangOpts.MicrosoftExt) { - // Define all sections using syntax that makes sense. - // These are currently generated. - Preamble += "\n#pragma section(\".objc_classlist$B\", long, read, write)\n"; - Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n"; - Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n"; - Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n"; - Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n"; - // These are generated but not necessary for functionality. - Preamble += "#pragma section(\".cat_cls_meth$B\", long, read, write)\n"; - Preamble += "#pragma section(\".inst_meth$B\", long, read, write)\n"; - Preamble += "#pragma section(\".cls_meth$B\", long, read, write)\n"; - Preamble += "#pragma section(\".objc_ivar$B\", long, read, write)\n"; - - // These need be generated for performance. Currently they are not, - // using API calls instead. - Preamble += "#pragma section(\".objc_selrefs$B\", long, read, write)\n"; - Preamble += "#pragma section(\".objc_classrefs$B\", long, read, write)\n"; - Preamble += "#pragma section(\".objc_superrefs$B\", long, read, write)\n"; - - } - Preamble += "#ifndef _REWRITER_typedef_Protocol\n"; - Preamble += "typedef struct objc_object Protocol;\n"; - Preamble += "#define _REWRITER_typedef_Protocol\n"; - Preamble += "#endif\n"; - if (LangOpts.MicrosoftExt) { - Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n"; - Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n"; - } - else - Preamble += "#define __OBJC_RW_DLLIMPORT extern\n"; - - Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n"; - - Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass"; - Preamble += "(const char *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass"; - Preamble += "(struct objc_class *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass"; - Preamble += "(const char *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n"; - // @synchronized hooks. - Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n"; - Preamble += "#ifdef _WIN64\n"; - Preamble += "typedef unsigned long long _WIN_NSUInteger;\n"; - Preamble += "#else\n"; - Preamble += "typedef unsigned int _WIN_NSUInteger;\n"; - Preamble += "#endif\n"; - Preamble += "#ifndef __FASTENUMERATIONSTATE\n"; - Preamble += "struct __objcFastEnumerationState {\n\t"; - Preamble += "unsigned long state;\n\t"; - Preamble += "void **itemsPtr;\n\t"; - Preamble += "unsigned long *mutationsPtr;\n\t"; - Preamble += "unsigned long extra[5];\n};\n"; - Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n"; - Preamble += "#define __FASTENUMERATIONSTATE\n"; - Preamble += "#endif\n"; - Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n"; - Preamble += "struct __NSConstantStringImpl {\n"; - Preamble += " int *isa;\n"; - Preamble += " int flags;\n"; - Preamble += " char *str;\n"; - Preamble += "#if _WIN64\n"; - Preamble += " long long length;\n"; - Preamble += "#else\n"; - Preamble += " long length;\n"; - Preamble += "#endif\n"; - Preamble += "};\n"; - Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n"; - Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n"; - Preamble += "#else\n"; - Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n"; - Preamble += "#endif\n"; - Preamble += "#define __NSCONSTANTSTRINGIMPL\n"; - Preamble += "#endif\n"; - // Blocks preamble. - Preamble += "#ifndef BLOCK_IMPL\n"; - Preamble += "#define BLOCK_IMPL\n"; - Preamble += "struct __block_impl {\n"; - Preamble += " void *isa;\n"; - Preamble += " int Flags;\n"; - Preamble += " int Reserved;\n"; - Preamble += " void *FuncPtr;\n"; - Preamble += "};\n"; - Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n"; - Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n"; - Preamble += "extern \"C\" __declspec(dllexport) " - "void _Block_object_assign(void *, const void *, const int);\n"; - Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n"; - Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n"; - Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n"; - Preamble += "#else\n"; - Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n"; - Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n"; - Preamble += "#endif\n"; - Preamble += "#endif\n"; - if (LangOpts.MicrosoftExt) { - Preamble += "#undef __OBJC_RW_DLLIMPORT\n"; - Preamble += "#undef __OBJC_RW_STATICIMPORT\n"; - Preamble += "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests. - Preamble += "#define __attribute__(X)\n"; - Preamble += "#endif\n"; - Preamble += "#ifndef __weak\n"; - Preamble += "#define __weak\n"; - Preamble += "#endif\n"; - Preamble += "#ifndef __block\n"; - Preamble += "#define __block\n"; - Preamble += "#endif\n"; - } - else { - Preamble += "#define __block\n"; - Preamble += "#define __weak\n"; - } - - // Declarations required for modern objective-c array and dictionary literals. - Preamble += "\n#include \n"; - Preamble += "struct __NSContainer_literal {\n"; - Preamble += " void * *arr;\n"; - Preamble += " __NSContainer_literal (unsigned int count, ...) {\n"; - Preamble += "\tva_list marker;\n"; - Preamble += "\tva_start(marker, count);\n"; - Preamble += "\tarr = new void *[count];\n"; - Preamble += "\tfor (unsigned i = 0; i < count; i++)\n"; - Preamble += "\t arr[i] = va_arg(marker, void *);\n"; - Preamble += "\tva_end( marker );\n"; - Preamble += " };\n"; - Preamble += " ~__NSContainer_literal() {\n"; - Preamble += "\tdelete[] arr;\n"; - Preamble += " }\n"; - Preamble += "};\n"; - - // Declaration required for implementation of @autoreleasepool statement. - Preamble += "extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n"; - Preamble += "extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n"; - Preamble += "struct __AtAutoreleasePool {\n"; - Preamble += " __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n"; - Preamble += " ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n"; - Preamble += " void * atautoreleasepoolobj;\n"; - Preamble += "};\n"; - - // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long - // as this avoids warning in any 64bit/32bit compilation model. - Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n"; -} - -/// RewriteIvarOffsetComputation - This routine synthesizes computation of -/// ivar offset. -void RewriteModernObjC::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, - std::string &Result) { - Result += "__OFFSETOFIVAR__(struct "; - Result += ivar->getContainingInterface()->getNameAsString(); - if (LangOpts.MicrosoftExt) - Result += "_IMPL"; - Result += ", "; - if (ivar->isBitField()) - ObjCIvarBitfieldGroupDecl(ivar, Result); - else - Result += ivar->getNameAsString(); - Result += ")"; -} - -/// WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI. -/// struct _prop_t { -/// const char *name; -/// char *attributes; -/// } - -/// struct _prop_list_t { -/// uint32_t entsize; // sizeof(struct _prop_t) -/// uint32_t count_of_properties; -/// struct _prop_t prop_list[count_of_properties]; -/// } - -/// struct _protocol_t; - -/// struct _protocol_list_t { -/// long protocol_count; // Note, this is 32/64 bit -/// struct _protocol_t * protocol_list[protocol_count]; -/// } - -/// struct _objc_method { -/// SEL _cmd; -/// const char *method_type; -/// char *_imp; -/// } - -/// struct _method_list_t { -/// uint32_t entsize; // sizeof(struct _objc_method) -/// uint32_t method_count; -/// struct _objc_method method_list[method_count]; -/// } - -/// struct _protocol_t { -/// id isa; // NULL -/// const char *protocol_name; -/// const struct _protocol_list_t * protocol_list; // super protocols -/// const struct method_list_t *instance_methods; -/// const struct method_list_t *class_methods; -/// const struct method_list_t *optionalInstanceMethods; -/// const struct method_list_t *optionalClassMethods; -/// const struct _prop_list_t * properties; -/// const uint32_t size; // sizeof(struct _protocol_t) -/// const uint32_t flags; // = 0 -/// const char ** extendedMethodTypes; -/// } - -/// struct _ivar_t { -/// unsigned long int *offset; // pointer to ivar offset location -/// const char *name; -/// const char *type; -/// uint32_t alignment; -/// uint32_t size; -/// } - -/// struct _ivar_list_t { -/// uint32 entsize; // sizeof(struct _ivar_t) -/// uint32 count; -/// struct _ivar_t list[count]; -/// } - -/// struct _class_ro_t { -/// uint32_t flags; -/// uint32_t instanceStart; -/// uint32_t instanceSize; -/// uint32_t reserved; // only when building for 64bit targets -/// const uint8_t *ivarLayout; -/// const char *name; -/// const struct _method_list_t *baseMethods; -/// const struct _protocol_list_t *baseProtocols; -/// const struct _ivar_list_t *ivars; -/// const uint8_t *weakIvarLayout; -/// const struct _prop_list_t *properties; -/// } - -/// struct _class_t { -/// struct _class_t *isa; -/// struct _class_t *superclass; -/// void *cache; -/// IMP *vtable; -/// struct _class_ro_t *ro; -/// } - -/// struct _category_t { -/// const char *name; -/// struct _class_t *cls; -/// const struct _method_list_t *instance_methods; -/// const struct _method_list_t *class_methods; -/// const struct _protocol_list_t *protocols; -/// const struct _prop_list_t *properties; -/// } - -/// MessageRefTy - LLVM for: -/// struct _message_ref_t { -/// IMP messenger; -/// SEL name; -/// }; - -/// SuperMessageRefTy - LLVM for: -/// struct _super_message_ref_t { -/// SUPER_IMP messenger; -/// SEL name; -/// }; - -static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result) { - static bool meta_data_declared = false; - if (meta_data_declared) - return; - - Result += "\nstruct _prop_t {\n"; - Result += "\tconst char *name;\n"; - Result += "\tconst char *attributes;\n"; - Result += "};\n"; - - Result += "\nstruct _protocol_t;\n"; - - Result += "\nstruct _objc_method {\n"; - Result += "\tstruct objc_selector * _cmd;\n"; - Result += "\tconst char *method_type;\n"; - Result += "\tvoid *_imp;\n"; - Result += "};\n"; - - Result += "\nstruct _protocol_t {\n"; - Result += "\tvoid * isa; // NULL\n"; - Result += "\tconst char *protocol_name;\n"; - Result += "\tconst struct _protocol_list_t * protocol_list; // super protocols\n"; - Result += "\tconst struct method_list_t *instance_methods;\n"; - Result += "\tconst struct method_list_t *class_methods;\n"; - Result += "\tconst struct method_list_t *optionalInstanceMethods;\n"; - Result += "\tconst struct method_list_t *optionalClassMethods;\n"; - Result += "\tconst struct _prop_list_t * properties;\n"; - Result += "\tconst unsigned int size; // sizeof(struct _protocol_t)\n"; - Result += "\tconst unsigned int flags; // = 0\n"; - Result += "\tconst char ** extendedMethodTypes;\n"; - Result += "};\n"; - - Result += "\nstruct _ivar_t {\n"; - Result += "\tunsigned long int *offset; // pointer to ivar offset location\n"; - Result += "\tconst char *name;\n"; - Result += "\tconst char *type;\n"; - Result += "\tunsigned int alignment;\n"; - Result += "\tunsigned int size;\n"; - Result += "};\n"; - - Result += "\nstruct _class_ro_t {\n"; - Result += "\tunsigned int flags;\n"; - Result += "\tunsigned int instanceStart;\n"; - Result += "\tunsigned int instanceSize;\n"; - const llvm::Triple &Triple(Context->getTargetInfo().getTriple()); - if (Triple.getArch() == llvm::Triple::x86_64) - Result += "\tunsigned int reserved;\n"; - Result += "\tconst unsigned char *ivarLayout;\n"; - Result += "\tconst char *name;\n"; - Result += "\tconst struct _method_list_t *baseMethods;\n"; - Result += "\tconst struct _objc_protocol_list *baseProtocols;\n"; - Result += "\tconst struct _ivar_list_t *ivars;\n"; - Result += "\tconst unsigned char *weakIvarLayout;\n"; - Result += "\tconst struct _prop_list_t *properties;\n"; - Result += "};\n"; - - Result += "\nstruct _class_t {\n"; - Result += "\tstruct _class_t *isa;\n"; - Result += "\tstruct _class_t *superclass;\n"; - Result += "\tvoid *cache;\n"; - Result += "\tvoid *vtable;\n"; - Result += "\tstruct _class_ro_t *ro;\n"; - Result += "};\n"; - - Result += "\nstruct _category_t {\n"; - Result += "\tconst char *name;\n"; - Result += "\tstruct _class_t *cls;\n"; - Result += "\tconst struct _method_list_t *instance_methods;\n"; - Result += "\tconst struct _method_list_t *class_methods;\n"; - Result += "\tconst struct _protocol_list_t *protocols;\n"; - Result += "\tconst struct _prop_list_t *properties;\n"; - Result += "};\n"; - - Result += "extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n"; - Result += "#pragma warning(disable:4273)\n"; - meta_data_declared = true; -} - -static void Write_protocol_list_t_TypeDecl(std::string &Result, - long super_protocol_count) { - Result += "struct /*_protocol_list_t*/"; Result += " {\n"; - Result += "\tlong protocol_count; // Note, this is 32/64 bit\n"; - Result += "\tstruct _protocol_t *super_protocols["; - Result += utostr(super_protocol_count); Result += "];\n"; - Result += "}"; -} - -static void Write_method_list_t_TypeDecl(std::string &Result, - unsigned int method_count) { - Result += "struct /*_method_list_t*/"; Result += " {\n"; - Result += "\tunsigned int entsize; // sizeof(struct _objc_method)\n"; - Result += "\tunsigned int method_count;\n"; - Result += "\tstruct _objc_method method_list["; - Result += utostr(method_count); Result += "];\n"; - Result += "}"; -} - -static void Write__prop_list_t_TypeDecl(std::string &Result, - unsigned int property_count) { - Result += "struct /*_prop_list_t*/"; Result += " {\n"; - Result += "\tunsigned int entsize; // sizeof(struct _prop_t)\n"; - Result += "\tunsigned int count_of_properties;\n"; - Result += "\tstruct _prop_t prop_list["; - Result += utostr(property_count); Result += "];\n"; - Result += "}"; -} - -static void Write__ivar_list_t_TypeDecl(std::string &Result, - unsigned int ivar_count) { - Result += "struct /*_ivar_list_t*/"; Result += " {\n"; - Result += "\tunsigned int entsize; // sizeof(struct _prop_t)\n"; - Result += "\tunsigned int count;\n"; - Result += "\tstruct _ivar_t ivar_list["; - Result += utostr(ivar_count); Result += "];\n"; - Result += "}"; -} - -static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result, - ArrayRef SuperProtocols, - StringRef VarName, - StringRef ProtocolName) { - if (SuperProtocols.size() > 0) { - Result += "\nstatic "; - Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size()); - Result += " "; Result += VarName; - Result += ProtocolName; - Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; - Result += "\t"; Result += utostr(SuperProtocols.size()); Result += ",\n"; - for (unsigned i = 0, e = SuperProtocols.size(); i < e; i++) { - ObjCProtocolDecl *SuperPD = SuperProtocols[i]; - Result += "\t&"; Result += "_OBJC_PROTOCOL_"; - Result += SuperPD->getNameAsString(); - if (i == e-1) - Result += "\n};\n"; - else - Result += ",\n"; - } - } -} - -static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj, - ASTContext *Context, std::string &Result, - ArrayRef Methods, - StringRef VarName, - StringRef TopLevelDeclName, - bool MethodImpl) { - if (Methods.size() > 0) { - Result += "\nstatic "; - Write_method_list_t_TypeDecl(Result, Methods.size()); - Result += " "; Result += VarName; - Result += TopLevelDeclName; - Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; - Result += "\t"; Result += "sizeof(_objc_method)"; Result += ",\n"; - Result += "\t"; Result += utostr(Methods.size()); Result += ",\n"; - for (unsigned i = 0, e = Methods.size(); i < e; i++) { - ObjCMethodDecl *MD = Methods[i]; - if (i == 0) - Result += "\t{{(struct objc_selector *)\""; - else - Result += "\t{(struct objc_selector *)\""; - Result += (MD)->getSelector().getAsString(); Result += "\""; - Result += ", "; - std::string MethodTypeString = Context->getObjCEncodingForMethodDecl(MD); - Result += "\""; Result += MethodTypeString; Result += "\""; - Result += ", "; - if (!MethodImpl) - Result += "0"; - else { - Result += "(void *)"; - Result += RewriteObj.MethodInternalNames[MD]; - } - if (i == e-1) - Result += "}}\n"; - else - Result += "},\n"; - } - Result += "};\n"; - } -} - -static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj, - ASTContext *Context, std::string &Result, - ArrayRef Properties, - const Decl *Container, - StringRef VarName, - StringRef ProtocolName) { - if (Properties.size() > 0) { - Result += "\nstatic "; - Write__prop_list_t_TypeDecl(Result, Properties.size()); - Result += " "; Result += VarName; - Result += ProtocolName; - Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; - Result += "\t"; Result += "sizeof(_prop_t)"; Result += ",\n"; - Result += "\t"; Result += utostr(Properties.size()); Result += ",\n"; - for (unsigned i = 0, e = Properties.size(); i < e; i++) { - ObjCPropertyDecl *PropDecl = Properties[i]; - if (i == 0) - Result += "\t{{\""; - else - Result += "\t{\""; - Result += PropDecl->getName(); Result += "\","; - std::string PropertyTypeString = - Context->getObjCEncodingForPropertyDecl(PropDecl, Container); - std::string QuotePropertyTypeString; - RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString); - Result += "\""; Result += QuotePropertyTypeString; Result += "\""; - if (i == e-1) - Result += "}}\n"; - else - Result += "},\n"; - } - Result += "};\n"; - } -} - -// Metadata flags -enum MetaDataDlags { - CLS = 0x0, - CLS_META = 0x1, - CLS_ROOT = 0x2, - OBJC2_CLS_HIDDEN = 0x10, - CLS_EXCEPTION = 0x20, - - /// (Obsolete) ARC-specific: this class has a .release_ivars method - CLS_HAS_IVAR_RELEASER = 0x40, - /// class was compiled with -fobjc-arr - CLS_COMPILED_BY_ARC = 0x80 // (1<<7) -}; - -static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, - unsigned int flags, - const std::string &InstanceStart, - const std::string &InstanceSize, - ArrayRefbaseMethods, - ArrayRefbaseProtocols, - ArrayRefivars, - ArrayRefProperties, - StringRef VarName, - StringRef ClassName) { - Result += "\nstatic struct _class_ro_t "; - Result += VarName; Result += ClassName; - Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; - Result += "\t"; - Result += llvm::utostr(flags); Result += ", "; - Result += InstanceStart; Result += ", "; - Result += InstanceSize; Result += ", \n"; - Result += "\t"; - const llvm::Triple &Triple(Context->getTargetInfo().getTriple()); - if (Triple.getArch() == llvm::Triple::x86_64) - // uint32_t const reserved; // only when building for 64bit targets - Result += "(unsigned int)0, \n\t"; - // const uint8_t * const ivarLayout; - Result += "0, \n\t"; - Result += "\""; Result += ClassName; Result += "\",\n\t"; - bool metaclass = ((flags & CLS_META) != 0); - if (baseMethods.size() > 0) { - Result += "(const struct _method_list_t *)&"; - if (metaclass) - Result += "_OBJC_$_CLASS_METHODS_"; - else - Result += "_OBJC_$_INSTANCE_METHODS_"; - Result += ClassName; - Result += ",\n\t"; - } - else - Result += "0, \n\t"; - - if (!metaclass && baseProtocols.size() > 0) { - Result += "(const struct _objc_protocol_list *)&"; - Result += "_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName; - Result += ",\n\t"; - } - else - Result += "0, \n\t"; - - if (!metaclass && ivars.size() > 0) { - Result += "(const struct _ivar_list_t *)&"; - Result += "_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName; - Result += ",\n\t"; - } - else - Result += "0, \n\t"; - - // weakIvarLayout - Result += "0, \n\t"; - if (!metaclass && Properties.size() > 0) { - Result += "(const struct _prop_list_t *)&"; - Result += "_OBJC_$_PROP_LIST_"; Result += ClassName; - Result += ",\n"; - } - else - Result += "0, \n"; - - Result += "};\n"; -} - -static void Write_class_t(ASTContext *Context, std::string &Result, - StringRef VarName, - const ObjCInterfaceDecl *CDecl, bool metaclass) { - bool rootClass = (!CDecl->getSuperClass()); - const ObjCInterfaceDecl *RootClass = CDecl; - - if (!rootClass) { - // Find the Root class - RootClass = CDecl->getSuperClass(); - while (RootClass->getSuperClass()) { - RootClass = RootClass->getSuperClass(); - } - } - - if (metaclass && rootClass) { - // Need to handle a case of use of forward declaration. - Result += "\n"; - Result += "extern \"C\" "; - if (CDecl->getImplementation()) - Result += "__declspec(dllexport) "; - else - Result += "__declspec(dllimport) "; - - Result += "struct _class_t OBJC_CLASS_$_"; - Result += CDecl->getNameAsString(); - Result += ";\n"; - } - // Also, for possibility of 'super' metadata class not having been defined yet. - if (!rootClass) { - ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass(); - Result += "\n"; - Result += "extern \"C\" "; - if (SuperClass->getImplementation()) - Result += "__declspec(dllexport) "; - else - Result += "__declspec(dllimport) "; - - Result += "struct _class_t "; - Result += VarName; - Result += SuperClass->getNameAsString(); - Result += ";\n"; - - if (metaclass && RootClass != SuperClass) { - Result += "extern \"C\" "; - if (RootClass->getImplementation()) - Result += "__declspec(dllexport) "; - else - Result += "__declspec(dllimport) "; - - Result += "struct _class_t "; - Result += VarName; - Result += RootClass->getNameAsString(); - Result += ";\n"; - } - } - - Result += "\nextern \"C\" __declspec(dllexport) struct _class_t "; - Result += VarName; Result += CDecl->getNameAsString(); - Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n"; - Result += "\t"; - if (metaclass) { - if (!rootClass) { - Result += "0, // &"; Result += VarName; - Result += RootClass->getNameAsString(); - Result += ",\n\t"; - Result += "0, // &"; Result += VarName; - Result += CDecl->getSuperClass()->getNameAsString(); - Result += ",\n\t"; - } - else { - Result += "0, // &"; Result += VarName; - Result += CDecl->getNameAsString(); - Result += ",\n\t"; - Result += "0, // &OBJC_CLASS_$_"; Result += CDecl->getNameAsString(); - Result += ",\n\t"; - } - } - else { - Result += "0, // &OBJC_METACLASS_$_"; - Result += CDecl->getNameAsString(); - Result += ",\n\t"; - if (!rootClass) { - Result += "0, // &"; Result += VarName; - Result += CDecl->getSuperClass()->getNameAsString(); - Result += ",\n\t"; - } - else - Result += "0,\n\t"; - } - Result += "0, // (void *)&_objc_empty_cache,\n\t"; - Result += "0, // unused, was (void *)&_objc_empty_vtable,\n\t"; - if (metaclass) - Result += "&_OBJC_METACLASS_RO_$_"; - else - Result += "&_OBJC_CLASS_RO_$_"; - Result += CDecl->getNameAsString(); - Result += ",\n};\n"; - - // Add static function to initialize some of the meta-data fields. - // avoid doing it twice. - if (metaclass) - return; - - const ObjCInterfaceDecl *SuperClass = - rootClass ? CDecl : CDecl->getSuperClass(); - - Result += "static void OBJC_CLASS_SETUP_$_"; - Result += CDecl->getNameAsString(); - Result += "(void ) {\n"; - Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString(); - Result += ".isa = "; Result += "&OBJC_METACLASS_$_"; - Result += RootClass->getNameAsString(); Result += ";\n"; - - Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString(); - Result += ".superclass = "; - if (rootClass) - Result += "&OBJC_CLASS_$_"; - else - Result += "&OBJC_METACLASS_$_"; - - Result += SuperClass->getNameAsString(); Result += ";\n"; - - Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString(); - Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n"; - - Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString(); - Result += ".isa = "; Result += "&OBJC_METACLASS_$_"; - Result += CDecl->getNameAsString(); Result += ";\n"; - - if (!rootClass) { - Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString(); - Result += ".superclass = "; Result += "&OBJC_CLASS_$_"; - Result += SuperClass->getNameAsString(); Result += ";\n"; - } - - Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString(); - Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n"; - Result += "}\n"; -} - -static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, - std::string &Result, - ObjCCategoryDecl *CatDecl, - ObjCInterfaceDecl *ClassDecl, - ArrayRef InstanceMethods, - ArrayRef ClassMethods, - ArrayRef RefedProtocols, - ArrayRef ClassProperties) { - StringRef CatName = CatDecl->getName(); - StringRef ClassName = ClassDecl->getName(); - // must declare an extern class object in case this class is not implemented - // in this TU. - Result += "\n"; - Result += "extern \"C\" "; - if (ClassDecl->getImplementation()) - Result += "__declspec(dllexport) "; - else - Result += "__declspec(dllimport) "; - - Result += "struct _class_t "; - Result += "OBJC_CLASS_$_"; Result += ClassName; - Result += ";\n"; - - Result += "\nstatic struct _category_t "; - Result += "_OBJC_$_CATEGORY_"; - Result += ClassName; Result += "_$_"; Result += CatName; - Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n"; - Result += "{\n"; - Result += "\t\""; Result += ClassName; Result += "\",\n"; - Result += "\t0, // &"; Result += "OBJC_CLASS_$_"; Result += ClassName; - Result += ",\n"; - if (InstanceMethods.size() > 0) { - Result += "\t(const struct _method_list_t *)&"; - Result += "_OBJC_$_CATEGORY_INSTANCE_METHODS_"; - Result += ClassName; Result += "_$_"; Result += CatName; - Result += ",\n"; - } - else - Result += "\t0,\n"; - - if (ClassMethods.size() > 0) { - Result += "\t(const struct _method_list_t *)&"; - Result += "_OBJC_$_CATEGORY_CLASS_METHODS_"; - Result += ClassName; Result += "_$_"; Result += CatName; - Result += ",\n"; - } - else - Result += "\t0,\n"; - - if (RefedProtocols.size() > 0) { - Result += "\t(const struct _protocol_list_t *)&"; - Result += "_OBJC_CATEGORY_PROTOCOLS_$_"; - Result += ClassName; Result += "_$_"; Result += CatName; - Result += ",\n"; - } - else - Result += "\t0,\n"; - - if (ClassProperties.size() > 0) { - Result += "\t(const struct _prop_list_t *)&"; Result += "_OBJC_$_PROP_LIST_"; - Result += ClassName; Result += "_$_"; Result += CatName; - Result += ",\n"; - } - else - Result += "\t0,\n"; - - Result += "};\n"; - - // Add static function to initialize the class pointer in the category structure. - Result += "static void OBJC_CATEGORY_SETUP_$_"; - Result += ClassDecl->getNameAsString(); - Result += "_$_"; - Result += CatName; - Result += "(void ) {\n"; - Result += "\t_OBJC_$_CATEGORY_"; - Result += ClassDecl->getNameAsString(); - Result += "_$_"; - Result += CatName; - Result += ".cls = "; Result += "&OBJC_CLASS_$_"; Result += ClassName; - Result += ";\n}\n"; -} - -static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj, - ASTContext *Context, std::string &Result, - ArrayRef Methods, - StringRef VarName, - StringRef ProtocolName) { - if (Methods.size() == 0) - return; - - Result += "\nstatic const char *"; - Result += VarName; Result += ProtocolName; - Result += " [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n"; - Result += "{\n"; - for (unsigned i = 0, e = Methods.size(); i < e; i++) { - ObjCMethodDecl *MD = Methods[i]; - std::string MethodTypeString = - Context->getObjCEncodingForMethodDecl(MD, true); - std::string QuoteMethodTypeString; - RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString); - Result += "\t\""; Result += QuoteMethodTypeString; Result += "\""; - if (i == e-1) - Result += "\n};\n"; - else { - Result += ",\n"; - } - } -} - -static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj, - ASTContext *Context, - std::string &Result, - ArrayRef Ivars, - ObjCInterfaceDecl *CDecl) { - // FIXME. visibility of offset symbols may have to be set; for Darwin - // this is what happens: - /** - if (Ivar->getAccessControl() == ObjCIvarDecl::Private || - Ivar->getAccessControl() == ObjCIvarDecl::Package || - Class->getVisibility() == HiddenVisibility) - Visibility should be: HiddenVisibility; - else - Visibility should be: DefaultVisibility; - */ - - Result += "\n"; - for (unsigned i =0, e = Ivars.size(); i < e; i++) { - ObjCIvarDecl *IvarDecl = Ivars[i]; - if (Context->getLangOpts().MicrosoftExt) - Result += "__declspec(allocate(\".objc_ivar$B\")) "; - - if (!Context->getLangOpts().MicrosoftExt || - IvarDecl->getAccessControl() == ObjCIvarDecl::Private || - IvarDecl->getAccessControl() == ObjCIvarDecl::Package) - Result += "extern \"C\" unsigned long int "; - else - Result += "extern \"C\" __declspec(dllexport) unsigned long int "; - if (Ivars[i]->isBitField()) - RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result); - else - WriteInternalIvarName(CDecl, IvarDecl, Result); - Result += " __attribute__ ((used, section (\"__DATA,__objc_ivar\")))"; - Result += " = "; - RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result); - Result += ";\n"; - if (Ivars[i]->isBitField()) { - // skip over rest of the ivar bitfields. - SKIP_BITFIELDS(i , e, Ivars); - } - } -} - -static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj, - ASTContext *Context, std::string &Result, - ArrayRef OriginalIvars, - StringRef VarName, - ObjCInterfaceDecl *CDecl) { - if (OriginalIvars.size() > 0) { - Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl); - SmallVector Ivars; - // strip off all but the first ivar bitfield from each group of ivars. - // Such ivars in the ivar list table will be replaced by their grouping struct - // 'ivar'. - for (unsigned i = 0, e = OriginalIvars.size(); i < e; i++) { - if (OriginalIvars[i]->isBitField()) { - Ivars.push_back(OriginalIvars[i]); - // skip over rest of the ivar bitfields. - SKIP_BITFIELDS(i , e, OriginalIvars); - } - else - Ivars.push_back(OriginalIvars[i]); - } - - Result += "\nstatic "; - Write__ivar_list_t_TypeDecl(Result, Ivars.size()); - Result += " "; Result += VarName; - Result += CDecl->getNameAsString(); - Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; - Result += "\t"; Result += "sizeof(_ivar_t)"; Result += ",\n"; - Result += "\t"; Result += utostr(Ivars.size()); Result += ",\n"; - for (unsigned i =0, e = Ivars.size(); i < e; i++) { - ObjCIvarDecl *IvarDecl = Ivars[i]; - if (i == 0) - Result += "\t{{"; - else - Result += "\t {"; - Result += "(unsigned long int *)&"; - if (Ivars[i]->isBitField()) - RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result); - else - WriteInternalIvarName(CDecl, IvarDecl, Result); - Result += ", "; - - Result += "\""; - if (Ivars[i]->isBitField()) - RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result); - else - Result += IvarDecl->getName(); - Result += "\", "; - - QualType IVQT = IvarDecl->getType(); - if (IvarDecl->isBitField()) - IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl); - - std::string IvarTypeString, QuoteIvarTypeString; - Context->getObjCEncodingForType(IVQT, IvarTypeString, - IvarDecl); - RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString); - Result += "\""; Result += QuoteIvarTypeString; Result += "\", "; - - // FIXME. this alignment represents the host alignment and need be changed to - // represent the target alignment. - unsigned Align = Context->getTypeAlign(IVQT)/8; - Align = llvm::Log2_32(Align); - Result += llvm::utostr(Align); Result += ", "; - CharUnits Size = Context->getTypeSizeInChars(IVQT); - Result += llvm::utostr(Size.getQuantity()); - if (i == e-1) - Result += "}}\n"; - else - Result += "},\n"; - } - Result += "};\n"; - } -} - -/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data. -void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, - std::string &Result) { - - // Do not synthesize the protocol more than once. - if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl())) - return; - WriteModernMetadataDeclarations(Context, Result); - - if (ObjCProtocolDecl *Def = PDecl->getDefinition()) - PDecl = Def; - // Must write out all protocol definitions in current qualifier list, - // and in their nested qualifiers before writing out current definition. - for (auto *I : PDecl->protocols()) - RewriteObjCProtocolMetaData(I, Result); - - // Construct method lists. - std::vector InstanceMethods, ClassMethods; - std::vector OptInstanceMethods, OptClassMethods; - for (auto *MD : PDecl->instance_methods()) { - if (MD->getImplementationControl() == ObjCImplementationControl::Optional) { - OptInstanceMethods.push_back(MD); - } else { - InstanceMethods.push_back(MD); - } - } - - for (auto *MD : PDecl->class_methods()) { - if (MD->getImplementationControl() == ObjCImplementationControl::Optional) { - OptClassMethods.push_back(MD); - } else { - ClassMethods.push_back(MD); - } - } - std::vector AllMethods; - for (unsigned i = 0, e = InstanceMethods.size(); i < e; i++) - AllMethods.push_back(InstanceMethods[i]); - for (unsigned i = 0, e = ClassMethods.size(); i < e; i++) - AllMethods.push_back(ClassMethods[i]); - for (unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++) - AllMethods.push_back(OptInstanceMethods[i]); - for (unsigned i = 0, e = OptClassMethods.size(); i < e; i++) - AllMethods.push_back(OptClassMethods[i]); - - Write__extendedMethodTypes_initializer(*this, Context, Result, - AllMethods, - "_OBJC_PROTOCOL_METHOD_TYPES_", - PDecl->getNameAsString()); - // Protocol's super protocol list - SmallVector SuperProtocols(PDecl->protocols()); - Write_protocol_list_initializer(Context, Result, SuperProtocols, - "_OBJC_PROTOCOL_REFS_", - PDecl->getNameAsString()); - - Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, - "_OBJC_PROTOCOL_INSTANCE_METHODS_", - PDecl->getNameAsString(), false); - - Write_method_list_t_initializer(*this, Context, Result, ClassMethods, - "_OBJC_PROTOCOL_CLASS_METHODS_", - PDecl->getNameAsString(), false); - - Write_method_list_t_initializer(*this, Context, Result, OptInstanceMethods, - "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_", - PDecl->getNameAsString(), false); - - Write_method_list_t_initializer(*this, Context, Result, OptClassMethods, - "_OBJC_PROTOCOL_OPT_CLASS_METHODS_", - PDecl->getNameAsString(), false); - - // Protocol's property metadata. - SmallVector ProtocolProperties( - PDecl->instance_properties()); - Write_prop_list_t_initializer(*this, Context, Result, ProtocolProperties, - /* Container */nullptr, - "_OBJC_PROTOCOL_PROPERTIES_", - PDecl->getNameAsString()); - - // Writer out root metadata for current protocol: struct _protocol_t - Result += "\n"; - if (LangOpts.MicrosoftExt) - Result += "static "; - Result += "struct _protocol_t _OBJC_PROTOCOL_"; - Result += PDecl->getNameAsString(); - Result += " __attribute__ ((used)) = {\n"; - Result += "\t0,\n"; // id is; is null - Result += "\t\""; Result += PDecl->getNameAsString(); Result += "\",\n"; - if (SuperProtocols.size() > 0) { - Result += "\t(const struct _protocol_list_t *)&"; Result += "_OBJC_PROTOCOL_REFS_"; - Result += PDecl->getNameAsString(); Result += ",\n"; - } - else - Result += "\t0,\n"; - if (InstanceMethods.size() > 0) { - Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; - Result += PDecl->getNameAsString(); Result += ",\n"; - } - else - Result += "\t0,\n"; - - if (ClassMethods.size() > 0) { - Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_"; - Result += PDecl->getNameAsString(); Result += ",\n"; - } - else - Result += "\t0,\n"; - - if (OptInstanceMethods.size() > 0) { - Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_"; - Result += PDecl->getNameAsString(); Result += ",\n"; - } - else - Result += "\t0,\n"; - - if (OptClassMethods.size() > 0) { - Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_"; - Result += PDecl->getNameAsString(); Result += ",\n"; - } - else - Result += "\t0,\n"; - - if (ProtocolProperties.size() > 0) { - Result += "\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_"; - Result += PDecl->getNameAsString(); Result += ",\n"; - } - else - Result += "\t0,\n"; - - Result += "\t"; Result += "sizeof(_protocol_t)"; Result += ",\n"; - Result += "\t0,\n"; - - if (AllMethods.size() > 0) { - Result += "\t(const char **)&"; Result += "_OBJC_PROTOCOL_METHOD_TYPES_"; - Result += PDecl->getNameAsString(); - Result += "\n};\n"; - } - else - Result += "\t0\n};\n"; - - if (LangOpts.MicrosoftExt) - Result += "static "; - Result += "struct _protocol_t *"; - Result += "_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->getNameAsString(); - Result += " = &_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString(); - Result += ";\n"; - - // Mark this protocol as having been generated. - if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()).second) - llvm_unreachable("protocol already synthesized"); -} - -/// hasObjCExceptionAttribute - Return true if this class or any super -/// class has the __objc_exception__ attribute. -/// FIXME. Move this to ASTContext.cpp as it is also used for IRGen. -static bool hasObjCExceptionAttribute(ASTContext &Context, - const ObjCInterfaceDecl *OID) { - if (OID->hasAttr()) - return true; - if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) - return hasObjCExceptionAttribute(Context, Super); - return false; -} - -void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, - std::string &Result) { - ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); - - // Explicitly declared @interface's are already synthesized. - if (CDecl->isImplicitInterfaceDecl()) - assert(false && - "Legacy implicit interface rewriting not supported in moder abi"); - - WriteModernMetadataDeclarations(Context, Result); - SmallVector IVars; - - for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); - IVD; IVD = IVD->getNextIvar()) { - // Ignore unnamed bit-fields. - if (!IVD->getDeclName()) - continue; - IVars.push_back(IVD); - } - - Write__ivar_list_t_initializer(*this, Context, Result, IVars, - "_OBJC_$_INSTANCE_VARIABLES_", - CDecl); - - // Build _objc_method_list for class's instance methods if needed - SmallVector InstanceMethods(IDecl->instance_methods()); - - // If any of our property implementations have associated getters or - // setters, produce metadata for them as well. - for (const auto *Prop : IDecl->property_impls()) { - if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) - continue; - if (!Prop->getPropertyIvarDecl()) - continue; - ObjCPropertyDecl *PD = Prop->getPropertyDecl(); - if (!PD) - continue; - if (ObjCMethodDecl *Getter = Prop->getGetterMethodDecl()) - if (mustSynthesizeSetterGetterMethod(IDecl, PD, true /*getter*/)) - InstanceMethods.push_back(Getter); - if (PD->isReadOnly()) - continue; - if (ObjCMethodDecl *Setter = Prop->getSetterMethodDecl()) - if (mustSynthesizeSetterGetterMethod(IDecl, PD, false /*setter*/)) - InstanceMethods.push_back(Setter); - } - - Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, - "_OBJC_$_INSTANCE_METHODS_", - IDecl->getNameAsString(), true); - - SmallVector ClassMethods(IDecl->class_methods()); - - Write_method_list_t_initializer(*this, Context, Result, ClassMethods, - "_OBJC_$_CLASS_METHODS_", - IDecl->getNameAsString(), true); - - // Protocols referenced in class declaration? - // Protocol's super protocol list - std::vector RefedProtocols; - const ObjCList &Protocols = CDecl->getReferencedProtocols(); - for (ObjCList::iterator I = Protocols.begin(), - E = Protocols.end(); - I != E; ++I) { - RefedProtocols.push_back(*I); - // Must write out all protocol definitions in current qualifier list, - // and in their nested qualifiers before writing out current definition. - RewriteObjCProtocolMetaData(*I, Result); - } - - Write_protocol_list_initializer(Context, Result, - RefedProtocols, - "_OBJC_CLASS_PROTOCOLS_$_", - IDecl->getNameAsString()); - - // Protocol's property metadata. - SmallVector ClassProperties( - CDecl->instance_properties()); - Write_prop_list_t_initializer(*this, Context, Result, ClassProperties, - /* Container */IDecl, - "_OBJC_$_PROP_LIST_", - CDecl->getNameAsString()); - - // Data for initializing _class_ro_t metaclass meta-data - uint32_t flags = CLS_META; - std::string InstanceSize; - std::string InstanceStart; - - bool classIsHidden = CDecl->getVisibility() == HiddenVisibility; - if (classIsHidden) - flags |= OBJC2_CLS_HIDDEN; - - if (!CDecl->getSuperClass()) - // class is root - flags |= CLS_ROOT; - InstanceSize = "sizeof(struct _class_t)"; - InstanceStart = InstanceSize; - Write__class_ro_t_initializer(Context, Result, flags, - InstanceStart, InstanceSize, - ClassMethods, - nullptr, - nullptr, - nullptr, - "_OBJC_METACLASS_RO_$_", - CDecl->getNameAsString()); - - // Data for initializing _class_ro_t meta-data - flags = CLS; - if (classIsHidden) - flags |= OBJC2_CLS_HIDDEN; - - if (hasObjCExceptionAttribute(*Context, CDecl)) - flags |= CLS_EXCEPTION; - - if (!CDecl->getSuperClass()) - // class is root - flags |= CLS_ROOT; - - InstanceSize.clear(); - InstanceStart.clear(); - if (!ObjCSynthesizedStructs.count(CDecl)) { - InstanceSize = "0"; - InstanceStart = "0"; - } - else { - InstanceSize = "sizeof(struct "; - InstanceSize += CDecl->getNameAsString(); - InstanceSize += "_IMPL)"; - - ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); - if (IVD) { - RewriteIvarOffsetComputation(IVD, InstanceStart); - } - else - InstanceStart = InstanceSize; - } - Write__class_ro_t_initializer(Context, Result, flags, - InstanceStart, InstanceSize, - InstanceMethods, - RefedProtocols, - IVars, - ClassProperties, - "_OBJC_CLASS_RO_$_", - CDecl->getNameAsString()); - - Write_class_t(Context, Result, - "OBJC_METACLASS_$_", - CDecl, /*metaclass*/true); - - Write_class_t(Context, Result, - "OBJC_CLASS_$_", - CDecl, /*metaclass*/false); - - if (ImplementationIsNonLazy(IDecl)) - DefinedNonLazyClasses.push_back(CDecl); -} - -void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) { - int ClsDefCount = ClassImplementation.size(); - if (!ClsDefCount) - return; - Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n"; - Result += "__declspec(allocate(\".objc_inithooks$B\")) "; - Result += "static void *OBJC_CLASS_SETUP[] = {\n"; - for (int i = 0; i < ClsDefCount; i++) { - ObjCImplementationDecl *IDecl = ClassImplementation[i]; - ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); - Result += "\t(void *)&OBJC_CLASS_SETUP_$_"; - Result += CDecl->getName(); Result += ",\n"; - } - Result += "};\n"; -} - -void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) { - int ClsDefCount = ClassImplementation.size(); - int CatDefCount = CategoryImplementation.size(); - - // For each implemented class, write out all its meta data. - for (int i = 0; i < ClsDefCount; i++) - RewriteObjCClassMetaData(ClassImplementation[i], Result); - - RewriteClassSetupInitHook(Result); - - // For each implemented category, write out all its meta data. - for (int i = 0; i < CatDefCount; i++) - RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result); - - RewriteCategorySetupInitHook(Result); - - if (ClsDefCount > 0) { - if (LangOpts.MicrosoftExt) - Result += "__declspec(allocate(\".objc_classlist$B\")) "; - Result += "static struct _class_t *L_OBJC_LABEL_CLASS_$ ["; - Result += llvm::utostr(ClsDefCount); Result += "]"; - Result += - " __attribute__((used, section (\"__DATA, __objc_classlist," - "regular,no_dead_strip\")))= {\n"; - for (int i = 0; i < ClsDefCount; i++) { - Result += "\t&OBJC_CLASS_$_"; - Result += ClassImplementation[i]->getNameAsString(); - Result += ",\n"; - } - Result += "};\n"; - - if (!DefinedNonLazyClasses.empty()) { - if (LangOpts.MicrosoftExt) - Result += "__declspec(allocate(\".objc_nlclslist$B\")) \n"; - Result += "static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t"; - for (unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) { - Result += "\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString(); - Result += ",\n"; - } - Result += "};\n"; - } - } - - if (CatDefCount > 0) { - if (LangOpts.MicrosoftExt) - Result += "__declspec(allocate(\".objc_catlist$B\")) "; - Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ ["; - Result += llvm::utostr(CatDefCount); Result += "]"; - Result += - " __attribute__((used, section (\"__DATA, __objc_catlist," - "regular,no_dead_strip\")))= {\n"; - for (int i = 0; i < CatDefCount; i++) { - Result += "\t&_OBJC_$_CATEGORY_"; - Result += - CategoryImplementation[i]->getClassInterface()->getNameAsString(); - Result += "_$_"; - Result += CategoryImplementation[i]->getNameAsString(); - Result += ",\n"; - } - Result += "};\n"; - } - - if (!DefinedNonLazyCategories.empty()) { - if (LangOpts.MicrosoftExt) - Result += "__declspec(allocate(\".objc_nlcatlist$B\")) \n"; - Result += "static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t"; - for (unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) { - Result += "\t&_OBJC_$_CATEGORY_"; - Result += - DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString(); - Result += "_$_"; - Result += DefinedNonLazyCategories[i]->getNameAsString(); - Result += ",\n"; - } - Result += "};\n"; - } -} - -void RewriteModernObjC::WriteImageInfo(std::string &Result) { - if (LangOpts.MicrosoftExt) - Result += "__declspec(allocate(\".objc_imageinfo$B\")) \n"; - - Result += "static struct IMAGE_INFO { unsigned version; unsigned flag; } "; - // version 0, ObjCABI is 2 - Result += "_OBJC_IMAGE_INFO = { 0, 2 };\n"; -} - -/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category -/// implementation. -void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, - std::string &Result) { - WriteModernMetadataDeclarations(Context, Result); - ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); - // Find category declaration for this implementation. - ObjCCategoryDecl *CDecl - = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier()); - - std::string FullCategoryName = ClassDecl->getNameAsString(); - FullCategoryName += "_$_"; - FullCategoryName += CDecl->getNameAsString(); - - // Build _objc_method_list for class's instance methods if needed - SmallVector InstanceMethods(IDecl->instance_methods()); - - // If any of our property implementations have associated getters or - // setters, produce metadata for them as well. - for (const auto *Prop : IDecl->property_impls()) { - if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) - continue; - if (!Prop->getPropertyIvarDecl()) - continue; - ObjCPropertyDecl *PD = Prop->getPropertyDecl(); - if (!PD) - continue; - if (ObjCMethodDecl *Getter = Prop->getGetterMethodDecl()) - InstanceMethods.push_back(Getter); - if (PD->isReadOnly()) - continue; - if (ObjCMethodDecl *Setter = Prop->getSetterMethodDecl()) - InstanceMethods.push_back(Setter); - } - - Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, - "_OBJC_$_CATEGORY_INSTANCE_METHODS_", - FullCategoryName, true); - - SmallVector ClassMethods(IDecl->class_methods()); - - Write_method_list_t_initializer(*this, Context, Result, ClassMethods, - "_OBJC_$_CATEGORY_CLASS_METHODS_", - FullCategoryName, true); - - // Protocols referenced in class declaration? - // Protocol's super protocol list - SmallVector RefedProtocols(CDecl->protocols()); - for (auto *I : CDecl->protocols()) - // Must write out all protocol definitions in current qualifier list, - // and in their nested qualifiers before writing out current definition. - RewriteObjCProtocolMetaData(I, Result); - - Write_protocol_list_initializer(Context, Result, - RefedProtocols, - "_OBJC_CATEGORY_PROTOCOLS_$_", - FullCategoryName); - - // Protocol's property metadata. - SmallVector ClassProperties( - CDecl->instance_properties()); - Write_prop_list_t_initializer(*this, Context, Result, ClassProperties, - /* Container */IDecl, - "_OBJC_$_PROP_LIST_", - FullCategoryName); - - Write_category_t(*this, Context, Result, - CDecl, - ClassDecl, - InstanceMethods, - ClassMethods, - RefedProtocols, - ClassProperties); - - // Determine if this category is also "non-lazy". - if (ImplementationIsNonLazy(IDecl)) - DefinedNonLazyCategories.push_back(CDecl); -} - -void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) { - int CatDefCount = CategoryImplementation.size(); - if (!CatDefCount) - return; - Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n"; - Result += "__declspec(allocate(\".objc_inithooks$B\")) "; - Result += "static void *OBJC_CATEGORY_SETUP[] = {\n"; - for (int i = 0; i < CatDefCount; i++) { - ObjCCategoryImplDecl *IDecl = CategoryImplementation[i]; - ObjCCategoryDecl *CatDecl= IDecl->getCategoryDecl(); - ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); - Result += "\t(void *)&OBJC_CATEGORY_SETUP_$_"; - Result += ClassDecl->getName(); - Result += "_$_"; - Result += CatDecl->getName(); - Result += ",\n"; - } - Result += "};\n"; -} - -// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or -/// class methods. -template -void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin, - MethodIterator MethodEnd, - bool IsInstanceMethod, - StringRef prefix, - StringRef ClassName, - std::string &Result) { - if (MethodBegin == MethodEnd) return; - - if (!objc_impl_method) { - /* struct _objc_method { - SEL _cmd; - char *method_types; - void *_imp; - } - */ - Result += "\nstruct _objc_method {\n"; - Result += "\tSEL _cmd;\n"; - Result += "\tchar *method_types;\n"; - Result += "\tvoid *_imp;\n"; - Result += "};\n"; - - objc_impl_method = true; - } - - // Build _objc_method_list for class's methods if needed - - /* struct { - struct _objc_method_list *next_method; - int method_count; - struct _objc_method method_list[]; - } - */ - unsigned NumMethods = std::distance(MethodBegin, MethodEnd); - Result += "\n"; - if (LangOpts.MicrosoftExt) { - if (IsInstanceMethod) - Result += "__declspec(allocate(\".inst_meth$B\")) "; - else - Result += "__declspec(allocate(\".cls_meth$B\")) "; - } - Result += "static struct {\n"; - Result += "\tstruct _objc_method_list *next_method;\n"; - Result += "\tint method_count;\n"; - Result += "\tstruct _objc_method method_list["; - Result += utostr(NumMethods); - Result += "];\n} _OBJC_"; - Result += prefix; - Result += IsInstanceMethod ? "INSTANCE" : "CLASS"; - Result += "_METHODS_"; - Result += ClassName; - Result += " __attribute__ ((used, section (\"__OBJC, __"; - Result += IsInstanceMethod ? "inst" : "cls"; - Result += "_meth\")))= "; - Result += "{\n\t0, " + utostr(NumMethods) + "\n"; - - Result += "\t,{{(SEL)\""; - Result += (*MethodBegin)->getSelector().getAsString().c_str(); - std::string MethodTypeString; - Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); - Result += "\", \""; - Result += MethodTypeString; - Result += "\", (void *)"; - Result += MethodInternalNames[*MethodBegin]; - Result += "}\n"; - for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) { - Result += "\t ,{(SEL)\""; - Result += (*MethodBegin)->getSelector().getAsString().c_str(); - std::string MethodTypeString; - Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); - Result += "\", \""; - Result += MethodTypeString; - Result += "\", (void *)"; - Result += MethodInternalNames[*MethodBegin]; - Result += "}\n"; - } - Result += "\t }\n};\n"; -} - -Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { - SourceRange OldRange = IV->getSourceRange(); - Expr *BaseExpr = IV->getBase(); - - // Rewrite the base, but without actually doing replaces. - { - DisableReplaceStmtScope S(*this); - BaseExpr = cast(RewriteFunctionBodyOrGlobalInitializer(BaseExpr)); - IV->setBase(BaseExpr); - } - - ObjCIvarDecl *D = IV->getDecl(); - - Expr *Replacement = IV; - - if (BaseExpr->getType()->isObjCObjectPointerType()) { - const ObjCInterfaceType *iFaceDecl = - dyn_cast(BaseExpr->getType()->getPointeeType()); - assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null"); - // lookup which class implements the instance variable. - ObjCInterfaceDecl *clsDeclared = nullptr; - iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), - clsDeclared); - assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); - - // Build name of symbol holding ivar offset. - std::string IvarOffsetName; - if (D->isBitField()) - ObjCIvarBitfieldGroupOffset(D, IvarOffsetName); - else - WriteInternalIvarName(clsDeclared, D, IvarOffsetName); - - ReferencedIvars[clsDeclared].insert(D); - - // cast offset to "char *". - CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(Context->CharTy), - CK_BitCast, - BaseExpr); - VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), - SourceLocation(), &Context->Idents.get(IvarOffsetName), - Context->UnsignedLongTy, nullptr, - SC_Extern); - DeclRefExpr *DRE = new (Context) - DeclRefExpr(*Context, NewVD, false, Context->UnsignedLongTy, - VK_LValue, SourceLocation()); - BinaryOperator *addExpr = BinaryOperator::Create( - *Context, castExpr, DRE, BO_Add, - Context->getPointerType(Context->CharTy), VK_PRValue, OK_Ordinary, - SourceLocation(), FPOptionsOverride()); - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), - SourceLocation(), - addExpr); - QualType IvarT = D->getType(); - if (D->isBitField()) - IvarT = GetGroupRecordTypeForObjCIvarBitfield(D); - - if (!IvarT->getAs() && IvarT->isRecordType()) { - RecordDecl *RD = IvarT->castAs()->getDecl(); - RD = RD->getDefinition(); - if (RD && !RD->getDeclName().getAsIdentifierInfo()) { - // decltype(((Foo_IMPL*)0)->bar) * - auto *CDecl = cast(D->getDeclContext()); - // ivar in class extensions requires special treatment. - if (ObjCCategoryDecl *CatDecl = dyn_cast(CDecl)) - CDecl = CatDecl->getClassInterface(); - std::string RecName = std::string(CDecl->getName()); - RecName += "_IMPL"; - RecordDecl *RD = RecordDecl::Create( - *Context, TagTypeKind::Struct, TUDecl, SourceLocation(), - SourceLocation(), &Context->Idents.get(RecName)); - QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD)); - unsigned UnsignedIntSize = - static_cast(Context->getTypeSize(Context->UnsignedIntTy)); - Expr *Zero = IntegerLiteral::Create(*Context, - llvm::APInt(UnsignedIntSize, 0), - Context->UnsignedIntTy, SourceLocation()); - Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero); - ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), - Zero); - FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), - SourceLocation(), - &Context->Idents.get(D->getNameAsString()), - IvarT, nullptr, - /*BitWidth=*/nullptr, - /*Mutable=*/true, ICIS_NoInit); - MemberExpr *ME = MemberExpr::CreateImplicit( - *Context, PE, true, FD, FD->getType(), VK_LValue, OK_Ordinary); - IvarT = Context->getDecltypeType(ME, ME->getType()); - } - } - convertObjCTypeToCStyleType(IvarT); - QualType castT = Context->getPointerType(IvarT); - - castExpr = NoTypeInfoCStyleCastExpr(Context, - castT, - CK_BitCast, - PE); - - Expr *Exp = UnaryOperator::Create( - const_cast(*Context), castExpr, UO_Deref, IvarT, - VK_LValue, OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); - PE = new (Context) ParenExpr(OldRange.getBegin(), - OldRange.getEnd(), - Exp); - - if (D->isBitField()) { - FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), - SourceLocation(), - &Context->Idents.get(D->getNameAsString()), - D->getType(), nullptr, - /*BitWidth=*/D->getBitWidth(), - /*Mutable=*/true, ICIS_NoInit); - MemberExpr *ME = - MemberExpr::CreateImplicit(*Context, PE, /*isArrow*/ false, FD, - FD->getType(), VK_LValue, OK_Ordinary); - Replacement = ME; - - } - else - Replacement = PE; - } - - ReplaceStmtWithRange(IV, Replacement, OldRange); - return Replacement; -} - -#endif // CLANG_ENABLE_OBJC_REWRITER diff --git a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp deleted file mode 100644 index f49ccf7be68e22..00000000000000 --- a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp +++ /dev/null @@ -1,5866 +0,0 @@ -//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Hacks and fun related to the code rewriter. -// -//===----------------------------------------------------------------------===// - -#include "clang/Rewrite/Frontend/ASTConsumers.h" -#include "clang/AST/AST.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/Attr.h" -#include "clang/AST/ParentMap.h" -#include "clang/Basic/CharInfo.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Config/config.h" -#include "clang/Lex/Lexer.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include - -#if CLANG_ENABLE_OBJC_REWRITER - -using namespace clang; -using llvm::RewriteBuffer; -using llvm::utostr; - -namespace { - class RewriteObjC : public ASTConsumer { - protected: - enum { - BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), - block, ... */ - BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ - BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the - __block variable */ - BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy - helpers */ - BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose - support routines */ - BLOCK_BYREF_CURRENT_MAX = 256 - }; - - enum { - BLOCK_NEEDS_FREE = (1 << 24), - BLOCK_HAS_COPY_DISPOSE = (1 << 25), - BLOCK_HAS_CXX_OBJ = (1 << 26), - BLOCK_IS_GC = (1 << 27), - BLOCK_IS_GLOBAL = (1 << 28), - BLOCK_HAS_DESCRIPTOR = (1 << 29) - }; - static const int OBJC_ABI_VERSION = 7; - - Rewriter Rewrite; - DiagnosticsEngine &Diags; - const LangOptions &LangOpts; - ASTContext *Context; - SourceManager *SM; - TranslationUnitDecl *TUDecl; - FileID MainFileID; - const char *MainFileStart, *MainFileEnd; - Stmt *CurrentBody; - ParentMap *PropParentMap; // created lazily. - std::string InFileName; - std::unique_ptr OutFile; - std::string Preamble; - - TypeDecl *ProtocolTypeDecl; - VarDecl *GlobalVarDecl; - unsigned RewriteFailedDiag; - // ObjC string constant support. - unsigned NumObjCStringLiterals; - VarDecl *ConstantStringClassReference; - RecordDecl *NSStringRecord; - - // ObjC foreach break/continue generation support. - int BcLabelCount; - - unsigned TryFinallyContainsReturnDiag; - // Needed for super. - ObjCMethodDecl *CurMethodDef; - RecordDecl *SuperStructDecl; - RecordDecl *ConstantStringDecl; - - FunctionDecl *MsgSendFunctionDecl; - FunctionDecl *MsgSendSuperFunctionDecl; - FunctionDecl *MsgSendStretFunctionDecl; - FunctionDecl *MsgSendSuperStretFunctionDecl; - FunctionDecl *MsgSendFpretFunctionDecl; - FunctionDecl *GetClassFunctionDecl; - FunctionDecl *GetMetaClassFunctionDecl; - FunctionDecl *GetSuperClassFunctionDecl; - FunctionDecl *SelGetUidFunctionDecl; - FunctionDecl *CFStringFunctionDecl; - FunctionDecl *SuperConstructorFunctionDecl; - FunctionDecl *CurFunctionDef; - FunctionDecl *CurFunctionDeclToDeclareForBlock; - - /* Misc. containers needed for meta-data rewrite. */ - SmallVector ClassImplementation; - SmallVector CategoryImplementation; - llvm::SmallPtrSet ObjCSynthesizedStructs; - llvm::SmallPtrSet ObjCSynthesizedProtocols; - llvm::SmallPtrSet ObjCForwardDecls; - llvm::DenseMap MethodInternalNames; - SmallVector Stmts; - SmallVector ObjCBcLabelNo; - // Remember all the @protocol() expressions. - llvm::SmallPtrSet ProtocolExprDecls; - - llvm::DenseSet CopyDestroyCache; - - // Block expressions. - SmallVector Blocks; - SmallVector InnerDeclRefsCount; - SmallVector InnerDeclRefs; - - SmallVector BlockDeclRefs; - - // Block related declarations. - llvm::SmallSetVector BlockByCopyDecls; - llvm::SmallSetVector BlockByRefDecls; - llvm::DenseMap BlockByRefDeclNo; - llvm::SmallPtrSet ImportedBlockDecls; - llvm::SmallPtrSet ImportedLocalExternalDecls; - - llvm::DenseMap RewrittenBlockExprs; - - // This maps an original source AST to it's rewritten form. This allows - // us to avoid rewriting the same node twice (which is very uncommon). - // This is needed to support some of the exotic property rewriting. - llvm::DenseMap ReplacedNodes; - - // Needed for header files being rewritten - bool IsHeader; - bool SilenceRewriteMacroWarning; - bool objc_impl_method; - - bool DisableReplaceStmt; - class DisableReplaceStmtScope { - RewriteObjC &R; - bool SavedValue; - - public: - DisableReplaceStmtScope(RewriteObjC &R) - : R(R), SavedValue(R.DisableReplaceStmt) { - R.DisableReplaceStmt = true; - } - - ~DisableReplaceStmtScope() { - R.DisableReplaceStmt = SavedValue; - } - }; - - void InitializeCommon(ASTContext &context); - - public: - // Top Level Driver code. - bool HandleTopLevelDecl(DeclGroupRef D) override { - for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { - if (ObjCInterfaceDecl *Class = dyn_cast(*I)) { - if (!Class->isThisDeclarationADefinition()) { - RewriteForwardClassDecl(D); - break; - } - } - - if (ObjCProtocolDecl *Proto = dyn_cast(*I)) { - if (!Proto->isThisDeclarationADefinition()) { - RewriteForwardProtocolDecl(D); - break; - } - } - - HandleTopLevelSingleDecl(*I); - } - return true; - } - - void HandleTopLevelSingleDecl(Decl *D); - void HandleDeclInMainFile(Decl *D); - RewriteObjC(std::string inFile, std::unique_ptr OS, - DiagnosticsEngine &D, const LangOptions &LOpts, - bool silenceMacroWarn); - - ~RewriteObjC() override {} - - void HandleTranslationUnit(ASTContext &C) override; - - void ReplaceStmt(Stmt *Old, Stmt *New) { - ReplaceStmtWithRange(Old, New, Old->getSourceRange()); - } - - void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) { - assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's"); - - Stmt *ReplacingStmt = ReplacedNodes[Old]; - if (ReplacingStmt) - return; // We can't rewrite the same node twice. - - if (DisableReplaceStmt) - return; - - // Measure the old text. - int Size = Rewrite.getRangeSize(SrcRange); - if (Size == -1) { - Diags.Report(Context->getFullLoc(Old->getBeginLoc()), RewriteFailedDiag) - << Old->getSourceRange(); - return; - } - // Get the new text. - std::string Str; - llvm::raw_string_ostream S(Str); - New->printPretty(S, nullptr, PrintingPolicy(LangOpts)); - - // If replacement succeeded or warning disabled return with no warning. - if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) { - ReplacedNodes[Old] = New; - return; - } - if (SilenceRewriteMacroWarning) - return; - Diags.Report(Context->getFullLoc(Old->getBeginLoc()), RewriteFailedDiag) - << Old->getSourceRange(); - } - - void InsertText(SourceLocation Loc, StringRef Str, - bool InsertAfter = true) { - // If insertion succeeded or warning disabled return with no warning. - if (!Rewrite.InsertText(Loc, Str, InsertAfter) || - SilenceRewriteMacroWarning) - return; - - Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag); - } - - void ReplaceText(SourceLocation Start, unsigned OrigLength, - StringRef Str) { - // If removal succeeded or warning disabled return with no warning. - if (!Rewrite.ReplaceText(Start, OrigLength, Str) || - SilenceRewriteMacroWarning) - return; - - Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag); - } - - // Syntactic Rewriting. - void RewriteRecordBody(RecordDecl *RD); - void RewriteInclude(); - void RewriteForwardClassDecl(DeclGroupRef D); - void RewriteForwardClassDecl(const SmallVectorImpl &DG); - void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, - const std::string &typedefString); - void RewriteImplementations(); - void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, - ObjCImplementationDecl *IMD, - ObjCCategoryImplDecl *CID); - void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl); - void RewriteImplementationDecl(Decl *Dcl); - void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, - ObjCMethodDecl *MDecl, std::string &ResultStr); - void RewriteTypeIntoString(QualType T, std::string &ResultStr, - const FunctionType *&FPRetType); - void RewriteByRefString(std::string &ResultStr, const std::string &Name, - ValueDecl *VD, bool def=false); - void RewriteCategoryDecl(ObjCCategoryDecl *Dcl); - void RewriteProtocolDecl(ObjCProtocolDecl *Dcl); - void RewriteForwardProtocolDecl(DeclGroupRef D); - void RewriteForwardProtocolDecl(const SmallVectorImpl &DG); - void RewriteMethodDeclaration(ObjCMethodDecl *Method); - void RewriteProperty(ObjCPropertyDecl *prop); - void RewriteFunctionDecl(FunctionDecl *FD); - void RewriteBlockPointerType(std::string& Str, QualType Type); - void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD); - void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD); - void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl); - void RewriteTypeOfDecl(VarDecl *VD); - void RewriteObjCQualifiedInterfaceTypes(Expr *E); - - // Expression Rewriting. - Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S); - Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp); - Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo); - Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo); - Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp); - Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp); - Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp); - Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp); - void RewriteTryReturnStmts(Stmt *S); - void RewriteSyncReturnStmts(Stmt *S, std::string buf); - Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S); - Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S); - Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S); - Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, - SourceLocation OrigEnd); - Stmt *RewriteBreakStmt(BreakStmt *S); - Stmt *RewriteContinueStmt(ContinueStmt *S); - void RewriteCastExpr(CStyleCastExpr *CE); - - // Block rewriting. - void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D); - - // Block specific rewrite rules. - void RewriteBlockPointerDecl(NamedDecl *VD); - void RewriteByRefVar(VarDecl *VD); - Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD); - Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE); - void RewriteBlockPointerFunctionArgs(FunctionDecl *FD); - - void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, - std::string &Result); - - void Initialize(ASTContext &context) override = 0; - - // Metadata Rewriting. - virtual void RewriteMetaDataIntoBuffer(std::string &Result) = 0; - virtual void RewriteObjCProtocolListMetaData(const ObjCList &Prots, - StringRef prefix, - StringRef ClassName, - std::string &Result) = 0; - virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, - std::string &Result) = 0; - virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, - StringRef prefix, - StringRef ClassName, - std::string &Result) = 0; - virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, - std::string &Result) = 0; - - // Rewriting ivar access - virtual Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) = 0; - virtual void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, - std::string &Result) = 0; - - // Misc. AST transformation routines. Sometimes they end up calling - // rewriting routines on the new ASTs. - CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, - ArrayRef Args, - SourceLocation StartLoc=SourceLocation(), - SourceLocation EndLoc=SourceLocation()); - CallExpr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, - QualType msgSendType, - QualType returnType, - SmallVectorImpl &ArgTypes, - SmallVectorImpl &MsgExprs, - ObjCMethodDecl *Method); - Stmt *SynthMessageExpr(ObjCMessageExpr *Exp, - SourceLocation StartLoc=SourceLocation(), - SourceLocation EndLoc=SourceLocation()); - - void SynthCountByEnumWithState(std::string &buf); - void SynthMsgSendFunctionDecl(); - void SynthMsgSendSuperFunctionDecl(); - void SynthMsgSendStretFunctionDecl(); - void SynthMsgSendFpretFunctionDecl(); - void SynthMsgSendSuperStretFunctionDecl(); - void SynthGetClassFunctionDecl(); - void SynthGetMetaClassFunctionDecl(); - void SynthGetSuperClassFunctionDecl(); - void SynthSelGetUidFunctionDecl(); - void SynthSuperConstructorFunctionDecl(); - - std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag); - std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, - StringRef funcName, std::string Tag); - std::string SynthesizeBlockFunc(BlockExpr *CE, int i, - StringRef funcName, std::string Tag); - std::string SynthesizeBlockImpl(BlockExpr *CE, - std::string Tag, std::string Desc); - std::string SynthesizeBlockDescriptor(std::string DescTag, - std::string ImplTag, - int i, StringRef funcName, - unsigned hasCopy); - Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); - void SynthesizeBlockLiterals(SourceLocation FunLocStart, - StringRef FunName); - FunctionDecl *SynthBlockInitFunctionDecl(StringRef name); - Stmt *SynthBlockInitExpr(BlockExpr *Exp, - const SmallVectorImpl &InnerBlockDeclRefs); - - // Misc. helper routines. - QualType getProtocolType(); - void WarnAboutReturnGotoStmts(Stmt *S); - void HasReturnStmts(Stmt *S, bool &hasReturns); - void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND); - void InsertBlockLiteralsWithinFunction(FunctionDecl *FD); - void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD); - - bool IsDeclStmtInForeachHeader(DeclStmt *DS); - void CollectBlockDeclRefInfo(BlockExpr *Exp); - void GetBlockDeclRefExprs(Stmt *S); - void GetInnerBlockDeclRefExprs(Stmt *S, - SmallVectorImpl &InnerBlockDeclRefs, - llvm::SmallPtrSetImpl &InnerContexts); - - // We avoid calling Type::isBlockPointerType(), since it operates on the - // canonical type. We only care if the top-level type is a closure pointer. - bool isTopLevelBlockPointerType(QualType T) { - return isa(T); - } - - /// convertBlockPointerToFunctionPointer - Converts a block-pointer type - /// to a function pointer type and upon success, returns true; false - /// otherwise. - bool convertBlockPointerToFunctionPointer(QualType &T) { - if (isTopLevelBlockPointerType(T)) { - const auto *BPT = T->castAs(); - T = Context->getPointerType(BPT->getPointeeType()); - return true; - } - return false; - } - - bool needToScanForQualifiers(QualType T); - QualType getSuperStructType(); - QualType getConstantStringStructType(); - QualType convertFunctionTypeOfBlocks(const FunctionType *FT); - bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf); - - void convertToUnqualifiedObjCType(QualType &T) { - if (T->isObjCQualifiedIdType()) - T = Context->getObjCIdType(); - else if (T->isObjCQualifiedClassType()) - T = Context->getObjCClassType(); - else if (T->isObjCObjectPointerType() && - T->getPointeeType()->isObjCQualifiedInterfaceType()) { - if (const ObjCObjectPointerType * OBJPT = - T->getAsObjCInterfacePointerType()) { - const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType(); - T = QualType(IFaceT, 0); - T = Context->getPointerType(T); - } - } - } - - // FIXME: This predicate seems like it would be useful to add to ASTContext. - bool isObjCType(QualType T) { - if (!LangOpts.ObjC) - return false; - - QualType OCT = Context->getCanonicalType(T).getUnqualifiedType(); - - if (OCT == Context->getCanonicalType(Context->getObjCIdType()) || - OCT == Context->getCanonicalType(Context->getObjCClassType())) - return true; - - if (const PointerType *PT = OCT->getAs()) { - if (isa(PT->getPointeeType()) || - PT->getPointeeType()->isObjCQualifiedIdType()) - return true; - } - return false; - } - bool PointerTypeTakesAnyBlockArguments(QualType QT); - bool PointerTypeTakesAnyObjCQualifiedType(QualType QT); - void GetExtentOfArgList(const char *Name, const char *&LParen, - const char *&RParen); - - void QuoteDoublequotes(std::string &From, std::string &To) { - for (unsigned i = 0; i < From.length(); i++) { - if (From[i] == '"') - To += "\\\""; - else - To += From[i]; - } - } - - QualType getSimpleFunctionType(QualType result, - ArrayRef args, - bool variadic = false) { - if (result == Context->getObjCInstanceType()) - result = Context->getObjCIdType(); - FunctionProtoType::ExtProtoInfo fpi; - fpi.Variadic = variadic; - return Context->getFunctionType(result, args, fpi); - } - - // Helper function: create a CStyleCastExpr with trivial type source info. - CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty, - CastKind Kind, Expr *E) { - TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation()); - return CStyleCastExpr::Create(*Ctx, Ty, VK_PRValue, Kind, E, nullptr, - FPOptionsOverride(), TInfo, - SourceLocation(), SourceLocation()); - } - - StringLiteral *getStringLiteral(StringRef Str) { - QualType StrType = Context->getConstantArrayType( - Context->CharTy, llvm::APInt(32, Str.size() + 1), nullptr, - ArraySizeModifier::Normal, 0); - return StringLiteral::Create(*Context, Str, StringLiteralKind::Ordinary, - /*Pascal=*/false, StrType, SourceLocation()); - } - }; - - class RewriteObjCFragileABI : public RewriteObjC { - public: - RewriteObjCFragileABI(std::string inFile, std::unique_ptr OS, - DiagnosticsEngine &D, const LangOptions &LOpts, - bool silenceMacroWarn) - : RewriteObjC(inFile, std::move(OS), D, LOpts, silenceMacroWarn) {} - - ~RewriteObjCFragileABI() override {} - void Initialize(ASTContext &context) override; - - // Rewriting metadata - template - void RewriteObjCMethodsMetaData(MethodIterator MethodBegin, - MethodIterator MethodEnd, - bool IsInstanceMethod, - StringRef prefix, - StringRef ClassName, - std::string &Result); - void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, - StringRef prefix, StringRef ClassName, - std::string &Result) override; - void RewriteObjCProtocolListMetaData( - const ObjCList &Prots, - StringRef prefix, StringRef ClassName, std::string &Result) override; - void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, - std::string &Result) override; - void RewriteMetaDataIntoBuffer(std::string &Result) override; - void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, - std::string &Result) override; - - // Rewriting ivar - void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, - std::string &Result) override; - Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) override; - }; -} // end anonymous namespace - -void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType, - NamedDecl *D) { - if (const FunctionProtoType *fproto - = dyn_cast(funcType.IgnoreParens())) { - for (const auto &I : fproto->param_types()) - if (isTopLevelBlockPointerType(I)) { - // All the args are checked/rewritten. Don't call twice! - RewriteBlockPointerDecl(D); - break; - } - } -} - -void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) { - const PointerType *PT = funcType->getAs(); - if (PT && PointerTypeTakesAnyBlockArguments(funcType)) - RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND); -} - -static bool IsHeaderFile(const std::string &Filename) { - std::string::size_type DotPos = Filename.rfind('.'); - - if (DotPos == std::string::npos) { - // no file extension - return false; - } - - std::string Ext = Filename.substr(DotPos + 1); - // C header: .h - // C++ header: .hh or .H; - return Ext == "h" || Ext == "hh" || Ext == "H"; -} - -RewriteObjC::RewriteObjC(std::string inFile, std::unique_ptr OS, - DiagnosticsEngine &D, const LangOptions &LOpts, - bool silenceMacroWarn) - : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)), - SilenceRewriteMacroWarning(silenceMacroWarn) { - IsHeader = IsHeaderFile(inFile); - RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, - "rewriting sub-expression within a macro (may not be correct)"); - TryFinallyContainsReturnDiag = Diags.getCustomDiagID( - DiagnosticsEngine::Warning, - "rewriter doesn't support user-specified control flow semantics " - "for @try/@finally (code may not execute properly)"); -} - -std::unique_ptr -clang::CreateObjCRewriter(const std::string &InFile, - std::unique_ptr OS, - DiagnosticsEngine &Diags, const LangOptions &LOpts, - bool SilenceRewriteMacroWarning) { - return std::make_unique( - InFile, std::move(OS), Diags, LOpts, SilenceRewriteMacroWarning); -} - -void RewriteObjC::InitializeCommon(ASTContext &context) { - Context = &context; - SM = &Context->getSourceManager(); - TUDecl = Context->getTranslationUnitDecl(); - MsgSendFunctionDecl = nullptr; - MsgSendSuperFunctionDecl = nullptr; - MsgSendStretFunctionDecl = nullptr; - MsgSendSuperStretFunctionDecl = nullptr; - MsgSendFpretFunctionDecl = nullptr; - GetClassFunctionDecl = nullptr; - GetMetaClassFunctionDecl = nullptr; - GetSuperClassFunctionDecl = nullptr; - SelGetUidFunctionDecl = nullptr; - CFStringFunctionDecl = nullptr; - ConstantStringClassReference = nullptr; - NSStringRecord = nullptr; - CurMethodDef = nullptr; - CurFunctionDef = nullptr; - CurFunctionDeclToDeclareForBlock = nullptr; - GlobalVarDecl = nullptr; - SuperStructDecl = nullptr; - ProtocolTypeDecl = nullptr; - ConstantStringDecl = nullptr; - BcLabelCount = 0; - SuperConstructorFunctionDecl = nullptr; - NumObjCStringLiterals = 0; - PropParentMap = nullptr; - CurrentBody = nullptr; - DisableReplaceStmt = false; - objc_impl_method = false; - - // Get the ID and start/end of the main file. - MainFileID = SM->getMainFileID(); - llvm::MemoryBufferRef MainBuf = SM->getBufferOrFake(MainFileID); - MainFileStart = MainBuf.getBufferStart(); - MainFileEnd = MainBuf.getBufferEnd(); - - Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts()); -} - -//===----------------------------------------------------------------------===// -// Top Level Driver Code -//===----------------------------------------------------------------------===// - -void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) { - if (Diags.hasErrorOccurred()) - return; - - // Two cases: either the decl could be in the main file, or it could be in a - // #included file. If the former, rewrite it now. If the later, check to see - // if we rewrote the #include/#import. - SourceLocation Loc = D->getLocation(); - Loc = SM->getExpansionLoc(Loc); - - // If this is for a builtin, ignore it. - if (Loc.isInvalid()) return; - - // Look for built-in declarations that we need to refer during the rewrite. - if (FunctionDecl *FD = dyn_cast(D)) { - RewriteFunctionDecl(FD); - } else if (VarDecl *FVD = dyn_cast(D)) { - // declared in - if (FVD->getName() == "_NSConstantStringClassReference") { - ConstantStringClassReference = FVD; - return; - } - } else if (ObjCInterfaceDecl *ID = dyn_cast(D)) { - if (ID->isThisDeclarationADefinition()) - RewriteInterfaceDecl(ID); - } else if (ObjCCategoryDecl *CD = dyn_cast(D)) { - RewriteCategoryDecl(CD); - } else if (ObjCProtocolDecl *PD = dyn_cast(D)) { - if (PD->isThisDeclarationADefinition()) - RewriteProtocolDecl(PD); - } else if (LinkageSpecDecl *LSD = dyn_cast(D)) { - // Recurse into linkage specifications - for (DeclContext::decl_iterator DI = LSD->decls_begin(), - DIEnd = LSD->decls_end(); - DI != DIEnd; ) { - if (ObjCInterfaceDecl *IFace = dyn_cast((*DI))) { - if (!IFace->isThisDeclarationADefinition()) { - SmallVector DG; - SourceLocation StartLoc = IFace->getBeginLoc(); - do { - if (isa(*DI) && - !cast(*DI)->isThisDeclarationADefinition() && - StartLoc == (*DI)->getBeginLoc()) - DG.push_back(*DI); - else - break; - - ++DI; - } while (DI != DIEnd); - RewriteForwardClassDecl(DG); - continue; - } - } - - if (ObjCProtocolDecl *Proto = dyn_cast((*DI))) { - if (!Proto->isThisDeclarationADefinition()) { - SmallVector DG; - SourceLocation StartLoc = Proto->getBeginLoc(); - do { - if (isa(*DI) && - !cast(*DI)->isThisDeclarationADefinition() && - StartLoc == (*DI)->getBeginLoc()) - DG.push_back(*DI); - else - break; - - ++DI; - } while (DI != DIEnd); - RewriteForwardProtocolDecl(DG); - continue; - } - } - - HandleTopLevelSingleDecl(*DI); - ++DI; - } - } - // If we have a decl in the main file, see if we should rewrite it. - if (SM->isWrittenInMainFile(Loc)) - return HandleDeclInMainFile(D); -} - -//===----------------------------------------------------------------------===// -// Syntactic (non-AST) Rewriting Code -//===----------------------------------------------------------------------===// - -void RewriteObjC::RewriteInclude() { - SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID); - StringRef MainBuf = SM->getBufferData(MainFileID); - const char *MainBufStart = MainBuf.begin(); - const char *MainBufEnd = MainBuf.end(); - size_t ImportLen = strlen("import"); - - // Loop over the whole file, looking for includes. - for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) { - if (*BufPtr == '#') { - if (++BufPtr == MainBufEnd) - return; - while (*BufPtr == ' ' || *BufPtr == '\t') - if (++BufPtr == MainBufEnd) - return; - if (!strncmp(BufPtr, "import", ImportLen)) { - // replace import with include - SourceLocation ImportLoc = - LocStart.getLocWithOffset(BufPtr-MainBufStart); - ReplaceText(ImportLoc, ImportLen, "include"); - BufPtr += ImportLen; - } - } - } -} - -static std::string getIvarAccessString(ObjCIvarDecl *OID) { - const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface(); - std::string S; - S = "((struct "; - S += ClassDecl->getIdentifier()->getName(); - S += "_IMPL *)self)->"; - S += OID->getName(); - return S; -} - -void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, - ObjCImplementationDecl *IMD, - ObjCCategoryImplDecl *CID) { - static bool objcGetPropertyDefined = false; - static bool objcSetPropertyDefined = false; - SourceLocation startLoc = PID->getBeginLoc(); - InsertText(startLoc, "// "); - const char *startBuf = SM->getCharacterData(startLoc); - assert((*startBuf == '@') && "bogus @synthesize location"); - const char *semiBuf = strchr(startBuf, ';'); - assert((*semiBuf == ';') && "@synthesize: can't find ';'"); - SourceLocation onePastSemiLoc = - startLoc.getLocWithOffset(semiBuf-startBuf+1); - - if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) - return; // FIXME: is this correct? - - // Generate the 'getter' function. - ObjCPropertyDecl *PD = PID->getPropertyDecl(); - ObjCIvarDecl *OID = PID->getPropertyIvarDecl(); - - if (!OID) - return; - - unsigned Attributes = PD->getPropertyAttributes(); - if (PID->getGetterMethodDecl() && !PID->getGetterMethodDecl()->isDefined()) { - bool GenGetProperty = - !(Attributes & ObjCPropertyAttribute::kind_nonatomic) && - (Attributes & (ObjCPropertyAttribute::kind_retain | - ObjCPropertyAttribute::kind_copy)); - std::string Getr; - if (GenGetProperty && !objcGetPropertyDefined) { - objcGetPropertyDefined = true; - // FIXME. Is this attribute correct in all cases? - Getr = "\nextern \"C\" __declspec(dllimport) " - "id objc_getProperty(id, SEL, long, bool);\n"; - } - RewriteObjCMethodDecl(OID->getContainingInterface(), - PID->getGetterMethodDecl(), Getr); - Getr += "{ "; - // Synthesize an explicit cast to gain access to the ivar. - // See objc-act.c:objc_synthesize_new_getter() for details. - if (GenGetProperty) { - // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1) - Getr += "typedef "; - const FunctionType *FPRetType = nullptr; - RewriteTypeIntoString(PID->getGetterMethodDecl()->getReturnType(), Getr, - FPRetType); - Getr += " _TYPE"; - if (FPRetType) { - Getr += ")"; // close the precedence "scope" for "*". - - // Now, emit the argument types (if any). - if (const FunctionProtoType *FT = dyn_cast(FPRetType)){ - Getr += "("; - for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { - if (i) Getr += ", "; - std::string ParamStr = - FT->getParamType(i).getAsString(Context->getPrintingPolicy()); - Getr += ParamStr; - } - if (FT->isVariadic()) { - if (FT->getNumParams()) - Getr += ", "; - Getr += "..."; - } - Getr += ")"; - } else - Getr += "()"; - } - Getr += ";\n"; - Getr += "return (_TYPE)"; - Getr += "objc_getProperty(self, _cmd, "; - RewriteIvarOffsetComputation(OID, Getr); - Getr += ", 1)"; - } - else - Getr += "return " + getIvarAccessString(OID); - Getr += "; }"; - InsertText(onePastSemiLoc, Getr); - } - - if (PD->isReadOnly() || !PID->getSetterMethodDecl() || - PID->getSetterMethodDecl()->isDefined()) - return; - - // Generate the 'setter' function. - std::string Setr; - bool GenSetProperty = Attributes & (ObjCPropertyAttribute::kind_retain | - ObjCPropertyAttribute::kind_copy); - if (GenSetProperty && !objcSetPropertyDefined) { - objcSetPropertyDefined = true; - // FIXME. Is this attribute correct in all cases? - Setr = "\nextern \"C\" __declspec(dllimport) " - "void objc_setProperty (id, SEL, long, id, bool, bool);\n"; - } - - RewriteObjCMethodDecl(OID->getContainingInterface(), - PID->getSetterMethodDecl(), Setr); - Setr += "{ "; - // Synthesize an explicit cast to initialize the ivar. - // See objc-act.c:objc_synthesize_new_setter() for details. - if (GenSetProperty) { - Setr += "objc_setProperty (self, _cmd, "; - RewriteIvarOffsetComputation(OID, Setr); - Setr += ", (id)"; - Setr += PD->getName(); - Setr += ", "; - if (Attributes & ObjCPropertyAttribute::kind_nonatomic) - Setr += "0, "; - else - Setr += "1, "; - if (Attributes & ObjCPropertyAttribute::kind_copy) - Setr += "1)"; - else - Setr += "0)"; - } - else { - Setr += getIvarAccessString(OID) + " = "; - Setr += PD->getName(); - } - Setr += "; }"; - 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(ObjCInterfaceDecl *ClassDecl, - const std::string &typedefString) { - SourceLocation startLoc = ClassDecl->getBeginLoc(); - 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) { - std::string typedefString; - for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { - ObjCInterfaceDecl *ForwardDecl = cast(*I); - if (I == D.begin()) { - // 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"; - } - RewriteOneForwardClassDecl(ForwardDecl, typedefString); - } - DeclGroupRef::iterator I = D.begin(); - RewriteForwardClassEpilogue(cast(*I), typedefString); -} - -void RewriteObjC::RewriteForwardClassDecl(const SmallVectorImpl &D) { - std::string typedefString; - for (unsigned i = 0; i < D.size(); i++) { - ObjCInterfaceDecl *ForwardDecl = cast(D[i]); - if (i == 0) { - typedefString += "// @class "; - typedefString += ForwardDecl->getNameAsString(); - typedefString += ";\n"; - } - RewriteOneForwardClassDecl(ForwardDecl, typedefString); - } - RewriteForwardClassEpilogue(cast(D[0]), typedefString); -} - -void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) { - // When method is a synthesized one, such as a getter/setter there is - // nothing to rewrite. - if (Method->isImplicit()) - return; - SourceLocation LocStart = Method->getBeginLoc(); - SourceLocation LocEnd = Method->getEndLoc(); - - if (SM->getExpansionLineNumber(LocEnd) > - SM->getExpansionLineNumber(LocStart)) { - InsertText(LocStart, "#if 0\n"); - ReplaceText(LocEnd, 1, ";\n#endif\n"); - } else { - InsertText(LocStart, "// "); - } -} - -void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) { - SourceLocation Loc = prop->getAtLoc(); - - ReplaceText(Loc, 0, "// "); - // FIXME: handle properties that are declared across multiple lines. -} - -void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) { - SourceLocation LocStart = CatDecl->getBeginLoc(); - - // FIXME: handle category headers that are declared across multiple lines. - ReplaceText(LocStart, 0, "// "); - - for (auto *I : CatDecl->instance_properties()) - RewriteProperty(I); - for (auto *I : CatDecl->instance_methods()) - RewriteMethodDeclaration(I); - for (auto *I : CatDecl->class_methods()) - RewriteMethodDeclaration(I); - - // Lastly, comment out the @end. - ReplaceText(CatDecl->getAtEndRange().getBegin(), - strlen("@end"), "/* @end */"); -} - -void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) { - SourceLocation LocStart = PDecl->getBeginLoc(); - assert(PDecl->isThisDeclarationADefinition()); - - // FIXME: handle protocol headers that are declared across multiple lines. - ReplaceText(LocStart, 0, "// "); - - for (auto *I : PDecl->instance_methods()) - RewriteMethodDeclaration(I); - for (auto *I : PDecl->class_methods()) - RewriteMethodDeclaration(I); - for (auto *I : PDecl->instance_properties()) - RewriteProperty(I); - - // Lastly, comment out the @end. - SourceLocation LocEnd = PDecl->getAtEndRange().getBegin(); - ReplaceText(LocEnd, strlen("@end"), "/* @end */"); - - // Must comment out @optional/@required - const char *startBuf = SM->getCharacterData(LocStart); - const char *endBuf = SM->getCharacterData(LocEnd); - for (const char *p = startBuf; p < endBuf; p++) { - if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) { - SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); - ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */"); - - } - else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) { - SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); - ReplaceText(OptionalLoc, strlen("@required"), "/* @required */"); - - } - } -} - -void RewriteObjC::RewriteForwardProtocolDecl(DeclGroupRef D) { - SourceLocation LocStart = (*D.begin())->getBeginLoc(); - if (LocStart.isInvalid()) - llvm_unreachable("Invalid SourceLocation"); - // FIXME: handle forward protocol that are declared across multiple lines. - ReplaceText(LocStart, 0, "// "); -} - -void -RewriteObjC::RewriteForwardProtocolDecl(const SmallVectorImpl &DG) { - SourceLocation LocStart = DG[0]->getBeginLoc(); - if (LocStart.isInvalid()) - llvm_unreachable("Invalid SourceLocation"); - // FIXME: handle forward protocol that are declared across multiple lines. - ReplaceText(LocStart, 0, "// "); -} - -void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr, - const FunctionType *&FPRetType) { - if (T->isObjCQualifiedIdType()) - ResultStr += "id"; - else if (T->isFunctionPointerType() || - T->isBlockPointerType()) { - // needs special handling, since pointer-to-functions have special - // syntax (where a decaration models use). - QualType retType = T; - QualType PointeeTy; - if (const PointerType* PT = retType->getAs()) - PointeeTy = PT->getPointeeType(); - else if (const BlockPointerType *BPT = retType->getAs()) - PointeeTy = BPT->getPointeeType(); - if ((FPRetType = PointeeTy->getAs())) { - ResultStr += - FPRetType->getReturnType().getAsString(Context->getPrintingPolicy()); - ResultStr += "(*"; - } - } else - ResultStr += T.getAsString(Context->getPrintingPolicy()); -} - -void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, - ObjCMethodDecl *OMD, - std::string &ResultStr) { - //fprintf(stderr,"In RewriteObjCMethodDecl\n"); - const FunctionType *FPRetType = nullptr; - ResultStr += "\nstatic "; - RewriteTypeIntoString(OMD->getReturnType(), ResultStr, FPRetType); - ResultStr += " "; - - // Unique method name - std::string NameStr; - - if (OMD->isInstanceMethod()) - NameStr += "_I_"; - else - NameStr += "_C_"; - - NameStr += IDecl->getNameAsString(); - NameStr += "_"; - - if (ObjCCategoryImplDecl *CID = - dyn_cast(OMD->getDeclContext())) { - NameStr += CID->getNameAsString(); - NameStr += "_"; - } - // Append selector names, replacing ':' with '_' - { - std::string selString = OMD->getSelector().getAsString(); - int len = selString.size(); - for (int i = 0; i < len; i++) - if (selString[i] == ':') - selString[i] = '_'; - NameStr += selString; - } - // Remember this name for metadata emission - MethodInternalNames[OMD] = NameStr; - ResultStr += NameStr; - - // Rewrite arguments - ResultStr += "("; - - // invisible arguments - if (OMD->isInstanceMethod()) { - QualType selfTy = Context->getObjCInterfaceType(IDecl); - selfTy = Context->getPointerType(selfTy); - if (!LangOpts.MicrosoftExt) { - if (ObjCSynthesizedStructs.count(const_cast(IDecl))) - ResultStr += "struct "; - } - // When rewriting for Microsoft, explicitly omit the structure name. - ResultStr += IDecl->getNameAsString(); - ResultStr += " *"; - } - else - ResultStr += Context->getObjCClassType().getAsString( - Context->getPrintingPolicy()); - - ResultStr += " self, "; - ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy()); - ResultStr += " _cmd"; - - // Method arguments. - for (const auto *PDecl : OMD->parameters()) { - ResultStr += ", "; - if (PDecl->getType()->isObjCQualifiedIdType()) { - ResultStr += "id "; - ResultStr += PDecl->getNameAsString(); - } else { - std::string Name = PDecl->getNameAsString(); - QualType QT = PDecl->getType(); - // Make sure we convert "t (^)(...)" to "t (*)(...)". - (void)convertBlockPointerToFunctionPointer(QT); - QT.getAsStringInternal(Name, Context->getPrintingPolicy()); - ResultStr += Name; - } - } - if (OMD->isVariadic()) - ResultStr += ", ..."; - ResultStr += ") "; - - if (FPRetType) { - ResultStr += ")"; // close the precedence "scope" for "*". - - // Now, emit the argument types (if any). - if (const FunctionProtoType *FT = dyn_cast(FPRetType)) { - ResultStr += "("; - for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { - if (i) ResultStr += ", "; - std::string ParamStr = - FT->getParamType(i).getAsString(Context->getPrintingPolicy()); - ResultStr += ParamStr; - } - if (FT->isVariadic()) { - if (FT->getNumParams()) - ResultStr += ", "; - ResultStr += "..."; - } - ResultStr += ")"; - } else { - ResultStr += "()"; - } - } -} - -void RewriteObjC::RewriteImplementationDecl(Decl *OID) { - ObjCImplementationDecl *IMD = dyn_cast(OID); - ObjCCategoryImplDecl *CID = dyn_cast(OID); - assert((IMD || CID) && "Unknown ImplementationDecl"); - - InsertText(IMD ? IMD->getBeginLoc() : CID->getBeginLoc(), "// "); - - for (auto *OMD : IMD ? IMD->instance_methods() : CID->instance_methods()) { - if (!OMD->getBody()) - continue; - std::string ResultStr; - RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); - SourceLocation LocStart = OMD->getBeginLoc(); - SourceLocation LocEnd = OMD->getCompoundBody()->getBeginLoc(); - - const char *startBuf = SM->getCharacterData(LocStart); - const char *endBuf = SM->getCharacterData(LocEnd); - ReplaceText(LocStart, endBuf-startBuf, ResultStr); - } - - for (auto *OMD : IMD ? IMD->class_methods() : CID->class_methods()) { - if (!OMD->getBody()) - continue; - std::string ResultStr; - RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); - SourceLocation LocStart = OMD->getBeginLoc(); - SourceLocation LocEnd = OMD->getCompoundBody()->getBeginLoc(); - - const char *startBuf = SM->getCharacterData(LocStart); - const char *endBuf = SM->getCharacterData(LocEnd); - ReplaceText(LocStart, endBuf-startBuf, ResultStr); - } - for (auto *I : IMD ? IMD->property_impls() : CID->property_impls()) - RewritePropertyImplDecl(I, IMD, CID); - - InsertText(IMD ? IMD->getEndLoc() : CID->getEndLoc(), "// "); -} - -void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { - std::string ResultStr; - if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) { - // we haven't seen a forward decl - generate a typedef. - ResultStr = "#ifndef _REWRITER_typedef_"; - ResultStr += ClassDecl->getNameAsString(); - ResultStr += "\n"; - ResultStr += "#define _REWRITER_typedef_"; - ResultStr += ClassDecl->getNameAsString(); - ResultStr += "\n"; - ResultStr += "typedef struct objc_object "; - ResultStr += ClassDecl->getNameAsString(); - ResultStr += ";\n#endif\n"; - // Mark this typedef as having been generated. - ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl()); - } - RewriteObjCInternalStruct(ClassDecl, ResultStr); - - for (auto *I : ClassDecl->instance_properties()) - RewriteProperty(I); - for (auto *I : ClassDecl->instance_methods()) - RewriteMethodDeclaration(I); - for (auto *I : ClassDecl->class_methods()) - RewriteMethodDeclaration(I); - - // Lastly, comment out the @end. - ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), - "/* @end */"); -} - -Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) { - SourceRange OldRange = PseudoOp->getSourceRange(); - - // We just magically know some things about the structure of this - // expression. - ObjCMessageExpr *OldMsg = - cast(PseudoOp->getSemanticExpr( - PseudoOp->getNumSemanticExprs() - 1)); - - // Because the rewriter doesn't allow us to rewrite rewritten code, - // we need to suppress rewriting the sub-statements. - Expr *Base, *RHS; - { - DisableReplaceStmtScope S(*this); - - // Rebuild the base expression if we have one. - Base = nullptr; - if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { - Base = OldMsg->getInstanceReceiver(); - Base = cast(Base)->getSourceExpr(); - Base = cast(RewriteFunctionBodyOrGlobalInitializer(Base)); - } - - // Rebuild the RHS. - RHS = cast(PseudoOp->getSyntacticForm())->getRHS(); - RHS = cast(RHS)->getSourceExpr(); - RHS = cast(RewriteFunctionBodyOrGlobalInitializer(RHS)); - } - - // TODO: avoid this copy. - SmallVector SelLocs; - OldMsg->getSelectorLocs(SelLocs); - - ObjCMessageExpr *NewMsg = nullptr; - switch (OldMsg->getReceiverKind()) { - case ObjCMessageExpr::Class: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - OldMsg->getClassReceiverTypeInfo(), - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - RHS, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - - case ObjCMessageExpr::Instance: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - Base, - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - RHS, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - - case ObjCMessageExpr::SuperClass: - case ObjCMessageExpr::SuperInstance: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - OldMsg->getSuperLoc(), - OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, - OldMsg->getSuperType(), - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - RHS, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - } - - Stmt *Replacement = SynthMessageExpr(NewMsg); - ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); - return Replacement; -} - -Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) { - SourceRange OldRange = PseudoOp->getSourceRange(); - - // We just magically know some things about the structure of this - // expression. - ObjCMessageExpr *OldMsg = - cast(PseudoOp->getResultExpr()->IgnoreImplicit()); - - // Because the rewriter doesn't allow us to rewrite rewritten code, - // we need to suppress rewriting the sub-statements. - Expr *Base = nullptr; - { - DisableReplaceStmtScope S(*this); - - // Rebuild the base expression if we have one. - if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { - Base = OldMsg->getInstanceReceiver(); - Base = cast(Base)->getSourceExpr(); - Base = cast(RewriteFunctionBodyOrGlobalInitializer(Base)); - } - } - - // Intentionally empty. - SmallVector SelLocs; - SmallVector Args; - - ObjCMessageExpr *NewMsg = nullptr; - switch (OldMsg->getReceiverKind()) { - case ObjCMessageExpr::Class: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - OldMsg->getClassReceiverTypeInfo(), - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - Args, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - - case ObjCMessageExpr::Instance: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - Base, - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - Args, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - - case ObjCMessageExpr::SuperClass: - case ObjCMessageExpr::SuperInstance: - NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), - OldMsg->getValueKind(), - OldMsg->getLeftLoc(), - OldMsg->getSuperLoc(), - OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, - OldMsg->getSuperType(), - OldMsg->getSelector(), - SelLocs, - OldMsg->getMethodDecl(), - Args, - OldMsg->getRightLoc(), - OldMsg->isImplicit()); - break; - } - - Stmt *Replacement = SynthMessageExpr(NewMsg); - ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); - return Replacement; -} - -/// SynthCountByEnumWithState - To print: -/// ((unsigned int (*) -/// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int)) -/// (void *)objc_msgSend)((id)l_collection, -/// sel_registerName( -/// "countByEnumeratingWithState:objects:count:"), -/// &enumState, -/// (id *)__rw_items, (unsigned int)16) -/// -void RewriteObjC::SynthCountByEnumWithState(std::string &buf) { - buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, " - "id *, unsigned int))(void *)objc_msgSend)"; - buf += "\n\t\t"; - buf += "((id)l_collection,\n\t\t"; - buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),"; - buf += "\n\t\t"; - buf += "&enumState, " - "(id *)__rw_items, (unsigned int)16)"; -} - -/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach -/// statement to exit to its outer synthesized loop. -/// -Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) { - if (Stmts.empty() || !isa(Stmts.back())) - return S; - // replace break with goto __break_label - std::string buf; - - SourceLocation startLoc = S->getBeginLoc(); - buf = "goto __break_label_"; - buf += utostr(ObjCBcLabelNo.back()); - ReplaceText(startLoc, strlen("break"), buf); - - return nullptr; -} - -/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach -/// statement to continue with its inner synthesized loop. -/// -Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) { - if (Stmts.empty() || !isa(Stmts.back())) - return S; - // replace continue with goto __continue_label - std::string buf; - - SourceLocation startLoc = S->getBeginLoc(); - buf = "goto __continue_label_"; - buf += utostr(ObjCBcLabelNo.back()); - ReplaceText(startLoc, strlen("continue"), buf); - - return nullptr; -} - -/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement. -/// It rewrites: -/// for ( type elem in collection) { stmts; } - -/// Into: -/// { -/// type elem; -/// struct __objcFastEnumerationState enumState = { 0 }; -/// id __rw_items[16]; -/// id l_collection = (id)collection; -/// unsigned long limit = [l_collection countByEnumeratingWithState:&enumState -/// objects:__rw_items count:16]; -/// if (limit) { -/// unsigned long startMutations = *enumState.mutationsPtr; -/// do { -/// unsigned long counter = 0; -/// do { -/// if (startMutations != *enumState.mutationsPtr) -/// objc_enumerationMutation(l_collection); -/// elem = (type)enumState.itemsPtr[counter++]; -/// stmts; -/// __continue_label: ; -/// } while (counter < limit); -/// } while (limit = [l_collection countByEnumeratingWithState:&enumState -/// objects:__rw_items count:16]); -/// elem = nil; -/// __break_label: ; -/// } -/// else -/// elem = nil; -/// } -/// -Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, - SourceLocation OrigEnd) { - assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty"); - assert(isa(Stmts.back()) && - "ObjCForCollectionStmt Statement stack mismatch"); - assert(!ObjCBcLabelNo.empty() && - "ObjCForCollectionStmt - Label No stack empty"); - - SourceLocation startLoc = S->getBeginLoc(); - const char *startBuf = SM->getCharacterData(startLoc); - StringRef elementName; - std::string elementTypeAsString; - std::string buf; - buf = "\n{\n\t"; - if (DeclStmt *DS = dyn_cast(S->getElement())) { - // type elem; - NamedDecl* D = cast(DS->getSingleDecl()); - QualType ElementType = cast(D)->getType(); - if (ElementType->isObjCQualifiedIdType() || - ElementType->isObjCQualifiedInterfaceType()) - // Simply use 'id' for all qualified types. - elementTypeAsString = "id"; - else - elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy()); - buf += elementTypeAsString; - buf += " "; - elementName = D->getName(); - buf += elementName; - buf += ";\n\t"; - } - else { - DeclRefExpr *DR = cast(S->getElement()); - elementName = DR->getDecl()->getName(); - ValueDecl *VD = DR->getDecl(); - if (VD->getType()->isObjCQualifiedIdType() || - VD->getType()->isObjCQualifiedInterfaceType()) - // Simply use 'id' for all qualified types. - elementTypeAsString = "id"; - else - elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy()); - } - - // struct __objcFastEnumerationState enumState = { 0 }; - buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t"; - // id __rw_items[16]; - buf += "id __rw_items[16];\n\t"; - // id l_collection = (id) - buf += "id l_collection = (id)"; - // Find start location of 'collection' the hard way! - const char *startCollectionBuf = startBuf; - startCollectionBuf += 3; // skip 'for' - startCollectionBuf = strchr(startCollectionBuf, '('); - startCollectionBuf++; // skip '(' - // find 'in' and skip it. - while (*startCollectionBuf != ' ' || - *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' || - (*(startCollectionBuf+3) != ' ' && - *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '(')) - startCollectionBuf++; - startCollectionBuf += 3; - - // Replace: "for (type element in" with string constructed thus far. - ReplaceText(startLoc, startCollectionBuf - startBuf, buf); - // Replace ')' in for '(' type elem in collection ')' with ';' - SourceLocation rightParenLoc = S->getRParenLoc(); - const char *rparenBuf = SM->getCharacterData(rightParenLoc); - SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf); - buf = ";\n\t"; - - // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState - // objects:__rw_items count:16]; - // which is synthesized into: - // unsigned int limit = - // ((unsigned int (*) - // (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int)) - // (void *)objc_msgSend)((id)l_collection, - // sel_registerName( - // "countByEnumeratingWithState:objects:count:"), - // (struct __objcFastEnumerationState *)&state, - // (id *)__rw_items, (unsigned int)16); - buf += "unsigned long limit =\n\t\t"; - SynthCountByEnumWithState(buf); - buf += ";\n\t"; - /// if (limit) { - /// unsigned long startMutations = *enumState.mutationsPtr; - /// do { - /// unsigned long counter = 0; - /// do { - /// if (startMutations != *enumState.mutationsPtr) - /// objc_enumerationMutation(l_collection); - /// elem = (type)enumState.itemsPtr[counter++]; - buf += "if (limit) {\n\t"; - buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t"; - buf += "do {\n\t\t"; - buf += "unsigned long counter = 0;\n\t\t"; - buf += "do {\n\t\t\t"; - buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t"; - buf += "objc_enumerationMutation(l_collection);\n\t\t\t"; - buf += elementName; - buf += " = ("; - buf += elementTypeAsString; - buf += ")enumState.itemsPtr[counter++];"; - // Replace ')' in for '(' type elem in collection ')' with all of these. - ReplaceText(lparenLoc, 1, buf); - - /// __continue_label: ; - /// } while (counter < limit); - /// } while (limit = [l_collection countByEnumeratingWithState:&enumState - /// objects:__rw_items count:16]); - /// elem = nil; - /// __break_label: ; - /// } - /// else - /// elem = nil; - /// } - /// - buf = ";\n\t"; - buf += "__continue_label_"; - buf += utostr(ObjCBcLabelNo.back()); - buf += ": ;"; - buf += "\n\t\t"; - buf += "} while (counter < limit);\n\t"; - buf += "} while (limit = "; - SynthCountByEnumWithState(buf); - buf += ");\n\t"; - buf += elementName; - buf += " = (("; - buf += elementTypeAsString; - buf += ")0);\n\t"; - buf += "__break_label_"; - buf += utostr(ObjCBcLabelNo.back()); - buf += ": ;\n\t"; - buf += "}\n\t"; - buf += "else\n\t\t"; - buf += elementName; - buf += " = (("; - buf += elementTypeAsString; - buf += ")0);\n\t"; - buf += "}\n"; - - // Insert all these *after* the statement body. - // FIXME: If this should support Obj-C++, support CXXTryStmt - if (isa(S->getBody())) { - SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1); - InsertText(endBodyLoc, buf); - } else { - /* Need to treat single statements specially. For example: - * - * for (A *a in b) if (stuff()) break; - * for (A *a in b) xxxyy; - * - * The following code simply scans ahead to the semi to find the actual end. - */ - const char *stmtBuf = SM->getCharacterData(OrigEnd); - const char *semiBuf = strchr(stmtBuf, ';'); - assert(semiBuf && "Can't find ';'"); - SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1); - InsertText(endBodyLoc, buf); - } - Stmts.pop_back(); - ObjCBcLabelNo.pop_back(); - return nullptr; -} - -/// RewriteObjCSynchronizedStmt - -/// This routine rewrites @synchronized(expr) stmt; -/// into: -/// objc_sync_enter(expr); -/// @try stmt @finally { objc_sync_exit(expr); } -/// -Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) { - // Get the start location and compute the semi location. - SourceLocation startLoc = S->getBeginLoc(); - const char *startBuf = SM->getCharacterData(startLoc); - - assert((*startBuf == '@') && "bogus @synchronized location"); - - std::string buf; - buf = "objc_sync_enter((id)"; - const char *lparenBuf = startBuf; - while (*lparenBuf != '(') lparenBuf++; - ReplaceText(startLoc, lparenBuf-startBuf+1, buf); - // We can't use S->getSynchExpr()->getEndLoc() to find the end location, since - // the sync expression is typically a message expression that's already - // been rewritten! (which implies the SourceLocation's are invalid). - SourceLocation endLoc = S->getSynchBody()->getBeginLoc(); - const char *endBuf = SM->getCharacterData(endLoc); - while (*endBuf != ')') endBuf--; - SourceLocation rparenLoc = startLoc.getLocWithOffset(endBuf-startBuf); - buf = ");\n"; - // declare a new scope with two variables, _stack and _rethrow. - buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n"; - buf += "int buf[18/*32-bit i386*/];\n"; - buf += "char *pointers[4];} _stack;\n"; - buf += "id volatile _rethrow = 0;\n"; - buf += "objc_exception_try_enter(&_stack);\n"; - buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n"; - ReplaceText(rparenLoc, 1, buf); - startLoc = S->getSynchBody()->getEndLoc(); - startBuf = SM->getCharacterData(startLoc); - - assert((*startBuf == '}') && "bogus @synchronized block"); - SourceLocation lastCurlyLoc = startLoc; - buf = "}\nelse {\n"; - buf += " _rethrow = objc_exception_extract(&_stack);\n"; - buf += "}\n"; - buf += "{ /* implicit finally clause */\n"; - buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n"; - - std::string syncBuf; - syncBuf += " objc_sync_exit("; - - Expr *syncExpr = S->getSynchExpr(); - CastKind CK = syncExpr->getType()->isObjCObjectPointerType() - ? CK_BitCast : - syncExpr->getType()->isBlockPointerType() - ? CK_BlockPointerToObjCPointerCast - : CK_CPointerToObjCPointerCast; - syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), - CK, syncExpr); - std::string syncExprBufS; - llvm::raw_string_ostream syncExprBuf(syncExprBufS); - assert(syncExpr != nullptr && "Expected non-null Expr"); - syncExpr->printPretty(syncExprBuf, nullptr, PrintingPolicy(LangOpts)); - syncBuf += syncExprBufS; - syncBuf += ");"; - - buf += syncBuf; - buf += "\n if (_rethrow) objc_exception_throw(_rethrow);\n"; - buf += "}\n"; - buf += "}"; - - ReplaceText(lastCurlyLoc, 1, buf); - - bool hasReturns = false; - HasReturnStmts(S->getSynchBody(), hasReturns); - if (hasReturns) - RewriteSyncReturnStmts(S->getSynchBody(), syncBuf); - - return nullptr; -} - -void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S) -{ - // Perform a bottom up traversal of all children. - for (Stmt *SubStmt : S->children()) - if (SubStmt) - WarnAboutReturnGotoStmts(SubStmt); - - if (isa(S) || isa(S)) { - Diags.Report(Context->getFullLoc(S->getBeginLoc()), - TryFinallyContainsReturnDiag); - } -} - -void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) -{ - // Perform a bottom up traversal of all children. - for (Stmt *SubStmt : S->children()) - if (SubStmt) - HasReturnStmts(SubStmt, hasReturns); - - if (isa(S)) - hasReturns = true; -} - -void RewriteObjC::RewriteTryReturnStmts(Stmt *S) { - // Perform a bottom up traversal of all children. - for (Stmt *SubStmt : S->children()) - if (SubStmt) { - RewriteTryReturnStmts(SubStmt); - } - if (isa(S)) { - SourceLocation startLoc = S->getBeginLoc(); - const char *startBuf = SM->getCharacterData(startLoc); - const char *semiBuf = strchr(startBuf, ';'); - assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'"); - SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); - - std::string buf; - buf = "{ objc_exception_try_exit(&_stack); return"; - - ReplaceText(startLoc, 6, buf); - InsertText(onePastSemiLoc, "}"); - } -} - -void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) { - // Perform a bottom up traversal of all children. - for (Stmt *SubStmt : S->children()) - if (SubStmt) { - RewriteSyncReturnStmts(SubStmt, syncExitBuf); - } - if (isa(S)) { - SourceLocation startLoc = S->getBeginLoc(); - const char *startBuf = SM->getCharacterData(startLoc); - - const char *semiBuf = strchr(startBuf, ';'); - assert((*semiBuf == ';') && "RewriteSyncReturnStmts: can't find ';'"); - SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); - - std::string buf; - buf = "{ objc_exception_try_exit(&_stack);"; - buf += syncExitBuf; - buf += " return"; - - ReplaceText(startLoc, 6, buf); - InsertText(onePastSemiLoc, "}"); - } -} - -Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { - // Get the start location and compute the semi location. - SourceLocation startLoc = S->getBeginLoc(); - const char *startBuf = SM->getCharacterData(startLoc); - - assert((*startBuf == '@') && "bogus @try location"); - - std::string buf; - // declare a new scope with two variables, _stack and _rethrow. - buf = "/* @try scope begin */ { struct _objc_exception_data {\n"; - buf += "int buf[18/*32-bit i386*/];\n"; - buf += "char *pointers[4];} _stack;\n"; - buf += "id volatile _rethrow = 0;\n"; - buf += "objc_exception_try_enter(&_stack);\n"; - buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n"; - - ReplaceText(startLoc, 4, buf); - - startLoc = S->getTryBody()->getEndLoc(); - startBuf = SM->getCharacterData(startLoc); - - assert((*startBuf == '}') && "bogus @try block"); - - SourceLocation lastCurlyLoc = startLoc; - if (S->getNumCatchStmts()) { - startLoc = startLoc.getLocWithOffset(1); - buf = " /* @catch begin */ else {\n"; - buf += " id _caught = objc_exception_extract(&_stack);\n"; - buf += " objc_exception_try_enter (&_stack);\n"; - buf += " if (_setjmp(_stack.buf))\n"; - buf += " _rethrow = objc_exception_extract(&_stack);\n"; - buf += " else { /* @catch continue */"; - - InsertText(startLoc, buf); - } else { /* no catch list */ - buf = "}\nelse {\n"; - buf += " _rethrow = objc_exception_extract(&_stack);\n"; - buf += "}"; - ReplaceText(lastCurlyLoc, 1, buf); - } - Stmt *lastCatchBody = nullptr; - for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { - ObjCAtCatchStmt *Catch = S->getCatchStmt(I); - VarDecl *catchDecl = Catch->getCatchParamDecl(); - - if (I == 0) - buf = "if ("; // we are generating code for the first catch clause - else - buf = "else if ("; - startLoc = Catch->getBeginLoc(); - startBuf = SM->getCharacterData(startLoc); - - assert((*startBuf == '@') && "bogus @catch location"); - - const char *lParenLoc = strchr(startBuf, '('); - - if (Catch->hasEllipsis()) { - // Now rewrite the body... - lastCatchBody = Catch->getCatchBody(); - SourceLocation bodyLoc = lastCatchBody->getBeginLoc(); - const char *bodyBuf = SM->getCharacterData(bodyLoc); - assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' && - "bogus @catch paren location"); - assert((*bodyBuf == '{') && "bogus @catch body location"); - - buf += "1) { id _tmp = _caught;"; - Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf); - } else if (catchDecl) { - QualType t = catchDecl->getType(); - if (t == Context->getObjCIdType()) { - buf += "1) { "; - ReplaceText(startLoc, lParenLoc-startBuf+1, buf); - } else if (const ObjCObjectPointerType *Ptr = - t->getAs()) { - // Should be a pointer to a class. - ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface(); - if (IDecl) { - buf += "objc_exception_match((struct objc_class *)objc_getClass(\""; - buf += IDecl->getNameAsString(); - buf += "\"), (struct objc_object *)_caught)) { "; - ReplaceText(startLoc, lParenLoc-startBuf+1, buf); - } - } - // Now rewrite the body... - lastCatchBody = Catch->getCatchBody(); - SourceLocation rParenLoc = Catch->getRParenLoc(); - SourceLocation bodyLoc = lastCatchBody->getBeginLoc(); - const char *bodyBuf = SM->getCharacterData(bodyLoc); - const char *rParenBuf = SM->getCharacterData(rParenLoc); - assert((*rParenBuf == ')') && "bogus @catch paren location"); - assert((*bodyBuf == '{') && "bogus @catch body location"); - - // Here we replace ") {" with "= _caught;" (which initializes and - // declares the @catch parameter). - ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;"); - } else { - llvm_unreachable("@catch rewrite bug"); - } - } - // Complete the catch list... - if (lastCatchBody) { - SourceLocation bodyLoc = lastCatchBody->getEndLoc(); - assert(*SM->getCharacterData(bodyLoc) == '}' && - "bogus @catch body location"); - - // Insert the last (implicit) else clause *before* the right curly brace. - bodyLoc = bodyLoc.getLocWithOffset(-1); - buf = "} /* last catch end */\n"; - buf += "else {\n"; - buf += " _rethrow = _caught;\n"; - buf += " objc_exception_try_exit(&_stack);\n"; - buf += "} } /* @catch end */\n"; - if (!S->getFinallyStmt()) - buf += "}\n"; - InsertText(bodyLoc, buf); - - // Set lastCurlyLoc - lastCurlyLoc = lastCatchBody->getEndLoc(); - } - if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) { - startLoc = finalStmt->getBeginLoc(); - startBuf = SM->getCharacterData(startLoc); - assert((*startBuf == '@') && "bogus @finally start"); - - ReplaceText(startLoc, 8, "/* @finally */"); - - Stmt *body = finalStmt->getFinallyBody(); - SourceLocation startLoc = body->getBeginLoc(); - SourceLocation endLoc = body->getEndLoc(); - assert(*SM->getCharacterData(startLoc) == '{' && - "bogus @finally body location"); - assert(*SM->getCharacterData(endLoc) == '}' && - "bogus @finally body location"); - - startLoc = startLoc.getLocWithOffset(1); - InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n"); - endLoc = endLoc.getLocWithOffset(-1); - InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n"); - - // Set lastCurlyLoc - lastCurlyLoc = body->getEndLoc(); - - // Now check for any return/continue/go statements within the @try. - WarnAboutReturnGotoStmts(S->getTryBody()); - } else { /* no finally clause - make sure we synthesize an implicit one */ - buf = "{ /* implicit finally clause */\n"; - buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n"; - buf += " if (_rethrow) objc_exception_throw(_rethrow);\n"; - buf += "}"; - ReplaceText(lastCurlyLoc, 1, buf); - - // Now check for any return/continue/go statements within the @try. - // The implicit finally clause won't called if the @try contains any - // jump statements. - bool hasReturns = false; - HasReturnStmts(S->getTryBody(), hasReturns); - if (hasReturns) - RewriteTryReturnStmts(S->getTryBody()); - } - // Now emit the final closing curly brace... - lastCurlyLoc = lastCurlyLoc.getLocWithOffset(1); - InsertText(lastCurlyLoc, " } /* @try scope end */\n"); - return nullptr; -} - -// This can't be done with ReplaceStmt(S, ThrowExpr), since -// the throw expression is typically a message expression that's already -// been rewritten! (which implies the SourceLocation's are invalid). -Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) { - // Get the start location and compute the semi location. - SourceLocation startLoc = S->getBeginLoc(); - const char *startBuf = SM->getCharacterData(startLoc); - - assert((*startBuf == '@') && "bogus @throw location"); - - std::string buf; - /* void objc_exception_throw(id) __attribute__((noreturn)); */ - if (S->getThrowExpr()) - buf = "objc_exception_throw("; - else // add an implicit argument - buf = "objc_exception_throw(_caught"; - - // handle "@ throw" correctly. - const char *wBuf = strchr(startBuf, 'w'); - assert((*wBuf == 'w') && "@throw: can't find 'w'"); - ReplaceText(startLoc, wBuf-startBuf+1, buf); - - const char *semiBuf = strchr(startBuf, ';'); - assert((*semiBuf == ';') && "@throw: can't find ';'"); - SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf); - ReplaceText(semiLoc, 1, ");"); - return nullptr; -} - -Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) { - // Create a new string expression. - std::string StrEncoding; - Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding); - Expr *Replacement = getStringLiteral(StrEncoding); - ReplaceStmt(Exp, Replacement); - - // Replace this subexpr in the parent. - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return Replacement; -} - -Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) { - if (!SelGetUidFunctionDecl) - SynthSelGetUidFunctionDecl(); - assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl"); - // Create a call to sel_registerName("selName"). - SmallVector SelExprs; - SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString())); - CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, - SelExprs); - ReplaceStmt(Exp, SelExp); - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return SelExp; -} - -CallExpr * -RewriteObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD, - ArrayRef Args, - SourceLocation StartLoc, - SourceLocation EndLoc) { - // Get the type, we will need to reference it in a couple spots. - QualType msgSendType = FD->getType(); - - // Create a reference to the objc_msgSend() declaration. - DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, FD, false, msgSendType, - VK_LValue, SourceLocation()); - - // Now, we cast the reference to a pointer to the objc_msgSend type. - QualType pToFunc = Context->getPointerType(msgSendType); - ImplicitCastExpr *ICE = - ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay, - DRE, nullptr, VK_PRValue, FPOptionsOverride()); - - const auto *FT = msgSendType->castAs(); - - CallExpr *Exp = - CallExpr::Create(*Context, ICE, Args, FT->getCallResultType(*Context), - VK_PRValue, EndLoc, FPOptionsOverride()); - return Exp; -} - -static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, - const char *&startRef, const char *&endRef) { - while (startBuf < endBuf) { - if (*startBuf == '<') - startRef = startBuf; // mark the start. - if (*startBuf == '>') { - if (startRef && *startRef == '<') { - endRef = startBuf; // mark the end. - return true; - } - return false; - } - startBuf++; - } - return false; -} - -static void scanToNextArgument(const char *&argRef) { - int angle = 0; - while (*argRef != ')' && (*argRef != ',' || angle > 0)) { - if (*argRef == '<') - angle++; - else if (*argRef == '>') - angle--; - argRef++; - } - assert(angle == 0 && "scanToNextArgument - bad protocol type syntax"); -} - -bool RewriteObjC::needToScanForQualifiers(QualType T) { - if (T->isObjCQualifiedIdType()) - return true; - if (const PointerType *PT = T->getAs()) { - if (PT->getPointeeType()->isObjCQualifiedIdType()) - return true; - } - if (T->isObjCObjectPointerType()) { - T = T->getPointeeType(); - return T->isObjCQualifiedInterfaceType(); - } - if (T->isArrayType()) { - QualType ElemTy = Context->getBaseElementType(T); - return needToScanForQualifiers(ElemTy); - } - return false; -} - -void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) { - QualType Type = E->getType(); - if (needToScanForQualifiers(Type)) { - SourceLocation Loc, EndLoc; - - if (const CStyleCastExpr *ECE = dyn_cast(E)) { - Loc = ECE->getLParenLoc(); - EndLoc = ECE->getRParenLoc(); - } else { - Loc = E->getBeginLoc(); - EndLoc = E->getEndLoc(); - } - // This will defend against trying to rewrite synthesized expressions. - if (Loc.isInvalid() || EndLoc.isInvalid()) - return; - - const char *startBuf = SM->getCharacterData(Loc); - const char *endBuf = SM->getCharacterData(EndLoc); - const char *startRef = nullptr, *endRef = nullptr; - if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { - // Get the locations of the startRef, endRef. - SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf); - SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1); - // Comment out the protocol references. - InsertText(LessLoc, "/*"); - InsertText(GreaterLoc, "*/"); - } - } -} - -void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) { - SourceLocation Loc; - QualType Type; - const FunctionProtoType *proto = nullptr; - if (VarDecl *VD = dyn_cast(Dcl)) { - Loc = VD->getLocation(); - Type = VD->getType(); - } - else if (FunctionDecl *FD = dyn_cast(Dcl)) { - Loc = FD->getLocation(); - // Check for ObjC 'id' and class types that have been adorned with protocol - // information (id

, C

*). The protocol references need to be rewritten! - const FunctionType *funcType = FD->getType()->getAs(); - assert(funcType && "missing function type"); - proto = dyn_cast(funcType); - if (!proto) - return; - Type = proto->getReturnType(); - } - else if (FieldDecl *FD = dyn_cast(Dcl)) { - Loc = FD->getLocation(); - Type = FD->getType(); - } - else - return; - - if (needToScanForQualifiers(Type)) { - // Since types are unique, we need to scan the buffer. - - const char *endBuf = SM->getCharacterData(Loc); - const char *startBuf = endBuf; - while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart) - startBuf--; // scan backward (from the decl location) for return type. - const char *startRef = nullptr, *endRef = nullptr; - if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { - // Get the locations of the startRef, endRef. - SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf); - SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1); - // Comment out the protocol references. - InsertText(LessLoc, "/*"); - InsertText(GreaterLoc, "*/"); - } - } - if (!proto) - return; // most likely, was a variable - // Now check arguments. - const char *startBuf = SM->getCharacterData(Loc); - const char *startFuncBuf = startBuf; - for (unsigned i = 0; i < proto->getNumParams(); i++) { - if (needToScanForQualifiers(proto->getParamType(i))) { - // Since types are unique, we need to scan the buffer. - - const char *endBuf = startBuf; - // scan forward (from the decl location) for argument types. - scanToNextArgument(endBuf); - const char *startRef = nullptr, *endRef = nullptr; - if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { - // Get the locations of the startRef, endRef. - SourceLocation LessLoc = - Loc.getLocWithOffset(startRef-startFuncBuf); - SourceLocation GreaterLoc = - Loc.getLocWithOffset(endRef-startFuncBuf+1); - // Comment out the protocol references. - InsertText(LessLoc, "/*"); - InsertText(GreaterLoc, "*/"); - } - startBuf = ++endBuf; - } - else { - // If the function name is derived from a macro expansion, then the - // argument buffer will not follow the name. Need to speak with Chris. - while (*startBuf && *startBuf != ')' && *startBuf != ',') - startBuf++; // scan forward (from the decl location) for argument types. - startBuf++; - } - } -} - -void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) { - QualType QT = ND->getType(); - const Type* TypePtr = QT->getAs(); - if (!isa(TypePtr)) - return; - while (isa(TypePtr)) { - const TypeOfExprType *TypeOfExprTypePtr = cast(TypePtr); - QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); - TypePtr = QT->getAs(); - } - // FIXME. This will not work for multiple declarators; as in: - // __typeof__(a) b,c,d; - std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy())); - SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); - const char *startBuf = SM->getCharacterData(DeclLoc); - if (ND->getInit()) { - std::string Name(ND->getNameAsString()); - TypeAsString += " " + Name + " = "; - Expr *E = ND->getInit(); - SourceLocation startLoc; - if (const CStyleCastExpr *ECE = dyn_cast(E)) - startLoc = ECE->getLParenLoc(); - else - startLoc = E->getBeginLoc(); - startLoc = SM->getExpansionLoc(startLoc); - const char *endBuf = SM->getCharacterData(startLoc); - ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); - } - else { - SourceLocation X = ND->getEndLoc(); - X = SM->getExpansionLoc(X); - const char *endBuf = SM->getCharacterData(X); - ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); - } -} - -// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str); -void RewriteObjC::SynthSelGetUidFunctionDecl() { - IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName"); - SmallVector ArgTys; - ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); - QualType getFuncType = - getSimpleFunctionType(Context->getObjCSelType(), ArgTys); - SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - SelGetUidIdent, getFuncType, - nullptr, SC_Extern); -} - -void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) { - // declared in - if (FD->getIdentifier() && - FD->getName() == "sel_registerName") { - SelGetUidFunctionDecl = FD; - return; - } - RewriteObjCQualifiedInterfaceTypes(FD); -} - -void RewriteObjC::RewriteBlockPointerType(std::string& Str, QualType Type) { - std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); - const char *argPtr = TypeString.c_str(); - if (!strchr(argPtr, '^')) { - Str += TypeString; - return; - } - while (*argPtr) { - Str += (*argPtr == '^' ? '*' : *argPtr); - argPtr++; - } -} - -// FIXME. Consolidate this routine with RewriteBlockPointerType. -void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str, - ValueDecl *VD) { - QualType Type = VD->getType(); - std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); - const char *argPtr = TypeString.c_str(); - int paren = 0; - while (*argPtr) { - switch (*argPtr) { - case '(': - Str += *argPtr; - paren++; - break; - case ')': - Str += *argPtr; - paren--; - break; - case '^': - Str += '*'; - if (paren == 1) - Str += VD->getNameAsString(); - break; - default: - Str += *argPtr; - break; - } - argPtr++; - } -} - -void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { - SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); - const FunctionType *funcType = FD->getType()->getAs(); - const FunctionProtoType *proto = dyn_cast_or_null(funcType); - if (!proto) - return; - QualType Type = proto->getReturnType(); - std::string FdStr = Type.getAsString(Context->getPrintingPolicy()); - FdStr += " "; - FdStr += FD->getName(); - FdStr += "("; - unsigned numArgs = proto->getNumParams(); - for (unsigned i = 0; i < numArgs; i++) { - QualType ArgType = proto->getParamType(i); - RewriteBlockPointerType(FdStr, ArgType); - if (i+1 < numArgs) - FdStr += ", "; - } - FdStr += ");\n"; - InsertText(FunLocStart, FdStr); - CurFunctionDeclToDeclareForBlock = nullptr; -} - -// SynthSuperConstructorFunctionDecl - id objc_super(id obj, id super); -void RewriteObjC::SynthSuperConstructorFunctionDecl() { - if (SuperConstructorFunctionDecl) - return; - IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super"); - SmallVector ArgTys; - QualType argT = Context->getObjCIdType(); - assert(!argT.isNull() && "Can't find 'id' type"); - ArgTys.push_back(argT); - ArgTys.push_back(argT); - QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys); - SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, msgSendType, - nullptr, SC_Extern); -} - -// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); -void RewriteObjC::SynthMsgSendFunctionDecl() { - IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend"); - SmallVector ArgTys; - QualType argT = Context->getObjCIdType(); - assert(!argT.isNull() && "Can't find 'id' type"); - ArgTys.push_back(argT); - argT = Context->getObjCSelType(); - assert(!argT.isNull() && "Can't find 'SEL' type"); - ArgTys.push_back(argT); - QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys, /*variadic=*/true); - MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, msgSendType, - nullptr, SC_Extern); -} - -// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...); -void RewriteObjC::SynthMsgSendSuperFunctionDecl() { - IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); - SmallVector ArgTys; - RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl, - SourceLocation(), SourceLocation(), - &Context->Idents.get("objc_super")); - QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); - assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); - ArgTys.push_back(argT); - argT = Context->getObjCSelType(); - assert(!argT.isNull() && "Can't find 'SEL' type"); - ArgTys.push_back(argT); - QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys, /*variadic=*/true); - MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, msgSendType, - nullptr, SC_Extern); -} - -// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...); -void RewriteObjC::SynthMsgSendStretFunctionDecl() { - IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret"); - SmallVector ArgTys; - QualType argT = Context->getObjCIdType(); - assert(!argT.isNull() && "Can't find 'id' type"); - ArgTys.push_back(argT); - argT = Context->getObjCSelType(); - assert(!argT.isNull() && "Can't find 'SEL' type"); - ArgTys.push_back(argT); - QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys, /*variadic=*/true); - MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, msgSendType, - nullptr, SC_Extern); -} - -// SynthMsgSendSuperStretFunctionDecl - -// id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...); -void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { - IdentifierInfo *msgSendIdent = - &Context->Idents.get("objc_msgSendSuper_stret"); - SmallVector ArgTys; - RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl, - SourceLocation(), SourceLocation(), - &Context->Idents.get("objc_super")); - QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); - assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); - ArgTys.push_back(argT); - argT = Context->getObjCSelType(); - assert(!argT.isNull() && "Can't find 'SEL' type"); - ArgTys.push_back(argT); - QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys, /*variadic=*/true); - MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, - msgSendType, nullptr, - SC_Extern); -} - -// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...); -void RewriteObjC::SynthMsgSendFpretFunctionDecl() { - IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret"); - SmallVector ArgTys; - QualType argT = Context->getObjCIdType(); - assert(!argT.isNull() && "Can't find 'id' type"); - ArgTys.push_back(argT); - argT = Context->getObjCSelType(); - assert(!argT.isNull() && "Can't find 'SEL' type"); - ArgTys.push_back(argT); - QualType msgSendType = getSimpleFunctionType(Context->DoubleTy, - ArgTys, /*variadic=*/true); - MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - msgSendIdent, msgSendType, - nullptr, SC_Extern); -} - -// SynthGetClassFunctionDecl - id objc_getClass(const char *name); -void RewriteObjC::SynthGetClassFunctionDecl() { - IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass"); - SmallVector ArgTys; - ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); - QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys); - GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - getClassIdent, getClassType, - nullptr, SC_Extern); -} - -// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls); -void RewriteObjC::SynthGetSuperClassFunctionDecl() { - IdentifierInfo *getSuperClassIdent = - &Context->Idents.get("class_getSuperclass"); - SmallVector ArgTys; - ArgTys.push_back(Context->getObjCClassType()); - QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), - ArgTys); - GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - getSuperClassIdent, - getClassType, nullptr, - SC_Extern); -} - -// SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name); -void RewriteObjC::SynthGetMetaClassFunctionDecl() { - IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass"); - SmallVector ArgTys; - ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); - QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(), - ArgTys); - GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, - SourceLocation(), - SourceLocation(), - getClassIdent, getClassType, - nullptr, SC_Extern); -} - -Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { - assert(Exp != nullptr && "Expected non-null ObjCStringLiteral"); - QualType strType = getConstantStringStructType(); - - std::string S = "__NSConstantStringImpl_"; - - std::string tmpName = InFileName; - unsigned i; - for (i=0; i < tmpName.length(); i++) { - char c = tmpName.at(i); - // replace any non-alphanumeric characters with '_'. - if (!isAlphanumeric(c)) - tmpName[i] = '_'; - } - S += tmpName; - S += "_"; - S += utostr(NumObjCStringLiterals++); - - Preamble += "static __NSConstantStringImpl " + S; - Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,"; - Preamble += "0x000007c8,"; // utf8_str - // The pretty printer for StringLiteral handles escape characters properly. - std::string prettyBufS; - llvm::raw_string_ostream prettyBuf(prettyBufS); - Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts)); - Preamble += prettyBufS; - Preamble += ","; - Preamble += utostr(Exp->getString()->getByteLength()) + "};\n"; - - VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), - SourceLocation(), &Context->Idents.get(S), - strType, nullptr, SC_Static); - DeclRefExpr *DRE = new (Context) - DeclRefExpr(*Context, NewVD, false, strType, VK_LValue, SourceLocation()); - Expr *Unop = UnaryOperator::Create( - const_cast(*Context), DRE, UO_AddrOf, - Context->getPointerType(DRE->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - // cast to NSConstantString * - CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), - CK_CPointerToObjCPointerCast, Unop); - ReplaceStmt(Exp, cast); - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return cast; -} - -// struct objc_super { struct objc_object *receiver; struct objc_class *super; }; -QualType RewriteObjC::getSuperStructType() { - if (!SuperStructDecl) { - SuperStructDecl = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl, - SourceLocation(), SourceLocation(), - &Context->Idents.get("objc_super")); - QualType FieldTypes[2]; - - // struct objc_object *receiver; - FieldTypes[0] = Context->getObjCIdType(); - // struct objc_class *super; - FieldTypes[1] = Context->getObjCClassType(); - - // Create fields - for (unsigned i = 0; i < 2; ++i) { - SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl, - SourceLocation(), - SourceLocation(), nullptr, - FieldTypes[i], nullptr, - /*BitWidth=*/nullptr, - /*Mutable=*/false, - ICIS_NoInit)); - } - - SuperStructDecl->completeDefinition(); - } - return Context->getTagDeclType(SuperStructDecl); -} - -QualType RewriteObjC::getConstantStringStructType() { - if (!ConstantStringDecl) { - ConstantStringDecl = RecordDecl::Create( - *Context, TagTypeKind::Struct, TUDecl, SourceLocation(), - SourceLocation(), &Context->Idents.get("__NSConstantStringImpl")); - QualType FieldTypes[4]; - - // struct objc_object *receiver; - FieldTypes[0] = Context->getObjCIdType(); - // int flags; - FieldTypes[1] = Context->IntTy; - // char *str; - FieldTypes[2] = Context->getPointerType(Context->CharTy); - // long length; - FieldTypes[3] = Context->LongTy; - - // Create fields - for (unsigned i = 0; i < 4; ++i) { - ConstantStringDecl->addDecl(FieldDecl::Create(*Context, - ConstantStringDecl, - SourceLocation(), - SourceLocation(), nullptr, - FieldTypes[i], nullptr, - /*BitWidth=*/nullptr, - /*Mutable=*/true, - ICIS_NoInit)); - } - - ConstantStringDecl->completeDefinition(); - } - return Context->getTagDeclType(ConstantStringDecl); -} - -CallExpr *RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, - QualType msgSendType, - QualType returnType, - SmallVectorImpl &ArgTypes, - SmallVectorImpl &MsgExprs, - ObjCMethodDecl *Method) { - // Create a reference to the objc_msgSend_stret() declaration. - DeclRefExpr *STDRE = - new (Context) DeclRefExpr(*Context, MsgSendStretFlavor, false, - msgSendType, VK_LValue, SourceLocation()); - // Need to cast objc_msgSend_stret to "void *" (see above comment). - CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(Context->VoidTy), - CK_BitCast, STDRE); - // Now do the "normal" pointer to function cast. - QualType castType = getSimpleFunctionType(returnType, ArgTypes, - Method ? Method->isVariadic() - : false); - castType = Context->getPointerType(castType); - cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, - cast); - - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast); - - const auto *FT = msgSendType->castAs(); - CallExpr *STCE = - CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(), VK_PRValue, - SourceLocation(), FPOptionsOverride()); - return STCE; -} - -Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, - SourceLocation StartLoc, - SourceLocation EndLoc) { - if (!SelGetUidFunctionDecl) - SynthSelGetUidFunctionDecl(); - if (!MsgSendFunctionDecl) - SynthMsgSendFunctionDecl(); - if (!MsgSendSuperFunctionDecl) - SynthMsgSendSuperFunctionDecl(); - if (!MsgSendStretFunctionDecl) - SynthMsgSendStretFunctionDecl(); - if (!MsgSendSuperStretFunctionDecl) - SynthMsgSendSuperStretFunctionDecl(); - if (!MsgSendFpretFunctionDecl) - SynthMsgSendFpretFunctionDecl(); - if (!GetClassFunctionDecl) - SynthGetClassFunctionDecl(); - if (!GetSuperClassFunctionDecl) - SynthGetSuperClassFunctionDecl(); - if (!GetMetaClassFunctionDecl) - SynthGetMetaClassFunctionDecl(); - - // default to objc_msgSend(). - FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; - // May need to use objc_msgSend_stret() as well. - FunctionDecl *MsgSendStretFlavor = nullptr; - if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) { - QualType resultType = mDecl->getReturnType(); - if (resultType->isRecordType()) - MsgSendStretFlavor = MsgSendStretFunctionDecl; - else if (resultType->isRealFloatingType()) - MsgSendFlavor = MsgSendFpretFunctionDecl; - } - - // Synthesize a call to objc_msgSend(). - SmallVector MsgExprs; - switch (Exp->getReceiverKind()) { - case ObjCMessageExpr::SuperClass: { - MsgSendFlavor = MsgSendSuperFunctionDecl; - if (MsgSendStretFlavor) - MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; - assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); - - ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); - - SmallVector InitExprs; - - // set the receiver to self, the first argument to all methods. - InitExprs.push_back(NoTypeInfoCStyleCastExpr( - Context, Context->getObjCIdType(), CK_BitCast, - new (Context) DeclRefExpr(*Context, CurMethodDef->getSelfDecl(), false, - Context->getObjCIdType(), VK_PRValue, - SourceLocation()))); // set the 'receiver'. - - // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) - SmallVector ClsExprs; - ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName())); - CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl, - ClsExprs, StartLoc, EndLoc); - // (Class)objc_getClass("CurrentClass") - CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, - Context->getObjCClassType(), - CK_BitCast, Cls); - ClsExprs.clear(); - ClsExprs.push_back(ArgExpr); - Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) - // To turn off a warning, type-cast to 'id' - InitExprs.push_back( // set 'super class', using class_getSuperclass(). - NoTypeInfoCStyleCastExpr(Context, - Context->getObjCIdType(), - CK_BitCast, Cls)); - // struct objc_super - QualType superType = getSuperStructType(); - Expr *SuperRep; - - if (LangOpts.MicrosoftExt) { - SynthSuperConstructorFunctionDecl(); - // Simulate a constructor call... - DeclRefExpr *DRE = new (Context) - DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType, - VK_LValue, SourceLocation()); - SuperRep = - CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue, - SourceLocation(), FPOptionsOverride()); - // The code for super is a little tricky to prevent collision with - // the structure definition in the header. The rewriter has it's own - // internal definition (__rw_objc_super) that is uses. This is why - // we need the cast below. For example: - // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) - // - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - SuperRep = NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(superType), - CK_BitCast, SuperRep); - } else { - // (struct objc_super) { } - InitListExpr *ILE = - new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, - SourceLocation()); - TypeSourceInfo *superTInfo - = Context->getTrivialTypeSourceInfo(superType); - SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, - superType, VK_LValue, - ILE, false); - // struct objc_super * - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - } - MsgExprs.push_back(SuperRep); - break; - } - - case ObjCMessageExpr::Class: { - SmallVector ClsExprs; - auto *Class = - Exp->getClassReceiver()->castAs()->getInterface(); - IdentifierInfo *clsName = Class->getIdentifier(); - ClsExprs.push_back(getStringLiteral(clsName->getName())); - CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - MsgExprs.push_back(Cls); - break; - } - - case ObjCMessageExpr::SuperInstance:{ - MsgSendFlavor = MsgSendSuperFunctionDecl; - if (MsgSendStretFlavor) - MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; - assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); - ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); - SmallVector InitExprs; - - InitExprs.push_back(NoTypeInfoCStyleCastExpr( - Context, Context->getObjCIdType(), CK_BitCast, - new (Context) DeclRefExpr(*Context, CurMethodDef->getSelfDecl(), false, - Context->getObjCIdType(), VK_PRValue, - SourceLocation()))); // set the 'receiver'. - - // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) - SmallVector ClsExprs; - ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName())); - CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - // (Class)objc_getClass("CurrentClass") - CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, - Context->getObjCClassType(), - CK_BitCast, Cls); - ClsExprs.clear(); - ClsExprs.push_back(ArgExpr); - Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs, - StartLoc, EndLoc); - - // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) - // To turn off a warning, type-cast to 'id' - InitExprs.push_back( - // set 'super class', using class_getSuperclass(). - NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), - CK_BitCast, Cls)); - // struct objc_super - QualType superType = getSuperStructType(); - Expr *SuperRep; - - if (LangOpts.MicrosoftExt) { - SynthSuperConstructorFunctionDecl(); - // Simulate a constructor call... - DeclRefExpr *DRE = new (Context) - DeclRefExpr(*Context, SuperConstructorFunctionDecl, false, superType, - VK_LValue, SourceLocation()); - SuperRep = - CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue, - SourceLocation(), FPOptionsOverride()); - // The code for super is a little tricky to prevent collision with - // the structure definition in the header. The rewriter has it's own - // internal definition (__rw_objc_super) that is uses. This is why - // we need the cast below. For example: - // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) - // - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - SuperRep = NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(superType), - CK_BitCast, SuperRep); - } else { - // (struct objc_super) { } - InitListExpr *ILE = - new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, - SourceLocation()); - TypeSourceInfo *superTInfo - = Context->getTrivialTypeSourceInfo(superType); - SuperRep = new (Context) CompoundLiteralExpr( - SourceLocation(), superTInfo, superType, VK_PRValue, ILE, false); - } - MsgExprs.push_back(SuperRep); - break; - } - - case ObjCMessageExpr::Instance: { - // Remove all type-casts because it may contain objc-style types; e.g. - // Foo *. - Expr *recExpr = Exp->getInstanceReceiver(); - while (CStyleCastExpr *CE = dyn_cast(recExpr)) - recExpr = CE->getSubExpr(); - CastKind CK = recExpr->getType()->isObjCObjectPointerType() - ? CK_BitCast : recExpr->getType()->isBlockPointerType() - ? CK_BlockPointerToObjCPointerCast - : CK_CPointerToObjCPointerCast; - - recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), - CK, recExpr); - MsgExprs.push_back(recExpr); - break; - } - } - - // Create a call to sel_registerName("selName"), it will be the 2nd argument. - SmallVector SelExprs; - SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString())); - CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, - SelExprs, StartLoc, EndLoc); - MsgExprs.push_back(SelExp); - - // Now push any user supplied arguments. - for (unsigned i = 0; i < Exp->getNumArgs(); i++) { - Expr *userExpr = Exp->getArg(i); - // Make all implicit casts explicit...ICE comes in handy:-) - if (ImplicitCastExpr *ICE = dyn_cast(userExpr)) { - // Reuse the ICE type, it is exactly what the doctor ordered. - QualType type = ICE->getType(); - if (needToScanForQualifiers(type)) - type = Context->getObjCIdType(); - // Make sure we convert "type (^)(...)" to "type (*)(...)". - (void)convertBlockPointerToFunctionPointer(type); - const Expr *SubExpr = ICE->IgnoreParenImpCasts(); - CastKind CK; - if (SubExpr->getType()->isIntegralType(*Context) && - type->isBooleanType()) { - CK = CK_IntegralToBoolean; - } else if (type->isObjCObjectPointerType()) { - if (SubExpr->getType()->isBlockPointerType()) { - CK = CK_BlockPointerToObjCPointerCast; - } else if (SubExpr->getType()->isPointerType()) { - CK = CK_CPointerToObjCPointerCast; - } else { - CK = CK_BitCast; - } - } else { - CK = CK_BitCast; - } - - userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr); - } - // Make id cast into an 'id' cast. - else if (CStyleCastExpr *CE = dyn_cast(userExpr)) { - if (CE->getType()->isObjCQualifiedIdType()) { - while ((CE = dyn_cast(userExpr))) - userExpr = CE->getSubExpr(); - CastKind CK; - if (userExpr->getType()->isIntegralType(*Context)) { - CK = CK_IntegralToPointer; - } else if (userExpr->getType()->isBlockPointerType()) { - CK = CK_BlockPointerToObjCPointerCast; - } else if (userExpr->getType()->isPointerType()) { - CK = CK_CPointerToObjCPointerCast; - } else { - CK = CK_BitCast; - } - userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), - CK, userExpr); - } - } - MsgExprs.push_back(userExpr); - // We've transferred the ownership to MsgExprs. For now, we *don't* null - // out the argument in the original expression (since we aren't deleting - // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info. - //Exp->setArg(i, 0); - } - // Generate the funky cast. - CastExpr *cast; - SmallVector ArgTypes; - QualType returnType; - - // Push 'id' and 'SEL', the 2 implicit arguments. - if (MsgSendFlavor == MsgSendSuperFunctionDecl) - ArgTypes.push_back(Context->getPointerType(getSuperStructType())); - else - ArgTypes.push_back(Context->getObjCIdType()); - ArgTypes.push_back(Context->getObjCSelType()); - if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) { - // Push any user argument types. - for (const auto *PI : OMD->parameters()) { - QualType t = PI->getType()->isObjCQualifiedIdType() - ? Context->getObjCIdType() - : PI->getType(); - // Make sure we convert "t (^)(...)" to "t (*)(...)". - (void)convertBlockPointerToFunctionPointer(t); - ArgTypes.push_back(t); - } - returnType = Exp->getType(); - convertToUnqualifiedObjCType(returnType); - (void)convertBlockPointerToFunctionPointer(returnType); - } else { - returnType = Context->getObjCIdType(); - } - // Get the type, we will need to reference it in a couple spots. - QualType msgSendType = MsgSendFlavor->getType(); - - // Create a reference to the objc_msgSend() declaration. - DeclRefExpr *DRE = new (Context) DeclRefExpr( - *Context, MsgSendFlavor, false, msgSendType, VK_LValue, SourceLocation()); - - // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). - // If we don't do this cast, we get the following bizarre warning/note: - // xx.m:13: warning: function called through a non-compatible type - // xx.m:13: note: if this code is reached, the program will abort - cast = NoTypeInfoCStyleCastExpr(Context, - Context->getPointerType(Context->VoidTy), - CK_BitCast, DRE); - - // Now do the "normal" pointer to function cast. - // If we don't have a method decl, force a variadic cast. - const ObjCMethodDecl *MD = Exp->getMethodDecl(); - QualType castType = - getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true); - castType = Context->getPointerType(castType); - cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, - cast); - - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); - - const auto *FT = msgSendType->castAs(); - CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(), - VK_PRValue, EndLoc, FPOptionsOverride()); - Stmt *ReplacingStmt = CE; - if (MsgSendStretFlavor) { - // We have the method which returns a struct/union. Must also generate - // call to objc_msgSend_stret and hang both varieties on a conditional - // expression which dictate which one to envoke depending on size of - // method's return type. - - CallExpr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor, - msgSendType, returnType, - ArgTypes, MsgExprs, - Exp->getMethodDecl()); - - // Build sizeof(returnType) - UnaryExprOrTypeTraitExpr *sizeofExpr = - new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf, - Context->getTrivialTypeSourceInfo(returnType), - Context->getSizeType(), SourceLocation(), - SourceLocation()); - // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) - // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases. - // For X86 it is more complicated and some kind of target specific routine - // is needed to decide what to do. - unsigned IntSize = - static_cast(Context->getTypeSize(Context->IntTy)); - IntegerLiteral *limit = IntegerLiteral::Create(*Context, - llvm::APInt(IntSize, 8), - Context->IntTy, - SourceLocation()); - BinaryOperator *lessThanExpr = BinaryOperator::Create( - *Context, sizeofExpr, limit, BO_LE, Context->IntTy, VK_PRValue, - OK_Ordinary, SourceLocation(), FPOptionsOverride()); - // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) - ConditionalOperator *CondExpr = new (Context) ConditionalOperator( - lessThanExpr, SourceLocation(), CE, SourceLocation(), STCE, returnType, - VK_PRValue, OK_Ordinary); - ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), - CondExpr); - } - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return ReplacingStmt; -} - -Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) { - Stmt *ReplacingStmt = - SynthMessageExpr(Exp, Exp->getBeginLoc(), Exp->getEndLoc()); - - // Now do the actual rewrite. - ReplaceStmt(Exp, ReplacingStmt); - - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return ReplacingStmt; -} - -// typedef struct objc_object Protocol; -QualType RewriteObjC::getProtocolType() { - if (!ProtocolTypeDecl) { - TypeSourceInfo *TInfo - = Context->getTrivialTypeSourceInfo(Context->getObjCIdType()); - ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl, - SourceLocation(), SourceLocation(), - &Context->Idents.get("Protocol"), - TInfo); - } - return Context->getTypeDeclType(ProtocolTypeDecl); -} - -/// RewriteObjCProtocolExpr - Rewrite a protocol expression into -/// a synthesized/forward data reference (to the protocol's metadata). -/// The forward references (and metadata) are generated in -/// RewriteObjC::HandleTranslationUnit(). -Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { - std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString(); - IdentifierInfo *ID = &Context->Idents.get(Name); - VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), - SourceLocation(), ID, getProtocolType(), - nullptr, SC_Extern); - DeclRefExpr *DRE = new (Context) DeclRefExpr( - *Context, VD, false, getProtocolType(), VK_LValue, SourceLocation()); - Expr *DerefExpr = UnaryOperator::Create( - const_cast(*Context), DRE, UO_AddrOf, - Context->getPointerType(DRE->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), - CK_BitCast, - DerefExpr); - ReplaceStmt(Exp, castExpr); - ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl()); - // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. - return castExpr; -} - -bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf, - const char *endBuf) { - while (startBuf < endBuf) { - if (*startBuf == '#') { - // Skip whitespace. - for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf) - ; - if (!strncmp(startBuf, "if", strlen("if")) || - !strncmp(startBuf, "ifdef", strlen("ifdef")) || - !strncmp(startBuf, "ifndef", strlen("ifndef")) || - !strncmp(startBuf, "define", strlen("define")) || - !strncmp(startBuf, "undef", strlen("undef")) || - !strncmp(startBuf, "else", strlen("else")) || - !strncmp(startBuf, "elif", strlen("elif")) || - !strncmp(startBuf, "endif", strlen("endif")) || - !strncmp(startBuf, "pragma", strlen("pragma")) || - !strncmp(startBuf, "include", strlen("include")) || - !strncmp(startBuf, "import", strlen("import")) || - !strncmp(startBuf, "include_next", strlen("include_next"))) - return true; - } - startBuf++; - } - return false; -} - -/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to -/// an objective-c class with ivars. -void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, - std::string &Result) { - assert(CDecl && "Class missing in SynthesizeObjCInternalStruct"); - assert(CDecl->getName() != "" && - "Name missing in SynthesizeObjCInternalStruct"); - // Do not synthesize more than once. - if (ObjCSynthesizedStructs.count(CDecl)) - return; - ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass(); - int NumIvars = CDecl->ivar_size(); - SourceLocation LocStart = CDecl->getBeginLoc(); - SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc(); - - const char *startBuf = SM->getCharacterData(LocStart); - const char *endBuf = SM->getCharacterData(LocEnd); - - // 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->isThisDeclarationADefinition() || NumIvars == 0) && - (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) { - endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); - ReplaceText(LocStart, endBuf-startBuf, Result); - return; - } - - // FIXME: This has potential of causing problem. If - // SynthesizeObjCInternalStruct is ever called recursively. - Result += "\nstruct "; - Result += CDecl->getNameAsString(); - if (LangOpts.MicrosoftExt) - Result += "_IMPL"; - - if (NumIvars > 0) { - const char *cursor = strchr(startBuf, '{'); - assert((cursor && endBuf) - && "SynthesizeObjCInternalStruct - malformed @interface"); - // If the buffer contains preprocessor directives, we do more fine-grained - // rewrites. This is intended to fix code that looks like (which occurs in - // NSURL.h, for example): - // - // #ifdef XYZ - // @interface Foo : NSObject - // #else - // @interface FooBar : NSObject - // #endif - // { - // int i; - // } - // @end - // - // This clause is segregated to avoid breaking the common case. - if (BufferContainsPPDirectives(startBuf, cursor)) { - SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() : - CDecl->getAtStartLoc(); - const char *endHeader = SM->getCharacterData(L); - endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts); - - if (CDecl->protocol_begin() != CDecl->protocol_end()) { - // advance to the end of the referenced protocols. - while (endHeader < cursor && *endHeader != '>') endHeader++; - endHeader++; - } - // rewrite the original header - ReplaceText(LocStart, endHeader-startBuf, Result); - } else { - // rewrite the original header *without* disturbing the '{' - ReplaceText(LocStart, cursor-startBuf, Result); - } - if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) { - Result = "\n struct "; - Result += RCDecl->getNameAsString(); - Result += "_IMPL "; - Result += RCDecl->getNameAsString(); - Result += "_IVARS;\n"; - - // insert the super class structure definition. - SourceLocation OnePastCurly = - LocStart.getLocWithOffset(cursor-startBuf+1); - InsertText(OnePastCurly, Result); - } - cursor++; // past '{' - - // Now comment out any visibility specifiers. - while (cursor < endBuf) { - if (*cursor == '@') { - SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf); - // Skip whitespace. - for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor) - /*scan*/; - - // FIXME: presence of @public, etc. inside comment results in - // this transformation as well, which is still correct c-code. - if (!strncmp(cursor, "public", strlen("public")) || - !strncmp(cursor, "private", strlen("private")) || - !strncmp(cursor, "package", strlen("package")) || - !strncmp(cursor, "protected", strlen("protected"))) - InsertText(atLoc, "// "); - } - // FIXME: If there are cases where '<' is used in ivar declaration part - // of user code, then scan the ivar list and use needToScanForQualifiers - // for type checking. - else if (*cursor == '<') { - SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf); - InsertText(atLoc, "/* "); - cursor = strchr(cursor, '>'); - cursor++; - atLoc = LocStart.getLocWithOffset(cursor-startBuf); - InsertText(atLoc, " */"); - } else if (*cursor == '^') { // rewrite block specifier. - SourceLocation caretLoc = LocStart.getLocWithOffset(cursor-startBuf); - ReplaceText(caretLoc, 1, "*"); - } - cursor++; - } - // Don't forget to add a ';'!! - InsertText(LocEnd.getLocWithOffset(1), ";"); - } else { // we don't have any instance variables - insert super struct. - endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); - Result += " {\n struct "; - Result += RCDecl->getNameAsString(); - Result += "_IMPL "; - Result += RCDecl->getNameAsString(); - Result += "_IVARS;\n};\n"; - ReplaceText(LocStart, endBuf-startBuf, Result); - } - // Mark this struct as having been generated. - if (!ObjCSynthesizedStructs.insert(CDecl).second) - llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct"); -} - -//===----------------------------------------------------------------------===// -// Meta Data Emission -//===----------------------------------------------------------------------===// - -/// RewriteImplementations - This routine rewrites all method implementations -/// and emits meta-data. - -void RewriteObjC::RewriteImplementations() { - int ClsDefCount = ClassImplementation.size(); - int CatDefCount = CategoryImplementation.size(); - - // Rewrite implemented methods - for (int i = 0; i < ClsDefCount; i++) - RewriteImplementationDecl(ClassImplementation[i]); - - for (int i = 0; i < CatDefCount; i++) - RewriteImplementationDecl(CategoryImplementation[i]); -} - -void RewriteObjC::RewriteByRefString(std::string &ResultStr, - const std::string &Name, - ValueDecl *VD, bool def) { - assert(BlockByRefDeclNo.count(VD) && - "RewriteByRefString: ByRef decl missing"); - if (def) - ResultStr += "struct "; - ResultStr += "__Block_byref_" + Name + - "_" + utostr(BlockByRefDeclNo[VD]) ; -} - -static bool HasLocalVariableExternalStorage(ValueDecl *VD) { - if (VarDecl *Var = dyn_cast(VD)) - return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage()); - return false; -} - -std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, - StringRef funcName, - std::string Tag) { - const FunctionType *AFT = CE->getFunctionType(); - QualType RT = AFT->getReturnType(); - std::string StructRef = "struct " + Tag; - std::string S = "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" + - funcName.str() + "_" + "block_func_" + utostr(i); - - BlockDecl *BD = CE->getBlockDecl(); - - if (isa(AFT)) { - // No user-supplied arguments. Still need to pass in a pointer to the - // block (to reference imported block decl refs). - S += "(" + StructRef + " *__cself)"; - } else if (BD->param_empty()) { - S += "(" + StructRef + " *__cself)"; - } else { - const FunctionProtoType *FT = cast(AFT); - assert(FT && "SynthesizeBlockFunc: No function proto"); - S += '('; - // first add the implicit argument. - S += StructRef + " *__cself, "; - std::string ParamStr; - for (BlockDecl::param_iterator AI = BD->param_begin(), - E = BD->param_end(); AI != E; ++AI) { - if (AI != BD->param_begin()) S += ", "; - ParamStr = (*AI)->getNameAsString(); - QualType QT = (*AI)->getType(); - (void)convertBlockPointerToFunctionPointer(QT); - QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy()); - S += ParamStr; - } - if (FT->isVariadic()) { - if (!BD->param_empty()) S += ", "; - S += "..."; - } - S += ')'; - } - S += " {\n"; - - // Create local declarations to avoid rewriting all closure decl ref exprs. - // First, emit a declaration for all "by ref" decls. - for (auto I = BlockByRefDecls.begin(), E = BlockByRefDecls.end(); I != E; - ++I) { - S += " "; - std::string Name = (*I)->getNameAsString(); - std::string TypeString; - RewriteByRefString(TypeString, Name, (*I)); - TypeString += " *"; - Name = TypeString + Name; - S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n"; - } - // Next, emit a declaration for all "by copy" declarations. - for (auto I = BlockByCopyDecls.begin(), E = BlockByCopyDecls.end(); I != E; - ++I) { - S += " "; - // Handle nested closure invocation. For example: - // - // void (^myImportedClosure)(void); - // myImportedClosure = ^(void) { setGlobalInt(x + y); }; - // - // void (^anotherClosure)(void); - // anotherClosure = ^(void) { - // myImportedClosure(); // import and invoke the closure - // }; - // - if (isTopLevelBlockPointerType((*I)->getType())) { - RewriteBlockPointerTypeVariable(S, (*I)); - S += " = ("; - RewriteBlockPointerType(S, (*I)->getType()); - S += ")"; - S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; - } - else { - std::string Name = (*I)->getNameAsString(); - QualType QT = (*I)->getType(); - if (HasLocalVariableExternalStorage(*I)) - QT = Context->getPointerType(QT); - QT.getAsStringInternal(Name, Context->getPrintingPolicy()); - S += Name + " = __cself->" + - (*I)->getNameAsString() + "; // bound by copy\n"; - } - } - std::string RewrittenStr = RewrittenBlockExprs[CE]; - const char *cstr = RewrittenStr.c_str(); - while (*cstr++ != '{') ; - S += cstr; - S += "\n"; - return S; -} - -std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, - StringRef funcName, - std::string Tag) { - std::string StructRef = "struct " + Tag; - std::string S = "static void __"; - - S += funcName; - S += "_block_copy_" + utostr(i); - S += "(" + StructRef; - S += "*dst, " + StructRef; - S += "*src) {"; - for (ValueDecl *VD : ImportedBlockDecls) { - S += "_Block_object_assign((void*)&dst->"; - S += VD->getNameAsString(); - S += ", (void*)src->"; - S += VD->getNameAsString(); - if (BlockByRefDecls.contains(VD)) - S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; - else if (VD->getType()->isBlockPointerType()) - S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; - else - S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; - } - S += "}\n"; - - S += "\nstatic void __"; - S += funcName; - S += "_block_dispose_" + utostr(i); - S += "(" + StructRef; - S += "*src) {"; - for (ValueDecl *VD : ImportedBlockDecls) { - S += "_Block_object_dispose((void*)src->"; - S += VD->getNameAsString(); - if (BlockByRefDecls.contains(VD)) - S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; - else if (VD->getType()->isBlockPointerType()) - S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; - else - S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; - } - S += "}\n"; - return S; -} - -std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, - std::string Desc) { - std::string S = "\nstruct " + Tag; - std::string Constructor = " " + Tag; - - S += " {\n struct __block_impl impl;\n"; - S += " struct " + Desc; - S += "* Desc;\n"; - - Constructor += "(void *fp, "; // Invoke function pointer. - Constructor += "struct " + Desc; // Descriptor pointer. - Constructor += " *desc"; - - if (BlockDeclRefs.size()) { - // Output all "by copy" declarations. - for (auto I = BlockByCopyDecls.begin(), E = BlockByCopyDecls.end(); I != E; - ++I) { - S += " "; - std::string FieldName = (*I)->getNameAsString(); - std::string ArgName = "_" + FieldName; - // Handle nested closure invocation. For example: - // - // void (^myImportedBlock)(void); - // myImportedBlock = ^(void) { setGlobalInt(x + y); }; - // - // void (^anotherBlock)(void); - // anotherBlock = ^(void) { - // myImportedBlock(); // import and invoke the closure - // }; - // - if (isTopLevelBlockPointerType((*I)->getType())) { - S += "struct __block_impl *"; - Constructor += ", void *" + ArgName; - } else { - QualType QT = (*I)->getType(); - if (HasLocalVariableExternalStorage(*I)) - QT = Context->getPointerType(QT); - QT.getAsStringInternal(FieldName, Context->getPrintingPolicy()); - QT.getAsStringInternal(ArgName, Context->getPrintingPolicy()); - Constructor += ", " + ArgName; - } - S += FieldName + ";\n"; - } - // Output all "by ref" declarations. - for (auto I = BlockByRefDecls.begin(), E = BlockByRefDecls.end(); I != E; - ++I) { - S += " "; - std::string FieldName = (*I)->getNameAsString(); - std::string ArgName = "_" + FieldName; - { - std::string TypeString; - RewriteByRefString(TypeString, FieldName, (*I)); - TypeString += " *"; - FieldName = TypeString + FieldName; - ArgName = TypeString + ArgName; - Constructor += ", " + ArgName; - } - S += FieldName + "; // by ref\n"; - } - // Finish writing the constructor. - Constructor += ", int flags=0)"; - // Initialize all "by copy" arguments. - bool firsTime = true; - for (auto I = BlockByCopyDecls.begin(), E = BlockByCopyDecls.end(); I != E; - ++I) { - std::string Name = (*I)->getNameAsString(); - if (firsTime) { - Constructor += " : "; - firsTime = false; - } - else - Constructor += ", "; - if (isTopLevelBlockPointerType((*I)->getType())) - Constructor += Name + "((struct __block_impl *)_" + Name + ")"; - else - Constructor += Name + "(_" + Name + ")"; - } - // Initialize all "by ref" arguments. - for (auto I = BlockByRefDecls.begin(), E = BlockByRefDecls.end(); I != E; - ++I) { - std::string Name = (*I)->getNameAsString(); - if (firsTime) { - Constructor += " : "; - firsTime = false; - } - else - Constructor += ", "; - Constructor += Name + "(_" + Name + "->__forwarding)"; - } - - Constructor += " {\n"; - if (GlobalVarDecl) - Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; - else - Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; - Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; - - Constructor += " Desc = desc;\n"; - } else { - // Finish writing the constructor. - Constructor += ", int flags=0) {\n"; - if (GlobalVarDecl) - Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; - else - Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; - Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; - Constructor += " Desc = desc;\n"; - } - Constructor += " "; - Constructor += "}\n"; - S += Constructor; - S += "};\n"; - return S; -} - -std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, - std::string ImplTag, int i, - StringRef FunName, - unsigned hasCopy) { - std::string S = "\nstatic struct " + DescTag; - - S += " {\n unsigned long reserved;\n"; - S += " unsigned long Block_size;\n"; - if (hasCopy) { - S += " void (*copy)(struct "; - S += ImplTag; S += "*, struct "; - S += ImplTag; S += "*);\n"; - - S += " void (*dispose)(struct "; - S += ImplTag; S += "*);\n"; - } - S += "} "; - - S += DescTag + "_DATA = { 0, sizeof(struct "; - S += ImplTag + ")"; - if (hasCopy) { - S += ", __" + FunName.str() + "_block_copy_" + utostr(i); - S += ", __" + FunName.str() + "_block_dispose_" + utostr(i); - } - S += "};\n"; - return S; -} - -void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, - StringRef FunName) { - // Insert declaration for the function in which block literal is used. - if (CurFunctionDeclToDeclareForBlock && !Blocks.empty()) - RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); - bool RewriteSC = (GlobalVarDecl && - !Blocks.empty() && - GlobalVarDecl->getStorageClass() == SC_Static && - GlobalVarDecl->getType().getCVRQualifiers()); - if (RewriteSC) { - std::string SC(" void __"); - SC += GlobalVarDecl->getNameAsString(); - SC += "() {}"; - InsertText(FunLocStart, SC); - } - - // Insert closures that were part of the function. - for (unsigned i = 0, count=0; i < Blocks.size(); i++) { - CollectBlockDeclRefInfo(Blocks[i]); - // Need to copy-in the inner copied-in variables not actually used in this - // block. - for (int j = 0; j < InnerDeclRefsCount[i]; j++) { - DeclRefExpr *Exp = InnerDeclRefs[count++]; - ValueDecl *VD = Exp->getDecl(); - BlockDeclRefs.push_back(Exp); - if (VD->hasAttr()) - BlockByRefDecls.insert(VD); - else - BlockByCopyDecls.insert(VD); - // imported objects in the inner blocks not used in the outer - // blocks must be copied/disposed in the outer block as well. - if (VD->hasAttr() || - VD->getType()->isObjCObjectPointerType() || - VD->getType()->isBlockPointerType()) - ImportedBlockDecls.insert(VD); - } - - std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i); - std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i); - - std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag); - - InsertText(FunLocStart, CI); - - std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag); - - InsertText(FunLocStart, CF); - - if (ImportedBlockDecls.size()) { - std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag); - InsertText(FunLocStart, HF); - } - std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName, - ImportedBlockDecls.size() > 0); - InsertText(FunLocStart, BD); - - BlockDeclRefs.clear(); - BlockByRefDecls.clear(); - BlockByCopyDecls.clear(); - ImportedBlockDecls.clear(); - } - if (RewriteSC) { - // Must insert any 'const/volatile/static here. Since it has been - // removed as result of rewriting of block literals. - std::string SC; - if (GlobalVarDecl->getStorageClass() == SC_Static) - SC = "static "; - if (GlobalVarDecl->getType().isConstQualified()) - SC += "const "; - if (GlobalVarDecl->getType().isVolatileQualified()) - SC += "volatile "; - if (GlobalVarDecl->getType().isRestrictQualified()) - SC += "restrict "; - InsertText(FunLocStart, SC); - } - - Blocks.clear(); - InnerDeclRefsCount.clear(); - InnerDeclRefs.clear(); - RewrittenBlockExprs.clear(); -} - -void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { - SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); - StringRef FuncName = FD->getName(); - - SynthesizeBlockLiterals(FunLocStart, FuncName); -} - -static void BuildUniqueMethodName(std::string &Name, - ObjCMethodDecl *MD) { - ObjCInterfaceDecl *IFace = MD->getClassInterface(); - Name = std::string(IFace->getName()); - Name += "__" + MD->getSelector().getAsString(); - // Convert colons to underscores. - std::string::size_type loc = 0; - while ((loc = Name.find(':', loc)) != std::string::npos) - Name.replace(loc, 1, "_"); -} - -void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) { - // fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n"); - // SourceLocation FunLocStart = MD->getBeginLoc(); - SourceLocation FunLocStart = MD->getBeginLoc(); - std::string FuncName; - BuildUniqueMethodName(FuncName, MD); - SynthesizeBlockLiterals(FunLocStart, FuncName); -} - -void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { - for (Stmt *SubStmt : S->children()) - if (SubStmt) { - if (BlockExpr *CBE = dyn_cast(SubStmt)) - GetBlockDeclRefExprs(CBE->getBody()); - else - GetBlockDeclRefExprs(SubStmt); - } - // Handle specific things. - if (DeclRefExpr *DRE = dyn_cast(S)) - if (DRE->refersToEnclosingVariableOrCapture() || - HasLocalVariableExternalStorage(DRE->getDecl())) - // FIXME: Handle enums. - BlockDeclRefs.push_back(DRE); -} - -void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, - SmallVectorImpl &InnerBlockDeclRefs, - llvm::SmallPtrSetImpl &InnerContexts) { - for (Stmt *SubStmt : S->children()) - if (SubStmt) { - if (BlockExpr *CBE = dyn_cast(SubStmt)) { - InnerContexts.insert(cast(CBE->getBlockDecl())); - GetInnerBlockDeclRefExprs(CBE->getBody(), - InnerBlockDeclRefs, - InnerContexts); - } - else - GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts); - } - // Handle specific things. - if (DeclRefExpr *DRE = dyn_cast(S)) { - if (DRE->refersToEnclosingVariableOrCapture() || - HasLocalVariableExternalStorage(DRE->getDecl())) { - if (!InnerContexts.count(DRE->getDecl()->getDeclContext())) - InnerBlockDeclRefs.push_back(DRE); - if (VarDecl *Var = cast(DRE->getDecl())) - if (Var->isFunctionOrMethodVarDecl()) - ImportedLocalExternalDecls.insert(Var); - } - } -} - -/// convertFunctionTypeOfBlocks - This routine converts a function type -/// whose result type may be a block pointer or whose argument type(s) -/// might be block pointers to an equivalent function type replacing -/// all block pointers to function pointers. -QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) { - const FunctionProtoType *FTP = dyn_cast(FT); - // FTP will be null for closures that don't take arguments. - // Generate a funky cast. - SmallVector ArgTypes; - QualType Res = FT->getReturnType(); - bool HasBlockType = convertBlockPointerToFunctionPointer(Res); - - if (FTP) { - for (auto &I : FTP->param_types()) { - QualType t = I; - // Make sure we convert "t (^)(...)" to "t (*)(...)". - if (convertBlockPointerToFunctionPointer(t)) - HasBlockType = true; - ArgTypes.push_back(t); - } - } - QualType FuncType; - // FIXME. Does this work if block takes no argument but has a return type - // which is of block type? - if (HasBlockType) - FuncType = getSimpleFunctionType(Res, ArgTypes); - else FuncType = QualType(FT, 0); - return FuncType; -} - -Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { - // Navigate to relevant type information. - const BlockPointerType *CPT = nullptr; - - if (const DeclRefExpr *DRE = dyn_cast(BlockExp)) { - CPT = DRE->getType()->getAs(); - } else if (const MemberExpr *MExpr = dyn_cast(BlockExp)) { - CPT = MExpr->getType()->getAs(); - } - else if (const ParenExpr *PRE = dyn_cast(BlockExp)) { - return SynthesizeBlockCall(Exp, PRE->getSubExpr()); - } - else if (const ImplicitCastExpr *IEXPR = dyn_cast(BlockExp)) - CPT = IEXPR->getType()->getAs(); - else if (const ConditionalOperator *CEXPR = - dyn_cast(BlockExp)) { - Expr *LHSExp = CEXPR->getLHS(); - Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp); - Expr *RHSExp = CEXPR->getRHS(); - Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp); - Expr *CONDExp = CEXPR->getCond(); - ConditionalOperator *CondExpr = new (Context) ConditionalOperator( - CONDExp, SourceLocation(), cast(LHSStmt), SourceLocation(), - cast(RHSStmt), Exp->getType(), VK_PRValue, OK_Ordinary); - return CondExpr; - } else if (const ObjCIvarRefExpr *IRE = dyn_cast(BlockExp)) { - CPT = IRE->getType()->getAs(); - } else if (const PseudoObjectExpr *POE - = dyn_cast(BlockExp)) { - CPT = POE->getType()->castAs(); - } else { - assert(false && "RewriteBlockClass: Bad type"); - } - assert(CPT && "RewriteBlockClass: Bad type"); - const FunctionType *FT = CPT->getPointeeType()->getAs(); - assert(FT && "RewriteBlockClass: Bad type"); - const FunctionProtoType *FTP = dyn_cast(FT); - // FTP will be null for closures that don't take arguments. - - RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl, - SourceLocation(), SourceLocation(), - &Context->Idents.get("__block_impl")); - QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); - - // Generate a funky cast. - SmallVector ArgTypes; - - // Push the block argument type. - ArgTypes.push_back(PtrBlock); - if (FTP) { - for (auto &I : FTP->param_types()) { - QualType t = I; - // Make sure we convert "t (^)(...)" to "t (*)(...)". - if (!convertBlockPointerToFunctionPointer(t)) - convertToUnqualifiedObjCType(t); - ArgTypes.push_back(t); - } - } - // Now do the pointer to function cast. - QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes); - - PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); - - CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock, - CK_BitCast, - const_cast(BlockExp)); - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), - BlkCast); - //PE->dump(); - - FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), - SourceLocation(), - &Context->Idents.get("FuncPtr"), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - MemberExpr *ME = MemberExpr::CreateImplicit( - *Context, PE, true, FD, FD->getType(), VK_LValue, OK_Ordinary); - - CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, - CK_BitCast, ME); - PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); - - SmallVector BlkExprs; - // Add the implicit argument. - BlkExprs.push_back(BlkCast); - // Add the user arguments. - for (CallExpr::arg_iterator I = Exp->arg_begin(), - E = Exp->arg_end(); I != E; ++I) { - BlkExprs.push_back(*I); - } - CallExpr *CE = - CallExpr::Create(*Context, PE, BlkExprs, Exp->getType(), VK_PRValue, - SourceLocation(), FPOptionsOverride()); - return CE; -} - -// We need to return the rewritten expression to handle cases where the -// BlockDeclRefExpr is embedded in another expression being rewritten. -// For example: -// -// int main() { -// __block Foo *f; -// __block int i; -// -// void (^myblock)() = ^() { -// [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten). -// i = 77; -// }; -//} -Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { - // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR - // for each DeclRefExp where BYREFVAR is name of the variable. - ValueDecl *VD = DeclRefExp->getDecl(); - bool isArrow = DeclRefExp->refersToEnclosingVariableOrCapture() || - HasLocalVariableExternalStorage(DeclRefExp->getDecl()); - - FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), - SourceLocation(), - &Context->Idents.get("__forwarding"), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - MemberExpr *ME = - MemberExpr::CreateImplicit(*Context, DeclRefExp, isArrow, FD, - FD->getType(), VK_LValue, OK_Ordinary); - - StringRef Name = VD->getName(); - FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), - &Context->Idents.get(Name), - Context->VoidPtrTy, nullptr, - /*BitWidth=*/nullptr, /*Mutable=*/true, - ICIS_NoInit); - ME = MemberExpr::CreateImplicit(*Context, ME, true, FD, DeclRefExp->getType(), - VK_LValue, OK_Ordinary); - - // Need parens to enforce precedence. - ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), - DeclRefExp->getExprLoc(), - ME); - ReplaceStmt(DeclRefExp, PE); - return PE; -} - -// Rewrites the imported local variable V with external storage -// (static, extern, etc.) as *V -// -Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { - ValueDecl *VD = DRE->getDecl(); - if (VarDecl *Var = dyn_cast(VD)) - if (!ImportedLocalExternalDecls.count(Var)) - return DRE; - Expr *Exp = UnaryOperator::Create( - const_cast(*Context), DRE, UO_Deref, DRE->getType(), - VK_LValue, OK_Ordinary, DRE->getLocation(), false, FPOptionsOverride()); - // Need parens to enforce precedence. - ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), - Exp); - ReplaceStmt(DRE, PE); - return PE; -} - -void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) { - SourceLocation LocStart = CE->getLParenLoc(); - SourceLocation LocEnd = CE->getRParenLoc(); - - // Need to avoid trying to rewrite synthesized casts. - if (LocStart.isInvalid()) - return; - // Need to avoid trying to rewrite casts contained in macros. - if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd)) - return; - - const char *startBuf = SM->getCharacterData(LocStart); - const char *endBuf = SM->getCharacterData(LocEnd); - QualType QT = CE->getType(); - const Type* TypePtr = QT->getAs(); - if (isa(TypePtr)) { - const TypeOfExprType *TypeOfExprTypePtr = cast(TypePtr); - QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); - std::string TypeAsString = "("; - RewriteBlockPointerType(TypeAsString, QT); - TypeAsString += ")"; - ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString); - return; - } - // advance the location to startArgList. - const char *argPtr = startBuf; - - while (*argPtr++ && (argPtr < endBuf)) { - switch (*argPtr) { - case '^': - // Replace the '^' with '*'. - LocStart = LocStart.getLocWithOffset(argPtr-startBuf); - ReplaceText(LocStart, 1, "*"); - break; - } - } -} - -void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { - SourceLocation DeclLoc = FD->getLocation(); - unsigned parenCount = 0; - - // We have 1 or more arguments that have closure pointers. - const char *startBuf = SM->getCharacterData(DeclLoc); - const char *startArgList = strchr(startBuf, '('); - - assert((*startArgList == '(') && "Rewriter fuzzy parser confused"); - - parenCount++; - // advance the location to startArgList. - DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf); - assert((DeclLoc.isValid()) && "Invalid DeclLoc"); - - const char *argPtr = startArgList; - - while (*argPtr++ && parenCount) { - switch (*argPtr) { - case '^': - // Replace the '^' with '*'. - DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList); - ReplaceText(DeclLoc, 1, "*"); - break; - case '(': - parenCount++; - break; - case ')': - parenCount--; - break; - } - } -} - -bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { - const FunctionProtoType *FTP; - const PointerType *PT = QT->getAs(); - if (PT) { - FTP = PT->getPointeeType()->getAs(); - } else { - const BlockPointerType *BPT = QT->getAs(); - assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); - FTP = BPT->getPointeeType()->getAs(); - } - if (FTP) { - for (const auto &I : FTP->param_types()) - if (isTopLevelBlockPointerType(I)) - return true; - } - return false; -} - -bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) { - const FunctionProtoType *FTP; - const PointerType *PT = QT->getAs(); - if (PT) { - FTP = PT->getPointeeType()->getAs(); - } else { - const BlockPointerType *BPT = QT->getAs(); - assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); - FTP = BPT->getPointeeType()->getAs(); - } - if (FTP) { - for (const auto &I : FTP->param_types()) { - if (I->isObjCQualifiedIdType()) - return true; - if (I->isObjCObjectPointerType() && - I->getPointeeType()->isObjCQualifiedInterfaceType()) - return true; - } - - } - return false; -} - -void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen, - const char *&RParen) { - const char *argPtr = strchr(Name, '('); - assert((*argPtr == '(') && "Rewriter fuzzy parser confused"); - - LParen = argPtr; // output the start. - argPtr++; // skip past the left paren. - unsigned parenCount = 1; - - while (*argPtr && parenCount) { - switch (*argPtr) { - case '(': parenCount++; break; - case ')': parenCount--; break; - default: break; - } - if (parenCount) argPtr++; - } - assert((*argPtr == ')') && "Rewriter fuzzy parser confused"); - RParen = argPtr; // output the end -} - -void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) { - if (FunctionDecl *FD = dyn_cast(ND)) { - RewriteBlockPointerFunctionArgs(FD); - return; - } - // Handle Variables and Typedefs. - SourceLocation DeclLoc = ND->getLocation(); - QualType DeclT; - if (VarDecl *VD = dyn_cast(ND)) - DeclT = VD->getType(); - else if (TypedefNameDecl *TDD = dyn_cast(ND)) - DeclT = TDD->getUnderlyingType(); - else if (FieldDecl *FD = dyn_cast(ND)) - DeclT = FD->getType(); - else - llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled"); - - const char *startBuf = SM->getCharacterData(DeclLoc); - const char *endBuf = startBuf; - // scan backward (from the decl location) for the end of the previous decl. - while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart) - startBuf--; - SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf); - std::string buf; - unsigned OrigLength=0; - // *startBuf != '^' if we are dealing with a pointer to function that - // may take block argument types (which will be handled below). - if (*startBuf == '^') { - // Replace the '^' with '*', computing a negative offset. - buf = '*'; - startBuf++; - OrigLength++; - } - while (*startBuf != ')') { - buf += *startBuf; - startBuf++; - OrigLength++; - } - buf += ')'; - OrigLength++; - - if (PointerTypeTakesAnyBlockArguments(DeclT) || - PointerTypeTakesAnyObjCQualifiedType(DeclT)) { - // Replace the '^' with '*' for arguments. - // Replace id

with id/*<>*/ - DeclLoc = ND->getLocation(); - startBuf = SM->getCharacterData(DeclLoc); - const char *argListBegin, *argListEnd; - GetExtentOfArgList(startBuf, argListBegin, argListEnd); - while (argListBegin < argListEnd) { - if (*argListBegin == '^') - buf += '*'; - else if (*argListBegin == '<') { - buf += "/*"; - buf += *argListBegin++; - OrigLength++; - while (*argListBegin != '>') { - buf += *argListBegin++; - OrigLength++; - } - buf += *argListBegin; - buf += "*/"; - } - else - buf += *argListBegin; - argListBegin++; - OrigLength++; - } - buf += ')'; - OrigLength++; - } - ReplaceText(Start, OrigLength, buf); -} - -/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: -/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, -/// struct Block_byref_id_object *src) { -/// _Block_object_assign (&_dest->object, _src->object, -/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT -/// [|BLOCK_FIELD_IS_WEAK]) // object -/// _Block_object_assign(&_dest->object, _src->object, -/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK -/// [|BLOCK_FIELD_IS_WEAK]) // block -/// } -/// And: -/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { -/// _Block_object_dispose(_src->object, -/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT -/// [|BLOCK_FIELD_IS_WEAK]) // object -/// _Block_object_dispose(_src->object, -/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK -/// [|BLOCK_FIELD_IS_WEAK]) // block -/// } - -std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, - int flag) { - std::string S; - if (!CopyDestroyCache.insert(flag).second) - return S; - S = "static void __Block_byref_id_object_copy_"; - S += utostr(flag); - S += "(void *dst, void *src) {\n"; - - // offset into the object pointer is computed as: - // void * + void* + int + int + void* + void * - unsigned IntSize = - static_cast(Context->getTypeSize(Context->IntTy)); - unsigned VoidPtrSize = - static_cast(Context->getTypeSize(Context->VoidPtrTy)); - - unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth(); - S += " _Block_object_assign((char*)dst + "; - S += utostr(offset); - S += ", *(void * *) ((char*)src + "; - S += utostr(offset); - S += "), "; - S += utostr(flag); - S += ");\n}\n"; - - S += "static void __Block_byref_id_object_dispose_"; - S += utostr(flag); - S += "(void *src) {\n"; - S += " _Block_object_dispose(*(void * *) ((char*)src + "; - S += utostr(offset); - S += "), "; - S += utostr(flag); - S += ");\n}\n"; - return S; -} - -/// RewriteByRefVar - For each __block typex ND variable this routine transforms -/// the declaration into: -/// struct __Block_byref_ND { -/// void *__isa; // NULL for everything except __weak pointers -/// struct __Block_byref_ND *__forwarding; -/// int32_t __flags; -/// int32_t __size; -/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object -/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object -/// typex ND; -/// }; -/// -/// It then replaces declaration of ND variable with: -/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, -/// __size=sizeof(struct __Block_byref_ND), -/// ND=initializer-if-any}; -/// -/// -void RewriteObjC::RewriteByRefVar(VarDecl *ND) { - // Insert declaration for the function in which block literal is - // used. - if (CurFunctionDeclToDeclareForBlock) - RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); - int flag = 0; - int isa = 0; - SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); - if (DeclLoc.isInvalid()) - // If type location is missing, it is because of missing type (a warning). - // Use variable's location which is good for this case. - DeclLoc = ND->getLocation(); - const char *startBuf = SM->getCharacterData(DeclLoc); - SourceLocation X = ND->getEndLoc(); - X = SM->getExpansionLoc(X); - const char *endBuf = SM->getCharacterData(X); - std::string Name(ND->getNameAsString()); - std::string ByrefType; - RewriteByRefString(ByrefType, Name, ND, true); - ByrefType += " {\n"; - ByrefType += " void *__isa;\n"; - RewriteByRefString(ByrefType, Name, ND); - ByrefType += " *__forwarding;\n"; - ByrefType += " int __flags;\n"; - ByrefType += " int __size;\n"; - // Add void *__Block_byref_id_object_copy; - // void *__Block_byref_id_object_dispose; if needed. - QualType Ty = ND->getType(); - bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND); - if (HasCopyAndDispose) { - ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n"; - ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n"; - } - - QualType T = Ty; - (void)convertBlockPointerToFunctionPointer(T); - T.getAsStringInternal(Name, Context->getPrintingPolicy()); - - ByrefType += " " + Name + ";\n"; - ByrefType += "};\n"; - // Insert this type in global scope. It is needed by helper function. - SourceLocation FunLocStart; - if (CurFunctionDef) - FunLocStart = CurFunctionDef->getTypeSpecStartLoc(); - else { - assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null"); - FunLocStart = CurMethodDef->getBeginLoc(); - } - InsertText(FunLocStart, ByrefType); - if (Ty.isObjCGCWeak()) { - flag |= BLOCK_FIELD_IS_WEAK; - isa = 1; - } - - if (HasCopyAndDispose) { - flag = BLOCK_BYREF_CALLER; - QualType Ty = ND->getType(); - // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well. - if (Ty->isBlockPointerType()) - flag |= BLOCK_FIELD_IS_BLOCK; - else - flag |= BLOCK_FIELD_IS_OBJECT; - std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag); - if (!HF.empty()) - InsertText(FunLocStart, HF); - } - - // struct __Block_byref_ND ND = - // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), - // initializer-if-any}; - bool hasInit = (ND->getInit() != nullptr); - unsigned flags = 0; - if (HasCopyAndDispose) - flags |= BLOCK_HAS_COPY_DISPOSE; - Name = ND->getNameAsString(); - ByrefType.clear(); - RewriteByRefString(ByrefType, Name, ND); - std::string ForwardingCastType("("); - ForwardingCastType += ByrefType + " *)"; - if (!hasInit) { - ByrefType += " " + Name + " = {(void*)"; - ByrefType += utostr(isa); - ByrefType += "," + ForwardingCastType + "&" + Name + ", "; - ByrefType += utostr(flags); - ByrefType += ", "; - ByrefType += "sizeof("; - RewriteByRefString(ByrefType, Name, ND); - ByrefType += ")"; - if (HasCopyAndDispose) { - ByrefType += ", __Block_byref_id_object_copy_"; - ByrefType += utostr(flag); - ByrefType += ", __Block_byref_id_object_dispose_"; - ByrefType += utostr(flag); - } - ByrefType += "};\n"; - unsigned nameSize = Name.size(); - // for block or function pointer declaration. Name is already - // part of the declaration. - if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) - nameSize = 1; - ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType); - } - else { - SourceLocation startLoc; - Expr *E = ND->getInit(); - if (const CStyleCastExpr *ECE = dyn_cast(E)) - startLoc = ECE->getLParenLoc(); - else - startLoc = E->getBeginLoc(); - startLoc = SM->getExpansionLoc(startLoc); - endBuf = SM->getCharacterData(startLoc); - ByrefType += " " + Name; - ByrefType += " = {(void*)"; - ByrefType += utostr(isa); - ByrefType += "," + ForwardingCastType + "&" + Name + ", "; - ByrefType += utostr(flags); - ByrefType += ", "; - ByrefType += "sizeof("; - RewriteByRefString(ByrefType, Name, ND); - ByrefType += "), "; - if (HasCopyAndDispose) { - ByrefType += "__Block_byref_id_object_copy_"; - ByrefType += utostr(flag); - ByrefType += ", __Block_byref_id_object_dispose_"; - ByrefType += utostr(flag); - ByrefType += ", "; - } - ReplaceText(DeclLoc, endBuf-startBuf, ByrefType); - - // Complete the newly synthesized compound expression by inserting a right - // curly brace before the end of the declaration. - // FIXME: This approach avoids rewriting the initializer expression. It - // also assumes there is only one declarator. For example, the following - // isn't currently supported by this routine (in general): - // - // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37; - // - const char *startInitializerBuf = SM->getCharacterData(startLoc); - const char *semiBuf = strchr(startInitializerBuf, ';'); - assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'"); - SourceLocation semiLoc = - startLoc.getLocWithOffset(semiBuf-startInitializerBuf); - - InsertText(semiLoc, "}"); - } -} - -void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { - // Add initializers for any closure decl refs. - GetBlockDeclRefExprs(Exp->getBody()); - if (BlockDeclRefs.size()) { - // Unique all "by copy" declarations. - for (unsigned i = 0; i < BlockDeclRefs.size(); i++) - if (!BlockDeclRefs[i]->getDecl()->hasAttr()) - BlockByCopyDecls.insert(BlockDeclRefs[i]->getDecl()); - // Unique all "by ref" declarations. - for (unsigned i = 0; i < BlockDeclRefs.size(); i++) - if (BlockDeclRefs[i]->getDecl()->hasAttr()) - BlockByRefDecls.insert(BlockDeclRefs[i]->getDecl()); - // Find any imported blocks...they will need special attention. - for (unsigned i = 0; i < BlockDeclRefs.size(); i++) - if (BlockDeclRefs[i]->getDecl()->hasAttr() || - BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || - BlockDeclRefs[i]->getType()->isBlockPointerType()) - ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl()); - } -} - -FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) { - IdentifierInfo *ID = &Context->Idents.get(name); - QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); - return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), - SourceLocation(), ID, FType, nullptr, SC_Extern, - false, false); -} - -Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, - const SmallVectorImpl &InnerBlockDeclRefs) { - const BlockDecl *block = Exp->getBlockDecl(); - Blocks.push_back(Exp); - - CollectBlockDeclRefInfo(Exp); - - // Add inner imported variables now used in current block. - int countOfInnerDecls = 0; - if (!InnerBlockDeclRefs.empty()) { - for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { - DeclRefExpr *Exp = InnerBlockDeclRefs[i]; - ValueDecl *VD = Exp->getDecl(); - if (!VD->hasAttr() && BlockByCopyDecls.insert(VD)) { - // We need to save the copied-in variables in nested - // blocks because it is needed at the end for some of the API - // generations. See SynthesizeBlockLiterals routine. - InnerDeclRefs.push_back(Exp); - countOfInnerDecls++; - BlockDeclRefs.push_back(Exp); - } - if (VD->hasAttr() && BlockByRefDecls.insert(VD)) { - InnerDeclRefs.push_back(Exp); - countOfInnerDecls++; - BlockDeclRefs.push_back(Exp); - } - } - // Find any imported blocks...they will need special attention. - for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) - if (InnerBlockDeclRefs[i]->getDecl()->hasAttr() || - InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || - InnerBlockDeclRefs[i]->getType()->isBlockPointerType()) - ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl()); - } - InnerDeclRefsCount.push_back(countOfInnerDecls); - - std::string FuncName; - - if (CurFunctionDef) - FuncName = CurFunctionDef->getNameAsString(); - else if (CurMethodDef) - BuildUniqueMethodName(FuncName, CurMethodDef); - else if (GlobalVarDecl) - FuncName = std::string(GlobalVarDecl->getNameAsString()); - - std::string BlockNumber = utostr(Blocks.size()-1); - - std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber; - std::string Func = "__" + FuncName + "_block_func_" + BlockNumber; - - // Get a pointer to the function type so we can cast appropriately. - QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType()); - QualType FType = Context->getPointerType(BFT); - - FunctionDecl *FD; - Expr *NewRep; - - // Simulate a constructor call... - FD = SynthBlockInitFunctionDecl(Tag); - DeclRefExpr *DRE = new (Context) - DeclRefExpr(*Context, FD, false, FType, VK_PRValue, SourceLocation()); - - SmallVector InitExprs; - - // Initialize the block function. - FD = SynthBlockInitFunctionDecl(Func); - DeclRefExpr *Arg = new (Context) DeclRefExpr( - *Context, FD, false, FD->getType(), VK_LValue, SourceLocation()); - CastExpr *castExpr = - NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, CK_BitCast, Arg); - InitExprs.push_back(castExpr); - - // Initialize the block descriptor. - std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA"; - - VarDecl *NewVD = VarDecl::Create( - *Context, TUDecl, SourceLocation(), SourceLocation(), - &Context->Idents.get(DescData), Context->VoidPtrTy, nullptr, SC_Static); - UnaryOperator *DescRefExpr = UnaryOperator::Create( - const_cast(*Context), - new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy, - VK_LValue, SourceLocation()), - UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_PRValue, - OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); - InitExprs.push_back(DescRefExpr); - - // Add initializers for any closure decl refs. - if (BlockDeclRefs.size()) { - Expr *Exp; - // Output all "by copy" declarations. - for (auto I = BlockByCopyDecls.begin(), E = BlockByCopyDecls.end(); I != E; - ++I) { - if (isObjCType((*I)->getType())) { - // FIXME: Conform to ABI ([[obj retain] autorelease]). - FD = SynthBlockInitFunctionDecl((*I)->getName()); - Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(), - VK_LValue, SourceLocation()); - if (HasLocalVariableExternalStorage(*I)) { - QualType QT = (*I)->getType(); - QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_PRValue, OK_Ordinary, - SourceLocation(), false, - FPOptionsOverride()); - } - } else if (isTopLevelBlockPointerType((*I)->getType())) { - FD = SynthBlockInitFunctionDecl((*I)->getName()); - Arg = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(), - VK_LValue, SourceLocation()); - Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, CK_BitCast, - Arg); - } else { - FD = SynthBlockInitFunctionDecl((*I)->getName()); - Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(), - VK_LValue, SourceLocation()); - if (HasLocalVariableExternalStorage(*I)) { - QualType QT = (*I)->getType(); - QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_PRValue, OK_Ordinary, - SourceLocation(), false, - FPOptionsOverride()); - } - } - InitExprs.push_back(Exp); - } - // Output all "by ref" declarations. - for (auto I = BlockByRefDecls.begin(), E = BlockByRefDecls.end(); I != E; - ++I) { - ValueDecl *ND = (*I); - std::string Name(ND->getNameAsString()); - std::string RecName; - RewriteByRefString(RecName, Name, ND, true); - IdentifierInfo *II = &Context->Idents.get(RecName.c_str() - + sizeof("struct")); - RecordDecl *RD = - RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl, - SourceLocation(), SourceLocation(), II); - assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); - QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); - - FD = SynthBlockInitFunctionDecl((*I)->getName()); - Exp = new (Context) DeclRefExpr(*Context, FD, false, FD->getType(), - VK_LValue, SourceLocation()); - bool isNestedCapturedVar = false; - if (block) - for (const auto &CI : block->captures()) { - const VarDecl *variable = CI.getVariable(); - if (variable == ND && CI.isNested()) { - assert (CI.isByRef() && - "SynthBlockInitExpr - captured block variable is not byref"); - isNestedCapturedVar = true; - break; - } - } - // captured nested byref variable has its address passed. Do not take - // its address again. - if (!isNestedCapturedVar) - Exp = UnaryOperator::Create( - const_cast(*Context), Exp, UO_AddrOf, - Context->getPointerType(Exp->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); - InitExprs.push_back(Exp); - } - } - if (ImportedBlockDecls.size()) { - // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR - int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR); - unsigned IntSize = - static_cast(Context->getTypeSize(Context->IntTy)); - Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), - Context->IntTy, SourceLocation()); - InitExprs.push_back(FlagExp); - } - NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue, - SourceLocation(), FPOptionsOverride()); - NewRep = UnaryOperator::Create( - const_cast(*Context), NewRep, UO_AddrOf, - Context->getPointerType(NewRep->getType()), VK_PRValue, OK_Ordinary, - SourceLocation(), false, FPOptionsOverride()); - NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, - NewRep); - BlockDeclRefs.clear(); - BlockByRefDecls.clear(); - BlockByCopyDecls.clear(); - ImportedBlockDecls.clear(); - return NewRep; -} - -bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) { - if (const ObjCForCollectionStmt * CS = - dyn_cast(Stmts.back())) - return CS->getElement() == DS; - return false; -} - -//===----------------------------------------------------------------------===// -// Function Body / Expression rewriting -//===----------------------------------------------------------------------===// - -Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { - if (isa(S) || isa(S) || - isa(S) || isa(S)) - Stmts.push_back(S); - else if (isa(S)) { - Stmts.push_back(S); - ObjCBcLabelNo.push_back(++BcLabelCount); - } - - // Pseudo-object operations and ivar references need special - // treatment because we're going to recursively rewrite them. - if (PseudoObjectExpr *PseudoOp = dyn_cast(S)) { - if (isa(PseudoOp->getSyntacticForm())) { - return RewritePropertyOrImplicitSetter(PseudoOp); - } else { - return RewritePropertyOrImplicitGetter(PseudoOp); - } - } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast(S)) { - return RewriteObjCIvarRefExpr(IvarRefExpr); - } - - SourceRange OrigStmtRange = S->getSourceRange(); - - // Perform a bottom up rewrite of all children. - for (Stmt *&childStmt : S->children()) - if (childStmt) { - Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt); - if (newStmt) { - childStmt = newStmt; - } - } - - if (BlockExpr *BE = dyn_cast(S)) { - SmallVector InnerBlockDeclRefs; - llvm::SmallPtrSet InnerContexts; - InnerContexts.insert(BE->getBlockDecl()); - ImportedLocalExternalDecls.clear(); - GetInnerBlockDeclRefExprs(BE->getBody(), - InnerBlockDeclRefs, InnerContexts); - // Rewrite the block body in place. - Stmt *SaveCurrentBody = CurrentBody; - CurrentBody = BE->getBody(); - PropParentMap = nullptr; - // block literal on rhs of a property-dot-sytax assignment - // must be replaced by its synthesize ast so getRewrittenText - // works as expected. In this case, what actually ends up on RHS - // is the blockTranscribed which is the helper function for the - // block literal; as in: self.c = ^() {[ace ARR];}; - bool saveDisableReplaceStmt = DisableReplaceStmt; - DisableReplaceStmt = false; - RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); - DisableReplaceStmt = saveDisableReplaceStmt; - CurrentBody = SaveCurrentBody; - PropParentMap = nullptr; - ImportedLocalExternalDecls.clear(); - // Now we snarf the rewritten text and stash it away for later use. - std::string Str = Rewrite.getRewrittenText(BE->getSourceRange()); - RewrittenBlockExprs[BE] = Str; - - Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); - - //blockTranscribed->dump(); - ReplaceStmt(S, blockTranscribed); - return blockTranscribed; - } - // Handle specific things. - if (ObjCEncodeExpr *AtEncode = dyn_cast(S)) - return RewriteAtEncode(AtEncode); - - if (ObjCSelectorExpr *AtSelector = dyn_cast(S)) - return RewriteAtSelector(AtSelector); - - if (ObjCStringLiteral *AtString = dyn_cast(S)) - return RewriteObjCStringLiteral(AtString); - - if (ObjCMessageExpr *MessExpr = dyn_cast(S)) { -#if 0 - // Before we rewrite it, put the original message expression in a comment. - SourceLocation startLoc = MessExpr->getBeginLoc(); - SourceLocation endLoc = MessExpr->getEndLoc(); - - const char *startBuf = SM->getCharacterData(startLoc); - const char *endBuf = SM->getCharacterData(endLoc); - - std::string messString; - messString += "// "; - messString.append(startBuf, endBuf-startBuf+1); - messString += "\n"; - - // FIXME: Missing definition of - // InsertText(clang::SourceLocation, char const*, unsigned int). - // InsertText(startLoc, messString); - // Tried this, but it didn't work either... - // ReplaceText(startLoc, 0, messString.c_str(), messString.size()); -#endif - return RewriteMessageExpr(MessExpr); - } - - if (ObjCAtTryStmt *StmtTry = dyn_cast(S)) - return RewriteObjCTryStmt(StmtTry); - - if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast(S)) - return RewriteObjCSynchronizedStmt(StmtTry); - - if (ObjCAtThrowStmt *StmtThrow = dyn_cast(S)) - return RewriteObjCThrowStmt(StmtThrow); - - if (ObjCProtocolExpr *ProtocolExp = dyn_cast(S)) - return RewriteObjCProtocolExpr(ProtocolExp); - - if (ObjCForCollectionStmt *StmtForCollection = - dyn_cast(S)) - return RewriteObjCForCollectionStmt(StmtForCollection, - OrigStmtRange.getEnd()); - if (BreakStmt *StmtBreakStmt = - dyn_cast(S)) - return RewriteBreakStmt(StmtBreakStmt); - if (ContinueStmt *StmtContinueStmt = - dyn_cast(S)) - return RewriteContinueStmt(StmtContinueStmt); - - // Need to check for protocol refs (id

, Foo

*) in variable decls - // and cast exprs. - if (DeclStmt *DS = dyn_cast(S)) { - // FIXME: What we're doing here is modifying the type-specifier that - // precedes the first Decl. In the future the DeclGroup should have - // a separate type-specifier that we can rewrite. - // NOTE: We need to avoid rewriting the DeclStmt if it is within - // the context of an ObjCForCollectionStmt. For example: - // NSArray *someArray; - // for (id index in someArray) ; - // This is because RewriteObjCForCollectionStmt() does textual rewriting - // and it depends on the original text locations/positions. - if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS)) - RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin()); - - // Blocks rewrite rules. - for (auto *SD : DS->decls()) { - if (ValueDecl *ND = dyn_cast(SD)) { - if (isTopLevelBlockPointerType(ND->getType())) - RewriteBlockPointerDecl(ND); - else if (ND->getType()->isFunctionPointerType()) - CheckFunctionPointerDecl(ND->getType(), ND); - if (VarDecl *VD = dyn_cast(SD)) { - if (VD->hasAttr()) { - static unsigned uniqueByrefDeclCount = 0; - assert(!BlockByRefDeclNo.count(ND) && - "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl"); - BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; - RewriteByRefVar(VD); - } - else - RewriteTypeOfDecl(VD); - } - } - if (TypedefNameDecl *TD = dyn_cast(SD)) { - if (isTopLevelBlockPointerType(TD->getUnderlyingType())) - RewriteBlockPointerDecl(TD); - else if (TD->getUnderlyingType()->isFunctionPointerType()) - CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); - } - } - } - - if (CStyleCastExpr *CE = dyn_cast(S)) - RewriteObjCQualifiedInterfaceTypes(CE); - - if (isa(S) || isa(S) || - isa(S) || isa(S)) { - assert(!Stmts.empty() && "Statement stack is empty"); - assert ((isa(Stmts.back()) || isa(Stmts.back()) || - isa(Stmts.back()) || isa(Stmts.back())) - && "Statement stack mismatch"); - Stmts.pop_back(); - } - // Handle blocks rewriting. - if (DeclRefExpr *DRE = dyn_cast(S)) { - ValueDecl *VD = DRE->getDecl(); - if (VD->hasAttr()) - return RewriteBlockDeclRefExpr(DRE); - if (HasLocalVariableExternalStorage(VD)) - return RewriteLocalVariableExternalStorage(DRE); - } - - if (CallExpr *CE = dyn_cast(S)) { - if (CE->getCallee()->getType()->isBlockPointerType()) { - Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee()); - ReplaceStmt(S, BlockCall); - return BlockCall; - } - } - if (CStyleCastExpr *CE = dyn_cast(S)) { - RewriteCastExpr(CE); - } -#if 0 - if (ImplicitCastExpr *ICE = dyn_cast(S)) { - CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), - ICE->getSubExpr(), - SourceLocation()); - // Get the new text. - std::string SStr; - llvm::raw_string_ostream Buf(SStr); - Replacement->printPretty(Buf); - const std::string &Str = Buf.str(); - - printf("CAST = %s\n", &Str[0]); - InsertText(ICE->getSubExpr()->getBeginLoc(), Str); - delete S; - return Replacement; - } -#endif - // Return this stmt unmodified. - return S; -} - -void RewriteObjC::RewriteRecordBody(RecordDecl *RD) { - for (auto *FD : RD->fields()) { - if (isTopLevelBlockPointerType(FD->getType())) - RewriteBlockPointerDecl(FD); - if (FD->getType()->isObjCQualifiedIdType() || - FD->getType()->isObjCQualifiedInterfaceType()) - RewriteObjCQualifiedInterfaceTypes(FD); - } -} - -/// HandleDeclInMainFile - This is called for each top-level decl defined in the -/// main file of the input. -void RewriteObjC::HandleDeclInMainFile(Decl *D) { - switch (D->getKind()) { - case Decl::Function: { - FunctionDecl *FD = cast(D); - if (FD->isOverloadedOperator()) - return; - - // Since function prototypes don't have ParmDecl's, we check the function - // prototype. This enables us to rewrite function declarations and - // definitions using the same code. - RewriteBlocksInFunctionProtoType(FD->getType(), FD); - - if (!FD->isThisDeclarationADefinition()) - break; - - // FIXME: If this should support Obj-C++, support CXXTryStmt - if (CompoundStmt *Body = dyn_cast_or_null(FD->getBody())) { - CurFunctionDef = FD; - CurFunctionDeclToDeclareForBlock = FD; - CurrentBody = Body; - Body = - cast_or_null(RewriteFunctionBodyOrGlobalInitializer(Body)); - FD->setBody(Body); - CurrentBody = nullptr; - if (PropParentMap) { - delete PropParentMap; - PropParentMap = nullptr; - } - // This synthesizes and inserts the block "impl" struct, invoke function, - // and any copy/dispose helper functions. - InsertBlockLiteralsWithinFunction(FD); - CurFunctionDef = nullptr; - CurFunctionDeclToDeclareForBlock = nullptr; - } - break; - } - case Decl::ObjCMethod: { - ObjCMethodDecl *MD = cast(D); - if (CompoundStmt *Body = MD->getCompoundBody()) { - CurMethodDef = MD; - CurrentBody = Body; - Body = - cast_or_null(RewriteFunctionBodyOrGlobalInitializer(Body)); - MD->setBody(Body); - CurrentBody = nullptr; - if (PropParentMap) { - delete PropParentMap; - PropParentMap = nullptr; - } - InsertBlockLiteralsWithinMethod(MD); - CurMethodDef = nullptr; - } - break; - } - case Decl::ObjCImplementation: { - ObjCImplementationDecl *CI = cast(D); - ClassImplementation.push_back(CI); - break; - } - case Decl::ObjCCategoryImpl: { - ObjCCategoryImplDecl *CI = cast(D); - CategoryImplementation.push_back(CI); - break; - } - case Decl::Var: { - VarDecl *VD = cast(D); - RewriteObjCQualifiedInterfaceTypes(VD); - if (isTopLevelBlockPointerType(VD->getType())) - RewriteBlockPointerDecl(VD); - else if (VD->getType()->isFunctionPointerType()) { - CheckFunctionPointerDecl(VD->getType(), VD); - if (VD->getInit()) { - if (CStyleCastExpr *CE = dyn_cast(VD->getInit())) { - RewriteCastExpr(CE); - } - } - } else if (VD->getType()->isRecordType()) { - RecordDecl *RD = VD->getType()->castAs()->getDecl(); - if (RD->isCompleteDefinition()) - RewriteRecordBody(RD); - } - if (VD->getInit()) { - GlobalVarDecl = VD; - CurrentBody = VD->getInit(); - RewriteFunctionBodyOrGlobalInitializer(VD->getInit()); - CurrentBody = nullptr; - if (PropParentMap) { - delete PropParentMap; - PropParentMap = nullptr; - } - SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName()); - GlobalVarDecl = nullptr; - - // This is needed for blocks. - if (CStyleCastExpr *CE = dyn_cast(VD->getInit())) { - RewriteCastExpr(CE); - } - } - break; - } - case Decl::TypeAlias: - case Decl::Typedef: { - if (TypedefNameDecl *TD = dyn_cast(D)) { - if (isTopLevelBlockPointerType(TD->getUnderlyingType())) - RewriteBlockPointerDecl(TD); - else if (TD->getUnderlyingType()->isFunctionPointerType()) - CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); - } - break; - } - case Decl::CXXRecord: - case Decl::Record: { - RecordDecl *RD = cast(D); - if (RD->isCompleteDefinition()) - RewriteRecordBody(RD); - break; - } - default: - break; - } - // Nothing yet. -} - -void RewriteObjC::HandleTranslationUnit(ASTContext &C) { - if (Diags.hasErrorOccurred()) - return; - - RewriteInclude(); - - // Here's a great place to add any extra declarations that may be needed. - // Write out meta data for each @protocol(). - for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) - RewriteObjCProtocolMetaData(ProtDecl, "", "", Preamble); - - InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); - if (ClassImplementation.size() || CategoryImplementation.size()) - RewriteImplementations(); - - // Get the buffer corresponding to MainFileID. If we haven't changed it, then - // we are done. - if (const RewriteBuffer *RewriteBuf = - Rewrite.getRewriteBufferFor(MainFileID)) { - //printf("Changed:\n"); - *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); - } else { - llvm::errs() << "No changes\n"; - } - - if (ClassImplementation.size() || CategoryImplementation.size() || - ProtocolExprDecls.size()) { - // Rewrite Objective-c meta data* - std::string ResultStr; - RewriteMetaDataIntoBuffer(ResultStr); - // Emit metadata. - *OutFile << ResultStr; - } - OutFile->flush(); -} - -void RewriteObjCFragileABI::Initialize(ASTContext &context) { - InitializeCommon(context); - - // declaring objc_selector outside the parameter list removes a silly - // scope related warning... - if (IsHeader) - Preamble = "#pragma once\n"; - Preamble += "struct objc_selector; struct objc_class;\n"; - Preamble += "struct __rw_objc_super { struct objc_object *object; "; - Preamble += "struct objc_object *superClass; "; - if (LangOpts.MicrosoftExt) { - // Add a constructor for creating temporary objects. - Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) " - ": "; - Preamble += "object(o), superClass(s) {} "; - } - Preamble += "};\n"; - Preamble += "#ifndef _REWRITER_typedef_Protocol\n"; - Preamble += "typedef struct objc_object Protocol;\n"; - Preamble += "#define _REWRITER_typedef_Protocol\n"; - Preamble += "#endif\n"; - if (LangOpts.MicrosoftExt) { - Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n"; - Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n"; - } else - Preamble += "#define __OBJC_RW_DLLIMPORT extern\n"; - Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend"; - Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; - Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper"; - Preamble += "(struct objc_super *, struct objc_selector *, ...);\n"; - Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSend_stret"; - Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; - Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSendSuper_stret"; - Preamble += "(struct objc_super *, struct objc_selector *, ...);\n"; - Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret"; - Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; - Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass"; - Preamble += "(const char *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass"; - Preamble += "(struct objc_class *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass"; - Preamble += "(const char *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match"; - Preamble += "(struct objc_class *, struct objc_object *);\n"; - // @synchronized hooks. - Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter(struct objc_object *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit(struct objc_object *);\n"; - Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n"; - Preamble += "#ifndef __FASTENUMERATIONSTATE\n"; - Preamble += "struct __objcFastEnumerationState {\n\t"; - Preamble += "unsigned long state;\n\t"; - Preamble += "void **itemsPtr;\n\t"; - Preamble += "unsigned long *mutationsPtr;\n\t"; - Preamble += "unsigned long extra[5];\n};\n"; - Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n"; - Preamble += "#define __FASTENUMERATIONSTATE\n"; - Preamble += "#endif\n"; - Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n"; - Preamble += "struct __NSConstantStringImpl {\n"; - Preamble += " int *isa;\n"; - Preamble += " int flags;\n"; - Preamble += " char *str;\n"; - Preamble += " long length;\n"; - Preamble += "};\n"; - Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n"; - Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n"; - Preamble += "#else\n"; - Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n"; - Preamble += "#endif\n"; - Preamble += "#define __NSCONSTANTSTRINGIMPL\n"; - Preamble += "#endif\n"; - // Blocks preamble. - Preamble += "#ifndef BLOCK_IMPL\n"; - Preamble += "#define BLOCK_IMPL\n"; - Preamble += "struct __block_impl {\n"; - Preamble += " void *isa;\n"; - Preamble += " int Flags;\n"; - Preamble += " int Reserved;\n"; - Preamble += " void *FuncPtr;\n"; - Preamble += "};\n"; - Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n"; - Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n"; - Preamble += "extern \"C\" __declspec(dllexport) " - "void _Block_object_assign(void *, const void *, const int);\n"; - Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n"; - Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n"; - Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n"; - Preamble += "#else\n"; - Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n"; - Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n"; - Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n"; - Preamble += "#endif\n"; - Preamble += "#endif\n"; - if (LangOpts.MicrosoftExt) { - Preamble += "#undef __OBJC_RW_DLLIMPORT\n"; - Preamble += "#undef __OBJC_RW_STATICIMPORT\n"; - Preamble += "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests. - Preamble += "#define __attribute__(X)\n"; - Preamble += "#endif\n"; - Preamble += "#define __weak\n"; - } - else { - Preamble += "#define __block\n"; - Preamble += "#define __weak\n"; - } - // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long - // as this avoids warning in any 64bit/32bit compilation model. - Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n"; -} - -/// RewriteIvarOffsetComputation - This routine synthesizes computation of -/// ivar offset. -void RewriteObjCFragileABI::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, - std::string &Result) { - if (ivar->isBitField()) { - // FIXME: The hack below doesn't work for bitfields. For now, we simply - // place all bitfields at offset 0. - Result += "0"; - } else { - Result += "__OFFSETOFIVAR__(struct "; - Result += ivar->getContainingInterface()->getNameAsString(); - if (LangOpts.MicrosoftExt) - Result += "_IMPL"; - Result += ", "; - Result += ivar->getNameAsString(); - Result += ")"; - } -} - -/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data. -void RewriteObjCFragileABI::RewriteObjCProtocolMetaData( - ObjCProtocolDecl *PDecl, StringRef prefix, - StringRef ClassName, std::string &Result) { - static bool objc_protocol_methods = false; - - // Output struct protocol_methods holder of method selector and type. - if (!objc_protocol_methods && PDecl->hasDefinition()) { - /* struct protocol_methods { - SEL _cmd; - char *method_types; - } - */ - Result += "\nstruct _protocol_methods {\n"; - Result += "\tstruct objc_selector *_cmd;\n"; - Result += "\tchar *method_types;\n"; - Result += "};\n"; - - objc_protocol_methods = true; - } - // Do not synthesize the protocol more than once. - if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl())) - return; - - if (ObjCProtocolDecl *Def = PDecl->getDefinition()) - PDecl = Def; - - if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { - unsigned NumMethods = std::distance(PDecl->instmeth_begin(), - PDecl->instmeth_end()); - /* struct _objc_protocol_method_list { - int protocol_method_count; - struct protocol_methods protocols[]; - } - */ - Result += "\nstatic struct {\n"; - Result += "\tint protocol_method_count;\n"; - Result += "\tstruct _protocol_methods protocol_methods["; - Result += utostr(NumMethods); - Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_"; - Result += PDecl->getNameAsString(); - Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= " - "{\n\t" + utostr(NumMethods) + "\n"; - - // Output instance methods declared in this protocol. - for (ObjCProtocolDecl::instmeth_iterator - I = PDecl->instmeth_begin(), E = PDecl->instmeth_end(); - I != E; ++I) { - if (I == PDecl->instmeth_begin()) - Result += "\t ,{{(struct objc_selector *)\""; - else - Result += "\t ,{(struct objc_selector *)\""; - Result += (*I)->getSelector().getAsString(); - std::string MethodTypeString = Context->getObjCEncodingForMethodDecl(*I); - Result += "\", \""; - Result += MethodTypeString; - Result += "\"}\n"; - } - Result += "\t }\n};\n"; - } - - // Output class methods declared in this protocol. - unsigned NumMethods = std::distance(PDecl->classmeth_begin(), - PDecl->classmeth_end()); - if (NumMethods > 0) { - /* struct _objc_protocol_method_list { - int protocol_method_count; - struct protocol_methods protocols[]; - } - */ - Result += "\nstatic struct {\n"; - Result += "\tint protocol_method_count;\n"; - Result += "\tstruct _protocol_methods protocol_methods["; - Result += utostr(NumMethods); - Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_"; - Result += PDecl->getNameAsString(); - Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " - "{\n\t"; - Result += utostr(NumMethods); - Result += "\n"; - - // Output instance methods declared in this protocol. - for (ObjCProtocolDecl::classmeth_iterator - I = PDecl->classmeth_begin(), E = PDecl->classmeth_end(); - I != E; ++I) { - if (I == PDecl->classmeth_begin()) - Result += "\t ,{{(struct objc_selector *)\""; - else - Result += "\t ,{(struct objc_selector *)\""; - Result += (*I)->getSelector().getAsString(); - std::string MethodTypeString = Context->getObjCEncodingForMethodDecl(*I); - Result += "\", \""; - Result += MethodTypeString; - Result += "\"}\n"; - } - Result += "\t }\n};\n"; - } - - // Output: - /* struct _objc_protocol { - // Objective-C 1.0 extensions - struct _objc_protocol_extension *isa; - char *protocol_name; - struct _objc_protocol **protocol_list; - struct _objc_protocol_method_list *instance_methods; - struct _objc_protocol_method_list *class_methods; - }; - */ - static bool objc_protocol = false; - if (!objc_protocol) { - Result += "\nstruct _objc_protocol {\n"; - Result += "\tstruct _objc_protocol_extension *isa;\n"; - Result += "\tchar *protocol_name;\n"; - Result += "\tstruct _objc_protocol **protocol_list;\n"; - Result += "\tstruct _objc_protocol_method_list *instance_methods;\n"; - Result += "\tstruct _objc_protocol_method_list *class_methods;\n"; - Result += "};\n"; - - objc_protocol = true; - } - - Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_"; - Result += PDecl->getNameAsString(); - Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= " - "{\n\t0, \""; - Result += PDecl->getNameAsString(); - Result += "\", 0, "; - if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { - Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; - Result += PDecl->getNameAsString(); - Result += ", "; - } - else - Result += "0, "; - if (PDecl->classmeth_begin() != PDecl->classmeth_end()) { - Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_"; - Result += PDecl->getNameAsString(); - Result += "\n"; - } - else - Result += "0\n"; - Result += "};\n"; - - // Mark this protocol as having been generated. - if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()).second) - llvm_unreachable("protocol already synthesized"); -} - -void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData( - const ObjCList &Protocols, - StringRef prefix, StringRef ClassName, - std::string &Result) { - if (Protocols.empty()) return; - - for (unsigned i = 0; i != Protocols.size(); i++) - RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result); - - // Output the top lovel protocol meta-data for the class. - /* struct _objc_protocol_list { - struct _objc_protocol_list *next; - int protocol_count; - struct _objc_protocol *class_protocols[]; - } - */ - Result += "\nstatic struct {\n"; - Result += "\tstruct _objc_protocol_list *next;\n"; - Result += "\tint protocol_count;\n"; - Result += "\tstruct _objc_protocol *class_protocols["; - Result += utostr(Protocols.size()); - Result += "];\n} _OBJC_"; - Result += prefix; - Result += "_PROTOCOLS_"; - Result += ClassName; - Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " - "{\n\t0, "; - Result += utostr(Protocols.size()); - Result += "\n"; - - Result += "\t,{&_OBJC_PROTOCOL_"; - Result += Protocols[0]->getNameAsString(); - Result += " \n"; - - for (unsigned i = 1; i != Protocols.size(); i++) { - Result += "\t ,&_OBJC_PROTOCOL_"; - Result += Protocols[i]->getNameAsString(); - Result += "\n"; - } - Result += "\t }\n};\n"; -} - -void RewriteObjCFragileABI::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, - std::string &Result) { - ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); - - // Explicitly declared @interface's are already synthesized. - if (CDecl->isImplicitInterfaceDecl()) { - // FIXME: Implementation of a class with no @interface (legacy) does not - // produce correct synthesis as yet. - RewriteObjCInternalStruct(CDecl, Result); - } - - // Build _objc_ivar_list metadata for classes ivars if needed - unsigned NumIvars = - !IDecl->ivar_empty() ? IDecl->ivar_size() : CDecl->ivar_size(); - if (NumIvars > 0) { - static bool objc_ivar = false; - if (!objc_ivar) { - /* struct _objc_ivar { - char *ivar_name; - char *ivar_type; - int ivar_offset; - }; - */ - Result += "\nstruct _objc_ivar {\n"; - Result += "\tchar *ivar_name;\n"; - Result += "\tchar *ivar_type;\n"; - Result += "\tint ivar_offset;\n"; - Result += "};\n"; - - objc_ivar = true; - } - - /* struct { - int ivar_count; - struct _objc_ivar ivar_list[nIvars]; - }; - */ - Result += "\nstatic struct {\n"; - Result += "\tint ivar_count;\n"; - Result += "\tstruct _objc_ivar ivar_list["; - Result += utostr(NumIvars); - Result += "];\n} _OBJC_INSTANCE_VARIABLES_"; - Result += IDecl->getNameAsString(); - Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= " - "{\n\t"; - Result += utostr(NumIvars); - Result += "\n"; - - ObjCInterfaceDecl::ivar_iterator IVI, IVE; - SmallVector IVars; - if (!IDecl->ivar_empty()) { - for (auto *IV : IDecl->ivars()) - IVars.push_back(IV); - IVI = IDecl->ivar_begin(); - IVE = IDecl->ivar_end(); - } else { - IVI = CDecl->ivar_begin(); - IVE = CDecl->ivar_end(); - } - Result += "\t,{{\""; - Result += IVI->getNameAsString(); - Result += "\", \""; - std::string TmpString, StrEncoding; - Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI); - QuoteDoublequotes(TmpString, StrEncoding); - Result += StrEncoding; - Result += "\", "; - RewriteIvarOffsetComputation(*IVI, Result); - Result += "}\n"; - for (++IVI; IVI != IVE; ++IVI) { - Result += "\t ,{\""; - Result += IVI->getNameAsString(); - Result += "\", \""; - std::string TmpString, StrEncoding; - Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI); - QuoteDoublequotes(TmpString, StrEncoding); - Result += StrEncoding; - Result += "\", "; - RewriteIvarOffsetComputation(*IVI, Result); - Result += "}\n"; - } - - Result += "\t }\n};\n"; - } - - // Build _objc_method_list for class's instance methods if needed - SmallVector InstanceMethods(IDecl->instance_methods()); - - // If any of our property implementations have associated getters or - // setters, produce metadata for them as well. - for (const auto *Prop : IDecl->property_impls()) { - if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) - continue; - if (!Prop->getPropertyIvarDecl()) - continue; - ObjCPropertyDecl *PD = Prop->getPropertyDecl(); - if (!PD) - continue; - if (ObjCMethodDecl *Getter = Prop->getGetterMethodDecl()) - if (!Getter->isDefined()) - InstanceMethods.push_back(Getter); - if (PD->isReadOnly()) - continue; - if (ObjCMethodDecl *Setter = Prop->getSetterMethodDecl()) - if (!Setter->isDefined()) - InstanceMethods.push_back(Setter); - } - RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), - true, "", IDecl->getName(), Result); - - // Build _objc_method_list for class's class methods if needed - RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), - false, "", IDecl->getName(), Result); - - // Protocols referenced in class declaration? - RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), - "CLASS", CDecl->getName(), Result); - - // Declaration of class/meta-class metadata - /* struct _objc_class { - struct _objc_class *isa; // or const char *root_class_name when metadata - const char *super_class_name; - char *name; - long version; - long info; - long instance_size; - struct _objc_ivar_list *ivars; - struct _objc_method_list *methods; - struct objc_cache *cache; - struct objc_protocol_list *protocols; - const char *ivar_layout; - struct _objc_class_ext *ext; - }; - */ - static bool objc_class = false; - if (!objc_class) { - Result += "\nstruct _objc_class {\n"; - Result += "\tstruct _objc_class *isa;\n"; - Result += "\tconst char *super_class_name;\n"; - Result += "\tchar *name;\n"; - Result += "\tlong version;\n"; - Result += "\tlong info;\n"; - Result += "\tlong instance_size;\n"; - Result += "\tstruct _objc_ivar_list *ivars;\n"; - Result += "\tstruct _objc_method_list *methods;\n"; - Result += "\tstruct objc_cache *cache;\n"; - Result += "\tstruct _objc_protocol_list *protocols;\n"; - Result += "\tconst char *ivar_layout;\n"; - Result += "\tstruct _objc_class_ext *ext;\n"; - Result += "};\n"; - objc_class = true; - } - - // Meta-class metadata generation. - ObjCInterfaceDecl *RootClass = nullptr; - ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass(); - while (SuperClass) { - RootClass = SuperClass; - SuperClass = SuperClass->getSuperClass(); - } - SuperClass = CDecl->getSuperClass(); - - Result += "\nstatic struct _objc_class _OBJC_METACLASS_"; - Result += CDecl->getNameAsString(); - Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= " - "{\n\t(struct _objc_class *)\""; - Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString()); - Result += "\""; - - if (SuperClass) { - Result += ", \""; - Result += SuperClass->getNameAsString(); - Result += "\", \""; - Result += CDecl->getNameAsString(); - Result += "\""; - } - else { - Result += ", 0, \""; - Result += CDecl->getNameAsString(); - Result += "\""; - } - // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it. - // 'info' field is initialized to CLS_META(2) for metaclass - Result += ", 0,2, sizeof(struct _objc_class), 0"; - if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { - Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_"; - Result += IDecl->getNameAsString(); - Result += "\n"; - } - else - Result += ", 0\n"; - if (CDecl->protocol_begin() != CDecl->protocol_end()) { - Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_"; - Result += CDecl->getNameAsString(); - Result += ",0,0\n"; - } - else - Result += "\t,0,0,0,0\n"; - Result += "};\n"; - - // class metadata generation. - Result += "\nstatic struct _objc_class _OBJC_CLASS_"; - Result += CDecl->getNameAsString(); - Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= " - "{\n\t&_OBJC_METACLASS_"; - Result += CDecl->getNameAsString(); - if (SuperClass) { - Result += ", \""; - Result += SuperClass->getNameAsString(); - Result += "\", \""; - Result += CDecl->getNameAsString(); - Result += "\""; - } - else { - Result += ", 0, \""; - Result += CDecl->getNameAsString(); - Result += "\""; - } - // 'info' field is initialized to CLS_CLASS(1) for class - Result += ", 0,1"; - if (!ObjCSynthesizedStructs.count(CDecl)) - Result += ",0"; - else { - // class has size. Must synthesize its size. - Result += ",sizeof(struct "; - Result += CDecl->getNameAsString(); - if (LangOpts.MicrosoftExt) - Result += "_IMPL"; - Result += ")"; - } - if (NumIvars > 0) { - Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_"; - Result += CDecl->getNameAsString(); - Result += "\n\t"; - } - else - Result += ",0"; - if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { - Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_"; - Result += CDecl->getNameAsString(); - Result += ", 0\n\t"; - } - else - Result += ",0,0"; - if (CDecl->protocol_begin() != CDecl->protocol_end()) { - Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_"; - Result += CDecl->getNameAsString(); - Result += ", 0,0\n"; - } - else - Result += ",0,0,0\n"; - Result += "};\n"; -} - -void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) { - int ClsDefCount = ClassImplementation.size(); - int CatDefCount = CategoryImplementation.size(); - - // For each implemented class, write out all its meta data. - for (int i = 0; i < ClsDefCount; i++) - RewriteObjCClassMetaData(ClassImplementation[i], Result); - - // For each implemented category, write out all its meta data. - for (int i = 0; i < CatDefCount; i++) - RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result); - - // Write objc_symtab metadata - /* - struct _objc_symtab - { - long sel_ref_cnt; - SEL *refs; - short cls_def_cnt; - short cat_def_cnt; - void *defs[cls_def_cnt + cat_def_cnt]; - }; - */ - - Result += "\nstruct _objc_symtab {\n"; - Result += "\tlong sel_ref_cnt;\n"; - Result += "\tSEL *refs;\n"; - Result += "\tshort cls_def_cnt;\n"; - Result += "\tshort cat_def_cnt;\n"; - Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n"; - Result += "};\n\n"; - - Result += "static struct _objc_symtab " - "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n"; - Result += "\t0, 0, " + utostr(ClsDefCount) - + ", " + utostr(CatDefCount) + "\n"; - for (int i = 0; i < ClsDefCount; i++) { - Result += "\t,&_OBJC_CLASS_"; - Result += ClassImplementation[i]->getNameAsString(); - Result += "\n"; - } - - for (int i = 0; i < CatDefCount; i++) { - Result += "\t,&_OBJC_CATEGORY_"; - Result += CategoryImplementation[i]->getClassInterface()->getNameAsString(); - Result += "_"; - Result += CategoryImplementation[i]->getNameAsString(); - Result += "\n"; - } - - Result += "};\n\n"; - - // Write objc_module metadata - - /* - struct _objc_module { - long version; - long size; - const char *name; - struct _objc_symtab *symtab; - } - */ - - Result += "\nstruct _objc_module {\n"; - Result += "\tlong version;\n"; - Result += "\tlong size;\n"; - Result += "\tconst char *name;\n"; - Result += "\tstruct _objc_symtab *symtab;\n"; - Result += "};\n\n"; - Result += "static struct _objc_module " - "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n"; - Result += "\t" + utostr(OBJC_ABI_VERSION) + - ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n"; - Result += "};\n\n"; - - if (LangOpts.MicrosoftExt) { - if (ProtocolExprDecls.size()) { - Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n"; - Result += "#pragma data_seg(push, \".objc_protocol$B\")\n"; - for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) { - Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_"; - Result += ProtDecl->getNameAsString(); - Result += " = &_OBJC_PROTOCOL_"; - Result += ProtDecl->getNameAsString(); - Result += ";\n"; - } - Result += "#pragma data_seg(pop)\n\n"; - } - Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n"; - Result += "#pragma data_seg(push, \".objc_module_info$B\")\n"; - Result += "static struct _objc_module *_POINTER_OBJC_MODULES = "; - Result += "&_OBJC_MODULES;\n"; - Result += "#pragma data_seg(pop)\n\n"; - } -} - -/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category -/// implementation. -void RewriteObjCFragileABI::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, - std::string &Result) { - ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); - // Find category declaration for this implementation. - ObjCCategoryDecl *CDecl - = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier()); - - std::string FullCategoryName = ClassDecl->getNameAsString(); - FullCategoryName += '_'; - FullCategoryName += IDecl->getNameAsString(); - - // Build _objc_method_list for class's instance methods if needed - SmallVector InstanceMethods(IDecl->instance_methods()); - - // If any of our property implementations have associated getters or - // setters, produce metadata for them as well. - for (const auto *Prop : IDecl->property_impls()) { - if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) - continue; - if (!Prop->getPropertyIvarDecl()) - continue; - ObjCPropertyDecl *PD = Prop->getPropertyDecl(); - if (!PD) - continue; - if (ObjCMethodDecl *Getter = Prop->getGetterMethodDecl()) - InstanceMethods.push_back(Getter); - if (PD->isReadOnly()) - continue; - if (ObjCMethodDecl *Setter = Prop->getSetterMethodDecl()) - InstanceMethods.push_back(Setter); - } - RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), - true, "CATEGORY_", FullCategoryName, Result); - - // Build _objc_method_list for class's class methods if needed - RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), - false, "CATEGORY_", FullCategoryName, Result); - - // Protocols referenced in class declaration? - // Null CDecl is case of a category implementation with no category interface - if (CDecl) - RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY", - FullCategoryName, Result); - /* struct _objc_category { - char *category_name; - char *class_name; - struct _objc_method_list *instance_methods; - struct _objc_method_list *class_methods; - struct _objc_protocol_list *protocols; - // Objective-C 1.0 extensions - uint32_t size; // sizeof (struct _objc_category) - struct _objc_property_list *instance_properties; // category's own - // @property decl. - }; - */ - - static bool objc_category = false; - if (!objc_category) { - Result += "\nstruct _objc_category {\n"; - Result += "\tchar *category_name;\n"; - Result += "\tchar *class_name;\n"; - Result += "\tstruct _objc_method_list *instance_methods;\n"; - Result += "\tstruct _objc_method_list *class_methods;\n"; - Result += "\tstruct _objc_protocol_list *protocols;\n"; - Result += "\tunsigned int size;\n"; - Result += "\tstruct _objc_property_list *instance_properties;\n"; - Result += "};\n"; - objc_category = true; - } - Result += "\nstatic struct _objc_category _OBJC_CATEGORY_"; - Result += FullCategoryName; - Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\""; - Result += IDecl->getNameAsString(); - Result += "\"\n\t, \""; - Result += ClassDecl->getNameAsString(); - Result += "\"\n"; - - if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { - Result += "\t, (struct _objc_method_list *)" - "&_OBJC_CATEGORY_INSTANCE_METHODS_"; - Result += FullCategoryName; - Result += "\n"; - } - else - Result += "\t, 0\n"; - if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { - Result += "\t, (struct _objc_method_list *)" - "&_OBJC_CATEGORY_CLASS_METHODS_"; - Result += FullCategoryName; - Result += "\n"; - } - else - Result += "\t, 0\n"; - - if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) { - Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_"; - Result += FullCategoryName; - Result += "\n"; - } - else - Result += "\t, 0\n"; - Result += "\t, sizeof(struct _objc_category), 0\n};\n"; -} - -// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or -/// class methods. -template -void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin, - MethodIterator MethodEnd, - bool IsInstanceMethod, - StringRef prefix, - StringRef ClassName, - std::string &Result) { - if (MethodBegin == MethodEnd) return; - - if (!objc_impl_method) { - /* struct _objc_method { - SEL _cmd; - char *method_types; - void *_imp; - } - */ - Result += "\nstruct _objc_method {\n"; - Result += "\tSEL _cmd;\n"; - Result += "\tchar *method_types;\n"; - Result += "\tvoid *_imp;\n"; - Result += "};\n"; - - objc_impl_method = true; - } - - // Build _objc_method_list for class's methods if needed - - /* struct { - struct _objc_method_list *next_method; - int method_count; - struct _objc_method method_list[]; - } - */ - unsigned NumMethods = std::distance(MethodBegin, MethodEnd); - Result += "\nstatic struct {\n"; - Result += "\tstruct _objc_method_list *next_method;\n"; - Result += "\tint method_count;\n"; - Result += "\tstruct _objc_method method_list["; - Result += utostr(NumMethods); - Result += "];\n} _OBJC_"; - Result += prefix; - Result += IsInstanceMethod ? "INSTANCE" : "CLASS"; - Result += "_METHODS_"; - Result += ClassName; - Result += " __attribute__ ((used, section (\"__OBJC, __"; - Result += IsInstanceMethod ? "inst" : "cls"; - Result += "_meth\")))= "; - Result += "{\n\t0, " + utostr(NumMethods) + "\n"; - - Result += "\t,{{(SEL)\""; - Result += (*MethodBegin)->getSelector().getAsString(); - std::string MethodTypeString = - Context->getObjCEncodingForMethodDecl(*MethodBegin); - Result += "\", \""; - Result += MethodTypeString; - Result += "\", (void *)"; - Result += MethodInternalNames[*MethodBegin]; - Result += "}\n"; - for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) { - Result += "\t ,{(SEL)\""; - Result += (*MethodBegin)->getSelector().getAsString(); - std::string MethodTypeString = - Context->getObjCEncodingForMethodDecl(*MethodBegin); - Result += "\", \""; - Result += MethodTypeString; - Result += "\", (void *)"; - Result += MethodInternalNames[*MethodBegin]; - Result += "}\n"; - } - Result += "\t }\n};\n"; -} - -Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { - SourceRange OldRange = IV->getSourceRange(); - Expr *BaseExpr = IV->getBase(); - - // Rewrite the base, but without actually doing replaces. - { - DisableReplaceStmtScope S(*this); - BaseExpr = cast(RewriteFunctionBodyOrGlobalInitializer(BaseExpr)); - IV->setBase(BaseExpr); - } - - ObjCIvarDecl *D = IV->getDecl(); - - Expr *Replacement = IV; - if (CurMethodDef) { - if (BaseExpr->getType()->isObjCObjectPointerType()) { - const ObjCInterfaceType *iFaceDecl = - dyn_cast(BaseExpr->getType()->getPointeeType()); - assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null"); - // lookup which class implements the instance variable. - ObjCInterfaceDecl *clsDeclared = nullptr; - iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), - clsDeclared); - assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); - - // Synthesize an explicit cast to gain access to the ivar. - std::string RecName = - std::string(clsDeclared->getIdentifier()->getName()); - RecName += "_IMPL"; - IdentifierInfo *II = &Context->Idents.get(RecName); - RecordDecl *RD = - RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl, - SourceLocation(), SourceLocation(), II); - assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); - QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); - CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, - CK_BitCast, - IV->getBase()); - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr(OldRange.getBegin(), - OldRange.getEnd(), - castExpr); - if (IV->isFreeIvar() && - declaresSameEntity(CurMethodDef->getClassInterface(), - iFaceDecl->getDecl())) { - MemberExpr *ME = MemberExpr::CreateImplicit( - *Context, PE, true, D, D->getType(), VK_LValue, OK_Ordinary); - Replacement = ME; - } else { - IV->setBase(PE); - } - } - } else { // we are outside a method. - assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method"); - - // Explicit ivar refs need to have a cast inserted. - // FIXME: consider sharing some of this code with the code above. - if (BaseExpr->getType()->isObjCObjectPointerType()) { - const ObjCInterfaceType *iFaceDecl = - dyn_cast(BaseExpr->getType()->getPointeeType()); - // lookup which class implements the instance variable. - ObjCInterfaceDecl *clsDeclared = nullptr; - iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), - clsDeclared); - assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); - - // Synthesize an explicit cast to gain access to the ivar. - std::string RecName = - std::string(clsDeclared->getIdentifier()->getName()); - RecName += "_IMPL"; - IdentifierInfo *II = &Context->Idents.get(RecName); - RecordDecl *RD = - RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl, - SourceLocation(), SourceLocation(), II); - assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); - QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); - CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, - CK_BitCast, - IV->getBase()); - // Don't forget the parens to enforce the proper binding. - ParenExpr *PE = new (Context) ParenExpr( - IV->getBase()->getBeginLoc(), IV->getBase()->getEndLoc(), castExpr); - // Cannot delete IV->getBase(), since PE points to it. - // Replace the old base with the cast. This is important when doing - // embedded rewrites. For example, [newInv->_container addObject:0]. - IV->setBase(PE); - } - } - - ReplaceStmtWithRange(IV, Replacement, OldRange); - return Replacement; -} - -#endif // CLANG_ENABLE_OBJC_REWRITER diff --git a/clang/lib/FrontendTool/CMakeLists.txt b/clang/lib/FrontendTool/CMakeLists.txt index bfc7652b4c118f..d7a3699361f0aa 100644 --- a/clang/lib/FrontendTool/CMakeLists.txt +++ b/clang/lib/FrontendTool/CMakeLists.txt @@ -21,12 +21,6 @@ if(CLANG_ENABLE_CIR) ) endif() -if(CLANG_ENABLE_ARCMT) - list(APPEND link_libs - clangARCMigrate - ) -endif() - if(CLANG_ENABLE_STATIC_ANALYZER) list(APPEND link_libs clangStaticAnalyzerFrontend diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 3f95a1efb2eed7..a2d76409a588bf 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/ARCMigrate/ARCMTActions.h" #include "clang/CodeGen/CodeGenAction.h" #include "clang/Config/config.h" #include "clang/Driver/Options.h" @@ -125,18 +124,8 @@ CreateFrontendBaseAction(CompilerInstance &CI) { } case RewriteMacros: return std::make_unique(); - case RewriteTest: return std::make_unique(); -#if CLANG_ENABLE_OBJC_REWRITER - case RewriteObjC: return std::make_unique(); -#else - case RewriteObjC: Action = "RewriteObjC"; break; -#endif -#if CLANG_ENABLE_ARCMT - case MigrateSource: - return std::make_unique(); -#else - case MigrateSource: Action = "MigrateSource"; break; -#endif + case RewriteTest: + return std::make_unique(); #if CLANG_ENABLE_STATIC_ANALYZER case RunAnalysis: return std::make_unique(); #else @@ -147,8 +136,7 @@ CreateFrontendBaseAction(CompilerInstance &CI) { return std::make_unique(); } -#if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \ - || !CLANG_ENABLE_OBJC_REWRITER +#if !CLANG_ENABLE_STATIC_ANALYZER CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action; return 0; #else @@ -169,35 +157,6 @@ CreateFrontendAction(CompilerInstance &CI) { Act = std::make_unique(std::move(Act)); } -#if CLANG_ENABLE_ARCMT - if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource && - CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) { - // Potentially wrap the base FE action in an ARC Migrate Tool action. - switch (FEOpts.ARCMTAction) { - case FrontendOptions::ARCMT_None: - break; - case FrontendOptions::ARCMT_Check: - Act = std::make_unique(std::move(Act)); - break; - case FrontendOptions::ARCMT_Modify: - Act = std::make_unique(std::move(Act)); - break; - case FrontendOptions::ARCMT_Migrate: - Act = std::make_unique(std::move(Act), - FEOpts.MTMigrateDir, - FEOpts.ARCMTMigrateReportOut, - FEOpts.ARCMTMigrateEmitARCErrors); - break; - } - - if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) { - Act = std::make_unique(std::move(Act), - FEOpts.MTMigrateDir, - FEOpts.ObjCMTAction); - } - } -#endif - // Wrap the base FE action in an extract api action to generate // symbol graph as a biproduct of compilation (enabled with // --emit-symbol-graph option) diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index 2e97cac0796cee..732de7b82475df 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -214,9 +214,6 @@ makeCommonInvocationForModuleBuild(CompilerInvocation CI) { CI.getDependencyOutputOpts().Targets.clear(); CI.getFrontendOpts().ProgramAction = frontend::GenerateModule; - CI.getFrontendOpts().ARCMTAction = FrontendOptions::ARCMT_None; - CI.getFrontendOpts().ObjCMTAction = FrontendOptions::ObjCMT_None; - CI.getFrontendOpts().MTMigrateDir.clear(); CI.getLangOpts().ModuleName.clear(); // Remove any macro definitions that are explicitly ignored. diff --git a/clang/test/ARCMT/Common.h b/clang/test/ARCMT/Common.h deleted file mode 100644 index b388ecab741097..00000000000000 --- a/clang/test/ARCMT/Common.h +++ /dev/null @@ -1,110 +0,0 @@ -#if __has_feature(objc_arr) -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) -#else -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE -#endif - -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#define CF_CONSUMED __attribute__((cf_consumed)) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) - -#define NS_INLINE static __inline__ __attribute__((always_inline)) -#define nil ((void*) 0) -#define NULL ((void*)0) - -typedef int BOOL; -typedef unsigned NSUInteger; -typedef int int32_t; -typedef unsigned char uint8_t; -typedef int32_t UChar32; -typedef unsigned char UChar; - -typedef struct _NSZone NSZone; - -typedef const void * CFTypeRef; -CFTypeRef CFRetain(CFTypeRef cf); -CFTypeRef CFMakeCollectable(CFTypeRef cf) NS_AUTOMATED_REFCOUNT_UNAVAILABLE; - -NS_INLINE NS_RETURNS_RETAINED id NSMakeCollectable(CFTypeRef CF_CONSUMED cf) NS_AUTOMATED_REFCOUNT_UNAVAILABLE; - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -@end - -@interface NSObject {} -- (id)init; - -+ (id)new; -+ (id)alloc; -- (void)dealloc; - -- (void)finalize; - -- (id)copy; -- (id)mutableCopy; -@end - -NS_AUTOMATED_REFCOUNT_UNAVAILABLE -@interface NSAutoreleasePool : NSObject { -@private - void *_token; - void *_reserved3; - void *_reserved2; - void *_reserved; -} - -+ (void)addObject:(id)anObject; - -- (void)addObject:(id)anObject; - -- (void)drain; - -@end - -typedef const void* objc_objectptr_t; -extern __attribute__((ns_returns_retained)) id objc_retainedObject(objc_objectptr_t __attribute__((cf_consumed)) pointer); -extern __attribute__((ns_returns_not_retained)) id objc_unretainedObject(objc_objectptr_t pointer); -extern objc_objectptr_t objc_unretainedPointer(id object); - -#define dispatch_retain(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); (void)[_o retain]; }) -#define dispatch_release(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); [_o release]; }) -#define xpc_retain(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o retain]; }) -#define xpc_release(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o release]; }) - -typedef id dispatch_object_t; -typedef id xpc_object_t; - -void _dispatch_object_validate(dispatch_object_t object); -void _xpc_object_validate(xpc_object_t object); - -#if __has_feature(objc_arc) - -NS_INLINE CF_RETURNS_RETAINED CFTypeRef CFBridgingRetain(id X) { - return (__bridge_retained CFTypeRef)X; -} - -NS_INLINE id CFBridgingRelease(CFTypeRef CF_CONSUMED X) { - return (__bridge_transfer id)X; -} - -#else - -NS_INLINE CF_RETURNS_RETAINED CFTypeRef CFBridgingRetain(id X) { - return X ? CFRetain((CFTypeRef)X) : NULL; -} - -NS_INLINE id CFBridgingRelease(CFTypeRef CF_CONSUMED X) { - return [(id)CFMakeCollectable(X) autorelease]; -} - -#endif - -void *_Block_copy(const void *aBlock); -void _Block_release(const void *aBlock); -#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__))) -#define Block_release(...) _Block_release((const void *)(__VA_ARGS__)) diff --git a/clang/test/ARCMT/GC-check-warn-nsalloc.m b/clang/test/ARCMT/GC-check-warn-nsalloc.m deleted file mode 100644 index 1c33de5b65b256..00000000000000 --- a/clang/test/ARCMT/GC-check-warn-nsalloc.m +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -no-ns-alloc-error -triple x86_64-apple-darwin10 -fobjc-gc-only %s 2>&1 | grep 'warning: \[rewriter\] call returns pointer to GC managed memory' -// RUN: %clang_cc1 -arcmt-action=check -no-ns-alloc-error -triple x86_64-apple-darwin10 -fobjc-gc-only -x objective-c++ %s 2>&1 | grep 'warning: \[rewriter\] call returns pointer to GC managed memory' -// TODO: Investigate VerifyDiagnosticConsumer failures on these tests when using -verify. - -typedef unsigned NSUInteger; -void *__strong NSAllocateCollectable(NSUInteger size, NSUInteger options); - -void test1(void) { - NSAllocateCollectable(100, 0); -} diff --git a/clang/test/ARCMT/GC-check.m b/clang/test/ARCMT/GC-check.m deleted file mode 100644 index e95e285432e0f0..00000000000000 --- a/clang/test/ARCMT/GC-check.m +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 -fobjc-gc-only %s -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 -fobjc-gc-only -x objective-c++ %s - -#define CF_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) -typedef unsigned NSUInteger; -typedef const void * CFTypeRef; -CFTypeRef CFMakeCollectable(CFTypeRef cf) CF_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note {{unavailable}} -void *__strong NSAllocateCollectable(NSUInteger size, NSUInteger options); - -void test1(CFTypeRef *cft) { - CFTypeRef c = CFMakeCollectable(cft); // expected-error {{CFMakeCollectable will leak the object that it receives in ARC}} \ - // expected-error {{unavailable}} - NSAllocateCollectable(100, 0); // expected-error {{call returns pointer to GC managed memory; it will become unmanaged in ARC}} -} - -@interface I1 { - __strong void *gcVar; // expected-error {{GC managed memory will become unmanaged in ARC}} -} -@end; diff --git a/clang/test/ARCMT/GC-no-arc-runtime.m b/clang/test/ARCMT/GC-no-arc-runtime.m deleted file mode 100644 index 99ba2eb5f7aef3..00000000000000 --- a/clang/test/ARCMT/GC-no-arc-runtime.m +++ /dev/null @@ -1,80 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -// MRC __weak broke this test somehow. -// XFAIL: * - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = NSMakeCollectable(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - --(void)finalize { - // finalize - test1(0); -} -@end - -@interface I2 -@property (retain) id prop; -@end - -@implementation I2 -@synthesize prop; - --(void)finalize { - self.prop = 0; - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __weak id s; - __weak QQ *q; -} -@end - -@interface I3 -@property (assign) I3 *__weak pw1, *__weak pw2; -@property (assign) I3 *__strong ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *pds2; -} -@property (assign) I4Impl *__weak pw1, *__weak pw2; -@property (assign) I4Impl *__strong ps; -@property (assign) I4Impl * pds; -@property (assign) I4Impl * pds2; -@end - -@implementation I4Impl -@synthesize pw1, pw2, ps, pds, pds2; - --(void)test1:(CFTypeRef *)cft { - id x = NSMakeCollectable(cft); -} -@end - -@interface I5 { - __weak id prop; -} -@property (readonly) __weak id prop; -@end diff --git a/clang/test/ARCMT/GC-no-arc-runtime.m.result b/clang/test/ARCMT/GC-no-arc-runtime.m.result deleted file mode 100644 index c338bdb2ed471e..00000000000000 --- a/clang/test/ARCMT/GC-no-arc-runtime.m.result +++ /dev/null @@ -1,72 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = CFBridgingRelease(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - -@end - -@interface I2 -@property (strong) id prop; -@end - -@implementation I2 -@synthesize prop; - --(void)dealloc { - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __unsafe_unretained id s; - __unsafe_unretained QQ *q; -} -@end - -@interface I3 -@property (unsafe_unretained) I3 * pw1, * pw2; -@property (strong) I3 * ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *__strong pds2; -} -@property (unsafe_unretained) I4Impl * pw1, * pw2; -@property (strong) I4Impl * ps; -@property (strong) I4Impl * pds; -@property (strong) I4Impl * pds2; -@end - -@implementation I4Impl -@synthesize pw1, pw2, ps, pds, pds2; - --(void)test1:(CFTypeRef *)cft { - id x = CFBridgingRelease(cft); -} -@end - -@interface I5 { - __unsafe_unretained id prop; -} -@property (unsafe_unretained, readonly) id prop; -@end diff --git a/clang/test/ARCMT/GC-no-finalize-removal.m b/clang/test/ARCMT/GC-no-finalize-removal.m deleted file mode 100644 index 07a737c1b7757e..00000000000000 --- a/clang/test/ARCMT/GC-no-finalize-removal.m +++ /dev/null @@ -1,88 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -no-finalize-removal -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -no-finalize-removal -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = NSMakeCollectable(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - --(void)finalize { - // finalize - test1(0); -} -@end - -@interface I2 -@property (retain) id prop; -@end - -@implementation I2 -@synthesize prop; - --(void)finalize { - self.prop = 0; - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __weak id s; - __weak QQ *q; -} -@end - -@interface I3 -@property (assign) I3 *__weak pw1, *__weak pw2; -@property (assign) I3 *__strong ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *pds2; - I4Impl *pds3; - __weak I4Impl *pw3; - __weak I4Impl *pw4; -} -@property (assign) I4Impl *__weak pw1, *__weak pw2; -@property (assign) I4Impl *__strong ps; -@property (assign) I4Impl * pds; -@property (assign) I4Impl * pds2; -@property (readwrite) I4Impl * pds3; -@property (readonly) I4Impl * pds4; -@property (readonly) __weak I4Impl *pw3; -@property (assign) __weak I4Impl *pw4; -@end - -@implementation I4Impl -@synthesize pw1, pw2, pw3, pw4, ps, pds, pds2, pds3, pds4; - --(void)test1:(CFTypeRef *)cft { - id x = NSMakeCollectable(cft); -} -@end - -@interface rdar10532449 -@property (assign) id assign_prop; -@property (assign, readonly) id __strong strong_readonly_prop; -@property (assign) id __weak weak_prop; -@end - -@implementation rdar10532449 -@synthesize assign_prop, strong_readonly_prop, weak_prop; -@end diff --git a/clang/test/ARCMT/GC-no-finalize-removal.m.result b/clang/test/ARCMT/GC-no-finalize-removal.m.result deleted file mode 100644 index a2105b32fc755b..00000000000000 --- a/clang/test/ARCMT/GC-no-finalize-removal.m.result +++ /dev/null @@ -1,96 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -no-finalize-removal -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -no-finalize-removal -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = CFBridgingRelease(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - -#if !__has_feature(objc_arc) --(void)finalize { - // finalize - test1(0); -} -#endif -@end - -@interface I2 -@property (strong) id prop; -@end - -@implementation I2 -@synthesize prop; - -#if !__has_feature(objc_arc) --(void)finalize { - self.prop = 0; - // finalize - test1(0); -} -#endif --(void)dealloc { - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __weak id s; - __unsafe_unretained QQ *q; -} -@end - -@interface I3 -@property (weak) I3 * pw1, * pw2; -@property (strong) I3 * ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *__strong pds2; - I4Impl *pds3; - __weak I4Impl *pw3; - __weak I4Impl *pw4; -} -@property (weak) I4Impl * pw1, * pw2; -@property (strong) I4Impl * ps; -@property (strong) I4Impl * pds; -@property (strong) I4Impl * pds2; -@property (readwrite) I4Impl * pds3; -@property (readonly) I4Impl * pds4; -@property (weak, readonly) I4Impl *pw3; -@property (weak) I4Impl *pw4; -@end - -@implementation I4Impl -@synthesize pw1, pw2, pw3, pw4, ps, pds, pds2, pds3, pds4; - --(void)test1:(CFTypeRef *)cft { - id x = CFBridgingRelease(cft); -} -@end - -@interface rdar10532449 -@property (strong) id assign_prop; -@property (strong, readonly) id strong_readonly_prop; -@property (weak) id weak_prop; -@end - -@implementation rdar10532449 -@synthesize assign_prop, strong_readonly_prop, weak_prop; -@end diff --git a/clang/test/ARCMT/GC.h b/clang/test/ARCMT/GC.h deleted file mode 100644 index 4301baf272465a..00000000000000 --- a/clang/test/ARCMT/GC.h +++ /dev/null @@ -1,6 +0,0 @@ - -@interface ExtInterface { - __strong ExtInterface *myivar; - __strong void *gcVar; -} -@end diff --git a/clang/test/ARCMT/GC.m b/clang/test/ARCMT/GC.m deleted file mode 100644 index 97723e89ed369f..00000000000000 --- a/clang/test/ARCMT/GC.m +++ /dev/null @@ -1,93 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = NSMakeCollectable(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - --(void)finalize { - // finalize - test1(0); -} -@end - -@interface I2 -@property (retain) id prop; -@end - -@implementation I2 -@synthesize prop; - --(void)finalize { - self.prop = 0; - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __weak id s; - __weak QQ *q; -} -@end - -@interface I3 -@property (assign) I3 *__weak pw1, *__weak pw2; -@property (assign) I3 *__strong ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *pds2; - I4Impl *pds3; - __weak I4Impl *pw3; - __weak I4Impl *pw4; -} -@property (assign) I4Impl *__weak pw1, *__weak pw2; -@property (assign) I4Impl *__strong ps; -@property (assign) I4Impl * pds; -@property (assign) I4Impl * pds2; -@property (readwrite) I4Impl * pds3; -@property (readonly) I4Impl * pds4; -@property (readonly) __weak I4Impl *pw3; -@property (assign) __weak I4Impl *pw4; -@end - -@implementation I4Impl -@synthesize pw1, pw2, pw3, pw4, ps, pds, pds2, pds3, pds4; - --(void)test1:(CFTypeRef *)cft { - id x = NSMakeCollectable(cft); -} -@end - -@interface rdar10532449 -@property (assign) id assign_prop; -@property (assign, readonly) id __strong strong_readonly_prop; -@property (assign) id __weak weak_prop; -@end - -@implementation rdar10532449 -@synthesize assign_prop, strong_readonly_prop, weak_prop; -@end - -void test2(id p, __strong I1 *ap[]) { - for (__strong I1 *specRule in p) { - } -} diff --git a/clang/test/ARCMT/GC.m.result b/clang/test/ARCMT/GC.m.result deleted file mode 100644 index b60b07ac9c1109..00000000000000 --- a/clang/test/ARCMT/GC.m.result +++ /dev/null @@ -1,88 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = CFBridgingRelease(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - -@end - -@interface I2 -@property (strong) id prop; -@end - -@implementation I2 -@synthesize prop; - --(void)dealloc { - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __weak id s; - __unsafe_unretained QQ *q; -} -@end - -@interface I3 -@property (weak) I3 * pw1, * pw2; -@property (strong) I3 * ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *__strong pds2; - I4Impl *pds3; - __weak I4Impl *pw3; - __weak I4Impl *pw4; -} -@property (weak) I4Impl * pw1, * pw2; -@property (strong) I4Impl * ps; -@property (strong) I4Impl * pds; -@property (strong) I4Impl * pds2; -@property (readwrite) I4Impl * pds3; -@property (readonly) I4Impl * pds4; -@property (weak, readonly) I4Impl *pw3; -@property (weak) I4Impl *pw4; -@end - -@implementation I4Impl -@synthesize pw1, pw2, pw3, pw4, ps, pds, pds2, pds3, pds4; - --(void)test1:(CFTypeRef *)cft { - id x = CFBridgingRelease(cft); -} -@end - -@interface rdar10532449 -@property (strong) id assign_prop; -@property (strong, readonly) id strong_readonly_prop; -@property (weak) id weak_prop; -@end - -@implementation rdar10532449 -@synthesize assign_prop, strong_readonly_prop, weak_prop; -@end - -void test2(id p, __strong I1 *ap[]) { - for (__strong I1 *specRule in p) { - } -} diff --git a/clang/test/ARCMT/Inputs/Module.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h b/clang/test/ARCMT/Inputs/Module.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h deleted file mode 100644 index f7f9fb66c9e945..00000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef MODULE_SUBFRAMEWORK_H -#define MODULE_SUBFRAMEWORK_H -#__private_macro MODULE_SUBFRAMEWORK_H -char *module_subframework; -#endif diff --git a/clang/test/ARCMT/Inputs/Module.framework/Headers/Buried/Treasure.h b/clang/test/ARCMT/Inputs/Module.framework/Headers/Buried/Treasure.h deleted file mode 100644 index 6e81adcb2b60c3..00000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Headers/Buried/Treasure.h +++ /dev/null @@ -1 +0,0 @@ -unsigned *Buried_Treasure; diff --git a/clang/test/ARCMT/Inputs/Module.framework/Headers/Module.h b/clang/test/ARCMT/Inputs/Module.framework/Headers/Module.h deleted file mode 100644 index 3d2476b20431de..00000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Headers/Module.h +++ /dev/null @@ -1,28 +0,0 @@ -// expected-warning 0-1 {{umbrella header}} - -// FIXME: The "umbrella header" warning should be moved to a separate test. -// This "0-1" is only here because the warning is only emitted when the -// module is (otherwise) successfully included. - -#ifndef MODULE_H -#define MODULE_H -const char *getModuleVersion(void); - -#ifdef FOO -# error Module should have been built without -DFOO -#endif - -@interface Module -+(const char *)version; // retrieve module version -+alloc; -@end - -#define MODULE_H_MACRO 1 -#__private_macro MODULE_H_MACRO - -#include -#include - -__asm("foo"); - -#endif // MODULE_H diff --git a/clang/test/ARCMT/Inputs/Module.framework/Headers/NotInModule.h b/clang/test/ARCMT/Inputs/Module.framework/Headers/NotInModule.h deleted file mode 100644 index 6b15791eb2c704..00000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Headers/NotInModule.h +++ /dev/null @@ -1 +0,0 @@ -int not_in_module; diff --git a/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub.h b/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub.h deleted file mode 100644 index dea76e7646176d..00000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub.h +++ /dev/null @@ -1,3 +0,0 @@ -#include -int *Module_Sub; - diff --git a/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub2.h b/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub2.h deleted file mode 100644 index beed4a862dcaf7..00000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub2.h +++ /dev/null @@ -1 +0,0 @@ -int *Module_Sub2; diff --git a/clang/test/ARCMT/Inputs/Module.framework/Module b/clang/test/ARCMT/Inputs/Module.framework/Module deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/clang/test/ARCMT/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h b/clang/test/ARCMT/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h deleted file mode 100644 index 0782336df9dec0..00000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h +++ /dev/null @@ -1 +0,0 @@ -int module_private; diff --git a/clang/test/ARCMT/Inputs/module.modulemap b/clang/test/ARCMT/Inputs/module.modulemap deleted file mode 100644 index 061abbd24d570c..00000000000000 --- a/clang/test/ARCMT/Inputs/module.modulemap +++ /dev/null @@ -1,309 +0,0 @@ -module c_library [extern_c] { module inner { header "c-header.h" } } -module cxx_library { header "cxx-header.h" requires cplusplus } -module c_library_bad [extern_c] { header "c-header-bad.h" } -module diamond_top { header "diamond_top.h" } -module diamond_left { - header "diamond_left.h" - export diamond_top -} -module diamond_right { - header "diamond_right.h" - export diamond_top -} -module diamond_bottom { - header "diamond_bottom.h" - export * -} -module irgen { header "irgen.h" } -module cxx_irgen_top { header "cxx-irgen-top.h" } -module cxx_irgen_left { header "cxx-irgen-left.h" } -module cxx_irgen_right { header "cxx-irgen-right.h" } -module lookup_left_objc { header "lookup_left.h" } -module lookup_right_objc { header "lookup_right.h" } -module lookup_left_cxx { header "lookup_left.hpp" } -module lookup_right_cxx { header "lookup_right.hpp" } -module module_private_left { header "module_private_left.h" } -module module_private_right { header "module_private_right.h" } -module macros_top { - header "macros_top.h" - explicit module b { header "macros_top_b.h" } - explicit module c { header "macros_top_c.h" } -} -module macros_left { - header "macros_left.h" - export * -} -module macros_right { - header "macros_right.h" - export * - explicit module undef { - header "macros_right_undef.h" - } -} -module macros { header "macros.h" } -module macros_other { header "macros_other.h" } -module category_top { header "category_top.h" } -module category_left { - header "category_left.h" - export category_top - - explicit module sub { - header "category_left_sub.h" - } -} -module category_right { - header "category_right.h" - export category_top - - explicit module sub { - header "category_right_sub.h" - } -} -module category_bottom { - header "category_bottom.h" - export category_left - export category_right -} -module category_other { header "category_other.h" } -module redeclarations_left { header "redeclarations_left.h" } -module redeclarations_right { header "redeclarations_right.h" } -module redecl_namespaces_left { header "redecl_namespaces_left.h" } -module redecl_namespaces_right { header "redecl_namespaces_right.h" } -module redecl_add_after_load_top { header "redecl-add-after-load-top.h" } -module redecl_add_after_load { header "redecl-add-after-load.h" } -module load_failure { header "load_failure.h" } - -module decldef { - explicit module Decl { header "decl.h" } - explicit module Decl2 { header "decl2.h" } - explicit module Def { header "def.h" } -} - -module redecl_merge_top { - header "redecl-merge-top.h" - explicit module Explicit { header "redecl-merge-top-explicit.h" } - exclude header "nonexistent.h" -} -module redecl_merge_left { - header "redecl-merge-left.h" - export * -} -module redecl_merge_left_left { - header "redecl-merge-left-left.h" - export * -} -module redecl_merge_right { - header "redecl-merge-right.h" - export * -} -module redecl_merge_bottom { - explicit module prefix { - header "redecl-merge-bottom-prefix.h" - } - - header "redecl-merge-bottom.h" - export * -} -module namespaces_top { - header "namespaces-top.h" - export * -} -module namespaces_left { - header "namespaces-left.h" - export * -} -module namespaces_right { - header "namespaces-right.h" - export * -} -module templates_top { - header "templates-top.h" - export * -} -module templates_left { - header "templates-left.h" - export * -} -module templates_right { - header "templates-right.h" - export * -} -module MethodPoolA { - header "MethodPoolA.h" - - explicit module Sub2 { - header "MethodPoolASub2.h" - } - - explicit module Sub { - header "MethodPoolASub.h" - } -} -module MethodPoolB { - header "MethodPoolB.h" - - explicit module Sub2 { - header "MethodPoolBSub2.h" - } - - explicit module Sub { - header "MethodPoolBSub.h" - } -} -module import_decl { - header "import-decl.h" -} - -framework module * { - exclude NotAModule -} - -module linkage_merge_left { - explicit module sub { - header "linkage-merge-sub.h" - } -} - -module autolink { - header "autolink.h" - link "autolink" - - explicit module sub { - header "autolink-sub.h" - link "autolink_sub" - } - - explicit module sub2 { - header "autolink-sub2.h" - link framework "autolink_framework" - } - - explicit module sub3 { - header "autolink-sub3.h" - link "autolink_from_pch" - } -} - -module weird_objc { - header "weird_objc.h" -} - -module ignored_macros { - header "ignored_macros.h" -} - -module cxx_many_overloads { - header "cxx-many-overloads.h" -} - -module cxx_inline_namespace { - header "cxx-inline-namespace.h" -} - -module cxx_inline_namespace_b { - header "cxx-inline-namespace-b.h" -} - -module cxx_linkage_cache { - header "cxx-linkage-cache.h" -} - -module cxx_templates_common { - header "cxx-templates-common.h" -} - -module cxx_templates_a { - header "cxx-templates-a.h" -} - -module cxx_templates_b_impl { - header "cxx-templates-b-impl.h" -} - -module cxx_templates_b { - header "cxx-templates-b.h" -} - -module cxx_templates_c { - header "cxx-templates-c.h" -} - -module cxx_decls { - module unimported { - header "cxx-decls-unimported.h" - } - module imported { - header "cxx-decls-imported.h" - } -} - -module config { - header "config.h" - config_macros [exhaustive] WANT_FOO, WANT_BAR -} - -module diag_pragma { - header "diag_pragma.h" -} - -module dummy { - header "dummy.h" -} - -module builtin { - header "builtin.h" - explicit module sub { - header "builtin_sub.h" - } -} - -module linkage_merge { - explicit module foo { - header "linkage-merge-foo.h" - } - explicit module bar { - header "linkage-merge-bar.h" - } - -} - -module incomplete_mod { - header "incomplete_mod.h" -} - -module warning { - header "warning.h" -} - -module initializer_list { - header "initializer_list" -} - -module using_decl { - module a { header "using-decl-a.h" export * } - module b { header "using-decl-b.h" export * } -} - -module recursive_visibility_a1 { - module inner { header "recursive_visibility_a1_inner.h" } -} -module recursive_visibility_a2 { - module inner { - module more_inner { - header "recursive_visibility_a2_more_inner.h" - } - } -} -module recursive_visibility_b { - header "recursive_visibility_b.h" - export * -} -module recursive_visibility_c { - header "recursive_visibility_c.h" -} -module recursive1 { - header "recursive1.h" -} -module recursive2 { - header "recursive2.h" -} diff --git a/clang/test/ARCMT/Inputs/test.h b/clang/test/ARCMT/Inputs/test.h deleted file mode 100644 index 756295f27e6983..00000000000000 --- a/clang/test/ARCMT/Inputs/test.h +++ /dev/null @@ -1,15 +0,0 @@ -@protocol NSObject -- (oneway void)release; -@end - -#ifdef PART1 -static inline void part1(id p) { - [p release]; -} -#endif - -#ifdef PART2 -static inline void part2(id p) { - [p release]; -} -#endif diff --git a/clang/test/ARCMT/Inputs/test.h.result b/clang/test/ARCMT/Inputs/test.h.result deleted file mode 100644 index 0638a3378c1c06..00000000000000 --- a/clang/test/ARCMT/Inputs/test.h.result +++ /dev/null @@ -1,13 +0,0 @@ -@protocol NSObject -- (oneway void)release; -@end - -#ifdef PART1 -static inline void part1(id p) { -} -#endif - -#ifdef PART2 -static inline void part2(id p) { -} -#endif diff --git a/clang/test/ARCMT/Inputs/test1.m.in b/clang/test/ARCMT/Inputs/test1.m.in deleted file mode 100644 index 44a3c4cf3d93fc..00000000000000 --- a/clang/test/ARCMT/Inputs/test1.m.in +++ /dev/null @@ -1,16 +0,0 @@ -#define PART1 -#include "test.h" - -void test1(id p) { - [p release]; -} - -@interface Test2 -@property (strong) id prop; -@end - -@implementation Test2 --(id)init { - _prop = 0; -} -@end diff --git a/clang/test/ARCMT/Inputs/test1.m.in.result b/clang/test/ARCMT/Inputs/test1.m.in.result deleted file mode 100644 index 1db9bf7ad65c79..00000000000000 --- a/clang/test/ARCMT/Inputs/test1.m.in.result +++ /dev/null @@ -1,15 +0,0 @@ -#define PART1 -#include "test.h" - -void test1(id p) { -} - -@interface Test2 -@property (strong) id prop; -@end - -@implementation Test2 --(id)init { - _prop = 0; -} -@end diff --git a/clang/test/ARCMT/Inputs/test2.m.in b/clang/test/ARCMT/Inputs/test2.m.in deleted file mode 100644 index 99f87b0721716a..00000000000000 --- a/clang/test/ARCMT/Inputs/test2.m.in +++ /dev/null @@ -1,6 +0,0 @@ -#define PART2 -#include "test.h" - -void test2(id p) { - [p release]; -} diff --git a/clang/test/ARCMT/Inputs/test2.m.in.result b/clang/test/ARCMT/Inputs/test2.m.in.result deleted file mode 100644 index f8e918ce2598e5..00000000000000 --- a/clang/test/ARCMT/Inputs/test2.m.in.result +++ /dev/null @@ -1,5 +0,0 @@ -#define PART2 -#include "test.h" - -void test2(id p) { -} diff --git a/clang/test/ARCMT/Inputs/with space/test.h b/clang/test/ARCMT/Inputs/with space/test.h deleted file mode 100644 index 756295f27e6983..00000000000000 --- a/clang/test/ARCMT/Inputs/with space/test.h +++ /dev/null @@ -1,15 +0,0 @@ -@protocol NSObject -- (oneway void)release; -@end - -#ifdef PART1 -static inline void part1(id p) { - [p release]; -} -#endif - -#ifdef PART2 -static inline void part2(id p) { - [p release]; -} -#endif diff --git a/clang/test/ARCMT/Inputs/with space/test.h.result b/clang/test/ARCMT/Inputs/with space/test.h.result deleted file mode 100644 index 0638a3378c1c06..00000000000000 --- a/clang/test/ARCMT/Inputs/with space/test.h.result +++ /dev/null @@ -1,13 +0,0 @@ -@protocol NSObject -- (oneway void)release; -@end - -#ifdef PART1 -static inline void part1(id p) { -} -#endif - -#ifdef PART2 -static inline void part2(id p) { -} -#endif diff --git a/clang/test/ARCMT/Inputs/with space/test1.m.in b/clang/test/ARCMT/Inputs/with space/test1.m.in deleted file mode 100644 index 8416a889656960..00000000000000 --- a/clang/test/ARCMT/Inputs/with space/test1.m.in +++ /dev/null @@ -1,6 +0,0 @@ -#define PART1 -#include "test.h" - -void test1(id p) { - [p release]; -} diff --git a/clang/test/ARCMT/Inputs/with space/test1.m.in.result b/clang/test/ARCMT/Inputs/with space/test1.m.in.result deleted file mode 100644 index f351fe6c835522..00000000000000 --- a/clang/test/ARCMT/Inputs/with space/test1.m.in.result +++ /dev/null @@ -1,5 +0,0 @@ -#define PART1 -#include "test.h" - -void test1(id p) { -} diff --git a/clang/test/ARCMT/Inputs/with space/test2.m.in b/clang/test/ARCMT/Inputs/with space/test2.m.in deleted file mode 100644 index 99f87b0721716a..00000000000000 --- a/clang/test/ARCMT/Inputs/with space/test2.m.in +++ /dev/null @@ -1,6 +0,0 @@ -#define PART2 -#include "test.h" - -void test2(id p) { - [p release]; -} diff --git a/clang/test/ARCMT/Inputs/with space/test2.m.in.result b/clang/test/ARCMT/Inputs/with space/test2.m.in.result deleted file mode 100644 index f8e918ce2598e5..00000000000000 --- a/clang/test/ARCMT/Inputs/with space/test2.m.in.result +++ /dev/null @@ -1,5 +0,0 @@ -#define PART2 -#include "test.h" - -void test2(id p) { -} diff --git a/clang/test/ARCMT/allowlisted/Inputs/header1.h b/clang/test/ARCMT/allowlisted/Inputs/header1.h deleted file mode 100644 index 44430f3b77e328..00000000000000 --- a/clang/test/ARCMT/allowlisted/Inputs/header1.h +++ /dev/null @@ -1 +0,0 @@ -// the contents are not important diff --git a/clang/test/ARCMT/allowlisted/header1.h b/clang/test/ARCMT/allowlisted/header1.h deleted file mode 100644 index 33f77aa5dd1527..00000000000000 --- a/clang/test/ARCMT/allowlisted/header1.h +++ /dev/null @@ -1,8 +0,0 @@ - -@interface I1 : NSObject --(int)prop; --(void)setProp:(int)p; -+(id)i1; -@end - -typedef long NSInteger; diff --git a/clang/test/ARCMT/allowlisted/header1.h.result b/clang/test/ARCMT/allowlisted/header1.h.result deleted file mode 100644 index c7cf109a27e92c..00000000000000 --- a/clang/test/ARCMT/allowlisted/header1.h.result +++ /dev/null @@ -1,7 +0,0 @@ - -@interface I1 : NSObject -@property (nonatomic) int prop; -+(instancetype)i1; -@end - -typedef long NSInteger; diff --git a/clang/test/ARCMT/allowlisted/header2.h b/clang/test/ARCMT/allowlisted/header2.h deleted file mode 100644 index ac3888ccdf8c11..00000000000000 --- a/clang/test/ARCMT/allowlisted/header2.h +++ /dev/null @@ -1,8 +0,0 @@ - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -typedef enum : NSInteger {five} ApplicableEnum; - -@interface I2 : NSObject --(int)prop; --(void)setProp:(int)p; -@end diff --git a/clang/test/ARCMT/allowlisted/header2.h.result b/clang/test/ARCMT/allowlisted/header2.h.result deleted file mode 100644 index 3226e711b98acb..00000000000000 --- a/clang/test/ARCMT/allowlisted/header2.h.result +++ /dev/null @@ -1,7 +0,0 @@ - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -typedef NS_ENUM(NSInteger, ApplicableEnum) {five}; - -@interface I2 : NSObject -@property (nonatomic) int prop; -@end diff --git a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m b/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m deleted file mode 100644 index 36797eb1c843b4..00000000000000 --- a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-allowlist-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %s.result - -@interface NSObject -+ (id)alloc; -@end - -#include "header1.h" -#include "header2.h" - -@interface I2(cat) --(id)initInCat; -@end - -@implementation I1 -+(id)i1 {} -@end diff --git a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m.result b/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m.result deleted file mode 100644 index 69e7b767ef2b70..00000000000000 --- a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m.result +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-allowlist-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %s.result - -@interface NSObject -+ (id)alloc; -@end - -#include "header1.h" -#include "header2.h" - -@interface I2(cat) --(id)initInCat; -@end - -@implementation I1 -+(instancetype)i1 {} -@end diff --git a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist.m b/clang/test/ARCMT/allowlisted/objcmt-with-allowlist.m deleted file mode 100644 index c22c02d3bf2e43..00000000000000 --- a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist.m +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-migrate-ns-macros %s -triple x86_64-apple-darwin11 -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %S/header2.h.result -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-migrate-ns-macros -objcmt-allowlist-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result - -@interface NSObject -+ (id)alloc; -@end - -#include "header1.h" -#include "header2.h" diff --git a/clang/test/ARCMT/api.m b/clang/test/ARCMT/api.m deleted file mode 100644 index b186ec724745cc..00000000000000 --- a/clang/test/ARCMT/api.m +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void test(NSObject *o) { - NSZone *z = [o zone]; -} diff --git a/clang/test/ARCMT/api.m.result b/clang/test/ARCMT/api.m.result deleted file mode 100644 index e3093751b626b8..00000000000000 --- a/clang/test/ARCMT/api.m.result +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void test(NSObject *o) { - NSZone *z = nil; -} diff --git a/clang/test/ARCMT/assign-prop-no-arc-runtime.m b/clang/test/ARCMT/assign-prop-no-arc-runtime.m deleted file mode 100644 index de1c456b3d19f4..00000000000000 --- a/clang/test/ARCMT/assign-prop-no-arc-runtime.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface Foo : NSObject { - NSObject *x; -} -@property (readonly,assign) id x; -@end - -@implementation Foo -@synthesize x; -@end diff --git a/clang/test/ARCMT/assign-prop-no-arc-runtime.m.result b/clang/test/ARCMT/assign-prop-no-arc-runtime.m.result deleted file mode 100644 index 23848d357268f6..00000000000000 --- a/clang/test/ARCMT/assign-prop-no-arc-runtime.m.result +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface Foo : NSObject { - NSObject *__unsafe_unretained x; -} -@property (readonly,unsafe_unretained) id x; -@end - -@implementation Foo -@synthesize x; -@end diff --git a/clang/test/ARCMT/assign-prop-with-arc-runtime.m b/clang/test/ARCMT/assign-prop-with-arc-runtime.m deleted file mode 100644 index a00538cd6197d6..00000000000000 --- a/clang/test/ARCMT/assign-prop-with-arc-runtime.m +++ /dev/null @@ -1,72 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface WeakOptOut -@end - -@class _NSCachedAttributedString; -typedef _NSCachedAttributedString *BadClassForWeak; - -@class Forw; - -@interface Foo : NSObject { - Foo *x, *w, *q1, *q2; - WeakOptOut *oo; - BadClassForWeak bcw; - id not_safe1; - NSObject *not_safe2; - Forw *not_safe3; - Foo *assign_plus1; -} -@property (readonly) Foo *x; -@property (assign) Foo *w; -@property Foo *q1, *q2; -@property (assign) WeakOptOut *oo; -@property (assign) BadClassForWeak bcw; -@property (assign) id not_safe1; -@property () NSObject *not_safe2; -@property Forw *not_safe3; -@property (readonly) Foo *assign_plus1; -@property (readonly) Foo *assign_plus2; -@property (readonly) Foo *assign_plus3; - -@property (assign) Foo *no_user_ivar1; -@property (readonly) Foo *no_user_ivar2; - -@property (retain) id def1; -@property (atomic,retain) id def2; -@property (retain,atomic) id def3; - -@end - -@implementation Foo -@synthesize x,w,q1,q2,oo,bcw,not_safe1,not_safe2,not_safe3; -@synthesize no_user_ivar1, no_user_ivar2; -@synthesize assign_plus1, assign_plus2, assign_plus3; -@synthesize def1, def2, def3; - --(void)test:(Foo *)parm { - assign_plus1 = [[Foo alloc] init]; - assign_plus2 = [Foo new]; - assign_plus3 = [parm retain]; -} -@end - -@interface TestExt -@property (retain,readonly) TestExt *x1; -@property (readonly) TestExt *x2; -@end - -@interface TestExt() -@property (retain,readwrite) TestExt *x1; -@property (readwrite) TestExt *x2; -@property (retain) TestExt *x3; -@end - -@implementation TestExt -@synthesize x1, x2, x3; -@end diff --git a/clang/test/ARCMT/assign-prop-with-arc-runtime.m.result b/clang/test/ARCMT/assign-prop-with-arc-runtime.m.result deleted file mode 100644 index 8bb684f79a3399..00000000000000 --- a/clang/test/ARCMT/assign-prop-with-arc-runtime.m.result +++ /dev/null @@ -1,72 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface WeakOptOut -@end - -@class _NSCachedAttributedString; -typedef _NSCachedAttributedString *BadClassForWeak; - -@class Forw; - -@interface Foo : NSObject { - Foo *__weak x, *__weak w, *__weak q1, *__weak q2; - WeakOptOut *__unsafe_unretained oo; - BadClassForWeak __unsafe_unretained bcw; - id __unsafe_unretained not_safe1; - NSObject *__unsafe_unretained not_safe2; - Forw *__unsafe_unretained not_safe3; - Foo *assign_plus1; -} -@property (weak, readonly) Foo *x; -@property (weak) Foo *w; -@property (weak) Foo *q1, *q2; -@property (unsafe_unretained) WeakOptOut *oo; -@property (unsafe_unretained) BadClassForWeak bcw; -@property (unsafe_unretained) id not_safe1; -@property (unsafe_unretained) NSObject *not_safe2; -@property (unsafe_unretained) Forw *not_safe3; -@property (readonly) Foo *assign_plus1; -@property (readonly) Foo *assign_plus2; -@property (readonly) Foo *assign_plus3; - -@property (weak) Foo *no_user_ivar1; -@property (weak, readonly) Foo *no_user_ivar2; - -@property (strong) id def1; -@property (atomic,strong) id def2; -@property (strong,atomic) id def3; - -@end - -@implementation Foo -@synthesize x,w,q1,q2,oo,bcw,not_safe1,not_safe2,not_safe3; -@synthesize no_user_ivar1, no_user_ivar2; -@synthesize assign_plus1, assign_plus2, assign_plus3; -@synthesize def1, def2, def3; - --(void)test:(Foo *)parm { - assign_plus1 = [[Foo alloc] init]; - assign_plus2 = [Foo new]; - assign_plus3 = parm; -} -@end - -@interface TestExt -@property (strong,readonly) TestExt *x1; -@property (weak, readonly) TestExt *x2; -@end - -@interface TestExt() -@property (strong,readwrite) TestExt *x1; -@property (weak, readwrite) TestExt *x2; -@property (strong) TestExt *x3; -@end - -@implementation TestExt -@synthesize x1, x2, x3; -@end diff --git a/clang/test/ARCMT/atautorelease-2.m b/clang/test/ARCMT/atautorelease-2.m deleted file mode 100644 index b9bc1065532597..00000000000000 --- a/clang/test/ARCMT/atautorelease-2.m +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface NSAutoreleasePool -- drain; -+new; -+alloc; --init; --autorelease; --release; -@end - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; - - while (argc) { - [chunkPool release]; - return 0; - } - - [chunkPool drain]; - [pool drain]; - - return 0; -} diff --git a/clang/test/ARCMT/atautorelease-2.m.result b/clang/test/ARCMT/atautorelease-2.m.result deleted file mode 100644 index 205473380b7391..00000000000000 --- a/clang/test/ARCMT/atautorelease-2.m.result +++ /dev/null @@ -1,28 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface NSAutoreleasePool -- drain; -+new; -+alloc; --init; --autorelease; --release; -@end - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - @autoreleasepool { - @autoreleasepool { - - while (argc) { - return 0; - } - - } - } - - return 0; -} diff --git a/clang/test/ARCMT/atautorelease-3.m b/clang/test/ARCMT/atautorelease-3.m deleted file mode 100644 index 87b80af9350eb0..00000000000000 --- a/clang/test/ARCMT/atautorelease-3.m +++ /dev/null @@ -1,40 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface NSAutoreleasePool -- drain; -+new; -+alloc; --init; --autorelease; -- release; -@end - -void NSLog(id, ...); - -void test1(int x) { - // All this stuff get removed since nothing is happening inside. - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; - while (x) { - chunkPool = [[NSAutoreleasePool alloc] init]; - [chunkPool release]; - } - - [chunkPool drain]; - [pool drain]; -} - -void test2(int x) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; - while (x) { - chunkPool = [[NSAutoreleasePool alloc] init]; - ++x; - [chunkPool release]; - } - - [chunkPool drain]; - [pool drain]; -} diff --git a/clang/test/ARCMT/atautorelease-3.m.result b/clang/test/ARCMT/atautorelease-3.m.result deleted file mode 100644 index 801376a7e82bda..00000000000000 --- a/clang/test/ARCMT/atautorelease-3.m.result +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface NSAutoreleasePool -- drain; -+new; -+alloc; --init; --autorelease; -- release; -@end - -void NSLog(id, ...); - -void test1(int x) { - // All this stuff get removed since nothing is happening inside. -} - -void test2(int x) { - @autoreleasepool { - @autoreleasepool { - while (x) { - @autoreleasepool { - ++x; - } - } - - } - } -} diff --git a/clang/test/ARCMT/atautorelease-check.m b/clang/test/ARCMT/atautorelease-check.m deleted file mode 100644 index 5f8ffa8bc40ee2..00000000000000 --- a/clang/test/ARCMT/atautorelease-check.m +++ /dev/null @@ -1,144 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 %s - -#if __has_feature(objc_arr) -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) -#else -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE -#endif - -typedef struct _NSZone NSZone; -typedef int BOOL; -typedef unsigned NSUInteger; - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; - -- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -@end - -@protocol NSCopying -- (id)copyWithZone:(NSZone *)zone; -@end - -@protocol NSMutableCopying -- (id)mutableCopyWithZone:(NSZone *)zone; -@end - -@interface NSObject {} -- (id)init; - -+ (id)new; -+ (id)allocWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -+ (id)alloc; -- (void)dealloc; - -- (void)finalize; - -- (id)copy; -- (id)mutableCopy; - -+ (id)copyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -+ (id)mutableCopyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -@end - -extern void NSRecycleZone(NSZone *zone); - -NS_AUTOMATED_REFCOUNT_UNAVAILABLE -@interface NSAutoreleasePool : NSObject { // expected-note 13 {{marked unavailable here}} -@private - void *_token; - void *_reserved3; - void *_reserved2; - void *_reserved; -} - -+ (void)addObject:(id)anObject; - -- (void)addObject:(id)anObject; - -- (void)drain; - -@end - - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} - - while (argc) { - [chunkPool release]; - // the following pool was not released in this scope, don't touch it. - chunkPool = [[NSAutoreleasePool alloc] init]; // expected-error {{'NSAutoreleasePool' is unavailable}} - } - - [chunkPool drain]; - [pool drain]; - - return 0; -} - -void f(void) { - NSAutoreleasePool * pool; // expected-error {{'NSAutoreleasePool' is unavailable}} - - for (int i=0; i != 10; ++i) { - id x = pool; // We won't touch a NSAutoreleasePool if we can't safely - // remove all the references to it. - } - - pool = [[NSAutoreleasePool alloc] init]; // expected-error {{'NSAutoreleasePool' is unavailable}} - NSLog(@"%s", "YES"); - [pool release]; -} - -void f2(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ - // expected-note {{scope begins here}} - - // 'x' is declared inside the "pool scope" but used outside it, if we create - // a @autorelease scope it will be undefined outside it so don't touch the pool. - int x = 0; // expected-note {{declared here}} - - [pool release]; // expected-note {{scope ends here}} - - ++x; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} -} - -void f3(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ - // expected-note {{scope begins here}} - - struct S { int x; }; // expected-note {{declared here}} - - [pool release]; // expected-note {{scope ends here}} - - struct S *var; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} - var->x = 0; -} - -void f4(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ - // expected-note {{scope begins here}} - - enum { Bar }; // expected-note {{declared here}} - - [pool release]; // expected-note {{scope ends here}} - - int x = Bar; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} -} - -void f5(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ - // expected-note {{scope begins here}} - - typedef int Bar; // expected-note {{declared here}} - - [pool release]; // expected-note {{scope ends here}} - - Bar x; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} -} diff --git a/clang/test/ARCMT/atautorelease.m b/clang/test/ARCMT/atautorelease.m deleted file mode 100644 index a6aed146497b43..00000000000000 --- a/clang/test/ARCMT/atautorelease.m +++ /dev/null @@ -1,61 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - - if (argc) { - NSAutoreleasePool * pool = [NSAutoreleasePool new]; - NSLog(@"%s", "YES"); - [pool drain]; - } - [pool drain]; - - NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init]; - NSLog(@"%s", "YES"); - [pool1 release]; - - return 0; -} - -void f(void) { - NSAutoreleasePool *pool1; - - pool1 = [NSAutoreleasePool new]; - int x = 4; - - NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; - ++x; - [pool2 drain]; - - [pool1 release]; -} - -int UIApplicationMain(int argc, char *argv[]); - -int main2(int argc, char *argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - int result = UIApplicationMain(argc, argv); - [pool release]; - return result; -} - -@interface Foo : NSObject -@property (assign) id myProp; -@end - -@implementation Foo -@synthesize myProp; - --(void)test:(id)p { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [pool drain]; - self.myProp = p; -} -@end diff --git a/clang/test/ARCMT/atautorelease.m.result b/clang/test/ARCMT/atautorelease.m.result deleted file mode 100644 index e24339a3b9e36b..00000000000000 --- a/clang/test/ARCMT/atautorelease.m.result +++ /dev/null @@ -1,60 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - - @autoreleasepool { - - if (argc) { - @autoreleasepool { - NSLog(@"%s", "YES"); - } - } - } - - @autoreleasepool { - NSLog(@"%s", "YES"); - } - - return 0; -} - -void f(void) { - - @autoreleasepool { - int x = 4; - - @autoreleasepool { - ++x; - } - - } -} - -int UIApplicationMain(int argc, char *argv[]); - -int main2(int argc, char *argv[]) { - @autoreleasepool { - int result = UIApplicationMain(argc, argv); - return result; - } -} - -@interface Foo : NSObject -@property (unsafe_unretained) id myProp; -@end - -@implementation Foo -@synthesize myProp; - --(void)test:(id)p { - @autoreleasepool { - } - self.myProp = p; -} -@end diff --git a/clang/test/ARCMT/autoreleases.m b/clang/test/ARCMT/autoreleases.m deleted file mode 100644 index 4c268c09a715c6..00000000000000 --- a/clang/test/ARCMT/autoreleases.m +++ /dev/null @@ -1,75 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface A : NSObject { -@package - id object; -} -@end - -@interface B : NSObject { - id _prop; - xpc_object_t _xpc_prop; -} -- (BOOL)containsSelf:(A*)a; -@property (retain) id prop; -@property (retain) xpc_object_t xpc_prop; -@end - -@implementation A -@end - -@implementation B -- (BOOL)containsSelf:(A*)a { - return a->object == self; -} - --(id) prop { - return _prop; -} --(void) setProp:(id) newVal { - [_prop autorelease]; - _prop = [newVal retain]; -} --(void) setProp2:(CFTypeRef) newVal { - [_prop autorelease]; - _prop = (id)CFRetain(newVal); -} - --(id) xpc_prop { - return _xpc_prop; -} --(void) setXpc_prop:(xpc_object_t) newVal { - [_xpc_prop autorelease]; - _xpc_prop = xpc_retain(newVal); -} -@end - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - A *a = [[A new] autorelease]; - B *b = [[B new] autorelease]; - NSLog(@"%s", [b containsSelf:a] ? "YES" : "NO"); - [pool drain]; - return 0; -} - -void test(A *prevVal, A *newVal) { - [prevVal autorelease]; - prevVal = [newVal retain]; -} - -id test2(A* val) { - [[val retain] autorelease]; - return val; -} - -id test3(void) { - id a = [[A alloc] init]; - [a autorelease]; -} diff --git a/clang/test/ARCMT/autoreleases.m.result b/clang/test/ARCMT/autoreleases.m.result deleted file mode 100644 index b3aad804a45be6..00000000000000 --- a/clang/test/ARCMT/autoreleases.m.result +++ /dev/null @@ -1,69 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface A : NSObject { -@package - id object; -} -@end - -@interface B : NSObject { - id _prop; - xpc_object_t _xpc_prop; -} -- (BOOL)containsSelf:(A*)a; -@property (strong) id prop; -@property (strong) xpc_object_t xpc_prop; -@end - -@implementation A -@end - -@implementation B -- (BOOL)containsSelf:(A*)a { - return a->object == self; -} - --(id) prop { - return _prop; -} --(void) setProp:(id) newVal { - _prop = newVal; -} --(void) setProp2:(CFTypeRef) newVal { - _prop = (id)CFBridgingRelease(CFRetain(newVal)); -} - --(id) xpc_prop { - return _xpc_prop; -} --(void) setXpc_prop:(xpc_object_t) newVal { - _xpc_prop = newVal; -} -@end - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - @autoreleasepool { - A *a = [A new]; - B *b = [B new]; - NSLog(@"%s", [b containsSelf:a] ? "YES" : "NO"); - } - return 0; -} - -void test(A *prevVal, A *newVal) { - prevVal = newVal; -} - -id test2(A* val) { - return val; -} - -id test3(void) { - id a = [[A alloc] init]; -} diff --git a/clang/test/ARCMT/block_copy_release.m b/clang/test/ARCMT/block_copy_release.m deleted file mode 100644 index ae3b82660a8e43..00000000000000 --- a/clang/test/ARCMT/block_copy_release.m +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -typedef void (^blk)(int); - -void func(blk b) { - blk c = Block_copy(b); - Block_release(c); -} - -void func2(id b) { - id c = Block_copy(b); - Block_release(c); -} diff --git a/clang/test/ARCMT/block_copy_release.m.result b/clang/test/ARCMT/block_copy_release.m.result deleted file mode 100644 index b292b64f17d6bc..00000000000000 --- a/clang/test/ARCMT/block_copy_release.m.result +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -typedef void (^blk)(int); - -void func(blk b) { - blk c = [b copy]; -} - -void func2(id b) { - id c = [b copy]; -} diff --git a/clang/test/ARCMT/check-api.m b/clang/test/ARCMT/check-api.m deleted file mode 100644 index b395f0b4a4b975..00000000000000 --- a/clang/test/ARCMT/check-api.m +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-macosx10.7 %s - -#include "Common.h" - -@interface NSInvocation : NSObject -- (void)getReturnValue:(void *)retLoc; -- (void)setReturnValue:(void *)retLoc; - -- (void)getArgument:(void *)argumentLocation atIndex:(int)idx; -- (void)setArgument:(void *)argumentLocation atIndex:(int)idx; -@end - -@interface Test -@end - -@implementation Test { - id strong_id; - __weak id weak_id; - __unsafe_unretained id unsafe_id; - int arg; -} -- (void) test:(NSInvocation *)invok { - [invok getReturnValue:&strong_id]; // expected-error {{NSInvocation's getReturnValue is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok getReturnValue:&weak_id]; // expected-error {{NSInvocation's getReturnValue is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok getReturnValue:&unsafe_id]; - [invok getReturnValue:&arg]; - - [invok setReturnValue:&strong_id]; // expected-error {{NSInvocation's setReturnValue is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok setReturnValue:&weak_id]; // expected-error {{NSInvocation's setReturnValue is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok setReturnValue:&unsafe_id]; - [invok setReturnValue:&arg]; - - [invok getArgument:&strong_id atIndex:0]; // expected-error {{NSInvocation's getArgument is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok getArgument:&weak_id atIndex:0]; // expected-error {{NSInvocation's getArgument is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok getArgument:&unsafe_id atIndex:0]; - [invok getArgument:&arg atIndex:0]; - - [invok setArgument:&strong_id atIndex:0]; // expected-error {{NSInvocation's setArgument is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok setArgument:&weak_id atIndex:0]; // expected-error {{NSInvocation's setArgument is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok setArgument:&unsafe_id atIndex:0]; - [invok setArgument:&arg atIndex:0]; -} -@end diff --git a/clang/test/ARCMT/check-with-pch.m b/clang/test/ARCMT/check-with-pch.m deleted file mode 100644 index c2fda3b52cbc98..00000000000000 --- a/clang/test/ARCMT/check-with-pch.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin10 %S/Common.h -emit-pch -o %t.pch -// RUN: %clang_cc1 -include-pch %t.pch -arcmt-action=check -verify -triple x86_64-apple-darwin10 -fblocks -Werror %s -// REQUIRES: x86-registered-target - -@interface I9601437 { - __unsafe_unretained id x; -} --(void)Meth; -@end - -@implementation I9601437 --(void)Meth { - self->x = [NSObject new]; // expected-error {{assigning retained object}} -} -@end diff --git a/clang/test/ARCMT/check-with-serialized-diag.m b/clang/test/ARCMT/check-with-serialized-diag.m deleted file mode 100644 index 6102be037fcc1a..00000000000000 --- a/clang/test/ARCMT/check-with-serialized-diag.m +++ /dev/null @@ -1,55 +0,0 @@ - -@protocol NSObject -- (id)retain; -- (unsigned)retainCount; -- (oneway void)release; -- (id)autorelease; -@end - -@interface NSObject {} -- (id)init; - -+ (id)new; -+ (id)alloc; -- (void)dealloc; - -- (void)finalize; - -- (id)copy; -- (id)mutableCopy; -@end - -@interface A : NSObject -@end - -struct UnsafeS { - A *__unsafe_unretained unsafeObj; -}; - -id global_foo; - -void test1(A *a, struct UnsafeS *unsafeS) { - [unsafeS->unsafeObj retain]; - id foo = [unsafeS->unsafeObj retain]; // no warning. - [global_foo retain]; - [a retainCount]; -} - -// RUN: not %clang_cc1 -arcmt-action=check -triple x86_64-apple-darwin10 %s -serialize-diagnostic-file %t.diag -// RUN: c-index-test -read-diagnostics %t.diag > %t 2>&1 -// RUN: FileCheck --input-file=%t %s - -// CHECK: {{.*}}check-with-serialized-diag.m:32:4: error: [rewriter] it is not safe to remove 'retain' message on an __unsafe_unretained type -// CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:4: error: [rewriter] it is not safe to remove 'retain' message on a global variable -// CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:32:23: error: ARC forbids explicit message send of 'retain' -// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:32:4 {{.*}}check-with-serialized-diag.m:32:22 -// CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:15: error: ARC forbids explicit message send of 'retain' -// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:34:4 {{.*}}check-with-serialized-diag.m:34:14 -// CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:35:6: error: ARC forbids explicit message send of 'retainCount' -// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:35:4 {{.*}}check-with-serialized-diag.m:35:5 -// CHECK-NEXT: Number FIXITs = 0 - diff --git a/clang/test/ARCMT/checking-in-arc.m b/clang/test/ARCMT/checking-in-arc.m deleted file mode 100644 index 1bf6aca18a3428..00000000000000 --- a/clang/test/ARCMT/checking-in-arc.m +++ /dev/null @@ -1,50 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -fobjc-arc -fobjc-runtime=macosx-10.8.0 -triple x86_64-apple-darwin12 -fblocks -Werror %s - -#if __has_feature(objc_arc) -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) -#else -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE -#endif - -typedef const void * CFTypeRef; -CFTypeRef CFBridgingRetain(id X); -id CFBridgingRelease(CFTypeRef); - -typedef int BOOL; -typedef unsigned NSUInteger; - -@protocol NSObject -- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -@end - -@interface NSObject {} -- (id)init; - -+ (id)new; -+ (id)alloc; -- (void)dealloc; - -- (void)finalize; - -- (id)copy; -- (id)mutableCopy; -@end - -typedef const struct __CFString * CFStringRef; -extern const CFStringRef kUTTypePlainText; -extern const CFStringRef kUTTypeRTF; -@class NSString; - -@interface Test : NSObject -@property (weak) NSString *weakProperty; -@end - -@implementation Test -@end - -#if ! __has_feature(objc_arc) -#error This file must be compiled with ARC (set -fobjc_arc flag on file) -#endif diff --git a/clang/test/ARCMT/checking.m b/clang/test/ARCMT/checking.m deleted file mode 100644 index 5bc456c6301c08..00000000000000 --- a/clang/test/ARCMT/checking.m +++ /dev/null @@ -1,351 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 -fblocks -Werror %s - -#if __has_feature(objc_arc) -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) -#else -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE -#endif - -typedef const void * CFTypeRef; -CFTypeRef CFBridgingRetain(id X); -id CFBridgingRelease(CFTypeRef); - -typedef int BOOL; -typedef unsigned NSUInteger; - -@protocol NSObject -- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -@end - -@interface NSObject {} -- (id)init; - -+ (id)new; -+ (id)alloc; -- (void)dealloc; - -- (void)finalize; - -- (id)copy; -- (id)mutableCopy; -@end - -typedef const struct __CFString * CFStringRef; -extern const CFStringRef kUTTypePlainText; -extern const CFStringRef kUTTypeRTF; -@class NSString; -@class A; - -struct UnsafeS { - A *__unsafe_unretained unsafeObj; -}; - -@interface A : NSObject -- (id)retain __attribute__((unavailable)); // expected-note {{'retain' has been explicitly marked unavailable here}} -- (id)retainCount __attribute__((unavailable)); // expected-note {{'retainCount' has been explicitly marked unavailable here}} -- (id)autorelease __attribute__((unavailable)); // expected-note 2 {{'autorelease' has been explicitly marked unavailable here}} -- (id)init; -- (oneway void)release; -- (void)dealloc; --(void)test; --(id)delegate; -@end - -@implementation A --(void)test { - [super dealloc]; -} --(void)dealloc { - [super dealloc]; -} - -- (id)retain { return self; } // expected-error {{ARC forbids implementation}} -- (id)retainCount { return self; } // expected-error {{ARC forbids implementation}} -- (id)autorelease { return self; } // expected-error {{ARC forbids implementation}} -- (oneway void)release { } // expected-error {{ARC forbids implementation}} - --(id)delegate { return self; } -@end - -id global_foo; - -void test1(A *a, BOOL b, struct UnsafeS *unsafeS) { - [[a delegate] release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \ - // expected-error {{ARC forbids explicit message send}} - [a.delegate release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \ - // expected-error {{ARC forbids explicit message send}} - [unsafeS->unsafeObj retain]; // expected-error {{it is not safe to remove 'retain' message on an __unsafe_unretained type}} \ - // expected-error {{ARC forbids explicit message send}} \ - // expected-error {{'retain' is unavailable}} - id foo = [unsafeS->unsafeObj retain]; // no warning. - [global_foo retain]; // expected-error {{it is not safe to remove 'retain' message on a global variable}} \ - // expected-error {{ARC forbids explicit message send}} - [global_foo release]; // expected-error {{it is not safe to remove 'release' message on a global variable}} \ - // expected-error {{ARC forbids explicit message send}} - [a dealloc]; - [a retain]; - [a retainCount]; // expected-error {{ARC forbids explicit message send of 'retainCount'}} \ - // expected-error {{'retainCount' is unavailable}} - [a release]; - [a autorelease]; // expected-error {{it is not safe to remove an unused 'autorelease' message; its receiver may be destroyed immediately}} \ - // expected-error {{ARC forbids explicit message send}} \ - // expected-error {{'autorelease' is unavailable}} - [a autorelease]; // expected-error {{it is not safe to remove an unused 'autorelease' message; its receiver may be destroyed immediately}} \ - // expected-error {{ARC forbids explicit message send}} \ - // expected-error {{'autorelease' is unavailable}} - a = 0; - - CFStringRef cfstr; - NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} \ - str = (NSString *)kUTTypePlainText; - str = b ? kUTTypeRTF : kUTTypePlainText; - str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); - str = (NSString *)a; // no change. - - SEL s = @selector(retain); // expected-error {{ARC forbids use of 'retain' in a @selector}} - s = @selector(release); // expected-error {{ARC forbids use of 'release' in a @selector}} - s = @selector(autorelease); // expected-error {{ARC forbids use of 'autorelease' in a @selector}} - s = @selector(dealloc); // expected-error {{ARC forbids use of 'dealloc' in a @selector}} - - static id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}} -} - -struct S { - A* a; -}; - -@interface B --(id)alloc; -- (id)initWithInt: (int) i; -@end - -void rdar8861761(void) { - B *o1 = [[B alloc] initWithInt:0]; - B *o2 = [B alloc]; - [o2 initWithInt:0]; -} - -@interface Test13 -- (id) init0; -- (void) noninit; -@end -@implementation Test13 -- (id) init0 { - self = 0; -} -- (void) noninit { - self = 0; // expected-error {{cannot assign to 'self' outside of a method in the init family}} - - for (__strong id x in collection) { // expected-error {{use of undeclared identifier 'collection'}} - x = 0; - } -} -@end - -void * cvt(id arg) -{ - void* voidp_val; - (void)(int*)arg; // expected-error {{disallowed}} - (void)(id)arg; - (void)(__autoreleasing id*)arg; // expected-error {{disallowed}} - (void)(id*)arg; // expected-error {{disallowed}} - - (void)(__autoreleasing id**)voidp_val; - (void)(void*)voidp_val; - (void)(void**)arg; // expected-error {{disallowed}} - cvt((void*)arg); // expected-error 2 {{requires a bridged cast}} \ - // expected-note 2 {{use __bridge to}} expected-note {{use CFBridgingRelease call}} expected-note {{use CFBridgingRetain call}} - cvt(0); - (void)(__strong id**)(0); - return arg; // expected-error {{requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}} -} - - -void test12(id collection) { - for (id x in collection) { - x = 0; - } - - for (__strong id x in collection) { - x = 0; - } -} - -void test6(unsigned cond) { - switch (cond) { - case 0: - ; - id x; // expected-note {{jump bypasses initialization of __strong variable}} - - case 1: // expected-error {{cannot jump}} - x = 0; - break; - } -} - -@class Test8_incomplete; -@interface Test8_complete @end; -@interface Test8_super @end; -@interface Test8 : Test8_super -- (id) init00; -- (id) init01; // expected-note {{declaration in interface}} -- (id) init02; -- (id) init03; // covariance -- (id) init04; // covariance -- (id) init05; - -- (void) init10; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} -- (void) init11; -- (void) init12; -- (void) init13; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} -- (void) init14; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} -- (void) init15; - -// These should be invalid to actually call. -- (Test8_incomplete*) init20; -- (Test8_incomplete*) init21; // expected-note {{declaration in interface}} -- (Test8_incomplete*) init22; -- (Test8_incomplete*) init23; -- (Test8_incomplete*) init24; -- (Test8_incomplete*) init25; - -- (Test8_super*) init30; // id exception to covariance -- (Test8_super*) init31; // expected-note {{declaration in interface}} -- (Test8_super*) init32; -- (Test8_super*) init33; -- (Test8_super*) init34; // covariance -- (Test8_super*) init35; - -- (Test8*) init40; // id exception to covariance -- (Test8*) init41; // expected-note {{declaration in interface}} -- (Test8*) init42; -- (Test8*) init43; // this should be a warning, but that's a general language thing, not an ARC thing -- (Test8*) init44; -- (Test8*) init45; - -- (Test8_complete*) init50; // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init51; // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init52; // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init53; // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init54; // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init55; // expected-error {{init methods must return a type related to the receiver type}} -@end -@implementation Test8 -- (id) init00 { return 0; } -- (id) init10 { return 0; } // expected-error {{method implementation does not match its declaration}} -- (id) init20 { return 0; } -- (id) init30 { return 0; } -- (id) init40 { return 0; } -- (id) init50 { return 0; } - -- (void) init01 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} -- (void) init11 {} -- (void) init21 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} -- (void) init31 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} -- (void) init41 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} -- (void) init51 {} - -- (Test8_incomplete*) init02 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_incomplete*) init12 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_incomplete*) init22 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_incomplete*) init32 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_incomplete*) init42 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_incomplete*) init52 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} - -- (Test8_super*) init03 { return 0; } -- (Test8_super*) init13 { return 0; } // expected-error {{method implementation does not match its declaration}} -- (Test8_super*) init23 { return 0; } -- (Test8_super*) init33 { return 0; } -- (Test8_super*) init43 { return 0; } -- (Test8_super*) init53 { return 0; } - -- (Test8*) init04 { return 0; } -- (Test8*) init14 { return 0; } // expected-error {{method implementation does not match its declaration}} -- (Test8*) init24 { return 0; } -- (Test8*) init34 { return 0; } -- (Test8*) init44 { return 0; } -- (Test8*) init54 { return 0; } - -- (Test8_complete*) init05 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init15 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init25 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init35 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init45 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init55 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -@end - -@class Test9_incomplete; -@interface Test9 -- (Test9_incomplete*) init1; // expected-error {{init methods must return a type related to the receiver type}} -- (Test9_incomplete*) init2; -@end -id test9(Test9 *v) { - return [v init1]; -} - -void rdar9491791(int p) { - switch (p) { - case 3:; - NSObject *o = [[NSObject alloc] init]; - [o release]; - break; - default: - break; - } -} - -#define RELEASE_MACRO(x) do { [x release]; } while(1) - -void rdar9504750(id p) { - RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}} -} - -@interface TestReadonlyProperty : NSObject -@property(assign,readonly) NSObject *value; -@end - -@implementation TestReadonlyProperty -@synthesize value; -- (void)viewDidLoad { - value = [NSObject new]; // expected-error {{assigning retained object}} -} -@end - -@interface I9601437 { - __unsafe_unretained id x; -} --(void)Meth; -@end - -@implementation I9601437 --(void)Meth { - self->x = [NSObject new]; // expected-error {{assigning retained object}} -} -@end - -@interface Test10 : NSObject { - CFStringRef cfstr; -} -@property (retain) id prop; --(void)foo; -@end - -void test(Test10 *x) { - x.prop = ^{ [x foo]; }; // expected-warning {{likely to lead to a retain cycle}} \ - // expected-note {{retained by the captured object}} -} - -@implementation Test10 --(void)foo { - ^{ - NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} - }; -} -@end diff --git a/clang/test/ARCMT/cxx-checking.mm b/clang/test/ARCMT/cxx-checking.mm deleted file mode 100644 index f8836d9d7cd8df..00000000000000 --- a/clang/test/ARCMT/cxx-checking.mm +++ /dev/null @@ -1,100 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 -fsyntax-only -fblocks %s - -// Classes that have an Objective-C object pointer. -struct HasObjectMember0 { - id x; -}; - -struct HasObjectMember1 { - id x[3]; -}; - -struct HasObjectMember2 { - id x[3][2]; -}; - -// Don't complain if the type has non-external linkage -namespace { - struct HasObjectMember3 { - id x[3][2]; - }; -} - -// Don't complain if the Objective-C pointer type was explicitly given -// no lifetime. -struct HasObjectMember3 { - __unsafe_unretained id x[3][2]; -}; - -struct HasBlockPointerMember0 { - int (^bp)(int); -}; - -struct HasBlockPointerMember1 { - int (^bp[2][3])(int); -}; - -struct NonPOD { - NonPOD(const NonPOD&); -}; - -struct HasObjectMemberAndNonPOD0 { - id x; - NonPOD np; -}; - -struct HasObjectMemberAndNonPOD1 { - NonPOD np; - id x[3]; -}; - -struct HasObjectMemberAndNonPOD2 { - NonPOD np; - id x[3][2]; -}; - -struct HasObjectMemberAndNonPOD3 { - HasObjectMemberAndNonPOD3 &operator=(const HasObjectMemberAndNonPOD3&); - ~HasObjectMemberAndNonPOD3(); - NonPOD np; - id x[3][2]; -}; - -struct HasBlockPointerMemberAndNonPOD0 { - NonPOD np; - int (^bp)(int); -}; - -struct HasBlockPointerMemberAndNonPOD1 { - NonPOD np; - int (^bp[2][3])(int); -}; - -int check_non_pod_objc_pointer0[__is_pod(id)? 1 : -1]; -int check_non_pod_objc_pointer1[__is_pod(__strong id)? -1 : 1]; -int check_non_pod_objc_pointer2[__is_pod(__unsafe_unretained id)? 1 : -1]; -int check_non_pod_objc_pointer3[__is_pod(id[2][3])? 1 : -1]; -int check_non_pod_objc_pointer4[__is_pod(__unsafe_unretained id[2][3])? 1 : -1]; -int check_non_pod_block0[__is_pod(int (^)(int))? 1 : -1]; -int check_non_pod_block1[__is_pod(int (^ __unsafe_unretained)(int))? 1 : -1]; - -struct FlexibleArrayMember0 { - int length; - id array[]; // expected-error{{flexible array member 'array' of type '__strong id[]' with non-trivial destruction}} -}; - -struct FlexibleArrayMember1 { - int length; - __unsafe_unretained id array[]; -}; - -// It's okay to pass a retainable type through an ellipsis. -void variadic(...); -void test_variadic() { - variadic(1, 17, @"Foo"); -} - -// It's okay to create a VLA of retainable types. -void vla(int n) { - id vla[n]; -} diff --git a/clang/test/ARCMT/cxx-rewrite.mm b/clang/test/ARCMT/cxx-rewrite.mm deleted file mode 100644 index 4a9c50c92426e8..00000000000000 --- a/clang/test/ARCMT/cxx-rewrite.mm +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c++ %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface NSString : NSObject -+(id)string; -@end - -struct foo { - NSString *s; - foo(NSString *s): s([s retain]){ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - [[[NSString string] retain] release]; - [pool drain]; - if (s) - [s release]; - } - ~foo(){ [s release]; } -private: - foo(foo const &); - foo &operator=(foo const &); -}; - -int main(){ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - - foo f([[NSString string] autorelease]); - - [pool drain]; - return 0; -} diff --git a/clang/test/ARCMT/cxx-rewrite.mm.result b/clang/test/ARCMT/cxx-rewrite.mm.result deleted file mode 100644 index a96d254bf4633e..00000000000000 --- a/clang/test/ARCMT/cxx-rewrite.mm.result +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c++ %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface NSString : NSObject -+(id)string; -@end - -struct foo { - NSString *s; - foo(NSString *s): s(s){ - @autoreleasepool { - [NSString string]; - } - } - ~foo(){ } -private: - foo(foo const &); - foo &operator=(foo const &); -}; - -int main(){ - @autoreleasepool { - - foo f([NSString string]); - - } - return 0; -} diff --git a/clang/test/ARCMT/dealloc.m b/clang/test/ARCMT/dealloc.m deleted file mode 100644 index d7a72af4f726fe..00000000000000 --- a/clang/test/ARCMT/dealloc.m +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface A -- (id)retain; -- (id)autorelease; -- (oneway void)release; -- (void)dealloc; -@end - -void test1(A *a) { - [a dealloc]; -} - -@interface Test2 : A -- (void) dealloc; -@end - -@implementation Test2 -- (void) dealloc { - [super dealloc]; -} -@end diff --git a/clang/test/ARCMT/dealloc.m.result b/clang/test/ARCMT/dealloc.m.result deleted file mode 100644 index fbd9e445d27512..00000000000000 --- a/clang/test/ARCMT/dealloc.m.result +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface A -- (id)retain; -- (id)autorelease; -- (oneway void)release; -- (void)dealloc; -@end - -void test1(A *a) { -} - -@interface Test2 : A -- (void) dealloc; -@end - -@implementation Test2 -@end diff --git a/clang/test/ARCMT/designated-init-in-header/designated-init-in-header.m b/clang/test/ARCMT/designated-init-in-header/designated-init-in-header.m deleted file mode 100644 index 8286583b3c898a..00000000000000 --- a/clang/test/ARCMT/designated-init-in-header/designated-init-in-header.m +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %clang_cc1 -objcmt-migrate-designated-init -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -x objective-c %S/file1.m.in -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t1.remap -// RUN: %clang_cc1 -objcmt-migrate-designated-init -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -x objective-c %S/file2.m.in -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t2.remap -// RUN: c-arcmt-test %t1.remap %t2.remap | arcmt-test -verify-transformed-files %S/header1.h.result %S/file2.m.in.result diff --git a/clang/test/ARCMT/designated-init-in-header/file1.m.in b/clang/test/ARCMT/designated-init-in-header/file1.m.in deleted file mode 100644 index 0201b32abd323d..00000000000000 --- a/clang/test/ARCMT/designated-init-in-header/file1.m.in +++ /dev/null @@ -1,2 +0,0 @@ -#include "header1.h" - diff --git a/clang/test/ARCMT/designated-init-in-header/file2.m.in b/clang/test/ARCMT/designated-init-in-header/file2.m.in deleted file mode 100644 index 258159735a77f5..00000000000000 --- a/clang/test/ARCMT/designated-init-in-header/file2.m.in +++ /dev/null @@ -1,14 +0,0 @@ -#include "header1.h" - -@implementation S1 --(int)prop { return 0; } --(void)setProp:(int)p {} -+(id)s1 { return 0; } --(id)initWithFoo:(NSString*)foo -{ - self = [super init]; - if (self) { - } - return self; -} -@end diff --git a/clang/test/ARCMT/designated-init-in-header/file2.m.in.result b/clang/test/ARCMT/designated-init-in-header/file2.m.in.result deleted file mode 100644 index 7465ed576f5ff9..00000000000000 --- a/clang/test/ARCMT/designated-init-in-header/file2.m.in.result +++ /dev/null @@ -1,14 +0,0 @@ -#include "header1.h" - -@implementation S1 --(int)prop { return 0; } --(void)setProp:(int)p {} -+(instancetype)s1 { return 0; } --(instancetype)initWithFoo:(NSString*)foo -{ - self = [super init]; - if (self) { - } - return self; -} -@end diff --git a/clang/test/ARCMT/designated-init-in-header/header1.h b/clang/test/ARCMT/designated-init-in-header/header1.h deleted file mode 100644 index c5668cc460869c..00000000000000 --- a/clang/test/ARCMT/designated-init-in-header/header1.h +++ /dev/null @@ -1,14 +0,0 @@ -#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) - -@class NSString; - -@interface B1 --(id)init; -@end - -@interface S1 : B1 --(int)prop; --(void)setProp:(int)p; -+(id)s1; --(id)initWithFoo:(NSString*)foo; -@end diff --git a/clang/test/ARCMT/designated-init-in-header/header1.h.result b/clang/test/ARCMT/designated-init-in-header/header1.h.result deleted file mode 100644 index 974175b1c3e639..00000000000000 --- a/clang/test/ARCMT/designated-init-in-header/header1.h.result +++ /dev/null @@ -1,13 +0,0 @@ -#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) - -@class NSString; - -@interface B1 --(instancetype)init; -@end - -@interface S1 : B1 -@property (nonatomic) int prop; -+(instancetype)s1; --(instancetype)initWithFoo:(NSString*)foo NS_DESIGNATED_INITIALIZER; -@end diff --git a/clang/test/ARCMT/dispatch.m b/clang/test/ARCMT/dispatch.m deleted file mode 100644 index 58c7769638cbe7..00000000000000 --- a/clang/test/ARCMT/dispatch.m +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -dispatch_object_t getme(void); - -void func(dispatch_object_t o) { - dispatch_retain(o); - dispatch_release(o); - dispatch_retain(getme()); -} - -void func2(xpc_object_t o) { - xpc_retain(o); - xpc_release(o); -} diff --git a/clang/test/ARCMT/dispatch.m.result b/clang/test/ARCMT/dispatch.m.result deleted file mode 100644 index 55b65585e4f6c2..00000000000000 --- a/clang/test/ARCMT/dispatch.m.result +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -dispatch_object_t getme(void); - -void func(dispatch_object_t o) { - getme(); -} - -void func2(xpc_object_t o) { -} diff --git a/clang/test/ARCMT/driver-migrate.m b/clang/test/ARCMT/driver-migrate.m deleted file mode 100644 index ec3f4cc8c4a312..00000000000000 --- a/clang/test/ARCMT/driver-migrate.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang -### -ccc-arcmt-migrate /foo/bar -fsyntax-only %s 2>&1 | FileCheck %s - -// CHECK: "-arcmt-action=migrate" "-mt-migrate-directory" "{{[^"]*}}/foo/bar" - -// RUN: touch %t.o -// RUN: %clang -ccc-arcmt-check -target i386-apple-darwin9 -### %t.o 2> %t.log -// RUN: FileCheck -check-prefix=LINK %s < %t.log -// RUN: %clang -ccc-arcmt-migrate /foo/bar -target i386-apple-darwin9 -### %t.o 2> %t.log -// RUN: FileCheck -check-prefix=LINK %s < %t.log - -// LINK-NOT: {{ld(.exe)?"}} -// LINK: {{touch(.exe)?"}} - -// RUN: %clang -### -ccc-arcmt-migrate /foo/bar -fsyntax-only -fno-objc-arc %s 2>&1 | FileCheck -check-prefix=CHECK-NOARC %s -// CHECK-NOARC-NOT: argument unused during compilation diff --git a/clang/test/ARCMT/init.m b/clang/test/ARCMT/init.m deleted file mode 100644 index b1f127e54fd1b4..00000000000000 --- a/clang/test/ARCMT/init.m +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil (void *)0 - -@interface NSObject --init; -@end - -@interface A : NSObject --init; --init2; --foo; -+alloc; -@end - -@implementation A --(id) init { - [self init]; - id a; - [a init]; - a = [[A alloc] init]; - - return self; -} - --(id) init2 { - [super init]; - return self; -} - --(id) foo { - [self init]; - [super init]; - - return self; -} -@end diff --git a/clang/test/ARCMT/init.m.result b/clang/test/ARCMT/init.m.result deleted file mode 100644 index d550dedb1dc191..00000000000000 --- a/clang/test/ARCMT/init.m.result +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil (void *)0 - -@interface NSObject --init; -@end - -@interface A : NSObject --init; --init2; --foo; -+alloc; -@end - -@implementation A --(id) init { - if (!(self = [self init])) return nil; - id a; - [a init]; - a = [[A alloc] init]; - - return self; -} - --(id) init2 { - if (!(self = [super init])) return nil; - return self; -} - --(id) foo { - [self init]; - [super init]; - - return self; -} -@end diff --git a/clang/test/ARCMT/lit.local.cfg b/clang/test/ARCMT/lit.local.cfg deleted file mode 100644 index e9b04164d69df8..00000000000000 --- a/clang/test/ARCMT/lit.local.cfg +++ /dev/null @@ -1,2 +0,0 @@ -if not config.root.clang_arcmt: - config.unsupported = True diff --git a/clang/test/ARCMT/migrate-emit-errors.m b/clang/test/ARCMT/migrate-emit-errors.m deleted file mode 100644 index 3e33acf75a5914..00000000000000 --- a/clang/test/ARCMT/migrate-emit-errors.m +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t -arcmt-migrate-emit-errors %s 2>&1 | FileCheck %s -// RUN: rm -rf %t - -@protocol NSObject -- (oneway void)release; -@end - -void test(id p) { - [p release]; -} - -// CHECK: error: ARC forbids explicit message send of 'release' diff --git a/clang/test/ARCMT/migrate-on-pch-and-module.m b/clang/test/ARCMT/migrate-on-pch-and-module.m deleted file mode 100644 index 42e01ea91a9c72..00000000000000 --- a/clang/test/ARCMT/migrate-on-pch-and-module.m +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: rm -rf %t-mcp -// RUN: %clang_cc1 -objcmt-migrate-subscripting -emit-pch -o %t.pch %s -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -F %S/Inputs -fmodules -fimplicit-module-maps -fmodules-cache-path=%t-mcp -w -// RUN: %clang_cc1 -objcmt-migrate-subscripting -include-pch %t.pch %s -migrate -o %t.remap -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -F %S/Inputs -fmodules -fimplicit-module-maps -fmodules-cache-path=%t-mcp -// REQUIRES: x86-registered-target -#ifndef HEADER -#define HEADER - -@import Module; - -#else - -#endif diff --git a/clang/test/ARCMT/migrate-plist-output.m b/clang/test/ARCMT/migrate-plist-output.m deleted file mode 100644 index e5710d818eccc6..00000000000000 --- a/clang/test/ARCMT/migrate-plist-output.m +++ /dev/null @@ -1,51 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t.dir -arcmt-migrate-report-output %t.plist %s -// RUN: FileCheck %s -input-file=%t.plist -// RUN: rm -rf %t.dir - -@protocol NSObject -- (oneway void)release; -@end - -void test(id p) { - [p release]; -} - -// CHECK: -// CHECK: -// CHECK: -// CHECK: -// CHECK: files -// CHECK: -// CHECK: -// CHECK: diagnostics -// CHECK: -// CHECK: -// CHECK: descriptionARC forbids explicit message send of 'release' -// CHECK: categoryARC Restrictions -// CHECK: typeerror -// CHECK: location -// CHECK: -// CHECK: line10 -// CHECK: col6 -// CHECK: file0 -// CHECK: -// CHECK: ranges -// CHECK: -// CHECK: -// CHECK: -// CHECK: line10 -// CHECK: col4 -// CHECK: file0 -// CHECK: -// CHECK: -// CHECK: line10 -// CHECK: col4 -// CHECK: file0 -// CHECK: -// CHECK: -// CHECK: -// CHECK: -// CHECK: -// CHECK: -// CHECK: - diff --git a/clang/test/ARCMT/migrate-space-in-path.m b/clang/test/ARCMT/migrate-space-in-path.m deleted file mode 100644 index 14a464d438f40d..00000000000000 --- a/clang/test/ARCMT/migrate-space-in-path.m +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: rm -rf %t.migrate -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t.migrate %S/Inputs/"with space"/test1.m.in -x objective-c -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t.migrate %S/Inputs/"with space"/test2.m.in -x objective-c -// RUN: c-arcmt-test -mt-migrate-directory %t.migrate | arcmt-test -verify-transformed-files %S/Inputs/"with space"/test1.m.in.result %S/Inputs/"with space"/test2.m.in.result %S/Inputs/"with space"/test.h.result -// RUN: rm -rf %t.migrate diff --git a/clang/test/ARCMT/migrate-with-pch.m b/clang/test/ARCMT/migrate-with-pch.m deleted file mode 100644 index d8e261be13d855..00000000000000 --- a/clang/test/ARCMT/migrate-with-pch.m +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -x objective-c %S/Common.h -emit-pch -o %t.pch -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t %S/Inputs/test1.m.in -x objective-c -include-pch %t.pch -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t %S/Inputs/test2.m.in -x objective-c -include-pch %t.pch -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %S/Inputs/test1.m.in.result %S/Inputs/test2.m.in.result %S/Inputs/test.h.result -// RUN: rm -rf %t diff --git a/clang/test/ARCMT/migrate.m b/clang/test/ARCMT/migrate.m deleted file mode 100644 index bc819df1c8a110..00000000000000 --- a/clang/test/ARCMT/migrate.m +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t %S/Inputs/test1.m.in -x objective-c -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t %S/Inputs/test2.m.in -x objective-c -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %S/Inputs/test1.m.in.result %S/Inputs/test2.m.in.result %S/Inputs/test.h.result -// RUN: rm -rf %t diff --git a/clang/test/ARCMT/no-canceling-bridge-to-bridge-cast.m b/clang/test/ARCMT/no-canceling-bridge-to-bridge-cast.m deleted file mode 100644 index be493949515233..00000000000000 --- a/clang/test/ARCMT/no-canceling-bridge-to-bridge-cast.m +++ /dev/null @@ -1,41 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -verify %s -typedef const void * CFTypeRef; -CFTypeRef CFBridgingRetain(id X); -id CFBridgingRelease(CFTypeRef); - -extern -CFTypeRef CFRetain(CFTypeRef cf); - -@interface INTF -{ - void *cf_format; - id objc_format; -} -@end - -@interface NSString -+ (id)stringWithFormat:(NSString *)format; -@end - -@implementation INTF -- (void) Meth { - NSString *result; - - result = (id) CFRetain([NSString stringWithFormat:@"PBXLoopMode"]); // expected-error {{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}} - - result = (id) CFRetain((id)((objc_format))); // expected-error {{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}} - - result = (id) CFRetain((id)((cf_format))); // expected-error {{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}} - - result = (id) CFRetain((CFTypeRef)((objc_format))); - - result = (id) CFRetain(cf_format); // OK -} -@end - diff --git a/clang/test/ARCMT/nonobjc-to-objc-cast-2.m b/clang/test/ARCMT/nonobjc-to-objc-cast-2.m deleted file mode 100644 index 391c636906d53e..00000000000000 --- a/clang/test/ARCMT/nonobjc-to-objc-cast-2.m +++ /dev/null @@ -1,63 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 %s - -#include "Common.h" - -typedef const struct __CFString * CFStringRef; -typedef const void * CFTypeRef; -CFTypeRef CFBridgingRetain(id X); -id CFBridgingRelease(CFTypeRef); - -struct StrS { - CFStringRef sref_member; -}; - -@interface NSString : NSObject { - CFStringRef sref; - struct StrS *strS; -} --(id)string; --(id)newString; -@end - -@implementation NSString --(id)string { - if (0) - return sref; - else - return strS->sref_member; -} --(id)newString { - return sref; // expected-error {{implicit conversion of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'id' requires a bridged cast}} \ - // expected-note{{use __bridge to convert directly (no change in ownership)}} \ - // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} -} -@end - -void f(BOOL b) { - CFStringRef cfstr; - NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ - // expected-note{{use __bridge to convert directly (no change in ownership)}} \ - // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} - void *vp = str; // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRetain call}} expected-note {{use __bridge}} -} - -void f2(NSString *s) { - CFStringRef ref; - ref = [(CFStringRef)[s string] retain]; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef' (aka 'const struct __CFString *') requires a bridged cast}} \ - // expected-error {{bad receiver type 'CFStringRef' (aka 'const struct __CFString *')}} \ - // expected-note{{use __bridge to convert directly (no change in ownership)}} \ - // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFStringRef' (aka 'const struct __CFString *')}} -} - -CFStringRef f3(void) { - return (CFStringRef)[[[NSString alloc] init] autorelease]; // expected-error {{it is not safe to cast to 'CFStringRef' the result of 'autorelease' message; a __bridge cast may result in a pointer to a destroyed object and a __bridge_retained may leak the object}} \ - // expected-note {{remove the cast and change return type of function to 'NSString *' to have the object automatically autoreleased}} -} - -extern void NSLog(NSString *format, ...); - -void f4(NSString *s) { - NSLog(@"%@", (CFStringRef)s); // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFStringRef' (aka 'const struct __CFString *') requires a bridged cast}} \ - // expected-note{{use __bridge to convert directly (no change in ownership)}} \ - // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFStringRef' (aka 'const struct __CFString *')}} -} diff --git a/clang/test/ARCMT/nonobjc-to-objc-cast.m b/clang/test/ARCMT/nonobjc-to-objc-cast.m deleted file mode 100644 index 7913661787e509..00000000000000 --- a/clang/test/ARCMT/nonobjc-to-objc-cast.m +++ /dev/null @@ -1,83 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -typedef const struct __CFString * CFStringRef; -extern const CFStringRef kUTTypePlainText; -extern const CFStringRef kUTTypeRTF; -extern CFStringRef kNonConst; - -typedef const struct __CFAllocator * CFAllocatorRef; -typedef const struct __CFUUID * CFUUIDRef; - -extern const CFAllocatorRef kCFAllocatorDefault; - -extern CFStringRef CFUUIDCreateString(CFAllocatorRef alloc, CFUUIDRef uuid); - -struct StrS { - CFStringRef sref_member; -}; - -@interface NSString : NSObject { - CFStringRef sref; - struct StrS *strS; -} --(id)string; --(id)newString; -@end - -void f(BOOL b, id p) { - NSString *str = (NSString *)kUTTypePlainText; // no change - str = b ? kUTTypeRTF : kUTTypePlainText; // no change - str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); // no change - str = (NSString *)p; // no change. - - str = (NSString *)kNonConst; - str = b ? kUTTypeRTF : kNonConst; - str = (NSString *)(b ? kUTTypeRTF : kNonConst); - - CFUUIDRef _uuid; - NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid); - _uuidString = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid) autorelease]; - _uuidString = CFRetain(_uuid); -} - -@implementation NSString (StrExt) -- (NSString *)stringEscapedAsURI { - CFStringRef str = (CFStringRef)self; - CFStringRef str2 = self; - return self; -} -@end - -@implementation NSString --(id)string { - if (0) - return sref; - else - return strS->sref_member; -} --(id)newString { return 0; } -@end - -extern void consumeParam(CFStringRef CF_CONSUMED p); - -void f2(NSString *s) { - CFStringRef ref = [s string]; - ref = (CFStringRef)[s string]; - ref = s.string; - ref = [NSString new]; - ref = [s newString]; - ref = (CFStringRef)[NSString new]; - ref = [[NSString alloc] init]; - ref = [[s string] retain]; - ref = CFRetain((CFStringRef)[s string]); - ref = CFRetain([s string]); - ref = CFRetain(s); - ref = [s retain]; - - consumeParam((CFStringRef)s); - consumeParam(s); -} diff --git a/clang/test/ARCMT/nonobjc-to-objc-cast.m.result b/clang/test/ARCMT/nonobjc-to-objc-cast.m.result deleted file mode 100644 index 8f3092f8786d8b..00000000000000 --- a/clang/test/ARCMT/nonobjc-to-objc-cast.m.result +++ /dev/null @@ -1,83 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -typedef const struct __CFString * CFStringRef; -extern const CFStringRef kUTTypePlainText; -extern const CFStringRef kUTTypeRTF; -extern CFStringRef kNonConst; - -typedef const struct __CFAllocator * CFAllocatorRef; -typedef const struct __CFUUID * CFUUIDRef; - -extern const CFAllocatorRef kCFAllocatorDefault; - -extern CFStringRef CFUUIDCreateString(CFAllocatorRef alloc, CFUUIDRef uuid); - -struct StrS { - CFStringRef sref_member; -}; - -@interface NSString : NSObject { - CFStringRef sref; - struct StrS *strS; -} --(id)string; --(id)newString; -@end - -void f(BOOL b, id p) { - NSString *str = (NSString *)kUTTypePlainText; // no change - str = b ? kUTTypeRTF : kUTTypePlainText; // no change - str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); // no change - str = (NSString *)p; // no change. - - str = (__bridge NSString *)kNonConst; - str = (__bridge NSString *)(b ? kUTTypeRTF : kNonConst); - str = (__bridge NSString *)(b ? kUTTypeRTF : kNonConst); - - CFUUIDRef _uuid; - NSString *_uuidString = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid)); - _uuidString = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid)); - _uuidString = CFBridgingRelease(CFRetain(_uuid)); -} - -@implementation NSString (StrExt) -- (NSString *)stringEscapedAsURI { - CFStringRef str = (__bridge CFStringRef)self; - CFStringRef str2 = (__bridge CFStringRef)(self); - return self; -} -@end - -@implementation NSString --(id)string { - if (0) - return (__bridge id)(sref); - else - return (__bridge id)(strS->sref_member); -} --(id)newString { return 0; } -@end - -extern void consumeParam(CFStringRef CF_CONSUMED p); - -void f2(NSString *s) { - CFStringRef ref = (__bridge CFStringRef)([s string]); - ref = (__bridge CFStringRef)[s string]; - ref = (__bridge CFStringRef)(s.string); - ref = CFBridgingRetain([NSString new]); - ref = CFBridgingRetain([s newString]); - ref = (CFStringRef)CFBridgingRetain([NSString new]); - ref = CFBridgingRetain([[NSString alloc] init]); - ref = CFBridgingRetain([s string]); - ref = (CFStringRef)CFBridgingRetain([s string]); - ref = CFBridgingRetain([s string]); - ref = CFBridgingRetain(s); - ref = CFBridgingRetain(s); - - consumeParam((CFStringRef)CFBridgingRetain(s)); - consumeParam(CFBridgingRetain(s)); -} diff --git a/clang/test/ARCMT/objcmt-arc-cf-annotations.m b/clang/test/ARCMT/objcmt-arc-cf-annotations.m deleted file mode 100644 index 47c83ac9e3dd55..00000000000000 --- a/clang/test/ARCMT/objcmt-arc-cf-annotations.m +++ /dev/null @@ -1,2017 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-annotation -objcmt-migrate-instancetype -objcmt-migrate-readwrite-property -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -#ifndef CF_IMPLICIT_BRIDGING_ENABLED -#if __has_feature(arc_cf_code_audited) -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") -#else -#define CF_IMPLICIT_BRIDGING_ENABLED -#endif -#endif - -#ifndef CF_IMPLICIT_BRIDGING_DISABLED -#if __has_feature(arc_cf_code_audited) -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") -#else -#define CF_IMPLICIT_BRIDGING_DISABLED -#endif -#endif - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -//===----------------------------------------------------------------------===// -// The following code is reduced using delta-debugging from Mac OS X headers: -// -// #include -// #include -// #include -// #include -// #include -// #include -// -// It includes the basic definitions for the test cases below. -//===----------------------------------------------------------------------===// - -typedef unsigned int __darwin_natural_t; -typedef unsigned long uintptr_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -typedef unsigned int UInt32; -typedef signed long CFIndex; -typedef CFIndex CFByteOrder; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; -static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) { - CFRange range; - range.location = loc; - range.length = len; - return range; -} -typedef const void * CFTypeRef; -typedef const struct __CFString * CFStringRef; -typedef const struct __CFAllocator * CFAllocatorRef; -extern const CFAllocatorRef kCFAllocatorDefault; -extern CFTypeRef CFRetain(CFTypeRef cf); -extern void CFRelease(CFTypeRef cf); -extern CFTypeRef CFAutorelease(CFTypeRef cf); -extern CFTypeRef CFMakeCollectable(CFTypeRef cf); -typedef struct { -} -CFArrayCallBacks; -extern const CFArrayCallBacks kCFTypeArrayCallBacks; -typedef const struct __CFArray * CFArrayRef; -typedef struct __CFArray * CFMutableArrayRef; -extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); -extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); -extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); -typedef struct { -} -CFDictionaryKeyCallBacks; -extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; -typedef struct { -} -CFDictionaryValueCallBacks; -extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; -extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); -typedef UInt32 CFStringEncoding; -enum { -kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 }; -extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); -typedef double CFTimeInterval; -typedef CFTimeInterval CFAbsoluteTime; -extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); -typedef const struct __CFDate * CFDateRef; -extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); -extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); -typedef __darwin_natural_t natural_t; -typedef natural_t mach_port_name_t; -typedef mach_port_name_t mach_port_t; -typedef int kern_return_t; -typedef kern_return_t mach_error_t; -enum { -kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 }; -typedef CFIndex CFNumberType; -typedef const struct __CFNumber * CFNumberRef; -extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; -extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ; -extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ; -extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ; -typedef signed char BOOL; -typedef unsigned long NSUInteger; -@class NSString, Protocol; -extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); -typedef struct _NSZone NSZone; -@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -- (id)autorelease; -- (NSString *)description; -- (id)init; -@end -@protocol NSCopying -- (id)copyWithZone:(NSZone *)zone; -@end -@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; -@end -@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; -@end -@interface NSObject {} -+ (id)allocWithZone:(NSZone *)zone; -+ (id)alloc; -+ (id)new; -- (void)dealloc; -@end -@interface NSObject (NSCoderMethods) -- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; -@end -extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); -typedef struct { -} -NSFastEnumerationState; -@protocol NSFastEnumeration -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; -@end -@class NSString, NSDictionary; -@interface NSValue : NSObject - (void)getValue:(void *)value; -@end -@interface NSNumber : NSValue -- (char)charValue; -- (id)initWithInt:(int)value; -+ (NSNumber *)numberWithInt:(int)value; -@end -@class NSString; -@interface NSArray : NSObject -- (NSUInteger)count; -- (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; -+ (id)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); -- (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); -- (id)initWithArray:(NSArray *)array; -@end @interface NSArray (NSArrayCreation) + (id)array; -@end @interface NSAutoreleasePool : NSObject { -} -- (void)drain; -@end extern NSString * const NSBundleDidLoadNotification; -typedef double NSTimeInterval; -@interface NSDate : NSObject - (NSTimeInterval)timeIntervalSinceReferenceDate; -@end typedef unsigned short unichar; -@interface NSString : NSObject -- (NSUInteger)length; -- (NSString *)stringByAppendingString:(NSString *)aString; -- ( const char *)UTF8String; -- (id)initWithUTF8String:(const char *)nullTerminatedCString; -+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; -@end @class NSString, NSURL, NSError; -@interface NSData : NSObject - (NSUInteger)length; -+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; -+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; -@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; -@interface NSDictionary : NSObject -- (NSUInteger)count; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt; -@end -@interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; -- (void)setObject:(id)anObject forKey:(id)aKey; -@end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (id)dictionaryWithCapacity:(NSUInteger)numItems; -@end typedef double CGFloat; -struct CGSize { -}; -typedef struct CGSize CGSize; -struct CGRect { -}; -typedef struct CGRect CGRect; -typedef mach_port_t io_object_t; -typedef char io_name_t[128]; -typedef io_object_t io_iterator_t; -typedef io_object_t io_service_t; -typedef struct IONotificationPort * IONotificationPortRef; -typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator ); -io_service_t IOServiceGetMatchingService( mach_port_t mainPort, CFDictionaryRef matching ); -kern_return_t IOServiceGetMatchingServices( mach_port_t mainPort, CFDictionaryRef matching, io_iterator_t * existing ); -kern_return_t IOServiceAddNotification( mach_port_t mainPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); // expected-note {{'IOServiceAddNotification' declared here}} -kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification ); -CFMutableDictionaryRef IOServiceMatching( const char * name ); -CFMutableDictionaryRef IOServiceNameMatching( const char * name ); -CFMutableDictionaryRef IOBSDNameMatching( mach_port_t mainPort, uint32_t options, const char * bsdName ); -CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t mainPort, uint32_t options, const char * path ); -CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID ); -typedef struct __DASession * DASessionRef; -extern DASessionRef DASessionCreate( CFAllocatorRef allocator ); -typedef struct __DADisk * DADiskRef; -extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ); -extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ); -extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ); -extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ); -@interface NSTask : NSObject - (id)init; -@end typedef struct CGColorSpace *CGColorSpaceRef; -typedef struct CGImage *CGImageRef; -typedef struct CGLayer *CGLayerRef; -@interface NSResponder : NSObject { -} -@end @protocol NSAnimatablePropertyContainer - (id)animator; -@end extern NSString *NSAnimationTriggerOrderIn ; -@interface NSView : NSResponder { -} -@end @protocol NSValidatedUserInterfaceItem - (SEL)action; -@end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id )anItem; -@end @class NSDate, NSDictionary, NSError, NSException, NSNotification; -@class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; -@interface NSApplication : NSResponder { -} -- (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo; -@end enum { -NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; -typedef NSUInteger NSApplicationTerminateReply; -@protocol NSApplicationDelegate @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; -@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; -@interface NSCell : NSObject { -} -@end -typedef struct { -} -CVTimeStamp; -@interface CIImage : NSObject { -} -typedef int CIFormat; -@end enum { -kDAReturnSuccess = 0, kDAReturnError = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01, kDAReturnBusy = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02, kDAReturnBadArgument = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03, kDAReturnExclusiveAccess = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04, kDAReturnNoResources = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05, kDAReturnNotFound = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06, kDAReturnNotMounted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07, kDAReturnNotPermitted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08, kDAReturnNotPrivileged = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09, kDAReturnNotReady = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A, kDAReturnNotWritable = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B, kDAReturnUnsupported = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C }; -typedef mach_error_t DAReturn; -typedef const struct __DADissenter * DADissenterRef; -extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ); -@interface CIContext: NSObject { -} -- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r; -- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs; -- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d; -@end extern NSString* const QCRendererEventKey; -@protocol QCCompositionRenderer - (NSDictionary*) attributes; -@end @interface QCRenderer : NSObject { -} -- (id) createSnapshotImageOfType:(NSString*)type; -@end extern NSString* const QCViewDidStartRenderingNotification; -@interface QCView : NSView { -} -- (id) createSnapshotImageOfType:(NSString*)type; -@end enum { -ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, }; -@class ICDevice; -@protocol ICDeviceDelegate @required - (void)didRemoveDevice:(ICDevice*)device; -@end extern NSString *const ICScannerStatusWarmingUp; -@class ICScannerDevice; -@protocol ICScannerDeviceDelegate @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner; -@end - -typedef long unsigned int __darwin_size_t; -typedef __darwin_size_t size_t; -typedef unsigned long CFTypeID; -struct CGPoint { - CGFloat x; - CGFloat y; -}; -typedef struct CGPoint CGPoint; -typedef struct CGGradient *CGGradientRef; -typedef uint32_t CGGradientDrawingOptions; -extern CFTypeID CGGradientGetTypeID(void); -extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef - space, const CGFloat components[], const CGFloat locations[], size_t count); -extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, - CFArrayRef colors, const CGFloat locations[]); -extern CGGradientRef CGGradientRetain(CGGradientRef gradient); -extern void CGGradientRelease(CGGradientRef gradient); -typedef struct CGContext *CGContextRef; -extern void CGContextDrawLinearGradient(CGContextRef context, - CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, - CGGradientDrawingOptions options); -extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); - -@interface NSMutableArray : NSObject -- (void)addObject:(id)object; -+ (id)array; -@end - -// This is how NSMakeCollectable is declared in the OS X 10.8 headers. -id NSMakeCollectable(CFTypeRef __attribute__((cf_consumed))) __attribute__((ns_returns_retained)); - -typedef const struct __CFUUID * CFUUIDRef; - -extern -void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID); - -//===----------------------------------------------------------------------===// -// Test cases. -//===----------------------------------------------------------------------===// - -CFAbsoluteTime f1(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - CFRetain(date); - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - CFRelease(date); - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} - return t; -} - -CFAbsoluteTime f2(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} - return t; -} - - -NSDate* global_x; - -// Test to see if we suppress an error when we store the pointer -// to a global. - -CFAbsoluteTime f3(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - global_x = (NSDate*) date; - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // no-warning - return t; -} - -//--------------------------------------------------------------------------- -// Test case 'f4' differs for region store and basic store. See -// retain-release-region-store.m and retain-release-basic-store.m. -//--------------------------------------------------------------------------- - -// Test a leak. - -CFAbsoluteTime f5(int x) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}} - - if (x) - CFRelease(date); - - return t; -} - -// Test a leak involving the return. - -CFDateRef f6(int x) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning{{leak}} - CFRetain(date); - return date; -} - -// Test a leak involving an overwrite. - -CFDateRef f7(void) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} - CFRetain(date); - date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning {{leak}} - return date; -} - -// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and -// has the word create. -CFDateRef MyDateCreate(void); - -CFDateRef f8(void) { - CFDateRef date = MyDateCreate(); // expected-warning{{leak}} - CFRetain(date); - return date; -} - -__attribute__((cf_returns_retained)) CFDateRef f9(void) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // no-warning - int *p = 0; - // When allocations fail, CFDateCreate can return null. - if (!date) *p = 1; // expected-warning{{null}} - return date; -} - -// Handle DiskArbitration API: -// -// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/ -// -void f10(io_service_t media, DADiskRef d, CFStringRef s) { - DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - CFDictionaryRef dict = DADiskCopyDescription(d); // expected-warning{{leak}} - if (dict) NSLog(@"ok"); - - disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, // expected-warning{{leak}} - kDAReturnSuccess, s); - if (dissenter) NSLog(@"ok"); - - DASessionRef session = DASessionCreate(kCFAllocatorDefault); // expected-warning{{leak}} - if (session) NSLog(@"ok"); -} - -// Test retain/release checker with CFString and CFMutableArray. -void f11(void) { - // Create the array. - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - - // Create a string. - CFStringRef s1 = CFStringCreateWithCString(0, "hello world", - kCFStringEncodingUTF8); - - // Add the string to the array. - CFArrayAppendValue(A, s1); - - // Decrement the reference count. - CFRelease(s1); // no-warning - - // Get the string. We don't own it. - s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); - - // Release the array. - CFRelease(A); // no-warning - - // Release the string. This is a bug. - CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} -} - -// PR 3337: Handle functions declared using typedefs. -typedef CFTypeRef CREATEFUN(void); -CFTypeRef MyCreateFun(void); - -void f12(void) { - CFTypeRef o = MyCreateFun(); // expected-warning {{leak}} -} - -void f13_autorelease(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning - [(id) A autorelease]; // no-warning -} - -void f13_autorelease_b(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; -} // expected-warning{{Object autoreleased too many times}} - -CFMutableArrayRef f13_autorelease_c(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; - return A; // expected-warning{{Object autoreleased too many times}} -} - -CFMutableArrayRef f13_autorelease_d(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; - CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object autoreleased too many times}} - CFRelease(B); // no-warning - while (1) {} -} - - -// This case exercises the logic where the leak site is the same as the allocation site. -void f14_leakimmediately(void) { - CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}} -} - -// Test that we track an allocated object beyond the point where the *name* -// of the variable storing the reference is no longer live. -void f15(void) { - // Create the array. - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - CFMutableArrayRef *B = &A; - // At this point, the name 'A' is no longer live. - CFRelease(*B); // no-warning -} - -// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease. -void f16(int x, CFTypeRef p) { - if (p) - return; - - switch (x) { - case 0: - CFRelease(p); - break; - case 1: - CFRetain(p); - break; - case 2: - CFMakeCollectable(p); - break; - case 3: - CFAutorelease(p); - break; - default: - break; - } -} - -// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease. -void f17(int x, CFTypeRef p) { - switch (x) { - case 0: - CFRelease(p); - if (!p) - CFRelease(0); // no-warning - break; - case 1: - CFRetain(p); - if (!p) - CFRetain(0); // no-warning - break; - case 2: - CFMakeCollectable(p); - if (!p) - CFMakeCollectable(0); // no-warning - break; - case 3: - CFAutorelease(p); - if (!p) - CFAutorelease(0); // no-warning - break; - default: - break; - } -} - -// Test basic tracking of ivars associated with 'self'. For the retain/release -// checker we currently do not want to flag leaks associated with stores -// of tracked objects to ivars. -@interface SelfIvarTest : NSObject { - id myObj; -} -- (void)test_self_tracking; -@end - -@implementation SelfIvarTest -- (void)test_self_tracking { - myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} -@end - -// Test return of non-owned objects in contexts where an owned object -// is expected. -@interface TestReturnNotOwnedWhenExpectedOwned -- (NSString*)newString; -@end - -@implementation TestReturnNotOwnedWhenExpectedOwned -- (NSString*)newString { - NSString *s = [NSString stringWithUTF8String:"hello"]; - return s; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} -@end - -int isFoo(char c); - -static void rdar_6659160(char *inkind, char *inname) -{ - // We currently expect that [NSObject alloc] cannot fail. This - // will be a toggled flag in the future. It can indeed return null, but - // Cocoa programmers generally aren't expected to reason about out-of-memory - // conditions. - NSString *kind = [[NSString alloc] initWithUTF8String:inkind]; // expected-warning{{leak}} - - // We do allow stringWithUTF8String to fail. This isn't really correct, as - // far as returning 0. In most error conditions it will throw an exception. - // If allocation fails it could return 0, but again this - // isn't expected. - NSString *name = [NSString stringWithUTF8String:inname]; - if(!name) - return; - - const char *kindC = 0; - const char *nameC = 0; - - // In both cases, we cannot reach a point down below where we - // dereference kindC or nameC with either being null. This is because - // we assume that [NSObject alloc] doesn't fail and that we have the guard - // up above. - - if(kind) - kindC = [kind UTF8String]; - if(name) - nameC = [name UTF8String]; - if(!isFoo(kindC[0])) // expected-warning{{null}} - return; - if(!isFoo(nameC[0])) // no-warning - return; - - [kind release]; - [name release]; // expected-warning{{Incorrect decrement of the reference count}} -} - -// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming -// conventions with respect to 'return'ing ownership. -@interface PR3677: NSObject @end -@implementation PR3677 -+ (id)allocWithZone:(NSZone *)inZone { - return [super allocWithZone:inZone]; // no-warning -} -@end - -// PR 3820 - Reason about calls to -dealloc -void pr3820_DeallocInsteadOfRelease(void) -{ - id foo = [[NSString alloc] init]; // no-warning - [foo dealloc]; - // foo is not leaked, since it has been deallocated. -} - -void pr3820_ReleaseAfterDealloc(void) -{ - id foo = [[NSString alloc] init]; - [foo dealloc]; - [foo release]; // expected-warning{{used after it is release}} - // NSInternalInconsistencyException: message sent to deallocated object -} - -void pr3820_DeallocAfterRelease(void) -{ - NSLog(@"\n\n[%s]", __FUNCTION__); - id foo = [[NSString alloc] init]; - [foo release]; - [foo dealloc]; // expected-warning{{used after it is released}} - // message sent to released object -} - -// The problem here is that 'length' binds to '($0 - 1)' after '--length', but -// SimpleConstraintManager doesn't know how to reason about -// '($0 - 1) > constant'. As a temporary hack, we drop the value of '($0 - 1)' -// and conjure a new symbol. -void rdar6704930(unsigned char *s, unsigned int length) { - NSString* name = 0; - if (s != 0) { - if (length > 0) { - while (length > 0) { - if (*s == ':') { - ++s; - --length; - name = [[NSString alloc] init]; // no-warning - break; - } - ++s; - --length; - } - if ((length == 0) && (name != 0)) { - [name release]; - name = 0; - } - if (length == 0) { // no ':' found -> use it all as name - name = [[NSString alloc] init]; // no-warning - } - } - } - - if (name != 0) { - [name release]; - } -} - -//===----------------------------------------------------------------------===// -// One build of the analyzer accidentally stopped tracking the allocated -// object after the 'retain'. -//===----------------------------------------------------------------------===// - -@interface rdar_6833332 : NSObject { - NSWindow *window; -} -@property (nonatomic, retain) NSWindow *window; -@end - -@implementation rdar_6833332 -@synthesize window; -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} - - [dict setObject:@"foo" forKey:@"bar"]; - - NSLog(@"%@", dict); -} -- (void)dealloc { - [window release]; - [super dealloc]; -} - -- (void)radar10102244 { - NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} - if (window) - NSLog(@"%@", window); -} -@end - -//===----------------------------------------------------------------------===// -// clang checker fails to catch use-after-release -//===----------------------------------------------------------------------===// -int rdar_6257780_Case1(void) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSArray *array = [NSArray array]; - [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} - [pool drain]; - return 0; -} - -//===----------------------------------------------------------------------===// -// Analyzer is confused about NSAutoreleasePool -allocWithZone:. -//===----------------------------------------------------------------------===// -void rdar_10640253_autorelease_allocWithZone(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool allocWithZone:(NSZone*)0] init]; - (void) pool; -} - -//===----------------------------------------------------------------------===// -// Checker should understand new/setObject:/release constructs -//===----------------------------------------------------------------------===// -void rdar_6866843(void) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init]; - NSArray* array = [[NSArray alloc] init]; - [dictionary setObject:array forKey:@"key"]; - [array release]; - // Using 'array' here should be fine - NSLog(@"array = %@\n", array); // no-warning - // Now the array is released - [dictionary release]; - [pool drain]; -} - - -//===----------------------------------------------------------------------===// -// Classes typedef-ed to CF objects should get the same treatment as CF objects -//===----------------------------------------------------------------------===// -typedef CFTypeRef OtherRef; - -@interface RDar6877235 : NSObject {} -- (CFTypeRef)_copyCFTypeRef; -- (OtherRef)_copyOtherRef; -@end - -@implementation RDar6877235 -- (CFTypeRef)_copyCFTypeRef { - return [[NSString alloc] init]; // no-warning -} -- (OtherRef)_copyOtherRef { - return [[NSString alloc] init]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// false positive - init method returns an object owned by caller -//===----------------------------------------------------------------------===// -@interface RDar6320065 : NSObject { - NSString *_foo; -} -- (id)initReturningNewClass; -- (id)_initReturningNewClassBad; -- (id)initReturningNewClassBad2; -@end - -@interface RDar6320065Subclass : RDar6320065 -@end - -@implementation RDar6320065 -- (id)initReturningNewClass { - [self release]; - self = [[RDar6320065Subclass alloc] init]; // no-warning - return self; -} -- (id)_initReturningNewClassBad { - [self release]; - [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}} - return self; -} -- (id)initReturningNewClassBad2 { - [self release]; - self = [[RDar6320065Subclass alloc] init]; - return [self autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} - -@end - -@implementation RDar6320065Subclass -@end - -int RDar6320065_test(void) { - RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning - [test release]; - return 0; -} - -//===----------------------------------------------------------------------===// -// -awakeAfterUsingCoder: returns an owned object and claims the receiver -//===----------------------------------------------------------------------===// -@interface RDar7129086 : NSObject {} @end -@implementation RDar7129086 -- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder { - [self release]; // no-warning - return [NSString alloc]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// [NSData dataWithBytesNoCopy] does not return a retained object -//===----------------------------------------------------------------------===// -@interface RDar6859457 : NSObject {} -- (NSString*) NoCopyString; -- (NSString*) noCopyString; -@end - -@implementation RDar6859457 -- (NSString*) NoCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} -- (NSString*) noCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} -@end - -void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) { - [x NoCopyString]; // expected-warning{{leak}} - [x noCopyString]; // expected-warning{{leak}} - [NSData dataWithBytesNoCopy:bytes length:dataLength]; // no-warning - [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning -} - -//===----------------------------------------------------------------------===// -// PR 4230 - an autorelease pool is not necessarily leaked during a premature -// return -//===----------------------------------------------------------------------===// - -static void PR4230(void) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning - NSString *object = [[[NSString alloc] init] autorelease]; // no-warning - return; -} - -static void PR4230_new(void) -{ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; // no-warning - NSString *object = [[[NSString alloc] init] autorelease]; // no-warning - return; -} - -//===----------------------------------------------------------------------===// -// Method name that has a null IdentifierInfo* for its first selector slot. -// This test just makes sure that we handle it. -//===----------------------------------------------------------------------===// -@interface TestNullIdentifier -@end - -@implementation TestNullIdentifier -+ (id):(int)x, ... { - return [[NSString alloc] init]; // expected-warning{{leak}} -} -@end - -//===----------------------------------------------------------------------===// -// don't flag leaks for return types that cannot be determined to be CF types -//===----------------------------------------------------------------------===// - -// We don't know if 'struct s6893565' represents a Core Foundation type, so -// we shouldn't emit an error here. -typedef struct s6893565* TD6893565; - -@interface RDar6893565 {} --(TD6893565)newThing; -@end - -@implementation RDar6893565 --(TD6893565)newThing { - return (TD6893565) [[NSString alloc] init]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// clang: false positives w/QC and CoreImage methods -//===----------------------------------------------------------------------===// -void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context, - NSString *str, CIImage *img, CGRect rect, - CIFormat form, CGColorSpaceRef cs) { - [view createSnapshotImageOfType:str]; // expected-warning{{leak}} - [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}} - [context createCGImage:img fromRect:rect]; // expected-warning{{leak}} - [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// -[CIContext createCGLayerWithSize:info:] misinterpreted by clang scan-build -//===----------------------------------------------------------------------===// -void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) { - [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// Add knowledge of IOKit functions to retain/release checker. -//===----------------------------------------------------------------------===// -void IOBSDNameMatching_wrapper(mach_port_t mainPort, uint32_t options, const char * bsdName) { - IOBSDNameMatching(mainPort, options, bsdName); // expected-warning{{leak}} -} - -void IOServiceMatching_wrapper(const char * name) { - IOServiceMatching(name); // expected-warning{{leak}} -} - -void IOServiceNameMatching_wrapper(const char * name) { - IOServiceNameMatching(name); // expected-warning{{leak}} -} - -CF_RETURNS_RETAINED CFDictionaryRef CreateDict(void); - -void IOServiceAddNotification_wrapper(mach_port_t mainPort, const io_name_t notificationType, - mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) { - - CFDictionaryRef matching = CreateDict(); - CFRelease(matching); - IOServiceAddNotification(mainPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}} - wakePort, reference, notification); -} - -void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) { - IORegistryEntryIDMatching(entryID); // expected-warning{{leak}} -} - -void IOOpenFirmwarePathMatching_wrapper(mach_port_t mainPort, uint32_t options, - const char * path) { - IOOpenFirmwarePathMatching(mainPort, options, path); // expected-warning{{leak}} -} - -void IOServiceGetMatchingService_wrapper(mach_port_t mainPort) { - CFDictionaryRef matching = CreateDict(); - IOServiceGetMatchingService(mainPort, matching); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -void IOServiceGetMatchingServices_wrapper(mach_port_t mainPort, io_iterator_t *existing) { - CFDictionaryRef matching = CreateDict(); - IOServiceGetMatchingServices(mainPort, matching, existing); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, - IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) { - - CFDictionaryRef matching = CreateDict(); - IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -//===----------------------------------------------------------------------===// -// Test of handling objects whose references "escape" to containers. -//===----------------------------------------------------------------------===// -void CFDictionaryAddValue(CFMutableDictionaryRef, void *, void *); - -void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) { - CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionaryAddValue(y, key, x); - CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); - if (value) { - CFDictionaryAddValue(x, val_key, (void*)value); // no-warning - CFRelease(value); - CFDictionaryAddValue(y, val_key, (void*)value); // no-warning - } -} - -// Same issue, except with "AppendValue" functions. -void rdar_6560661(CFMutableArrayRef x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); - // CFArrayAppendValue keeps a reference to value. - CFArrayAppendValue(x, value); - CFRelease(value); - CFRetain(value); - CFRelease(value); // no-warning -} - -// Same issue, excwept with "CFAttributeStringSetAttribute". -void rdar_7152619(CFStringRef str) { - CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0); - CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string); - CFRelease(string); - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} - CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number); - [number release]; - [number retain]; - CFRelease(attrString); -} - -//===----------------------------------------------------------------------===// -// Test of handling CGGradientXXX functions. -//===----------------------------------------------------------------------===// - -void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, - CGPoint myEndPoint) { - size_t num_locations = 6; - CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; - CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, - x, // Start color - 207.0/255.0, 39.0/255.0, 39.0/255.0, x, - 147.0/255.0, 21.0/255.0, 22.0/255.0, x, - 175.0/255.0, 175.0/255.0, 175.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x - }; // End color - - CGGradientRef myGradient = - CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}} - components, locations, num_locations); - - CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, - 0); - CGGradientRelease(myGradient); -} - -void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, - CGPoint myEndPoint) { - size_t num_locations = 6; - CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; - CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, - x, // Start color - 207.0/255.0, 39.0/255.0, 39.0/255.0, x, - 147.0/255.0, 21.0/255.0, 22.0/255.0, x, - 175.0/255.0, 175.0/255.0, 175.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x - }; // End color - - CGGradientRef myGradient = - CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}} - - CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, - 0); -} - -//===----------------------------------------------------------------------===// -// clang false positive: retained instance passed to thread in pthread_create -// marked as leak -// -// Until we have full IPA, the analyzer should stop tracking the reference -// count of objects passed to pthread_create. -// -//===----------------------------------------------------------------------===// -struct _opaque_pthread_t {}; -struct _opaque_pthread_attr_t {}; -typedef struct _opaque_pthread_t *__darwin_pthread_t; -typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t; -typedef __darwin_pthread_t pthread_t; -typedef __darwin_pthread_attr_t pthread_attr_t; -typedef unsigned long __darwin_pthread_key_t; -typedef __darwin_pthread_key_t pthread_key_t; - -int pthread_create(pthread_t *, const pthread_attr_t *, - void *(*)(void *), void *); - -int pthread_setspecific(pthread_key_t key, const void *value); - -void *rdar_7299394_start_routine(void *p) { - [((id) p) release]; - return 0; -} -void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - pthread_create(thread, attr, rdar_7299394_start_routine, number); -} -void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// false positive with not understanding thread local storage -//===----------------------------------------------------------------------===// -void rdar11282706(pthread_key_t key) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - pthread_setspecific(key, (void*) number); -} - -//===----------------------------------------------------------------------===// -// False leak associated with call to CVPixelBufferCreateWithBytes () -// -// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and -// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the -// pixel buffer object. These test cases show how the analyzer stops tracking -// the reference count for the objects passed for this argument. This -// could be made smarter. -//===----------------------------------------------------------------------===// -typedef int int32_t; -typedef UInt32 FourCharCode; -typedef FourCharCode OSType; -typedef uint64_t CVOptionFlags; -typedef int32_t CVReturn; -typedef struct __CVBuffer *CVBufferRef; -typedef CVBufferRef CVImageBufferRef; -typedef CVImageBufferRef CVPixelBufferRef; -typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress ); - -extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] ); - -extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *dataPtr, - size_t dataSize, - size_t numberOfPlanes, - void *planeBaseAddress[], - size_t planeWidth[], - size_t planeHeight[], - size_t planeBytesPerRow[], - CVPixelBufferReleasePlanarBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height, - OSType pixelFormatType, void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType, - baseAddress, bytesPerRow, releaseCallback, - number, // potentially released by callback - pixelBufferAttributes, pixelBufferOut) ; -} - -CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height, - OSType pixelFormatType, void *dataPtr, size_t dataSize, - size_t numberOfPlanes, void *planeBaseAddress[], - size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[], - CVPixelBufferReleasePlanarBytesCallback releaseCallback, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - return CVPixelBufferCreateWithPlanarBytes(allocator, - width, height, pixelFormatType, dataPtr, dataSize, - numberOfPlanes, planeBaseAddress, planeWidth, - planeHeight, planeBytesPerRow, releaseCallback, - number, // potentially released by callback - pixelBufferAttributes, pixelBufferOut) ; -} - -//===----------------------------------------------------------------------===// -// False leak associated with CGBitmapContextCreateWithData -//===----------------------------------------------------------------------===// -typedef uint32_t CGBitmapInfo; -typedef void (*CGBitmapContextReleaseDataCallback)(void *releaseInfo, void *data); - -CGContextRef CGBitmapContextCreateWithData(void *data, - size_t width, size_t height, size_t bitsPerComponent, - size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, - CGBitmapContextReleaseDataCallback releaseCallback, void *releaseInfo); - -void rdar_7358899(void *data, - size_t width, size_t height, size_t bitsPerComponent, - size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, - CGBitmapContextReleaseDataCallback releaseCallback) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - CGBitmapContextCreateWithData(data, width, height, bitsPerComponent, // expected-warning{{leak}} - bytesPerRow, space, bitmapInfo, releaseCallback, number); -} - -//===----------------------------------------------------------------------===// -// Allow 'new', 'copy', 'alloc', 'init' prefix to start before '_' when -// determining Cocoa fundamental rule. -// -// Previously the retain/release checker just skipped prefixes before the -// first '_' entirely. Now the checker honors the prefix if it results in a -// recognizable naming convention (e.g., 'new', 'init'). -//===----------------------------------------------------------------------===// -@interface RDar7265711 {} -- (id) new_stuff; -@end - -void rdar7265711_a(RDar7265711 *x) { - id y = [x new_stuff]; // expected-warning{{leak}} -} - -void rdar7265711_b(RDar7265711 *x) { - id y = [x new_stuff]; // no-warning - [y release]; -} - -//===----------------------------------------------------------------------===// -// clang thinks [NSCursor dragCopyCursor] returns a retained reference -//===----------------------------------------------------------------------===// -@interface NSCursor : NSObject -+ (NSCursor *)dragCopyCursor; -@end - -void rdar7306898(void) { - // 'dragCopyCursor' does not follow Cocoa's fundamental rule. It is a noun, not an sentence - // implying a 'copy' of something. - NSCursor *c = [NSCursor dragCopyCursor]; // no-warning - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// Sending 'release', 'retain', etc. to a Class directly is not likely what the -// user intended. -//===----------------------------------------------------------------------===// -@interface RDar7252064 : NSObject @end -void rdar7252064(void) { - [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [NSAutoreleasePool drain]; // expected-warning{{method '+drain' not found}} expected-warning{{The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly}} -} - -//===----------------------------------------------------------------------===// -// Tests of ownership attributes. -//===----------------------------------------------------------------------===// - -typedef NSString* MyStringTy; - -@protocol FooP; - -@interface TestOwnershipAttr : NSObject -- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning -- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning -- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning -- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning -- (NSString*) newString_auto NS_RETURNS_AUTORELEASED; // no-warning -- (NSString*) newStringNoAttr; -- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}} -- (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED; -+ (void) consume:(id) NS_CONSUMED x; -+ (void) consume2:(id) CF_CONSUMED x; -@end - -static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions and methods}} - -void test_attr_1(TestOwnershipAttr *X) { - NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}} -} - -void test_attr_1b(TestOwnershipAttr *X) { - NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}} -} - -void test_attr1c(TestOwnershipAttr *X) { - NSString *str = [X newString]; // no-warning - NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}} - NSString *str3 = [X newString_auto]; // no-warning - NSString *str4 = [[X newString_auto] retain]; // expected-warning {{leak}} -} - -void testattr2_a(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // expected-warning{{leak}} -} - -void testattr2_b(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // expected-warning{{leak}} -} - -void testattr2_b_11358224_self_assign_looses_the_leak(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit];// expected-warning{{leak}} - x = x; -} - -void testattr2_c(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // no-warning - [x release]; -} - -void testattr3(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning - [TestOwnershipAttr consume:x]; - TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning - [TestOwnershipAttr consume2:y]; -} - -void consume_ns(id NS_CONSUMED x); -void consume_cf(id CF_CONSUMED x); - -void testattr4(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning - consume_ns(x); - TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning - consume_cf(y); -} - -@interface TestOwnershipAttr2 : NSObject -- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning -@end - -@implementation TestOwnershipAttr2 -- (NSString*) newString { - return [NSString alloc]; // expected-warning {{Potential leak of an object}} -} -@end - -@interface MyClassTestCFAttr : NSObject {} -- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED; -- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED; -- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED; -- (CFDateRef) newCFRetainedAsCFNoAttr; -- (NSDate*) alsoReturnsRetained; -- (CFDateRef) alsoReturnsRetainedAsCF; -- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; -@end - -CF_RETURNS_RETAINED -CFDateRef returnsRetainedCFDate(void) { - return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); -} - -@implementation MyClassTestCFAttr -- (NSDate*) returnsCFRetained { - return (NSDate*) returnsRetainedCFDate(); // No leak. -} - -- (CFDateRef) returnsCFRetainedAsCF { - return returnsRetainedCFDate(); // No leak. -} - -- (CFDateRef) newCFRetainedAsCF { - return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; -} - -- (CFDateRef) newCFRetainedAsCFNoAttr { - return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} - -- (NSDate*) alsoReturnsRetained { - return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}} -} - -- (CFDateRef) alsoReturnsRetainedAsCF { - return returnsRetainedCFDate(); // expected-warning{{leak}} -} - - -- (NSDate*) returnsNSRetained { - return (NSDate*) returnsRetainedCFDate(); // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// Test that leaks post-dominated by "panic" functions are not reported. -// -// Do not report a leak when post-dominated by a call to a noreturn or panic -// function. -//===----------------------------------------------------------------------===// -void panic(void) __attribute__((noreturn)); -void panic_not_in_hardcoded_list(void) __attribute__((noreturn)); - -void test_panic_negative(void) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} -} - -void test_panic_positive(void) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning - panic(); -} - -void test_panic_neg_2(int x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} - if (x) - panic(); -} - -void test_panic_pos_2(int x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning - if (x) - panic(); - if (!x) { - // This showed up previously where we silently missed checking the function - // type for noreturn. "panic()" is a hard-coded known panic function that - // isn't always noreturn. - panic_not_in_hardcoded_list(); - } -} - -//===----------------------------------------------------------------------===// -// Test uses of blocks (closures) -//===----------------------------------------------------------------------===// - -void test_blocks_1_pos(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} - ^{}(); -} - -void test_blocks_1_indirect_release(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^{ [number release]; }(); -} - -void test_blocks_1_indirect_retain(void) { - // Eventually this should be reported as a leak. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^{ [number retain]; }(); -} - -void test_blocks_1_indirect_release_via_call(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^(NSObject *o){ [o release]; }(number); -} - -void test_blocks_1_indirect_retain_via_call(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning {{leak}} - ^(NSObject *o){ [o retain]; }(number); -} - -//===--------------------------------------------------------------------===// -// Test sending message to super that returns an object alias. Previously -// this caused a crash in the analyzer. -//===--------------------------------------------------------------------===// - -@interface Rdar8015556 : NSObject {} @end -@implementation Rdar8015556 -- (id)retain { - return [super retain]; -} -@end - -// Correcly handle Class<...> in Cocoa Conventions detector. -@protocol Prot_R8272168 @end -Class GetAClassThatImplementsProt_R8272168(void); -void r8272168(void) { - GetAClassThatImplementsProt_R8272168(); -} - -// Test case which in the past triggered a false positive. -@interface RDar8356342 -- (NSDate*) rdar8356342:(NSDate *)inValue; -@end - -@implementation RDar8356342 -- (NSDate*) rdar8356342:(NSDate*)inValue { - NSDate *outValue = inValue; - if (outValue == 0) - outValue = [[NSDate alloc] init]; // no-warning - - if (outValue != inValue) - [outValue autorelease]; - - return outValue; -} -@end - -// This test case previously crashed because of a bug in BugReporter. -extern const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key); -typedef struct __CFError * CFErrorRef; -extern const CFStringRef kCFErrorUnderlyingErrorKey; -extern CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err); -static void rdar_8724287(CFErrorRef error) -{ - CFErrorRef error_to_dump; - - error_to_dump = error; - while (error_to_dump != ((void*)0)) { - CFDictionaryRef info; - - info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object}} - - if (info != ((void*)0)) { - } - - error_to_dump = (CFErrorRef) CFDictionaryGetValue(info, kCFErrorUnderlyingErrorKey); - } -} - -// Make sure the model applies cf_consumed correctly in argument positions -// besides the first. -extern void *CFStringCreate(void); -extern void rdar_9234108_helper(void *key, void * CF_CONSUMED value); -void rdar_9234108(void) { - rdar_9234108_helper(0, CFStringCreate()); -} - -// Make sure that objc_method_family works to override naming conventions. -struct TwoDoubles { - double one; - double two; -}; -typedef struct TwoDoubles TwoDoubles; - -@interface NSValue (Mine) -- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles __attribute__((objc_method_family(init))); -@end - -@implementation NSValue (Mine) -- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles -{ - return [self init]; -} -@end - -void rdar9726279(void) { - TwoDoubles twoDoubles = { 0.0, 0.0 }; - NSValue *value = [[NSValue alloc] _prefix_initWithTwoDoubles:twoDoubles]; - [value release]; -} - -// Test camelcase support for CF conventions. While Core Foundation APIs -// don't use camel casing, other code is allowed to use it. -CFArrayRef camelcase_create_1(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camelcase_createno(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef camelcase_copy(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camelcase_copying(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef copyCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef __copyCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef __createCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_create(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - - -CFArrayRef camel_creat(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef camel_copy(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_copyMachine(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_copymachine(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -@protocol F18P -- (id) clone; -@end -@interface F18 : NSObject @end -@interface F18(Cat) -- (id) clone NS_RETURNS_RETAINED; -@end - -@implementation F18 -- (id) clone { - return [F18 alloc]; -} -@end - -void rdar6582778(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFTypeRef vals[] = { CFDateCreate(0, t) }; // expected-warning {{leak}} -} - -CFTypeRef global; - -void rdar6582778_2(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - global = CFDateCreate(0, t); // no-warning -} - -// Test that objects passed to containers are marked "escaped". -void rdar10232019(void) { - NSMutableArray *array = [NSMutableArray array]; - - NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; - [array addObject:string]; - [string release]; - - NSString *otherString = [string stringByAppendingString:@"bar"]; // no-warning - NSLog(@"%@", otherString); -} - -void rdar10232019_positive(void) { - NSMutableArray *array = [NSMutableArray array]; - - NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; - [string release]; - - NSString *otherString = [string stringByAppendingString:@"bar"]; // expected-warning {{Reference-counted object is used after it is release}} - NSLog(@"%@", otherString); -} - -// RetainCountChecker support for XPC. -typedef void * xpc_object_t; -xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef cf); -void xpc_release(xpc_object_t object); - -void rdar9658496(void) { - CFStringRef cf; - xpc_object_t xpc; - cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - xpc = _CFXPCCreateXPCObjectFromCFObject( cf ); - CFRelease(cf); - xpc_release(xpc); -} - -// Support annotations with method families. -@interface RDar10824732 : NSObject -- (id)initWithObj:(id CF_CONSUMED)obj; -@end - -@implementation RDar10824732 -- (id)initWithObj:(id)obj { - [obj release]; - return [super init]; -} -@end - -void rdar_10824732(void) { - @autoreleasepool { - NSString *obj = @"test"; - RDar10824732 *foo = [[RDar10824732 alloc] initWithObj:obj]; // no-warning - [foo release]; - } -} - -// Stop tracking objects passed to functions, which take callbacks as parameters. -typedef int (*CloseCallback) (void *); -void ReaderForIO(CloseCallback ioclose, void *ioctx); -int IOClose(void *context); - -@protocol SInS -@end - -@interface radar10973977 : NSObject -- (id)inputS; -- (void)reader; -@end - -@implementation radar10973977 -- (void)reader -{ - id inputS = [[self inputS] retain]; - ReaderForIO(IOClose, inputS); -} -- (id)inputS -{ - return 0; -} -@end - -// Object escapes through a selector callback -extern id NSApp; -@interface MySheetController -- (id)inputS; -- (void)showDoSomethingSheetAction:(id)action; -- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; -@end - -@implementation MySheetController -- (id)inputS { - return 0; -} -- (void)showDoSomethingSheetAction:(id)action { - id inputS = [[self inputS] retain]; - [NSApp beginSheet:0 - modalForWindow:0 - modalDelegate:0 - didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo:(void *)inputS]; // no - warning -} -- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { - - id contextObject = (id)contextInfo; - [contextObject release]; -} - -- (id)copyAutoreleaseRadar13081402 { - id x = [[[NSString alloc] initWithUTF8String:"foo"] autorelease]; - [x retain]; - return x; // no warning -} - -@end -//===----------------------------------------------------------------------===// -// Test returning allocated memory in a struct. -// -// We currently don't have a general way to track pointers that "escape". -// Here we test that RetainCountChecker doesn't get excited about returning -// allocated CF objects in struct fields. -//===----------------------------------------------------------------------===// -void *malloc(size_t); -struct rdar11104566 { CFStringRef myStr; }; -struct rdar11104566 test_rdar11104566(void) { - CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - struct rdar11104566 V; - V.myStr = cf; - return V; // no-warning -} - -struct rdar11104566 *test_2_rdar11104566(void) { - CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - struct rdar11104566 *V = (struct rdar11104566 *) malloc(sizeof(*V)); - V->myStr = cf; - return V; // no-warning -} - -//===----------------------------------------------------------------------===// -// ObjC literals support. -//===----------------------------------------------------------------------===// - -void test_objc_arrays(void) { - { // CASE ONE -- OBJECT IN ARRAY CREATED DIRECTLY - NSObject *o = [[NSObject alloc] init]; - NSArray *a = [[NSArray alloc] initWithObjects:o, (void*)0]; // expected-warning {{leak}} - [o release]; - [a description]; - [o description]; - } - - { // CASE TWO -- OBJECT IN ARRAY CREATED BY DUPING AUTORELEASED ARRAY - NSObject *o = [[NSObject alloc] init]; - NSArray *a1 = [NSArray arrayWithObjects:o, (void*)0]; - NSArray *a2 = [[NSArray alloc] initWithArray:a1]; // expected-warning {{leak}} - [o release]; - [a2 description]; - [o description]; - } - - { // CASE THREE -- OBJECT IN RETAINED @[] - NSObject *o = [[NSObject alloc] init]; - NSArray *a3 = [@[o] retain]; // expected-warning {{leak}} - [o release]; - [a3 description]; - [o description]; - } - - { // CASE FOUR -- OBJECT IN ARRAY CREATED BY DUPING @[] - NSObject *o = [[NSObject alloc] init]; - NSArray *a = [[NSArray alloc] initWithArray:@[o]]; // expected-warning {{leak}} - [o release]; - - [a description]; - [o description]; - } - - { // CASE FIVE -- OBJECT IN RETAINED @{} - NSValue *o = [[NSValue alloc] init]; - NSDictionary *a = [@{o : o} retain]; // expected-warning {{leak}} - [o release]; - - [a description]; - [o description]; - } -} - -void test_objc_integer_literals(void) { - id value = [@1 retain]; // expected-warning {{leak}} - [value description]; -} - -void test_objc_boxed_expressions(int x, const char *y) { - id value = [@(x) retain]; // expected-warning {{leak}} - [value description]; - - value = [@(y) retain]; // expected-warning {{leak}} - [value description]; -} - -// Test NSLog doesn't escape tracked objects. -void rdar11400885(int y) -{ - @autoreleasepool { - NSString *printString; - if(y > 2) - printString = [[NSString alloc] init]; - else - printString = [[NSString alloc] init]; - NSLog(@"Once %@", printString); - [printString release]; - NSLog(@"Again: %@", printString); // expected-warning {{Reference-counted object is used after it is released}} - } -} - -id makeCollectableNonLeak(void) { - extern CFTypeRef CFCreateSomething(void); - - CFTypeRef object = CFCreateSomething(); // +1 - CFRetain(object); // +2 - id objCObject = NSMakeCollectable(object); // +2 - [objCObject release]; // +1 - return [objCObject autorelease]; // +0 -} - - -void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void)); -void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void)); - -void testConsumeAndStopTracking(void) { - id retained = [@[] retain]; // +1 - consumeAndStopTracking(retained, ^{}); // no-warning - - id doubleRetained = [[@[] retain] retain]; // +2 - consumeAndStopTracking(doubleRetained, ^{ - [doubleRetained release]; - }); // no-warning - - id unretained = @[]; // +0 - consumeAndStopTracking(unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} - -void testCFConsumeAndStopTracking(void) { - id retained = [@[] retain]; // +1 - CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // no-warning - - id doubleRetained = [[@[] retain] retain]; // +2 - CFConsumeAndStopTracking((CFTypeRef)doubleRetained, ^{ - [doubleRetained release]; - }); // no-warning - - id unretained = @[]; // +0 - CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} -//===----------------------------------------------------------------------===// -// Test 'pragma clang arc_cf_code_audited' support. -//===----------------------------------------------------------------------===// - -typedef void *MyCFType; -#pragma clang arc_cf_code_audited begin -MyCFType CreateMyCFType(void); -#pragma clang arc_cf_code_audited end - -void test_custom_cf(void) { - MyCFType x = CreateMyCFType(); // expected-warning {{leak of an object stored into 'x'}} -} - -//===----------------------------------------------------------------------===// -// Test calling CFPlugInInstanceCreate, which appears in CF but doesn't -// return a CF object. -//===----------------------------------------------------------------------===// - -void test_CFPlugInInstanceCreate(CFUUIDRef factoryUUID, CFUUIDRef typeUUID) { - CFPlugInInstanceCreate(kCFAllocatorDefault, factoryUUID, typeUUID); // no-warning -} - -//===----------------------------------------------------------------------===// -// PR14927: -drain only has retain-count semantics on NSAutoreleasePool. -//===----------------------------------------------------------------------===// - -@interface PR14927 : NSObject -- (void)drain; -@end - -void test_drain(void) { - PR14927 *obj = [[PR14927 alloc] init]; - [obj drain]; - [obj release]; // no-warning -} - -//===----------------------------------------------------------------------===// -// Allow cf_returns_retained and cf_returns_not_retained to mark a return -// value as tracked, even if the object isn't a known CF type. -//===----------------------------------------------------------------------===// - -MyCFType getCustom(void) __attribute__((cf_returns_not_retained)); -MyCFType makeCustom(void) __attribute__((cf_returns_retained)); - -void testCustomReturnsRetained(void) { - MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}} -} - -void testCustomReturnsNotRetained(void) { - CFRelease(getCustom()); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} - -//===----------------------------------------------------------------------===// -// Don't print variables which are out of the current scope. -//===----------------------------------------------------------------------===// -@interface MyObj12706177 : NSObject --(id)initX; -+(void)test12706177; -@end -static int Cond; -@implementation MyObj12706177 --(id)initX { - if (Cond) - return 0; - self = [super init]; - return self; -} -+(void)test12706177 { - id x = [[MyObj12706177 alloc] initX]; //expected-warning {{Potential leak of an object}} - [x release]; -} -@end - -//===----------------------------------------------------------------------===// -// xpc_connection_set_finalizer_f -//===----------------------------------------------------------------------===// -typedef xpc_object_t xpc_connection_t; -typedef void (*xpc_finalizer_t)(void *value); -void xpc_connection_set_context(xpc_connection_t connection, void *ctx); -void xpc_connection_set_finalizer_f(xpc_connection_t connection, - xpc_finalizer_t finalizer); -void releaseAfterXPC(void *context) { - [(NSArray *)context release]; -} - -void rdar13783514(xpc_connection_t connection) { - xpc_connection_set_context(connection, [[NSMutableArray alloc] init]); - xpc_connection_set_finalizer_f(connection, releaseAfterXPC); -} // no-warning - -CFAttributedStringRef CFAttributedCreate(void *CFObj CF_CONSUMED) CF_RETURNS_RETAINED; - -@interface Action -- (SEL)action; -- (void)setAction:(SEL)aSelector; -- (id) target; -- (void)setTarget:(id)aTarget; -@end diff --git a/clang/test/ARCMT/objcmt-arc-cf-annotations.m.result b/clang/test/ARCMT/objcmt-arc-cf-annotations.m.result deleted file mode 100644 index 1e941297848805..00000000000000 --- a/clang/test/ARCMT/objcmt-arc-cf-annotations.m.result +++ /dev/null @@ -1,2063 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-annotation -objcmt-migrate-instancetype -objcmt-migrate-readwrite-property -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -#ifndef CF_IMPLICIT_BRIDGING_ENABLED -#if __has_feature(arc_cf_code_audited) -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") -#else -#define CF_IMPLICIT_BRIDGING_ENABLED -#endif -#endif - -#ifndef CF_IMPLICIT_BRIDGING_DISABLED -#if __has_feature(arc_cf_code_audited) -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") -#else -#define CF_IMPLICIT_BRIDGING_DISABLED -#endif -#endif - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -//===----------------------------------------------------------------------===// -// The following code is reduced using delta-debugging from Mac OS X headers: -// -// #include -// #include -// #include -// #include -// #include -// #include -// -// It includes the basic definitions for the test cases below. -//===----------------------------------------------------------------------===// - -typedef unsigned int __darwin_natural_t; -typedef unsigned long uintptr_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -typedef unsigned int UInt32; -typedef signed long CFIndex; -typedef CFIndex CFByteOrder; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; -static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) { - CFRange range; - range.location = loc; - range.length = len; - return range; -} -typedef const void * CFTypeRef; -typedef const struct __CFString * CFStringRef; -typedef const struct __CFAllocator * CFAllocatorRef; -extern const CFAllocatorRef kCFAllocatorDefault; -extern CFTypeRef CFRetain(CFTypeRef cf); - -CF_IMPLICIT_BRIDGING_ENABLED - -extern void CFRelease(CFTypeRef cf); - -CF_IMPLICIT_BRIDGING_DISABLED - -extern CFTypeRef CFAutorelease(CFTypeRef cf); -extern CFTypeRef CFMakeCollectable(CFTypeRef cf); -typedef struct { -} -CFArrayCallBacks; -extern const CFArrayCallBacks kCFTypeArrayCallBacks; -typedef const struct __CFArray * CFArrayRef; -typedef struct __CFArray * CFMutableArrayRef; -extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks) CF_RETURNS_RETAINED; -extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx) CF_RETURNS_NOT_RETAINED; -extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); -typedef struct { -} -CFDictionaryKeyCallBacks; -extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; -typedef struct { -} -CFDictionaryValueCallBacks; -extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; -extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks) CF_RETURNS_RETAINED; -typedef UInt32 CFStringEncoding; -enum { -kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 }; -extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding) CF_RETURNS_RETAINED; -typedef double CFTimeInterval; -typedef CFTimeInterval CFAbsoluteTime; -extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); -typedef const struct __CFDate * CFDateRef; -extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at) CF_RETURNS_RETAINED; -extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); -typedef __darwin_natural_t natural_t; -typedef natural_t mach_port_name_t; -typedef mach_port_name_t mach_port_t; -typedef int kern_return_t; -typedef kern_return_t mach_error_t; -enum { -kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 }; -typedef CFIndex CFNumberType; -typedef const struct __CFNumber * CFNumberRef; -extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr) CF_RETURNS_RETAINED; -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; -extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) CF_RETURNS_RETAINED ; -extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) CF_RETURNS_RETAINED ; -extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ; -typedef signed char BOOL; -typedef unsigned long NSUInteger; -@class NSString, Protocol; -extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); -typedef struct _NSZone NSZone; -@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -- (id)autorelease; -- (NSString *)description; -- (instancetype)init; -@end -@protocol NSCopying -- (id)copyWithZone:(NSZone *)zone; -@end -@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; -@end -@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; -@end -@interface NSObject {} -+ (id)allocWithZone:(NSZone *)zone; -+ (id)alloc; -+ (id)new; -- (void)dealloc; -@end -@interface NSObject (NSCoderMethods) -- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; -@end -extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); -typedef struct { -} -NSFastEnumerationState; -@protocol NSFastEnumeration -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; -@end -@class NSString, NSDictionary; -@interface NSValue : NSObject - (void)getValue:(void *)value; -@end -@interface NSNumber : NSValue -- (char)charValue; -- (instancetype)initWithInt:(int)value; -+ (NSNumber *)numberWithInt:(int)value; -@end -@class NSString; -@interface NSArray : NSObject -- (NSUInteger)count; -- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt; -+ (instancetype)arrayWithObject:(id)anObject; -+ (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; -+ (instancetype)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); -- (instancetype)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); -- (instancetype)initWithArray:(NSArray *)array; -@end @interface NSArray (NSArrayCreation) + (instancetype)array; -@end @interface NSAutoreleasePool : NSObject { -} -- (void)drain; -@end extern NSString * const NSBundleDidLoadNotification; -typedef double NSTimeInterval; -@interface NSDate : NSObject - (NSTimeInterval)timeIntervalSinceReferenceDate; -@end typedef unsigned short unichar; -@interface NSString : NSObject -- (NSUInteger)length; -- (NSString *)stringByAppendingString:(NSString *)aString; -- ( const char *)UTF8String; -- (instancetype)initWithUTF8String:(const char *)nullTerminatedCString; -+ (instancetype)stringWithUTF8String:(const char *)nullTerminatedCString; -@end @class NSString, NSURL, NSError; -@interface NSData : NSObject - (NSUInteger)length; -+ (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; -+ (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; -@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; -@interface NSDictionary : NSObject -- (NSUInteger)count; -+ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -+ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt; -@end -@interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; -- (void)setObject:(id)anObject forKey:(id)aKey; -@end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (instancetype)dictionaryWithCapacity:(NSUInteger)numItems; -@end typedef double CGFloat; -struct CGSize { -}; -typedef struct CGSize CGSize; -struct CGRect { -}; -typedef struct CGRect CGRect; -typedef mach_port_t io_object_t; -typedef char io_name_t[128]; -typedef io_object_t io_iterator_t; -typedef io_object_t io_service_t; -typedef struct IONotificationPort * IONotificationPortRef; -typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator ); - -CF_IMPLICIT_BRIDGING_ENABLED - -io_service_t IOServiceGetMatchingService( mach_port_t mainPort, CFDictionaryRef matching ); -kern_return_t IOServiceGetMatchingServices( mach_port_t mainPort, CFDictionaryRef matching, io_iterator_t * existing ); - -CF_IMPLICIT_BRIDGING_DISABLED - -kern_return_t IOServiceAddNotification( mach_port_t mainPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); // expected-note {{'IOServiceAddNotification' declared here}} -kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef CF_CONSUMED matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification ); - -CF_IMPLICIT_BRIDGING_ENABLED - -CFMutableDictionaryRef IOServiceMatching( const char * name ); -CFMutableDictionaryRef IOServiceNameMatching( const char * name ); -CFMutableDictionaryRef IOBSDNameMatching( mach_port_t mainPort, uint32_t options, const char * bsdName ); -CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t mainPort, uint32_t options, const char * path ); -CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID ); - -CF_IMPLICIT_BRIDGING_DISABLED - -typedef struct __DASession * DASessionRef; -extern DASessionRef DASessionCreate( CFAllocatorRef allocator ) CF_RETURNS_RETAINED; -typedef struct __DADisk * DADiskRef; -extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ) CF_RETURNS_RETAINED; -extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ) CF_RETURNS_RETAINED; -extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ) CF_RETURNS_RETAINED; -extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ) CF_RETURNS_RETAINED; -@interface NSTask : NSObject - (instancetype)init; -@end typedef struct CGColorSpace *CGColorSpaceRef; -typedef struct CGImage *CGImageRef; -typedef struct CGLayer *CGLayerRef; -@interface NSResponder : NSObject { -} -@end @protocol NSAnimatablePropertyContainer - (id)animator; -@end extern NSString *NSAnimationTriggerOrderIn ; -@interface NSView : NSResponder { -} -@end @protocol NSValidatedUserInterfaceItem - (SEL)action; -@end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id )anItem; -@end @class NSDate, NSDictionary, NSError, NSException, NSNotification; -@class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; -@interface NSApplication : NSResponder { -} -- (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo; -@end enum { -NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; -typedef NSUInteger NSApplicationTerminateReply; -@protocol NSApplicationDelegate @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; -@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; -@interface NSCell : NSObject { -} -@end -typedef struct { -} -CVTimeStamp; -@interface CIImage : NSObject { -} -typedef int CIFormat; -@end enum { -kDAReturnSuccess = 0, kDAReturnError = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01, kDAReturnBusy = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02, kDAReturnBadArgument = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03, kDAReturnExclusiveAccess = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04, kDAReturnNoResources = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05, kDAReturnNotFound = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06, kDAReturnNotMounted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07, kDAReturnNotPermitted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08, kDAReturnNotPrivileged = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09, kDAReturnNotReady = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A, kDAReturnNotWritable = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B, kDAReturnUnsupported = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C }; -typedef mach_error_t DAReturn; -typedef const struct __DADissenter * DADissenterRef; -extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ) CF_RETURNS_RETAINED; -@interface CIContext: NSObject { -} -- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r CF_RETURNS_RETAINED; -- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs CF_RETURNS_RETAINED; -- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d CF_RETURNS_RETAINED; -@end extern NSString* const QCRendererEventKey; -@protocol QCCompositionRenderer - (NSDictionary*) attributes; -@end @interface QCRenderer : NSObject { -} -- (id) createSnapshotImageOfType:(NSString*)type NS_RETURNS_RETAINED; -@end extern NSString* const QCViewDidStartRenderingNotification; -@interface QCView : NSView { -} -- (id) createSnapshotImageOfType:(NSString*)type NS_RETURNS_RETAINED; -@end enum { -ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, }; -@class ICDevice; -@protocol ICDeviceDelegate @required - (void)didRemoveDevice:(ICDevice*)device; -@end extern NSString *const ICScannerStatusWarmingUp; -@class ICScannerDevice; -@protocol ICScannerDeviceDelegate @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner; -@end - -typedef long unsigned int __darwin_size_t; -typedef __darwin_size_t size_t; -typedef unsigned long CFTypeID; -struct CGPoint { - CGFloat x; - CGFloat y; -}; -typedef struct CGPoint CGPoint; -typedef struct CGGradient *CGGradientRef; -typedef uint32_t CGGradientDrawingOptions; -extern CFTypeID CGGradientGetTypeID(void); -extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef - space, const CGFloat components[], const CGFloat locations[], size_t count) CF_RETURNS_RETAINED; -extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, - CFArrayRef colors, const CGFloat locations[]) CF_RETURNS_RETAINED; -extern CGGradientRef CGGradientRetain(CGGradientRef gradient); - -CF_IMPLICIT_BRIDGING_ENABLED - -extern void CGGradientRelease(CGGradientRef gradient); - -CF_IMPLICIT_BRIDGING_DISABLED - -typedef struct CGContext *CGContextRef; -extern void CGContextDrawLinearGradient(CGContextRef context, - CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, - CGGradientDrawingOptions options); - -CF_IMPLICIT_BRIDGING_ENABLED - -extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); - -CF_IMPLICIT_BRIDGING_DISABLED - - -@interface NSMutableArray : NSObject -- (void)addObject:(id)object; -+ (instancetype)array; -@end - -// This is how NSMakeCollectable is declared in the OS X 10.8 headers. -id NSMakeCollectable(CFTypeRef __attribute__((cf_consumed))) __attribute__((ns_returns_retained)); - -typedef const struct __CFUUID * CFUUIDRef; - -extern -void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID); - -//===----------------------------------------------------------------------===// -// Test cases. -//===----------------------------------------------------------------------===// - -CFAbsoluteTime f1(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - CFRetain(date); - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - CFRelease(date); - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} - return t; -} - -CFAbsoluteTime f2(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} - return t; -} - - -NSDate* global_x; - -// Test to see if we suppress an error when we store the pointer -// to a global. - -CFAbsoluteTime f3(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - global_x = (NSDate*) date; - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // no-warning - return t; -} - -//--------------------------------------------------------------------------- -// Test case 'f4' differs for region store and basic store. See -// retain-release-region-store.m and retain-release-basic-store.m. -//--------------------------------------------------------------------------- - -// Test a leak. - -CFAbsoluteTime f5(int x) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}} - - if (x) - CFRelease(date); - - return t; -} - -// Test a leak involving the return. - -CFDateRef f6(int x) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning{{leak}} - CFRetain(date); - return date; -} - -// Test a leak involving an overwrite. - -CFDateRef f7(void) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} - CFRetain(date); - date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning {{leak}} - return date; -} - -// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and -// has the word create. - -CF_IMPLICIT_BRIDGING_ENABLED - -CFDateRef MyDateCreate(void); - -CF_IMPLICIT_BRIDGING_DISABLED - - -CFDateRef f8(void) { - CFDateRef date = MyDateCreate(); // expected-warning{{leak}} - CFRetain(date); - return date; -} - -__attribute__((cf_returns_retained)) CFDateRef f9(void) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // no-warning - int *p = 0; - // When allocations fail, CFDateCreate can return null. - if (!date) *p = 1; // expected-warning{{null}} - return date; -} - -// Handle DiskArbitration API: -// -// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/ -// -void f10(io_service_t media, DADiskRef d, CFStringRef s) { - DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - CFDictionaryRef dict = DADiskCopyDescription(d); // expected-warning{{leak}} - if (dict) NSLog(@"ok"); - - disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, // expected-warning{{leak}} - kDAReturnSuccess, s); - if (dissenter) NSLog(@"ok"); - - DASessionRef session = DASessionCreate(kCFAllocatorDefault); // expected-warning{{leak}} - if (session) NSLog(@"ok"); -} - -// Test retain/release checker with CFString and CFMutableArray. -void f11(void) { - // Create the array. - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - - // Create a string. - CFStringRef s1 = CFStringCreateWithCString(0, "hello world", - kCFStringEncodingUTF8); - - // Add the string to the array. - CFArrayAppendValue(A, s1); - - // Decrement the reference count. - CFRelease(s1); // no-warning - - // Get the string. We don't own it. - s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); - - // Release the array. - CFRelease(A); // no-warning - - // Release the string. This is a bug. - CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} -} - -// PR 3337: Handle functions declared using typedefs. -typedef CFTypeRef CREATEFUN(void); - -CF_IMPLICIT_BRIDGING_ENABLED - -CFTypeRef MyCreateFun(void); - -CF_IMPLICIT_BRIDGING_DISABLED - - -void f12(void) { - CFTypeRef o = MyCreateFun(); // expected-warning {{leak}} -} - -void f13_autorelease(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning - [(id) A autorelease]; // no-warning -} - -void f13_autorelease_b(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; -} // expected-warning{{Object autoreleased too many times}} - -CFMutableArrayRef f13_autorelease_c(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; - return A; // expected-warning{{Object autoreleased too many times}} -} - -CFMutableArrayRef f13_autorelease_d(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; - CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object autoreleased too many times}} - CFRelease(B); // no-warning - while (1) {} -} - - -// This case exercises the logic where the leak site is the same as the allocation site. -void f14_leakimmediately(void) { - CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}} -} - -// Test that we track an allocated object beyond the point where the *name* -// of the variable storing the reference is no longer live. -void f15(void) { - // Create the array. - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - CFMutableArrayRef *B = &A; - // At this point, the name 'A' is no longer live. - CFRelease(*B); // no-warning -} - -// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease. -void f16(int x, CFTypeRef p) { - if (p) - return; - - switch (x) { - case 0: - CFRelease(p); - break; - case 1: - CFRetain(p); - break; - case 2: - CFMakeCollectable(p); - break; - case 3: - CFAutorelease(p); - break; - default: - break; - } -} - -// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease. -void f17(int x, CFTypeRef p) { - switch (x) { - case 0: - CFRelease(p); - if (!p) - CFRelease(0); // no-warning - break; - case 1: - CFRetain(p); - if (!p) - CFRetain(0); // no-warning - break; - case 2: - CFMakeCollectable(p); - if (!p) - CFMakeCollectable(0); // no-warning - break; - case 3: - CFAutorelease(p); - if (!p) - CFAutorelease(0); // no-warning - break; - default: - break; - } -} - -// Test basic tracking of ivars associated with 'self'. For the retain/release -// checker we currently do not want to flag leaks associated with stores -// of tracked objects to ivars. -@interface SelfIvarTest : NSObject { - id myObj; -} -- (void)test_self_tracking; -@end - -@implementation SelfIvarTest -- (void)test_self_tracking { - myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} -@end - -// Test return of non-owned objects in contexts where an owned object -// is expected. -@interface TestReturnNotOwnedWhenExpectedOwned -- (NSString*)newString; -@end - -@implementation TestReturnNotOwnedWhenExpectedOwned -- (NSString*)newString { - NSString *s = [NSString stringWithUTF8String:"hello"]; - return s; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} -@end - -int isFoo(char c); - -static void rdar_6659160(char *inkind, char *inname) -{ - // We currently expect that [NSObject alloc] cannot fail. This - // will be a toggled flag in the future. It can indeed return null, but - // Cocoa programmers generally aren't expected to reason about out-of-memory - // conditions. - NSString *kind = [[NSString alloc] initWithUTF8String:inkind]; // expected-warning{{leak}} - - // We do allow stringWithUTF8String to fail. This isn't really correct, as - // far as returning 0. In most error conditions it will throw an exception. - // If allocation fails it could return 0, but again this - // isn't expected. - NSString *name = [NSString stringWithUTF8String:inname]; - if(!name) - return; - - const char *kindC = 0; - const char *nameC = 0; - - // In both cases, we cannot reach a point down below where we - // dereference kindC or nameC with either being null. This is because - // we assume that [NSObject alloc] doesn't fail and that we have the guard - // up above. - - if(kind) - kindC = [kind UTF8String]; - if(name) - nameC = [name UTF8String]; - if(!isFoo(kindC[0])) // expected-warning{{null}} - return; - if(!isFoo(nameC[0])) // no-warning - return; - - [kind release]; - [name release]; // expected-warning{{Incorrect decrement of the reference count}} -} - -// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming -// conventions with respect to 'return'ing ownership. -@interface PR3677: NSObject @end -@implementation PR3677 -+ (id)allocWithZone:(NSZone *)inZone { - return [super allocWithZone:inZone]; // no-warning -} -@end - -// PR 3820 - Reason about calls to -dealloc -void pr3820_DeallocInsteadOfRelease(void) -{ - id foo = [[NSString alloc] init]; // no-warning - [foo dealloc]; - // foo is not leaked, since it has been deallocated. -} - -void pr3820_ReleaseAfterDealloc(void) -{ - id foo = [[NSString alloc] init]; - [foo dealloc]; - [foo release]; // expected-warning{{used after it is release}} - // NSInternalInconsistencyException: message sent to deallocated object -} - -void pr3820_DeallocAfterRelease(void) -{ - NSLog(@"\n\n[%s]", __FUNCTION__); - id foo = [[NSString alloc] init]; - [foo release]; - [foo dealloc]; // expected-warning{{used after it is released}} - // message sent to released object -} - -// The problem here is that 'length' binds to '($0 - 1)' after '--length', but -// SimpleConstraintManager doesn't know how to reason about -// '($0 - 1) > constant'. As a temporary hack, we drop the value of '($0 - 1)' -// and conjure a new symbol. -void rdar6704930(unsigned char *s, unsigned int length) { - NSString* name = 0; - if (s != 0) { - if (length > 0) { - while (length > 0) { - if (*s == ':') { - ++s; - --length; - name = [[NSString alloc] init]; // no-warning - break; - } - ++s; - --length; - } - if ((length == 0) && (name != 0)) { - [name release]; - name = 0; - } - if (length == 0) { // no ':' found -> use it all as name - name = [[NSString alloc] init]; // no-warning - } - } - } - - if (name != 0) { - [name release]; - } -} - -//===----------------------------------------------------------------------===// -// One build of the analyzer accidentally stopped tracking the allocated -// object after the 'retain'. -//===----------------------------------------------------------------------===// - -@interface rdar_6833332 : NSObject { - NSWindow *window; -} -@property (nonatomic, retain) NSWindow *window; -@end - -@implementation rdar_6833332 -@synthesize window; -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} - - [dict setObject:@"foo" forKey:@"bar"]; - - NSLog(@"%@", dict); -} -- (void)dealloc { - [window release]; - [super dealloc]; -} - -- (void)radar10102244 { - NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} - if (window) - NSLog(@"%@", window); -} -@end - -//===----------------------------------------------------------------------===// -// clang checker fails to catch use-after-release -//===----------------------------------------------------------------------===// -int rdar_6257780_Case1(void) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSArray *array = [NSArray array]; - [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} - [pool drain]; - return 0; -} - -//===----------------------------------------------------------------------===// -// Analyzer is confused about NSAutoreleasePool -allocWithZone:. -//===----------------------------------------------------------------------===// -void rdar_10640253_autorelease_allocWithZone(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool allocWithZone:(NSZone*)0] init]; - (void) pool; -} - -//===----------------------------------------------------------------------===// -// Checker should understand new/setObject:/release constructs -//===----------------------------------------------------------------------===// -void rdar_6866843(void) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init]; - NSArray* array = [[NSArray alloc] init]; - [dictionary setObject:array forKey:@"key"]; - [array release]; - // Using 'array' here should be fine - NSLog(@"array = %@\n", array); // no-warning - // Now the array is released - [dictionary release]; - [pool drain]; -} - - -//===----------------------------------------------------------------------===// -// Classes typedef-ed to CF objects should get the same treatment as CF objects -//===----------------------------------------------------------------------===// -typedef CFTypeRef OtherRef; - -@interface RDar6877235 : NSObject {} -- (CFTypeRef)_copyCFTypeRef CF_RETURNS_RETAINED; -- (OtherRef)_copyOtherRef CF_RETURNS_RETAINED; -@end - -@implementation RDar6877235 -- (CFTypeRef)_copyCFTypeRef { - return [[NSString alloc] init]; // no-warning -} -- (OtherRef)_copyOtherRef { - return [[NSString alloc] init]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// false positive - init method returns an object owned by caller -//===----------------------------------------------------------------------===// -@interface RDar6320065 : NSObject { - NSString *_foo; -} -- (instancetype)initReturningNewClass; -- (id)_initReturningNewClassBad; -- (instancetype)initReturningNewClassBad2; -@end - -@interface RDar6320065Subclass : RDar6320065 -@end - -@implementation RDar6320065 -- (instancetype)initReturningNewClass { - [self release]; - self = [[RDar6320065Subclass alloc] init]; // no-warning - return self; -} -- (id)_initReturningNewClassBad { - [self release]; - [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}} - return self; -} -- (instancetype)initReturningNewClassBad2 { - [self release]; - self = [[RDar6320065Subclass alloc] init]; - return [self autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} - -@end - -@implementation RDar6320065Subclass -@end - -int RDar6320065_test(void) { - RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning - [test release]; - return 0; -} - -//===----------------------------------------------------------------------===// -// -awakeAfterUsingCoder: returns an owned object and claims the receiver -//===----------------------------------------------------------------------===// -@interface RDar7129086 : NSObject {} @end -@implementation RDar7129086 -- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder { - [self release]; // no-warning - return [NSString alloc]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// [NSData dataWithBytesNoCopy] does not return a retained object -//===----------------------------------------------------------------------===// -@interface RDar6859457 : NSObject {} -- (NSString*) NoCopyString; -- (NSString*) noCopyString; -@end - -@implementation RDar6859457 -- (NSString*) NoCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} -- (NSString*) noCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} -@end - -void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) { - [x NoCopyString]; // expected-warning{{leak}} - [x noCopyString]; // expected-warning{{leak}} - [NSData dataWithBytesNoCopy:bytes length:dataLength]; // no-warning - [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning -} - -//===----------------------------------------------------------------------===// -// PR 4230 - an autorelease pool is not necessarily leaked during a premature -// return -//===----------------------------------------------------------------------===// - -static void PR4230(void) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning - NSString *object = [[[NSString alloc] init] autorelease]; // no-warning - return; -} - -static void PR4230_new(void) -{ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; // no-warning - NSString *object = [[[NSString alloc] init] autorelease]; // no-warning - return; -} - -//===----------------------------------------------------------------------===// -// Method name that has a null IdentifierInfo* for its first selector slot. -// This test just makes sure that we handle it. -//===----------------------------------------------------------------------===// -@interface TestNullIdentifier -@end - -@implementation TestNullIdentifier -+ (id):(int)x, ... { - return [[NSString alloc] init]; // expected-warning{{leak}} -} -@end - -//===----------------------------------------------------------------------===// -// don't flag leaks for return types that cannot be determined to be CF types -//===----------------------------------------------------------------------===// - -// We don't know if 'struct s6893565' represents a Core Foundation type, so -// we shouldn't emit an error here. -typedef struct s6893565* TD6893565; - -@interface RDar6893565 {} --(TD6893565)newThing; -@end - -@implementation RDar6893565 --(TD6893565)newThing { - return (TD6893565) [[NSString alloc] init]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// clang: false positives w/QC and CoreImage methods -//===----------------------------------------------------------------------===// -void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context, - NSString *str, CIImage *img, CGRect rect, - CIFormat form, CGColorSpaceRef cs) { - [view createSnapshotImageOfType:str]; // expected-warning{{leak}} - [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}} - [context createCGImage:img fromRect:rect]; // expected-warning{{leak}} - [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// -[CIContext createCGLayerWithSize:info:] misinterpreted by clang scan-build -//===----------------------------------------------------------------------===// -void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) { - [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// Add knowledge of IOKit functions to retain/release checker. -//===----------------------------------------------------------------------===// -void IOBSDNameMatching_wrapper(mach_port_t mainPort, uint32_t options, const char * bsdName) { - IOBSDNameMatching(mainPort, options, bsdName); // expected-warning{{leak}} -} - -void IOServiceMatching_wrapper(const char * name) { - IOServiceMatching(name); // expected-warning{{leak}} -} - -void IOServiceNameMatching_wrapper(const char * name) { - IOServiceNameMatching(name); // expected-warning{{leak}} -} - -CF_RETURNS_RETAINED CFDictionaryRef CreateDict(void); - -void IOServiceAddNotification_wrapper(mach_port_t mainPort, const io_name_t notificationType, - mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) { - - CFDictionaryRef matching = CreateDict(); - CFRelease(matching); - IOServiceAddNotification(mainPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}} - wakePort, reference, notification); -} - -void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) { - IORegistryEntryIDMatching(entryID); // expected-warning{{leak}} -} - -void IOOpenFirmwarePathMatching_wrapper(mach_port_t mainPort, uint32_t options, - const char * path) { - IOOpenFirmwarePathMatching(mainPort, options, path); // expected-warning{{leak}} -} - -void IOServiceGetMatchingService_wrapper(mach_port_t mainPort) { - CFDictionaryRef matching = CreateDict(); - IOServiceGetMatchingService(mainPort, matching); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -void IOServiceGetMatchingServices_wrapper(mach_port_t mainPort, io_iterator_t *existing) { - CFDictionaryRef matching = CreateDict(); - IOServiceGetMatchingServices(mainPort, matching, existing); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, - IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) { - - CFDictionaryRef matching = CreateDict(); - IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -//===----------------------------------------------------------------------===// -// Test of handling objects whose references "escape" to containers. -//===----------------------------------------------------------------------===// -void CFDictionaryAddValue(CFMutableDictionaryRef, void *, void *); - -void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) { - CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionaryAddValue(y, key, x); - CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); - if (value) { - CFDictionaryAddValue(x, val_key, (void*)value); // no-warning - CFRelease(value); - CFDictionaryAddValue(y, val_key, (void*)value); // no-warning - } -} - -// Same issue, except with "AppendValue" functions. -void rdar_6560661(CFMutableArrayRef x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); - // CFArrayAppendValue keeps a reference to value. - CFArrayAppendValue(x, value); - CFRelease(value); - CFRetain(value); - CFRelease(value); // no-warning -} - -// Same issue, excwept with "CFAttributeStringSetAttribute". -void rdar_7152619(CFStringRef str) { - CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0); - CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string); - CFRelease(string); - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} - CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number); - [number release]; - [number retain]; - CFRelease(attrString); -} - -//===----------------------------------------------------------------------===// -// Test of handling CGGradientXXX functions. -//===----------------------------------------------------------------------===// - -void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, - CGPoint myEndPoint) { - size_t num_locations = 6; - CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; - CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, - x, // Start color - 207.0/255.0, 39.0/255.0, 39.0/255.0, x, - 147.0/255.0, 21.0/255.0, 22.0/255.0, x, - 175.0/255.0, 175.0/255.0, 175.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x - }; // End color - - CGGradientRef myGradient = - CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}} - components, locations, num_locations); - - CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, - 0); - CGGradientRelease(myGradient); -} - -void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, - CGPoint myEndPoint) { - size_t num_locations = 6; - CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; - CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, - x, // Start color - 207.0/255.0, 39.0/255.0, 39.0/255.0, x, - 147.0/255.0, 21.0/255.0, 22.0/255.0, x, - 175.0/255.0, 175.0/255.0, 175.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x - }; // End color - - CGGradientRef myGradient = - CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}} - - CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, - 0); -} - -//===----------------------------------------------------------------------===// -// clang false positive: retained instance passed to thread in pthread_create -// marked as leak -// -// Until we have full IPA, the analyzer should stop tracking the reference -// count of objects passed to pthread_create. -// -//===----------------------------------------------------------------------===// -struct _opaque_pthread_t {}; -struct _opaque_pthread_attr_t {}; -typedef struct _opaque_pthread_t *__darwin_pthread_t; -typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t; -typedef __darwin_pthread_t pthread_t; -typedef __darwin_pthread_attr_t pthread_attr_t; -typedef unsigned long __darwin_pthread_key_t; -typedef __darwin_pthread_key_t pthread_key_t; - -int pthread_create(pthread_t *, const pthread_attr_t *, - void *(*)(void *), void *); - -int pthread_setspecific(pthread_key_t key, const void *value); - -void *rdar_7299394_start_routine(void *p) { - [((id) p) release]; - return 0; -} -void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - pthread_create(thread, attr, rdar_7299394_start_routine, number); -} -void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// false positive with not understanding thread local storage -//===----------------------------------------------------------------------===// -void rdar11282706(pthread_key_t key) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - pthread_setspecific(key, (void*) number); -} - -//===----------------------------------------------------------------------===// -// False leak associated with call to CVPixelBufferCreateWithBytes () -// -// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and -// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the -// pixel buffer object. These test cases show how the analyzer stops tracking -// the reference count for the objects passed for this argument. This -// could be made smarter. -//===----------------------------------------------------------------------===// -typedef int int32_t; -typedef UInt32 FourCharCode; -typedef FourCharCode OSType; -typedef uint64_t CVOptionFlags; -typedef int32_t CVReturn; -typedef struct __CVBuffer *CVBufferRef; -typedef CVBufferRef CVImageBufferRef; -typedef CVImageBufferRef CVPixelBufferRef; -typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress ); - -extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] ); - -extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *dataPtr, - size_t dataSize, - size_t numberOfPlanes, - void *planeBaseAddress[], - size_t planeWidth[], - size_t planeHeight[], - size_t planeBytesPerRow[], - CVPixelBufferReleasePlanarBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height, - OSType pixelFormatType, void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType, - baseAddress, bytesPerRow, releaseCallback, - number, // potentially released by callback - pixelBufferAttributes, pixelBufferOut) ; -} - -CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height, - OSType pixelFormatType, void *dataPtr, size_t dataSize, - size_t numberOfPlanes, void *planeBaseAddress[], - size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[], - CVPixelBufferReleasePlanarBytesCallback releaseCallback, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - return CVPixelBufferCreateWithPlanarBytes(allocator, - width, height, pixelFormatType, dataPtr, dataSize, - numberOfPlanes, planeBaseAddress, planeWidth, - planeHeight, planeBytesPerRow, releaseCallback, - number, // potentially released by callback - pixelBufferAttributes, pixelBufferOut) ; -} - -//===----------------------------------------------------------------------===// -// False leak associated with CGBitmapContextCreateWithData -//===----------------------------------------------------------------------===// -typedef uint32_t CGBitmapInfo; -typedef void (*CGBitmapContextReleaseDataCallback)(void *releaseInfo, void *data); - -CGContextRef CGBitmapContextCreateWithData(void *data, - size_t width, size_t height, size_t bitsPerComponent, - size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, - CGBitmapContextReleaseDataCallback releaseCallback, void *releaseInfo) CF_RETURNS_RETAINED; - -void rdar_7358899(void *data, - size_t width, size_t height, size_t bitsPerComponent, - size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, - CGBitmapContextReleaseDataCallback releaseCallback) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - CGBitmapContextCreateWithData(data, width, height, bitsPerComponent, // expected-warning{{leak}} - bytesPerRow, space, bitmapInfo, releaseCallback, number); -} - -//===----------------------------------------------------------------------===// -// Allow 'new', 'copy', 'alloc', 'init' prefix to start before '_' when -// determining Cocoa fundamental rule. -// -// Previously the retain/release checker just skipped prefixes before the -// first '_' entirely. Now the checker honors the prefix if it results in a -// recognizable naming convention (e.g., 'new', 'init'). -//===----------------------------------------------------------------------===// -@interface RDar7265711 {} -- (id) new_stuff; -@end - -void rdar7265711_a(RDar7265711 *x) { - id y = [x new_stuff]; // expected-warning{{leak}} -} - -void rdar7265711_b(RDar7265711 *x) { - id y = [x new_stuff]; // no-warning - [y release]; -} - -//===----------------------------------------------------------------------===// -// clang thinks [NSCursor dragCopyCursor] returns a retained reference -//===----------------------------------------------------------------------===// -@interface NSCursor : NSObject -+ (NSCursor *)dragCopyCursor; -@end - -void rdar7306898(void) { - // 'dragCopyCursor' does not follow Cocoa's fundamental rule. It is a noun, not an sentence - // implying a 'copy' of something. - NSCursor *c = [NSCursor dragCopyCursor]; // no-warning - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// Sending 'release', 'retain', etc. to a Class directly is not likely what the -// user intended. -//===----------------------------------------------------------------------===// -@interface RDar7252064 : NSObject @end -void rdar7252064(void) { - [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [NSAutoreleasePool drain]; // expected-warning{{method '+drain' not found}} expected-warning{{The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly}} -} - -//===----------------------------------------------------------------------===// -// Tests of ownership attributes. -//===----------------------------------------------------------------------===// - -typedef NSString* MyStringTy; - -@protocol FooP; - -@interface TestOwnershipAttr : NSObject -- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning -- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning -- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning -- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning -- (NSString*) newString_auto NS_RETURNS_AUTORELEASED; // no-warning -- (NSString*) newStringNoAttr; -- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}} -- (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED; -+ (void) consume:(id) NS_CONSUMED x; -+ (void) consume2:(id) CF_CONSUMED x; -@end - -static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions and methods}} - -void test_attr_1(TestOwnershipAttr *X) { - NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}} -} - -void test_attr_1b(TestOwnershipAttr *X) { - NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}} -} - -void test_attr1c(TestOwnershipAttr *X) { - NSString *str = [X newString]; // no-warning - NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}} - NSString *str3 = [X newString_auto]; // no-warning - NSString *str4 = [[X newString_auto] retain]; // expected-warning {{leak}} -} - -void testattr2_a(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // expected-warning{{leak}} -} - -void testattr2_b(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // expected-warning{{leak}} -} - -void testattr2_b_11358224_self_assign_looses_the_leak(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit];// expected-warning{{leak}} - x = x; -} - -void testattr2_c(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // no-warning - [x release]; -} - -void testattr3(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning - [TestOwnershipAttr consume:x]; - TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning - [TestOwnershipAttr consume2:y]; -} - -void consume_ns(id NS_CONSUMED x); -void consume_cf(id CF_CONSUMED x); - -void testattr4(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning - consume_ns(x); - TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning - consume_cf(y); -} - -@interface TestOwnershipAttr2 : NSObject -- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning -@end - -@implementation TestOwnershipAttr2 -- (NSString*) newString { - return [NSString alloc]; // expected-warning {{Potential leak of an object}} -} -@end - -@interface MyClassTestCFAttr : NSObject {} -- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED; -- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED; -- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED; -- (CFDateRef) newCFRetainedAsCFNoAttr CF_RETURNS_RETAINED; -- (NSDate*) alsoReturnsRetained; -- (CFDateRef) alsoReturnsRetainedAsCF CF_RETURNS_NOT_RETAINED; -- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; -@end - -CF_RETURNS_RETAINED -CFDateRef returnsRetainedCFDate(void) { - return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); -} - -@implementation MyClassTestCFAttr -- (NSDate*) returnsCFRetained { - return (NSDate*) returnsRetainedCFDate(); // No leak. -} - -- (CFDateRef) returnsCFRetainedAsCF { - return returnsRetainedCFDate(); // No leak. -} - -- (CFDateRef) newCFRetainedAsCF { - return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; -} - -- (CFDateRef) newCFRetainedAsCFNoAttr { - return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} - -- (NSDate*) alsoReturnsRetained { - return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}} -} - -- (CFDateRef) alsoReturnsRetainedAsCF { - return returnsRetainedCFDate(); // expected-warning{{leak}} -} - - -- (NSDate*) returnsNSRetained { - return (NSDate*) returnsRetainedCFDate(); // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// Test that leaks post-dominated by "panic" functions are not reported. -// -// Do not report a leak when post-dominated by a call to a noreturn or panic -// function. -//===----------------------------------------------------------------------===// -void panic(void) __attribute__((noreturn)); -void panic_not_in_hardcoded_list(void) __attribute__((noreturn)); - -void test_panic_negative(void) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} -} - -void test_panic_positive(void) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning - panic(); -} - -void test_panic_neg_2(int x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} - if (x) - panic(); -} - -void test_panic_pos_2(int x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning - if (x) - panic(); - if (!x) { - // This showed up previously where we silently missed checking the function - // type for noreturn. "panic()" is a hard-coded known panic function that - // isn't always noreturn. - panic_not_in_hardcoded_list(); - } -} - -//===----------------------------------------------------------------------===// -// Test uses of blocks (closures) -//===----------------------------------------------------------------------===// - -void test_blocks_1_pos(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} - ^{}(); -} - -void test_blocks_1_indirect_release(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^{ [number release]; }(); -} - -void test_blocks_1_indirect_retain(void) { - // Eventually this should be reported as a leak. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^{ [number retain]; }(); -} - -void test_blocks_1_indirect_release_via_call(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^(NSObject *o){ [o release]; }(number); -} - -void test_blocks_1_indirect_retain_via_call(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning {{leak}} - ^(NSObject *o){ [o retain]; }(number); -} - -//===--------------------------------------------------------------------===// -// Test sending message to super that returns an object alias. Previously -// this caused a crash in the analyzer. -//===--------------------------------------------------------------------===// - -@interface Rdar8015556 : NSObject {} @end -@implementation Rdar8015556 -- (id)retain { - return [super retain]; -} -@end - -// Correcly handle Class<...> in Cocoa Conventions detector. -@protocol Prot_R8272168 @end -Class GetAClassThatImplementsProt_R8272168(void); -void r8272168(void) { - GetAClassThatImplementsProt_R8272168(); -} - -// Test case which in the past triggered a false positive. -@interface RDar8356342 -- (NSDate*) rdar8356342:(NSDate *)inValue; -@end - -@implementation RDar8356342 -- (NSDate*) rdar8356342:(NSDate*)inValue { - NSDate *outValue = inValue; - if (outValue == 0) - outValue = [[NSDate alloc] init]; // no-warning - - if (outValue != inValue) - [outValue autorelease]; - - return outValue; -} -@end - -// This test case previously crashed because of a bug in BugReporter. -extern const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key) CF_RETURNS_NOT_RETAINED; -typedef struct __CFError * CFErrorRef; -extern const CFStringRef kCFErrorUnderlyingErrorKey; -extern CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err) CF_RETURNS_RETAINED; -static void rdar_8724287(CFErrorRef error) -{ - CFErrorRef error_to_dump; - - error_to_dump = error; - while (error_to_dump != ((void*)0)) { - CFDictionaryRef info; - - info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object}} - - if (info != ((void*)0)) { - } - - error_to_dump = (CFErrorRef) CFDictionaryGetValue(info, kCFErrorUnderlyingErrorKey); - } -} - -// Make sure the model applies cf_consumed correctly in argument positions -// besides the first. - -CF_IMPLICIT_BRIDGING_ENABLED - -extern void *CFStringCreate(void); - -CF_IMPLICIT_BRIDGING_DISABLED - -extern void rdar_9234108_helper(void *key, void * CF_CONSUMED value); -void rdar_9234108(void) { - rdar_9234108_helper(0, CFStringCreate()); -} - -// Make sure that objc_method_family works to override naming conventions. -struct TwoDoubles { - double one; - double two; -}; -typedef struct TwoDoubles TwoDoubles; - -@interface NSValue (Mine) -- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles __attribute__((objc_method_family(init))); -@end - -@implementation NSValue (Mine) -- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles -{ - return [self init]; -} -@end - -void rdar9726279(void) { - TwoDoubles twoDoubles = { 0.0, 0.0 }; - NSValue *value = [[NSValue alloc] _prefix_initWithTwoDoubles:twoDoubles]; - [value release]; -} - -// Test camelcase support for CF conventions. While Core Foundation APIs -// don't use camel casing, other code is allowed to use it. -CFArrayRef camelcase_create_1(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camelcase_createno(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef camelcase_copy(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camelcase_copying(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef copyCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef __copyCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef __createCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_create(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - - -CFArrayRef camel_creat(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef camel_copy(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_copyMachine(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_copymachine(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -@protocol F18P -- (id) clone; -@end -@interface F18 : NSObject @end -@interface F18(Cat) -- (id) clone NS_RETURNS_RETAINED; -@end - -@implementation F18 -- (id) clone { - return [F18 alloc]; -} -@end - -void rdar6582778(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFTypeRef vals[] = { CFDateCreate(0, t) }; // expected-warning {{leak}} -} - -CFTypeRef global; - -void rdar6582778_2(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - global = CFDateCreate(0, t); // no-warning -} - -// Test that objects passed to containers are marked "escaped". -void rdar10232019(void) { - NSMutableArray *array = [NSMutableArray array]; - - NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; - [array addObject:string]; - [string release]; - - NSString *otherString = [string stringByAppendingString:@"bar"]; // no-warning - NSLog(@"%@", otherString); -} - -void rdar10232019_positive(void) { - NSMutableArray *array = [NSMutableArray array]; - - NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; - [string release]; - - NSString *otherString = [string stringByAppendingString:@"bar"]; // expected-warning {{Reference-counted object is used after it is release}} - NSLog(@"%@", otherString); -} - -// RetainCountChecker support for XPC. -typedef void * xpc_object_t; -xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef cf); -void xpc_release(xpc_object_t object); - -void rdar9658496(void) { - CFStringRef cf; - xpc_object_t xpc; - cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - xpc = _CFXPCCreateXPCObjectFromCFObject( cf ); - CFRelease(cf); - xpc_release(xpc); -} - -// Support annotations with method families. -@interface RDar10824732 : NSObject -- (instancetype)initWithObj:(id CF_CONSUMED)obj; -@end - -@implementation RDar10824732 -- (instancetype)initWithObj:(id)obj { - [obj release]; - return [super init]; -} -@end - -void rdar_10824732(void) { - @autoreleasepool { - NSString *obj = @"test"; - RDar10824732 *foo = [[RDar10824732 alloc] initWithObj:obj]; // no-warning - [foo release]; - } -} - -// Stop tracking objects passed to functions, which take callbacks as parameters. -typedef int (*CloseCallback) (void *); -void ReaderForIO(CloseCallback ioclose, void *ioctx); -int IOClose(void *context); - -@protocol SInS -@end - -@interface radar10973977 : NSObject -- (id)inputS; -- (void)reader; -@end - -@implementation radar10973977 -- (void)reader -{ - id inputS = [[self inputS] retain]; - ReaderForIO(IOClose, inputS); -} -- (id)inputS -{ - return 0; -} -@end - -// Object escapes through a selector callback -extern id NSApp; -@interface MySheetController -- (id)inputS; -- (void)showDoSomethingSheetAction:(id)action; -- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; -@end - -@implementation MySheetController -- (id)inputS { - return 0; -} -- (void)showDoSomethingSheetAction:(id)action { - id inputS = [[self inputS] retain]; - [NSApp beginSheet:0 - modalForWindow:0 - modalDelegate:0 - didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo:(void *)inputS]; // no - warning -} -- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { - - id contextObject = (id)contextInfo; - [contextObject release]; -} - -- (id)copyAutoreleaseRadar13081402 { - id x = [[[NSString alloc] initWithUTF8String:"foo"] autorelease]; - [x retain]; - return x; // no warning -} - -@end -//===----------------------------------------------------------------------===// -// Test returning allocated memory in a struct. -// -// We currently don't have a general way to track pointers that "escape". -// Here we test that RetainCountChecker doesn't get excited about returning -// allocated CF objects in struct fields. -//===----------------------------------------------------------------------===// -void *malloc(size_t); -struct rdar11104566 { CFStringRef myStr; }; -struct rdar11104566 test_rdar11104566(void) { - CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - struct rdar11104566 V; - V.myStr = cf; - return V; // no-warning -} - -struct rdar11104566 *test_2_rdar11104566(void) { - CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - struct rdar11104566 *V = (struct rdar11104566 *) malloc(sizeof(*V)); - V->myStr = cf; - return V; // no-warning -} - -//===----------------------------------------------------------------------===// -// ObjC literals support. -//===----------------------------------------------------------------------===// - -void test_objc_arrays(void) { - { // CASE ONE -- OBJECT IN ARRAY CREATED DIRECTLY - NSObject *o = [[NSObject alloc] init]; - NSArray *a = [[NSArray alloc] initWithObjects:o, (void*)0]; // expected-warning {{leak}} - [o release]; - [a description]; - [o description]; - } - - { // CASE TWO -- OBJECT IN ARRAY CREATED BY DUPING AUTORELEASED ARRAY - NSObject *o = [[NSObject alloc] init]; - NSArray *a1 = [NSArray arrayWithObjects:o, (void*)0]; - NSArray *a2 = [[NSArray alloc] initWithArray:a1]; // expected-warning {{leak}} - [o release]; - [a2 description]; - [o description]; - } - - { // CASE THREE -- OBJECT IN RETAINED @[] - NSObject *o = [[NSObject alloc] init]; - NSArray *a3 = [@[o] retain]; // expected-warning {{leak}} - [o release]; - [a3 description]; - [o description]; - } - - { // CASE FOUR -- OBJECT IN ARRAY CREATED BY DUPING @[] - NSObject *o = [[NSObject alloc] init]; - NSArray *a = [[NSArray alloc] initWithArray:@[o]]; // expected-warning {{leak}} - [o release]; - - [a description]; - [o description]; - } - - { // CASE FIVE -- OBJECT IN RETAINED @{} - NSValue *o = [[NSValue alloc] init]; - NSDictionary *a = [@{o : o} retain]; // expected-warning {{leak}} - [o release]; - - [a description]; - [o description]; - } -} - -void test_objc_integer_literals(void) { - id value = [@1 retain]; // expected-warning {{leak}} - [value description]; -} - -void test_objc_boxed_expressions(int x, const char *y) { - id value = [@(x) retain]; // expected-warning {{leak}} - [value description]; - - value = [@(y) retain]; // expected-warning {{leak}} - [value description]; -} - -// Test NSLog doesn't escape tracked objects. -void rdar11400885(int y) -{ - @autoreleasepool { - NSString *printString; - if(y > 2) - printString = [[NSString alloc] init]; - else - printString = [[NSString alloc] init]; - NSLog(@"Once %@", printString); - [printString release]; - NSLog(@"Again: %@", printString); // expected-warning {{Reference-counted object is used after it is released}} - } -} - -id makeCollectableNonLeak(void) { - extern CFTypeRef CFCreateSomething(void); - - CFTypeRef object = CFCreateSomething(); // +1 - CFRetain(object); // +2 - id objCObject = NSMakeCollectable(object); // +2 - [objCObject release]; // +1 - return [objCObject autorelease]; // +0 -} - - -void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void)); -void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void)); - -void testConsumeAndStopTracking(void) { - id retained = [@[] retain]; // +1 - consumeAndStopTracking(retained, ^{}); // no-warning - - id doubleRetained = [[@[] retain] retain]; // +2 - consumeAndStopTracking(doubleRetained, ^{ - [doubleRetained release]; - }); // no-warning - - id unretained = @[]; // +0 - consumeAndStopTracking(unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} - -void testCFConsumeAndStopTracking(void) { - id retained = [@[] retain]; // +1 - CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // no-warning - - id doubleRetained = [[@[] retain] retain]; // +2 - CFConsumeAndStopTracking((CFTypeRef)doubleRetained, ^{ - [doubleRetained release]; - }); // no-warning - - id unretained = @[]; // +0 - CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} -//===----------------------------------------------------------------------===// -// Test 'pragma clang arc_cf_code_audited' support. -//===----------------------------------------------------------------------===// - -typedef void *MyCFType; -#pragma clang arc_cf_code_audited begin -MyCFType CreateMyCFType(void); -#pragma clang arc_cf_code_audited end - -void test_custom_cf(void) { - MyCFType x = CreateMyCFType(); // expected-warning {{leak of an object stored into 'x'}} -} - -//===----------------------------------------------------------------------===// -// Test calling CFPlugInInstanceCreate, which appears in CF but doesn't -// return a CF object. -//===----------------------------------------------------------------------===// - -void test_CFPlugInInstanceCreate(CFUUIDRef factoryUUID, CFUUIDRef typeUUID) { - CFPlugInInstanceCreate(kCFAllocatorDefault, factoryUUID, typeUUID); // no-warning -} - -//===----------------------------------------------------------------------===// -// PR14927: -drain only has retain-count semantics on NSAutoreleasePool. -//===----------------------------------------------------------------------===// - -@interface PR14927 : NSObject -- (void)drain; -@end - -void test_drain(void) { - PR14927 *obj = [[PR14927 alloc] init]; - [obj drain]; - [obj release]; // no-warning -} - -//===----------------------------------------------------------------------===// -// Allow cf_returns_retained and cf_returns_not_retained to mark a return -// value as tracked, even if the object isn't a known CF type. -//===----------------------------------------------------------------------===// - -MyCFType getCustom(void) __attribute__((cf_returns_not_retained)); -MyCFType makeCustom(void) __attribute__((cf_returns_retained)); - -void testCustomReturnsRetained(void) { - MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}} -} - -void testCustomReturnsNotRetained(void) { - CFRelease(getCustom()); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} - -//===----------------------------------------------------------------------===// -// Don't print variables which are out of the current scope. -//===----------------------------------------------------------------------===// -@interface MyObj12706177 : NSObject --(instancetype)initX; -+(void)test12706177; -@end -static int Cond; -@implementation MyObj12706177 --(instancetype)initX { - if (Cond) - return 0; - self = [super init]; - return self; -} -+(void)test12706177 { - id x = [[MyObj12706177 alloc] initX]; //expected-warning {{Potential leak of an object}} - [x release]; -} -@end - -//===----------------------------------------------------------------------===// -// xpc_connection_set_finalizer_f -//===----------------------------------------------------------------------===// -typedef xpc_object_t xpc_connection_t; -typedef void (*xpc_finalizer_t)(void *value); -void xpc_connection_set_context(xpc_connection_t connection, void *ctx); -void xpc_connection_set_finalizer_f(xpc_connection_t connection, - xpc_finalizer_t finalizer); -void releaseAfterXPC(void *context) { - [(NSArray *)context release]; -} - -void rdar13783514(xpc_connection_t connection) { - xpc_connection_set_context(connection, [[NSMutableArray alloc] init]); - xpc_connection_set_finalizer_f(connection, releaseAfterXPC); -} // no-warning - -CFAttributedStringRef CFAttributedCreate(void *CFObj CF_CONSUMED) CF_RETURNS_RETAINED; - -@interface Action -@property (nonatomic) SEL action; -@property (nonatomic, assign) id target; -@end diff --git a/clang/test/ARCMT/objcmt-atomic-property.m b/clang/test/ARCMT/objcmt-atomic-property.m deleted file mode 100644 index 00b5e09c8e084c..00000000000000 --- a/clang/test/ARCMT/objcmt-atomic-property.m +++ /dev/null @@ -1,227 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -objcmt-atomic-property -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 -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -- (void) setWeakProp : (NSString *__weak)Val; -- (NSString *__weak) WeakProp; - -- (NSString *) StrongProp; -- (void) setStrongProp : (NSString *)Val; - -- (NSString *) UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -- (NSString *) UnavailProp1 __attribute__((unavailable)); -- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); - -- (NSString *) UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -- (NSDictionary*) undoAction; -- (void) setUndoAction: (NSDictionary*)Arg; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -- (void)setNames1:(NSArray *)names; -- (void)setNames4:(__strong NSArray *)names; -- (void)setNames3:(__strong NSArray *)names; -- (void)setNames2:(NSArray *)names; -- (NSArray *) names2; -- (NSArray *)names3; -- (__strong NSArray *)names4; -- (NSArray *) names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; -- (void *)JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -- (BOOL)isIgnoringInteractionEvents; - -- (NSString *)getStringValue; -- (BOOL)getCounterValue; -- (void)setStringValue:(NSString *)stringValue AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; -- (NSDictionary *)getns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - - -@interface NSInvocation(CAT) -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -- (NSURL *)appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -- (NSURL *)appStoreReceiptURLX NS_AVAILABLE; -- (void) setAppStoreReceiptURLX : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -- (id)OkToInfer NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -- (id)method1 ALIGNED NS_AVAILABLE; -- (void) setMethod1 : (id) object NS_AVAILABLE ALIGNED; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -- (BOOL)isClass; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -- (id (^)(id, NSArray *, NSMutableDictionary *)) expressionBlock; -- (id (^)(id, NSArray *, NSMutableDictionary *)) MyBlock; -- (void) setMyBlock : (id (^)(id, NSArray *, NSMutableDictionary *)) bl; -- (id (*)(id, NSArray *, NSMutableDictionary *)) expressionFuncptr; -- (id (*)(id, NSArray *, NSMutableDictionary *)) MyFuncptr; -- (void) setMyFuncptr : (id (*)(id, NSArray *, NSMutableDictionary *)) bl; -@end diff --git a/clang/test/ARCMT/objcmt-atomic-property.m.result b/clang/test/ARCMT/objcmt-atomic-property.m.result deleted file mode 100644 index c829a7aacb50d0..00000000000000 --- a/clang/test/ARCMT/objcmt-atomic-property.m.result +++ /dev/null @@ -1,200 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -objcmt-atomic-property -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 -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -@property (weak) NSString *WeakProp; - -@property (strong) NSString *StrongProp; - -@property (strong) NSString *UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -@property (strong) NSString *UnavailProp1 __attribute__((unavailable)); - -@property (strong) NSString *UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -@property (copy) NSDictionary *undoAction; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -@property (strong) NSArray *names2; -@property (strong) NSArray *names3; -@property (strong) NSArray *names4; -@property (strong) NSArray *names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -@property (assign) id target; - -@property (assign) id dataSource; - -@property (assign) id xxxdelegateYYY; - - -@property (strong) id MYtarget; - -@property (strong) id targetX; - -@property int value; - -@property (getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (readonly) int Length; -@property (readonly, strong) id object; -+ (double) D; -@property (readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -@property (getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents; - -@property (getter=getStringValue, strong) NSString *stringValue; -@property (getter=getCounterValue, readonly) BOOL counterValue; -@property (getter=getns_dixtionary, readonly, copy) NSDictionary *ns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (getter=getM, readonly) BOOL m; -@property (getter=getMA, readonly) BOOL MA; -@property (getter=getALL, readonly) BOOL ALL; -@property (getter=getMANY, readonly) BOOL MANY; -@property (getter=getSome, readonly) BOOL some; -@end - - -@interface NSInvocation(CAT) -@property (assign) id target; - -@property (assign) id dataSource; - -@property (assign) id xxxdelegateYYY; - - -@property (strong) id MYtarget; - -@property (strong) id targetX; - -@property int value; - -@property (getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (readonly) int Length; -@property (readonly, strong) id object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (getter=getM, readonly) BOOL m; -@property (getter=getMA, readonly) BOOL MA; -@property (getter=getALL, readonly) BOOL ALL; -@property (getter=getMANY, readonly) BOOL MANY; -@property (getter=getSome, readonly) BOOL some; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -@property (strong) NSURL *appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -@property (strong) NSURL *appStoreReceiptURLX NS_AVAILABLE; - -// Do not infer a property. -@property (strong) NSURL *appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -@property (readonly, strong) id OkToInfer NS_AVAILABLE; - -// Do not infer a property. -@property (strong) NSURL *appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -@property (strong) id method1 ALIGNED NS_AVAILABLE; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -@property (getter=isClass, readonly) BOOL class; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -@property (readonly, copy) id (^expressionBlock)(id, NSArray *, NSMutableDictionary *); -@property (copy) id (^MyBlock)(id, NSArray *, NSMutableDictionary *); -@property (readonly) id (*expressionFuncptr)(id, NSArray *, NSMutableDictionary *); -@property id (*MyFuncptr)(id, NSArray *, NSMutableDictionary *); -@end diff --git a/clang/test/ARCMT/objcmt-boxing.m b/clang/test/ARCMT/objcmt-boxing.m deleted file mode 100644 index 07ee68dda33bd7..00000000000000 --- a/clang/test/ARCMT/objcmt-boxing.m +++ /dev/null @@ -1,106 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fobjc-arc -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ -verify -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s.result - -#define YES __objc_yes -#define NO __objc_no - -typedef long NSInteger; -typedef unsigned long NSUInteger; -typedef signed char BOOL; -#define nil ((void*) 0) - -#define INT_MIN (-__INT_MAX__ -1) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -- (id)initWithChar:(char)value; -- (id)initWithUnsignedChar:(unsigned char)value; -- (id)initWithShort:(short)value; -- (id)initWithUnsignedShort:(unsigned short)value; -- (id)initWithInt:(int)value; -- (id)initWithUnsignedInt:(unsigned int)value; -- (id)initWithLong:(long)value; -- (id)initWithUnsignedLong:(unsigned long)value; -- (id)initWithLongLong:(long long)value; -- (id)initWithUnsignedLongLong:(unsigned long long)value; -- (id)initWithFloat:(float)value; -- (id)initWithDouble:(double)value; -- (id)initWithBool:(BOOL)value; -- (id)initWithInteger:(NSInteger)value; -- (id)initWithUnsignedInteger:(NSUInteger)value; - -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value; -@end - -enum { - NSASCIIStringEncoding = 1, - NSUTF8StringEncoding = 4, - NSUnicodeStringEncoding = 10 -}; -typedef NSUInteger NSStringEncoding; - -@interface NSString : NSObject -@end - -@interface NSString (NSStringExtensionMethods) -+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; -+ (id)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc; -+ (id)stringWithCString:(const char *)bytes; -- (instancetype)initWithUTF8String:(const char *)nullTerminatedCString; -@end - -enum MyEnm { - ME_foo -}; - -void foo() { - [NSNumber numberWithInt:INT_MIN]; - bool cppb; - [NSNumber numberWithBool:cppb]; - MyEnm myenum; - [NSNumber numberWithInteger:myenum]; - [NSNumber numberWithInteger:ME_foo]; - [NSNumber numberWithDouble:cppb]; // expected-warning {{converting to boxing syntax requires casting 'bool' to 'double'}} -} - -void boxString() { - NSString *s = [NSString stringWithUTF8String:"box"]; - const char *cstr1; - char *cstr2; - s = [NSString stringWithUTF8String:cstr1]; - s = [NSString stringWithUTF8String:cstr2]; - s = [NSString stringWithCString:cstr1 encoding:NSASCIIStringEncoding]; - s = [NSString stringWithCString:cstr1 encoding:NSUTF8StringEncoding]; - s = [NSString stringWithCString:cstr1 encoding: NSUnicodeStringEncoding]; - NSStringEncoding encode; - s = [NSString stringWithCString:cstr1 encoding:encode]; - s = [NSString stringWithCString:cstr1]; - - static const char strarr[] = "coolbox"; - s = [NSString stringWithUTF8String:strarr]; - const char *utf8Bytes = "blah"; - NSString *string1 = [NSString stringWithUTF8String:utf8Bytes]; - NSString *string2 = [[NSString alloc] initWithUTF8String:utf8Bytes]; -} diff --git a/clang/test/ARCMT/objcmt-boxing.m.result b/clang/test/ARCMT/objcmt-boxing.m.result deleted file mode 100644 index a60b35900bf384..00000000000000 --- a/clang/test/ARCMT/objcmt-boxing.m.result +++ /dev/null @@ -1,106 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fobjc-arc -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ -verify -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s.result - -#define YES __objc_yes -#define NO __objc_no - -typedef long NSInteger; -typedef unsigned long NSUInteger; -typedef signed char BOOL; -#define nil ((void*) 0) - -#define INT_MIN (-__INT_MAX__ -1) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -- (id)initWithChar:(char)value; -- (id)initWithUnsignedChar:(unsigned char)value; -- (id)initWithShort:(short)value; -- (id)initWithUnsignedShort:(unsigned short)value; -- (id)initWithInt:(int)value; -- (id)initWithUnsignedInt:(unsigned int)value; -- (id)initWithLong:(long)value; -- (id)initWithUnsignedLong:(unsigned long)value; -- (id)initWithLongLong:(long long)value; -- (id)initWithUnsignedLongLong:(unsigned long long)value; -- (id)initWithFloat:(float)value; -- (id)initWithDouble:(double)value; -- (id)initWithBool:(BOOL)value; -- (id)initWithInteger:(NSInteger)value; -- (id)initWithUnsignedInteger:(NSUInteger)value; - -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value; -@end - -enum { - NSASCIIStringEncoding = 1, - NSUTF8StringEncoding = 4, - NSUnicodeStringEncoding = 10 -}; -typedef NSUInteger NSStringEncoding; - -@interface NSString : NSObject -@end - -@interface NSString (NSStringExtensionMethods) -+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; -+ (id)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc; -+ (id)stringWithCString:(const char *)bytes; -- (instancetype)initWithUTF8String:(const char *)nullTerminatedCString; -@end - -enum MyEnm { - ME_foo -}; - -void foo() { - @INT_MIN; - bool cppb; - @(cppb); - MyEnm myenum; - @(myenum); - @(ME_foo); - [NSNumber numberWithDouble:cppb]; // expected-warning {{converting to boxing syntax requires casting 'bool' to 'double'}} -} - -void boxString() { - NSString *s = @"box"; - const char *cstr1; - char *cstr2; - s = @(cstr1); - s = @(cstr2); - s = @(cstr1); - s = @(cstr1); - s = [NSString stringWithCString:cstr1 encoding: NSUnicodeStringEncoding]; - NSStringEncoding encode; - s = [NSString stringWithCString:cstr1 encoding:encode]; - s = @(cstr1); - - static const char strarr[] = "coolbox"; - s = @(strarr); - const char *utf8Bytes = "blah"; - NSString *string1 = @(utf8Bytes); - NSString *string2 = @(utf8Bytes); -} diff --git a/clang/test/ARCMT/objcmt-designated-initializer.m b/clang/test/ARCMT/objcmt-designated-initializer.m deleted file mode 100644 index 279d4f35d8eb19..00000000000000 --- a/clang/test/ARCMT/objcmt-designated-initializer.m +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-designated-init %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-arc %s.result - -#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) - -@class NSString; - -@interface B1 --(id)init; -@end - -@interface S1 : B1 --(id)initWithFoo:(NSString*)foo; -@end - -@implementation S1 --(id)initWithFoo:(NSString*)foo -{ - self = [super init]; - if (self) { - } - return self; -} -@end - -@interface B2 --(id)init NS_DESIGNATED_INITIALIZER; -@end - -@interface S2 : B2 --(id)init; -@end - -@implementation S2 --(id)init -{ - self = [super init]; - if (self) { - } - return self; -} -@end diff --git a/clang/test/ARCMT/objcmt-designated-initializer.m.result b/clang/test/ARCMT/objcmt-designated-initializer.m.result deleted file mode 100644 index 4c59b0cc582616..00000000000000 --- a/clang/test/ARCMT/objcmt-designated-initializer.m.result +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-designated-init %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-arc %s.result - -#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) - -@class NSString; - -@interface B1 --(id)init; -@end - -@interface S1 : B1 --(id)initWithFoo:(NSString*)foo NS_DESIGNATED_INITIALIZER; -@end - -@implementation S1 --(id)initWithFoo:(NSString*)foo -{ - self = [super init]; - if (self) { - } - return self; -} -@end - -@interface B2 --(id)init NS_DESIGNATED_INITIALIZER; -@end - -@interface S2 : B2 --(id)init; -@end - -@implementation S2 --(id)init -{ - self = [super init]; - if (self) { - } - return self; -} -@end diff --git a/clang/test/ARCMT/objcmt-instancetype-2.m b/clang/test/ARCMT/objcmt-instancetype-2.m deleted file mode 100644 index fb59265c4be32b..00000000000000 --- a/clang/test/ARCMT/objcmt-instancetype-2.m +++ /dev/null @@ -1,103 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-instancetype -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef unsigned int NSUInteger; -typedef int NSInteger; -typedef char BOOL; -@class NSData, NSError, NSProtocolChecker, NSObject; -@class NSPortNameServer, NSTimeZone; - -@interface NSMutableString -@end - -@interface NSString @end - -@class NSString, NSURL; -@interface NSString (NSStringDeprecated) -+ (id)stringWithContentsOfFile:(NSString *)path __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithContentsOfURL:(NSURL *)url __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithCString:(const char *)bytes length:(NSUInteger)length __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithCString:(const char *)bytes __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -@end - - -typedef enum NSURLBookmarkResolutionOptions { - Bookmark -} NSURLBookmarkResolutionOptions; - -@interface NSURL -+ (id)URLWithString:(NSString *)URLString; -+ (id)URLWithString:(NSString *)URLString relativeToURL:(NSURL *)baseURL; -+ (id)URLByResolvingBookmarkData:(NSData *)bookmarkData options:(NSURLBookmarkResolutionOptions)options relativeToURL:(NSURL *)relativeURL bookmarkDataIsStale:(BOOL *)isStale error:(NSError **)error __attribute__((availability(macosx,introduced=10.6))); -@end - -@class NSDictionary; -@interface NSError -+ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict; -@end - - -@interface NSMutableString (NSMutableStringExtensionMethods) -+ (id)stringWithCapacity:(NSUInteger)capacity; -@end - -@interface NSMutableData -+ (id)dataWithCapacity:(NSUInteger)aNumItems; -+ (id)dataWithLength:(NSUInteger)length; -@end - -@interface NSMutableDictionary @end - -@interface NSMutableDictionary (NSSharedKeySetDictionary) -+ (id )dictionaryWithSharedKeySet:(id)keyset __attribute__((availability(macosx,introduced=10.8))); -@end - -@interface NSProtocolChecker -+ (id)protocolCheckerWithTarget:(NSObject *)anObject protocol:(Protocol *)aProtocol; -@end - -@interface NSConnection -+ (id)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName; -+ (id)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName usingNameServer:(NSPortNameServer *)server; -@end - -@interface NSDate -+ (id)dateWithString:(NSString *)aString __attribute__((availability(macosx,introduced=10.4))); -@end - -@interface NSCalendarDate : NSDate -+ (id)calendarDate __attribute__((availability(macosx,introduced=10.4))); -+ (id)dateWithString:(NSString *)description calendarFormat:(NSString *)format locale:(id)locale __attribute__((availability(macosx,introduced=10.4))); -+ (id)dateWithString:(NSString *)description calendarFormat:(NSString *)format __attribute__((availability(macosx,introduced=10.4))); -+ (id)dateWithYear:(NSInteger)year month:(NSUInteger)month day:(NSUInteger)day hour:(NSUInteger)hour minute:(NSUInteger)minute second:(NSUInteger)second timeZone:(NSTimeZone *)aTimeZone __attribute__((availability(macosx,introduced=10.4))); -@end - -@interface NSUserDefaults -+ (id) standardUserDefaults; -@end - -@interface NSNotificationCenter -+ (id) defaultCenter; -+ sharedCenter; -@end - -@interface UIApplication -+ (id)sharedApplication; -+ defaultApplication; -@end - -//===----------------------------------------------------------------------===// -// Method name that has a null IdentifierInfo* for its first selector slot. -// This test just makes sure that we handle it. -//===----------------------------------------------------------------------===// -@interface TestNullIdentifier -@end - -@implementation TestNullIdentifier -+ (id):(int)x, ... { - return 0; -} -@end - diff --git a/clang/test/ARCMT/objcmt-instancetype-2.m.result b/clang/test/ARCMT/objcmt-instancetype-2.m.result deleted file mode 100644 index 7a32894f570602..00000000000000 --- a/clang/test/ARCMT/objcmt-instancetype-2.m.result +++ /dev/null @@ -1,103 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-instancetype -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef unsigned int NSUInteger; -typedef int NSInteger; -typedef char BOOL; -@class NSData, NSError, NSProtocolChecker, NSObject; -@class NSPortNameServer, NSTimeZone; - -@interface NSMutableString -@end - -@interface NSString @end - -@class NSString, NSURL; -@interface NSString (NSStringDeprecated) -+ (id)stringWithContentsOfFile:(NSString *)path __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithContentsOfURL:(NSURL *)url __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithCString:(const char *)bytes length:(NSUInteger)length __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithCString:(const char *)bytes __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -@end - - -typedef enum NSURLBookmarkResolutionOptions { - Bookmark -} NSURLBookmarkResolutionOptions; - -@interface NSURL -+ (instancetype)URLWithString:(NSString *)URLString; -+ (instancetype)URLWithString:(NSString *)URLString relativeToURL:(NSURL *)baseURL; -+ (instancetype)URLByResolvingBookmarkData:(NSData *)bookmarkData options:(NSURLBookmarkResolutionOptions)options relativeToURL:(NSURL *)relativeURL bookmarkDataIsStale:(BOOL *)isStale error:(NSError **)error __attribute__((availability(macosx,introduced=10.6))); -@end - -@class NSDictionary; -@interface NSError -+ (instancetype)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict; -@end - - -@interface NSMutableString (NSMutableStringExtensionMethods) -+ (instancetype)stringWithCapacity:(NSUInteger)capacity; -@end - -@interface NSMutableData -+ (instancetype)dataWithCapacity:(NSUInteger)aNumItems; -+ (instancetype)dataWithLength:(NSUInteger)length; -@end - -@interface NSMutableDictionary @end - -@interface NSMutableDictionary (NSSharedKeySetDictionary) -+ (instancetype )dictionaryWithSharedKeySet:(id)keyset __attribute__((availability(macosx,introduced=10.8))); -@end - -@interface NSProtocolChecker -+ (instancetype)protocolCheckerWithTarget:(NSObject *)anObject protocol:(Protocol *)aProtocol; -@end - -@interface NSConnection -+ (instancetype)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName; -+ (instancetype)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName usingNameServer:(NSPortNameServer *)server; -@end - -@interface NSDate -+ (instancetype)dateWithString:(NSString *)aString __attribute__((availability(macosx,introduced=10.4))); -@end - -@interface NSCalendarDate : NSDate -+ (instancetype)calendarDate __attribute__((availability(macosx,introduced=10.4))); -+ (instancetype)dateWithString:(NSString *)description calendarFormat:(NSString *)format locale:(id)locale __attribute__((availability(macosx,introduced=10.4))); -+ (instancetype)dateWithString:(NSString *)description calendarFormat:(NSString *)format __attribute__((availability(macosx,introduced=10.4))); -+ (instancetype)dateWithYear:(NSInteger)year month:(NSUInteger)month day:(NSUInteger)day hour:(NSUInteger)hour minute:(NSUInteger)minute second:(NSUInteger)second timeZone:(NSTimeZone *)aTimeZone __attribute__((availability(macosx,introduced=10.4))); -@end - -@interface NSUserDefaults -+ (instancetype) standardUserDefaults; -@end - -@interface NSNotificationCenter -+ (NSNotificationCenter*) defaultCenter; -+ (NSNotificationCenter*) sharedCenter; -@end - -@interface UIApplication -+ (UIApplication*)sharedApplication; -+ (UIApplication*) defaultApplication; -@end - -//===----------------------------------------------------------------------===// -// Method name that has a null IdentifierInfo* for its first selector slot. -// This test just makes sure that we handle it. -//===----------------------------------------------------------------------===// -@interface TestNullIdentifier -@end - -@implementation TestNullIdentifier -+ (id):(int)x, ... { - return 0; -} -@end - diff --git a/clang/test/ARCMT/objcmt-instancetype-unnecessary-diff.m b/clang/test/ARCMT/objcmt-instancetype-unnecessary-diff.m deleted file mode 100644 index e250bb0956c050..00000000000000 --- a/clang/test/ARCMT/objcmt-instancetype-unnecessary-diff.m +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %clang_cc1 -objcmt-migrate-instancetype %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap -// RUN: FileCheck %s -input-file=%t.remap - -// Make sure we don't create an edit unnecessarily. -// CHECK-NOT: instancetype - -@class NSString; -@interface NSDictionary -+(instancetype) dictionaryWithURLEncodedString:(NSString *)urlEncodedString; -@end diff --git a/clang/test/ARCMT/objcmt-instancetype.m b/clang/test/ARCMT/objcmt-instancetype.m deleted file mode 100644 index 17dd5a46b1e785..00000000000000 --- a/clang/test/ARCMT/objcmt-instancetype.m +++ /dev/null @@ -1,111 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-instancetype -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSString : NSObject -+ (id)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; -@end - -@implementation NSString : NSObject -+ (id)stringWithString:(NSString *)string { return 0; }; -- (instancetype)initWithString:(NSString *)aString { return 0; }; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -- (id)objectAtIndexedSubscript:(int)index; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; - -- (id)objectAtIndex:(unsigned long)index; -@end - -@implementation NSArray (NSArrayCreation) -+ (id)array { return 0; } -+ (id)arrayWithObject:(id)anObject { - return anObject; -} -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } -+ (id)arrayWithObjects:(id)firstObj, ... { - return 0; } -+ arrayWithArray:(NSArray *)array { - return 0; -} - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } -- (id)initWithObjects:(id)firstObj, ... { return 0; } -- (id)initWithArray:(NSArray *)array { return 0; } - -- (id)objectAtIndex:(unsigned long)index { return 0; } -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -- (void)setObject:(id)object atIndexedSubscript:(int)index; -@end - -@interface NSDictionary : NSObject -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)objectForKey:(id)aKey; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -- (void)setObject:(id)object forKeyedSubscript:(id)key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -@implementation NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value { return 0; } -@end - -#define M(x) (x) -#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] -#define TWO(x) ((x), (x)) - -void foo(void) { - NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}} - str = [[NSString alloc] initWithString:@"foo"]; // expected-warning {{redundant}} - NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}} - NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}} -} diff --git a/clang/test/ARCMT/objcmt-instancetype.m.result b/clang/test/ARCMT/objcmt-instancetype.m.result deleted file mode 100644 index 5203368aad6442..00000000000000 --- a/clang/test/ARCMT/objcmt-instancetype.m.result +++ /dev/null @@ -1,111 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-instancetype -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSString : NSObject -+ (instancetype)stringWithString:(NSString *)string; -- (instancetype)initWithString:(NSString *)aString; -@end - -@implementation NSString : NSObject -+ (instancetype)stringWithString:(NSString *)string { return 0; }; -- (instancetype)initWithString:(NSString *)aString { return 0; }; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -- (id)objectAtIndexedSubscript:(int)index; -@end - -@interface NSArray (NSArrayCreation) -+ (instancetype)array; -+ (instancetype)arrayWithObject:(id)anObject; -+ (instancetype)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (instancetype)arrayWithObjects:(id)firstObj, ...; -+ (instancetype) arrayWithArray:(NSArray *)array; - -- (instancetype)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (instancetype)initWithObjects:(id)firstObj, ...; -- (instancetype)initWithArray:(NSArray *)array; - -- (id)objectAtIndex:(unsigned long)index; -@end - -@implementation NSArray (NSArrayCreation) -+ (instancetype)array { return 0; } -+ (instancetype)arrayWithObject:(id)anObject { - return anObject; -} -+ (instancetype)arrayWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } -+ (instancetype)arrayWithObjects:(id)firstObj, ... { - return 0; } -+ (instancetype) arrayWithArray:(NSArray *)array { - return 0; -} - -- (instancetype)initWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } -- (instancetype)initWithObjects:(id)firstObj, ... { return 0; } -- (instancetype)initWithArray:(NSArray *)array { return 0; } - -- (id)objectAtIndex:(unsigned long)index { return 0; } -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -- (void)setObject:(id)object atIndexedSubscript:(int)index; -@end - -@interface NSDictionary : NSObject -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (instancetype)dictionary; -+ (instancetype)dictionaryWithObject:(id)object forKey:(id)key; -+ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (instancetype) dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (instancetype)dictionaryWithDictionary:(NSDictionary *)dict; -+ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (instancetype)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (instancetype)initWithObjectsAndKeys:(id)firstObject, ...; -- (instancetype)initWithDictionary:(NSDictionary *)otherDictionary; -- (instancetype)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)objectForKey:(id)aKey; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -- (void)setObject:(id)object forKeyedSubscript:(id)key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -@implementation NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value { return 0; } -@end - -#define M(x) (x) -#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] -#define TWO(x) ((x), (x)) - -void foo(void) { - NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}} - str = [[NSString alloc] initWithString:@"foo"]; // expected-warning {{redundant}} - NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}} - NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}} -} diff --git a/clang/test/ARCMT/objcmt-invalid-code.mm b/clang/test/ARCMT/objcmt-invalid-code.mm deleted file mode 100644 index f780d3de57ed80..00000000000000 --- a/clang/test/ARCMT/objcmt-invalid-code.mm +++ /dev/null @@ -1,19 +0,0 @@ -// REQUIRES: x86-registered-target -// RUN: rm -rf %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only %s -verify -// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result - -// Make sure there is no crash. - -@interface NSObject @end -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -void foo(int x = undeclared) { // expected-error {{undeclared}} - NSNumber *n = [NSNumber numberWithInt:1]; -} diff --git a/clang/test/ARCMT/objcmt-invalid-code.mm.result b/clang/test/ARCMT/objcmt-invalid-code.mm.result deleted file mode 100644 index 52b2db00f61096..00000000000000 --- a/clang/test/ARCMT/objcmt-invalid-code.mm.result +++ /dev/null @@ -1,19 +0,0 @@ -// REQUIRES: x86-registered-target -// RUN: rm -rf %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only %s -verify -// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result - -// Make sure there is no crash. - -@interface NSObject @end -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -void foo(int x = undeclared) { // expected-error {{undeclared}} - NSNumber *n = @1; -} diff --git a/clang/test/ARCMT/objcmt-migrate-all.m b/clang/test/ARCMT/objcmt-migrate-all.m deleted file mode 100644 index 0aa66756b761c7..00000000000000 --- a/clang/test/ARCMT/objcmt-migrate-all.m +++ /dev/null @@ -1,133 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-all -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure -#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) -#endif - -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") - -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) - -CF_IMPLICIT_BRIDGING_ENABLED - -typedef unsigned long CFTypeID; -typedef unsigned long CFOptionFlags; -typedef unsigned long CFHashCode; - -typedef signed long CFIndex; /*AnyObj*/ -typedef const struct __CFArray * CFArrayRef; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; - -typedef void (*CFArrayApplierFunction)(const void *value, void *context); - -typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { - kCFCompareLessThan = -1L, - kCFCompareEqualTo = 0, - kCFCompareGreaterThan = 1 -}; - - -typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); - -typedef struct __CFArray * CFMutableArrayRef; - -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; - -typedef const struct __CFAllocator * CFAllocatorRef; - -typedef const struct __CFString * CFStringRef; -typedef struct __CFString * CFMutableStringRef; - -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; - -typedef struct CGImage *CGImageRef; - -typedef struct OpaqueJSValue* JSObjectRef; - -typedef JSObjectRef TTJSObjectRef; -typedef unsigned int NSUInteger; - -CF_IMPLICIT_BRIDGING_DISABLED - -@interface I -- (void*) ReturnsInnerPointer; -- (int*) AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; -@end - -@interface UIImage -- (CGImageRef)CGImage; -@end - -@interface NSData -- (void *)bytes; -- (void **) ptr_bytes __attribute__((availability(macosx,unavailable))); -@end - -@interface NSMutableData -- (void *)mutableBytes __attribute__((deprecated)) __attribute__((unavailable)); -@end - -@interface JS -- (JSObjectRef)JSObject; -- (TTJSObjectRef)JSObject1; -- (JSObjectRef*)JSObject2; -@end - -typedef void *SecTrustRef; - -@interface NSURLProtectionSpace -@property (readonly) SecTrustRef serverTrust NS_AVAILABLE; -- (void *) FOO NS_AVAILABLE; -@property (readonly) void * mitTrust NS_AVAILABLE; - -@property (readonly) void * mittiTrust; - -@property (readonly) SecTrustRef XserverTrust; - -- (SecTrustRef) FOO1 NS_AVAILABLE; - -+ (const NSURLProtectionSpace *)ProtectionSpace; - -// pointer personality functions -@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); -@end - -@interface MustNotMigrateToInnerPointer -- (void*) nono; -- (void) setNono : (void*) val; -@end diff --git a/clang/test/ARCMT/objcmt-migrate-all.m.result b/clang/test/ARCMT/objcmt-migrate-all.m.result deleted file mode 100644 index e0972875e11b81..00000000000000 --- a/clang/test/ARCMT/objcmt-migrate-all.m.result +++ /dev/null @@ -1,132 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-all -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure -#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) -#endif - -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") - -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) - -CF_IMPLICIT_BRIDGING_ENABLED - -typedef unsigned long CFTypeID; -typedef unsigned long CFOptionFlags; -typedef unsigned long CFHashCode; - -typedef signed long CFIndex; /*AnyObj*/ -typedef const struct __CFArray * CFArrayRef; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; - -typedef void (*CFArrayApplierFunction)(const void *value, void *context); - -typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { - kCFCompareLessThan = -1L, - kCFCompareEqualTo = 0, - kCFCompareGreaterThan = 1 -}; - - -typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); - -typedef struct __CFArray * CFMutableArrayRef; - -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; - -typedef const struct __CFAllocator * CFAllocatorRef; - -typedef const struct __CFString * CFStringRef; -typedef struct __CFString * CFMutableStringRef; - -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; - -typedef struct CGImage *CGImageRef; - -typedef struct OpaqueJSValue* JSObjectRef; - -typedef JSObjectRef TTJSObjectRef; -typedef unsigned int NSUInteger; - -CF_IMPLICIT_BRIDGING_DISABLED - -@interface I -@property (nonatomic, readonly) void *ReturnsInnerPointer; -@property (nonatomic, readonly) int *AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; -@end - -@interface UIImage -@property (nonatomic, readonly) CGImageRef CGImage CF_RETURNS_NOT_RETAINED; -@end - -@interface NSData -@property (nonatomic, readonly) void *bytes; -@property (nonatomic, readonly) void **ptr_bytes __attribute__((availability(macosx,unavailable))); -@end - -@interface NSMutableData -@property (nonatomic, readonly) void *mutableBytes __attribute__((deprecated)) __attribute__((unavailable)); -@end - -@interface JS -@property (nonatomic, readonly) JSObjectRef JSObject; -@property (nonatomic, readonly) TTJSObjectRef JSObject1; -@property (nonatomic, readonly) JSObjectRef *JSObject2; -@end - -typedef void *SecTrustRef; - -@interface NSURLProtectionSpace -@property (readonly) SecTrustRef serverTrust NS_AVAILABLE; -@property (nonatomic, readonly) void *FOO NS_AVAILABLE; -@property (readonly) void * mitTrust NS_AVAILABLE; - -@property (readonly) void * mittiTrust; - -@property (readonly) SecTrustRef XserverTrust; - -@property (nonatomic, readonly) SecTrustRef FOO1 NS_AVAILABLE; - -+ (const NSURLProtectionSpace *)ProtectionSpace; - -// pointer personality functions -@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); -@end - -@interface MustNotMigrateToInnerPointer -@property (nonatomic) void *nono; -@end diff --git a/clang/test/ARCMT/objcmt-ns-enum-crash.m b/clang/test/ARCMT/objcmt-ns-enum-crash.m deleted file mode 100644 index 7c9c708efaefba..00000000000000 --- a/clang/test/ARCMT/objcmt-ns-enum-crash.m +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -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 - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type -typedef long NSInteger; - -typedef enum : NSInteger {five} ApplicableEnum; - -typedef unsigned long mytd; - -#define MY_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t -MY_ENUM(MyEnum, unsigned int, One); diff --git a/clang/test/ARCMT/objcmt-ns-enum-crash.m.result b/clang/test/ARCMT/objcmt-ns-enum-crash.m.result deleted file mode 100644 index 0a76e66ea2111b..00000000000000 --- a/clang/test/ARCMT/objcmt-ns-enum-crash.m.result +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -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 - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type -typedef long NSInteger; - -typedef NS_ENUM(NSInteger, ApplicableEnum) {five}; - -typedef unsigned long mytd; - -#define MY_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t -MY_ENUM(MyEnum, unsigned int, One); diff --git a/clang/test/ARCMT/objcmt-ns-macros.m b/clang/test/ARCMT/objcmt-ns-macros.m deleted file mode 100644 index 902e765bead3a3..00000000000000 --- a/clang/test/ARCMT/objcmt-ns-macros.m +++ /dev/null @@ -1,379 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef signed char int8_t; -typedef short int16_t; -typedef int int32_t; -typedef long NSInteger; -typedef long long int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long NSUInteger; -typedef unsigned long long uint64_t; - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type -#define DEPRECATED __attribute__((deprecated)) - -enum { - blah, - blarg -}; -typedef NSInteger wibble; - -enum { - UIViewAutoresizingNone = 0, - UIViewAutoresizingFlexibleLeftMargin, - UIViewAutoresizingFlexibleWidth, - UIViewAutoresizingFlexibleRightMargin, - UIViewAutoresizingFlexibleTopMargin, - UIViewAutoresizingFlexibleHeight, - UIViewAutoresizingFlexibleBottomMargin -}; -typedef NSUInteger UITableViewCellStyle; - -typedef enum { - UIViewAnimationTransitionNone, - UIViewAnimationTransitionFlipFromLeft, - UIViewAnimationTransitionFlipFromRight, - UIViewAnimationTransitionCurlUp, - UIViewAnimationTransitionCurlDown, -} UIViewAnimationTransition; - -typedef enum { - UIViewOne = 0, - UIViewTwo = 1 << 0, - UIViewThree = 1 << 1, - UIViewFour = 1 << 2, - UIViewFive = 1 << 3, - UIViewSix = 1 << 4, - UIViewSeven = 1 << 5 -} UITableView; - -enum { - UIOne = 0, - UITwo = 0x1, - UIthree = 0x8, - UIFour = 0x100 -}; -typedef NSInteger UI; - -typedef enum { - UIP2One = 0, - UIP2Two = 0x1, - UIP2three = 0x8, - UIP2Four = 0x100 -} UIPOWER2; - -enum { - UNOne, - UNTwo -}; - -// Should use NS_ENUM even though it is all power of 2. -enum { - UIKOne = 1, - UIKTwo = 2, -}; -typedef NSInteger UIK; - -typedef enum { - NSTickMarkBelow = 0, - NSTickMarkAbove = 1, - NSTickMarkLeft = NSTickMarkAbove, - NSTickMarkRight = NSTickMarkBelow -} NSTickMarkPosition; - -enum { - UIViewNone = 0x0, - UIViewMargin = 0x1, - UIViewWidth = 0x2, - UIViewRightMargin = 0x3, - UIViewBottomMargin = 0xbadbeef -}; -typedef NSInteger UITableStyle; - -enum { - UIView0 = 0, - UIView1 = 0XBADBEEF -}; -typedef NSInteger UIStyle; - -enum { - NSTIFFFileType, - NSBMPFileType, - NSGIFFileType, - NSJPEGFileType, - NSPNGFileType, - NSJPEG2000FileType -}; -typedef NSUInteger NSBitmapImageFileType; - -enum { - NSWarningAlertStyle = 0, - NSInformationalAlertStyle = 1, - NSCriticalAlertStyle = 2 -}; -typedef NSUInteger NSAlertStyle; - -enum { - D_NSTIFFFileType, - D_NSBMPFileType, - D_NSGIFFileType, - D_NSJPEGFileType, - D_NSPNGFileType, - D_NSJPEG2000FileType -}; -typedef NSUInteger D_NSBitmapImageFileType DEPRECATED; - -typedef enum { - D_NSTickMarkBelow = 0, - D_NSTickMarkAbove = 1 -} D_NSTickMarkPosition DEPRECATED; - - -#define NS_ENUM_AVAILABLE(X,Y) - -enum { - NSFStrongMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 0), - NSFOpaqueMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 0), - NSFMallocMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 0), - NSFMachVirtualMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 0), - NSFWeakMemory NS_ENUM_AVAILABLE(10_8, 6_0) = (5UL << 0), - - NSFObjectPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 8), - NSFOpaquePersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 8), - NSFObjectPointerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 8), - NSFCStringPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 8), - NSFStructPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 8), - NSFIntegerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (5UL << 8), - NSFCopyIn NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 16), -}; - -typedef NSUInteger NSFOptions; - -typedef enum { - UIP0One = 0, - UIP0Two = 1, - UIP0Three = 2, - UIP0Four = 10, - UIP0Last = 0x100 -} UIP; - -typedef enum { - UIPZero = 0x0, - UIPOne = 0x1, - UIPTwo = 0x2, - UIP10 = 0x10, - UIPHundred = 0x100 -} UIP_3; - -typedef enum { - UIP4Zero = 0x0, - UIP4One = 0x1, - UIP4Two = 0x2, - UIP410 = 0x10, - UIP4Hundred = 100 -} UIP4_3; - -typedef enum { - UIP5Zero = 0x0, - UIP5Two = 0x2, - UIP510 = 0x3, - UIP5Hundred = 0x4 -} UIP5_3; - -typedef enum { - UIP6Zero = 0x0, - UIP6One = 0x1, - UIP6Two = 0x2, - UIP610 = 10, - UIP6Hundred = 0x100 -} UIP6_3; - -typedef enum { - UIP7Zero = 0x0, - UIP7One = 1, - UIP7Two = 0x2, - UIP710 = 10, - UIP7Hundred = 100 -} UIP7_3; - - -typedef enum { - Random = 0, - Random1 = 2, - Random2 = 4, - Random3 = 0x12345, - Random4 = 0x3444444, - Random5 = 0xbadbeef, - Random6 -} UIP8_3; - -#define NS_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) -#define NS_ENUM_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) - -enum { - NSModalResponseStop = (-1000), // Also used as the default response for sheets - NSModalResponseAbort = (-1001), - NSModalResponseContinue = (-1002), -} NS_ENUM_AVAILABLE_MAC(10.9); -typedef NSInteger NSModalResponse NS_AVAILABLE_MAC(10.9); - -typedef NSUInteger FarFarAwayOptions; - -typedef NSUInteger FarAwayOptions; -enum { - NSWorkspaceLaunchAndPrint = 0x00000002, - NSWorkspaceLaunchWithErrorPresentation = 0x00000040, - NSWorkspaceLaunchInhibitingBackgroundOnly = 0x00000080, - NSWorkspaceLaunchWithoutAddingToRecents = 0x00000100, - NSWorkspaceLaunchWithoutActivation = 0x00000200, - NSWorkspaceLaunchAsync = 0x00010000, - NSWorkspaceLaunchAllowingClassicStartup = 0x00020000, - NSWorkspaceLaunchPreferringClassic = 0x00040000, - NSWorkspaceLaunchNewInstance = 0x00080000, - NSWorkspaceLaunchAndHide = 0x00100000, - NSWorkspaceLaunchAndHideOthers = 0x00200000, - NSWorkspaceLaunchDefault = NSWorkspaceLaunchAsync | - NSWorkspaceLaunchAllowingClassicStartup -}; -typedef NSUInteger NSWorkspaceLaunchOptions; - -enum { - NSExcludeQuickDrawElementsIconCreationOption = 1 << 1, - NSExclude10_4ElementsIconCreationOption = 1 << 2 -}; -typedef NSUInteger NSExcludeOptions; - -enum { - NSExcludeQuickDrawElementsCreationOption = 1 << 1, - NSExclude10_4ElementsCreationOption = 1 << 2 -}; -typedef NSUInteger NSExcludeCreationOption; - -enum { - FarAway1 = 1 << 1, - FarAway2 = 1 << 2 -}; - -enum { - NSExcludeQuickDrawElementsIconOption = 1 << 1, - NSExclude10_4ElementsIconOption = 1 << 2 -}; -typedef NSUInteger NSExcludeIconOptions; - -@interface INTF { - NSExcludeIconOptions I1; - NSExcludeIconOptions I2; -} -@end - -enum { - FarFarAway1 = 1 << 1, - FarFarAway2 = 1 << 2 -}; - -typedef NS_OPTIONS(NSUInteger, NSWindowOcclusionState) { - NSWindowOcclusionStateVisible = 1UL << 1, -}; - -typedef NSUInteger NSWindowNumberListOptions; - -enum { - NSDirectSelection = 0, - NSSelectingNext, - NSSelectingPrevious -}; -typedef NSUInteger NSSelectionDirection; - -// standard window buttons -enum { - NSWindowCloseButton, - NSWindowMiniaturizeButton, - NSWindowZoomButton, - NSWindowToolbarButton, - NSWindowDocumentIconButton -}; - -typedef enum : NSUInteger { - ThingOne, - ThingTwo, - ThingThree, -} Thing; - -typedef enum { - one = 1 -} NumericEnum; - -typedef enum { - Two = 2 -}NumericEnum2; - -typedef enum { - Three = 3 -} -NumericEnum3; - -typedef enum { - Four = 4 -} - - NumericEnum4; - -enum -{ - UI8one = 1 -}; -typedef int8_t MyEnumeratedType; - - -enum { - UI16One = 0, - UI16Two = 0x1, - UI16three = 0x8, - UI16Four = 0x100 -}; -typedef int16_t UI16; - -enum { - UI32ViewAutoresizingNone = 0, - UI32ViewAutoresizingFlexibleLeftMargin, - UI32ViewAutoresizingFlexibleWidth, - UI32ViewAutoresizingFlexibleRightMargin, - UI32ViewAutoresizingFlexibleTopMargin, - UI32ViewAutoresizingFlexibleHeight, - UI32ViewAutoresizingFlexibleBottomMargin -}; -typedef uint32_t UI32TableViewCellStyle; - -enum -{ - UIU8one = 1 -}; -typedef uint8_t UI8Type; - -typedef enum : NSInteger {zero} MyEnum; - -typedef enum : NSUInteger {two} MyEnumNSUInteger; - -typedef enum : int {three, four} MyEnumint; - -typedef enum : unsigned long {five} MyEnumlonglong; - -typedef enum : unsigned long long { - ll1, - ll2= 0xff, - ll3, - ll4 -} MyEnumunsignedlonglong; - -typedef enum : int8_t {int8_one} MyOneEnum; - -typedef enum : int16_t { - int16_t_one, - int16_t_two } Myint16_tEnum; diff --git a/clang/test/ARCMT/objcmt-ns-macros.m.result b/clang/test/ARCMT/objcmt-ns-macros.m.result deleted file mode 100644 index d4c0870e8cdc3a..00000000000000 --- a/clang/test/ARCMT/objcmt-ns-macros.m.result +++ /dev/null @@ -1,355 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef signed char int8_t; -typedef short int16_t; -typedef int int32_t; -typedef long NSInteger; -typedef long long int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long NSUInteger; -typedef unsigned long long uint64_t; - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type -#define DEPRECATED __attribute__((deprecated)) - -typedef NS_ENUM(NSInteger, wibble) { - blah, - blarg -}; - -typedef NS_ENUM(NSUInteger, UITableViewCellStyle) { - UIViewAutoresizingNone = 0, - UIViewAutoresizingFlexibleLeftMargin, - UIViewAutoresizingFlexibleWidth, - UIViewAutoresizingFlexibleRightMargin, - UIViewAutoresizingFlexibleTopMargin, - UIViewAutoresizingFlexibleHeight, - UIViewAutoresizingFlexibleBottomMargin -}; - -typedef NS_ENUM(unsigned int, UIViewAnimationTransition) { - UIViewAnimationTransitionNone, - UIViewAnimationTransitionFlipFromLeft, - UIViewAnimationTransitionFlipFromRight, - UIViewAnimationTransitionCurlUp, - UIViewAnimationTransitionCurlDown, -}; - -typedef NS_OPTIONS(unsigned int, UITableView) { - UIViewOne = 0, - UIViewTwo = 1 << 0, - UIViewThree = 1 << 1, - UIViewFour = 1 << 2, - UIViewFive = 1 << 3, - UIViewSix = 1 << 4, - UIViewSeven = 1 << 5 -}; - -typedef NS_OPTIONS(NSUInteger, UI) { - UIOne = 0, - UITwo = 0x1, - UIthree = 0x8, - UIFour = 0x100 -}; - -typedef NS_OPTIONS(unsigned int, UIPOWER2) { - UIP2One = 0, - UIP2Two = 0x1, - UIP2three = 0x8, - UIP2Four = 0x100 -}; - -enum { - UNOne, - UNTwo -}; - -// Should use NS_ENUM even though it is all power of 2. -typedef NS_ENUM(NSInteger, UIK) { - UIKOne = 1, - UIKTwo = 2, -}; - -typedef NS_ENUM(unsigned int, NSTickMarkPosition) { - NSTickMarkBelow = 0, - NSTickMarkAbove = 1, - NSTickMarkLeft = NSTickMarkAbove, - NSTickMarkRight = NSTickMarkBelow -}; - -typedef NS_OPTIONS(NSUInteger, UITableStyle) { - UIViewNone = 0x0, - UIViewMargin = 0x1, - UIViewWidth = 0x2, - UIViewRightMargin = 0x3, - UIViewBottomMargin = 0xbadbeef -}; - -typedef NS_OPTIONS(NSUInteger, UIStyle) { - UIView0 = 0, - UIView1 = 0XBADBEEF -}; - -typedef NS_ENUM(NSUInteger, NSBitmapImageFileType) { - NSTIFFFileType, - NSBMPFileType, - NSGIFFileType, - NSJPEGFileType, - NSPNGFileType, - NSJPEG2000FileType -}; - -typedef NS_ENUM(NSUInteger, NSAlertStyle) { - NSWarningAlertStyle = 0, - NSInformationalAlertStyle = 1, - NSCriticalAlertStyle = 2 -}; - -enum { - D_NSTIFFFileType, - D_NSBMPFileType, - D_NSGIFFileType, - D_NSJPEGFileType, - D_NSPNGFileType, - D_NSJPEG2000FileType -}; -typedef NSUInteger D_NSBitmapImageFileType DEPRECATED; - -typedef enum { - D_NSTickMarkBelow = 0, - D_NSTickMarkAbove = 1 -} D_NSTickMarkPosition DEPRECATED; - - -#define NS_ENUM_AVAILABLE(X,Y) - - -typedef NS_OPTIONS(NSUInteger, NSFOptions) { - NSFStrongMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 0), - NSFOpaqueMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 0), - NSFMallocMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 0), - NSFMachVirtualMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 0), - NSFWeakMemory NS_ENUM_AVAILABLE(10_8, 6_0) = (5UL << 0), - - NSFObjectPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 8), - NSFOpaquePersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 8), - NSFObjectPointerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 8), - NSFCStringPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 8), - NSFStructPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 8), - NSFIntegerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (5UL << 8), - NSFCopyIn NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 16), -}; - -typedef NS_ENUM(unsigned int, UIP) { - UIP0One = 0, - UIP0Two = 1, - UIP0Three = 2, - UIP0Four = 10, - UIP0Last = 0x100 -}; - -typedef NS_OPTIONS(unsigned int, UIP_3) { - UIPZero = 0x0, - UIPOne = 0x1, - UIPTwo = 0x2, - UIP10 = 0x10, - UIPHundred = 0x100 -}; - -typedef NS_ENUM(unsigned int, UIP4_3) { - UIP4Zero = 0x0, - UIP4One = 0x1, - UIP4Two = 0x2, - UIP410 = 0x10, - UIP4Hundred = 100 -}; - -typedef NS_OPTIONS(unsigned int, UIP5_3) { - UIP5Zero = 0x0, - UIP5Two = 0x2, - UIP510 = 0x3, - UIP5Hundred = 0x4 -}; - -typedef NS_ENUM(unsigned int, UIP6_3) { - UIP6Zero = 0x0, - UIP6One = 0x1, - UIP6Two = 0x2, - UIP610 = 10, - UIP6Hundred = 0x100 -}; - -typedef NS_ENUM(unsigned int, UIP7_3) { - UIP7Zero = 0x0, - UIP7One = 1, - UIP7Two = 0x2, - UIP710 = 10, - UIP7Hundred = 100 -}; - - -typedef NS_ENUM(unsigned int, UIP8_3) { - Random = 0, - Random1 = 2, - Random2 = 4, - Random3 = 0x12345, - Random4 = 0x3444444, - Random5 = 0xbadbeef, - Random6 -}; - -#define NS_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) -#define NS_ENUM_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) - -typedef NS_ENUM(NSInteger, NSModalResponse) { - NSModalResponseStop = (-1000), // Also used as the default response for sheets - NSModalResponseAbort = (-1001), - NSModalResponseContinue = (-1002), -} NS_ENUM_AVAILABLE_MAC(10.9); - -typedef NSUInteger FarFarAwayOptions; - -typedef NS_OPTIONS(NSUInteger, FarAwayOptions) { - FarAway1 = 1 << 1, - FarAway2 = 1 << 2 -}; -typedef NS_OPTIONS(NSUInteger, NSWorkspaceLaunchOptions) { - NSWorkspaceLaunchAndPrint = 0x00000002, - NSWorkspaceLaunchWithErrorPresentation = 0x00000040, - NSWorkspaceLaunchInhibitingBackgroundOnly = 0x00000080, - NSWorkspaceLaunchWithoutAddingToRecents = 0x00000100, - NSWorkspaceLaunchWithoutActivation = 0x00000200, - NSWorkspaceLaunchAsync = 0x00010000, - NSWorkspaceLaunchAllowingClassicStartup = 0x00020000, - NSWorkspaceLaunchPreferringClassic = 0x00040000, - NSWorkspaceLaunchNewInstance = 0x00080000, - NSWorkspaceLaunchAndHide = 0x00100000, - NSWorkspaceLaunchAndHideOthers = 0x00200000, - NSWorkspaceLaunchDefault = NSWorkspaceLaunchAsync | - NSWorkspaceLaunchAllowingClassicStartup -}; - -typedef NS_OPTIONS(NSUInteger, NSExcludeOptions) { - NSExcludeQuickDrawElementsIconCreationOption = 1 << 1, - NSExclude10_4ElementsIconCreationOption = 1 << 2 -}; - -typedef NS_OPTIONS(NSUInteger, NSExcludeCreationOption) { - NSExcludeQuickDrawElementsCreationOption = 1 << 1, - NSExclude10_4ElementsCreationOption = 1 << 2 -}; - - -typedef NS_OPTIONS(NSUInteger, NSExcludeIconOptions) { - NSExcludeQuickDrawElementsIconOption = 1 << 1, - NSExclude10_4ElementsIconOption = 1 << 2 -}; - -@interface INTF { - NSExcludeIconOptions I1; - NSExcludeIconOptions I2; -} -@end - -enum { - FarFarAway1 = 1 << 1, - FarFarAway2 = 1 << 2 -}; - -typedef NS_OPTIONS(NSUInteger, NSWindowOcclusionState) { - NSWindowOcclusionStateVisible = 1UL << 1, -}; - -typedef NS_ENUM(NSUInteger, NSWindowNumberListOptions) { - NSWindowCloseButton, - NSWindowMiniaturizeButton, - NSWindowZoomButton, - NSWindowToolbarButton, - NSWindowDocumentIconButton -}; - -typedef NS_ENUM(NSUInteger, NSSelectionDirection) { - NSDirectSelection = 0, - NSSelectingNext, - NSSelectingPrevious -}; - -// standard window buttons - -typedef NS_ENUM(NSUInteger, Thing) { - ThingOne, - ThingTwo, - ThingThree, -}; - -typedef NS_ENUM(unsigned int, NumericEnum) { - one = 1 -}; - -typedef NS_ENUM(unsigned int, NumericEnum2) { - Two = 2 -}; - -typedef NS_ENUM(unsigned int, NumericEnum3) { - Three = 3 -}; - -typedef NS_OPTIONS(unsigned int, NumericEnum4) { - Four = 4 -}; - -typedef NS_ENUM(int8_t, MyEnumeratedType) -{ - UI8one = 1 -}; - - -typedef NS_OPTIONS(uint16_t, UI16) { - UI16One = 0, - UI16Two = 0x1, - UI16three = 0x8, - UI16Four = 0x100 -}; - -typedef NS_ENUM(uint32_t, UI32TableViewCellStyle) { - UI32ViewAutoresizingNone = 0, - UI32ViewAutoresizingFlexibleLeftMargin, - UI32ViewAutoresizingFlexibleWidth, - UI32ViewAutoresizingFlexibleRightMargin, - UI32ViewAutoresizingFlexibleTopMargin, - UI32ViewAutoresizingFlexibleHeight, - UI32ViewAutoresizingFlexibleBottomMargin -}; - -typedef NS_ENUM(uint8_t, UI8Type) -{ - UIU8one = 1 -}; - -typedef NS_ENUM(NSInteger, MyEnum) {zero}; - -typedef NS_ENUM(NSUInteger, MyEnumNSUInteger) {two}; - -typedef NS_ENUM(int, MyEnumint) {three, four}; - -typedef NS_ENUM(unsigned long, MyEnumlonglong) {five}; - -typedef NS_ENUM(unsigned long long, MyEnumunsignedlonglong) { - ll1, - ll2= 0xff, - ll3, - ll4 -}; - -typedef NS_ENUM(int8_t, MyOneEnum) {int8_one}; - -typedef NS_ENUM(int16_t, Myint16_tEnum) { - int16_t_one, - int16_t_two }; diff --git a/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m b/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m deleted file mode 100644 index 55a116c8ca5da4..00000000000000 --- a/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m +++ /dev/null @@ -1,233 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-ns-nonatomic-iosonly -objcmt-migrate-readonly-property -objcmt-atomic-property -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 -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -#if TARGET_OS_IPHONE - #define NS_NONATOMIC_IOSONLY nonatomic -#else - #define NS_NONATOMIC_IOSONLY atomic -#endif - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -- (void) setWeakProp : (NSString *__weak)Val; -- (NSString *__weak) WeakProp; - -- (NSString *) StrongProp; -- (void) setStrongProp : (NSString *)Val; - -- (NSString *) UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -- (NSString *) UnavailProp1 __attribute__((unavailable)); -- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); - -- (NSString *) UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -- (NSDictionary*) undoAction; -- (void) setUndoAction: (NSDictionary*)Arg; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -- (void)setNames1:(NSArray *)names; -- (void)setNames4:(__strong NSArray *)names; -- (void)setNames3:(__strong NSArray *)names; -- (void)setNames2:(NSArray *)names; -- (NSArray *) names2; -- (NSArray *)names3; -- (__strong NSArray *)names4; -- (NSArray *) names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; -- (void *)JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -- (BOOL)isIgnoringInteractionEvents; - -- (NSString *)getStringValue; -- (BOOL)getCounterValue; -- (void)setStringValue:(NSString *)stringValue AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; -- (NSDictionary *)getns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - - -@interface NSInvocation(CAT) -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -- (NSURL *)appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -- (NSURL *)appStoreReceiptURLX NS_AVAILABLE; -- (void) setAppStoreReceiptURLX : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -- (id)OkToInfer NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -- (id)method1 ALIGNED NS_AVAILABLE; -- (void) setMethod1 : (id) object NS_AVAILABLE ALIGNED; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -- (BOOL)isClass; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -- (id (^)(id, NSArray *, NSMutableDictionary *)) expressionBlock; -- (id (^)(id, NSArray *, NSMutableDictionary *)) MyBlock; -- (void) setMyBlock : (id (^)(id, NSArray *, NSMutableDictionary *)) bl; -- (id (*)(id, NSArray *, NSMutableDictionary *)) expressionFuncptr; -- (id (*)(id, NSArray *, NSMutableDictionary *)) MyFuncptr; -- (void) setMyFuncptr : (id (*)(id, NSArray *, NSMutableDictionary *)) bl; -@end diff --git a/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result b/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result deleted file mode 100644 index 512deb12583a99..00000000000000 --- a/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result +++ /dev/null @@ -1,206 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-ns-nonatomic-iosonly -objcmt-migrate-readonly-property -objcmt-atomic-property -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 -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -#if TARGET_OS_IPHONE - #define NS_NONATOMIC_IOSONLY nonatomic -#else - #define NS_NONATOMIC_IOSONLY atomic -#endif - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -@property (NS_NONATOMIC_IOSONLY, weak) NSString *WeakProp; - -@property (NS_NONATOMIC_IOSONLY, strong) NSString *StrongProp; - -@property (NS_NONATOMIC_IOSONLY, strong) NSString *UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -@property (NS_NONATOMIC_IOSONLY, strong) NSString *UnavailProp1 __attribute__((unavailable)); - -@property (NS_NONATOMIC_IOSONLY, strong) NSString *UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -@property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *undoAction; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names2; -@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names3; -@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names4; -@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -@property (NS_NONATOMIC_IOSONLY, assign) id target; - -@property (NS_NONATOMIC_IOSONLY, assign) id dataSource; - -@property (NS_NONATOMIC_IOSONLY, assign) id xxxdelegateYYY; - - -@property (NS_NONATOMIC_IOSONLY, strong) id MYtarget; - -@property (NS_NONATOMIC_IOSONLY, strong) id targetX; - -@property (NS_NONATOMIC_IOSONLY) int value; - -@property (NS_NONATOMIC_IOSONLY, getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (NS_NONATOMIC_IOSONLY, getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (NS_NONATOMIC_IOSONLY, readonly) int Length; -@property (NS_NONATOMIC_IOSONLY, readonly, strong) id object; -+ (double) D; -@property (NS_NONATOMIC_IOSONLY, readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -@property (NS_NONATOMIC_IOSONLY, getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents; - -@property (NS_NONATOMIC_IOSONLY, getter=getStringValue, strong) NSString *stringValue; -@property (NS_NONATOMIC_IOSONLY, getter=getCounterValue, readonly) BOOL counterValue; -@property (NS_NONATOMIC_IOSONLY, getter=getns_dixtionary, readonly, copy) NSDictionary *ns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (NS_NONATOMIC_IOSONLY, getter=getM, readonly) BOOL m; -@property (NS_NONATOMIC_IOSONLY, getter=getMA, readonly) BOOL MA; -@property (NS_NONATOMIC_IOSONLY, getter=getALL, readonly) BOOL ALL; -@property (NS_NONATOMIC_IOSONLY, getter=getMANY, readonly) BOOL MANY; -@property (NS_NONATOMIC_IOSONLY, getter=getSome, readonly) BOOL some; -@end - - -@interface NSInvocation(CAT) -@property (NS_NONATOMIC_IOSONLY, assign) id target; - -@property (NS_NONATOMIC_IOSONLY, assign) id dataSource; - -@property (NS_NONATOMIC_IOSONLY, assign) id xxxdelegateYYY; - - -@property (NS_NONATOMIC_IOSONLY, strong) id MYtarget; - -@property (NS_NONATOMIC_IOSONLY, strong) id targetX; - -@property (NS_NONATOMIC_IOSONLY) int value; - -@property (NS_NONATOMIC_IOSONLY, getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (NS_NONATOMIC_IOSONLY, getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (NS_NONATOMIC_IOSONLY, readonly) int Length; -@property (NS_NONATOMIC_IOSONLY, readonly, strong) id object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (NS_NONATOMIC_IOSONLY, getter=getM, readonly) BOOL m; -@property (NS_NONATOMIC_IOSONLY, getter=getMA, readonly) BOOL MA; -@property (NS_NONATOMIC_IOSONLY, getter=getALL, readonly) BOOL ALL; -@property (NS_NONATOMIC_IOSONLY, getter=getMANY, readonly) BOOL MANY; -@property (NS_NONATOMIC_IOSONLY, getter=getSome, readonly) BOOL some; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURLX NS_AVAILABLE; - -// Do not infer a property. -@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -@property (NS_NONATOMIC_IOSONLY, readonly, strong) id OkToInfer NS_AVAILABLE; - -// Do not infer a property. -@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -@property (NS_NONATOMIC_IOSONLY, strong) id method1 ALIGNED NS_AVAILABLE; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -@property (NS_NONATOMIC_IOSONLY, getter=isClass, readonly) BOOL class; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -@property (NS_NONATOMIC_IOSONLY, readonly, copy) id (^expressionBlock)(id, NSArray *, NSMutableDictionary *); -@property (NS_NONATOMIC_IOSONLY, copy) id (^MyBlock)(id, NSArray *, NSMutableDictionary *); -@property (NS_NONATOMIC_IOSONLY, readonly) id (*expressionFuncptr)(id, NSArray *, NSMutableDictionary *); -@property (NS_NONATOMIC_IOSONLY) id (*MyFuncptr)(id, NSArray *, NSMutableDictionary *); -@end diff --git a/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m b/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m deleted file mode 100644 index 853d16dc789420..00000000000000 --- a/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m +++ /dev/null @@ -1,128 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-returns-innerpointer-property -objcmt-migrate-annotation -objcmt-migrate-readwrite-property -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure -#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) -#endif - -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") - -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) - -CF_IMPLICIT_BRIDGING_ENABLED - -typedef unsigned long CFTypeID; -typedef unsigned long CFOptionFlags; -typedef unsigned long CFHashCode; - -typedef signed long CFIndex; /*AnyObj*/ -typedef const struct __CFArray * CFArrayRef; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; - -typedef void (*CFArrayApplierFunction)(const void *value, void *context); - -typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { - kCFCompareLessThan = -1L, - kCFCompareEqualTo = 0, - kCFCompareGreaterThan = 1 -}; - - -typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); - -typedef struct __CFArray * CFMutableArrayRef; - -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; - -typedef const struct __CFAllocator * CFAllocatorRef; - -typedef const struct __CFString * CFStringRef; -typedef struct __CFString * CFMutableStringRef; - -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; - -typedef struct CGImage *CGImageRef; - -typedef struct OpaqueJSValue* JSObjectRef; - -typedef JSObjectRef TTJSObjectRef; -typedef unsigned int NSUInteger; - -CF_IMPLICIT_BRIDGING_DISABLED - -@interface I -- (void*) ReturnsInnerPointer; -- (int*) AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; -@end - -@interface UIImage -- (CGImageRef)CGImage; -@end - -@interface NSData -- (void *)bytes; -- (void **) ptr_bytes __attribute__((availability(macosx,unavailable))); -@end - -@interface NSMutableData -- (void *)mutableBytes __attribute__((deprecated)) __attribute__((unavailable)); -@end - -@interface JS -- (JSObjectRef)JSObject; -- (TTJSObjectRef)JSObject1; -- (JSObjectRef*)JSObject2; -@end - -typedef void *SecTrustRef; - -@interface NSURLProtectionSpace -@property (readonly) SecTrustRef serverTrust NS_AVAILABLE; -- (void *) FOO NS_AVAILABLE; -@property (readonly) void * mitTrust NS_AVAILABLE; - -@property (readonly) void * mittiTrust; - -@property (readonly) SecTrustRef XserverTrust; - -- (SecTrustRef) FOO1 NS_AVAILABLE; - -+ (const NSURLProtectionSpace *)ProtectionSpace; - -// pointer personality functions -@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); -@end diff --git a/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result b/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result deleted file mode 100644 index c89c91eedce35f..00000000000000 --- a/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result +++ /dev/null @@ -1,128 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-returns-innerpointer-property -objcmt-migrate-annotation -objcmt-migrate-readwrite-property -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure -#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) -#endif - -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") - -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) - -CF_IMPLICIT_BRIDGING_ENABLED - -typedef unsigned long CFTypeID; -typedef unsigned long CFOptionFlags; -typedef unsigned long CFHashCode; - -typedef signed long CFIndex; /*AnyObj*/ -typedef const struct __CFArray * CFArrayRef; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; - -typedef void (*CFArrayApplierFunction)(const void *value, void *context); - -typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { - kCFCompareLessThan = -1L, - kCFCompareEqualTo = 0, - kCFCompareGreaterThan = 1 -}; - - -typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); - -typedef struct __CFArray * CFMutableArrayRef; - -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; - -typedef const struct __CFAllocator * CFAllocatorRef; - -typedef const struct __CFString * CFStringRef; -typedef struct __CFString * CFMutableStringRef; - -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; - -typedef struct CGImage *CGImageRef; - -typedef struct OpaqueJSValue* JSObjectRef; - -typedef JSObjectRef TTJSObjectRef; -typedef unsigned int NSUInteger; - -CF_IMPLICIT_BRIDGING_DISABLED - -@interface I -- (void*) ReturnsInnerPointer NS_RETURNS_INNER_POINTER; -- (int*) AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; -@end - -@interface UIImage -- (CGImageRef)CGImage CF_RETURNS_NOT_RETAINED; -@end - -@interface NSData -- (void *)bytes NS_RETURNS_INNER_POINTER; -- (void **) ptr_bytes __attribute__((availability(macosx,unavailable))) NS_RETURNS_INNER_POINTER; -@end - -@interface NSMutableData -- (void *)mutableBytes __attribute__((deprecated)) __attribute__((unavailable)) NS_RETURNS_INNER_POINTER; -@end - -@interface JS -- (JSObjectRef)JSObject; -- (TTJSObjectRef)JSObject1; -- (JSObjectRef*)JSObject2 NS_RETURNS_INNER_POINTER; -@end - -typedef void *SecTrustRef; - -@interface NSURLProtectionSpace -@property (readonly) SecTrustRef NS_RETURNS_INNER_POINTER serverTrust NS_AVAILABLE; -- (void *) FOO NS_AVAILABLE NS_RETURNS_INNER_POINTER; -@property (readonly) void * NS_RETURNS_INNER_POINTER mitTrust NS_AVAILABLE; - -@property (readonly) void * NS_RETURNS_INNER_POINTER mittiTrust; - -@property (readonly) SecTrustRef NS_RETURNS_INNER_POINTER XserverTrust; - -- (SecTrustRef) FOO1 NS_AVAILABLE NS_RETURNS_INNER_POINTER; - -+ (const NSURLProtectionSpace *)ProtectionSpace; - -// pointer personality functions -@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); -@end diff --git a/clang/test/ARCMT/objcmt-numeric-literals.m b/clang/test/ARCMT/objcmt-numeric-literals.m deleted file mode 100644 index 7f33dc27997e1d..00000000000000 --- a/clang/test/ARCMT/objcmt-numeric-literals.m +++ /dev/null @@ -1,502 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s.result - -#define YES __objc_yes -#define NO __objc_no - -typedef long NSInteger; -typedef unsigned long NSUInteger; -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -- (id)initWithChar:(char)value; -- (id)initWithUnsignedChar:(unsigned char)value; -- (id)initWithShort:(short)value; -- (id)initWithUnsignedShort:(unsigned short)value; -- (id)initWithInt:(int)value; -- (id)initWithUnsignedInt:(unsigned int)value; -- (id)initWithLong:(long)value; -- (id)initWithUnsignedLong:(unsigned long)value; -- (id)initWithLongLong:(long long)value; -- (id)initWithUnsignedLongLong:(unsigned long long)value; -- (id)initWithFloat:(float)value; -- (id)initWithDouble:(double)value; -- (id)initWithBool:(BOOL)value; -- (id)initWithInteger:(NSInteger)value; -- (id)initWithUnsignedInteger:(NSUInteger)value; - -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value; -@end - -#define VAL_INT 2 -#define VAL_UINT 2U -#define VAL_CHAR 'a' - -void foo() { - [NSNumber numberWithChar:'a']; - [NSNumber numberWithChar:L'a']; - [NSNumber numberWithChar:2]; - [NSNumber numberWithChar:2U]; - [NSNumber numberWithChar:2u]; - [NSNumber numberWithChar:2L]; - [NSNumber numberWithChar:2l]; - [NSNumber numberWithChar:2LL]; - [NSNumber numberWithChar:2ll]; - [NSNumber numberWithChar:2ul]; - [NSNumber numberWithChar:2lu]; - [NSNumber numberWithChar:2ull]; - [NSNumber numberWithChar:2llu]; - [NSNumber numberWithChar:2.0]; - [NSNumber numberWithChar:2.0f]; - [NSNumber numberWithChar:2.0F]; - [NSNumber numberWithChar:2.0l]; - [NSNumber numberWithChar:2.0L]; - [NSNumber numberWithChar:0x2f]; - [NSNumber numberWithChar:04]; - [NSNumber numberWithChar:0]; - [NSNumber numberWithChar:0.0]; - [NSNumber numberWithChar:YES]; - [NSNumber numberWithChar:NO]; - [NSNumber numberWithChar:true]; - [NSNumber numberWithChar:false]; - [NSNumber numberWithChar:VAL_INT]; - [NSNumber numberWithChar:VAL_UINT]; - [NSNumber numberWithChar:VAL_CHAR]; - - [NSNumber numberWithUnsignedChar:'a']; - [NSNumber numberWithUnsignedChar:L'a']; - [NSNumber numberWithUnsignedChar:2]; - [NSNumber numberWithUnsignedChar:2U]; - [NSNumber numberWithUnsignedChar:2u]; - [NSNumber numberWithUnsignedChar:2L]; - [NSNumber numberWithUnsignedChar:2l]; - [NSNumber numberWithUnsignedChar:2LL]; - [NSNumber numberWithUnsignedChar:2ll]; - [NSNumber numberWithUnsignedChar:2ul]; - [NSNumber numberWithUnsignedChar:2lu]; - [NSNumber numberWithUnsignedChar:2ull]; - [NSNumber numberWithUnsignedChar:2llu]; - [NSNumber numberWithUnsignedChar:2.0]; - [NSNumber numberWithUnsignedChar:2.0f]; - [NSNumber numberWithUnsignedChar:2.0F]; - [NSNumber numberWithUnsignedChar:2.0l]; - [NSNumber numberWithUnsignedChar:2.0L]; - [NSNumber numberWithUnsignedChar:0x2f]; - [NSNumber numberWithUnsignedChar:04]; - [NSNumber numberWithUnsignedChar:0]; - [NSNumber numberWithUnsignedChar:0.0]; - [NSNumber numberWithUnsignedChar:YES]; - [NSNumber numberWithUnsignedChar:NO]; - [NSNumber numberWithUnsignedChar:true]; - [NSNumber numberWithUnsignedChar:false]; - [NSNumber numberWithUnsignedChar:VAL_INT]; - [NSNumber numberWithUnsignedChar:VAL_UINT]; - [NSNumber numberWithUnsignedChar:VAL_CHAR]; - - [NSNumber numberWithShort:'a']; - [NSNumber numberWithShort:L'a']; - [NSNumber numberWithShort:2]; - [NSNumber numberWithShort:2U]; - [NSNumber numberWithShort:2u]; - [NSNumber numberWithShort:2L]; - [NSNumber numberWithShort:2l]; - [NSNumber numberWithShort:2LL]; - [NSNumber numberWithShort:2ll]; - [NSNumber numberWithShort:2ul]; - [NSNumber numberWithShort:2lu]; - [NSNumber numberWithShort:2ull]; - [NSNumber numberWithShort:2llu]; - [NSNumber numberWithShort:2.0]; - [NSNumber numberWithShort:2.0f]; - [NSNumber numberWithShort:2.0F]; - [NSNumber numberWithShort:2.0l]; - [NSNumber numberWithShort:2.0L]; - [NSNumber numberWithShort:0x2f]; - [NSNumber numberWithShort:04]; - [NSNumber numberWithShort:0]; - [NSNumber numberWithShort:0.0]; - [NSNumber numberWithShort:YES]; - [NSNumber numberWithShort:NO]; - [NSNumber numberWithShort:true]; - [NSNumber numberWithShort:false]; - [NSNumber numberWithShort:VAL_INT]; - [NSNumber numberWithShort:VAL_UINT]; - - [NSNumber numberWithUnsignedShort:'a']; - [NSNumber numberWithUnsignedShort:L'a']; - [NSNumber numberWithUnsignedShort:2]; - [NSNumber numberWithUnsignedShort:2U]; - [NSNumber numberWithUnsignedShort:2u]; - [NSNumber numberWithUnsignedShort:2L]; - [NSNumber numberWithUnsignedShort:2l]; - [NSNumber numberWithUnsignedShort:2LL]; - [NSNumber numberWithUnsignedShort:2ll]; - [NSNumber numberWithUnsignedShort:2ul]; - [NSNumber numberWithUnsignedShort:2lu]; - [NSNumber numberWithUnsignedShort:2ull]; - [NSNumber numberWithUnsignedShort:2llu]; - [NSNumber numberWithUnsignedShort:2.0]; - [NSNumber numberWithUnsignedShort:2.0f]; - [NSNumber numberWithUnsignedShort:2.0F]; - [NSNumber numberWithUnsignedShort:2.0l]; - [NSNumber numberWithUnsignedShort:2.0L]; - [NSNumber numberWithUnsignedShort:0x2f]; - [NSNumber numberWithUnsignedShort:04]; - [NSNumber numberWithUnsignedShort:0]; - [NSNumber numberWithUnsignedShort:0.0]; - [NSNumber numberWithUnsignedShort:YES]; - [NSNumber numberWithUnsignedShort:NO]; - [NSNumber numberWithUnsignedShort:true]; - [NSNumber numberWithUnsignedShort:false]; - [NSNumber numberWithUnsignedShort:VAL_INT]; - [NSNumber numberWithUnsignedShort:VAL_UINT]; - - [NSNumber numberWithInt:'a']; - [NSNumber numberWithInt:L'a']; - [NSNumber numberWithInt:2]; - [NSNumber numberWithInt:2U]; - [NSNumber numberWithInt:2u]; - [NSNumber numberWithInt:2L]; - [NSNumber numberWithInt:2l]; - [NSNumber numberWithInt:2LL]; - [NSNumber numberWithInt:2ll]; - [NSNumber numberWithInt:2ul]; - [NSNumber numberWithInt:2lu]; - [NSNumber numberWithInt:2ull]; - [NSNumber numberWithInt:2llu]; - [NSNumber numberWithInt:2.0]; - [NSNumber numberWithInt:2.0f]; - [NSNumber numberWithInt:2.0F]; - [NSNumber numberWithInt:2.0l]; - [NSNumber numberWithInt:2.0L]; - [NSNumber numberWithInt:0x2f]; - [NSNumber numberWithInt:04]; - [NSNumber numberWithInt:0]; - [NSNumber numberWithInt:0.0]; - [NSNumber numberWithInt:YES]; - [NSNumber numberWithInt:NO]; - [NSNumber numberWithInt:true]; - [NSNumber numberWithInt:false]; - [NSNumber numberWithInt:VAL_INT]; - [NSNumber numberWithInt:VAL_UINT]; - - (void)[[NSNumber alloc] initWithInt:2]; - (void)[[NSNumber alloc] initWithInt:2U]; - - [NSNumber numberWithInt:+2]; - [NSNumber numberWithInt:-2]; - - [NSNumber numberWithUnsignedInt:'a']; - [NSNumber numberWithUnsignedInt:L'a']; - [NSNumber numberWithUnsignedInt:2]; - [NSNumber numberWithUnsignedInt:2U]; - [NSNumber numberWithUnsignedInt:2u]; - [NSNumber numberWithUnsignedInt:2L]; - [NSNumber numberWithUnsignedInt:2l]; - [NSNumber numberWithUnsignedInt:2LL]; - [NSNumber numberWithUnsignedInt:2ll]; - [NSNumber numberWithUnsignedInt:2ul]; - [NSNumber numberWithUnsignedInt:2lu]; - [NSNumber numberWithUnsignedInt:2ull]; - [NSNumber numberWithUnsignedInt:2llu]; - [NSNumber numberWithUnsignedInt:2.0]; - [NSNumber numberWithUnsignedInt:2.0f]; - [NSNumber numberWithUnsignedInt:2.0F]; - [NSNumber numberWithUnsignedInt:2.0l]; - [NSNumber numberWithUnsignedInt:2.0L]; - [NSNumber numberWithUnsignedInt:0x2f]; - [NSNumber numberWithUnsignedInt:04]; - [NSNumber numberWithUnsignedInt:0]; - [NSNumber numberWithUnsignedInt:0.0]; - [NSNumber numberWithUnsignedInt:YES]; - [NSNumber numberWithUnsignedInt:NO]; - [NSNumber numberWithUnsignedInt:true]; - [NSNumber numberWithUnsignedInt:false]; - [NSNumber numberWithUnsignedInt:VAL_INT]; - [NSNumber numberWithUnsignedInt:VAL_UINT]; - - [NSNumber numberWithLong:'a']; - [NSNumber numberWithLong:L'a']; - [NSNumber numberWithLong:2]; - [NSNumber numberWithLong:2U]; - [NSNumber numberWithLong:2u]; - [NSNumber numberWithLong:2L]; - [NSNumber numberWithLong:2l]; - [NSNumber numberWithLong:2LL]; - [NSNumber numberWithLong:2ll]; - [NSNumber numberWithLong:2ul]; - [NSNumber numberWithLong:2lu]; - [NSNumber numberWithLong:2ull]; - [NSNumber numberWithLong:2llu]; - [NSNumber numberWithLong:2.0]; - [NSNumber numberWithLong:2.0f]; - [NSNumber numberWithLong:2.0F]; - [NSNumber numberWithLong:2.0l]; - [NSNumber numberWithLong:2.0L]; - [NSNumber numberWithLong:0x2f]; - [NSNumber numberWithLong:04]; - [NSNumber numberWithLong:0]; - [NSNumber numberWithLong:0.0]; - [NSNumber numberWithLong:YES]; - [NSNumber numberWithLong:NO]; - [NSNumber numberWithLong:true]; - [NSNumber numberWithLong:false]; - [NSNumber numberWithLong:VAL_INT]; - [NSNumber numberWithLong:VAL_UINT]; - - [NSNumber numberWithUnsignedLong:'a']; - [NSNumber numberWithUnsignedLong:L'a']; - [NSNumber numberWithUnsignedLong:2]; - [NSNumber numberWithUnsignedLong:2U]; - [NSNumber numberWithUnsignedLong:2u]; - [NSNumber numberWithUnsignedLong:2L]; - [NSNumber numberWithUnsignedLong:2l]; - [NSNumber numberWithUnsignedLong:2LL]; - [NSNumber numberWithUnsignedLong:2ll]; - [NSNumber numberWithUnsignedLong:2ul]; - [NSNumber numberWithUnsignedLong:2lu]; - [NSNumber numberWithUnsignedLong:2ull]; - [NSNumber numberWithUnsignedLong:2llu]; - [NSNumber numberWithUnsignedLong:2.0]; - [NSNumber numberWithUnsignedLong:2.0f]; - [NSNumber numberWithUnsignedLong:2.0F]; - [NSNumber numberWithUnsignedLong:2.0l]; - [NSNumber numberWithUnsignedLong:2.0L]; - [NSNumber numberWithUnsignedLong:0x2f]; - [NSNumber numberWithUnsignedLong:04]; - [NSNumber numberWithUnsignedLong:0]; - [NSNumber numberWithUnsignedLong:0.0]; - [NSNumber numberWithUnsignedLong:YES]; - [NSNumber numberWithUnsignedLong:NO]; - [NSNumber numberWithUnsignedLong:true]; - [NSNumber numberWithUnsignedLong:false]; - [NSNumber numberWithUnsignedLong:VAL_INT]; - [NSNumber numberWithUnsignedLong:VAL_UINT]; - - [NSNumber numberWithLongLong:'a']; - [NSNumber numberWithLongLong:L'a']; - [NSNumber numberWithLongLong:2]; - [NSNumber numberWithLongLong:2U]; - [NSNumber numberWithLongLong:2u]; - [NSNumber numberWithLongLong:2L]; - [NSNumber numberWithLongLong:2l]; - [NSNumber numberWithLongLong:2LL]; - [NSNumber numberWithLongLong:2ll]; - [NSNumber numberWithLongLong:2ul]; - [NSNumber numberWithLongLong:2lu]; - [NSNumber numberWithLongLong:2ull]; - [NSNumber numberWithLongLong:2llu]; - [NSNumber numberWithLongLong:2.0]; - [NSNumber numberWithLongLong:2.0f]; - [NSNumber numberWithLongLong:2.0F]; - [NSNumber numberWithLongLong:2.0l]; - [NSNumber numberWithLongLong:2.0L]; - [NSNumber numberWithLongLong:0x2f]; - [NSNumber numberWithLongLong:04]; - [NSNumber numberWithLongLong:0]; - [NSNumber numberWithLongLong:0.0]; - [NSNumber numberWithLongLong:YES]; - [NSNumber numberWithLongLong:NO]; - [NSNumber numberWithLongLong:true]; - [NSNumber numberWithLongLong:false]; - [NSNumber numberWithLongLong:VAL_INT]; - [NSNumber numberWithLongLong:VAL_UINT]; - - [NSNumber numberWithUnsignedLongLong:'a']; - [NSNumber numberWithUnsignedLongLong:L'a']; - [NSNumber numberWithUnsignedLongLong:2]; - [NSNumber numberWithUnsignedLongLong:2U]; - [NSNumber numberWithUnsignedLongLong:2u]; - [NSNumber numberWithUnsignedLongLong:2L]; - [NSNumber numberWithUnsignedLongLong:2l]; - [NSNumber numberWithUnsignedLongLong:2LL]; - [NSNumber numberWithUnsignedLongLong:2ll]; - [NSNumber numberWithUnsignedLongLong:2ul]; - [NSNumber numberWithUnsignedLongLong:2lu]; - [NSNumber numberWithUnsignedLongLong:2ull]; - [NSNumber numberWithUnsignedLongLong:2llu]; - [NSNumber numberWithUnsignedLongLong:2.0]; - [NSNumber numberWithUnsignedLongLong:2.0f]; - [NSNumber numberWithUnsignedLongLong:2.0F]; - [NSNumber numberWithUnsignedLongLong:2.0l]; - [NSNumber numberWithUnsignedLongLong:2.0L]; - [NSNumber numberWithUnsignedLongLong:0x2f]; - [NSNumber numberWithUnsignedLongLong:04]; - [NSNumber numberWithUnsignedLongLong:0]; - [NSNumber numberWithUnsignedLongLong:0.0]; - [NSNumber numberWithUnsignedLongLong:YES]; - [NSNumber numberWithUnsignedLongLong:NO]; - [NSNumber numberWithUnsignedLongLong:true]; - [NSNumber numberWithUnsignedLongLong:false]; - [NSNumber numberWithUnsignedLongLong:VAL_INT]; - [NSNumber numberWithUnsignedLongLong:VAL_UINT]; - - [NSNumber numberWithFloat:'a']; - [NSNumber numberWithFloat:L'a']; - [NSNumber numberWithFloat:2]; - [NSNumber numberWithFloat:2U]; - [NSNumber numberWithFloat:2u]; - [NSNumber numberWithFloat:2L]; - [NSNumber numberWithFloat:2l]; - [NSNumber numberWithFloat:2LL]; - [NSNumber numberWithFloat:2ll]; - [NSNumber numberWithFloat:2ul]; - [NSNumber numberWithFloat:2lu]; - [NSNumber numberWithFloat:2ull]; - [NSNumber numberWithFloat:2llu]; - [NSNumber numberWithFloat:2.0]; - [NSNumber numberWithFloat:2.0f]; - [NSNumber numberWithFloat:2.0F]; - [NSNumber numberWithFloat:2.0l]; - [NSNumber numberWithFloat:2.0L]; - [NSNumber numberWithFloat:0x2f]; - [NSNumber numberWithFloat:04]; - [NSNumber numberWithFloat:0]; - [NSNumber numberWithFloat:0.0]; - [NSNumber numberWithFloat:YES]; - [NSNumber numberWithFloat:NO]; - [NSNumber numberWithFloat:true]; - [NSNumber numberWithFloat:false]; - [NSNumber numberWithFloat:VAL_INT]; - [NSNumber numberWithFloat:VAL_UINT]; - - [NSNumber numberWithDouble:'a']; - [NSNumber numberWithDouble:L'a']; - [NSNumber numberWithDouble:2]; - [NSNumber numberWithDouble:2U]; - [NSNumber numberWithDouble:2u]; - [NSNumber numberWithDouble:2L]; - [NSNumber numberWithDouble:2l]; - [NSNumber numberWithDouble:2LL]; - [NSNumber numberWithDouble:2ll]; - [NSNumber numberWithDouble:2ul]; - [NSNumber numberWithDouble:2lu]; - [NSNumber numberWithDouble:2ull]; - [NSNumber numberWithDouble:2llu]; - [NSNumber numberWithDouble:2.0]; - [NSNumber numberWithDouble:2.0f]; - [NSNumber numberWithDouble:2.0F]; - [NSNumber numberWithDouble:2.0l]; - [NSNumber numberWithDouble:2.0L]; - [NSNumber numberWithDouble:0x2f]; - [NSNumber numberWithDouble:04]; - [NSNumber numberWithDouble:0]; - [NSNumber numberWithDouble:0.0]; - [NSNumber numberWithDouble:YES]; - [NSNumber numberWithDouble:NO]; - [NSNumber numberWithDouble:true]; - [NSNumber numberWithDouble:false]; - [NSNumber numberWithDouble:VAL_INT]; - [NSNumber numberWithDouble:VAL_UINT]; - - [NSNumber numberWithBool:'a']; - [NSNumber numberWithBool:L'a']; - [NSNumber numberWithBool:2]; - [NSNumber numberWithBool:2U]; - [NSNumber numberWithBool:2u]; - [NSNumber numberWithBool:2L]; - [NSNumber numberWithBool:2l]; - [NSNumber numberWithBool:2LL]; - [NSNumber numberWithBool:2ll]; - [NSNumber numberWithBool:2ul]; - [NSNumber numberWithBool:2lu]; - [NSNumber numberWithBool:2ull]; - [NSNumber numberWithBool:2llu]; - [NSNumber numberWithBool:2.0]; - [NSNumber numberWithBool:2.0f]; - [NSNumber numberWithBool:2.0F]; - [NSNumber numberWithBool:2.0l]; - [NSNumber numberWithBool:2.0L]; - [NSNumber numberWithBool:0x2f]; - [NSNumber numberWithBool:04]; - [NSNumber numberWithBool:0]; - [NSNumber numberWithBool:0.0]; - [NSNumber numberWithBool:YES]; - [NSNumber numberWithBool:NO]; - [NSNumber numberWithBool:true]; - [NSNumber numberWithBool:false]; - [NSNumber numberWithBool:VAL_INT]; - [NSNumber numberWithBool:VAL_UINT]; - - [NSNumber numberWithInteger:'a']; - [NSNumber numberWithInteger:L'a']; - [NSNumber numberWithInteger:2]; - [NSNumber numberWithInteger:2U]; - [NSNumber numberWithInteger:2u]; - [NSNumber numberWithInteger:2L]; - [NSNumber numberWithInteger:2l]; - [NSNumber numberWithInteger:2LL]; - [NSNumber numberWithInteger:2ll]; - [NSNumber numberWithInteger:2ul]; - [NSNumber numberWithInteger:2lu]; - [NSNumber numberWithInteger:2ull]; - [NSNumber numberWithInteger:2llu]; - [NSNumber numberWithInteger:2.0]; - [NSNumber numberWithInteger:2.0f]; - [NSNumber numberWithInteger:2.0F]; - [NSNumber numberWithInteger:2.0l]; - [NSNumber numberWithInteger:2.0L]; - [NSNumber numberWithInteger:0x2f]; - [NSNumber numberWithInteger:04]; - [NSNumber numberWithInteger:0]; - [NSNumber numberWithInteger:0.0]; - [NSNumber numberWithInteger:YES]; - [NSNumber numberWithInteger:NO]; - [NSNumber numberWithInteger:true]; - [NSNumber numberWithInteger:false]; - [NSNumber numberWithInteger:VAL_INT]; - [NSNumber numberWithInteger:VAL_UINT]; - - [NSNumber numberWithUnsignedInteger:'a']; - [NSNumber numberWithUnsignedInteger:L'a']; - [NSNumber numberWithUnsignedInteger:2]; - [NSNumber numberWithUnsignedInteger:2U]; - [NSNumber numberWithUnsignedInteger:2u]; - [NSNumber numberWithUnsignedInteger:2L]; - [NSNumber numberWithUnsignedInteger:2l]; - [NSNumber numberWithUnsignedInteger:2LL]; - [NSNumber numberWithUnsignedInteger:2ll]; - [NSNumber numberWithUnsignedInteger:2ul]; - [NSNumber numberWithUnsignedInteger:2lu]; - [NSNumber numberWithUnsignedInteger:2ull]; - [NSNumber numberWithUnsignedInteger:2llu]; - [NSNumber numberWithUnsignedInteger:2.0]; - [NSNumber numberWithUnsignedInteger:2.0f]; - [NSNumber numberWithUnsignedInteger:2.0F]; - [NSNumber numberWithUnsignedInteger:2.0l]; - [NSNumber numberWithUnsignedInteger:2.0L]; - [NSNumber numberWithUnsignedInteger:0x2f]; - [NSNumber numberWithUnsignedInteger:04]; - [NSNumber numberWithUnsignedInteger:0]; - [NSNumber numberWithUnsignedInteger:0.0]; - [NSNumber numberWithUnsignedInteger:YES]; - [NSNumber numberWithUnsignedInteger:NO]; - [NSNumber numberWithUnsignedInteger:true]; - [NSNumber numberWithUnsignedInteger:false]; - [NSNumber numberWithUnsignedInteger:VAL_INT]; - [NSNumber numberWithUnsignedInteger:VAL_UINT]; -} diff --git a/clang/test/ARCMT/objcmt-numeric-literals.m.result b/clang/test/ARCMT/objcmt-numeric-literals.m.result deleted file mode 100644 index bb7b515566d094..00000000000000 --- a/clang/test/ARCMT/objcmt-numeric-literals.m.result +++ /dev/null @@ -1,502 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s.result - -#define YES __objc_yes -#define NO __objc_no - -typedef long NSInteger; -typedef unsigned long NSUInteger; -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -- (id)initWithChar:(char)value; -- (id)initWithUnsignedChar:(unsigned char)value; -- (id)initWithShort:(short)value; -- (id)initWithUnsignedShort:(unsigned short)value; -- (id)initWithInt:(int)value; -- (id)initWithUnsignedInt:(unsigned int)value; -- (id)initWithLong:(long)value; -- (id)initWithUnsignedLong:(unsigned long)value; -- (id)initWithLongLong:(long long)value; -- (id)initWithUnsignedLongLong:(unsigned long long)value; -- (id)initWithFloat:(float)value; -- (id)initWithDouble:(double)value; -- (id)initWithBool:(BOOL)value; -- (id)initWithInteger:(NSInteger)value; -- (id)initWithUnsignedInteger:(NSUInteger)value; - -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value; -@end - -#define VAL_INT 2 -#define VAL_UINT 2U -#define VAL_CHAR 'a' - -void foo() { - @'a'; - [NSNumber numberWithChar:L'a']; - [NSNumber numberWithChar:2]; - [NSNumber numberWithChar:2U]; - [NSNumber numberWithChar:2u]; - [NSNumber numberWithChar:2L]; - [NSNumber numberWithChar:2l]; - [NSNumber numberWithChar:2LL]; - [NSNumber numberWithChar:2ll]; - [NSNumber numberWithChar:2ul]; - [NSNumber numberWithChar:2lu]; - [NSNumber numberWithChar:2ull]; - [NSNumber numberWithChar:2llu]; - [NSNumber numberWithChar:2.0]; - [NSNumber numberWithChar:2.0f]; - [NSNumber numberWithChar:2.0F]; - [NSNumber numberWithChar:2.0l]; - [NSNumber numberWithChar:2.0L]; - [NSNumber numberWithChar:0x2f]; - [NSNumber numberWithChar:04]; - [NSNumber numberWithChar:0]; - [NSNumber numberWithChar:0.0]; - [NSNumber numberWithChar:YES]; - [NSNumber numberWithChar:NO]; - [NSNumber numberWithChar:true]; - [NSNumber numberWithChar:false]; - [NSNumber numberWithChar:VAL_INT]; - [NSNumber numberWithChar:VAL_UINT]; - @VAL_CHAR; - - [NSNumber numberWithUnsignedChar:'a']; - [NSNumber numberWithUnsignedChar:L'a']; - [NSNumber numberWithUnsignedChar:2]; - [NSNumber numberWithUnsignedChar:2U]; - [NSNumber numberWithUnsignedChar:2u]; - [NSNumber numberWithUnsignedChar:2L]; - [NSNumber numberWithUnsignedChar:2l]; - [NSNumber numberWithUnsignedChar:2LL]; - [NSNumber numberWithUnsignedChar:2ll]; - [NSNumber numberWithUnsignedChar:2ul]; - [NSNumber numberWithUnsignedChar:2lu]; - [NSNumber numberWithUnsignedChar:2ull]; - [NSNumber numberWithUnsignedChar:2llu]; - [NSNumber numberWithUnsignedChar:2.0]; - [NSNumber numberWithUnsignedChar:2.0f]; - [NSNumber numberWithUnsignedChar:2.0F]; - [NSNumber numberWithUnsignedChar:2.0l]; - [NSNumber numberWithUnsignedChar:2.0L]; - [NSNumber numberWithUnsignedChar:0x2f]; - [NSNumber numberWithUnsignedChar:04]; - [NSNumber numberWithUnsignedChar:0]; - [NSNumber numberWithUnsignedChar:0.0]; - [NSNumber numberWithUnsignedChar:YES]; - [NSNumber numberWithUnsignedChar:NO]; - [NSNumber numberWithUnsignedChar:true]; - [NSNumber numberWithUnsignedChar:false]; - [NSNumber numberWithUnsignedChar:VAL_INT]; - [NSNumber numberWithUnsignedChar:VAL_UINT]; - [NSNumber numberWithUnsignedChar:VAL_CHAR]; - - [NSNumber numberWithShort:'a']; - [NSNumber numberWithShort:L'a']; - [NSNumber numberWithShort:2]; - [NSNumber numberWithShort:2U]; - [NSNumber numberWithShort:2u]; - [NSNumber numberWithShort:2L]; - [NSNumber numberWithShort:2l]; - [NSNumber numberWithShort:2LL]; - [NSNumber numberWithShort:2ll]; - [NSNumber numberWithShort:2ul]; - [NSNumber numberWithShort:2lu]; - [NSNumber numberWithShort:2ull]; - [NSNumber numberWithShort:2llu]; - [NSNumber numberWithShort:2.0]; - [NSNumber numberWithShort:2.0f]; - [NSNumber numberWithShort:2.0F]; - [NSNumber numberWithShort:2.0l]; - [NSNumber numberWithShort:2.0L]; - [NSNumber numberWithShort:0x2f]; - [NSNumber numberWithShort:04]; - [NSNumber numberWithShort:0]; - [NSNumber numberWithShort:0.0]; - [NSNumber numberWithShort:YES]; - [NSNumber numberWithShort:NO]; - [NSNumber numberWithShort:true]; - [NSNumber numberWithShort:false]; - [NSNumber numberWithShort:VAL_INT]; - [NSNumber numberWithShort:VAL_UINT]; - - [NSNumber numberWithUnsignedShort:'a']; - [NSNumber numberWithUnsignedShort:L'a']; - [NSNumber numberWithUnsignedShort:2]; - [NSNumber numberWithUnsignedShort:2U]; - [NSNumber numberWithUnsignedShort:2u]; - [NSNumber numberWithUnsignedShort:2L]; - [NSNumber numberWithUnsignedShort:2l]; - [NSNumber numberWithUnsignedShort:2LL]; - [NSNumber numberWithUnsignedShort:2ll]; - [NSNumber numberWithUnsignedShort:2ul]; - [NSNumber numberWithUnsignedShort:2lu]; - [NSNumber numberWithUnsignedShort:2ull]; - [NSNumber numberWithUnsignedShort:2llu]; - [NSNumber numberWithUnsignedShort:2.0]; - [NSNumber numberWithUnsignedShort:2.0f]; - [NSNumber numberWithUnsignedShort:2.0F]; - [NSNumber numberWithUnsignedShort:2.0l]; - [NSNumber numberWithUnsignedShort:2.0L]; - [NSNumber numberWithUnsignedShort:0x2f]; - [NSNumber numberWithUnsignedShort:04]; - [NSNumber numberWithUnsignedShort:0]; - [NSNumber numberWithUnsignedShort:0.0]; - [NSNumber numberWithUnsignedShort:YES]; - [NSNumber numberWithUnsignedShort:NO]; - [NSNumber numberWithUnsignedShort:true]; - [NSNumber numberWithUnsignedShort:false]; - [NSNumber numberWithUnsignedShort:VAL_INT]; - [NSNumber numberWithUnsignedShort:VAL_UINT]; - - [NSNumber numberWithInt:'a']; - [NSNumber numberWithInt:L'a']; - @2; - @2; - @2; - @2; - @2; - @2; - @2; - @2; - @2; - @2; - @2; - [NSNumber numberWithInt:2.0]; - [NSNumber numberWithInt:2.0f]; - [NSNumber numberWithInt:2.0F]; - [NSNumber numberWithInt:2.0l]; - [NSNumber numberWithInt:2.0L]; - @0x2f; - @04; - @0; - [NSNumber numberWithInt:0.0]; - [NSNumber numberWithInt:YES]; - [NSNumber numberWithInt:NO]; - [NSNumber numberWithInt:true]; - [NSNumber numberWithInt:false]; - @VAL_INT; - [NSNumber numberWithInt:VAL_UINT]; - - (void)[[NSNumber alloc] initWithInt:2]; - (void)[[NSNumber alloc] initWithInt:2U]; - - @+2; - @-2; - - [NSNumber numberWithUnsignedInt:'a']; - [NSNumber numberWithUnsignedInt:L'a']; - @2U; - @2U; - @2u; - @2U; - @2u; - @2U; - @2u; - @2u; - @2u; - @2u; - @2u; - [NSNumber numberWithUnsignedInt:2.0]; - [NSNumber numberWithUnsignedInt:2.0f]; - [NSNumber numberWithUnsignedInt:2.0F]; - [NSNumber numberWithUnsignedInt:2.0l]; - [NSNumber numberWithUnsignedInt:2.0L]; - @0x2fU; - @04U; - @0U; - [NSNumber numberWithUnsignedInt:0.0]; - [NSNumber numberWithUnsignedInt:YES]; - [NSNumber numberWithUnsignedInt:NO]; - [NSNumber numberWithUnsignedInt:true]; - [NSNumber numberWithUnsignedInt:false]; - [NSNumber numberWithUnsignedInt:VAL_INT]; - @VAL_UINT; - - [NSNumber numberWithLong:'a']; - [NSNumber numberWithLong:L'a']; - @2L; - @2L; - @2l; - @2L; - @2l; - @2L; - @2l; - @2l; - @2l; - @2l; - @2l; - [NSNumber numberWithLong:2.0]; - [NSNumber numberWithLong:2.0f]; - [NSNumber numberWithLong:2.0F]; - [NSNumber numberWithLong:2.0l]; - [NSNumber numberWithLong:2.0L]; - @0x2fL; - @04L; - @0L; - [NSNumber numberWithLong:0.0]; - [NSNumber numberWithLong:YES]; - [NSNumber numberWithLong:NO]; - [NSNumber numberWithLong:true]; - [NSNumber numberWithLong:false]; - [NSNumber numberWithLong:VAL_INT]; - [NSNumber numberWithLong:VAL_UINT]; - - [NSNumber numberWithUnsignedLong:'a']; - [NSNumber numberWithUnsignedLong:L'a']; - @2UL; - @2UL; - @2ul; - @2UL; - @2ul; - @2UL; - @2ul; - @2ul; - @2lu; - @2ul; - @2ul; - [NSNumber numberWithUnsignedLong:2.0]; - [NSNumber numberWithUnsignedLong:2.0f]; - [NSNumber numberWithUnsignedLong:2.0F]; - [NSNumber numberWithUnsignedLong:2.0l]; - [NSNumber numberWithUnsignedLong:2.0L]; - @0x2fUL; - @04UL; - @0UL; - [NSNumber numberWithUnsignedLong:0.0]; - [NSNumber numberWithUnsignedLong:YES]; - [NSNumber numberWithUnsignedLong:NO]; - [NSNumber numberWithUnsignedLong:true]; - [NSNumber numberWithUnsignedLong:false]; - [NSNumber numberWithUnsignedLong:VAL_INT]; - [NSNumber numberWithUnsignedLong:VAL_UINT]; - - [NSNumber numberWithLongLong:'a']; - [NSNumber numberWithLongLong:L'a']; - @2LL; - @2LL; - @2ll; - @2LL; - @2ll; - @2LL; - @2ll; - @2ll; - @2ll; - @2ll; - @2ll; - [NSNumber numberWithLongLong:2.0]; - [NSNumber numberWithLongLong:2.0f]; - [NSNumber numberWithLongLong:2.0F]; - [NSNumber numberWithLongLong:2.0l]; - [NSNumber numberWithLongLong:2.0L]; - @0x2fLL; - @04LL; - @0LL; - [NSNumber numberWithLongLong:0.0]; - [NSNumber numberWithLongLong:YES]; - [NSNumber numberWithLongLong:NO]; - [NSNumber numberWithLongLong:true]; - [NSNumber numberWithLongLong:false]; - [NSNumber numberWithLongLong:VAL_INT]; - [NSNumber numberWithLongLong:VAL_UINT]; - - [NSNumber numberWithUnsignedLongLong:'a']; - [NSNumber numberWithUnsignedLongLong:L'a']; - @2ULL; - @2ULL; - @2ull; - @2ULL; - @2ull; - @2ULL; - @2ull; - @2ull; - @2ull; - @2ull; - @2llu; - [NSNumber numberWithUnsignedLongLong:2.0]; - [NSNumber numberWithUnsignedLongLong:2.0f]; - [NSNumber numberWithUnsignedLongLong:2.0F]; - [NSNumber numberWithUnsignedLongLong:2.0l]; - [NSNumber numberWithUnsignedLongLong:2.0L]; - @0x2fULL; - @04ULL; - @0ULL; - [NSNumber numberWithUnsignedLongLong:0.0]; - [NSNumber numberWithUnsignedLongLong:YES]; - [NSNumber numberWithUnsignedLongLong:NO]; - [NSNumber numberWithUnsignedLongLong:true]; - [NSNumber numberWithUnsignedLongLong:false]; - [NSNumber numberWithUnsignedLongLong:VAL_INT]; - [NSNumber numberWithUnsignedLongLong:VAL_UINT]; - - [NSNumber numberWithFloat:'a']; - [NSNumber numberWithFloat:L'a']; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0F; - @2.0f; - @2.0f; - [NSNumber numberWithFloat:0x2f]; - [NSNumber numberWithFloat:04]; - @0.0f; - @0.0f; - [NSNumber numberWithFloat:YES]; - [NSNumber numberWithFloat:NO]; - [NSNumber numberWithFloat:true]; - [NSNumber numberWithFloat:false]; - [NSNumber numberWithFloat:VAL_INT]; - [NSNumber numberWithFloat:VAL_UINT]; - - [NSNumber numberWithDouble:'a']; - [NSNumber numberWithDouble:L'a']; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - [NSNumber numberWithDouble:0x2f]; - [NSNumber numberWithDouble:04]; - @0.0; - @0.0; - [NSNumber numberWithDouble:YES]; - [NSNumber numberWithDouble:NO]; - [NSNumber numberWithDouble:true]; - [NSNumber numberWithDouble:false]; - [NSNumber numberWithDouble:VAL_INT]; - [NSNumber numberWithDouble:VAL_UINT]; - - [NSNumber numberWithBool:'a']; - [NSNumber numberWithBool:L'a']; - [NSNumber numberWithBool:2]; - [NSNumber numberWithBool:2U]; - [NSNumber numberWithBool:2u]; - [NSNumber numberWithBool:2L]; - [NSNumber numberWithBool:2l]; - [NSNumber numberWithBool:2LL]; - [NSNumber numberWithBool:2ll]; - [NSNumber numberWithBool:2ul]; - [NSNumber numberWithBool:2lu]; - [NSNumber numberWithBool:2ull]; - [NSNumber numberWithBool:2llu]; - [NSNumber numberWithBool:2.0]; - [NSNumber numberWithBool:2.0f]; - [NSNumber numberWithBool:2.0F]; - [NSNumber numberWithBool:2.0l]; - [NSNumber numberWithBool:2.0L]; - [NSNumber numberWithBool:0x2f]; - [NSNumber numberWithBool:04]; - [NSNumber numberWithBool:0]; - [NSNumber numberWithBool:0.0]; - @YES; - @NO; - @true; - @false; - [NSNumber numberWithBool:VAL_INT]; - [NSNumber numberWithBool:VAL_UINT]; - - [NSNumber numberWithInteger:'a']; - [NSNumber numberWithInteger:L'a']; - @2; - @2; - @2; - @2L; - @2l; - @2; - @2; - @2; - @2; - @2; - @2; - [NSNumber numberWithInteger:2.0]; - [NSNumber numberWithInteger:2.0f]; - [NSNumber numberWithInteger:2.0F]; - [NSNumber numberWithInteger:2.0l]; - [NSNumber numberWithInteger:2.0L]; - @0x2f; - @04; - @0; - [NSNumber numberWithInteger:0.0]; - [NSNumber numberWithInteger:YES]; - [NSNumber numberWithInteger:NO]; - [NSNumber numberWithInteger:true]; - [NSNumber numberWithInteger:false]; - @VAL_INT; - [NSNumber numberWithInteger:VAL_UINT]; - - [NSNumber numberWithUnsignedInteger:'a']; - [NSNumber numberWithUnsignedInteger:L'a']; - @2U; - @2U; - @2u; - @2U; - @2u; - @2U; - @2u; - @2ul; - @2lu; - @2u; - @2u; - [NSNumber numberWithUnsignedInteger:2.0]; - [NSNumber numberWithUnsignedInteger:2.0f]; - [NSNumber numberWithUnsignedInteger:2.0F]; - [NSNumber numberWithUnsignedInteger:2.0l]; - [NSNumber numberWithUnsignedInteger:2.0L]; - @0x2fU; - @04U; - @0U; - [NSNumber numberWithUnsignedInteger:0.0]; - [NSNumber numberWithUnsignedInteger:YES]; - [NSNumber numberWithUnsignedInteger:NO]; - [NSNumber numberWithUnsignedInteger:true]; - [NSNumber numberWithUnsignedInteger:false]; - [NSNumber numberWithUnsignedInteger:VAL_INT]; - @VAL_UINT; -} diff --git a/clang/test/ARCMT/objcmt-property-availability.m b/clang/test/ARCMT/objcmt-property-availability.m deleted file mode 100644 index 37ba74f3346fb4..00000000000000 --- a/clang/test/ARCMT/objcmt-property-availability.m +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - - -#define __NSi_7_0 introduced=7.0 -#define __NSi_6_0 introduced=6.0 - -#define CF_AVAILABLE(_mac, _ios) __attribute__((availability(ios,__NSi_##_ios))) -#define CF_AVAILABLE_MAC(_mac) __attribute__((availability(macosx,__NSi_##_mac))) -#define CF_AVAILABLE_IOS(_ios) __attribute__((availability(macosx,unavailable))) - -#define NS_AVAILABLE(_mac, _ios) CF_AVAILABLE(_mac, _ios) -#define NS_AVAILABLE_MAC(_mac) CF_AVAILABLE_MAC(_mac) -#define NS_AVAILABLE_IOS(_ios) CF_AVAILABLE_IOS(_ios) - -#define UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) - -@interface MKMapItem -- (MKMapItem *)source NS_AVAILABLE(10_9, 6_0); -- (void)setSource:(MKMapItem *)source NS_AVAILABLE(10_9, 7_0); - -- (void)setDest:(MKMapItem *)source NS_AVAILABLE(10_9, 6_0); -- (MKMapItem *)dest NS_AVAILABLE(10_9, 6_0); - -- (MKMapItem *)final; -- (void)setFinal:(MKMapItem *)source; - -- (MKMapItem *)total NS_AVAILABLE(10_9, 6_0); -- (void)setTotal:(MKMapItem *)source; - -- (MKMapItem *)comp NS_AVAILABLE(10_9, 6_0); -- (void)setComp:(MKMapItem *)source UNAVAILABLE; - -- (MKMapItem *)tally UNAVAILABLE NS_AVAILABLE(10_9, 6_0); -- (void)setTally:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); - -- (MKMapItem *)itally NS_AVAILABLE(10_9, 6_0); -- (void)setItally:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); - -- (MKMapItem *)normal UNAVAILABLE; -- (void)setNormal:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); -@end - diff --git a/clang/test/ARCMT/objcmt-property-availability.m.result b/clang/test/ARCMT/objcmt-property-availability.m.result deleted file mode 100644 index 3a212ac894c4a3..00000000000000 --- a/clang/test/ARCMT/objcmt-property-availability.m.result +++ /dev/null @@ -1,42 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - - -#define __NSi_7_0 introduced=7.0 -#define __NSi_6_0 introduced=6.0 - -#define CF_AVAILABLE(_mac, _ios) __attribute__((availability(ios,__NSi_##_ios))) -#define CF_AVAILABLE_MAC(_mac) __attribute__((availability(macosx,__NSi_##_mac))) -#define CF_AVAILABLE_IOS(_ios) __attribute__((availability(macosx,unavailable))) - -#define NS_AVAILABLE(_mac, _ios) CF_AVAILABLE(_mac, _ios) -#define NS_AVAILABLE_MAC(_mac) CF_AVAILABLE_MAC(_mac) -#define NS_AVAILABLE_IOS(_ios) CF_AVAILABLE_IOS(_ios) - -#define UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) - -@interface MKMapItem -@property (nonatomic, strong) MKMapItem *source NS_AVAILABLE(10_9, 6_0); -- (void)setSource:(MKMapItem *)source NS_AVAILABLE(10_9, 7_0); - -@property (nonatomic, strong) MKMapItem *dest NS_AVAILABLE(10_9, 6_0); - -@property (nonatomic, strong) MKMapItem *final; - -@property (nonatomic, strong) MKMapItem *total NS_AVAILABLE(10_9, 6_0); -- (void)setTotal:(MKMapItem *)source; - -- (MKMapItem *)comp NS_AVAILABLE(10_9, 6_0); -- (void)setComp:(MKMapItem *)source UNAVAILABLE; - -@property (nonatomic, strong) MKMapItem *tally UNAVAILABLE NS_AVAILABLE(10_9, 6_0); - -- (MKMapItem *)itally NS_AVAILABLE(10_9, 6_0); -- (void)setItally:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); - -- (MKMapItem *)normal UNAVAILABLE; -- (void)setNormal:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); -@end - diff --git a/clang/test/ARCMT/objcmt-property-dot-syntax.m b/clang/test/ARCMT/objcmt-property-dot-syntax.m deleted file mode 100644 index ec75b5140e18df..00000000000000 --- a/clang/test/ARCMT/objcmt-property-dot-syntax.m +++ /dev/null @@ -1,117 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-property-dot-syntax -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 -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -@class NSString; - -@protocol NSObject -@property (readonly, copy) NSString *description; -@end - -@interface NSObject @end - -@interface P : NSObject -{ - P* obj; - int i1, i2, i3; -} -@property int count; -@property (copy) P* PropertyReturnsPObj; -- (P*) MethodReturnsPObj; -@end - -P* fun(void); - -@implementation P -- (int) Meth : (P*)array { - [obj setCount : 100]; - - [(P*)0 setCount : [array count]]; - - [[obj PropertyReturnsPObj] setCount : [array count]]; - - [obj setCount : (i1+i2*i3 - 100)]; - - return [obj count] - - [(P*)0 count] + [array count] + - [fun() count] - - [[obj PropertyReturnsPObj] count] + - [self->obj count]; -} - -- (P*) MethodReturnsPObj { return 0; } - -- (NSString *)description { return [super description]; } -@end - -@interface Sub : P -@end - -@implementation Sub -- (int) Meth : (P*)array { - [super setCount : 100]; - - [super setCount : [array count]]; - - [[super PropertyReturnsPObj] setCount : [array count]]; - - [super setCount : (i1+i2*i3 - 100)]; - - return [super count] - - [(P*)0 count] + [array count] + - [fun() count] - - [[super PropertyReturnsPObj] count] + - [self->obj count]; -} -@end - - -@interface Rdar19038838 -@property id newItem; // should be marked objc_method_family(none), but isn't. -@end - -id testRdar19038838(Rdar19038838 *obj) { - return [obj newItem]; -} - -@interface rdar19381786 : NSObject -{ - rdar19381786* obj; -} -@property int count; -@end - -@protocol PR -@property int count; -@end - -@implementation rdar19381786 --(void)test:(id)some : (id)qsome : (SEL)selsome -{ - [obj setCount : 100]; - [some setCount : [some count]]; - [qsome setCount : [qsome count]]; -} -@end - -int NSOnState; -int ArrNSOnState[4]; -@interface rdar19140114 : NSObject -{ - rdar19140114* menuItem; -} -@property int state; -@end - -@implementation rdar19140114 -- (void) Meth { - [menuItem setState:NSOnState]; - [menuItem setState :NSOnState]; - [menuItem setState :ArrNSOnState[NSOnState]]; - [menuItem setState : NSOnState]; - [menuItem setState: NSOnState]; - [menuItem setState: NSOnState]; - [menuItem setState : NSOnState]; -} -@end diff --git a/clang/test/ARCMT/objcmt-property-dot-syntax.m.result b/clang/test/ARCMT/objcmt-property-dot-syntax.m.result deleted file mode 100644 index 5153b0e658f6ac..00000000000000 --- a/clang/test/ARCMT/objcmt-property-dot-syntax.m.result +++ /dev/null @@ -1,117 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-property-dot-syntax -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 -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -@class NSString; - -@protocol NSObject -@property (readonly, copy) NSString *description; -@end - -@interface NSObject @end - -@interface P : NSObject -{ - P* obj; - int i1, i2, i3; -} -@property int count; -@property (copy) P* PropertyReturnsPObj; -- (P*) MethodReturnsPObj; -@end - -P* fun(void); - -@implementation P -- (int) Meth : (P*)array { - obj.count = 100; - - ((P*)0).count = array.count; - - obj.PropertyReturnsPObj.count = array.count; - - obj.count = (i1+i2*i3 - 100); - - return obj.count - - ((P*)0).count + array.count + - fun().count - - obj.PropertyReturnsPObj.count + - self->obj.count; -} - -- (P*) MethodReturnsPObj { return 0; } - -- (NSString *)description { return super.description; } -@end - -@interface Sub : P -@end - -@implementation Sub -- (int) Meth : (P*)array { - super.count = 100; - - super.count = array.count; - - super.PropertyReturnsPObj.count = array.count; - - super.count = (i1+i2*i3 - 100); - - return super.count - - ((P*)0).count + array.count + - fun().count - - super.PropertyReturnsPObj.count + - self->obj.count; -} -@end - - -@interface Rdar19038838 -@property id newItem; // should be marked objc_method_family(none), but isn't. -@end - -id testRdar19038838(Rdar19038838 *obj) { - return obj.newItem; -} - -@interface rdar19381786 : NSObject -{ - rdar19381786* obj; -} -@property int count; -@end - -@protocol PR -@property int count; -@end - -@implementation rdar19381786 --(void)test:(id)some : (id)qsome : (SEL)selsome -{ - obj.count = 100; - [some setCount : [some count]]; - qsome.count = qsome.count; -} -@end - -int NSOnState; -int ArrNSOnState[4]; -@interface rdar19140114 : NSObject -{ - rdar19140114* menuItem; -} -@property int state; -@end - -@implementation rdar19140114 -- (void) Meth { - menuItem.state = NSOnState; - menuItem.state = NSOnState; - menuItem.state = ArrNSOnState[NSOnState]; - menuItem.state = NSOnState; - menuItem.state = NSOnState; - menuItem.state = NSOnState; - menuItem.state = NSOnState; -} -@end diff --git a/clang/test/ARCMT/objcmt-property.m b/clang/test/ARCMT/objcmt-property.m deleted file mode 100644 index f2b722e66d9699..00000000000000 --- a/clang/test/ARCMT/objcmt-property.m +++ /dev/null @@ -1,243 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -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 -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -- (void) setWeakProp : (NSString *__weak)Val; -- (NSString *__weak) WeakProp; - -- (NSString *) StrongProp; -- (void) setStrongProp : (NSString *)Val; - -- (NSString *) UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -- (NSString *) UnavailProp1 __attribute__((unavailable)); -- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); - -- (NSString *) UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -- (NSDictionary*) undoAction; -- (void) setUndoAction: (NSDictionary*)Arg; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -- (void)setNames1:(NSArray *)names; -- (void)setNames4:(__strong NSArray *)names; -- (void)setNames3:(__strong NSArray *)names; -- (void)setNames2:(NSArray *)names; -- (NSArray *) names2; -- (NSArray *)names3; -- (__strong NSArray *)names4; -- (NSArray *) names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)delegate; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; -- (void *)JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -- (BOOL)isIgnoringInteractionEvents; - -- (NSString *)getStringValue; -- (BOOL)getCounterValue; -- (void)setStringValue:(NSString *)stringValue AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; -- (NSDictionary *)getns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - - -@interface NSInvocation(CAT) -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -- (NSURL *)appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -- (NSURL *)appStoreReceiptURLX NS_AVAILABLE; -- (void) setAppStoreReceiptURLX : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -- (id)OkToInfer NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -- (id)method1 ALIGNED NS_AVAILABLE; -- (void) setMethod1 : (id) object NS_AVAILABLE ALIGNED; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -- (BOOL)isClass; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -- (id (^)(id, NSArray *, NSMutableDictionary *)) expressionBlock; -- (id (^)(id, NSArray *, NSMutableDictionary *)) MyBlock; -- (void) setMyBlock : (id (^)(id, NSArray *, NSMutableDictionary *)) bl; -- (id (*)(id, NSArray *, NSMutableDictionary *)) expressionFuncptr; -- (id (*)(id, NSArray *, NSMutableDictionary *)) MyFuncptr; -- (void) setMyFuncptr : (id (*)(id, NSArray *, NSMutableDictionary *)) bl; -@end - -@interface rdar15231241 -@property (nonatomic, readonly) double Ddelegate; -@property (nonatomic, readonly) float Fdelegate; -@property (nonatomic, readonly) int Idelegate; -@property (nonatomic, readonly) BOOL Bdelegate; -@end - -@protocol NSObject @end -@protocol MyProtocol -- (id)readonlyProperty; -- (id)readWriteProperty; -- (void)setReadWriteProperty:(id)readWriteProperty; -@end diff --git a/clang/test/ARCMT/objcmt-property.m.result b/clang/test/ARCMT/objcmt-property.m.result deleted file mode 100644 index 610f027cee5c15..00000000000000 --- a/clang/test/ARCMT/objcmt-property.m.result +++ /dev/null @@ -1,215 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -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 -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -@property (nonatomic, weak) NSString *WeakProp; - -@property (nonatomic, strong) NSString *StrongProp; - -@property (nonatomic, strong) NSString *UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -@property (nonatomic, strong) NSString *UnavailProp1 __attribute__((unavailable)); - -@property (nonatomic, strong) NSString *UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -@property (nonatomic, copy) NSDictionary *undoAction; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -@property (nonatomic, strong) NSArray *names2; -@property (nonatomic, strong) NSArray *names3; -@property (nonatomic, strong) NSArray *names4; -@property (nonatomic, strong) NSArray *names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -@property (nonatomic, assign) id target; - -@property (nonatomic, assign) id dataSource; - -@property (nonatomic, readonly, assign) id delegate; - -@property (nonatomic, assign) id xxxdelegateYYY; - - -@property (nonatomic, strong) id MYtarget; - -@property (nonatomic, strong) id targetX; - -@property (nonatomic) int value; - -@property (nonatomic, getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (nonatomic, getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (nonatomic, readonly) int Length; -@property (nonatomic, readonly, strong) id object; -+ (double) D; -@property (nonatomic, readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -@property (nonatomic, getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents; - -@property (nonatomic, getter=getStringValue, strong) NSString *stringValue; -@property (nonatomic, getter=getCounterValue, readonly) BOOL counterValue; -@property (nonatomic, getter=getns_dixtionary, readonly, copy) NSDictionary *ns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (nonatomic, getter=getM, readonly) BOOL m; -@property (nonatomic, getter=getMA, readonly) BOOL MA; -@property (nonatomic, getter=getALL, readonly) BOOL ALL; -@property (nonatomic, getter=getMANY, readonly) BOOL MANY; -@property (nonatomic, getter=getSome, readonly) BOOL some; -@end - - -@interface NSInvocation(CAT) -@property (nonatomic, assign) id target; - -@property (nonatomic, assign) id dataSource; - -@property (nonatomic, assign) id xxxdelegateYYY; - - -@property (nonatomic, strong) id MYtarget; - -@property (nonatomic, strong) id targetX; - -@property (nonatomic) int value; - -@property (nonatomic, getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (nonatomic, getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (nonatomic, readonly) int Length; -@property (nonatomic, readonly, strong) id object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (nonatomic, getter=getM, readonly) BOOL m; -@property (nonatomic, getter=getMA, readonly) BOOL MA; -@property (nonatomic, getter=getALL, readonly) BOOL ALL; -@property (nonatomic, getter=getMANY, readonly) BOOL MANY; -@property (nonatomic, getter=getSome, readonly) BOOL some; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -@property (nonatomic, strong) NSURL *appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -@property (nonatomic, strong) NSURL *appStoreReceiptURLX NS_AVAILABLE; - -// Do not infer a property. -@property (nonatomic, strong) NSURL *appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -@property (nonatomic, readonly, strong) id OkToInfer NS_AVAILABLE; - -// Do not infer a property. -@property (nonatomic, strong) NSURL *appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -@property (nonatomic, strong) id method1 ALIGNED NS_AVAILABLE; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -@property (nonatomic, getter=isClass, readonly) BOOL class; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -@property (nonatomic, readonly, copy) id (^expressionBlock)(id, NSArray *, NSMutableDictionary *); -@property (nonatomic, copy) id (^MyBlock)(id, NSArray *, NSMutableDictionary *); -@property (nonatomic, readonly) id (*expressionFuncptr)(id, NSArray *, NSMutableDictionary *); -@property (nonatomic) id (*MyFuncptr)(id, NSArray *, NSMutableDictionary *); -@end - -@interface rdar15231241 -@property (nonatomic, readonly) double Ddelegate; -@property (nonatomic, readonly) float Fdelegate; -@property (nonatomic, readonly) int Idelegate; -@property (nonatomic, readonly) BOOL Bdelegate; -@end - -@protocol NSObject @end -@protocol MyProtocol -@property (nonatomic, readonly, strong) id readonlyProperty; -@property (nonatomic, strong) id readWriteProperty; -@end diff --git a/clang/test/ARCMT/objcmt-protocol-conformance.m b/clang/test/ARCMT/objcmt-protocol-conformance.m deleted file mode 100644 index e9bb4ac12e6d48..00000000000000 --- a/clang/test/ARCMT/objcmt-protocol-conformance.m +++ /dev/null @@ -1,129 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-protocol-conformance -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -@interface NSObject @end - -@protocol P -- (id) Meth1: (double) arg; -@end - -@interface Test1 // Test for no super class and no protocol list -@end - -@implementation Test1 -- (id) Meth1: (double) arg { return 0; } -@end - -@protocol P1 @end -@protocol P2 @end - -@interface Test2 // Test for no super class and with protocol list -{ - id IVAR1; - id IVAR2; -} -@end - -@implementation Test2 -- (id) Meth1: (double) arg { return 0; } -@end - -@interface Test3 : NSObject { // Test for Super class and no protocol list - id IV1; -} -@end - -@implementation Test3 -- (id) Meth1: (double) arg { return 0; } -@end - -@interface Test4 : NSObject // Test for Super class and protocol list -@end - -@implementation Test4 -- (id) Meth1: (double) arg { return 0; } -@end - -// Test5 - conforms to P3 because it implement's P3's property. -@protocol P3 -@property (copy) id Prop; -@end - -@protocol P4 -@property (copy) id Prop; -@end - -@interface Test5 : NSObject -@end - -@implementation Test5 -@synthesize Prop=_XXX; -@end - -@protocol P5 -@property (copy) id Prop; -@end - -@protocol P6 -@property (copy) id Prop; -@end - -@interface Test6 : NSObject // Test for minimal listing of conforming protocols -@property (copy) id Prop; -@end - -@implementation Test6 -@end - -@class UIDynamicAnimator, UIWindow; -@interface UIResponder : NSObject -@end - -@protocol EmptyProtocol -@end - -@protocol OptionalMethodsOnly -@optional -- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; -- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; -@end - -@protocol OptionalPropertiesOnly -@optional -@property (strong, nonatomic) id OptionalProperty; -@end - -@protocol OptionalEvrything -@optional -- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; -@property (strong, nonatomic) id OptionalProperty; -- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; -@end - -@protocol UIApplicationDelegate -@end - -@interface Test7 : UIResponder -@property (strong, nonatomic) UIWindow *window; -@end - -@implementation Test7 -@end - -@interface BTLEBrowser -@end - -@protocol CBCentralManagerDelegate; - -@protocol CBCentralManagerDelegate -- (id) Meth1: (double) arg; -@end - -@interface BTLEBrowser() -@end - -@implementation BTLEBrowser -- (id) Meth15515206: (double) arg { return 0; } -@end diff --git a/clang/test/ARCMT/objcmt-protocol-conformance.m.result b/clang/test/ARCMT/objcmt-protocol-conformance.m.result deleted file mode 100644 index 987532544bc64b..00000000000000 --- a/clang/test/ARCMT/objcmt-protocol-conformance.m.result +++ /dev/null @@ -1,129 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-protocol-conformance -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 -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -@interface NSObject @end - -@protocol P -- (id) Meth1: (double) arg; -@end - -@interface Test1

// Test for no super class and no protocol list -@end - -@implementation Test1 -- (id) Meth1: (double) arg { return 0; } -@end - -@protocol P1 @end -@protocol P2 @end - -@interface Test2 // Test for no super class and with protocol list -{ - id IVAR1; - id IVAR2; -} -@end - -@implementation Test2 -- (id) Meth1: (double) arg { return 0; } -@end - -@interface Test3 : NSObject

{ // Test for Super class and no protocol list - id IV1; -} -@end - -@implementation Test3 -- (id) Meth1: (double) arg { return 0; } -@end - -@interface Test4 : NSObject // Test for Super class and protocol list -@end - -@implementation Test4 -- (id) Meth1: (double) arg { return 0; } -@end - -// Test5 - conforms to P3 because it implement's P3's property. -@protocol P3 -@property (copy) id Prop; -@end - -@protocol P4 -@property (copy) id Prop; -@end - -@interface Test5 : NSObject -@end - -@implementation Test5 -@synthesize Prop=_XXX; -@end - -@protocol P5 -@property (copy) id Prop; -@end - -@protocol P6 -@property (copy) id Prop; -@end - -@interface Test6 : NSObject // Test for minimal listing of conforming protocols -@property (copy) id Prop; -@end - -@implementation Test6 -@end - -@class UIDynamicAnimator, UIWindow; -@interface UIResponder : NSObject -@end - -@protocol EmptyProtocol -@end - -@protocol OptionalMethodsOnly -@optional -- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; -- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; -@end - -@protocol OptionalPropertiesOnly -@optional -@property (strong, nonatomic) id OptionalProperty; -@end - -@protocol OptionalEvrything -@optional -- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; -@property (strong, nonatomic) id OptionalProperty; -- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; -@end - -@protocol UIApplicationDelegate -@end - -@interface Test7 : UIResponder -@property (strong, nonatomic) UIWindow *window; -@end - -@implementation Test7 -@end - -@interface BTLEBrowser -@end - -@protocol CBCentralManagerDelegate; - -@protocol CBCentralManagerDelegate -- (id) Meth1: (double) arg; -@end - -@interface BTLEBrowser() -@end - -@implementation BTLEBrowser -- (id) Meth15515206: (double) arg { return 0; } -@end diff --git a/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m b/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m deleted file mode 100644 index 1f56f4a2cf510c..00000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m +++ /dev/null @@ -1,108 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fobjc-arc -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fobjc-arc -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -typedef const struct __CFString * CFStringRef; - -@interface NSObject -+ (id)alloc; -@end - -@protocol NSCopying -@end - -@interface NSString : NSObject -+ (id)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSExtendedArray) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSMutableArray (NSExtendedMutableArray) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface NSDictionary : NSObject -- (id)objectForKey:(id)aKey; -@end - -@interface NSDictionary (NSExtendedDictionary) -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface NSMutableDictionary (NSExtendedMutableDictionary) -- (void)setObject:(id)obj forKeyedSubscript:(id )key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -- (id)initWithInt:(int)value; -@end - -@interface I { - NSArray *ivarArr; -} -@end -@implementation I --(void) foo { - NSString *str; - NSArray *arr; - NSDictionary *dict; - - arr = [NSArray arrayWithObjects:str, str, nil]; - arr = [[NSArray alloc] initWithObjects:str, str, nil]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: @"value1", @"key1", @"value2", @"key2", nil]; - dict = [[NSDictionary alloc] initWithObjectsAndKeys: @"value1", @"key1", @"value2", @"key2", nil]; - - dict = [[NSDictionary alloc] initWithObjects:[[NSArray alloc] initWithObjects:@"1", @"2", nil] forKeys:[NSArray arrayWithObjects:@"A", @"B", nil]]; - - NSNumber *n = [[NSNumber alloc] initWithInt:2]; -} -@end diff --git a/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m.result b/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m.result deleted file mode 100644 index d974a2564d4302..00000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m.result +++ /dev/null @@ -1,108 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fobjc-arc -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fobjc-arc -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -typedef const struct __CFString * CFStringRef; - -@interface NSObject -+ (id)alloc; -@end - -@protocol NSCopying -@end - -@interface NSString : NSObject -+ (id)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSExtendedArray) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSMutableArray (NSExtendedMutableArray) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface NSDictionary : NSObject -- (id)objectForKey:(id)aKey; -@end - -@interface NSDictionary (NSExtendedDictionary) -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface NSMutableDictionary (NSExtendedMutableDictionary) -- (void)setObject:(id)obj forKeyedSubscript:(id )key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -- (id)initWithInt:(int)value; -@end - -@interface I { - NSArray *ivarArr; -} -@end -@implementation I --(void) foo { - NSString *str; - NSArray *arr; - NSDictionary *dict; - - arr = @[str, str]; - arr = @[str, str]; - dict = @{@"key1": @"value1", @"key2": @"value2"}; - dict = @{@"key1": @"value1", @"key2": @"value2"}; - - dict = @{@"A": @"1", @"B": @"2"}; - - NSNumber *n = @2; -} -@end diff --git a/clang/test/ARCMT/objcmt-subscripting-literals.m b/clang/test/ARCMT/objcmt-subscripting-literals.m deleted file mode 100644 index e2b03e2d7b587d..00000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-literals.m +++ /dev/null @@ -1,230 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -typedef const struct __CFString * CFStringRef; - -@interface NSObject -+ (id)alloc; -@end - -@protocol NSCopying -@end - -@interface NSString : NSObject -+ (id)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSExtendedArray) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSMutableArray (NSExtendedMutableArray) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface NSDictionary : NSObject -- (id)objectForKey:(id)aKey; -@end - -@interface NSDictionary (NSExtendedDictionary) -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface NSMutableDictionary (NSExtendedMutableDictionary) -- (void)setObject:(id)obj forKeyedSubscript:(id )key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -#define M(x) (x) -#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] -#define TWO(x) ((x), (x)) -#define TWO_SEP(x,y) ((x), (y)) - -@interface I { - NSArray *ivarArr; -} -@end -@implementation I --(void) foo { - NSString *str; - NSArray *arr; - NSDictionary *dict; - - arr = [NSArray array]; - arr = [NSArray arrayWithObject:str]; - arr = [NSArray arrayWithObjects:str, str, nil]; - dict = [NSDictionary dictionary]; - dict = [NSDictionary dictionaryWithObject:arr forKey:str]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: @"value1", @"key1", @"value2", @"key2", nil]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: PAIR(1), PAIR(2), nil]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: - @"value1", @"key1", -#ifdef BLAH - @"value2", @"key2", -#else - @"value3", @"key3", -#endif - nil ]; - - id o = [arr objectAtIndex:2]; - o = [dict objectForKey:@"key"]; - o = TWO([dict objectForKey:@"key"]); - o = TWO_SEP([dict objectForKey:@"key"], [arr objectAtIndex:2]); - o = [NSDictionary dictionaryWithObject:[NSDictionary dictionary] forKey:@"key"]; - NSMutableArray *marr = 0; - NSMutableDictionary *mdict = 0; - [marr replaceObjectAtIndex:2 withObject:@"val"]; - [mdict setObject:@"value" forKey:@"key"]; - [marr replaceObjectAtIndex:2 withObject:[arr objectAtIndex:4]]; - [mdict setObject:[dict objectForKey:@"key2"] forKey:@"key"]; - [mdict setObject:[dict objectForKey:@"key2"] forKey: -#if 1 - @"key1" -#else - @"key2" -#endif - ]; - [mdict setObject:[dict objectForKey: -#if 2 - @"key3" -#else - @"key4" -#endif - ] forKey:@"key"]; - [mdict setObject:@"value" forKey:[dict objectForKey: -#if 3 - @"key5" -#else - @"key6" -#endif - ] ]; - [mdict setObject:@"val" forKey:[dict objectForKey:@"key2"]]; - [mdict setObject:[dict objectForKey:@"key1"] forKey:[dict objectForKey:[NSArray arrayWithObject:@"arrkey"]]]; - __strong NSArray **parr = 0; - o = [*parr objectAtIndex:2]; - void *hd; - o = [(NSArray*)hd objectAtIndex:2]; - o = [ivarArr objectAtIndex:2]; - - dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", [NSArray array], nil] forKeys:[NSArray arrayWithObjects:@"A", [arr objectAtIndex:2], nil]]; - dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", @"2", nil] forKeys:arr]; - dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", @"2", nil] forKeys:@[@"A", @"B"]]; - dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray array], @"A", [NSArray array], @"B", nil]; -} -@end - -extern const CFStringRef globStr; - -void test1(NSString *str) { - NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: str, globStr, nil]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: globStr, str, nil]; - dict = [NSDictionary dictionaryWithObject:str forKey:globStr]; - dict = [NSDictionary dictionaryWithObject:globStr forKey:str]; - - NSArray *arr = [NSArray arrayWithObjects: globStr, globStr, nil]; - arr = [NSArray arrayWithObjects: str, globStr, nil]; - arr = [NSArray arrayWithObjects: globStr, str, nil]; - arr = [NSArray arrayWithObject:globStr]; -} - -@interface Custom : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface Custom (Extended) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface MutableCustom : Custom -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface MutableCustom (Extended) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface CustomUnavail : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface CustomUnavail (Extended) -- (id)objectAtIndexedSubscript:(unsigned)idx __attribute__((unavailable)); -@end - -@interface MutableCustomUnavail : CustomUnavail -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface MutableCustomUnavail (Extended) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx __attribute__((unavailable)); -@end - -void test2(void) { - MutableCustom *mutc; - id o = [mutc objectAtIndex:4]; - [mutc replaceObjectAtIndex:2 withObject:@"val"]; - - MutableCustomUnavail *mutcunaval; - o = [mutcunaval objectAtIndex:4]; - [mutcunaval replaceObjectAtIndex:2 withObject:@"val"]; -} - -@interface NSLocale : NSObject -+ (id)systemLocale; -+ (id)currentLocale; -- (id)objectForKey:(id)key; -@end - -void test3(id key) { - id o = [[NSLocale currentLocale] objectForKey:key]; -} diff --git a/clang/test/ARCMT/objcmt-subscripting-literals.m.result b/clang/test/ARCMT/objcmt-subscripting-literals.m.result deleted file mode 100644 index e0b385741f01ed..00000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-literals.m.result +++ /dev/null @@ -1,230 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -typedef const struct __CFString * CFStringRef; - -@interface NSObject -+ (id)alloc; -@end - -@protocol NSCopying -@end - -@interface NSString : NSObject -+ (id)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSExtendedArray) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSMutableArray (NSExtendedMutableArray) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface NSDictionary : NSObject -- (id)objectForKey:(id)aKey; -@end - -@interface NSDictionary (NSExtendedDictionary) -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface NSMutableDictionary (NSExtendedMutableDictionary) -- (void)setObject:(id)obj forKeyedSubscript:(id )key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -#define M(x) (x) -#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] -#define TWO(x) ((x), (x)) -#define TWO_SEP(x,y) ((x), (y)) - -@interface I { - NSArray *ivarArr; -} -@end -@implementation I --(void) foo { - NSString *str; - NSArray *arr; - NSDictionary *dict; - - arr = @[]; - arr = @[str]; - arr = @[str, str]; - dict = @{}; - dict = @{str: arr}; - dict = @{@"key1": @"value1", @"key2": @"value2"}; - dict = [NSDictionary dictionaryWithObjectsAndKeys: PAIR(1), PAIR(2), nil]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: - @"value1", @"key1", -#ifdef BLAH - @"value2", @"key2", -#else - @"value3", @"key3", -#endif - nil ]; - - id o = arr[2]; - o = dict[@"key"]; - o = TWO(dict[@"key"]); - o = TWO_SEP(dict[@"key"], arr[2]); - o = @{@"key": @{}}; - NSMutableArray *marr = 0; - NSMutableDictionary *mdict = 0; - marr[2] = @"val"; - mdict[@"key"] = @"value"; - marr[2] = arr[4]; - mdict[@"key"] = dict[@"key2"]; - [mdict setObject:dict[@"key2"] forKey: -#if 1 - @"key1" -#else - @"key2" -#endif - ]; - mdict[@"key"] = [dict objectForKey: -#if 2 - @"key3" -#else - @"key4" -#endif - ]; - mdict[[dict objectForKey: -#if 3 - @"key5" -#else - @"key6" -#endif - ]] = @"value"; - mdict[dict[@"key2"]] = @"val"; - mdict[dict[@[@"arrkey"]]] = dict[@"key1"]; - __strong NSArray **parr = 0; - o = (*parr)[2]; - void *hd; - o = ((NSArray*)hd)[2]; - o = ivarArr[2]; - - dict = @{@"A": @"1", arr[2]: @[]}; - dict = [NSDictionary dictionaryWithObjects:@[@"1", @"2"] forKeys:arr]; - dict = @{@"A": @"1", @"B": @"2"}; - dict = @{@"A": @[], @"B": @[]}; -} -@end - -extern const CFStringRef globStr; - -void test1(NSString *str) { - NSDictionary *dict = @{(id)globStr: str}; - dict = @{str: (id)globStr}; - dict = @{(id)globStr: str}; - dict = @{str: (id)globStr}; - - NSArray *arr = @[(id)globStr, (id)globStr]; - arr = @[str, (id)globStr]; - arr = @[(id)globStr, str]; - arr = @[(id)globStr]; -} - -@interface Custom : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface Custom (Extended) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface MutableCustom : Custom -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface MutableCustom (Extended) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface CustomUnavail : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface CustomUnavail (Extended) -- (id)objectAtIndexedSubscript:(unsigned)idx __attribute__((unavailable)); -@end - -@interface MutableCustomUnavail : CustomUnavail -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface MutableCustomUnavail (Extended) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx __attribute__((unavailable)); -@end - -void test2(void) { - MutableCustom *mutc; - id o = mutc[4]; - mutc[2] = @"val"; - - MutableCustomUnavail *mutcunaval; - o = [mutcunaval objectAtIndex:4]; - [mutcunaval replaceObjectAtIndex:2 withObject:@"val"]; -} - -@interface NSLocale : NSObject -+ (id)systemLocale; -+ (id)currentLocale; -- (id)objectForKey:(id)key; -@end - -void test3(id key) { - id o = [[NSLocale currentLocale] objectForKey:key]; -} diff --git a/clang/test/ARCMT/objcmt-subscripting-unavailable.m b/clang/test/ARCMT/objcmt-subscripting-unavailable.m deleted file mode 100644 index d72c362e30f4ff..00000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-unavailable.m +++ /dev/null @@ -1,79 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSDictionary : NSObject -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)objectForKey:(id)aKey; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface I -@end -@implementation I --(void) foo { - id str; - NSArray *arr; - NSDictionary *dict; - - arr = [NSArray array]; - arr = [NSArray arrayWithObject:str]; - arr = [NSArray arrayWithObjects:str, str, nil]; - dict = [NSDictionary dictionary]; - dict = [NSDictionary dictionaryWithObject:arr forKey:str]; - - id o = [arr objectAtIndex:2]; - o = [dict objectForKey:@"key"]; - NSMutableArray *marr = 0; - NSMutableDictionary *mdict = 0; - [marr replaceObjectAtIndex:2 withObject:@"val"]; - [mdict setObject:@"value" forKey:@"key"]; - [marr replaceObjectAtIndex:2 withObject:[arr objectAtIndex:4]]; - [mdict setObject:[dict objectForKey:@"key2"] forKey:@"key"]; -} -@end diff --git a/clang/test/ARCMT/objcmt-subscripting-unavailable.m.result b/clang/test/ARCMT/objcmt-subscripting-unavailable.m.result deleted file mode 100644 index bd74d558386080..00000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-unavailable.m.result +++ /dev/null @@ -1,79 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSDictionary : NSObject -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)objectForKey:(id)aKey; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface I -@end -@implementation I --(void) foo { - id str; - NSArray *arr; - NSDictionary *dict; - - arr = @[]; - arr = @[str]; - arr = @[str, str]; - dict = @{}; - dict = @{str: arr}; - - id o = [arr objectAtIndex:2]; - o = [dict objectForKey:@"key"]; - NSMutableArray *marr = 0; - NSMutableDictionary *mdict = 0; - [marr replaceObjectAtIndex:2 withObject:@"val"]; - [mdict setObject:@"value" forKey:@"key"]; - [marr replaceObjectAtIndex:2 withObject:[arr objectAtIndex:4]]; - [mdict setObject:[dict objectForKey:@"key2"] forKey:@"key"]; -} -@end diff --git a/clang/test/ARCMT/objcmt-undefined-ns-macros.m b/clang/test/ARCMT/objcmt-undefined-ns-macros.m deleted file mode 100644 index 473b49589222da..00000000000000 --- a/clang/test/ARCMT/objcmt-undefined-ns-macros.m +++ /dev/null @@ -1,22 +0,0 @@ -// 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 - -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; - diff --git a/clang/test/ARCMT/objcmt-undefined-ns-macros.m.result b/clang/test/ARCMT/objcmt-undefined-ns-macros.m.result deleted file mode 100644 index a6942e20795fd0..00000000000000 --- a/clang/test/ARCMT/objcmt-undefined-ns-macros.m.result +++ /dev/null @@ -1,24 +0,0 @@ -// 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 - -typedef long NSInteger; -#ifndef NS_ENUM -@import Foundation; -#endif -typedef NS_OPTIONS(NSUInteger, UITableStyle) { - UIViewNone = 0x0, - UIViewMargin = 0x1, - UIViewWidth = 0x2, - UIViewRightMargin = 0x3, - UIViewBottomMargin = 0xbadbeef -}; - - -typedef - NS_ENUM(unsigned int, NumericEnum2) { two = 1 }; - -typedef NS_ENUM(unsigned int, NumericEnum3) { three = 1 }; - -typedef NS_ENUM(unsigned int, NumericEnum4) { four = 1 }; - diff --git a/clang/test/ARCMT/objcmt-with-pch.m b/clang/test/ARCMT/objcmt-with-pch.m deleted file mode 100644 index 0925442d45eb97..00000000000000 --- a/clang/test/ARCMT/objcmt-with-pch.m +++ /dev/null @@ -1,17 +0,0 @@ -// REQUIRES: x86-registered-target -// RUN: rm -rf %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %S/Common.h -emit-pch -o %t.pch -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -include-pch %t.pch -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result -include-pch %t.pch - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -void foo(void) { - NSNumber *n = [NSNumber numberWithInt:1]; -} diff --git a/clang/test/ARCMT/objcmt-with-pch.m.result b/clang/test/ARCMT/objcmt-with-pch.m.result deleted file mode 100644 index 6d37d11fe480d4..00000000000000 --- a/clang/test/ARCMT/objcmt-with-pch.m.result +++ /dev/null @@ -1,17 +0,0 @@ -// REQUIRES: x86-registered-target -// RUN: rm -rf %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %S/Common.h -emit-pch -o %t.pch -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -include-pch %t.pch -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result -include-pch %t.pch - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -void foo(void) { - NSNumber *n = @1; -} diff --git a/clang/test/ARCMT/protected-scope.m b/clang/test/ARCMT/protected-scope.m deleted file mode 100644 index b522f54cdf7c16..00000000000000 --- a/clang/test/ARCMT/protected-scope.m +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void test(id p, int x) { - int v; - switch(x) { - case 0: - v++; - id w1 = p; - id w2 = p; - break; - case 1: - v++; - id w3 = p; - break; - case 2: - case 3: - break; - default: - break; - } -} - -void test2(int p) { - switch (p) { - case 3:; - NSObject *o = [[NSObject alloc] init]; - [o release]; - break; - default: - break; - } -} diff --git a/clang/test/ARCMT/protected-scope.m.result b/clang/test/ARCMT/protected-scope.m.result deleted file mode 100644 index 55070f27322712..00000000000000 --- a/clang/test/ARCMT/protected-scope.m.result +++ /dev/null @@ -1,38 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void test(id p, int x) { - int v; - switch(x) { - case 0: { - v++; - id w1 = p; - id w2 = p; - break; - } - case 1: { - v++; - id w3 = p; - break; - } - case 2: - case 3: - break; - default: - break; - } -} - -void test2(int p) { - switch (p) { - case 3: {; - NSObject *o = [[NSObject alloc] init]; - break; - } - default: - break; - } -} diff --git a/clang/test/ARCMT/releases-driver.m b/clang/test/ARCMT/releases-driver.m deleted file mode 100644 index 96f96c1d3b4821..00000000000000 --- a/clang/test/ARCMT/releases-driver.m +++ /dev/null @@ -1,67 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: cat %s > %t -// RUN: %clang_cc1 -arcmt-action=modify -triple x86_64-apple-macosx10.6 -x objective-c %t -// RUN: diff %t %s.result -// RUN: rm %t - -typedef int BOOL; - -id IhaveSideEffect(void); - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -@end - -@interface NSObject {} -@end - -@interface Foo : NSObject { - id bar; -} -@property (retain) id bar; --(void)test:(id)obj; -@end - -@implementation Foo - -@synthesize bar; - --(void)test:(id)obj { - id x = self.bar; - [x retain]; - self.bar = obj; - // do stuff with x; - [x release]; - - [IhaveSideEffect() release]; - - [x release], x = 0; -} - -@end - -void func(Foo *p) { - [p release]; - (([p release])); -} - -@interface Baz { - id _foo; -} -@end - -@implementation Baz -- (void) dealloc { - [_foo release]; -} -@end - -#define RELEASE_MACRO(x) [x release] -#define RELEASE_MACRO2(x) RELEASE_MACRO(x) - -void test2(id p) { - RELEASE_MACRO(p); - RELEASE_MACRO2(p); -} diff --git a/clang/test/ARCMT/releases-driver.m.result b/clang/test/ARCMT/releases-driver.m.result deleted file mode 100644 index e7da9a04fc62ab..00000000000000 --- a/clang/test/ARCMT/releases-driver.m.result +++ /dev/null @@ -1,58 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: cat %s > %t -// RUN: %clang_cc1 -arcmt-action=modify -triple x86_64-apple-macosx10.6 -x objective-c %t -// RUN: diff %t %s.result -// RUN: rm %t - -typedef int BOOL; - -id IhaveSideEffect(void); - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -@end - -@interface NSObject {} -@end - -@interface Foo : NSObject { - id bar; -} -@property (strong) id bar; --(void)test:(id)obj; -@end - -@implementation Foo - -@synthesize bar; - --(void)test:(id)obj { - id x = self.bar; - self.bar = obj; - // do stuff with x; - - IhaveSideEffect(); - - x = 0; -} - -@end - -void func(Foo *p) { -} - -@interface Baz { - id _foo; -} -@end - -@implementation Baz -@end - -#define RELEASE_MACRO(x) [x release] -#define RELEASE_MACRO2(x) RELEASE_MACRO(x) - -void test2(id p) { -} diff --git a/clang/test/ARCMT/releases.m b/clang/test/ARCMT/releases.m deleted file mode 100644 index 8636a8a5acea83..00000000000000 --- a/clang/test/ARCMT/releases.m +++ /dev/null @@ -1,98 +0,0 @@ -// RUN: %clang_cc1 -fobjc-exceptions -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-exceptions -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil 0 - -typedef int BOOL; - -id IhaveSideEffect(void); - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -@end - -@interface NSObject {} -@end - -@interface Foo : NSObject { - id bar; -} -@property (retain) id bar; --(void)test:(id)obj; -@end - -@implementation Foo - -@synthesize bar; - --(void)test:(id)obj { - id x = self.bar; - [x retain]; - self.bar = obj; - // do stuff with x; - [x release]; - - [IhaveSideEffect() release]; - - [x release], x = 0; - - @try { - } @finally { - [x release]; - } -} - -@end - -void func(Foo *p) { - [p release]; - (([p release])); -} - -@interface Baz { - id _foo; -} -@end - -@implementation Baz -- (void) dealloc { - [_foo release]; -} -@end - -void block_test(Foo *p) { - id (^B)(void) = ^(void) { - if (p) { - id (^IB)(void) = ^(void) { - id bar = [p retain]; - [p release]; - return bar; - }; - IB(); - } - return [p retain]; - }; -} - -#define RELEASE_MACRO(x) [x release] -#define RELEASE_MACRO2(x) RELEASE_MACRO(x) - -void test2(id p) { - RELEASE_MACRO(p); - RELEASE_MACRO2(p); -} - -@implementation Foo2 - -static id internal_var = 0; - -+ (void)setIt:(id)newone { - if (internal_var != newone) { - [internal_var release]; - internal_var = [newone retain]; - } -} -@end diff --git a/clang/test/ARCMT/releases.m.result b/clang/test/ARCMT/releases.m.result deleted file mode 100644 index 261175362b9bdf..00000000000000 --- a/clang/test/ARCMT/releases.m.result +++ /dev/null @@ -1,87 +0,0 @@ -// RUN: %clang_cc1 -fobjc-exceptions -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-exceptions -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil 0 - -typedef int BOOL; - -id IhaveSideEffect(void); - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -@end - -@interface NSObject {} -@end - -@interface Foo : NSObject { - id bar; -} -@property (strong) id bar; --(void)test:(id)obj; -@end - -@implementation Foo - -@synthesize bar; - --(void)test:(id)obj { - id x = self.bar; - self.bar = obj; - // do stuff with x; - - IhaveSideEffect(); - - x = 0; - - @try { - } @finally { - x = nil; - } -} - -@end - -void func(Foo *p) { -} - -@interface Baz { - id _foo; -} -@end - -@implementation Baz -@end - -void block_test(Foo *p) { - id (^B)(void) = ^(void) { - if (p) { - id (^IB)(void) = ^(void) { - id bar = p; - return bar; - }; - IB(); - } - return p; - }; -} - -#define RELEASE_MACRO(x) [x release] -#define RELEASE_MACRO2(x) RELEASE_MACRO(x) - -void test2(id p) { -} - -@implementation Foo2 - -static id internal_var = 0; - -+ (void)setIt:(id)newone { - if (internal_var != newone) { - internal_var = newone; - } -} -@end diff --git a/clang/test/ARCMT/remap-applying.c b/clang/test/ARCMT/remap-applying.c deleted file mode 100644 index dee2e391d5bd5b..00000000000000 --- a/clang/test/ARCMT/remap-applying.c +++ /dev/null @@ -1,4 +0,0 @@ -a bc - -// RUN: echo "[{\"file\": \"%/s\", \"offset\": 1, \"remove\": 2, }]" > %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result diff --git a/clang/test/ARCMT/remap-applying.c.result b/clang/test/ARCMT/remap-applying.c.result deleted file mode 100644 index 514e9c264915d9..00000000000000 --- a/clang/test/ARCMT/remap-applying.c.result +++ /dev/null @@ -1,4 +0,0 @@ -ac - -// RUN: echo "[{\"file\": \"%/s\", \"offset\": 1, \"remove\": 2, }]" > %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result diff --git a/clang/test/ARCMT/remove-dealloc-method.m b/clang/test/ARCMT/remove-dealloc-method.m deleted file mode 100644 index 8e39fc874c950c..00000000000000 --- a/clang/test/ARCMT/remove-dealloc-method.m +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil ((void*) 0) - -@interface Foo -@property (retain) id x; -@property (retain) id y; -@property (retain) id w; -@property (retain) id z; -@end - -@implementation Foo -@synthesize x; -@synthesize y; -@synthesize w; -@synthesize z; - -- (void) dealloc { - self.x = 0; - [self setY:nil]; - w = nil; - self.z = nil; -} -@end diff --git a/clang/test/ARCMT/remove-dealloc-method.m.result b/clang/test/ARCMT/remove-dealloc-method.m.result deleted file mode 100644 index 47e31f9d249aed..00000000000000 --- a/clang/test/ARCMT/remove-dealloc-method.m.result +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil ((void*) 0) - -@interface Foo -@property (strong) id x; -@property (strong) id y; -@property (strong) id w; -@property (strong) id z; -@end - -@implementation Foo -@synthesize x; -@synthesize y; -@synthesize w; -@synthesize z; - -@end diff --git a/clang/test/ARCMT/remove-dealloc-zerouts.m b/clang/test/ARCMT/remove-dealloc-zerouts.m deleted file mode 100644 index 4176ec580c3e58..00000000000000 --- a/clang/test/ARCMT/remove-dealloc-zerouts.m +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface Foo -@property (retain) id x; -@property (retain) id y; -@property (retain) id w; -@property (retain) id z; -@property (strong) id q; -@end - -@implementation Foo -@synthesize x; -@synthesize y; -@synthesize w; -@synthesize q; -@dynamic z; - -- (void) dealloc { - self.x = self.y = self.w = 0; - self.x = 0, w = 0, y = 0; - [self setY:0]; - w = 0; - q = 0; - self.z = 0; -} -@end - -@interface Bar -@property (retain) Foo *a; -- (void) setA:(Foo*) val; -- (id) a; -@end - -@implementation Bar -- (void) dealloc { - [self setA:0]; // This is user-defined setter overriding synthesize, don't touch it. - self.a.x = 0; // every dealloc must zero out its own ivar. This patter is not recognized. -} -@synthesize a; -- (void) setA:(Foo*) val { } -- (id) a {return 0;} -@end diff --git a/clang/test/ARCMT/remove-dealloc-zerouts.m.result b/clang/test/ARCMT/remove-dealloc-zerouts.m.result deleted file mode 100644 index 9ae831abacf25c..00000000000000 --- a/clang/test/ARCMT/remove-dealloc-zerouts.m.result +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface Foo -@property (strong) id x; -@property (strong) id y; -@property (strong) id w; -@property (strong) id z; -@property (strong) id q; -@end - -@implementation Foo -@synthesize x; -@synthesize y; -@synthesize w; -@synthesize q; -@dynamic z; - -- (void) dealloc { - self.z = 0; -} -@end - -@interface Bar -@property (strong) Foo *a; -- (void) setA:(Foo*) val; -- (id) a; -@end - -@implementation Bar -- (void) dealloc { - [self setA:0]; // This is user-defined setter overriding synthesize, don't touch it. - self.a.x = 0; // every dealloc must zero out its own ivar. This patter is not recognized. -} -@synthesize a; -- (void) setA:(Foo*) val { } -- (id) a {return 0;} -@end diff --git a/clang/test/ARCMT/remove-statements.m b/clang/test/ARCMT/remove-statements.m deleted file mode 100644 index 286a8e715e0d3f..00000000000000 --- a/clang/test/ARCMT/remove-statements.m +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface myController : NSObject --(id)test:(id)x; -@end - -#define MY_MACRO1(x) -#define MY_MACRO2(x) (void)x - -@implementation myController --(id) test:(id) x { - [[x retain] release]; - return [[x retain] autorelease]; -} - --(void)dealloc -{ - id array, array_already_empty; - for (id element in array_already_empty) { - } - - [array release]; - ; - - int b, b_array_already_empty; - if (b) - [array release]; - if (b_array_already_empty) ; - - if (b) { - [array release]; - } - if (b_array_already_empty) { - } - - if (b) - MY_MACRO1(array); - if (b) - MY_MACRO2(array); -} -@end diff --git a/clang/test/ARCMT/remove-statements.m.result b/clang/test/ARCMT/remove-statements.m.result deleted file mode 100644 index 6a4ea08b8c95b4..00000000000000 --- a/clang/test/ARCMT/remove-statements.m.result +++ /dev/null @@ -1,38 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface myController : NSObject --(id)test:(id)x; -@end - -#define MY_MACRO1(x) -#define MY_MACRO2(x) (void)x - -@implementation myController --(id) test:(id) x { - return x; -} - --(void)dealloc -{ - id array, array_already_empty; - for (id element in array_already_empty) { - } - - ; - - int b, b_array_already_empty; - if (b_array_already_empty) ; - - if (b_array_already_empty) { - } - - if (b) - MY_MACRO1(array); - if (b) - MY_MACRO2(array); -} -@end diff --git a/clang/test/ARCMT/retains.m b/clang/test/ARCMT/retains.m deleted file mode 100644 index 43a94fc16cecf2..00000000000000 --- a/clang/test/ARCMT/retains.m +++ /dev/null @@ -1,71 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -id IhaveSideEffect(void); - -@interface Foo : NSObject { - id bar; -} -@property (retain) id bar; --(id)test:(id)obj; --(id)something; -@end - -#define Something_Macro(key, comment) \ - [[Foo new] something] - -@implementation Foo - -@synthesize bar; - --(id)something {} - --(id)test:(id)obj { - id x = self.bar; - [x retain]; - self.bar = obj; - if (obj) - [obj retain]; - - [Something_Macro(@"foo", "@bar") retain]; - - [IhaveSideEffect() retain]; - - [[self something] retain]; - - [[self retain] something]; - - [[IhaveSideEffect() retain] release]; - [[x retain] release]; - // do stuff with x; - [x release]; - return [self retain]; -} - -- (id)test1 { - id x=0; - ([x retain]); - return ((([x retain]))); -} -@end - -id foo (Foo *p) { - p = [p retain]; - return ([p retain]); -} - -void block_tests(Foo *p) { - id (^B)(void) = ^(void) { - if (p) { - id (^IB)(void) = ^(void) { - id bar = [p retain]; - return bar; - }; - IB(); - } - return [p retain]; - }; -} diff --git a/clang/test/ARCMT/retains.m.result b/clang/test/ARCMT/retains.m.result deleted file mode 100644 index 4e720d6bb4c112..00000000000000 --- a/clang/test/ARCMT/retains.m.result +++ /dev/null @@ -1,65 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -id IhaveSideEffect(void); - -@interface Foo : NSObject { - id bar; -} -@property (strong) id bar; --(id)test:(id)obj; --(id)something; -@end - -#define Something_Macro(key, comment) \ - [[Foo new] something] - -@implementation Foo - -@synthesize bar; - --(id)something {} - --(id)test:(id)obj { - id x = self.bar; - self.bar = obj; - - Something_Macro(@"foo", "@bar"); - - IhaveSideEffect(); - - [self something]; - - [self something]; - - IhaveSideEffect(); - // do stuff with x; - return self; -} - -- (id)test1 { - id x=0; - return (((x))); -} -@end - -id foo (Foo *p) { - p = p; - return (p); -} - -void block_tests(Foo *p) { - id (^B)(void) = ^(void) { - if (p) { - id (^IB)(void) = ^(void) { - id bar = p; - return bar; - }; - IB(); - } - return p; - }; -} diff --git a/clang/test/ARCMT/rewrite-block-var.m b/clang/test/ARCMT/rewrite-block-var.m deleted file mode 100644 index eb3c5b65359718..00000000000000 --- a/clang/test/ARCMT/rewrite-block-var.m +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -fobjc-arc -x objective-c -fobjc-runtime-has-weak %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fblocks -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface Foo : NSObject --(Foo *)something; -@end - -void bar(void (^block)(void)); - -void test1(Foo *p) { - __block Foo *x = p; // __block used just to break cycle. - bar(^{ - [x something]; - }); -} - -void test2(Foo *p) { - __block Foo *x; // __block used as output variable. - bar(^{ - x = [p something]; - }); -} - -void test3(Foo *p) { - __block Foo *x; // __block used as output variable. - bar(^{ - [x something]; - }); - bar(^{ - x = 0; - }); -} - -void test4(Foo *p) { - __block Foo *x = p; // __block used just to break cycle. - bar(^{ - [x something]; - }); - bar(^{ - [x something]; - }); -} diff --git a/clang/test/ARCMT/rewrite-block-var.m.result b/clang/test/ARCMT/rewrite-block-var.m.result deleted file mode 100644 index cf5718fbd7f5de..00000000000000 --- a/clang/test/ARCMT/rewrite-block-var.m.result +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -fobjc-arc -x objective-c -fobjc-runtime-has-weak %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fblocks -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface Foo : NSObject --(Foo *)something; -@end - -void bar(void (^block)(void)); - -void test1(Foo *p) { - __weak Foo *x = p; // __block used just to break cycle. - bar(^{ - [x something]; - }); -} - -void test2(Foo *p) { - __block Foo *x; // __block used as output variable. - bar(^{ - x = [p something]; - }); -} - -void test3(Foo *p) { - __block Foo *x; // __block used as output variable. - bar(^{ - [x something]; - }); - bar(^{ - x = 0; - }); -} - -void test4(Foo *p) { - __weak Foo *x = p; // __block used just to break cycle. - bar(^{ - [x something]; - }); - bar(^{ - [x something]; - }); -} diff --git a/clang/test/ARCMT/safe-arc-assign.m b/clang/test/ARCMT/safe-arc-assign.m deleted file mode 100644 index 4a0a575794e162..00000000000000 --- a/clang/test/ARCMT/safe-arc-assign.m +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -void test12(id collection) { - for (id x in collection) { - x = 0; - x = 0; - } - - for (__strong id x in collection) { - x = 0; - } -} diff --git a/clang/test/ARCMT/safe-arc-assign.m.result b/clang/test/ARCMT/safe-arc-assign.m.result deleted file mode 100644 index c25955ea7d1c90..00000000000000 --- a/clang/test/ARCMT/safe-arc-assign.m.result +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -void test12(id collection) { - for (__strong id x in collection) { - x = 0; - x = 0; - } - - for (__strong id x in collection) { - x = 0; - } -} diff --git a/clang/test/ARCMT/verify.m b/clang/test/ARCMT/verify.m deleted file mode 100644 index 7d245fe80575e5..00000000000000 --- a/clang/test/ARCMT/verify.m +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify %s -// RUN: not %clang_cc1 -arcmt-action=check -verify %t.invalid 2>&1 | FileCheck %s - -#if 0 -// expected-error {{should be ignored}} -#endif - -#error should not be ignored -// expected-error@-1 {{should not be ignored}} - -#error -// expected-error@-1 {{}} - -// CHECK: error: no expected directives found: consider use of 'expected-no-diagnostics' -// CHECK-NEXT: error: 'expected-error' diagnostics seen but not expected: -// CHECK-NEXT: (frontend): error reading '{{.*}}verify.m.tmp.invalid' -// CHECK-NEXT: 2 errors generated. diff --git a/clang/test/ARCMT/with-arc-mode-modify.m b/clang/test/ARCMT/with-arc-mode-modify.m deleted file mode 100644 index beff6784bbbb07..00000000000000 --- a/clang/test/ARCMT/with-arc-mode-modify.m +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: cat %s > %t -// RUN: %clang_cc1 -arcmt-action=modify -fsyntax-only -fobjc-arc -x objective-c %t -// RUN: diff %t %s.result -// RUN: rm %t - -@protocol NSObject -- (oneway void)release; -@end - -void test1(id p) { - [p release]; -} diff --git a/clang/test/ARCMT/with-arc-mode-modify.m.result b/clang/test/ARCMT/with-arc-mode-modify.m.result deleted file mode 100644 index 685226db865415..00000000000000 --- a/clang/test/ARCMT/with-arc-mode-modify.m.result +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: cat %s > %t -// RUN: %clang_cc1 -arcmt-action=modify -fsyntax-only -fobjc-arc -x objective-c %t -// RUN: diff %t %s.result -// RUN: rm %t - -@protocol NSObject -- (oneway void)release; -@end - -void test1(id p) { -} diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index 5369dc92f69e8a..56356ddc71ccdf 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -5,7 +5,6 @@ llvm_canonicalize_cmake_booleans( CLANG_BUILD_EXAMPLES CLANG_BUILT_STANDALONE CLANG_DEFAULT_PIE_ON_LINUX - CLANG_ENABLE_ARCMT CLANG_ENABLE_STATIC_ANALYZER CLANG_PLUGIN_SUPPORT CLANG_SPAWN_CC1 @@ -84,7 +83,7 @@ list(APPEND CLANG_TEST_DEPS diagtool hmaptool ) - + if(CLANG_ENABLE_STATIC_ANALYZER) list(APPEND CLANG_TEST_DEPS clang-check @@ -92,13 +91,6 @@ if(CLANG_ENABLE_STATIC_ANALYZER) ) endif() -if (CLANG_ENABLE_ARCMT) - list(APPEND CLANG_TEST_DEPS - arcmt-test - c-arcmt-test - ) -endif () - if(CLANG_BUILD_EXAMPLES AND CLANG_PLUGIN_SUPPORT) list(APPEND CLANG_TEST_DEPS Attribute diff --git a/clang/test/ClangScanDeps/strip-input-args.m b/clang/test/ClangScanDeps/strip-input-args.m index e1954ecc289144..31f634dd80131b 100644 --- a/clang/test/ClangScanDeps/strip-input-args.m +++ b/clang/test/ClangScanDeps/strip-input-args.m @@ -11,11 +11,6 @@ // CHECK: "modules": [ // CHECK-NEXT: { -// CHECK: "command-line": [ -// CHECK-NOT: "-arcmt-action=check" -// CHECK-NOT: "-objcmt-migrate-literals" -// CHECK-NOT: "-mt-migrate-directory" -// CHECK: ] // CHECK: "name": "A" // CHECK: } // CHECK-NOT: "name": "A" @@ -25,12 +20,12 @@ [ { "directory": "DIR", - "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -ccc-arcmt-check -fsyntax-only DIR/t1.m", + "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -fsyntax-only DIR/t1.m", "file": "DIR/t1.m" }, { "directory": "DIR", - "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -ccc-objcmt-migrate bob -fsyntax-only DIR/t2.m", + "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -fsyntax-only DIR/t2.m", "file": "DIR/t2.m" } ] diff --git a/clang/test/Driver/objc-sdk-migration-options.m b/clang/test/Driver/objc-sdk-migration-options.m deleted file mode 100644 index 8f7e5c72a3cffe..00000000000000 --- a/clang/test/Driver/objc-sdk-migration-options.m +++ /dev/null @@ -1,8 +0,0 @@ -// Check miscellaneous Objective-C sdk migration options. - -// RUN: %clang -objcmt-migrate-property-dot-syntax -target x86_64-apple-darwin10 -S -### %s \ -// RUN: -arch x86_64 2> %t -// RUN: FileCheck < %t %s - -// CHECK: "-cc1" -// CHECK: -objcmt-migrate-property-dot-syntax diff --git a/clang/test/Misc/warning-flags.c b/clang/test/Misc/warning-flags.c index 1fd02440833359..46b4e5a064c36f 100644 --- a/clang/test/Misc/warning-flags.c +++ b/clang/test/Misc/warning-flags.c @@ -18,7 +18,7 @@ This test serves two purposes: The list of warnings below should NEVER grow. It should gradually shrink to 0. -CHECK: Warnings without flags (61): +CHECK: Warnings without flags (59): CHECK-NEXT: ext_expected_semi_decl_list CHECK-NEXT: ext_missing_whitespace_after_macro_name @@ -32,7 +32,6 @@ CHECK-NEXT: pp_invalid_string_literal CHECK-NEXT: pp_out_of_date_dependency CHECK-NEXT: pp_poisoning_existing_macro CHECK-NEXT: warn_accessor_property_type_mismatch -CHECK-NEXT: warn_arcmt_nsalloc_realloc CHECK-NEXT: warn_asm_label_on_auto_decl CHECK-NEXT: warn_c_kext CHECK-NEXT: warn_call_wrong_number_of_arguments @@ -60,7 +59,6 @@ CHECK-NEXT: warn_method_param_redefinition CHECK-NEXT: warn_missing_case_for_condition CHECK-NEXT: warn_missing_dependent_template_keyword CHECK-NEXT: warn_missing_whitespace_after_macro_name -CHECK-NEXT: warn_mt_message CHECK-NEXT: warn_no_constructor_for_refconst CHECK-NEXT: warn_not_compound_assign CHECK-NEXT: warn_objc_property_copy_missing_on_block diff --git a/clang/test/Rewriter/blockcast3.mm b/clang/test/Rewriter/blockcast3.mm deleted file mode 100644 index 54ec0f5e1a7994..00000000000000 --- a/clang/test/Rewriter/blockcast3.mm +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %t.mm -o %t-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LP --input-file=%t-rw.cpp %s -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o %t-modern-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LP --input-file=%t-modern-rw.cpp %s - -typedef struct { - int a; - int b; -} mystruct; - -void g(int (^block)(mystruct s)) { - mystruct x; - int v = block(x); -} - -void f(const void **arg) { - __block const void **q = arg; - g(^(mystruct s){ - *q++ = (void*)s.a; - return 314; - }); -} - -// CHECK-LP: (__Block_byref_q_0 *)&q diff --git a/clang/test/Rewriter/blockstruct.m b/clang/test/Rewriter/blockstruct.m deleted file mode 100644 index 988e1bf02f3a90..00000000000000 --- a/clang/test/Rewriter/blockstruct.m +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %clang_cc1 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %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 - -typedef void (^b_t)(void); -void a(b_t work) { } -struct _s { - int a; -}; -struct _s *r(void); - -void f(void) { - __block struct _s *s = 0; - a(^{ - s = (struct _s *)r(); - }); -} diff --git a/clang/test/Rewriter/crash.m b/clang/test/Rewriter/crash.m deleted file mode 100644 index c8d5d786c94d49..00000000000000 --- a/clang/test/Rewriter/crash.m +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -o - %s -@interface NSArray {} -+ (id)arrayWithObjects:(id)firstObj, ...; -@end - -@interface NSConstantString {} -@end - -int main(void) { - id foo = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"12", 0]; - return 0; -} - -@protocol A -@end - -@interface Foo -@end - -void func(void) { - id obj = (id )[Foo bar]; -} - diff --git a/clang/test/Rewriter/finally.m b/clang/test/Rewriter/finally.m deleted file mode 100644 index 89ecfe0e2f6427..00000000000000 --- a/clang/test/Rewriter/finally.m +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -fobjc-exceptions -verify %s -o - - -extern int printf(const char *, ...); - -int main(void) { - @try { - printf("executing try"); - return(0); // expected-warning{{rewriter doesn't support user-specified control flow semantics for @try/@finally (code may not execute properly)}} - } @finally { - printf("executing finally"); - } - while (1) { - @try { - printf("executing try"); - break; - } @finally { - printf("executing finally"); - } - printf("executing after finally block"); - } - @try { - printf("executing try"); - } @finally { - printf("executing finally"); - } - return 0; -} - -void test_sync_with_implicit_finally(void) { - id foo; - @synchronized (foo) { - return; // The rewriter knows how to generate code for implicit finally - } -} - -void test2_try_with_implicit_finally(void) { - @try { - return; // The rewriter knows how to generate code for implicit finally - } @catch (id e) { - - } -} - diff --git a/clang/test/Rewriter/func-in-impl.m b/clang/test/Rewriter/func-in-impl.m deleted file mode 100644 index 9c4a159364f4cf..00000000000000 --- a/clang/test/Rewriter/func-in-impl.m +++ /dev/null @@ -1,30 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.m -// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile-10.5 -rewrite-objc %t.m -o - | FileCheck %s - -@interface I { - id _delegate; -} --(void)foo; -@end - -@implementation I - -static void KKKK(int w); - --(void) foo { - KKKK(0); -} - -static void KKKK(int w) { - I *self = (I *)0; - if ([self->_delegate respondsToSelector:@selector(handlePortMessage:)]) { - } -} - --(void) foo2 { - KKKK(0); -} - -@end - -// CHECK: if (((id (*)(id, SEL, ...))(void *)objc_msgSend)((id)((struct I_IMPL *)self)->_delegate, sel_registerName("respondsToSelector:"), sel_registerName("handlePortMessage:"))) diff --git a/clang/test/Rewriter/id-test-3.m b/clang/test/Rewriter/id-test-3.m deleted file mode 100644 index ec4cfe44b0c9da..00000000000000 --- a/clang/test/Rewriter/id-test-3.m +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@protocol P -- (id

) Meth: (id

) Arg; -@end - -@interface INTF

-- (id

)IMeth; -@end - -@implementation INTF -- (id

)IMeth { return [(id

)self Meth: (id

)0]; } -- (id

) Meth : (id

) Arg { return 0; } -@end diff --git a/clang/test/Rewriter/inner-block-helper-funcs.mm b/clang/test/Rewriter/inner-block-helper-funcs.mm deleted file mode 100644 index 6bbfc5fee72f40..00000000000000 --- a/clang/test/Rewriter/inner-block-helper-funcs.mm +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LP --input-file=%t-rw.cpp %s - -typedef void (^dispatch_block_t)(void); - -extern int printf(const char*, ...); - -extern "C" dispatch_block_t Block_copy(dispatch_block_t aBlock); - -int main (int argc, char *argv[]) { - - dispatch_block_t innerBlock = ^{printf("argc = %d\n", argc); }; - id innerObject = 0; - - printf("innerBlock is %x\n", innerBlock); - - dispatch_block_t wrapperBlock = ^{ - printf("innerBlock is %x %x\n", innerBlock, innerObject); - }; - - wrapperBlock(); - - dispatch_block_t copiedBlock = Block_copy(wrapperBlock); - copiedBlock(); - - return 0; -} -// CHECK-LP: _Block_object_assign((void*)&dst->innerBlock, (void*)src->innerBlock, 7 -// CHECK-LP: _Block_object_dispose((void*)src->innerBlock, 7 -// CHECK-LP: _Block_object_assign((void*)&dst->innerObject, (void*)src->innerObject, 3 -// CHECK-LP: _Block_object_dispose((void*)src->innerObject, 3 diff --git a/clang/test/Rewriter/instancetype-test.mm b/clang/test/Rewriter/instancetype-test.mm deleted file mode 100644 index 1c4a92397f8dd1..00000000000000 --- a/clang/test/Rewriter/instancetype-test.mm +++ /dev/null @@ -1,77 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -void *sel_registerName(const char *); - -@interface Root -+ (instancetype)alloc; -- (instancetype)init; // expected-note{{overridden method is part of the 'init' method family}} -- (instancetype)self; -- (Class)class; - -@property (assign) Root *selfProp; -- (instancetype)selfProp; -@end - -@protocol Proto1 -@optional -- (instancetype)methodInProto1; -@end - -@protocol Proto2 -@optional -- (instancetype)methodInProto2; // expected-note{{overridden method returns an instance of its class type}} -- (instancetype)otherMethodInProto2; // expected-note{{overridden method returns an instance of its class type}} -@end - -@interface Subclass1 : Root -- (instancetype)initSubclass1; -- (void)methodOnSubclass1; -+ (instancetype)allocSubclass1; -@end - -@interface Subclass2 : Root -- (instancetype)initSubclass2; -- (void)methodOnSubclass2; -@end - -// Check the basic initialization pattern. -void test_instancetype_alloc_init_simple() { - Root *r1 = [[Root alloc] init]; - Subclass1 *sc1 = [[Subclass1 alloc] init]; -} - -// Test that message sends to instancetype methods have the right type. -void test_instancetype_narrow_method_search() { - // instancetype on class methods - Subclass1 *sc1 = [[Subclass1 alloc] initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}} - Subclass2 *sc2 = [[Subclass2 alloc] initSubclass2]; // okay - - // instancetype on instance methods - [[[Subclass1 alloc] init] methodOnSubclass2]; // expected-warning{{'Subclass1' may not respond to 'methodOnSubclass2'}} - [[[Subclass2 alloc] init] methodOnSubclass2]; - - // instancetype on class methods using protocols - [[Subclass1 alloc] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} - [[Subclass1 alloc] methodInProto2]; - - // instancetype on instance methods - Subclass1 *sc1proto1 = 0; - [[sc1proto1 self] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} - Subclass1 *sc1proto2 = 0; - [[sc1proto2 self] methodInProto2]; - - // Exact type checks - // Message sends to Class. - // FIXME. This is not supported due to missing capability in rewriter and not due to instancetype issues - // Subclass1 *sc1proto1_2 = [[[sc1proto1 class] alloc] init]; - - // Property access - [sc1proto1.self methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} - [sc1proto2.self methodInProto2]; - - [sc1proto1.selfProp methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} - [sc1proto2.selfProp methodInProto2]; -} diff --git a/clang/test/Rewriter/ivar-encoding-1.m b/clang/test/Rewriter/ivar-encoding-1.m deleted file mode 100644 index 3f5543e4cd15cd..00000000000000 --- a/clang/test/Rewriter/ivar-encoding-1.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@interface Intf -{ - id ivar; - id ivar1[12]; - - id **ivar3; - - id (*ivar4) (id, id); -} -@end - -@implementation Intf -@end diff --git a/clang/test/Rewriter/ivar-encoding-2.m b/clang/test/Rewriter/ivar-encoding-2.m deleted file mode 100644 index 422568bf479c4c..00000000000000 --- a/clang/test/Rewriter/ivar-encoding-2.m +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@implementation Intf -{ - id ivar; - id ivar1[12]; - - id **ivar3; - - id (*ivar4) (id, id); -} -@end diff --git a/clang/test/Rewriter/line-generation-test.m b/clang/test/Rewriter/line-generation-test.m deleted file mode 100644 index 063244fbfd58dc..00000000000000 --- a/clang/test/Rewriter/line-generation-test.m +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -fms-extensions -rewrite-objc -debug-info-kind=limited %t.mm -o %t-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LINE --input-file=%t-rw.cpp %s -// RUN: %clang_cc1 -fms-extensions -rewrite-objc %t.mm -o %t-rwnog.cpp -// RUN: FileCheck -check-prefix CHECK-NOLINE --input-file=%t-rwnog.cpp %s - -__attribute__((objc_root_class)) @interface MyObject { -@public - id _myLeader; - id _isTickledPink; -} -@property(retain) id myLeader; -@property(assign) id isTickledPink; -@end - -@implementation MyObject - -@synthesize myLeader = _myLeader; -@synthesize isTickledPink = _isTickledPink; - -- (void) doSomething { - _myLeader = _isTickledPink; -} - -@end - -MyObject * foo () -{ - MyObject* p; - p.isTickledPink = p.myLeader; // ok - p->_isTickledPink = p->_myLeader; - return p->_isTickledPink; -} - -// CHECK-LINE: #line 21 -// CHECK-LINE: #line 27 -// CHECK-NOLINE-NOT: #line 21 -// CHECK-NOLINE-NOT: #line 27 - diff --git a/clang/test/Rewriter/lit.local.cfg b/clang/test/Rewriter/lit.local.cfg deleted file mode 100644 index f5e1d0349f52dc..00000000000000 --- a/clang/test/Rewriter/lit.local.cfg +++ /dev/null @@ -1,3 +0,0 @@ -# The Objective-C rewriters are currently grouped with ARCMT. -if not config.root.clang_arcmt: - config.unsupported = True diff --git a/clang/test/Rewriter/metadata-test-1.m b/clang/test/Rewriter/metadata-test-1.m deleted file mode 100644 index caa7ca3b54e33c..00000000000000 --- a/clang/test/Rewriter/metadata-test-1.m +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@interface Intf -@end - -@implementation Intf(Category) -- (void) CatMeth {} -@end - -@implementation Another -- (void) CatMeth {} -@end diff --git a/clang/test/Rewriter/metadata-test-2.m b/clang/test/Rewriter/metadata-test-2.m deleted file mode 100644 index 3ffda5809c5330..00000000000000 --- a/clang/test/Rewriter/metadata-test-2.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -typedef struct _NSPoint { - float x; - float y; -} NSPoint; - -@interface Intf -- (void) MyMeth : (NSPoint) Arg1; -@end - -@implementation Intf -- (void) MyMeth : (NSPoint) Arg1{} -@end - diff --git a/clang/test/Rewriter/method-encoding-1.m b/clang/test/Rewriter/method-encoding-1.m deleted file mode 100644 index 2cd309ee9b98af..00000000000000 --- a/clang/test/Rewriter/method-encoding-1.m +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@protocol P1 -- (void) MyProtoMeth : (int **) arg1 : (void*) arg2; -+ (void) MyProtoMeth : (int **) arg1 : (void*) arg2; -@end - -@interface Intf -- (char *) MyMeth : (double) arg1 : (char *[12]) arg2; -- (id) address:(void *)location with:(unsigned **)arg2; -@end - -@implementation Intf -- (char *) MyMeth : (double) arg1 : (char *[12]) arg2{ return 0; } -- (void) MyProtoMeth : (int **) arg1 : (void*) arg2 {} -+ (void) MyProtoMeth : (int **) arg1 : (void*) arg2 {} -- (id) address:(void *)location with:(unsigned **)arg2{ return 0; } -@end diff --git a/clang/test/Rewriter/modern-write-bf-abi.mm b/clang/test/Rewriter/modern-write-bf-abi.mm deleted file mode 100644 index fa127f0b13bd75..00000000000000 --- a/clang/test/Rewriter/modern-write-bf-abi.mm +++ /dev/null @@ -1,119 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -// -Did="void*" -DSEL="void *" -DClass="void*" -@interface NSMutableArray { - id isa; -} -@end - -typedef unsigned char BOOL; -typedef unsigned long NSUInteger; - -__attribute__((visibility("hidden"))) -@interface __NSArrayM : NSMutableArray { - NSUInteger _used; - NSUInteger _doHardRetain:1; - NSUInteger _doWeakAccess:1; -#if __LP64__ - NSUInteger _size:62; -#else - NSUInteger _size:30; -#endif - NSUInteger _hasObjects:1; - NSUInteger _hasStrongReferences:1; -#if __LP64__ - NSUInteger _offset:62; -#else - NSUInteger _offset:30; -#endif - unsigned long _mutations; - id *_list; -} -@end - - -id __CFAllocateObject2(); -BOOL objc_collectingEnabled(); - -@implementation __NSArrayM -+ (id)__new:(const id [])objects :(NSUInteger)count :(BOOL)hasObjects :(BOOL)hasStrong :(BOOL)transferRetain { - __NSArrayM *newArray = (__NSArrayM *)__CFAllocateObject2(); - newArray->_size = count; - newArray->_mutations = 1; - newArray->_doHardRetain = (hasObjects && hasStrong); - newArray->_doWeakAccess = (objc_collectingEnabled() && !hasStrong); - newArray->_hasObjects = hasObjects; - newArray->_hasStrongReferences = hasStrong; - newArray->_list = 0; - return *newArray->_list; -} -@end - -// Test2 -@interface Super { - int ivar_super_a : 5; -} -@end - -@interface A : Super { -@public - int ivar_a : 5; -} -@end - -int f0(A *a) { - return a->ivar_a; -} - -@interface A () { -@public - int ivar_ext_a : 5; - int ivar_ext_b : 5; -}@end - -int f1(A *a) { - return a->ivar_ext_a + a->ivar_a; -} - -@interface A () { -@public - int ivar_ext2_a : 5; - int ivar_ext2_b : 5; -}@end - -int f2(A* a) { - return a->ivar_ext2_a + a->ivar_ext_a + a->ivar_a; -} - -@implementation A { -@public - int ivar_b : 5; - int ivar_c : 5; - int ivar_d : 5; -} -@end - -int f3(A *a) { - return a->ivar_d + a->ivar_ext2_a + a->ivar_ext_a + a->ivar_a; -} - -__attribute__((objc_root_class)) @interface Base -{ - struct objc_class *isa; - int full; - int full2: 32; - int _refs: 8; - int field2: 3; - unsigned f3: 8; - short cc; - unsigned g: 16; - int r2: 8; - int r3: 8; - int r4: 2; - int r5: 8; - char c; -} -@end - -@implementation Base @end diff --git a/clang/test/Rewriter/no-integrated-preprocessing-64bit.m b/clang/test/Rewriter/no-integrated-preprocessing-64bit.m deleted file mode 100644 index 81afe2eb438b99..00000000000000 --- a/clang/test/Rewriter/no-integrated-preprocessing-64bit.m +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: %clang -target x86_64-unknown-unknown -fms-extensions -rewrite-objc %s -o - | FileCheck %s - -#ifdef __cplusplus - -void *sel_registerName(const char *); - -@interface Root @end - -@interface MYINTF : Root -@end - -#endif - -@implementation MYINTF -- (id) MYMETH { return [self MYMETH]; } -@end - -int main() { -} - -// CHECK: static struct _class_ro_t _OBJC_CLASS_RO_$_MYINTF -// CHECK-NEXT: 0, 0, 0, -// CHECK-NEXT: (unsigned int)0, -// CHECK-NEXT: 0, -// CHECK-NEXT: "MYINTF", diff --git a/clang/test/Rewriter/no-integrated-preprocessing.m b/clang/test/Rewriter/no-integrated-preprocessing.m deleted file mode 100644 index c53c6601b3709a..00000000000000 --- a/clang/test/Rewriter/no-integrated-preprocessing.m +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: %clang -target i386-unknown-unknown -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: FileCheck %s < %t-rw.cpp - -#ifdef __cplusplus - -void *sel_registerName(const char *); - -@interface Root @end - -@interface MYINTF : Root -@end - -#endif - -@implementation MYINTF -- (id) MYMETH { return [self MYMETH]; } -@end - -int main() { -} - -// CHECK: static struct _class_ro_t _OBJC_CLASS_RO_$_MYINTF -// CHECK-NEXT: 0, 0, 0, -// CHECK-NEXT: 0, -// CHECK-NEXT: "MYINTF", diff --git a/clang/test/Rewriter/objc-bool-literal-check-modern.mm b/clang/test/Rewriter/objc-bool-literal-check-modern.mm deleted file mode 100644 index 12eaafe7c8e166..00000000000000 --- a/clang/test/Rewriter/objc-bool-literal-check-modern.mm +++ /dev/null @@ -1,28 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s - -typedef bool BOOL; - -BOOL yes() { - return __objc_yes; -} - -BOOL no() { - return __objc_no; -} - -BOOL which (int flag) { - return flag ? yes() : no(); -} - -int main() { - which (__objc_yes); - which (__objc_no); - return __objc_yes; -} - -// CHECK: return ((bool)1); -// CHECK: return ((bool)0); -// CHECK: which (((bool)1)); -// CHECK: which (((bool)0)); -// CHECK: return ((bool)1); diff --git a/clang/test/Rewriter/objc-bool-literal-modern-1.mm b/clang/test/Rewriter/objc-bool-literal-modern-1.mm deleted file mode 100644 index a5933825f04816..00000000000000 --- a/clang/test/Rewriter/objc-bool-literal-modern-1.mm +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"__declspec(X)=" %t-rw.cpp - -typedef unsigned long size_t; - -typedef bool BOOL; - -BOOL yes() { - return __objc_yes; -} - -BOOL no() { - return __objc_no; -} - -BOOL which (int flag) { - return flag ? yes() : no(); -} - -int main() { - which (__objc_yes); - which (__objc_no); - return __objc_yes; -} - -void y(BOOL (^foo)()); - -void x() { - y(^{ - return __objc_yes; - }); -} diff --git a/clang/test/Rewriter/objc-bool-literal-modern.mm b/clang/test/Rewriter/objc-bool-literal-modern.mm deleted file mode 100644 index c84ff931038140..00000000000000 --- a/clang/test/Rewriter/objc-bool-literal-modern.mm +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -D"__declspec(X)=" %t-rw.cpp - -typedef bool BOOL; - -BOOL yes() { - return __objc_yes; -} - -BOOL no() { - return __objc_no; -} - -BOOL which (int flag) { - return flag ? yes() : no(); -} - -int main() { - which (__objc_yes); - which (__objc_no); - return __objc_yes; -} diff --git a/clang/test/Rewriter/objc-encoding-bug-1.m b/clang/test/Rewriter/objc-encoding-bug-1.m deleted file mode 100644 index 55e980493c2905..00000000000000 --- a/clang/test/Rewriter/objc-encoding-bug-1.m +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -typedef struct NSMethodFrameArgInfo { - struct NSMethodFrameArgInfo *subInfo; - struct NSMethodFrameArgInfo *an; -} NSMethodFrameArgInfo; - -@interface NSMethodSignature -- (NSMethodFrameArgInfo *)_argInfo; -@end - -@implementation NSMethodSignature - -- (NSMethodFrameArgInfo *)_argInfo{ - return 0; -} - -@end - diff --git a/clang/test/Rewriter/objc-ivar-receiver-1.m b/clang/test/Rewriter/objc-ivar-receiver-1.m deleted file mode 100644 index 6cccf88d104cfc..00000000000000 --- a/clang/test/Rewriter/objc-ivar-receiver-1.m +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - | grep 'newInv->_container' - -@interface NSMutableArray -- (void)addObject:(id)addObject; -@end - -@interface NSInvocation { -@private - id _container; -} -+ (NSInvocation *)invocationWithMethodSignature; - -@end - -@implementation NSInvocation - -+ (NSInvocation *)invocationWithMethodSignature { - NSInvocation *newInv; - id obj = newInv->_container; - [newInv->_container addObject:0]; - return 0; -} -@end diff --git a/clang/test/Rewriter/objc-modern-StretAPI-2.mm b/clang/test/Rewriter/objc-modern-StretAPI-2.mm deleted file mode 100644 index 6ac361b9a1f845..00000000000000 --- a/clang/test/Rewriter/objc-modern-StretAPI-2.mm +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -extern "C" void *sel_registerName(const char *); -typedef unsigned long size_t; - -typedef unsigned long NSUInteger; -typedef struct _NSRange { - NSUInteger location; - NSUInteger length; -} NSRange; - - -@interface NSIndexSet -- (NSRange)rangeAtIndex:(NSUInteger)rangeIndex; -@end - -@interface NSArray -@end - -@implementation NSArray -- (NSArray *)objectsAtIndexes:(NSIndexSet *)iset { - - NSUInteger ridx = 0; - NSRange range = [iset rangeAtIndex:ridx]; - return 0; -} -@end - diff --git a/clang/test/Rewriter/objc-modern-StretAPI-3.mm b/clang/test/Rewriter/objc-modern-StretAPI-3.mm deleted file mode 100644 index a2c878646a5a33..00000000000000 --- a/clang/test/Rewriter/objc-modern-StretAPI-3.mm +++ /dev/null @@ -1,57 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -extern "C" void *sel_registerName(const char *); -typedef unsigned long size_t; - -typedef struct { - unsigned long long x; - unsigned long long y; -} myPoint; - -typedef struct { - unsigned long long x; - unsigned long long y; -} allPoint; - -@interface Obj -+ (myPoint)foo; -+ (myPoint)foo : (int)Arg1 : (double)fArg; -+ (allPoint)fee; -@end - -@implementation Obj -+ (allPoint)fee { - allPoint a; - a.x = a.y = 3; - - return a; -} -+ (myPoint)foo { - myPoint r; - r.x = 1; - r.y = 2; - return r; -} - -+ (myPoint)foo : (int)Arg1 : (double)fArg { - myPoint r; - return r; -} -@end - -myPoint Ret_myPoint() { - return [Obj foo]; -} - -allPoint Ret_allPoint() { - return [Obj fee]; -} - -myPoint Ret_myPoint1(int i, double d) { - return [Obj foo:i:d]; -} - -myPoint Ret_myPoint2() { - return [Obj foo]; -} diff --git a/clang/test/Rewriter/objc-modern-StretAPI.mm b/clang/test/Rewriter/objc-modern-StretAPI.mm deleted file mode 100644 index 618c229fafde99..00000000000000 --- a/clang/test/Rewriter/objc-modern-StretAPI.mm +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -extern "C" void *sel_registerName(const char *); -typedef unsigned long size_t; - -union U { - double d1; - char filler[32]; -}; - -struct S { - char filler[128]; -}; - -@interface I -- (struct S) Meth : (int) arg1 : (id) arg2; -- (struct S) Meth1; -- (union U) Meth2 : (double)d; -- (struct S) VAMeth : (int)anchor, ...; -@end - -I* PI(); - -extern "C" { - -struct S foo () { - struct S s = [PI() Meth : 1 : (id)0]; - - U u = [PI() Meth2 : 3.14]; - - S s1 = [PI() VAMeth : 12, 13.4, 1000, "hello"]; - - S s2 = [PI() VAMeth : 12]; - - S s3 = [PI() VAMeth : 0, "hello", "there"]; - - S s4 = [PI() VAMeth : 2, ^{}, &foo]; - - return [PI() Meth1]; -} - -} - diff --git a/clang/test/Rewriter/objc-modern-boxing.mm b/clang/test/Rewriter/objc-modern-boxing.mm deleted file mode 100644 index 22d092fecd664a..00000000000000 --- a/clang/test/Rewriter/objc-modern-boxing.mm +++ /dev/null @@ -1,72 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Werror -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp -Wno-attributes - -extern char *strdup(const char *str); -extern "C" void *sel_registerName(const char *); - -typedef signed char BOOL; -typedef long NSInteger; -typedef unsigned long NSUInteger; - -#if __has_feature(objc_bool) -#define YES __objc_yes -#define NO __objc_no -#else -#define YES ((BOOL)1) -#define NO ((BOOL)0) -#endif - -@interface NSNumber -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value ; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ; -@end - -@interface NSString -+ (id)stringWithUTF8String:(const char *)str; -@end - -int main(int argc, const char *argv[]) { - // character. - NSNumber *theLetterZ = @('Z'); // equivalent to [NSNumber numberWithChar:('Z')] - - // integral. - NSNumber *fortyTwo = @(42); // equivalent to [NSNumber numberWithInt:(42)] - NSNumber *fortyTwoUnsigned = @(42U); // equivalent to [NSNumber numberWithUnsignedInt:(42U)] - NSNumber *fortyTwoLong = @(42L); // equivalent to [NSNumber numberWithLong:(42L)] - NSNumber *fortyTwoLongLong = @(42LL); // equivalent to [NSNumber numberWithLongLong:(42LL)] - - // floating point. - NSNumber *piFloat = @(3.141592654F); // equivalent to [NSNumber numberWithFloat:(3.141592654F)] - NSNumber *piDouble = @(3.1415926535); // equivalent to [NSNumber numberWithDouble:(3.1415926535)] - - BOOL b; - NSNumber *nsb = @(b); - - // Strings. - NSString *duplicateString = @(strdup("Hello")); -} - -// CHECK: NSNumber *theLetterZ = ((NSNumber *(*)(Class, SEL, char))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithChar:"), ('Z')); -// CHECK: NSNumber *fortyTwo = ((NSNumber *(*)(Class, SEL, int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithInt:"), (42)); -// CHECK: NSNumber *fortyTwoUnsigned = ((NSNumber *(*)(Class, SEL, unsigned int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithUnsignedInt:"), (42U)); -// CHECK: NSNumber *fortyTwoLong = ((NSNumber *(*)(Class, SEL, long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLong:"), (42L)); -// CHECK: NSNumber *fortyTwoLongLong = ((NSNumber *(*)(Class, SEL, long long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLongLong:"), (42LL)); -// CHECK: NSNumber *piFloat = ((NSNumber *(*)(Class, SEL, float))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithFloat:"), (3.14159274F)); -// CHECK: NSNumber *piDouble = ((NSNumber *(*)(Class, SEL, double))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithDouble:"), (3.1415926535000001)); -// CHECK: NSNumber *nsb = ((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), (BOOL)(b)); -// CHECK: NSString *duplicateString = ((NSString *(*)(Class, SEL, const char *))(void *)objc_msgSend)(objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), (const char *)(strdup("Hello"))); diff --git a/clang/test/Rewriter/objc-modern-class-init-hooks.mm b/clang/test/Rewriter/objc-modern-class-init-hooks.mm deleted file mode 100644 index 0e19268b7f0b48..00000000000000 --- a/clang/test/Rewriter/objc-modern-class-init-hooks.mm +++ /dev/null @@ -1,35 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s - -@interface Root @end - -@interface Super : Root -@end - -@interface Sub : Super -@end - -@implementation Sub @end - -@implementation Root @end - -@interface Root(Cat) @end - -@interface Sub(Cat) @end - -@implementation Root(Cat) @end - -@implementation Sub(Cat) @end - - -// CHECK: #pragma section(".objc_inithooks$B", long, read, write) -// CHECK: __declspec(allocate(".objc_inithooks$B")) static void *OBJC_CLASS_SETUP[] = { -// CHECK: (void *)&OBJC_CLASS_SETUP_$_Sub, -// CHECK: (void *)&OBJC_CLASS_SETUP_$_Root, -// CHECK: }; - -// CHECK: #pragma section(".objc_inithooks$B", long, read, write) -// CHECK: __declspec(allocate(".objc_inithooks$B")) static void *OBJC_CATEGORY_SETUP[] = { -// CHECK: (void *)&OBJC_CATEGORY_SETUP_$_Root_$_Cat, -// CHECK: (void *)&OBJC_CATEGORY_SETUP_$_Sub_$_Cat, -// CHECK: }; diff --git a/clang/test/Rewriter/objc-modern-class-init.mm b/clang/test/Rewriter/objc-modern-class-init.mm deleted file mode 100644 index 1618bae2ed353a..00000000000000 --- a/clang/test/Rewriter/objc-modern-class-init.mm +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@interface Root @end - -@interface Super : Root -@end - -@interface Sub : Super -@end - -@implementation Sub @end - -@implementation Root @end - -@interface Root(Cat) @end - -@interface Sub(Cat) @end - -@implementation Root(Cat) @end - -@implementation Sub(Cat) @end diff --git a/clang/test/Rewriter/objc-modern-container-subscript.mm b/clang/test/Rewriter/objc-modern-container-subscript.mm deleted file mode 100644 index 7c417eb9a6ef90..00000000000000 --- a/clang/test/Rewriter/objc-modern-container-subscript.mm +++ /dev/null @@ -1,48 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -typedef unsigned long size_t; - -void *sel_registerName(const char *); - -@protocol P @end - -@interface NSMutableArray -#if __has_feature(objc_subscripting) -- (id)objectAtIndexedSubscript:(size_t)index; -- (void)setObject:(id)object atIndexedSubscript:(size_t)index; -#endif -@end - -#if __has_feature(objc_subscripting) -@interface XNSMutableArray -- (id)objectAtIndexedSubscript:(size_t)index; -- (void)setObject:(id)object atIndexedSubscript:(size_t)index; -#endif -@end - -@interface NSMutableDictionary -- (id)objectForKeyedSubscript:(id)key; -- (void)setObject:(id)object forKeyedSubscript:(id)key; -@end - -@class NSString; - -int main() { - NSMutableArray

* array; - id oldObject = array[10]; - - array[10] = oldObject; - - id unknown_array; - oldObject = unknown_array[1]; - - unknown_array[1] = oldObject; - - NSMutableDictionary *dictionary; - NSString *key; - id newObject; - oldObject = dictionary[key]; - dictionary[key] = newObject; // replace oldObject with newObject -} - diff --git a/clang/test/Rewriter/objc-modern-fast-enumeration.mm b/clang/test/Rewriter/objc-modern-fast-enumeration.mm deleted file mode 100644 index 082b04747b10d7..00000000000000 --- a/clang/test/Rewriter/objc-modern-fast-enumeration.mm +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -triple i686-pc-win32 -Werror -Wno-address-of-temporary -D"Class=struct objc_class *" -D"id=struct objc_object *" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp -Wno-attributes -// RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-win32 -Werror -Wno-address-of-temporary -D"Class=struct objc_class *" -D"id=struct objc_object *" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp -Wno-attributes - -extern "C" void *sel_registerName(const char *); - -void x() { - id y; - for (id a in y) { - } -} - -// CHECK: #ifdef _WIN64 -// CHECK-NEXT: typedef unsigned long long _WIN_NSUInteger; -// CHECK-NEXT: #else -// CHECK-NEXT: typedef unsigned int _WIN_NSUInteger; -// CHECK-NEXT: #endif -// CHECK: _WIN_NSUInteger limit = -// CHECK-NEXT: ((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, id *, _WIN_NSUInteger))(void *)objc_msgSend) -// CHECK-NEXT: ((id)l_collection, -// CHECK-NEXT: sel_registerName("countByEnumeratingWithState:objects:count:"), -// CHECK-NEXT: &enumState, (id *)__rw_items, (_WIN_NSUInteger)16); diff --git a/clang/test/Rewriter/objc-modern-getclass-proto.mm b/clang/test/Rewriter/objc-modern-getclass-proto.mm deleted file mode 100644 index da417477aa12b0..00000000000000 --- a/clang/test/Rewriter/objc-modern-getclass-proto.mm +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %t.mm -o %t-rw.cpp - -@interface I @end -@implementation I @end - -// CHECK: __OBJC_RW_DLLIMPORT struct objc_class *objc_getClass(const char *); -// CHECK: __OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass(const char *); - diff --git a/clang/test/Rewriter/objc-modern-implicit-cast.mm b/clang/test/Rewriter/objc-modern-implicit-cast.mm deleted file mode 100644 index 4b852518f91202..00000000000000 --- a/clang/test/Rewriter/objc-modern-implicit-cast.mm +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -typedef void(^BL)(void); - -id return_id(void(^block)(void)) { - return block; -} - -BL return_block(id obj) { - return obj; -} - -int main() -{ - void(^block)(void); - id obj; - block = obj; // AnyPointerToBlockPointerCast - obj = block; // BlockPointerToObjCPointerCast - - id obj1 = block; - - void(^block1)(void) = obj1; - - return_id(block1); - - return_id(obj1); - - return_block(block1); - - return_block(obj1); -} diff --git a/clang/test/Rewriter/objc-modern-ivar-receiver-1.mm b/clang/test/Rewriter/objc-modern-ivar-receiver-1.mm deleted file mode 100644 index cc454f36afcfc2..00000000000000 --- a/clang/test/Rewriter/objc-modern-ivar-receiver-1.mm +++ /dev/null @@ -1,30 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s - -void *sel_registerName(const char *); - -@interface NSMutableArray -- (void)addObject:(id)addObject; -@end - -@interface NSInvocation { -@private - id _container; -} -+ (NSInvocation *)invocationWithMethodSignature; - -@end - -@implementation NSInvocation - -+ (NSInvocation *)invocationWithMethodSignature { - NSInvocation *newInv; - id obj = newInv->_container; - [newInv->_container addObject:0]; - return 0; -} -@end - -// CHECK: id obj = (*(id *)((char *)newInv + OBJC_IVAR_$_NSInvocation$_container)); -// CHECK: struct _class_t *superclass; -// CHECK: extern "C" __declspec(dllimport) struct objc_cache _objc_empty_cache; diff --git a/clang/test/Rewriter/objc-modern-linkage-spec.mm b/clang/test/Rewriter/objc-modern-linkage-spec.mm deleted file mode 100644 index 18ef0d8cabf5f1..00000000000000 --- a/clang/test/Rewriter/objc-modern-linkage-spec.mm +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-attributes -D"__declspec(X)=" %t-rw.cpp - -extern "C" __declspec(dllexport) -@interface Test @end - -@implementation Test @end - -extern "C" { -__declspec(dllexport) -@interface Test1 @end - -@implementation Test1 @end - -__declspec(dllexport) -@interface Test2 @end - -@implementation Test2 @end -}; - diff --git a/clang/test/Rewriter/objc-modern-metadata-visibility.mm b/clang/test/Rewriter/objc-modern-metadata-visibility.mm deleted file mode 100644 index 6a0c3c6fb7b7cd..00000000000000 --- a/clang/test/Rewriter/objc-modern-metadata-visibility.mm +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s - -@class NSString; - -@interface NSObject { - Class isa; -} -@end - -@interface Sub : NSObject { - int subIvar; - NSString *nsstring; -@private - id PrivateIvar; -} -@end - -@implementation Sub -- (id) MyNSString { return subIvar ? PrivateIvar : nsstring; } -@end - -@interface NSString @end -@implementation NSString @end - -// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllimport) unsigned long OBJC_IVAR_$_Sub$subIvar; -// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" unsigned long OBJC_IVAR_$_Sub$PrivateIvar; -// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllimport) unsigned long OBJC_IVAR_$_Sub$nsstring; -// CHECK: #pragma warning(disable:4273) -// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllexport) unsigned long int OBJC_IVAR_$_Sub$subIvar -// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" __declspec(dllexport) unsigned long int OBJC_IVAR_$_Sub$nsstring -// CHECK: __declspec(allocate(".objc_ivar$B")) extern "C" unsigned long int OBJC_IVAR_$_Sub$PrivateIvar -// CHECK: extern "C" __declspec(dllimport) struct _class_t OBJC_METACLASS_$_NSObject; -// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_Sub -// CHECK: extern "C" __declspec(dllimport) struct _class_t OBJC_CLASS_$_NSObject; -// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_Sub -// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_NSString; -// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_NSString -// CHECK: extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_NSString diff --git a/clang/test/Rewriter/objc-modern-numeric-literal.mm b/clang/test/Rewriter/objc-modern-numeric-literal.mm deleted file mode 100644 index 3c7582a3e4d2a9..00000000000000 --- a/clang/test/Rewriter/objc-modern-numeric-literal.mm +++ /dev/null @@ -1,68 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s - -extern "C" void *sel_registerName(const char *); - -typedef bool BOOL; -typedef long NSInteger; -typedef unsigned long NSUInteger; - -#if __has_feature(objc_bool) -#define YES __objc_yes -#define NO __objc_no -#else -#define YES ((BOOL)1) -#define NO ((BOOL)0) -#endif - -@interface NSNumber -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value ; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ; -@end - -int main(int argc, const char *argv[]) { - // character literals. - NSNumber *theLetterZ = @'Z'; // equivalent to [NSNumber numberWithChar:'Z'] - - // integral literals. - NSNumber *fortyTwo = @42; // equivalent to [NSNumber numberWithInt:42] - NSNumber *fortyTwoUnsigned = @42U; // equivalent to [NSNumber numberWithUnsignedInt:42U] - NSNumber *fortyTwoLong = @42L; // equivalent to [NSNumber numberWithLong:42L] - NSNumber *fortyTwoLongLong = @42LL; // equivalent to [NSNumber numberWithLongLong:42LL] - - // floating point literals. - NSNumber *piFloat = @3.141592654F; // equivalent to [NSNumber numberWithFloat:3.141592654F] - NSNumber *piDouble = @3.1415926535; // equivalent to [NSNumber numberWithDouble:3.1415926535] - - // BOOL literals. - NSNumber *yesNumber = @YES; // equivalent to [NSNumber numberWithBool:YES] - NSNumber *noNumber = @NO; // equivalent to [NSNumber numberWithBool:NO] - - NSNumber *trueNumber = @true; // equivalent to [NSNumber numberWithBool:(BOOL)true] - NSNumber *falseNumber = @false; // equivalent to [NSNumber numberWithBool:(BOOL)false] -} - -// CHECK: NSNumber *theLetterZ = ((NSNumber *(*)(Class, SEL, char))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithChar:"), 'Z'); -// CHECK: NSNumber *fortyTwo = ((NSNumber *(*)(Class, SEL, int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithInt:"), 42); -// CHECK: NSNumber *fortyTwoUnsigned = ((NSNumber *(*)(Class, SEL, unsigned int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithUnsignedInt:"), 42U); -// CHECK: NSNumber *fortyTwoLong = ((NSNumber *(*)(Class, SEL, long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLong:"), 42L); -// CHECK: NSNumber *fortyTwoLongLong = ((NSNumber *(*)(Class, SEL, long long))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithLongLong:"), 42LL); -// CHECK: NSNumber *piFloat = ((NSNumber *(*)(Class, SEL, float))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithFloat:"), 3.14159274F); -// CHECK: NSNumber *piDouble = ((NSNumber *(*)(Class, SEL, double))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithDouble:"), 3.1415926535000001); -// CHECK: NSNumber *yesNumber = ((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), true); -// CHECK: NSNumber *noNumber = ((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), false); -// CHECK: NSNumber *trueNumber = ((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), true); -// CHECK: NSNumber *falseNumber = ((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), false); diff --git a/clang/test/Rewriter/objc-modern-property-attributes.mm b/clang/test/Rewriter/objc-modern-property-attributes.mm deleted file mode 100644 index ea4875d6a6ad30..00000000000000 --- a/clang/test/Rewriter/objc-modern-property-attributes.mm +++ /dev/null @@ -1,55 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s - -typedef void (^void_block_t)(void); - -@interface PropertyClass { - int q; - void_block_t __completion; - PropertyClass* YVAR; - id ID; -} -@property int q; -@property int r; - -@property (copy) void_block_t completionBlock; -@property (retain) PropertyClass* Yblock; -@property (readonly) PropertyClass* readonlyAttr; -@property (readonly,copy) PropertyClass* readonlyCopyAttr; -@property (readonly,retain) PropertyClass* readonlyRetainAttr; -@property (readonly,retain,nonatomic) PropertyClass* readonlyNonatomicAttr; -@property (copy) id ID; - -@end - -@implementation PropertyClass -@synthesize q; // attributes should be "Ti,Vq" -@dynamic r; // attributes should be "Ti,D" -@synthesize completionBlock=__completion; // "T@?,C,V__completion" -@synthesize Yblock = YVAR; // "T@\"PropertyClass\",&,VYVAR" -@synthesize readonlyAttr; -@synthesize readonlyCopyAttr; -@synthesize readonlyRetainAttr; -@synthesize readonlyNonatomicAttr; -@synthesize ID; // "T@,C,VID" -@end - -// CHECK: Ti,Vq -// CHECK: Ti,D -// CHECK: T@?,C,V__completion -// CHECK: T@\"PropertyClass\",&,VYVAR -// CHECK: T@\"PropertyClass\",R,VreadonlyAttr -// CHECK: T@\"PropertyClass\",R,C,VreadonlyCopyAttr -// CHECK: T@\"PropertyClass\",R,&,VreadonlyRetainAttr -// CHECK: T@\"PropertyClass\",R,&,N,VreadonlyNonatomicAttr - -@interface Test @end -@interface Test (Category) -@property int q; -@end - -@implementation Test (Category) -@dynamic q; -@end - -// CHECK: {{"q","Ti,D"}} diff --git a/clang/test/Rewriter/objc-modern-property-bitfield.m b/clang/test/Rewriter/objc-modern-property-bitfield.m deleted file mode 100644 index f6135e7bd61a9e..00000000000000 --- a/clang/test/Rewriter/objc-modern-property-bitfield.m +++ /dev/null @@ -1,42 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -void *sel_registerName(const char *); -extern void abort(); - -@interface NSObject -+ alloc; -- init; -@end - -typedef unsigned char BOOL; - -@interface Foo : NSObject { - - BOOL _field1 : 5; - BOOL _field2 : 3; -} - -@property BOOL field1; -@property BOOL field2; -@end - -@implementation Foo - -@synthesize field1 = _field1; -@synthesize field2 = _field2; - -@end - -int main() -{ - Foo *f = (Foo*)[[Foo alloc] init]; - f.field1 = 0xF; - f.field2 = 0x3; - f.field1 = f.field1 & f.field2; - if (f.field1 != 0x3) - abort (); - return 0; -} - - diff --git a/clang/test/Rewriter/objc-string-concat-1.m b/clang/test/Rewriter/objc-string-concat-1.m deleted file mode 100644 index 9a23abcc7ff976..00000000000000 --- a/clang/test/Rewriter/objc-string-concat-1.m +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@class NSString; - -@interface NSConstantString; -@end - - - -NSConstantString *t0 = @"123"; -NSConstantString *t = @"123" @"4567"; // concat -NSConstantString *t1 = @"123" @"4567" /* COMMENT */ @"89"; // concat -NSConstantString *t2 = @"123" @/* COMMENT */ "4567"; // concat - diff --git a/clang/test/Rewriter/objc-super-test.m b/clang/test/Rewriter/objc-super-test.m deleted file mode 100644 index 68412d899b9c57..00000000000000 --- a/clang/test/Rewriter/objc-super-test.m +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - | grep objc_msgSendSuper | grep MainMethod - -typedef struct objc_selector *SEL; -typedef struct objc_object *id; - -@interface SUPER -- (int) MainMethod; -@end - -@interface MyDerived : SUPER -- (int) instanceMethod; -@end - -@implementation MyDerived -- (int) instanceMethod { - return [super MainMethod]; -} -@end diff --git a/clang/test/Rewriter/objc-synchronized-1.m b/clang/test/Rewriter/objc-synchronized-1.m deleted file mode 100644 index 9172a1316cb0f5..00000000000000 --- a/clang/test/Rewriter/objc-synchronized-1.m +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -id SYNCH_EXPR(void); -void SYNCH_BODY(void); -void SYNCH_BEFORE(void); -void SYNC_AFTER(void); - -void foo(id sem) -{ - SYNCH_BEFORE(); - @synchronized (SYNCH_EXPR()) { - SYNCH_BODY(); - return; - } - SYNC_AFTER(); - @synchronized ([sem self]) { - SYNCH_BODY(); - return; - } -} diff --git a/clang/test/Rewriter/properties.m b/clang/test/Rewriter/properties.m deleted file mode 100644 index 9943511c36e53c..00000000000000 --- a/clang/test/Rewriter/properties.m +++ /dev/null @@ -1,57 +0,0 @@ -// RUN: %clang_cc1 -triple i686-pc-windows -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -triple i686-pc-windows -fsyntax-only -fms-extensions -Wno-address-of-temporary -Did="void *" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -void *sel_registerName(const char *); - -@interface Foo { - int i; - int rrrr; - Foo *o; -} -@property int i; -@property(readonly) int rrrr; -@property int d; -@property(retain) Foo *o; - -- (void)foo; -@end - -@implementation Foo -@synthesize i; -@synthesize rrrr; -@synthesize o; - -@dynamic d; - -- (void)foo { - i = 99; -} - -- (int)bar { - return i; -} -@end - -@interface Bar { -} -@end - -@implementation Bar - -static int func(int i) { return 0; } - -- (void)baz { - Foo *obj1, *obj2; - int i; - if (obj1.i == obj2.rrrr) - obj1.i = 33; - obj1.i = func(obj2.rrrr); - obj1.i = obj2.rrrr; - obj1.i = (obj2.rrrr); - [obj1 setI:[obj2 rrrr]]; - obj1.i = [obj2 rrrr]; - obj1.i = 3 + [obj2 rrrr]; - i = obj1.o.i; - obj1.o.i = 77; -} -@end diff --git a/clang/test/Rewriter/property-dot-syntax.mm b/clang/test/Rewriter/property-dot-syntax.mm deleted file mode 100644 index bbc30e3a80b4a4..00000000000000 --- a/clang/test/Rewriter/property-dot-syntax.mm +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -void *sel_registerName(const char *); - -@class NSString; - -@protocol CoreDAVAccountInfoProvider -- (NSString *)userAgentHeader; -@end - -@interface CoreDAVTask -{ - id _accountInfoProvider; -} -- (void)METHOD; -@end - -@implementation CoreDAVTask -- (void)METHOD { - if ([_accountInfoProvider userAgentHeader]) { - } - if (_accountInfoProvider.userAgentHeader) { - } -} -@end - -@interface A { } -@property (retain) NSString *scheme; -@end - -@interface B : A { - NSString* _schemeName; -} -@end - - -@implementation B --(void) test { - B *b; - b.scheme = _schemeName; // error because of this line -} -@end - diff --git a/clang/test/Rewriter/protocol-rewrite-1.m b/clang/test/Rewriter/protocol-rewrite-1.m deleted file mode 100644 index 867f4a6b28cbbf..00000000000000 --- a/clang/test/Rewriter/protocol-rewrite-1.m +++ /dev/null @@ -1,70 +0,0 @@ -// RUN: %clang_cc1 -x objective-c -Wno-objc-root-class -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: FileCheck --input-file=%t-rw.cpp %s - -typedef struct MyWidget { - int a; -} MyWidget; - -MyWidget gWidget = { 17 }; - -@protocol MyProto -- (MyWidget *)widget; -@end - -@interface Foo -@end - -@interface Bar: Foo -@end - -@interface Container -+ (MyWidget *)elementForView:(Foo *)view; -@end - -@implementation Foo -@end - -@implementation Bar -- (MyWidget *)widget { - return &gWidget; -} -@end - -@implementation Container -+ (MyWidget *)elementForView:(Foo *)view -{ - MyWidget *widget = (void*)0; - if (@protocol(MyProto)) { - widget = [(id )view widget]; - } - return widget; -} -@end - -int main(void) { - id view; - MyWidget *w = [Container elementForView: view]; - - return 0; -} - -@class NSObject; - -@interface NSProtocolChecker -+ (id)protocolCheckerWithTarget:(NSObject *)anObject protocol:(Protocol *)aProtocol; -@end - -@protocol NSConnectionVersionedProtocol -@end - - -@interface NSConnection @end - -@implementation NSConnection -- (void) Meth { - [NSProtocolChecker protocolCheckerWithTarget:0 protocol:@protocol(NSConnectionVersionedProtocol)]; -} -@end - -// CHECK: static struct _protocol_t *_OBJC_PROTOCOL_REFERENCE_$_NSConnectionVersionedProtocol = &_OBJC_PROTOCOL_NSConnectionVersionedProtocol -// CHECK: sel_registerName("protocolCheckerWithTarget:protocol:"), (NSObject *)0, (Protocol *)_OBJC_PROTOCOL_REFERENCE_$_NSConnectionVersionedProtocol diff --git a/clang/test/Rewriter/protocol-rewrite-2.m b/clang/test/Rewriter/protocol-rewrite-2.m deleted file mode 100644 index a49168b95ca800..00000000000000 --- a/clang/test/Rewriter/protocol-rewrite-2.m +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t.cpp -// RUN: %clang_cc1 -fsyntax-only %t.cpp - -@protocol Foo; -@protocol Foo -@end diff --git a/clang/test/Rewriter/rewrite-anonymous-union.m b/clang/test/Rewriter/rewrite-anonymous-union.m deleted file mode 100644 index b5b1aa4f1f5705..00000000000000 --- a/clang/test/Rewriter/rewrite-anonymous-union.m +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -o - %s - -typedef unsigned int uint32_t; - -typedef struct { - union { - uint32_t daysOfWeek; - uint32_t dayOfMonth; - }; - uint32_t nthOccurrence; -} OSPatternSpecificData; - -@interface NSNumber -+ (NSNumber *)numberWithLong:(long)value; -@end - -@interface OSRecurrence { - OSPatternSpecificData _pts; -} -- (void)_setTypeSpecificInfoOnRecord; -@end - -@implementation OSRecurrence -- (void)_setTypeSpecificInfoOnRecord -{ - [NSNumber numberWithLong:(_pts.dayOfMonth >= 31 ? -1 : _pts.dayOfMonth)]; -} -@end - diff --git a/clang/test/Rewriter/rewrite-api-bug.m b/clang/test/Rewriter/rewrite-api-bug.m deleted file mode 100644 index f4a88ddf778236..00000000000000 --- a/clang/test/Rewriter/rewrite-api-bug.m +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@interface MyDerived -- (void) instanceMethod; -@end - -@implementation MyDerived -- (void) instanceMethod { -} -@end - diff --git a/clang/test/Rewriter/rewrite-block-argument.m b/clang/test/Rewriter/rewrite-block-argument.m deleted file mode 100644 index dbcd237f0f5c62..00000000000000 --- a/clang/test/Rewriter/rewrite-block-argument.m +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %clang_cc1 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -Wno-address-of-temporary -Did="void *" -D"SEL=void*" -D"__declspec(X)=" -emit-llvm -o %t %t-rw.cpp - -void *sel_registerName(const char *); - -@interface Test { -} -@end - -@implementation Test - -- (void)enumerateProvidersWithBlock:(void (^)(void))block { - block(); -} - -- (void)providerEnumerator { - ^(void (^providerBlock)(void)) { - [self enumerateProvidersWithBlock:providerBlock]; - }; -} - -- (void)testNilBlock { - [self enumerateProvidersWithBlock:0]; -} - -@end - - - -int main(int argc, char *argv[]) { - return 0; -} diff --git a/clang/test/Rewriter/rewrite-block-consts.mm b/clang/test/Rewriter/rewrite-block-consts.mm deleted file mode 100644 index fb29d9f23511ed..00000000000000 --- a/clang/test/Rewriter/rewrite-block-consts.mm +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D__block="" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -void x(int y) {} -void f() { - const int bar = 3; - int baz = 4; - __block int bab = 4; - __block const int bas = 5; - void (^b)() = ^{ - x(bar); - x(baz); - x(bab); - x(bas); - b(); - }; - b(); -} diff --git a/clang/test/Rewriter/rewrite-block-ivar-call.mm b/clang/test/Rewriter/rewrite-block-ivar-call.mm deleted file mode 100644 index 8e5a2ea124a8e0..00000000000000 --- a/clang/test/Rewriter/rewrite-block-ivar-call.mm +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -o - %s - -@interface Foo { - void (^_block)(void); -} -@end - -@implementation Foo -- (void)bar { - _block(); -} -@end diff --git a/clang/test/Rewriter/rewrite-block-literal-1.mm b/clang/test/Rewriter/rewrite-block-literal-1.mm deleted file mode 100644 index a3959264e7812b..00000000000000 --- a/clang/test/Rewriter/rewrite-block-literal-1.mm +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -Did="void *" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -Did="void *" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - - -typedef unsigned long size_t; - -void *sel_registerName(const char *); -typedef void (^BLOCK_TYPE)(void); - -@interface CoreDAVTaskGroup -{ - int IVAR; -} -@property int IVAR; -- (void) setCompletionBlock : (BLOCK_TYPE) arg; -@end - -@implementation CoreDAVTaskGroup -- (void)_finishInitialSync { - CoreDAVTaskGroup *folderPost; - folderPost.completionBlock = ^{ - self.IVAR = 0; - [self _finishInitialSync]; - }; - - [folderPost setCompletionBlock : (^{ - self.IVAR = 0; - })]; -} -@dynamic IVAR; -- (void) setCompletionBlock : (BLOCK_TYPE) arg {} -@end - - diff --git a/clang/test/Rewriter/rewrite-block-literal.mm b/clang/test/Rewriter/rewrite-block-literal.mm deleted file mode 100644 index f9d0d2099a0cbc..00000000000000 --- a/clang/test/Rewriter/rewrite-block-literal.mm +++ /dev/null @@ -1,76 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -typedef unsigned long size_t; - -void I( void (^)(void)); -void (^noop)(void); - -void nothing(); -int printf(const char*, ...); - -typedef void (^T) (void); - -void takeblock(T); -int takeintint(int (^C)(int)) { return C(4); } - -T somefunction() { - if (^{ }) - nothing(); - - noop = ^{}; - - noop = ^{printf("\nClosure\n"); }; - - I(^{ }); - - return ^{printf("\nClosure\n"); }; -} -void test2() { - int x = 4; - - takeblock(^{ printf("%d\n", x); }); - - while (1) { - takeblock(^{ - while(1) break; // ok - }); - break; - } -} - -void test4() { - void (^noop)(void) = ^{}; - void (*noop2)() = 0; -} - -void myfunc(int (^block)(int)) {} - -void myfunc3(const int *x); - -void test5() { - int a; - - myfunc(^(int abcd) { - myfunc3(&a); - return 1; - }); -} - -void *X; - -static int global_x = 10; -void (^global_block)(void) = ^{ printf("global x is %d\n", global_x); }; - -// CHECK: static __global_block_block_impl_0 __global_global_block_block_impl_0((void *)__global_block_block_func_0, &__global_block_block_desc_0_DATA); -// CHECK: void (*global_block)(void) = ((void (*)())&__global_global_block_block_impl_0); - -typedef void (^void_block_t)(void); - -static const void_block_t myBlock = ^{ }; - -static const void_block_t myBlock2 = ^ void(void) { }; diff --git a/clang/test/Rewriter/rewrite-block-pointer.mm b/clang/test/Rewriter/rewrite-block-pointer.mm deleted file mode 100644 index 7dda94136c3783..00000000000000 --- a/clang/test/Rewriter/rewrite-block-pointer.mm +++ /dev/null @@ -1,106 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -typedef unsigned long size_t; - -typedef void * id; -void *sel_registerName(const char *); - -@interface X -@end - -void foo(void (^block)(int)); - -@implementation X -static void enumerateIt(void (^block)(id, id, char *)) { - foo(^(int idx) { }); -} -@end - -void apply(void (^block)(int)); - -static void x(int (^cmp)(int, int)) { - x(cmp); -} - -static void y(int (^cmp)(int, int)) { - apply(^(int sect) { - x(cmp); - }); -} - -void *_Block_copy(const void *aBlock); -void x(void (^block)(void)) { - block = ((__typeof(block))_Block_copy((const void *)(block))); -} - -@interface Y { -@private - id _private; -} -- (void (^)(void))f; -@end - -typedef void (^void_block_t)(void); - -@interface YY { - void_block_t __completion; -} -@property (copy) void_block_t f; -@end - -@implementation Y -- (void (^)(void))f { - return [_private f]; -} - -@end - -@protocol CoreDAVAccountInfoProvider; -@protocol CodeProvider; -typedef void (^BDVDiscoveryCompletionHandler)(int success, id discoveredInfo); -typedef void (^BDVDiscoveryCompletion)(id codeInfo, int success, id discoveredInfo); -typedef void (^BDVDiscovery)(int success); -typedef void (^BDVDisc)(id discoveredInfo, id codeInfo, - int success, id Info); -typedef void (^BLOCK)(id, id, id codeInfo); -typedef void (^EMPTY_BLOCK)(); -typedef void (^ BDVDiscoveryCompletion1 )(id codeInfo, int success, id discoveredInfo); - -void (^BL)(void(^arg1)(), int i1, void(^arg)(int)); - -typedef void (^iscoveryCompletionHandler)(void(^arg1)(), id discoveredInfo); - -typedef void (^DVDisc)(id discoveredInfo, id codeInfo, - void(^arg1)(), int i1, void(^arg)(id), - int success, id Info); - - -@interface I @end -@interface INTF @end -void (^BLINT)(I* ARG, INTF* ARG1); - -void test8608902() { - BDVDiscoveryCompletionHandler ppp; - ppp(1, 0); -} - -void test9204669() { - __attribute__((__blocks__(byref))) char (^addChangeToData)(); - - addChangeToData = ^() { - return 'b'; - }; - addChangeToData(); -} - -void test9204669_1() { - __attribute__((__blocks__(byref))) void (^addChangeToData)(); - - addChangeToData = ^() { - addChangeToData(); - }; -} - diff --git a/clang/test/Rewriter/rewrite-block-property.m b/clang/test/Rewriter/rewrite-block-property.m deleted file mode 100644 index 242ca3e199fc2b..00000000000000 --- a/clang/test/Rewriter/rewrite-block-property.m +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %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 - -void *sel_registerName(const char *); - -typedef void (^FooBlock) (int foo, int bar, int baz); - -@interface Foo { } -@property (readwrite, copy, nonatomic) FooBlock fooBlock; -@end - -static void Bar (Foo * foo) { - foo.fooBlock (1,2,3); -} diff --git a/clang/test/Rewriter/rewrite-byref-in-nested-blocks.mm b/clang/test/Rewriter/rewrite-byref-in-nested-blocks.mm deleted file mode 100644 index d433fe42241663..00000000000000 --- a/clang/test/Rewriter/rewrite-byref-in-nested-blocks.mm +++ /dev/null @@ -1,28 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Werror -Wno-address-of-temporary -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-modern-rw.cpp - -typedef unsigned long size_t; - -void f(void (^block)(void)); - -@interface X { - int y; -} -- (void)foo; -@end - -@implementation X -- (void)foo { - __block int kerfluffle; - __block int x; - f(^{ - f(^{ - y = 42; - kerfluffle = 1; - x = 2; - }); - }); -} -@end diff --git a/clang/test/Rewriter/rewrite-byref-vars.mm b/clang/test/Rewriter/rewrite-byref-vars.mm deleted file mode 100644 index 41f4e8d9734a10..00000000000000 --- a/clang/test/Rewriter/rewrite-byref-vars.mm +++ /dev/null @@ -1,56 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -extern "C" __declspec(dllexport) void BreakTheRewriter(int i) { - __block int aBlockVariable = 0; - void (^aBlock)(void) = ^ { - aBlockVariable = 42; - }; - aBlockVariable++; - if (i) { - __block int bbBlockVariable = 0; - void (^aBlock)(void) = ^ { - bbBlockVariable = 42; - }; - } -} - -__declspec(dllexport) extern "C" __declspec(dllexport) void XXXXBreakTheRewriter(void) { - - __block int aBlockVariable = 0; - void (^aBlock)(void) = ^ { - aBlockVariable = 42; - }; - aBlockVariable++; - void (^bBlocks)(void) = ^ { - aBlockVariable = 43; - }; - void (^c)(void) = ^ { - aBlockVariable = 44; - }; - -} - -@interface I -{ - id list; -} -- (void) Meth; -// use before definition -- (void) allObjects; -@end - -@implementation I -// use before definition -- (void) allObjects { - __attribute__((__blocks__(byref))) id *listp; - - ^(void) { - *listp++ = 0; - }; -} -- (void) Meth { __attribute__((__blocks__(byref))) void ** listp = (void **)list; } -@end - -// $CLANG -cc1 -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -x objective-c++ -fblocks bug.mm -// g++ -c -D"__declspec(X)=" bug.cpp diff --git a/clang/test/Rewriter/rewrite-captured-nested-bvar.c b/clang/test/Rewriter/rewrite-captured-nested-bvar.c deleted file mode 100644 index 34236dd646c8f0..00000000000000 --- a/clang/test/Rewriter/rewrite-captured-nested-bvar.c +++ /dev/null @@ -1,34 +0,0 @@ -// RUN: %clang_cc1 -x c -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: FileCheck --input-file=%t-rw.cpp %s - -void q(void (^p)(void)) { - p(); -} - -void f(void) { - __block char BYREF_VAR_CHECK = 'a'; - __block char d = 'd'; - q(^{ - q(^{ - __block char e = 'e'; - char l = 'l'; - BYREF_VAR_CHECK = 'b'; - d = 'd'; - q(^{ - e = '1'; - BYREF_VAR_CHECK = '2'; - d = '3'; - } - ); - }); - }); -} - -int main(void) { - f(); - return 0; -} - -// CHECK: (__Block_byref_BYREF_VAR_CHECK_0 *)BYREF_VAR_CHECK -// CHECK: (__Block_byref_BYREF_VAR_CHECK_0 *)&BYREF_VAR_CHECK -// CHECK: (struct __Block_byref_BYREF_VAR_CHECK_0 *)&BYREF_VAR_CHECK, (struct __Block_byref_d_1 *)&d, 570425344)); diff --git a/clang/test/Rewriter/rewrite-cast-ivar-access.mm b/clang/test/Rewriter/rewrite-cast-ivar-access.mm deleted file mode 100644 index 37ed7b3c1c876f..00000000000000 --- a/clang/test/Rewriter/rewrite-cast-ivar-access.mm +++ /dev/null @@ -1,51 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LP --input-file=%t-rw.cpp %s - -@interface F { - int supervar; -} -@end - -@interface G : F { -@public - int ivar; -} -@end - -@implementation G -- (void)foo:(F *)arg { - int q = arg->supervar; - int v = ((G *)arg)->ivar; -} -@end - -void objc_assign_strongCast(id); -void __CFAssignWithWriteBarrier(void **location, void *value) { - objc_assign_strongCast((id)value); -} - -@interface RealClass { - @public - int f; -} -@end - -@implementation RealClass -@end - -@interface Foo { - id reserved; -} -@end - -@implementation Foo -- (void)bar { - ((RealClass*)reserved)->f = 99; -} -@end - -// CHECK-LP: ((struct G_IMPL *)arg)->ivar - -// CHECK-LP: objc_assign_strongCast((id)value) - -// CHECK-LP: ((struct RealClass_IMPL *)((RealClass *)((struct Foo_IMPL *)self)->reserved))->f diff --git a/clang/test/Rewriter/rewrite-cast-ivar-modern-access.mm b/clang/test/Rewriter/rewrite-cast-ivar-modern-access.mm deleted file mode 100644 index 69c7eecefd7549..00000000000000 --- a/clang/test/Rewriter/rewrite-cast-ivar-modern-access.mm +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@interface F { - int supervar; -} -@end - -@interface G : F { -@public - int ivar; -} -@end - -@implementation G -- (void)foo:(F *)arg { - int q = arg->supervar; - int v = ((G *)arg)->ivar; -} -@end - -void objc_assign_strongCast(id); -void __CFAssignWithWriteBarrier(void **location, void *value) { - objc_assign_strongCast((id)value); -} - -@interface RealClass { - @public - int f; -} -@end - -@implementation RealClass -@end - -@interface Foo { - id reserved; -} -@end - -@implementation Foo -- (void)bar { - ((RealClass*)reserved)->f = 99; -} -@end diff --git a/clang/test/Rewriter/rewrite-cast-to-bool.mm b/clang/test/Rewriter/rewrite-cast-to-bool.mm deleted file mode 100644 index 9fd5bb57406c6c..00000000000000 --- a/clang/test/Rewriter/rewrite-cast-to-bool.mm +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %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 - -void *sel_registerName(const char *); - -@interface NSURLDownload --(void)setBool:(bool)Arg; -@end - -@implementation NSURLDownload -- (void) Meth -{ - [self setBool:(signed char)1]; -} -@end - diff --git a/clang/test/Rewriter/rewrite-category-property.mm b/clang/test/Rewriter/rewrite-category-property.mm deleted file mode 100644 index ae38b82283da4c..00000000000000 --- a/clang/test/Rewriter/rewrite-category-property.mm +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LP --input-file=%t-rw.cpp %s - -@class Y, Z; - -@interface A -@property (readonly) Y *y; -@end - -@interface A (cat) -@property (readonly) Z *z; -@end - -// CHECK-LP: // @property (readonly) Z *z; diff --git a/clang/test/Rewriter/rewrite-constructor-init.mm b/clang/test/Rewriter/rewrite-constructor-init.mm deleted file mode 100644 index c13dcc5d5b42a6..00000000000000 --- a/clang/test/Rewriter/rewrite-constructor-init.mm +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -typedef unsigned int NSUInteger; - -typedef struct _NSRange { - NSUInteger location; - NSUInteger length; -} NSRange; - -static __inline NSRange NSMakeRange(NSUInteger loc, NSUInteger len) { - NSRange r; - r.location = loc; - r.length = len; - return r; -} - -void bar() { - __block NSRange previousRange = NSMakeRange(0, 0); - void (^blk)() = ^{ - previousRange = NSMakeRange(1, 0); - }; -} diff --git a/clang/test/Rewriter/rewrite-eh.m b/clang/test/Rewriter/rewrite-eh.m deleted file mode 100644 index d20cdb822b6492..00000000000000 --- a/clang/test/Rewriter/rewrite-eh.m +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -fobjc-exceptions -o - %s - -@interface NSException -@end - -@interface Foo -@end - -@implementation Foo -- (void)bar { - @try { - } @catch (NSException *e) { - } - @catch (Foo *f) { - } - @catch (...) { - } -} -@end diff --git a/clang/test/Rewriter/rewrite-elaborated-type.mm b/clang/test/Rewriter/rewrite-elaborated-type.mm deleted file mode 100644 index f9dcea78932519..00000000000000 --- a/clang/test/Rewriter/rewrite-elaborated-type.mm +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D_Bool=bool -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D_Bool=bool -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -typedef struct objc_class *Class; -typedef unsigned NSPointerFunctionsOptions; -extern "C" id NSClassFromObject(id object); -void *sel_registerName(const char *); - -struct NSSlice { - int i1; -}; - -@interface NSConcretePointerFunctions { - @public - struct NSSlice slice; -} -- (bool)initializeSlice:(struct NSSlice *)slicep withOptions:(NSPointerFunctionsOptions)options; -@end - -@implementation NSConcretePointerFunctions -- (id)initWithOptions:(NSPointerFunctionsOptions)options { - if (![NSClassFromObject(self) initializeSlice:&slice withOptions:options]) - return 0; - return self; - } -- (bool)initializeSlice:(struct NSSlice *)slicep withOptions:(NSPointerFunctionsOptions)options { - return 0; - } -@end - -@interface I1 @end - -@implementation I1 -+ (struct s1 *) f0 { - return 0; -} -@end diff --git a/clang/test/Rewriter/rewrite-extern-c.mm b/clang/test/Rewriter/rewrite-extern-c.mm deleted file mode 100644 index 2941504ab78d87..00000000000000 --- a/clang/test/Rewriter/rewrite-extern-c.mm +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -o - %s - -extern "C" { - short foo() { } -} -typedef unsigned char Boolean; - diff --git a/clang/test/Rewriter/rewrite-foreach-1.m b/clang/test/Rewriter/rewrite-foreach-1.m deleted file mode 100644 index dcfa6e8a1afeef..00000000000000 --- a/clang/test/Rewriter/rewrite-foreach-1.m +++ /dev/null @@ -1,37 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@protocol P @end - -@interface MyList -@end - -@implementation MyList -- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount -{ - return 0; -} -@end - -@interface MyList (BasicTest) -- (void)compilerTestAgainst; -@end - -int LOOP(void); -@implementation MyList (BasicTest) -- (void)compilerTestAgainst { - id el; - for (el in self) - { LOOP(); } - for (id el1 in self) - LOOP(); - - for (el in (self)) - if (el) - LOOP(); - - for (el in ((self))) - if (el) - LOOP(); -} -@end - diff --git a/clang/test/Rewriter/rewrite-foreach-2.m b/clang/test/Rewriter/rewrite-foreach-2.m deleted file mode 100644 index c363681255a3f1..00000000000000 --- a/clang/test/Rewriter/rewrite-foreach-2.m +++ /dev/null @@ -1,34 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@protocol P @end - -@interface MyList -@end - -@implementation MyList -- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount -{ - return 0; -} -@end - -@interface MyList (BasicTest) -- (void)compilerTestAgainst; -@end - -int LOOP(void); -int INNERLOOP(void); -void END_LOOP(void); -@implementation MyList (BasicTest) -- (void)compilerTestAgainst { - id el; - for (el in self) - { LOOP(); - for (id el1 in self) - INNERLOOP(); - - END_LOOP(); - } -} -@end - diff --git a/clang/test/Rewriter/rewrite-foreach-3.m b/clang/test/Rewriter/rewrite-foreach-3.m deleted file mode 100644 index 4edbe80f2212bd..00000000000000 --- a/clang/test/Rewriter/rewrite-foreach-3.m +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@protocol P @end - -@interface MyList -@end - -@implementation MyList -- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount -{ - return 0; -} -@end - -@interface MyList (BasicTest) -- (void)compilerTestAgainst; -@end - -int LOOP(void); -@implementation MyList (BasicTest) -- (void)compilerTestAgainst { - MyList * el; - for (el in self) - { LOOP(); } - for (MyList * el1 in self) - LOOP(); -} -@end - diff --git a/clang/test/Rewriter/rewrite-foreach-4.m b/clang/test/Rewriter/rewrite-foreach-4.m deleted file mode 100644 index 50f95e4eb56dd7..00000000000000 --- a/clang/test/Rewriter/rewrite-foreach-4.m +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@interface MyList -- (id) allKeys; -@end - -@implementation MyList -- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount -{ - return 0; -} -- (id) allKeys { return 0; } -@end - -@interface MyList (BasicTest) -- (void)compilerTestAgainst; -@end - -int LOOP(void); -@implementation MyList (BasicTest) -- (void)compilerTestAgainst { - MyList * el; - for (el in [el allKeys]) { LOOP(); - } - - for (id el1 in[el allKeys]) { LOOP(); - } - for (el in([el allKeys])) { LOOP(); - } -} -@end - diff --git a/clang/test/Rewriter/rewrite-foreach-5.m b/clang/test/Rewriter/rewrite-foreach-5.m deleted file mode 100644 index a783dfc26448fe..00000000000000 --- a/clang/test/Rewriter/rewrite-foreach-5.m +++ /dev/null @@ -1,51 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=struct objc_object*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -void *sel_registerName(const char *); -void objc_enumerationMutation(id); - -@interface MyList -- (id) allKeys; -@end - -@implementation MyList -- (unsigned int)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state objects: (id *)items count:(unsigned int)stackcount -{ - return 0; -} -- (id) allKeys { return 0; } -@end - -@interface MyList (BasicTest) -- (void)compilerTestAgainst; -@end - -int LOOP(); -@implementation MyList (BasicTest) -- (void)compilerTestAgainst { - MyList * el; - int i; - for (el in [el allKeys]) { - for (i = 0; i < 10; i++) - if (i == 5) - break; - - if (el == 0) - break; - if (el != self) - continue; - LOOP(); - } - - for (id el1 in[el allKeys]) { - LOOP(); - for (el in self) { - if (el) - continue; - } - if (el1) - break; - } -} -@end - diff --git a/clang/test/Rewriter/rewrite-foreach-6.m b/clang/test/Rewriter/rewrite-foreach-6.m deleted file mode 100644 index 86673f8c35dd70..00000000000000 --- a/clang/test/Rewriter/rewrite-foreach-6.m +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=struct objc_object*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// FIXME: Should be able to pipe into clang, but code is not yet correct for -// other reasons. - -void *sel_registerName(const char *); -void objc_enumerationMutation(id); - -@class NSNotification; -@class NSMutableArray; - -void foo(NSMutableArray *notificationArray, id X) { - for (NSNotification *notification in notificationArray) - [X postNotification:notification]; -} - diff --git a/clang/test/Rewriter/rewrite-foreach-7.m b/clang/test/Rewriter/rewrite-foreach-7.m deleted file mode 100644 index 079825b01ea377..00000000000000 --- a/clang/test/Rewriter/rewrite-foreach-7.m +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@class NSArray; -int main(void) { - NSArray *foo; - for (Class c in foo) { } -} diff --git a/clang/test/Rewriter/rewrite-foreach-in-block.mm b/clang/test/Rewriter/rewrite-foreach-in-block.mm deleted file mode 100644 index b7d1dc1bb13f02..00000000000000 --- a/clang/test/Rewriter/rewrite-foreach-in-block.mm +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"id=struct objc_object*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"id=struct objc_object*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -typedef unsigned long size_t; - -void objc_enumerationMutation(id); -void *sel_registerName(const char *); -typedef void (^CoreDAVCompletionBlock)(void); - -@interface I -- (void)M; -- (id) ARR; -@property (readwrite, copy, nonatomic) CoreDAVCompletionBlock c; -@end - -@implementation I -- (void)M { - I* ace; - self.c = ^() { - // Basic correctness check for the changes. - [ace ARR]; - for (I *privilege in [ace ARR]) { } - }; - self.c = ^() { - // Basic correctness test for the changes. - [ace ARR]; - }; -} -@end diff --git a/clang/test/Rewriter/rewrite-foreach-protocol-id.m b/clang/test/Rewriter/rewrite-foreach-protocol-id.m deleted file mode 100644 index 48d94e95a05cfe..00000000000000 --- a/clang/test/Rewriter/rewrite-foreach-protocol-id.m +++ /dev/null @@ -1,28 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"id=struct objc_object*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -void *sel_registerName(const char *); -void objc_enumerationMutation(id); - -@protocol CoreDAVLeafDataPayload @end - -@class NSString; - -@interface CoreDAVAction -- (id) context; -@end - -@interface I -{ - id uuidsToAddActions; -} -@end - -@implementation I -- (void) Meth { - for (id uuid in uuidsToAddActions) { - CoreDAVAction *action = 0; - id payload = [action context]; - } -} -@end diff --git a/clang/test/Rewriter/rewrite-forward-class.m b/clang/test/Rewriter/rewrite-forward-class.m deleted file mode 100644 index 0ec99c505834b7..00000000000000 --- a/clang/test/Rewriter/rewrite-forward-class.m +++ /dev/null @@ -1,34 +0,0 @@ -// RUN: %clang_cc1 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@class XX; -@class YY, ZZ, QQ; -@class ISyncClient, SMSession, ISyncManager, ISyncSession, SMDataclassInfo, SMClientInfo, - DMCConfiguration, DMCStatusEntry; - -@interface QQ - -@end - -@interface SMDataclassInfo : QQ -- (XX*) Meth; -- (DMCStatusEntry*)Meth2; -@end - -@implementation SMDataclassInfo -- (XX*) Meth { return 0; } -- (DMCStatusEntry*)Meth2 { return 0; } -@end - -@interface YY -{ - ISyncClient *p1; - ISyncSession *p2; -} -@property (copy) ISyncClient *p1; -@end - -@implementation YY -@synthesize p1; -@end - diff --git a/clang/test/Rewriter/rewrite-forward-class.mm b/clang/test/Rewriter/rewrite-forward-class.mm deleted file mode 100644 index 616dd932635f6d..00000000000000 --- a/clang/test/Rewriter/rewrite-forward-class.mm +++ /dev/null @@ -1,53 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -extern "C" { -@class XX; -@class YY, ZZ, QQ; -@class ISyncClient, SMSession, ISyncManager, ISyncSession, SMDataclassInfo, SMClientInfo, - DMCConfiguration, DMCStatusEntry; - -@interface QQ - -@end - -@interface SMDataclassInfo : QQ -- (XX*) Meth; -- (DMCStatusEntry*)Meth2; -@end - -@implementation SMDataclassInfo -- (XX*) Meth { return 0; } -- (DMCStatusEntry*)Meth2 { return 0; } -@end - -@interface YY -{ - ISyncClient *p1; - ISyncSession *p2; -} -@property (copy) ISyncClient *p1; -@end - -@implementation YY -@synthesize p1; -@end - -extern "C" { -@class CCC; -@class Protocol, P , Q; -int I,J,K; -}; - -}; - -@interface ISDPropertyChangeGroup -@end - -@implementation ISDPropertyChangeGroup -@class ISDClientState; -- (id)lastModifiedGeneration : (ISDClientState *) obj -{ - return obj ; -} -@end diff --git a/clang/test/Rewriter/rewrite-function-decl.mm b/clang/test/Rewriter/rewrite-function-decl.mm deleted file mode 100644 index af85f687bf5a0d..00000000000000 --- a/clang/test/Rewriter/rewrite-function-decl.mm +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -x objective-c++ -fblocks -o - %s - -extern "C" __declspec(dllexport) void BreakTheRewriter(void) { - __block int aBlockVariable = 0; - void (^aBlock)(void) = ^ { - aBlockVariable = 42; - }; - aBlockVariable++; - void (^bBlocks)(void) = ^ { - aBlockVariable = 43; - }; - void (^c)(void) = ^ { - aBlockVariable = 44; - }; - -} -__declspec(dllexport) extern "C" void AnotherBreakTheRewriter(int *p1, double d) { - - __block int bBlockVariable = 0; - void (^aBlock)(void) = ^ { - bBlockVariable = 42; - }; - bBlockVariable++; - void (^bBlocks)(void) = ^ { - bBlockVariable = 43; - }; - void (^c)(void) = ^ { - bBlockVariable = 44; - }; - -} diff --git a/clang/test/Rewriter/rewrite-implementation.mm b/clang/test/Rewriter/rewrite-implementation.mm deleted file mode 100644 index acb11d5c84d73e..00000000000000 --- a/clang/test/Rewriter/rewrite-implementation.mm +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@interface a -@end - -@interface b : a -@end - -@implementation b -@end - -@interface NSArray @end -@class NSArray; -@implementation NSArray @end diff --git a/clang/test/Rewriter/rewrite-interface-locals.mm b/clang/test/Rewriter/rewrite-interface-locals.mm deleted file mode 100644 index 513c435d97abff..00000000000000 --- a/clang/test/Rewriter/rewrite-interface-locals.mm +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@class NSData, NSError; - -@interface Foo - -typedef void (^Callback)(NSData *data, NSError *error); - -- (void)doSomething:(NSData *)data callback:(Callback)callback; -@end - -@implementation Foo - -- (void)doSomething:(NSData *)data callback:(Callback)callback { - callback(0, 0); -} - -@end diff --git a/clang/test/Rewriter/rewrite-ivar-use.m b/clang/test/Rewriter/rewrite-ivar-use.m deleted file mode 100644 index 793dd6f7dbed56..00000000000000 --- a/clang/test/Rewriter/rewrite-ivar-use.m +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -void *sel_registerName(const char *); - -@interface Foo { - int a; - id b; -} -- (void)bar; -- (void)baz:(id)q; -@end - -@implementation Foo -static void foo(id bar) { - int i = ((Foo *)bar)->a; -} - -- (void)bar { - a = 42; - [self baz:b]; -} -- (void)baz:(id)q { -} -@end - diff --git a/clang/test/Rewriter/rewrite-line-directive.m b/clang/test/Rewriter/rewrite-line-directive.m deleted file mode 100644 index bfb7f14d20f1f3..00000000000000 --- a/clang/test/Rewriter/rewrite-line-directive.m +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang -fms-extensions -rewrite-objc %t.mm -o %t-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LP --input-file=%t-rw.cpp %s -// RUN: %clang -g -fms-extensions -rewrite-objc %t.mm -o %t-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LPG --input-file=%t-rw.cpp %s - -int z(); - -int x() { - id foo; - for (id y in foo) { - z(); - } - return 0; -} -// CHECK-LP-NOT: #line -// CHECK-LPG: #line diff --git a/clang/test/Rewriter/rewrite-local-externs-in-block.mm b/clang/test/Rewriter/rewrite-local-externs-in-block.mm deleted file mode 100644 index a3d71fd923d4eb..00000000000000 --- a/clang/test/Rewriter/rewrite-local-externs-in-block.mm +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -extern "C" int printf(const char*, ...); - -void bar(void (^block)()) { - block(); -} - -int main() { - static int myArr[3] = {1, 2, 3}; - printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]); - - bar(^{ - printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]); - myArr[0] = 42; - myArr[2] = 100; - printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]); - }); - - printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]); -} diff --git a/clang/test/Rewriter/rewrite-local-static-id.mm b/clang/test/Rewriter/rewrite-local-static-id.mm deleted file mode 100644 index 067cfd8c730f42..00000000000000 --- a/clang/test/Rewriter/rewrite-local-static-id.mm +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -Wno-address-of-temporary -Did="void *" -D"SEL=void*" -D"__declspec(X)=" -emit-llvm -o %t %t-rw.cpp - -void *sel_registerName(const char *); - -@interface foo -@end - -@interface foo2 : foo -+ (id)x; -@end - -typedef void (^b_t)(void); - -void bar(b_t block); - -void f() { - static id foo = 0; - bar(^{ - foo = [foo2 x]; - }); -} - diff --git a/clang/test/Rewriter/rewrite-message-expr.mm b/clang/test/Rewriter/rewrite-message-expr.mm deleted file mode 100644 index 10398cb25d0be6..00000000000000 --- a/clang/test/Rewriter/rewrite-message-expr.mm +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LP --input-file=%t-rw.cpp %s - -@interface Baz -- (id)y; -+ (id)z; -@end - -@interface Foo { -@public - int bar; -} -@end - -extern Foo* x(id a); - -int f(Baz *baz) { - int i = x([Baz z])->bar; - int j = ((Foo*)[Baz z])->bar; - int k = x([baz y])->bar; - return i+j+k; -} - -// CHECK-LP: ((struct Foo_IMPL *)x(((id (*)(id, SEL))(void *)objc_msgSend)(objc_getClass("Baz"), sel_registerName("z"))))->bar diff --git a/clang/test/Rewriter/rewrite-modern-array-literal.mm b/clang/test/Rewriter/rewrite-modern-array-literal.mm deleted file mode 100644 index bc9a37ea828ce1..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-array-literal.mm +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -extern "C" void *sel_registerName(const char *); -@class NSString; - -@interface NSNumber -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithInt:(int)value; -@end - -typedef unsigned long NSUInteger; - -@interface NSArray -+ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; -@end - -int i; -int main() { - NSArray *array = @[ @"Hello", @1234 ]; - if (i) { - NSArray *array = @[ @"Hello", @1234 ]; - } - NSArray *array1 = @[ @"Hello", @1234, @[ @"Hello", @1234 ] ]; -} - diff --git a/clang/test/Rewriter/rewrite-modern-atautoreleasepool.mm b/clang/test/Rewriter/rewrite-modern-atautoreleasepool.mm deleted file mode 100644 index a4270f0328b428..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-atautoreleasepool.mm +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o %t-rw.cpp -// RUN: FileCheck --input-file=%t-rw.cpp %s -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -extern "C" -void *sel_registerName(const char *); - -@interface I -{ - id ivar; -} -- (id) Meth; -+ (id) MyAlloc;; -@end - -@implementation I -- (id) Meth { - @autoreleasepool { - id p = [I MyAlloc]; - if (!p) - return ivar; - } - return 0; -} -+ (id) MyAlloc { - return 0; -} -@end - -// CHECK: /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; diff --git a/clang/test/Rewriter/rewrite-modern-block-consts.mm b/clang/test/Rewriter/rewrite-modern-block-consts.mm deleted file mode 100644 index 4af9e296941211..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-block-consts.mm +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Werror -Wno-address-of-temporary -U__declspec -D"__declspec(X)=" %t-modern-rw.cpp - -typedef unsigned long size_t; - -void x(int y) {} -void f() { - const int bar = 3; - int baz = 4; - __block int bab = 4; - __block const int bas = 5; - void (^b)() = ^{ - x(bar); - x(baz); - x(bab); - x(bas); - b(); - }; - b(); -} diff --git a/clang/test/Rewriter/rewrite-modern-block-ivar-call.mm b/clang/test/Rewriter/rewrite-modern-block-ivar-call.mm deleted file mode 100644 index 47920df85d98f8..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-block-ivar-call.mm +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.m -// RUN: %clang_cc1 -fblocks -rewrite-objc -fms-extensions %t.m -o %t-rw.cpp -// RUN: FileCheck --input-file=%t-rw.cpp %s -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@interface Foo { - void (^_block)(void); -} -@end - -@implementation Foo -- (void)bar { - _block(); -} -@end - -// CHECK: ((void (*)(struct __block_impl *))((struct __block_impl *)(*(void (**)(void))((char *)self + OBJC_IVAR_$_Foo$_block)))->FuncPtr)((struct __block_impl *)(*(void (**)(void))((char *)self + OBJC_IVAR_$_Foo$_block))); diff --git a/clang/test/Rewriter/rewrite-modern-block.mm b/clang/test/Rewriter/rewrite-modern-block.mm deleted file mode 100644 index 6841ab4a5a00fd..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-block.mm +++ /dev/null @@ -1,63 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Werror -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp - -typedef unsigned long size_t; -typedef struct { - char byte0; - char byte1; -} CFUUIDBytes; - -void x(void *); - -void y() { - __block CFUUIDBytes bytes; - - void (^bar)() = ^{ - x(&bytes); - }; -} - -int foo() { - __block int hello; - return hello; -} - -// rewriting multiple __block decls on wintin same decl stmt. -void radar7547630() { - __block int BI1, BI2; - - __block float FLOAT1, FT2, FFFFFFFF3, - FFFXXX4; - - __block void (^B)(), (^BB)(); -} - -// rewriting multiple __block decls on wintin same decl stmt -// with initializers. -int rdar7547630(const char *keybuf, const char *valuebuf) { - __block int BI1 = 1, BI2 = 2; - - double __block BYREFVAR = 1.34, BYREFVAR_NO_INIT, BYREFVAR2 = 1.37; - - __block const char *keys = keybuf, *values = valuebuf, *novalues; - - return BI2; -} - -typedef struct _z { - int location; - int length; -} z; - -z w(int loc, int len); - -@interface rdar11326988 -@end -@implementation rdar11326988 -- (void)y:(int)options { - __attribute__((__blocks__(byref))) z firstRange = w(1, 0); - options &= ~(1 | 2); -} -@end - -int Test18799145() { return ^(){return 0;}(); } diff --git a/clang/test/Rewriter/rewrite-modern-captured-nested-bvar.mm b/clang/test/Rewriter/rewrite-modern-captured-nested-bvar.mm deleted file mode 100644 index b85515ea7045ee..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-captured-nested-bvar.mm +++ /dev/null @@ -1,34 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s - -void q(void (^p)(void)) { - p(); -} - -void f() { - __block char BYREF_VAR_CHECK = 'a'; - __block char d = 'd'; - q(^{ - q(^{ - __block char e = 'e'; - char l = 'l'; - BYREF_VAR_CHECK = 'b'; - d = 'd'; - q(^{ - e = '1'; - BYREF_VAR_CHECK = '2'; - d = '3'; - } - ); - }); - }); -} - -int main() { - f(); - return 0; -} - -// CHECK: (__Block_byref_BYREF_VAR_CHECK_0 *)BYREF_VAR_CHECK -// CHECK: {(void*)0,(__Block_byref_BYREF_VAR_CHECK_0 *)&BYREF_VAR_CHECK, 0, sizeof(__Block_byref_BYREF_VAR_CHECK_0), 'a'} -// CHECK: __Block_byref_BYREF_VAR_CHECK_0 *)&BYREF_VAR_CHECK, (__Block_byref_d_1 *)&d, 570425344))); diff --git a/clang/test/Rewriter/rewrite-modern-catch.m b/clang/test/Rewriter/rewrite-modern-catch.m deleted file mode 100644 index 621c7ec45bae8a..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-catch.m +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -fexperimental-new-constant-interpreter -// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -void foo(id arg); - -@interface NSException -@end - -@interface Foo -@end - -@implementation Foo -- (void)bar { - @try { - } @catch (NSException *e) { - foo(e); - } - @catch (Foo *f) { - } - @catch (...) { - @try { - } - @catch (Foo *f1) { - foo(f1); - } - @catch (id pid) { - foo(pid); - } - } -} -@end diff --git a/clang/test/Rewriter/rewrite-modern-class.mm b/clang/test/Rewriter/rewrite-modern-class.mm deleted file mode 100644 index 7d75a51502cd99..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-class.mm +++ /dev/null @@ -1,70 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@protocol PROTO @end - -@interface empty_root @end - -@interface root_with_ivars -{ - id ROOT_IVAR; - id ROOT1_IVAR; -} -@end - -@interface MAXIMAL : root_with_ivars -{ - double D_IVAR; - double D_PROPERTY; -} -- (void) V_METH; -@end - -@implementation MAXIMAL -- (void) V_METH {} -@end -//========================================= -@interface empty_class @end - -@implementation empty_class @end -//========================================= -@interface class_empty_root : empty_root @end - -@implementation class_empty_root @end -//========================================= -@interface class_with_ivars : empty_root -{ - int class_with_ivars_IVAR; -} -@end - -@implementation class_with_ivars @end -//========================================= -@interface class_has_no_ivar : root_with_ivars @end - -@implementation class_has_no_ivar @end - -//===================== class needs to be synthesized here ===================== -@interface SUPER { -@public - double divar; - SUPER *p_super; -} -@end - -@interface INTF @end - -@implementation INTF -- (SUPER *) Meth : (SUPER *)arg { - return arg->p_super; -} -@end - -@class FORM_CLASS; -@interface INTF_DECL { -} -@end - -double Meth(INTF_DECL *p, FORM_CLASS *f) { - return 1.34; -} diff --git a/clang/test/Rewriter/rewrite-modern-container-literal.mm b/clang/test/Rewriter/rewrite-modern-container-literal.mm deleted file mode 100644 index 4c1c90cb19e7e6..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-container-literal.mm +++ /dev/null @@ -1,54 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -void *sel_registerName(const char *); -typedef unsigned long NSUInteger; -typedef long NSInteger; -typedef bool BOOL; - -@interface NSNumber -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value ; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ; -@end - -@protocol NSCopying @end - -@interface NSDictionary -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt; -@end - -@interface NSArray -+ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; -@end - -@interface NSString -@end - -id NSUserName(); - -@interface NSDate -+ (id)date; -@end - -int main() { -NSArray *array = @[ @"Hello", NSUserName(), [NSDate date], [NSNumber numberWithInt:42]]; - -NSDictionary *dictionary = @{ @"name" : NSUserName(), @"date" : [NSDate date], @"process" : @"processInfo"}; - -NSDictionary *dict = @{ @"name":@666, @"man":@__objc_yes, @"date":@1.3 }; - -} - diff --git a/clang/test/Rewriter/rewrite-modern-default-property-synthesis.mm b/clang/test/Rewriter/rewrite-modern-default-property-synthesis.mm deleted file mode 100644 index 9aa8adbb3776e3..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-default-property-synthesis.mm +++ /dev/null @@ -1,79 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fms-extensions -rewrite-objc %t.mm -o %t-rw.cpp -// RUN: FileCheck --input-file=%t-rw.cpp %s -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Werror -DSEL="void *" -Did="struct objc_object *" -Wno-attributes -Wno-address-of-temporary -U__declspec -D"__declspec(X)=" %t-rw.cpp - -extern "C" void *sel_registerName(const char *); - -@interface NSObject -- (void) release; -- (id) retain; -@end -@class NSString; - -@interface SynthItAll : NSObject -@property int howMany; -@property (retain) NSString* what; -@end - -@implementation SynthItAll -@end - - -@interface SynthSetter : NSObject -@property (nonatomic) int howMany; -@property (nonatomic, retain) NSString* what; -@end - -@implementation SynthSetter - -- (int) howMany { - return _howMany; -} -// - (void) setHowMany: (int) value - -- (NSString*) what { - return _what; -} -// - (void) setWhat: (NSString*) value -@end - - -@interface SynthGetter : NSObject -@property (nonatomic) int howMany; -@property (nonatomic, retain) NSString* what; -@end - -@implementation SynthGetter -// - (int) howMany -- (void) setHowMany: (int) value { - _howMany = value; -} - -// - (NSString*) what -- (void) setWhat: (NSString*) value { - if (_what != value) { - [_what release]; - _what = [value retain]; - } -} -@end - -typedef struct { - int x:1; - int y:1; -} TBAR; - -@interface NONAME -{ - TBAR _bar; -} -@property TBAR bad; -@end - -@implementation NONAME -@end - -// CHECK: (*(int *)((char *)self + OBJC_IVAR_$_SynthItAll$_howMany)) = howMany; -// CHECK: return (*(int *)((char *)self + OBJC_IVAR_$_SynthGetter$_howMany)); -// CHECK: (*(TBAR *)((char *)self + OBJC_IVAR_$_NONAME$_bad)) = bad; diff --git a/clang/test/Rewriter/rewrite-modern-extern-c-func-decl.mm b/clang/test/Rewriter/rewrite-modern-extern-c-func-decl.mm deleted file mode 100644 index dcbc06c9e9e817..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-extern-c-func-decl.mm +++ /dev/null @@ -1,91 +0,0 @@ -// RUN: %clang_cc1 -fms-extensions -U__declspec -rewrite-objc -x objective-c++ -fblocks -o %t-rw.cpp %s -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Werror -Wno-address-of-temporary -Wno-attributes -D"Class=void*" -D"id=void*" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp - -typedef unsigned long size_t; -extern "C" __declspec(dllexport) void BreakTheRewriter(void) { - __block int aBlockVariable = 0; - void (^aBlock)(void) = ^ { - aBlockVariable = 42; - }; - aBlockVariable++; - void (^bBlocks)(void) = ^ { - aBlockVariable = 43; - }; - void (^c)(void) = ^ { - aBlockVariable = 44; - }; - -} -__declspec(dllexport) extern "C" void AnotherBreakTheRewriter(int *p1, double d) { - - __block int bBlockVariable = 0; - void (^aBlock)(void) = ^ { - bBlockVariable = 42; - }; - bBlockVariable++; - void (^bBlocks)(void) = ^ { - bBlockVariable = 43; - }; - void (^c)(void) = ^ { - bBlockVariable = 44; - }; - -} - -int - -__declspec (dllexport) - -main (int argc, char *argv[]) -{ - __block int bBlockVariable = 0; - void (^aBlock)(void) = ^ { - bBlockVariable = 42; - }; -} - -static char stringtype; -char CFStringGetTypeID(); -void x(void (^)()); - -static void initStatics(int arg, ...) { - x(^{ - stringtype = CFStringGetTypeID(); - }); -} -static void initStatics1(...) { - x(^{ - stringtype = CFStringGetTypeID(); - }); -} -static void initStatics2() { - x(^{ - stringtype = CFStringGetTypeID(); - }); -} - -static inline const void *auto_zone_base_pointer(void *zone, const void *ptr) { return 0; } - -@interface I -{ - id list; -} -- (void) Meth; -// use before definition -- (void) allObjects; -@end - -@implementation I -// use before definition -- (void) allObjects { - __attribute__((__blocks__(byref))) id *listp; - - void (^B)(void) = ^(void) { - *listp++ = 0; - }; - - B(); -} -- (void) Meth { __attribute__((__blocks__(byref))) void ** listp = (void **)list; } -@end - diff --git a/clang/test/Rewriter/rewrite-modern-ivar-access.mm b/clang/test/Rewriter/rewrite-modern-ivar-access.mm deleted file mode 100644 index 4bde1a401312dc..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-ivar-access.mm +++ /dev/null @@ -1,98 +0,0 @@ -// RUN: %clang_cc1 -fblocks -rewrite-objc -fms-extensions %s -o %t-rw.cpp -// RUN: %clang_cc1 -Werror -fsyntax-only -Wno-address-of-temporary -Wno-c++11-narrowing -std=c++11 -D"Class=void*" -D"id=void*" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp - -struct OUTSIDE { - int i_OUTSIDE; - double d_OUTSIDE; -}; - - -@interface I1 { -@protected - struct OUTSIDE ivar_I1; - - struct INNER_I1 { - int i_INNER_I1; - double d_INNER_I1; - }; - - struct INNER_I1 ivar_I2; - - struct OUTSIDE ivar_I3; - - struct { - int i_noname; - double d_noname; - } NONAME_I4; - - struct { - int i_noname; - double d_noname; - } NONAME_I5; -} -@end - -@implementation I1 -- (void) I1_Meth { - ivar_I1.i_OUTSIDE = 0; - - ivar_I2.i_INNER_I1 = 1; - - ivar_I3.i_OUTSIDE = 2; - - NONAME_I4.i_noname = 3; - - NONAME_I5.i_noname = 4; -} -@end - -@interface INTF2 { -@protected - struct OUTSIDE ivar_INTF2; - - struct { - int i_noname; - double d_noname; - } NONAME_INTF4; - - - struct OUTSIDE ivar_INTF3; - - struct INNER_I1 ivar_INTF4; - - struct { - int i_noname; - double d_noname; - } NONAME_INTF5; - - struct INNER_INTF2 { - int i_INNER_INTF2; - double d_INNER_INTF2; - }; - - struct INNER_INTF2 ivar_INTF6, ivar_INTF7; - - struct INNER_INTF3 { - int i; - } X1,X2,X3; - -} -@end - -@implementation INTF2 -- (void) I2_Meth { - ivar_INTF2.i_OUTSIDE = 0; - - ivar_INTF4.i_INNER_I1 = 1; - - ivar_INTF3.i_OUTSIDE = 2; - - NONAME_INTF4.i_noname = 3; - - NONAME_INTF5.i_noname = 4; - ivar_INTF6.i_INNER_INTF2 = 5; - ivar_INTF7.i_INNER_INTF2 = 5; - X1.i = X2.i = X3.i = 1; -} -@end - diff --git a/clang/test/Rewriter/rewrite-modern-ivar-use.mm b/clang/test/Rewriter/rewrite-modern-ivar-use.mm deleted file mode 100644 index 1abc63bf32e0c0..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-ivar-use.mm +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw-modern.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw-modern.cpp - -void *sel_registerName(const char *); - -@interface Foo { - int a; - id b; -} -- (void)bar; -- (void)baz:(id)q; -@end - -@implementation Foo -static void foo(id bar) { - int i = ((Foo *)bar)->a; -} - -- (void)bar { - a = 42; -} -- (void)baz:(id)q { -} -@end - diff --git a/clang/test/Rewriter/rewrite-modern-ivars-1.mm b/clang/test/Rewriter/rewrite-modern-ivars-1.mm deleted file mode 100644 index dbd28d121ee0d4..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-ivars-1.mm +++ /dev/null @@ -1,124 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Werror -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp - -@interface NSCheapMutableString { -@private - struct S s0; - union { - char *fat; - unsigned char *thin; - } contents; - - struct { - unsigned int isFat:1; - unsigned int freeWhenDone:1; - unsigned int refs:30; - } flags; - - struct S { - int iS1; - double dS1; - } others; - - union U { - int iU1; - double dU1; - } u_others; - - enum { - One, Two - } E1; - - enum e { - Yes = 1, - No = 0 - } BoOl; - - struct S s1; - - enum e E2; - - union { - char *fat; - unsigned char *thin; - } Last_contents; - - struct { - unsigned int isFat:1; - unsigned int freeWhenDone:1; - unsigned int refs:30; - } Last_flags; -} -@end - -@interface III { -@private - struct S s0; - - union { - char *fat; - unsigned char *thin; - } contents; - - struct { - unsigned int isFat:1; - unsigned int freeWhenDone:1; - unsigned int refs:30; - } flags; - - enum { - One1 = 1000, Two1, Three1 - } E1; - - struct S s1; - - enum e E2; - - union { - char *fat; - unsigned char *thin; - } Last_contents; - - struct { - unsigned int isFat:1; - unsigned int freeWhenDone:1; - unsigned int refs:30; - } Last_flags; -} -@end - -enum OUTSIDE { - yes -}; - -@interface MoreEnumTests { -@private - enum INSIDE { - no - } others; - - enum OUTSIDE meetoo; - - enum { - one, - two - } eu; -} -@end - -@interface I { - enum INSIDE I1; - enum OUTSIDE I2; - enum ALSO_INSIDE { - maybe - } I3; - - enum ALSO_INSIDE I4; - - enum { - three, - four - } I5; -} -@end - diff --git a/clang/test/Rewriter/rewrite-modern-ivars-2.mm b/clang/test/Rewriter/rewrite-modern-ivars-2.mm deleted file mode 100644 index 52304ea22fabc2..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-ivars-2.mm +++ /dev/null @@ -1,99 +0,0 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin9 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@interface B @end - -@interface A { - struct s0 { - int f0; - int f1; - } f0; - id f1; -__weak B *f2; - int f3 : 5; - struct s1 { - int *f0; - int *f1; - } f4[2][1]; -} -@end - -@interface C : A -@property int p3; -@end - -@implementation C -@synthesize p3 = _p3; -@end - -@interface A() -@property int p0; -@property (assign) __strong id p1; -@property (assign) __weak id p2; -@end - -// FIXME: Check layout for this class, once it is clear what the right -// answer is. -@implementation A -@synthesize p0 = _p0; -@synthesize p1 = _p1; -@synthesize p2 = _p2; -@end - -@interface D : A -@property int p3; -@end - -// FIXME: Check layout for this class, once it is clear what the right -// answer is. -@implementation D -@synthesize p3 = _p3; -@end - -typedef unsigned short UInt16; - - -typedef signed char BOOL; -typedef unsigned int FSCatalogInfoBitmap; - -@interface NSFileLocationComponent { - @private - - id _specifierOrStandardizedPath; - BOOL _carbonCatalogInfoAndNameAreValid; - FSCatalogInfoBitmap _carbonCatalogInfoMask; - id _name; - id _containerComponent; - id _presentableName; - id _iconAsAttributedString; -} -@end - -@implementation NSFileLocationComponent @end - -@interface Foo { - int bar:26; -} -@end - -@implementation Foo -@end - -@interface Foo1 { - int bar:26; - int bar2:4; -} -@end - -@implementation Foo1 -@end - -@interface Foo3 { - int foo; - int bar:26; -} -@end - -@implementation Foo3 -@end - diff --git a/clang/test/Rewriter/rewrite-modern-ivars.mm b/clang/test/Rewriter/rewrite-modern-ivars.mm deleted file mode 100644 index 217cff662992e7..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-ivars.mm +++ /dev/null @@ -1,64 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@protocol P @end -@protocol P1 @end -@interface INTF -{ - id CLASS_IVAR; - id Q_IVAR; - - void (^_block)(id

); - void (*_fptr)(void (^_block)(id

)); - char CLASS_EXT_IVAR; - id (^ext_block)(id

, INTF*, INTF*); - id IMPL_IVAR; - double D_IMPL_IVAR; - INTF

*(*imp_fptr)(void (^_block)(id

, INTF*)); - id arr[100]; -} -@end - -@implementation INTF @end - -@interface MISC_INTF -{ - id CLASS_IVAR; - id Q_IVAR; - - void (^_block)(id

); - void (*_fptr)(void (^_block)(id

)); - unsigned int BF : 8; -} -@end - -@interface MISC_INTF() -{ - char CLASS_EXT_IVAR; - id (^ext_block)(id

, MISC_INTF*, MISC_INTF*); -} -@end - -@interface MISC_INTF() { - int II1; - double DD1; } -@end - -@interface MISC_INTF() { int II2; double DD2; } -@end - -@interface MISC_INTF() { int II3; - double DD3; } -@end - -@interface MISC_INTF() { int II4; double DD4; -} -@end - -@implementation MISC_INTF -{ - id IMPL_IVAR; - double D_IMPL_IVAR; - MISC_INTF

*(*imp_fptr)(void (^_block)(id

, MISC_INTF*)); -} -@end diff --git a/clang/test/Rewriter/rewrite-modern-nested-ivar.mm b/clang/test/Rewriter/rewrite-modern-nested-ivar.mm deleted file mode 100644 index 6e0cd3905a9380..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-nested-ivar.mm +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.m -// RUN: %clang_cc1 -fblocks -rewrite-objc -fms-extensions %t.m -o %t-rw.cpp -// RUN: FileCheck --input-file=%t-rw.cpp %s -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@interface NSURLResponse { -@public - NSURLResponse *InnerResponse; -} -@end - -@interface NSCachedURLResponseInternal -{ - @public - NSURLResponse *response; -} -@end - -@interface NSCachedURLResponse -{ - @private - NSCachedURLResponseInternal *_internal; -} -- (void) Meth; -@end - -@implementation NSCachedURLResponse -- (void) Meth { - _internal->response->InnerResponse = 0; - } -@end - -// CHECK: (*(NSURLResponse **)((char *)(*(NSURLResponse **)((char *)(*(NSCachedURLResponseInternal **)((char *)self + OBJC_IVAR_$_NSCachedURLResponse$_internal)) + OBJC_IVAR_$_NSCachedURLResponseInternal$response)) + OBJC_IVAR_$_NSURLResponse$InnerResponse)) = 0; diff --git a/clang/test/Rewriter/rewrite-modern-private-ivars.mm b/clang/test/Rewriter/rewrite-modern-private-ivars.mm deleted file mode 100644 index 01020a07a26f5c..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-private-ivars.mm +++ /dev/null @@ -1,52 +0,0 @@ -// RUN: %clang_cc1 -fblocks -rewrite-objc -fms-extensions %s -o %t-rw.cpp -// RUN: %clang_cc1 -Werror -fsyntax-only -Wno-address-of-temporary -Wno-c++11-narrowing -std=c++11 -D"Class=void*" -D"id=void*" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp - -struct Q { - int x; -}; - -@interface I -@end - -@interface I() { - - struct { - int x; - } unnamed; - - struct S { - int x; - } foo; - - double dd; - - struct S foo1; -} -@end - -@implementation I -{ - struct P { - int x; - } bar; - - double ee; - - struct Q bar1; - - struct { - int x; - } noname; -} - -- (void) Meth { - foo.x = 1; - bar.x = 2; - dd = 1.23; - ee = 0.0; - foo1.x = 3; - bar1.x = 4; - noname.x = 3; - unnamed.x = 10; -} -@end diff --git a/clang/test/Rewriter/rewrite-modern-protocol-1.mm b/clang/test/Rewriter/rewrite-modern-protocol-1.mm deleted file mode 100644 index 0cde38665c5882..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-protocol-1.mm +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s - -@protocol NSCopying @end - -@interface INTF -@end - -@implementation INTF @end - -// CHECK: static struct _protocol_t _OBJC_PROTOCOL_NSCopying -// CHECK: static struct _protocol_t *_OBJC_LABEL_PROTOCOL_$_NSCopying = &_OBJC_PROTOCOL_NSCopying; - diff --git a/clang/test/Rewriter/rewrite-modern-protocol.mm b/clang/test/Rewriter/rewrite-modern-protocol.mm deleted file mode 100644 index a4bd617ba6fda3..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-protocol.mm +++ /dev/null @@ -1,31 +0,0 @@ -// 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"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@protocol ROOT @end - -@protocol P1 @end - -@protocol P2 @end - -@class NSObject; - -@protocol PROTO -- (id) INST_METHOD; -+ (id) CLASS_METHOD : (id)ARG; -@property id Prop_in_PROTO; -@optional -- (id) opt_instance_method; -+ (id) opt_class_method; -@property (readonly, retain) NSObject *AnotherProperty; -@required -- (id) req; -@optional -- (id) X_opt_instance_method; -+ (id) X_opt_class_method; -@end - -@interface INTF -@end - -@implementation INTF -@end diff --git a/clang/test/Rewriter/rewrite-modern-qualified-type.mm b/clang/test/Rewriter/rewrite-modern-qualified-type.mm deleted file mode 100644 index 0652c51dc30eaf..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-qualified-type.mm +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D_Bool=bool -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -@protocol OS_dispatch_object @end - -@interface NSObject @end - -@protocol OS_dispatch_queue @end typedef NSObject *dispatch_queue_t; - -typedef id dispatch_queue_i; diff --git a/clang/test/Rewriter/rewrite-modern-struct-ivar-1.mm b/clang/test/Rewriter/rewrite-modern-struct-ivar-1.mm deleted file mode 100644 index ff34ff5a8881b5..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-struct-ivar-1.mm +++ /dev/null @@ -1,47 +0,0 @@ -// RUN: %clang_cc1 -fblocks -rewrite-objc -fms-extensions %s -o %t-rw.cpp -// RUN: %clang_cc1 -Werror -fsyntax-only -Wno-address-of-temporary -Wno-c++11-narrowing -std=c++11 -D"Class=void*" -D"id=void*" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp - -typedef unsigned long NSUInteger; - -typedef struct _NSRange { - NSUInteger location; - NSUInteger length; -} NSRange; - -typedef struct { - NSUInteger _capacity; - NSRange _ranges[0]; -} _NSRangeInfo; - -@interface Foo{ - @protected - struct _bar { - int x:1; - int y:1; - } bar; - union { - struct { - NSRange _range; - } _singleRange; - struct { - void * _data; - void *_reserved; - } _multipleRanges; - } _internal; -} -@end -@implementation Foo -- (void)x:(Foo *)other { - bar.x = 0; - bar.y = -1; - self->_internal._singleRange._range = (( other ->bar.x) ? &( other ->_internal._singleRange._range) : ((NSRange *)(&(((_NSRangeInfo *)( other ->_internal._multipleRanges._data))->_ranges))))[0]; -} -@end -@interface FooS : Foo -@end -@implementation FooS -- (void)y { - - NSUInteger asdf = (( self ->bar.x) ? 1 : ((_NSRangeInfo *)( self ->_internal._multipleRanges._data))->_capacity ); -} -@end diff --git a/clang/test/Rewriter/rewrite-modern-struct-ivar.mm b/clang/test/Rewriter/rewrite-modern-struct-ivar.mm deleted file mode 100644 index d6c64ea3c60ef2..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-struct-ivar.mm +++ /dev/null @@ -1,51 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -fblocks -rewrite-objc -fms-extensions %t.mm -o %t-rw.cpp -// RUN: FileCheck --input-file=%t-rw.cpp %s -// RUN: %clang_cc1 -fsyntax-only -Werror -Wno-address-of-temporary -Wno-c++11-narrowing -std=c++11 -D"Class=void*" -D"id=void*" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp - -struct S { - int i1; - double d1; - void (^block1)(); -}; - -@interface I -{ - struct S struct_ivar; - - struct S *pstruct_ivar; -} -@end - -@implementation I -- (struct S) dMeth{ return struct_ivar; } -@end - -// CHECK: return (*(struct S *)((char *)self + OBJC_IVAR_$_I$struct_ivar)); - -@interface Foo{ - @protected - struct { - int x:1; - int y:1; - } bar; - - struct _S { - int x:1; - int y:1; - } s; - -} -@end -@implementation Foo -- (void)x { - bar.x = 0; - bar.y = -1; - - s.x = 0; - s.y = -1; -} -@end - -// CHECK: (*(decltype(((Foo_IMPL *)0U)->bar) *)((char *)self + OBJC_IVAR_$_Foo$bar)).x = 0; -// CHECK: (*(struct _S *)((char *)self + OBJC_IVAR_$_Foo$s)).x = 0; diff --git a/clang/test/Rewriter/rewrite-modern-super.mm b/clang/test/Rewriter/rewrite-modern-super.mm deleted file mode 100644 index 2af6ec150f4157..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-super.mm +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"id=struct objc_object *" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -extern "C" void *sel_registerName(const char *); - -typedef struct objc_class * Class; - -@interface Sub -- (void)dealloc; -@end - -@interface I : Sub -- (void)dealloc; -@end - -@implementation I -- (void)dealloc { - return; - [super dealloc]; -} -@end - diff --git a/clang/test/Rewriter/rewrite-modern-synchronized.m b/clang/test/Rewriter/rewrite-modern-synchronized.m deleted file mode 100644 index 60650656a0635a..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-synchronized.m +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wno-address-of-temporary -D"SEL=void*" -D"Class=struct objc_class *" -D"__declspec(X)=" %t-rw.cpp - -typedef struct objc_object { - Class isa; -} *id; - -void *sel_registerName(const char *); - -id SYNCH_EXPR(void); -void SYNCH_BODY(void); -void SYNCH_BEFORE(void); -void SYNC_AFTER(void); - -void foo(id sem) -{ - SYNCH_BEFORE(); - @synchronized (SYNCH_EXPR()) { - SYNCH_BODY(); - return; - } - SYNC_AFTER(); - @synchronized ([sem self]) { - SYNCH_BODY(); - return; - } -} - -void test_sync_with_implicit_finally(void) { - id foo; - @synchronized (foo) { - return; // The rewriter knows how to generate code for implicit finally - } -} - -@interface NSObject @end - -@interface I : NSObject @end - -@implementation I -+ (void) Meth { -@synchronized(self) { -} -} -@end diff --git a/clang/test/Rewriter/rewrite-modern-throw.m b/clang/test/Rewriter/rewrite-modern-throw.m deleted file mode 100644 index c9a54147fcbb17..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-throw.m +++ /dev/null @@ -1,92 +0,0 @@ -// RUN: %clang_cc1 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fcxx-exceptions -fexceptions -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -typedef struct objc_class *Class; -typedef struct objc_object { - Class isa; -} *id; - -void *sel_registerName(const char *); - -@interface Foo @end -void TRY(void); -void SPLATCH(void); -void MYTRY(void); -void MYCATCH(void); - -void foo(void) { - @try { TRY(); } - @catch (...) { SPLATCH(); @throw; } -} - -int main(void) -{ - - @try { - MYTRY(); - } - - @catch (Foo* localException) { - MYCATCH(); - @throw localException; - } - - // no catch clause - @try { } - @finally { } -} - - -@interface INST -{ - INST* throw_val; -} - -- (id) ThrowThis; - -- (void) MainMeth; - -@end - - -@implementation INST -- (id) ThrowThis { return 0; } - -- (void) MainMeth { - @try { - MYTRY(); - } - @catch (Foo* localException) { - MYCATCH(); - @throw [self ThrowThis]; - } - @catch (...) { - @throw [throw_val ThrowThis]; - } -} -@end - -@class NSDictionary, NSException; -@class NSMutableDictionary; - -@interface NSString -+ (id)stringWithFormat:(NSString *)format, ... ; -@end - -@interface NSException -+ (NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo; -@end -id *_imp__NSInvalidArgumentException; - -@interface NSSetExpression @end - -@implementation NSSetExpression --(id)expressionValueWithObject:(id)object context:(NSMutableDictionary*)bindings { - id leftSet; - id rightSet; - @throw [NSException exceptionWithName: *_imp__NSInvalidArgumentException reason: [NSString stringWithFormat: @"Can't evaluate set expression; left subexpression not a set (lhs = %@ rhs = %@)", leftSet, rightSet] userInfo: 0]; - - return leftSet ; -} -@end - diff --git a/clang/test/Rewriter/rewrite-modern-try-catch-finally.m b/clang/test/Rewriter/rewrite-modern-try-catch-finally.m deleted file mode 100644 index cdf79dbd306a97..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-try-catch-finally.m +++ /dev/null @@ -1,63 +0,0 @@ -// RUN: %clang_cc1 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -typedef struct objc_class *Class; -typedef struct objc_object { - Class isa; -} *id; - -extern int printf(const char *, ...); - -int main(void) { - @try { - } - @finally { - } - while (1) { - @try { - printf("executing try"); - break; - } @finally { - printf("executing finally"); - } - printf("executing after finally block"); - } - @try { - printf("executing try"); - } @finally { - printf("executing finally"); - } - return 0; -} - -void test2_try_with_implicit_finally(void) { - @try { - return; - } @catch (id e) { - - } -} - -void FINALLY(void); -void TRY(void); -void CATCH(void); - -@interface NSException -@end - -@interface Foo -@end - -@implementation Foo -- (void)bar { - @try { - TRY(); - } - @catch (NSException *e) { - CATCH(); - } - @finally { - FINALLY(); - } -} -@end diff --git a/clang/test/Rewriter/rewrite-modern-try-finally.m b/clang/test/Rewriter/rewrite-modern-try-finally.m deleted file mode 100644 index b964c6f52927dc..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-try-finally.m +++ /dev/null @@ -1,40 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 -fsyntax-only -fcxx-exceptions -fexceptions -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -typedef struct objc_class *Class; -typedef struct objc_object { - Class isa; -} *id; - -void FINALLY(void); -void TRY(void); -void INNER_FINALLY(void); -void INNER_TRY(void); -void CHECK(void); - -@interface Foo -@end - -@implementation Foo -- (void)bar { - @try { - TRY(); - } - @finally { - FINALLY(); - } - CHECK(); - @try { - TRY(); - } - @finally { - @try { - INNER_TRY(); - } - @finally { - INNER_FINALLY(); - } - FINALLY(); - } -} -@end diff --git a/clang/test/Rewriter/rewrite-modern-typeof.mm b/clang/test/Rewriter/rewrite-modern-typeof.mm deleted file mode 100644 index 6136563e1f0bfb..00000000000000 --- a/clang/test/Rewriter/rewrite-modern-typeof.mm +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LP --input-file=%t-rw.cpp %s -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -Wno-attributes -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -typedef unsigned long size_t; -extern "C" { -extern "C" void *_Block_copy(const void *aBlock); -extern "C" void _Block_release(const void *aBlock); -} - -int main() { - __attribute__((__blocks__(byref))) int a = 42; - int save_a = a; - - void (^b)(void) = ^{ - ((__typeof(^{ a = 2; }))_Block_copy((const void *)(^{ a = 2; }))); - }; - - ((__typeof(b))_Block_copy((const void *)(b))); - - return 0; -} - -// CHECK-LP: ((void (^)(void))_Block_copy((const void *)(b))) - -void f() { - int a; - __typeof__(a) aVal = a; - char *a1t = (char *)@encode(__typeof__(a)); - __typeof__(aVal) bVal; - char *a2t = (char *)@encode(__typeof__(bVal)); - __typeof__(bVal) cVal = bVal; - char *a3t = (char *)@encode(__typeof__(cVal)); - -} - -void x() { - id y; - void (^z)() = ^{ }; - y = (id)((__typeof(z))_Block_copy((const void *)(z))); -} - -// CHECK-LP: int aVal = a; - -// CHECK-LP: int bVal; diff --git a/clang/test/Rewriter/rewrite-nest.m b/clang/test/Rewriter/rewrite-nest.m deleted file mode 100644 index 41bb875c680ab6..00000000000000 --- a/clang/test/Rewriter/rewrite-nest.m +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@interface NSMapTable @end -@interface NSEnumerator @end - -typedef unsigned int NSUInteger; - -@interface NSConcreteMapTable : NSMapTable { -@public - NSUInteger capacity; -} -@end - -@interface NSConcreteMapTableValueEnumerator : NSEnumerator { - NSConcreteMapTable *mapTable; -} -@end - -@implementation NSConcreteMapTableValueEnumerator - -- nextObject { - while (mapTable->capacity) { - } - return 0; -} -@end - diff --git a/clang/test/Rewriter/rewrite-nested-blocks-1.mm b/clang/test/Rewriter/rewrite-nested-blocks-1.mm deleted file mode 100644 index 27eb0543a6a07d..00000000000000 --- a/clang/test/Rewriter/rewrite-nested-blocks-1.mm +++ /dev/null @@ -1,49 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -typedef unsigned long size_t; -void *sel_registerName(const char *); - -void f(void (^block)(void)); -void f2(id); -void f3(int); -char f4(id, id); - -@interface Baz -- (void)b:(void (^)(void))block; -@end - -@interface Bar -@end - -@interface Foo { - int _x; -} -@end - -@implementation Foo -- (void)method:(Bar *)up { - Baz *down; - int at; - id cq; - __block char didit = 'a'; - __block char upIsFinished = 'b'; - f(^{ - id old_cq; - f2(cq); - [down b:^{ - [down b:^{ - f(^{ - didit = f4(up, down); - upIsFinished = 'c'; - self->_x++; - }); - }]; - }]; - f2(old_cq); - f3(at); - }); -} -@end diff --git a/clang/test/Rewriter/rewrite-nested-blocks-2.mm b/clang/test/Rewriter/rewrite-nested-blocks-2.mm deleted file mode 100644 index a7a83f6f0c0097..00000000000000 --- a/clang/test/Rewriter/rewrite-nested-blocks-2.mm +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %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 -// grep "static void __FUNC_block_copy_" %t-rw.cpp | count 2 -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp -// grep "static void __FUNC_block_copy_" %t-modern-rw.cpp | count 2 - -typedef unsigned long size_t; -void Outer(void (^bk)()); -void Inner(void (^bk)()); -void INNER_FUNC(id d); - -void FUNC() { - - id bar = (id)42; - Outer(^{ - Inner(^{ - INNER_FUNC(bar); - }); - }); -} diff --git a/clang/test/Rewriter/rewrite-nested-blocks.mm b/clang/test/Rewriter/rewrite-nested-blocks.mm deleted file mode 100644 index c379773aade3e4..00000000000000 --- a/clang/test/Rewriter/rewrite-nested-blocks.mm +++ /dev/null @@ -1,56 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -typedef unsigned long size_t; -void f(void (^block)(void)); - -@interface X { - int y; -} -- (void)foo; -@end - -@implementation X -- (void)foo { - f(^{ - f(^{ - f(^{ - y=42; - }); - }); -}); - -} -@end - -struct S { - int y; -}; - -void foo () { - struct S *SELF; - f(^{ - f(^{ - SELF->y = 42; - }); - }); -} - -@interface Bar -@end - -void f(Bar *); -void q(void (^block)(void)); - -void x() { - void (^myblock)(Bar *b) = ^(Bar *b) { - q(^{ - f(b); - }); - }; - - Bar *b = (Bar *)42; - myblock(b); -} diff --git a/clang/test/Rewriter/rewrite-nested-ivar.mm b/clang/test/Rewriter/rewrite-nested-ivar.mm deleted file mode 100644 index 5b8c2ddf08a18a..00000000000000 --- a/clang/test/Rewriter/rewrite-nested-ivar.mm +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw-modern.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw-modern.cpp - -@interface NSURLResponse { -@public - NSURLResponse *InnerResponse; -} -@end - -@interface NSCachedURLResponseInternal -{ - @public - NSURLResponse *response; -} -@end - -@interface NSCachedURLResponse -{ - @private - NSCachedURLResponseInternal *_internal; -} -- (void) Meth; -@end - -@implementation NSCachedURLResponse -- (void) Meth { - _internal->response->InnerResponse = 0; - } -@end diff --git a/clang/test/Rewriter/rewrite-nested-property-in-blocks.mm b/clang/test/Rewriter/rewrite-nested-property-in-blocks.mm deleted file mode 100644 index 71e97a16f3c62b..00000000000000 --- a/clang/test/Rewriter/rewrite-nested-property-in-blocks.mm +++ /dev/null @@ -1,54 +0,0 @@ -// RUN: %clang_cc1 -triple i686-pc-windows -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -triple i686-pc-windows -fsyntax-only -fms-extensions -Wno-address-of-temporary -Did="void *" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -triple i686-pc-windows -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -triple i686-pc-windows -fsyntax-only -fms-extensions -Wno-address-of-temporary -Did="void *" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -typedef unsigned long size_t; -void *sel_registerName(const char *); - -extern "C" void nowarn(id); - -extern "C" void noblockwarn(void (^)()); - -@interface INTFOFPROP -@property (readwrite, retain) INTFOFPROP *outer; -@property (readwrite, retain) id inner; -@end - -@interface NSSet -- (NSSet *)objectsPassingTest:(char (^)(id obj, char *stop))predicate ; -@end - -@interface INTF -- (NSSet *)Meth; -@end - -@implementation INTF - -- (NSSet *)Meth -{ - NSSet *aces; - - noblockwarn(^() { - INTFOFPROP *ace; - nowarn(ace.outer.inner); - noblockwarn(^() { - INTFOFPROP *ace; - nowarn(ace.outer.inner); - }); - }); - - noblockwarn(^() { - INTFOFPROP *ace; - nowarn(ace.outer.inner); - }); - -return [aces objectsPassingTest:^(id obj, char *stop) - { - INTFOFPROP *ace = (INTFOFPROP *)obj; - nowarn(ace.outer.inner); - return (char)0; - }]; - -} -@end diff --git a/clang/test/Rewriter/rewrite-no-nextline.mm b/clang/test/Rewriter/rewrite-no-nextline.mm deleted file mode 100644 index 3d514298c3799e..00000000000000 --- a/clang/test/Rewriter/rewrite-no-nextline.mm +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@interface RootObject { -} -@end void doStuff(); -int main(int argc, char *argv[]) { - return 0; -} diff --git a/clang/test/Rewriter/rewrite-property-attributes.mm b/clang/test/Rewriter/rewrite-property-attributes.mm deleted file mode 100644 index 5d70147fdc8753..00000000000000 --- a/clang/test/Rewriter/rewrite-property-attributes.mm +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -typedef void (^void_block_t)(void); - -@interface Y { - void_block_t __completion; - Y* YVAR; - id ID; -} -@property (copy) void_block_t completionBlock; -@property (retain) Y* Yblock; -@property (copy) id ID; -@end - -@implementation Y -@synthesize completionBlock=__completion; -@synthesize Yblock = YVAR; -@synthesize ID; -@end - diff --git a/clang/test/Rewriter/rewrite-property-set-cfstring.mm b/clang/test/Rewriter/rewrite-property-set-cfstring.mm deleted file mode 100644 index 9c1d2de68c4c8f..00000000000000 --- a/clang/test/Rewriter/rewrite-property-set-cfstring.mm +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -void *sel_registerName(const char *); - -@class NSString; -@interface CoreDAVDiscoveryAccountInfo { - NSString *_scheme; -} -@property (retain) NSString *scheme; -- (void) Meth ; -@end - -@implementation CoreDAVDiscoveryAccountInfo -@synthesize scheme=_scheme; -- (void) Meth { - CoreDAVDiscoveryAccountInfo *discoveryInfo; - discoveryInfo.scheme = @"https"; -} -@end diff --git a/clang/test/Rewriter/rewrite-protocol-property.mm b/clang/test/Rewriter/rewrite-protocol-property.mm deleted file mode 100644 index e5559f7e2262c9..00000000000000 --- a/clang/test/Rewriter/rewrite-protocol-property.mm +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -Did="void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@class NSString; -@interface NSObject @end - -@protocol P -@property (retain) NSString* test; -@end - - -@interface A : NSObject

{ - NSString* _test; -} -@end - - -@implementation A -@synthesize test=_test; -@end - diff --git a/clang/test/Rewriter/rewrite-protocol-qualified.mm b/clang/test/Rewriter/rewrite-protocol-qualified.mm deleted file mode 100644 index 316607d30f1284..00000000000000 --- a/clang/test/Rewriter/rewrite-protocol-qualified.mm +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"id=void*" -D"__declspec(X)=" %t-rw.cpp - -@protocol NSPortDelegate; -@interface NSConnection @end - -@interface NSMessagePort -- (void) clone; -@end - -@implementation NSMessagePort -- (void) clone { - NSConnection *conn = 0; - id *idc = 0; -} -@end - -@protocol Proto1, Proto2; - -@protocol Proto -@end - -unsigned char func(id inProxy); - -id bar(id); - -void f() { - id a; - id b = bar((id )a); -} - -@protocol NSObject @end -@class NSRunLoop; - -@protocol CoreDAVTaskManager - @property (retain) NSRunLoop *workRunLoop; -@end - -@protocol some_protocol; - -void foo (int n) -{ - id array[n]; -} - diff --git a/clang/test/Rewriter/rewrite-protocol-type-1.m b/clang/test/Rewriter/rewrite-protocol-type-1.m deleted file mode 100644 index 2ecae8b584a784..00000000000000 --- a/clang/test/Rewriter/rewrite-protocol-type-1.m +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@protocol MyProto1 -@end - -@protocol MyProto2 -@end - -@interface INTF @end - -INTF *g1; - -INTF *g2, *g3; - -INTF * Func(INTF *p2, INTF *p3, INTF *p4, INTF *p5) -{ - return p2; -} - -INTF * Func1(INTF *p2, INTF *p3, INTF *p4, INTF *p5) -{ - return p3; -} - -@interface Foo -@property int (*hashFunction)(const void *item, int (*size)(const void *item)); -@end diff --git a/clang/test/Rewriter/rewrite-qualified-id.mm b/clang/test/Rewriter/rewrite-qualified-id.mm deleted file mode 100644 index 96bc31c90cc69c..00000000000000 --- a/clang/test/Rewriter/rewrite-qualified-id.mm +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -typedef void * id; - -@protocol foo -@end - -@interface CL -{ - id changeSource; - CL * changeSource1; -} -@end - -typedef struct x -{ - id changeSource; -} x; - diff --git a/clang/test/Rewriter/rewrite-rewritten-initializer.mm b/clang/test/Rewriter/rewrite-rewritten-initializer.mm deleted file mode 100644 index b24c00cc852b1c..00000000000000 --- a/clang/test/Rewriter/rewrite-rewritten-initializer.mm +++ /dev/null @@ -1,30 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw-modern.cpp -// RUN: %clang_cc1 -fsyntax-only -Werror -Wno-address-of-temporary -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw-modern.cpp - -typedef unsigned long size_t; -typedef void * id; -void *sel_registerName(const char *); - -@interface NSMutableString -- (NSMutableString *)string; -@end - -@interface Z -@end - -@implementation Z - -- (void)x { - id numbers; - int i, numbersCount = 42; - __attribute__((__blocks__(byref))) int blockSum = 0; - void (^add)(id n, int idx, char *stop) = ^(id n, int idx, char *stop) { }; - [numbers enumerateObjectsUsingBlock:add]; - NSMutableString *forwardAppend = [NSMutableString string]; - __attribute__((__blocks__(byref))) NSMutableString *blockAppend = [NSMutableString string]; -} - -@end - diff --git a/clang/test/Rewriter/rewrite-static-block.mm b/clang/test/Rewriter/rewrite-static-block.mm deleted file mode 100644 index ed720e034a28ec..00000000000000 --- a/clang/test/Rewriter/rewrite-static-block.mm +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -emit-llvm -o %t-rw.ll -// RUN: FileCheck --input-file=%t-rw.ll %s - -typedef void (^void_block_t)(void); - -static const void_block_t myblock = ^{ - -}; - -// CHECK: myblock = internal global diff --git a/clang/test/Rewriter/rewrite-super-message.mm b/clang/test/Rewriter/rewrite-super-message.mm deleted file mode 100644 index 0b9272117edc66..00000000000000 --- a/clang/test/Rewriter/rewrite-super-message.mm +++ /dev/null @@ -1,50 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -Wno-address-of-temporary -DKEEP_ATTRIBUTES -D"id=struct objc_object *" -D"Class=struct objc_class *" -D"SEL=void*" -D"__declspec(X)=" -emit-llvm -o - %t-rw.cpp | FileCheck %t-rw.cpp - -void *sel_registerName(const char *); - -@interface __NSCFType -@end - -@interface __NSCFString : __NSCFType -- (const char *)UTF8String; -@end - -@implementation __NSCFString -- (const char *)UTF8String { - return (const char *)[super UTF8String]; -} -@end - -// CHECK: call ptr @class_getSuperclass - -@class NSZone; - -@interface NSObject { -} - -+ (id)allocWithZone:(NSZone *)zone; -@end - - -@interface NSArray : NSObject -@end - -@implementation NSArray -+ (id)allocWithZone:(NSZone *)zone { - return [super allocWithZone:zone]; -} -@end - -@interface XNSArray -{ - Class isa; -} -@end - -@class XNSArray; - -@interface __NSArray0 : XNSArray -@end - -@implementation __NSArray0 @end diff --git a/clang/test/Rewriter/rewrite-trivial-constructor.mm b/clang/test/Rewriter/rewrite-trivial-constructor.mm deleted file mode 100644 index 7cbcb2ad54246c..00000000000000 --- a/clang/test/Rewriter/rewrite-trivial-constructor.mm +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -x objective-c++ -fblocks -o - %s - -typedef struct { - int a; - int b; -} s; - -extern void CFBasicHashApply(int (^block)(s)) { - int used, cnt; - for (int idx = 0; 0 < used && idx < cnt; idx++) { - s bkt; - if (0 < bkt.a) { - if (!block(bkt)) { - return; - } - used--; - } - } -} - diff --git a/clang/test/Rewriter/rewrite-try-catch.m b/clang/test/Rewriter/rewrite-try-catch.m deleted file mode 100644 index 06b198cda7175b..00000000000000 --- a/clang/test/Rewriter/rewrite-try-catch.m +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -std=c99 %s -o - - -@interface Foo @end -@interface GARF @end - -void TRY(void); -void SPLATCH(void); -void MYTRY(void); -void MYCATCH(void); - -void foo(void) { - @try { TRY(); } - @catch (...) { SPLATCH(); @throw; } -} - -int main(void) -{ - - @try { - MYTRY(); - } - - @catch (Foo* localException) { - MYCATCH(); - @throw; - } - - // no catch clause - @try { } - @finally { } -} - diff --git a/clang/test/Rewriter/rewrite-typeof.mm b/clang/test/Rewriter/rewrite-typeof.mm deleted file mode 100644 index c3dcf439ffb0b1..00000000000000 --- a/clang/test/Rewriter/rewrite-typeof.mm +++ /dev/null @@ -1,38 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: FileCheck -check-prefix CHECK-LP --input-file=%t-rw.cpp %s - -extern "C" { -extern "C" void *_Block_copy(const void *aBlock); -extern "C" void _Block_release(const void *aBlock); -} - -int main() { - __attribute__((__blocks__(byref))) int a = 42; - int save_a = a; - - void (^b)(void) = ^{ - ((__typeof(^{ a = 2; }))_Block_copy((const void *)(^{ a = 2; }))); - }; - - ((__typeof(b))_Block_copy((const void *)(b))); - - return 0; -} - -// CHECK-LP: ((void (^)(void))_Block_copy((const void *)(b))) - -void f() { - int a; - __typeof__(a) aVal = a; - char *a1t = (char *)@encode(__typeof__(a)); - __typeof__(aVal) bVal; - char *a2t = (char *)@encode(__typeof__(bVal)); - __typeof__(bVal) cVal = bVal; - char *a3t = (char *)@encode(__typeof__(cVal)); - -} - - -// CHECK-LP: int aVal = a; - -// CHECK-LP: int bVal; diff --git a/clang/test/Rewriter/rewrite-unique-block-api.mm b/clang/test/Rewriter/rewrite-unique-block-api.mm deleted file mode 100644 index 5058fbd0fa9f98..00000000000000 --- a/clang/test/Rewriter/rewrite-unique-block-api.mm +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp - -typedef unsigned long size_t; -void f(void (^b)(char c)); - -@interface a -- (void)processStuff; -@end - -@implementation a -- (void)processStuff { - f(^(char x) { }); -} -@end - -@interface b -- (void)processStuff; -@end - -@implementation b -- (void)processStuff { - f(^(char x) { }); -} -@end diff --git a/clang/test/Rewriter/rewrite-user-defined-accessors.mm b/clang/test/Rewriter/rewrite-user-defined-accessors.mm deleted file mode 100644 index 74f092cbd42167..00000000000000 --- a/clang/test/Rewriter/rewrite-user-defined-accessors.mm +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -Did="void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -@interface Foo { - Foo *foo; -} - -@property (retain, nonatomic) Foo *foo; - -@end - -@implementation Foo - -- (Foo *)foo { - if (!foo) { - foo = 0; - } - return foo; -} - - -- (void) setFoo : (Foo *) arg { - foo = arg; -} - -@synthesize foo; - -@end - diff --git a/clang/test/Rewriter/rewrite-vararg.m b/clang/test/Rewriter/rewrite-vararg.m deleted file mode 100644 index 58791bbb4761a8..00000000000000 --- a/clang/test/Rewriter/rewrite-vararg.m +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp -// RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp - -void *sel_registerName(const char *); - -@interface NSObject @end -@class NSString; - -@protocol P - -(void)ParliamentFunkadelic; -@end - -@interface Foo { - NSObject

*_dataSource; -} -@end - -@interface Bar { } -+(void)WhateverBar:(NSString*)format, ...; -@end - -@implementation Foo --(void)WhateverFoo { - [Bar WhateverBar:@"ISyncSessionDriverDataSource %@ responded poorly", _dataSource]; -} -@end diff --git a/clang/test/Rewriter/rewrite-weak-attr.m b/clang/test/Rewriter/rewrite-weak-attr.m deleted file mode 100644 index 196f1d3c6e952f..00000000000000 --- a/clang/test/Rewriter/rewrite-weak-attr.m +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -fblocks -Dnil=0 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 -o - %s -int main(void) { - __weak __block id foo = nil; - __block id foo2 = nil; - id foo3 = nil; - - void (^myblock)(void) = ^{ - foo = nil; - foo2 = nil; - [foo3 bar]; - id foo4 = foo3; - }; -} diff --git a/clang/test/Rewriter/static-type-protocol-1.m b/clang/test/Rewriter/static-type-protocol-1.m deleted file mode 100644 index dbf9d38670fc5b..00000000000000 --- a/clang/test/Rewriter/static-type-protocol-1.m +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@protocol Proto -- (void) ProtoDidget; -@end - -@protocol MyProto -- (void) widget; -@end - -@interface Foo -- (void)StillMode; -@end - -@interface Container -+ (void)MyMeth; -@end - -@implementation Container -+ (void)MyMeth -{ - Foo *view; - [(Foo *)view StillMode]; - [(Foo *)view widget]; - [(Foo *)view ProtoDidget]; -} -@end diff --git a/clang/test/Rewriter/undecl-objc-h.m b/clang/test/Rewriter/undecl-objc-h.m deleted file mode 100644 index 2581aa598a8920..00000000000000 --- a/clang/test/Rewriter/undecl-objc-h.m +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -typedef struct S { - int * pint; - int size; -}NSRec; - -@interface SUPER -- (NSRec) MainMethod : (NSRec) Arg1 : (NSRec) Arg2; -@end - -@interface MyDerived : SUPER -{ - NSRec d; -} -- (int) instanceMethod; -- (int) another : (int) arg; -- (NSRec) MainMethod : (NSRec) Arg1 : (NSRec) Arg2; -@end - -@implementation MyDerived -- (int) instanceMethod { - return [self another : [self MainMethod : d : d].size]; -} - -- (int) another : (int) arg { return arg; } -- (NSRec) MainMethod : (NSRec) Arg1 : (NSRec) Arg2 { return Arg2; } -@end - diff --git a/clang/test/Rewriter/undeclared-method-1.m b/clang/test/Rewriter/undeclared-method-1.m deleted file mode 100644 index a52c677bc72108..00000000000000 --- a/clang/test/Rewriter/undeclared-method-1.m +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@interface Derived @end - -int main(void) { - Derived *v ; - [v free]; - return 0; -} diff --git a/clang/test/Rewriter/undef-field-reference-1.m b/clang/test/Rewriter/undef-field-reference-1.m deleted file mode 100644 index 3bffd3897ed25e..00000000000000 --- a/clang/test/Rewriter/undef-field-reference-1.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -@interface MyDerived -{ -@public - int IVAR; -} -@end - -MyDerived *pd; -int main(void) { - return pd->IVAR; -} - - diff --git a/clang/test/Rewriter/unnamed-bf-modern-write.mm b/clang/test/Rewriter/unnamed-bf-modern-write.mm deleted file mode 100644 index fa1e4a86898a14..00000000000000 --- a/clang/test/Rewriter/unnamed-bf-modern-write.mm +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %clang_cc1 -E %s -o %t.mm -// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s - -@interface Foo { -@private - int first; - int :1; - int third :1; - int :1; - int fifth :1; -} -@end -@implementation Foo -@end - -// CHECK: struct Foo__T_1 { -// CHECK-NEXT: int : 1; -// CHECK-NEXT: int third : 1; -// CHECK-NEXT: int : 1; -// CHECK-NEXT: int fifth : 1; -// CHECK-NEXT: char : 0; -// CHECK-NEXT: } ; -// CHECK: struct Foo_IMPL { -// CHECK-NEXT: int first; -// CHECK-NEXT: struct Foo__T_1 Foo__GRBF_1; -// CHECK-NEXT: }; diff --git a/clang/test/Rewriter/va-method.m b/clang/test/Rewriter/va-method.m deleted file mode 100644 index 78d9367819b512..00000000000000 --- a/clang/test/Rewriter/va-method.m +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -#include - -@interface NSObject @end -@interface XX : NSObject @end - -@implementation XX -- (void)encodeValuesOfObjCTypes:(const char *)types, ... { - va_list ap; - va_start(ap, types); - while (*types) ; - va_end(ap); -} - -@end - diff --git a/clang/test/Rewriter/weak_byref_objects.m b/clang/test/Rewriter/weak_byref_objects.m deleted file mode 100644 index 52111c10edc017..00000000000000 --- a/clang/test/Rewriter/weak_byref_objects.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -fblocks -triple i386-apple-darwin9 -fobjc-gc -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o - - -#define nil 0 -int main(void) { - __weak __block id foo = nil; - __block id foo2 = nil; - id foo3 = nil; - - void (^myblock)(void) = ^{ - foo = nil; - foo2 = nil; - [foo3 bar]; - id foo4 = foo3; - }; -} diff --git a/clang/test/Rewriter/missing-dllimport.c b/clang/test/Sema/missing-dllimport.c similarity index 100% rename from clang/test/Rewriter/missing-dllimport.c rename to clang/test/Sema/missing-dllimport.c diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index 1cbd876ac5bb93..0e27f5e0bfc957 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -22,7 +22,6 @@ config.host_cxx = "@CMAKE_CXX_COMPILER@" config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" config.have_zlib = @LLVM_ENABLE_ZLIB@ config.have_zstd = @LLVM_ENABLE_ZSTD@ -config.clang_arcmt = @CLANG_ENABLE_ARCMT@ config.clang_default_pie_on_linux = @CLANG_DEFAULT_PIE_ON_LINUX@ config.clang_default_cxx_stdlib = "@CLANG_DEFAULT_CXX_STDLIB@" config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@ diff --git a/clang/tools/CMakeLists.txt b/clang/tools/CMakeLists.txt index 98c018e96848df..de0b47f3751f1a 100644 --- a/clang/tools/CMakeLists.txt +++ b/clang/tools/CMakeLists.txt @@ -27,11 +27,6 @@ if(UNIX OR (MSVC AND LLVM_BUILD_LLVM_DYLIB_VIS) OR (MINGW AND LLVM_LINK_LLVM_DYL add_clang_subdirectory(clang-shlib) endif() -if(CLANG_ENABLE_ARCMT) - add_clang_subdirectory(arcmt-test) - add_clang_subdirectory(c-arcmt-test) -endif() - if(CLANG_ENABLE_STATIC_ANALYZER) add_clang_subdirectory(clang-check) add_clang_subdirectory(clang-extdef-mapping) diff --git a/clang/tools/arcmt-test/CMakeLists.txt b/clang/tools/arcmt-test/CMakeLists.txt deleted file mode 100644 index d3e6580e16efaf..00000000000000 --- a/clang/tools/arcmt-test/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(LLVM_LINK_COMPONENTS - support - ) - -add_clang_executable(arcmt-test - arcmt-test.cpp - ) - -clang_target_link_libraries(arcmt-test - PRIVATE - clangARCMigrate - clangBasic - clangFrontend - clangLex - clangSerialization - ) diff --git a/clang/tools/arcmt-test/arcmt-test.cpp b/clang/tools/arcmt-test/arcmt-test.cpp deleted file mode 100644 index b61f38e9905dba..00000000000000 --- a/clang/tools/arcmt-test/arcmt-test.cpp +++ /dev/null @@ -1,376 +0,0 @@ -//===-- arcmt-test.cpp - ARC Migration Tool testbed -----------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "clang/ARCMigrate/ARCMT.h" -#include "clang/AST/ASTContext.h" -#include "clang/Frontend/PCHContainerOperations.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Frontend/Utils.h" -#include "clang/Frontend/VerifyDiagnosticConsumer.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Lex/PreprocessorOptions.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Signals.h" -#include - -using namespace clang; -using namespace arcmt; - -static llvm::cl::opt -CheckOnly("check-only", - llvm::cl::desc("Just check for issues that need to be handled manually")); - -//static llvm::cl::opt -//TestResultForARC("test-result", -//llvm::cl::desc("Test the result of transformations by parsing it in ARC mode")); - -static llvm::cl::opt -OutputTransformations("output-transformations", - llvm::cl::desc("Print the source transformations")); - -static llvm::cl::opt -VerifyDiags("verify",llvm::cl::desc("Verify emitted diagnostics and warnings")); - -static llvm::cl::opt -VerboseOpt("v", llvm::cl::desc("Enable verbose output")); - -static llvm::cl::opt -VerifyTransformedFiles("verify-transformed-files", -llvm::cl::desc("Read pairs of file mappings (typically the output of " - "c-arcmt-test) and compare their contents with the filenames " - "provided in command-line")); - -static llvm::cl::opt -RemappingsFile("remappings-file", - llvm::cl::desc("Pairs of file mappings (typically the output of " - "c-arcmt-test)")); - -static llvm::cl::list -ResultFiles(llvm::cl::Positional, llvm::cl::desc("...")); - -static llvm::cl::extrahelp extraHelp( - "\nusage with compiler args: arcmt-test [options] --args [compiler flags]\n"); - -// This function isn't referenced outside its translation unit, but it -// can't use the "static" keyword because its address is used for -// GetMainExecutable (since some platforms don't support taking the -// address of main, and some platforms can't implement GetMainExecutable -// without being given the address of a function in the main executable). -std::string GetExecutablePath(const char *Argv0) { - // This just needs to be some symbol in the binary; C++ doesn't - // allow taking the address of ::main however. - void *MainAddr = (void*) (intptr_t) GetExecutablePath; - return llvm::sys::fs::getMainExecutable(Argv0, MainAddr); -} - -static void printSourceLocation(SourceLocation loc, ASTContext &Ctx, - raw_ostream &OS); -static void printSourceRange(CharSourceRange range, ASTContext &Ctx, - raw_ostream &OS); - -namespace { - -class PrintTransforms : public MigrationProcess::RewriteListener { - ASTContext *Ctx; - raw_ostream &OS; - -public: - PrintTransforms(raw_ostream &OS) - : Ctx(nullptr), OS(OS) {} - - void start(ASTContext &ctx) override { Ctx = &ctx; } - void finish() override { Ctx = nullptr; } - - void insert(SourceLocation loc, StringRef text) override { - assert(Ctx); - OS << "Insert: "; - printSourceLocation(loc, *Ctx, OS); - OS << " \"" << text << "\"\n"; - } - - void remove(CharSourceRange range) override { - assert(Ctx); - OS << "Remove: "; - printSourceRange(range, *Ctx, OS); - OS << '\n'; - } -}; - -} // anonymous namespace - -static bool checkForMigration(StringRef resourcesPath, - ArrayRef Args) { - IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); - DiagnosticConsumer *DiagClient = - new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient)); - // Chain in -verify checker, if requested. - VerifyDiagnosticConsumer *verifyDiag = nullptr; - if (VerifyDiags) { - verifyDiag = new VerifyDiagnosticConsumer(*Diags); - Diags->setClient(verifyDiag); - } - - CompilerInvocation CI; - if (!CompilerInvocation::CreateFromArgs(CI, Args, *Diags)) - return true; - - if (CI.getFrontendOpts().Inputs.empty()) { - llvm::errs() << "error: no input files\n"; - return true; - } - - if (!CI.getLangOpts().ObjC) - return false; - - arcmt::checkForManualIssues(CI, CI.getFrontendOpts().Inputs[0], - std::make_shared(), - Diags->getClient()); - return Diags->getClient()->getNumErrors() > 0; -} - -static void printResult(FileRemapper &remapper, raw_ostream &OS) { - remapper.forEachMapping([](StringRef, StringRef) {}, - [&](StringRef, const llvm::MemoryBufferRef &Buffer) { - OS << Buffer.getBuffer(); - }); -} - -static bool performTransformations(StringRef resourcesPath, - ArrayRef Args) { - // Check first. - if (checkForMigration(resourcesPath, Args)) - return true; - - IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); - DiagnosticConsumer *DiagClient = - new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr TopDiags( - new DiagnosticsEngine(DiagID, &*DiagOpts, &*DiagClient)); - - CompilerInvocation origCI; - if (!CompilerInvocation::CreateFromArgs(origCI, Args, *TopDiags)) - return true; - - if (origCI.getFrontendOpts().Inputs.empty()) { - llvm::errs() << "error: no input files\n"; - return true; - } - - if (!origCI.getLangOpts().ObjC) - return false; - - MigrationProcess migration(origCI, std::make_shared(), - DiagClient); - - std::vector - transforms = arcmt::getAllTransformations(origCI.getLangOpts().getGC(), - origCI.getMigratorOpts().NoFinalizeRemoval); - assert(!transforms.empty()); - - std::unique_ptr transformPrinter; - if (OutputTransformations) - transformPrinter.reset(new PrintTransforms(llvm::outs())); - - for (unsigned i=0, e = transforms.size(); i != e; ++i) { - bool err = migration.applyTransform(transforms[i], transformPrinter.get()); - if (err) return true; - - if (VerboseOpt) { - if (i == e-1) - llvm::errs() << "\n##### FINAL RESULT #####\n"; - else - llvm::errs() << "\n##### OUTPUT AFTER "<< i+1 <<". TRANSFORMATION #####\n"; - printResult(migration.getRemapper(), llvm::errs()); - llvm::errs() << "\n##########################\n\n"; - } - } - - if (!OutputTransformations) - printResult(migration.getRemapper(), llvm::outs()); - - // FIXME: TestResultForARC - - return false; -} - -static bool filesCompareEqual(StringRef fname1, StringRef fname2) { - using namespace llvm; - - ErrorOr> file1 = - MemoryBuffer::getFile(fname1, /*IsText=*/true); - if (!file1) - return false; - - ErrorOr> file2 = - MemoryBuffer::getFile(fname2, /*IsText=*/true); - if (!file2) - return false; - - return file1.get()->getBuffer() == file2.get()->getBuffer(); -} - -static bool verifyTransformedFiles(ArrayRef resultFiles) { - using namespace llvm; - - assert(!resultFiles.empty()); - - std::map resultMap; - - for (ArrayRef::iterator - I = resultFiles.begin(), E = resultFiles.end(); I != E; ++I) { - StringRef fname(*I); - if (!fname.ends_with(".result")) { - errs() << "error: filename '" << fname - << "' does not have '.result' extension\n"; - return true; - } - resultMap[sys::path::stem(fname)] = fname; - } - - ErrorOr> inputBuf = std::error_code(); - if (RemappingsFile.empty()) - inputBuf = MemoryBuffer::getSTDIN(); - else - inputBuf = MemoryBuffer::getFile(RemappingsFile, /*IsText=*/true); - if (!inputBuf) { - errs() << "error: could not read remappings input\n"; - return true; - } - - SmallVector strs; - inputBuf.get()->getBuffer().split(strs, "\n", /*MaxSplit=*/-1, - /*KeepEmpty=*/false); - - if (strs.empty()) { - errs() << "error: no files to verify from stdin\n"; - return true; - } - if (strs.size() % 2 != 0) { - errs() << "error: files to verify are not original/result pairs\n"; - return true; - } - - for (unsigned i = 0, e = strs.size(); i != e; i += 2) { - StringRef inputOrigFname = strs[i]; - StringRef inputResultFname = strs[i+1]; - - std::map::iterator It; - It = resultMap.find(sys::path::filename(inputOrigFname)); - if (It == resultMap.end()) { - errs() << "error: '" << inputOrigFname << "' is not in the list of " - << "transformed files to verify\n"; - return true; - } - - if (!sys::fs::exists(It->second)) { - errs() << "error: '" << It->second << "' does not exist\n"; - return true; - } - if (!sys::fs::exists(inputResultFname)) { - errs() << "error: '" << inputResultFname << "' does not exist\n"; - return true; - } - - if (!filesCompareEqual(It->second, inputResultFname)) { - errs() << "error: '" << It->second << "' is different than " - << "'" << inputResultFname << "'\n"; - return true; - } - - resultMap.erase(It); - } - - if (!resultMap.empty()) { - for (std::map::iterator - I = resultMap.begin(), E = resultMap.end(); I != E; ++I) - errs() << "error: '" << I->second << "' was not verified!\n"; - return true; - } - - return false; -} - -//===----------------------------------------------------------------------===// -// Misc. functions. -//===----------------------------------------------------------------------===// - -static void printSourceLocation(SourceLocation loc, ASTContext &Ctx, - raw_ostream &OS) { - SourceManager &SM = Ctx.getSourceManager(); - PresumedLoc PL = SM.getPresumedLoc(loc); - - OS << llvm::sys::path::filename(PL.getFilename()); - OS << ":" << PL.getLine() << ":" - << PL.getColumn(); -} - -static void printSourceRange(CharSourceRange range, ASTContext &Ctx, - raw_ostream &OS) { - SourceManager &SM = Ctx.getSourceManager(); - const LangOptions &langOpts = Ctx.getLangOpts(); - - PresumedLoc PL = SM.getPresumedLoc(range.getBegin()); - - OS << llvm::sys::path::filename(PL.getFilename()); - OS << " [" << PL.getLine() << ":" - << PL.getColumn(); - OS << " - "; - - SourceLocation end = range.getEnd(); - PL = SM.getPresumedLoc(end); - - unsigned endCol = PL.getColumn() - 1; - if (!range.isTokenRange()) - endCol += Lexer::MeasureTokenLength(end, SM, langOpts); - OS << PL.getLine() << ":" << endCol << "]"; -} - -//===----------------------------------------------------------------------===// -// Command line processing. -//===----------------------------------------------------------------------===// - -int main(int argc, const char **argv) { - void *MainAddr = (void*) (intptr_t) GetExecutablePath; - llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); - - std::string - resourcesPath = CompilerInvocation::GetResourcesPath(argv[0], MainAddr); - - int optargc = 0; - for (; optargc != argc; ++optargc) { - if (StringRef(argv[optargc]) == "--args") - break; - } - llvm::cl::ParseCommandLineOptions(optargc, argv, "arcmt-test"); - - if (VerifyTransformedFiles) { - if (ResultFiles.empty()) { - llvm::cl::PrintHelpMessage(); - return 1; - } - return verifyTransformedFiles(ResultFiles); - } - - if (optargc == argc) { - llvm::cl::PrintHelpMessage(); - return 1; - } - - ArrayRef Args(argv+optargc+1, argc-optargc-1); - - if (CheckOnly) - return checkForMigration(resourcesPath, Args); - - return performTransformations(resourcesPath, Args); -} diff --git a/clang/tools/c-arcmt-test/CMakeLists.txt b/clang/tools/c-arcmt-test/CMakeLists.txt deleted file mode 100644 index 08ac93c176db12..00000000000000 --- a/clang/tools/c-arcmt-test/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -add_clang_executable(c-arcmt-test - c-arcmt-test.c - ) - -if (LLVM_BUILD_STATIC) - target_link_libraries(c-arcmt-test - PRIVATE - libclang_static - ) -else() - target_link_libraries(c-arcmt-test - PRIVATE - libclang - ) -endif() - -set_target_properties(c-arcmt-test - PROPERTIES - LINKER_LANGUAGE CXX) diff --git a/clang/tools/c-arcmt-test/c-arcmt-test.c b/clang/tools/c-arcmt-test/c-arcmt-test.c deleted file mode 100644 index 4d0c418714b950..00000000000000 --- a/clang/tools/c-arcmt-test/c-arcmt-test.c +++ /dev/null @@ -1,138 +0,0 @@ -/* c-arcmt-test.c */ - -#include "clang-c/Index.h" -#include "llvm/Support/AutoConvert.h" -#include -#include -#include -#if defined(_WIN32) -#include -#include -#endif - -static int print_remappings(const char *path) { - CXRemapping remap; - unsigned i, N; - CXString origFname; - CXString transFname; - - remap = clang_getRemappings(path); - if (!remap) - return 1; - - N = clang_remap_getNumFiles(remap); - for (i = 0; i != N; ++i) { - clang_remap_getFilenames(remap, i, &origFname, &transFname); - - fprintf(stdout, "%s\n", clang_getCString(origFname)); - fprintf(stdout, "%s\n", clang_getCString(transFname)); - - clang_disposeString(origFname); - clang_disposeString(transFname); - } - - clang_remap_dispose(remap); - return 0; -} - -static int print_remappings_filelist(const char **files, unsigned numFiles) { - CXRemapping remap; - unsigned i, N; - CXString origFname; - CXString transFname; - - remap = clang_getRemappingsFromFileList(files, numFiles); - if (!remap) - return 1; - - N = clang_remap_getNumFiles(remap); - for (i = 0; i != N; ++i) { - clang_remap_getFilenames(remap, i, &origFname, &transFname); - - fprintf(stdout, "%s\n", clang_getCString(origFname)); - fprintf(stdout, "%s\n", clang_getCString(transFname)); - - clang_disposeString(origFname); - clang_disposeString(transFname); - } - - clang_remap_dispose(remap); - return 0; -} - -/******************************************************************************/ -/* Command line processing. */ -/******************************************************************************/ - -static void print_usage(void) { - fprintf(stderr, - "usage: c-arcmt-test -mt-migrate-directory \n" - " c-arcmt-test ...\n\n\n"); -} - -/***/ - -int carcmttest_main(int argc, const char **argv) { - clang_enableStackTraces(); - if (argc == 3 && strncmp(argv[1], "-mt-migrate-directory", 21) == 0) - return print_remappings(argv[2]); - - if (argc > 1) - return print_remappings_filelist(argv+1, argc-1); - - print_usage(); - return 1; -} - -/***/ - -/* We intentionally run in a separate thread to ensure we at least minimal - * testing of a multithreaded environment (for example, having a reduced stack - * size). */ - -typedef struct thread_info { - int argc; - const char **argv; - int result; -} thread_info; -void thread_runner(void *client_data_v) { - thread_info *client_data = client_data_v; - client_data->result = carcmttest_main(client_data->argc, client_data->argv); -} - -static void flush_atexit(void) { - /* stdout, and surprisingly even stderr, are not always flushed on process - * and thread exit, particularly when the system is under heavy load. */ - fflush(stdout); - fflush(stderr); -} - -int main(int argc, const char **argv) { -#ifdef __MVS__ - if (enablezOSAutoConversion(fileno(stdout)) == -1) - fprintf(stderr, "Setting conversion on stdout failed\n"); - - if (enablezOSAutoConversion(fileno(stderr)) == -1) - fprintf(stderr, "Setting conversion on stderr failed\n"); -#endif - - thread_info client_data; - - atexit(flush_atexit); - -#if defined(_WIN32) - if (getenv("LIBCLANG_LOGGING") == NULL) - putenv("LIBCLANG_LOGGING=1"); - _setmode( _fileno(stdout), _O_BINARY ); -#else - setenv("LIBCLANG_LOGGING", "1", /*overwrite=*/0); -#endif - - if (getenv("CINDEXTEST_NOTHREADS")) - return carcmttest_main(argc, argv); - - client_data.argc = argc; - client_data.argv = argv; - clang_executeOnThread(thread_runner, &client_data, 0); - return client_data.result; -} diff --git a/clang/tools/libclang/ARCMigrate.cpp b/clang/tools/libclang/ARCMigrate.cpp deleted file mode 100644 index da8a7e4b9130b9..00000000000000 --- a/clang/tools/libclang/ARCMigrate.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//===- ARCMigrate.cpp - Clang-C ARC Migration Library ---------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements the main API hooks in the Clang-C ARC Migration library. -// -//===----------------------------------------------------------------------===// - -#include "clang-c/Index.h" -#include "CXString.h" -#include "clang/ARCMigrate/ARCMT.h" -#include "clang/Config/config.h" -#include "clang/Frontend/TextDiagnosticBuffer.h" -#include "llvm/Support/FileSystem.h" - -using namespace clang; -using namespace arcmt; - -namespace { - -struct Remap { - std::vector > Vec; -}; - -} // anonymous namespace. - -//===----------------------------------------------------------------------===// -// libClang public APIs. -//===----------------------------------------------------------------------===// - -CXRemapping clang_getRemappings(const char *migrate_dir_path) { -#if !CLANG_ENABLE_ARCMT - llvm::errs() << "error: feature not enabled in this build\n"; - return nullptr; -#else - bool Logging = ::getenv("LIBCLANG_LOGGING"); - - if (!migrate_dir_path) { - if (Logging) - llvm::errs() << "clang_getRemappings was called with NULL parameter\n"; - return nullptr; - } - - if (!llvm::sys::fs::exists(migrate_dir_path)) { - if (Logging) { - llvm::errs() << "Error by clang_getRemappings(\"" << migrate_dir_path - << "\")\n"; - llvm::errs() << "\"" << migrate_dir_path << "\" does not exist\n"; - } - return nullptr; - } - - TextDiagnosticBuffer diagBuffer; - std::unique_ptr remap(new Remap()); - - bool err = arcmt::getFileRemappings(remap->Vec, migrate_dir_path,&diagBuffer); - - if (err) { - if (Logging) { - llvm::errs() << "Error by clang_getRemappings(\"" << migrate_dir_path - << "\")\n"; - for (TextDiagnosticBuffer::const_iterator - I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I) - llvm::errs() << I->second << '\n'; - } - return nullptr; - } - - return remap.release(); -#endif -} - -CXRemapping clang_getRemappingsFromFileList(const char **filePaths, - unsigned numFiles) { -#if !CLANG_ENABLE_ARCMT - llvm::errs() << "error: feature not enabled in this build\n"; - return nullptr; -#else - bool Logging = ::getenv("LIBCLANG_LOGGING"); - - std::unique_ptr remap(new Remap()); - - if (numFiles == 0) { - if (Logging) - llvm::errs() << "clang_getRemappingsFromFileList was called with " - "numFiles=0\n"; - return remap.release(); - } - - if (!filePaths) { - if (Logging) - llvm::errs() << "clang_getRemappingsFromFileList was called with " - "NULL filePaths\n"; - return nullptr; - } - - TextDiagnosticBuffer diagBuffer; - SmallVector Files(filePaths, filePaths + numFiles); - - bool err = arcmt::getFileRemappingsFromFileList(remap->Vec, Files, - &diagBuffer); - - if (err) { - if (Logging) { - llvm::errs() << "Error by clang_getRemappingsFromFileList\n"; - for (TextDiagnosticBuffer::const_iterator - I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I) - llvm::errs() << I->second << '\n'; - } - return remap.release(); - } - - return remap.release(); -#endif -} - -unsigned clang_remap_getNumFiles(CXRemapping map) { - return static_cast(map)->Vec.size(); - -} - -void clang_remap_getFilenames(CXRemapping map, unsigned index, - CXString *original, CXString *transformed) { - if (original) - *original = cxstring::createDup( - static_cast(map)->Vec[index].first); - if (transformed) - *transformed = cxstring::createDup( - static_cast(map)->Vec[index].second); -} - -void clang_remap_dispose(CXRemapping map) { - delete static_cast(map); -} diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt index 00a1223c0831a7..299c14660f3d4c 100644 --- a/clang/tools/libclang/CMakeLists.txt +++ b/clang/tools/libclang/CMakeLists.txt @@ -20,7 +20,6 @@ endif() # to clean up previous inconsistencies. set(SOURCES - ARCMigrate.cpp BuildSystem.cpp CIndex.cpp CIndexCXX.cpp @@ -71,10 +70,6 @@ set(LIBS clangTooling ) -if (CLANG_ENABLE_ARCMT) - list(APPEND LIBS clangARCMigrate) -endif () - if (HAVE_LIBDL) list(APPEND LIBS ${CMAKE_DL_LIBS}) elseif (CLANG_BUILT_STANDALONE) @@ -208,9 +203,6 @@ if(ENABLE_SHARED) target_link_options(libclang PRIVATE "-Wl,--version-script,${CMAKE_CURRENT_SOURCE_DIR}/libclang.map") endif() # Ensure that libclang.so gets rebuilt when the linker script changes. - set_property(SOURCE ARCMigrate.cpp APPEND PROPERTY - OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libclang.map) - set_target_properties(libclang PROPERTIES VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX} ${LIBCLANG_SOVERSION_ARG}) diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map index 25d8ba57d32514..e274cfd010b3b9 100644 --- a/clang/tools/libclang/libclang.map +++ b/clang/tools/libclang/libclang.map @@ -327,8 +327,6 @@ LLVM_13 { clang_getRange; clang_getRangeEnd; clang_getRangeStart; - clang_getRemappings; - clang_getRemappingsFromFileList; clang_getResultType; clang_getSkippedRanges; clang_getSpecializedCursorTemplate; @@ -389,9 +387,6 @@ LLVM_13 { clang_parseTranslationUnit; clang_parseTranslationUnit2; clang_parseTranslationUnit2FullArgv; - clang_remap_dispose; - clang_remap_getFilenames; - clang_remap_getNumFiles; clang_reparseTranslationUnit; clang_saveTranslationUnit; clang_sortCodeCompletionResults; diff --git a/clang/unittests/Basic/DiagnosticTest.cpp b/clang/unittests/Basic/DiagnosticTest.cpp index 36a77c7247655f..419ca257308540 100644 --- a/clang/unittests/Basic/DiagnosticTest.cpp +++ b/clang/unittests/Basic/DiagnosticTest.cpp @@ -60,7 +60,7 @@ TEST(DiagnosticTest, suppressAndTrap) { // Diag that would set FatalErrorOccurred // (via non-note following a fatal error). - Diags.Report(diag::warn_mt_message) << "warning"; + Diags.Report(diag::warn_apinotes_message) << "warning"; EXPECT_TRUE(trap.hasErrorOccurred()); EXPECT_TRUE(trap.hasUnrecoverableErrorOccurred()); @@ -85,7 +85,7 @@ TEST(DiagnosticTest, fatalsAsError) { // Diag that would set FatalErrorOccurred // (via non-note following a fatal error). - Diags.Report(diag::warn_mt_message) << "warning"; + Diags.Report(diag::warn_apinotes_message) << "warning"; EXPECT_TRUE(Diags.hasErrorOccurred()); EXPECT_EQ(Diags.hasFatalErrorOccurred(), FatalsAsError ? 0u : 1u); diff --git a/clang/utils/analyzer/entrypoint.py b/clang/utils/analyzer/entrypoint.py index 4deb42db0a0b1f..c8dfc1a9f2ed84 100644 --- a/clang/utils/analyzer/entrypoint.py +++ b/clang/utils/analyzer/entrypoint.py @@ -54,7 +54,6 @@ def is_cmake_needed(): "cmake -G Ninja -DCMAKE_BUILD_TYPE=Release " "-DCMAKE_INSTALL_PREFIX=/analyzer -DLLVM_TARGETS_TO_BUILD=X86 " '-DLLVM_ENABLE_PROJECTS="clang;openmp" -DLLVM_BUILD_RUNTIME=OFF ' - "-DCLANG_ENABLE_ARCMT=OFF " "-DCLANG_ENABLE_STATIC_ANALYZER=ON" ) diff --git a/flang/docs/FlangDriver.md b/flang/docs/FlangDriver.md index 23cbab30ee903e..309c5e2024dd84 100644 --- a/flang/docs/FlangDriver.md +++ b/flang/docs/FlangDriver.md @@ -119,7 +119,7 @@ Internally, a `clangDriver` based compiler driver works by creating actions that correspond to various compilation phases, e.g. `PreprocessJobClass`, `CompileJobClass`, `BackendJobClass` or `LinkJobClass` from the `clang::driver::Action::ActionClass` enum. There are also other, more -specialised actions, e.g. `MigrateJobClass` or `InputClass`, that do not map +specialised actions, e.g. `InputClass`, that do not map directly to common compilation steps. The actions to run are determined from the supplied compiler flags, e.g. diff --git a/llvm/utils/gn/secondary/BUILD.gn b/llvm/utils/gn/secondary/BUILD.gn index 5590a5ba195e2b..72c4476a147892 100644 --- a/llvm/utils/gn/secondary/BUILD.gn +++ b/llvm/utils/gn/secondary/BUILD.gn @@ -1,4 +1,3 @@ -import("//clang/lib/ARCMigrate/enable.gni") import("//clang/lib/StaticAnalyzer/Frontend/enable.gni") import("//llvm/utils/gn/build/toolchain/compiler.gni") diff --git a/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn b/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn index bc0631dc269ac7..fc0f973dfd9b43 100644 --- a/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn @@ -1,4 +1,3 @@ -import("//clang/lib/ARCMigrate/enable.gni") import("//clang/lib/StaticAnalyzer/Frontend/enable.gni") import("//llvm/utils/gn/build/libs/xml/enable.gni") import("//llvm/utils/gn/build/write_cmake_config.gni") @@ -26,18 +25,11 @@ write_cmake_config("Config") { "GCC_INSTALL_PREFIX=", "ENABLE_LINKER_BUILD_ID=", "ENABLE_X86_RELAX_RELOCATIONS=1", - "CLANG_ENABLE_OBJC_REWRITER=1", # FIXME: flag? "CLANG_ENABLE_CIR=", "CLANG_SYSTEMZ_DEFAULT_ARCH=z10", "PPC_LINUX_DEFAULT_IEEELONGDOUBLE=", ] - if (clang_enable_arcmt) { - values += [ "CLANG_ENABLE_ARCMT=1" ] - } else { - values += [ "CLANG_ENABLE_ARCMT=" ] - } - if (clang_enable_static_analyzer) { values += [ "CLANG_ENABLE_STATIC_ANALYZER=1" ] } else { diff --git a/llvm/utils/gn/secondary/clang/lib/ARCMigrate/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/ARCMigrate/BUILD.gn deleted file mode 100644 index 8a790c0875ac08..00000000000000 --- a/llvm/utils/gn/secondary/clang/lib/ARCMigrate/BUILD.gn +++ /dev/null @@ -1,39 +0,0 @@ -static_library("ARCMigrate") { - output_name = "clangARCMigrate" - configs += [ "//llvm/utils/gn/build:clang_code" ] - deps = [ - "//clang/lib/AST", - "//clang/lib/Analysis", - "//clang/lib/Basic", - "//clang/lib/Edit", - "//clang/lib/Frontend", - "//clang/lib/Lex", - "//clang/lib/Rewrite", - "//clang/lib/Sema", - "//clang/lib/Serialization", - "//llvm/lib/Support", - "//llvm/lib/TargetParser", - ] - sources = [ - "ARCMT.cpp", - "ARCMTActions.cpp", - "FileRemapper.cpp", - "ObjCMT.cpp", - "PlistReporter.cpp", - "TransAPIUses.cpp", - "TransARCAssign.cpp", - "TransAutoreleasePool.cpp", - "TransBlockObjCVariable.cpp", - "TransEmptyStatementsAndDealloc.cpp", - "TransGCAttrs.cpp", - "TransGCCalls.cpp", - "TransProperties.cpp", - "TransProtectedScope.cpp", - "TransRetainReleaseDealloc.cpp", - "TransUnbridgedCasts.cpp", - "TransUnusedInitDelegate.cpp", - "TransZeroOutPropsInDealloc.cpp", - "TransformActions.cpp", - "Transforms.cpp", - ] -} diff --git a/llvm/utils/gn/secondary/clang/lib/ARCMigrate/enable.gni b/llvm/utils/gn/secondary/clang/lib/ARCMigrate/enable.gni deleted file mode 100644 index 7a7a42edbfd42b..00000000000000 --- a/llvm/utils/gn/secondary/clang/lib/ARCMigrate/enable.gni +++ /dev/null @@ -1,4 +0,0 @@ -declare_args() { - # Whether to include the arc migrate tool in the clang binary. - clang_enable_arcmt = true -} diff --git a/llvm/utils/gn/secondary/clang/lib/Frontend/Rewrite/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Frontend/Rewrite/BUILD.gn index 1f185cf8834a46..c3f948af45382a 100644 --- a/llvm/utils/gn/secondary/clang/lib/Frontend/Rewrite/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Frontend/Rewrite/BUILD.gn @@ -17,8 +17,6 @@ static_library("Rewrite") { "HTMLPrint.cpp", "InclusionRewriter.cpp", "RewriteMacros.cpp", - "RewriteModernObjC.cpp", - "RewriteObjC.cpp", "RewriteTest.cpp", ] } diff --git a/llvm/utils/gn/secondary/clang/lib/FrontendTool/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/FrontendTool/BUILD.gn index 15d838a45aed39..9f7140ed391ddc 100644 --- a/llvm/utils/gn/secondary/clang/lib/FrontendTool/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/FrontendTool/BUILD.gn @@ -1,9 +1,5 @@ -import("//clang/lib/ARCMigrate/enable.gni") import("//clang/lib/StaticAnalyzer/Frontend/enable.gni") -assert(clang_enable_static_analyzer || !clang_enable_arcmt, - "Cannot disable static analyzer while enabling ARCMT") - static_library("FrontendTool") { output_name = "clangFrontendTool" configs += [ "//llvm/utils/gn/build:clang_code" ] @@ -18,9 +14,6 @@ static_library("FrontendTool") { "//llvm/lib/Option", "//llvm/lib/Support", ] - if (clang_enable_arcmt) { - deps += [ "//clang/lib/ARCMigrate" ] - } if (clang_enable_static_analyzer) { deps += [ "//clang/lib/StaticAnalyzer/Frontend" ] } diff --git a/llvm/utils/gn/secondary/clang/test/BUILD.gn b/llvm/utils/gn/secondary/clang/test/BUILD.gn index 41edc072a55e7d..e9b4c55edcf549 100644 --- a/llvm/utils/gn/secondary/clang/test/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/test/BUILD.gn @@ -1,4 +1,3 @@ -import("//clang/lib/ARCMigrate/enable.gni") import("//clang/lib/StaticAnalyzer/Frontend/enable.gni") import("//llvm/include/llvm/Config/config.gni") import("//llvm/lib/Target/targets.gni") @@ -76,12 +75,6 @@ write_lit_config("lit_site_cfg") { "PPC_LINUX_DEFAULT_IEEELONGDOUBLE=0", ] - if (clang_enable_arcmt) { - extra_values += [ "CLANG_ENABLE_ARCMT=1" ] - } else { - extra_values += [ "CLANG_ENABLE_ARCMT=0" ] - } - if (clang_enable_static_analyzer) { extra_values += [ "CLANG_ENABLE_STATIC_ANALYZER=1" ] } else { @@ -210,12 +203,6 @@ group("test") { "//llvm/utils/not", "//llvm/utils/split-file", ] - if (clang_enable_arcmt) { - deps += [ - "//clang/tools/arcmt-test", - "//clang/tools/c-arcmt-test", - ] - } if (clang_enable_static_analyzer) { deps += [ "//clang/tools/clang-check", diff --git a/llvm/utils/gn/secondary/clang/tools/arcmt-test/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/arcmt-test/BUILD.gn deleted file mode 100644 index 8d7fece1bc0244..00000000000000 --- a/llvm/utils/gn/secondary/clang/tools/arcmt-test/BUILD.gn +++ /dev/null @@ -1,11 +0,0 @@ -executable("arcmt-test") { - configs += [ "//llvm/utils/gn/build:clang_code" ] - deps = [ - "//clang/lib/ARCMigrate", - "//clang/lib/Basic", - "//clang/lib/Frontend", - "//clang/lib/Lex", - "//llvm/lib/Support", - ] - sources = [ "arcmt-test.cpp" ] -} diff --git a/llvm/utils/gn/secondary/clang/tools/c-arcmt-test/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/c-arcmt-test/BUILD.gn deleted file mode 100644 index a1c8fe10b59048..00000000000000 --- a/llvm/utils/gn/secondary/clang/tools/c-arcmt-test/BUILD.gn +++ /dev/null @@ -1,11 +0,0 @@ -executable("c-arcmt-test") { - configs += [ "//llvm/utils/gn/build:clang_code" ] - deps = [ "//clang/tools/libclang" ] - sources = [ "c-arcmt-test.c" ] - - # See comment at top of clang/tools/libclang/BUILD.gn for why this isn't - # needed on Linux. - if (host_os == "mac") { - ldflags = [ "-Wl,-rpath,@loader_path/../lib" ] - } -} diff --git a/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn index 9ec7dc975721a5..8f7beea152ab7b 100644 --- a/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn @@ -1,4 +1,3 @@ -import("//clang/lib/ARCMigrate/enable.gni") import("//llvm/utils/gn/build/symbol_exports.gni") import("//llvm/version.gni") @@ -48,9 +47,6 @@ shared_library("libclang") { ldflags = [ "-Wl,--version-script," + rebase_path(inputs[0], root_build_dir) ] } - if (clang_enable_arcmt) { - deps += [ "//clang/lib/ARCMigrate" ] - } defines = [] @@ -60,7 +56,6 @@ shared_library("libclang") { sources = [ "../../include/clang-c/Index.h", - "ARCMigrate.cpp", "BuildSystem.cpp", "CIndex.cpp", "CIndexCXX.cpp", diff --git a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel index e2babada500516..ab473abfbf3e33 100644 --- a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel @@ -2177,33 +2177,6 @@ cc_library( ], ) -cc_library( - name = "arc_migrate", - srcs = glob([ - "lib/ARCMigrate/*.cpp", - "lib/ARCMigrate/*.h", - ]), - hdrs = glob(["include/clang/ARCMigrate/*.h"]), - includes = ["include"], - deps = [ - ":analysis", - ":ast", - ":basic", - ":edit", - ":frontend", - ":frontend_rewrite", - ":lex", - ":parse", - ":rewrite", - ":sema", - ":serialization", - ":static_analyzer_checkers", - ":static_analyzer_core", - "//llvm:Support", - "//llvm:TargetParser", - ], -) - cc_library( name = "libclang_static", srcs = glob([ @@ -2324,39 +2297,6 @@ cc_library( ], ) -cc_binary( - name = "arcmt-test", - testonly = 1, - srcs = ["tools/arcmt-test/arcmt-test.cpp"], - stamp = 0, - deps = [ - ":arc_migrate", - ":ast", - ":basic", - ":frontend", - ":frontend_rewrite", - ":lex", - "//llvm:Support", - ], -) - -cc_binary( - name = "c-arcmt-test", - testonly = 1, - srcs = ["tools/c-arcmt-test/c-arcmt-test.c"], - copts = select({ - "@platforms//os:windows": [], - "//conditions:default": ["-std=gnu99"], - }), - stamp = 0, - deps = [ - ":codegen", - ":libclang", - "//llvm:MC", - "//llvm:Support", - ], -) - cc_binary( name = "clang-import-test", testonly = 1, diff --git a/utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h b/utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h index ac0d9eb24931f1..e1f728c32e433b 100644 --- a/utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h +++ b/utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h @@ -93,8 +93,6 @@ #define ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER 0 /* Enable each functionality of modules */ -#define CLANG_ENABLE_ARCMT 1 -#define CLANG_ENABLE_OBJC_REWRITER 1 #define CLANG_ENABLE_STATIC_ANALYZER 1 /* Spawn a new process clang.exe for the CC1 tool invocation, when necessary */