mirror of https://github.com/microsoft/clang.git
Use dotted format of version tuple for availability diagnostics
E. g. use "10.11" instead of "10_11". We are maintaining backward compatibility by parsing underscore-delimited version tuples but no longer keep track of the separator and using dot format for output. Differential Revision: https://reviews.llvm.org/D46747 rdar://problem/39845032 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@332598 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
be0479c04c
commit
ae156fd3e4
|
@ -24,9 +24,7 @@ namespace clang {
|
|||
|
||||
/// Represents a version number in the form major[.minor[.subminor[.build]]].
|
||||
class VersionTuple {
|
||||
unsigned Major : 31;
|
||||
|
||||
unsigned UsesUnderscores : 1;
|
||||
unsigned Major : 32;
|
||||
|
||||
unsigned Minor : 31;
|
||||
unsigned HasMinor : 1;
|
||||
|
@ -39,30 +37,25 @@ class VersionTuple {
|
|||
|
||||
public:
|
||||
VersionTuple()
|
||||
: Major(0), UsesUnderscores(false), Minor(0), HasMinor(false),
|
||||
Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {}
|
||||
: Major(0), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false),
|
||||
Build(0), HasBuild(false) {}
|
||||
|
||||
explicit VersionTuple(unsigned Major)
|
||||
: Major(Major), UsesUnderscores(false), Minor(0), HasMinor(false),
|
||||
Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {}
|
||||
: Major(Major), Minor(0), HasMinor(false), Subminor(0),
|
||||
HasSubminor(false), Build(0), HasBuild(false) {}
|
||||
|
||||
explicit VersionTuple(unsigned Major, unsigned Minor,
|
||||
bool UsesUnderscores = false)
|
||||
: Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
|
||||
HasMinor(true), Subminor(0), HasSubminor(false), Build(0),
|
||||
HasBuild(false) {}
|
||||
explicit VersionTuple(unsigned Major, unsigned Minor)
|
||||
: Major(Major), Minor(Minor), HasMinor(true), Subminor(0),
|
||||
HasSubminor(false), Build(0), HasBuild(false) {}
|
||||
|
||||
explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor)
|
||||
: Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
|
||||
HasSubminor(true), Build(0), HasBuild(false) {}
|
||||
|
||||
explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
|
||||
bool UsesUnderscores = false)
|
||||
: Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
|
||||
HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(0),
|
||||
HasBuild(false) {}
|
||||
|
||||
explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
|
||||
unsigned Build, bool UsesUnderscores = false)
|
||||
: Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor),
|
||||
HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(Build),
|
||||
HasBuild(true) {}
|
||||
unsigned Build)
|
||||
: Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
|
||||
HasSubminor(true), Build(Build), HasBuild(true) {}
|
||||
|
||||
/// Determine whether this version information is empty
|
||||
/// (e.g., all version components are zero).
|
||||
|
@ -93,14 +86,6 @@ public:
|
|||
return None;
|
||||
return Build;
|
||||
}
|
||||
|
||||
bool usesUnderscores() const {
|
||||
return UsesUnderscores;
|
||||
}
|
||||
|
||||
void UseDotAsSeparator() {
|
||||
UsesUnderscores = false;
|
||||
}
|
||||
|
||||
/// Determine if two version numbers are equivalent. If not
|
||||
/// provided, minor and subminor version numbers are considered to be zero.
|
||||
|
|
|
@ -550,7 +550,6 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
|
|||
Message->clear();
|
||||
llvm::raw_string_ostream Out(*Message);
|
||||
VersionTuple VTI(A->getIntroduced());
|
||||
VTI.UseDotAsSeparator();
|
||||
Out << "introduced in " << PrettyPlatformName << ' '
|
||||
<< VTI << HintMessage;
|
||||
}
|
||||
|
@ -564,7 +563,6 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
|
|||
Message->clear();
|
||||
llvm::raw_string_ostream Out(*Message);
|
||||
VersionTuple VTO(A->getObsoleted());
|
||||
VTO.UseDotAsSeparator();
|
||||
Out << "obsoleted in " << PrettyPlatformName << ' '
|
||||
<< VTO << HintMessage;
|
||||
}
|
||||
|
@ -578,7 +576,6 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
|
|||
Message->clear();
|
||||
llvm::raw_string_ostream Out(*Message);
|
||||
VersionTuple VTD(A->getDeprecated());
|
||||
VTD.UseDotAsSeparator();
|
||||
Out << "first deprecated in " << PrettyPlatformName << ' '
|
||||
<< VTD << HintMessage;
|
||||
}
|
||||
|
|
|
@ -29,11 +29,11 @@ raw_ostream& clang::operator<<(raw_ostream &Out,
|
|||
const VersionTuple &V) {
|
||||
Out << V.getMajor();
|
||||
if (Optional<unsigned> Minor = V.getMinor())
|
||||
Out << (V.usesUnderscores() ? '_' : '.') << *Minor;
|
||||
Out << '.' << *Minor;
|
||||
if (Optional<unsigned> Subminor = V.getSubminor())
|
||||
Out << (V.usesUnderscores() ? '_' : '.') << *Subminor;
|
||||
Out << '.' << *Subminor;
|
||||
if (Optional<unsigned> Build = V.getBuild())
|
||||
Out << (V.usesUnderscores() ? '_' : '.') << *Build;
|
||||
Out << '.' << *Build;
|
||||
return Out;
|
||||
}
|
||||
|
||||
|
|
|
@ -762,8 +762,10 @@ static bool VersionNumberSeparator(const char Separator) {
|
|||
///
|
||||
/// version:
|
||||
/// simple-integer
|
||||
/// simple-integer ',' simple-integer
|
||||
/// simple-integer ',' simple-integer ',' simple-integer
|
||||
/// simple-integer '.' simple-integer
|
||||
/// simple-integer '_' simple-integer
|
||||
/// simple-integer '.' simple-integer '.' simple-integer
|
||||
/// simple-integer '_' simple-integer '_' simple-integer
|
||||
VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
|
||||
Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
|
||||
|
||||
|
@ -841,7 +843,7 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
|
|||
return VersionTuple();
|
||||
}
|
||||
|
||||
return VersionTuple(Major, Minor, (AfterMajorSeparator == '_'));
|
||||
return VersionTuple(Major, Minor);
|
||||
}
|
||||
|
||||
const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
|
||||
|
@ -872,7 +874,7 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
|
|||
return VersionTuple();
|
||||
}
|
||||
ConsumeToken();
|
||||
return VersionTuple(Major, Minor, Subminor, (AfterMajorSeparator == '_'));
|
||||
return VersionTuple(Major, Minor, Subminor);
|
||||
}
|
||||
|
||||
/// Parse the contents of the "availability" attribute.
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
// CHECK: @end
|
||||
|
||||
// CHECK: @interface I(CAT)
|
||||
// CHECK: - (void)MethCAT __attribute__((availability(macos, introduced=10_1_0, deprecated=10_2)));
|
||||
// CHECK: - (void)MethCAT __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2)));
|
||||
// CHECK: @end
|
||||
|
||||
// CHECK: @implementation I
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-macosx-10.11 -Wunguarded-availability -fdiagnostics-parseable-fixits -fsyntax-only -verify %s
|
||||
|
||||
// Testing that even for source code using '_' as a delimiter in availability version tuple '.' is actually used in diagnostic output as a delimiter.
|
||||
|
||||
@interface foo
|
||||
- (void) method_bar __attribute__((availability(macosx, introduced = 10_12))); // expected-note {{'method_bar' has been explicitly marked partial here}}
|
||||
@end
|
||||
|
||||
int main() {
|
||||
[foo method_bar]; // \
|
||||
// expected-warning {{'method_bar' is only available on macOS 10.12 or newer}} \
|
||||
// expected-note {{enclose 'method_bar' in an @available check to silence this warning}} \
|
||||
// CHECK: "fix-it:.*if (@available(macOS 10.12, *))"
|
||||
return 0;
|
||||
}
|
|
@ -25,10 +25,10 @@
|
|||
// rdar://11475360
|
||||
@interface B : A
|
||||
- (void)method; // NOTE: we expect 'method' to *not* inherit availability.
|
||||
- (void)overridden __attribute__((availability(macosx,introduced=10_4))); // expected-warning{{overriding method introduced after overridden method on macOS (10_4 vs. 10_3)}}
|
||||
- (void)overridden __attribute__((availability(macosx,introduced=10_4))); // expected-warning{{overriding method introduced after overridden method on macOS (10.4 vs. 10.3)}}
|
||||
- (void)overridden2 __attribute__((availability(macosx,introduced=10_2)));
|
||||
- (void)overridden3 __attribute__((availability(macosx,deprecated=10_4)));
|
||||
- (void)overridden4 __attribute__((availability(macosx,deprecated=10_2))); // expected-warning{{overriding method deprecated before overridden method on macOS (10_3 vs. 10_2)}}
|
||||
- (void)overridden4 __attribute__((availability(macosx,deprecated=10_2))); // expected-warning{{overriding method deprecated before overridden method on macOS (10.3 vs. 10.2)}}
|
||||
- (void)overridden5 __attribute__((availability(macosx,introduced=10_3)));
|
||||
- (void)overridden6 __attribute__((availability(macosx,unavailable))); // expected-warning{{overriding method cannot be unavailable on macOS when its overridden method is available}}
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue