From: Fariborz Jahanian Date: Mon, 6 Oct 2014 16:46:02 +0000 (+0000) Subject: Patch to wrap up '_' as separator in version numbers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=835452b27aa416dbe5e4e0f94a0d7aeda202f0e8;p=clang Patch to wrap up '_' as separator in version numbers in availability attribute by preserving this info. in VersionTuple and using it in pretty printing of attributes and yet using '.' as separator when diagnosing unavailable message calls. rdar://18490958 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219124 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h index 54d06e0739..77fd947f96 100644 --- a/include/clang/Basic/VersionTuple.h +++ b/include/clang/Basic/VersionTuple.h @@ -24,30 +24,35 @@ namespace clang { /// \brief Represents a version number in the form major[.minor[.subminor]]. class VersionTuple { - unsigned Major; + unsigned Major : 31; unsigned Minor : 31; unsigned Subminor : 31; unsigned HasMinor : 1; unsigned HasSubminor : 1; + unsigned UsesUnderscores : 1; public: VersionTuple() - : Major(0), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false) { } + : Major(0), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false), + UsesUnderscores(false) { } explicit VersionTuple(unsigned Major) - : Major(Major), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false) + : Major(Major), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false), + UsesUnderscores(false) { } - explicit VersionTuple(unsigned Major, unsigned Minor) + explicit VersionTuple(unsigned Major, unsigned Minor, + bool UsesUnderscores = false) : Major(Major), Minor(Minor), Subminor(0), HasMinor(true), - HasSubminor(false) + HasSubminor(false), UsesUnderscores(UsesUnderscores) { } - explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor) + explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor, + bool UsesUnderscores = false) : Major(Major), Minor(Minor), Subminor(Subminor), HasMinor(true), - HasSubminor(true) + HasSubminor(true), UsesUnderscores(UsesUnderscores) { } - + /// \brief Determine whether this version information is empty /// (e.g., all version components are zero). bool empty() const { return Major == 0 && Minor == 0 && Subminor == 0; } @@ -69,6 +74,14 @@ public: return Subminor; } + bool usesUnderscores() const { + return UsesUnderscores; + } + + void UseDotAsSeparator() { + UsesUnderscores = false; + } + /// \brief Determine if two version numbers are equivalent. If not /// provided, minor and subminor version numbers are considered to be zero. friend bool operator==(const VersionTuple& X, const VersionTuple &Y) { diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 49d05d0d40..014e3f9ef5 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -374,8 +374,10 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, if (Message) { Message->clear(); llvm::raw_string_ostream Out(*Message); + VersionTuple VTI(A->getIntroduced()); + VTI.UseDotAsSeparator(); Out << "introduced in " << PrettyPlatformName << ' ' - << A->getIntroduced() << HintMessage; + << VTI << HintMessage; } return AR_NotYetIntroduced; @@ -386,8 +388,10 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, if (Message) { Message->clear(); llvm::raw_string_ostream Out(*Message); + VersionTuple VTO(A->getObsoleted()); + VTO.UseDotAsSeparator(); Out << "obsoleted in " << PrettyPlatformName << ' ' - << A->getObsoleted() << HintMessage; + << VTO << HintMessage; } return AR_Unavailable; @@ -398,8 +402,10 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, if (Message) { Message->clear(); llvm::raw_string_ostream Out(*Message); + VersionTuple VTD(A->getDeprecated()); + VTD.UseDotAsSeparator(); Out << "first deprecated in " << PrettyPlatformName << ' ' - << A->getDeprecated() << HintMessage; + << VTD << HintMessage; } return AR_Deprecated; diff --git a/lib/Basic/VersionTuple.cpp b/lib/Basic/VersionTuple.cpp index 8b781ab0a3..aa43ae298e 100644 --- a/lib/Basic/VersionTuple.cpp +++ b/lib/Basic/VersionTuple.cpp @@ -29,9 +29,9 @@ raw_ostream& clang::operator<<(raw_ostream &Out, const VersionTuple &V) { Out << V.getMajor(); if (Optional Minor = V.getMinor()) - Out << '.' << *Minor; + Out << (V.usesUnderscores() ? '_' : '.') << *Minor; if (Optional Subminor = V.getSubminor()) - Out << '.' << *Subminor; + Out << (V.usesUnderscores() ? '_' : '.') << *Subminor; return Out; } diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 6b1289b6f2..b05af8fa76 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -714,7 +714,7 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { return VersionTuple(); } - return VersionTuple(Major, Minor); + return VersionTuple(Major, Minor, (AfterMajorSeparator == '_')); } const char AfterMinorSeparator = ThisTokBegin[AfterMinor]; @@ -745,7 +745,7 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { return VersionTuple(); } ConsumeToken(); - return VersionTuple(Major, Minor, Subminor); + return VersionTuple(Major, Minor, Subminor, (AfterMajorSeparator == '_')); } /// \brief Parse the contents of the "availability" attribute. diff --git a/test/Misc/ast-print-objectivec.m b/test/Misc/ast-print-objectivec.m index 5e7acd37b8..ef0fcaa9e3 100644 --- a/test/Misc/ast-print-objectivec.m +++ b/test/Misc/ast-print-objectivec.m @@ -11,7 +11,7 @@ @end @interface I(CAT) -- (void)MethCAT __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))); +- (void)MethCAT __attribute__((availability(macosx,introduced=10_1_0,deprecated=10_2))); @end @implementation I @@ -28,7 +28,7 @@ // CHECK: @end // CHECK: @interface I(CAT) -// CHECK: - (void) MethCAT __attribute__((availability(macosx, introduced=10.1.0, deprecated=10.2))); +// CHECK: - (void) MethCAT __attribute__((availability(macosx, introduced=10_1_0, deprecated=10_2))); // CHECK: @end // CHECK: @implementation I diff --git a/test/SemaObjC/attr-availability-1.m b/test/SemaObjC/attr-availability-1.m index 3a9a7d7ef6..af0fcfe353 100644 --- a/test/SemaObjC/attr-availability-1.m +++ b/test/SemaObjC/attr-availability-1.m @@ -21,10 +21,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 OS X (10.4 vs. 10.3)}} +- (void)overridden __attribute__((availability(macosx,introduced=10_4))); // expected-warning{{overriding method introduced after overridden method on OS X (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 OS X (10.3 vs. 10.2)}} +- (void)overridden4 __attribute__((availability(macosx,deprecated=10_2))); // expected-warning{{overriding method deprecated before overridden method on OS X (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 OS X when its overridden method is available}} @end