This is an archive of the discontinued LLVM Phabricator instance.

[ObjC Availability] Implement parser support for Objective-C's @available
ClosedPublic

Authored by erik.pilkington on Jul 8 2016, 2:12 PM.

Details

Summary

This patch is the first of the feature I proposed on Monday here: http://lists.llvm.org/pipermail/cfe-dev/2016-July/049851.html

This patch adds a new AST node, ObjCAvailabilityCheckExpr, and teaches the parser and Sema to build it. Currently, if compiled without -fsyntax-only, Clang errors out in CodeGen. Up next is a patch that implements the availability violation warning itself, then CodeGen support.

ObjCAvailabilityCheckExpr is an predicate expression that will end up compiling into a runtime check of the host's OS version. It can be spelled in two ways:

@available(macos 10.10, *); // Objective-C only
__builtin_available(macos 10.10, *); // C, C++, and Objective-C

It's main purpose in life is to guard calls to API calls that are marked with an __attribute__((availability())) greater than the current deployment target, so users can safely use new APIs while still supporting old OS versions.

Thanks!

Diff Detail

Repository
rL LLVM

Event Timeline

erik.pilkington retitled this revision from to [ObjC Availability] Implement parser support for Objective-C's @available.
erik.pilkington updated this object.
erik.pilkington added a subscriber: cfe-commits.
manmanren edited edge metadata.Jul 11 2016, 11:45 AM

Thanks for working on this, Erik.

Manman

include/clang/AST/Availability.h
32 ↗(On Diff #63310)

Can you put a description for "Version"? i.e if it represents a range, specify the range here.

42 ↗(On Diff #63310)

Can you make this comment a full sentence?

51 ↗(On Diff #63310)

Same here.

include/clang/Basic/VersionTuple.h
29 ↗(On Diff #63310)

If this changes in this file are not related to @available, please commit it separately.

lib/AST/StmtPrinter.cpp
502 ↗(On Diff #63310)

Why not print other information of Node?

lib/Parse/ParseDecl.cpp
723 ↗(On Diff #63310)

I don't quite get what motivates this change. Are we not setting the range correctly before, for version tuples?

lib/Parse/ParseExpr.cpp
2875 ↗(On Diff #63310)

Please comment on the return value, i.e return true if invalid.

2957 ↗(On Diff #63310)

Why use "for (;;)" instead of "while(true)"?

2964 ↗(On Diff #63310)

Can you verify that when having error parsing a single spec, the compiler can still reasonably continue? Should we skip until the next comma, or the next right paren?

lib/Parse/ParseObjc.cpp
2863 ↗(On Diff #63310)

Should we move ConsumeToken to inside ParseAvailabilityCheckExpr, or at least provide a comment on skipping "@available", to be consistent with other parsing functions?

2865 ↗(On Diff #63310)

Is this a format change for "default:"? If yes, can you commit it before this @available change?

erik.pilkington edited edge metadata.

This patch addresses most of Manman's comments.

lib/AST/StmtPrinter.cpp
502 ↗(On Diff #63310)

Because by the time that we have the ObjCAvailabilityCheckExpr, we no longer keep track of the AvailabilitySpecs that are no longer relevant (ie, watchos if the platform we are targeting is macos), therefore we cannot replicate the text that lead to this particular @available. Is it worth it to carry these specs around? I can't think of any other time they are useful. (FWIW, many other AST nodes are also not fully supported, for example ObjCAtCatchStmt just above this.)

lib/Parse/ParseDecl.cpp
723 ↗(On Diff #63310)

Yes, Range = Tok.getLocation() sets both the Begin & End locations in Range to the same location, which makes us place the cursor at the wrong place in some diagnostics. I've fixed this a bit in the new patch.

manmanren accepted this revision.Jul 15 2016, 11:46 AM
manmanren edited edge metadata.

LGTM.

Manman

This revision is now accepted and ready to land.Jul 15 2016, 11:46 AM
This revision was automatically updated to reflect the committed changes.