1// RUN: %clang_cc1 -fsyntax-only -Wunguarded-availability -fdiagnostics-parseable-fixits -triple x86_64-apple-darwin9 %s 2>&1 | FileCheck %s
2
3__attribute__((availability(macos, introduced=10.12)))
4int function(void);
5
6void anotherFunction(int function);
7
8int use() {
9  function();
10// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
11// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n  } else {\n      // Fallback on earlier versions\n  }"
12  int y = function(), x = 0;
13// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
14// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:29-[[@LINE-2]]:29}:"\n  } else {\n      // Fallback on earlier versions\n  }"
15  x += function();
16// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
17// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:19-[[@LINE-2]]:19}:"\n  } else {\n      // Fallback on earlier versions\n  }"
18  if (1) {
19    x = function();
20// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n      "
21// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:20-[[@LINE-2]]:20}:"\n  } else {\n      // Fallback on earlier versions\n  }"
22  }
23  anotherFunction(function());
24// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
25// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:31-[[@LINE-2]]:31}:"\n  } else {\n      // Fallback on earlier versions\n  }"
26  if (function()) {
27// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
28// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+1]]:4-[[@LINE+1]]:4}:"\n  } else {\n      // Fallback on earlier versions\n  }"
29  }
30  while (function())
31    // CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
32    // CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+1]]:6-[[@LINE+1]]:6}:"\n  } else {\n      // Fallback on earlier versions\n  }"
33    ;
34  do
35    function();
36// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
37// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n    } else {\n        // Fallback on earlier versions\n    }"
38  while (1);
39  for (int i = 0; i < 10; ++i)
40    function();
41// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
42// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n    } else {\n        // Fallback on earlier versions\n    }"
43  switch (x) {
44  case 0:
45    function();
46// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
47// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n    } else {\n        // Fallback on earlier versions\n    }"
48  case 2:
49    anotherFunction(1);
50    function();
51// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
52// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n    } else {\n        // Fallback on earlier versions\n    }"
53    break;
54  default:
55    function();
56// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
57// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n    } else {\n        // Fallback on earlier versions\n    }"
58    break;
59  }
60  return function();
61// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
62// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:21-[[@LINE-2]]:21}:"\n  } else {\n      // Fallback on earlier versions\n  }"
63}
64
65#define MYFUNCTION function
66
67#define MACRO_ARGUMENT(X) X
68#define MACRO_ARGUMENT_SEMI(X) X;
69#define MACRO_ARGUMENT_2(X) if (1) X;
70
71#define INNER_MACRO if (1) MACRO_ARGUMENT(function()); else ;
72
73void useInMacros() {
74  MYFUNCTION();
75// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
76// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n  } else {\n      // Fallback on earlier versions\n  }"
77
78  MACRO_ARGUMENT_SEMI(function())
79// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
80// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:34-[[@LINE-2]]:34}:"\n  } else {\n      // Fallback on earlier versions\n  }"
81  MACRO_ARGUMENT(function());
82// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
83// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:30-[[@LINE-2]]:30}:"\n  } else {\n      // Fallback on earlier versions\n  }"
84  MACRO_ARGUMENT_2(function());
85// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
86// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:32-[[@LINE-2]]:32}:"\n  } else {\n      // Fallback on earlier versions\n  }"
87
88  INNER_MACRO
89// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
90// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n  } else {\n      // Fallback on earlier versions\n  }"
91}
92
93void wrapDeclStmtUses() {
94  int x = 0, y = function();
95// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
96// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+13]]:22-[[@LINE+13]]:22}:"\n  } else {\n      // Fallback on earlier versions\n  }"
97  {
98    int z = function();
99    if (z) {
100
101    }
102// CHECK: fix-it:{{.*}}:{[[@LINE-4]]:5-[[@LINE-4]]:5}:"if (@available(macOS 10.12, *)) {\n        "
103// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:6-[[@LINE-2]]:6}:"\n    } else {\n        // Fallback on earlier versions\n    }"
104  }
105  if (y)
106    int z = function();
107// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
108// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:24-[[@LINE-2]]:24}:"\n    } else {\n        // Fallback on earlier versions\n    }"
109  anotherFunction(y);
110  anotherFunction(x);
111
112  if (@available(macOS 10.1, *)) {
113    int z = function();
114    (void)z;
115// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:5-[[@LINE-2]]:5}:"if (@available(macOS 10.12, *)) {\n        "
116// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:13-[[@LINE-2]]:13}:"\n    } else {\n        // Fallback on earlier versions\n    }"
117    anotherFunction(x);
118  }
119}
120
121#define API_AVAILABLE(X) __attribute__((availability(macos, introduced=10.12))) // dummy macro
122
123API_AVAILABLE(macos(10.12))
124@interface NewClass
125@end
126
127@interface OldButOfferFixit
128@property(copy) NewClass *prop;
129// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:1-[[@LINE-2]]:1}:"API_AVAILABLE(macos(10.12))\n"
130
131- (NewClass *)fixitMe;
132// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:22-[[@LINE-1]]:22}:" API_AVAILABLE(macos(10.12))"
133@end
134
135void oldButOfferFixitFn(NewClass *) {
136// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:1-[[@LINE-1]]:1}:"API_AVAILABLE(macos(10.12))\n"
137}
138
139template<typename T>
140struct OldButOfferFixitTag {
141// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:7-[[@LINE-1]]:7}:" API_AVAILABLE(macos(10.12))"
142  NewClass *x;
143};
144
145// Avoid a fixit for declarations that already have an attribute:
146__attribute__((availability(macos, introduced=10.11)))
147@interface WithoutFixit
148@property(copy) NewClass *prop;
149// CHECK-NOT: API_AVAILABLE
150@end
151