summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2013-12-04 20:32:50 +0000
committerFariborz Jahanian <fjahanian@apple.com>2013-12-04 20:32:50 +0000
commit1a2519a7e9743825dd19c5e958040b3350791b64 (patch)
treeba2b8bbaa9385199c85da067826ce3b7382611ae /clang/lib
parent17c357342a7397aca0710613b72139a7256836f8 (diff)
downloadbcm5719-llvm-1a2519a7e9743825dd19c5e958040b3350791b64.tar.gz
bcm5719-llvm-1a2519a7e9743825dd19c5e958040b3350791b64.zip
ObjectiveC - Introducing objc_bridge_related attribute
which specifies couple of (optional) method selectors for bridging a CFobject to or from an ObjectiveC object. This is wip. // rdsr://15499111 llvm-svn: 196408
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp90
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp21
2 files changed, 111 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 944942658ab..2c93def4c2b 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -259,6 +259,12 @@ void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
return;
}
+
+ if (AttrKind == AttributeList::AT_ObjCBridgeRelated) {
+ ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
+ return;
+ }
+
// Thread safety attributes are parsed in an unevaluated context.
// FIXME: Share the bulk of the parsing code here and just pull out
// the unevaluated context.
@@ -959,6 +965,90 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
AttributeList::AS_GNU);
}
+/// \brief Parse the contents of the "objc_bridge_related" attribute.
+/// objc_bridge_related '(' related_class ',' opt-class_method ',' opt-instance_method ')'
+/// related_class:
+/// Identifier
+///
+/// opt-class_method:
+/// Identifier: | <empty>
+///
+/// opt-instance_method:
+/// Identifier | <empty>
+///
+void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
+ SourceLocation ObjCBridgeRelatedLoc,
+ ParsedAttributes &attrs,
+ SourceLocation *endLoc) {
+ // Opening '('.
+ BalancedDelimiterTracker T(*this, tok::l_paren);
+ if (T.consumeOpen()) {
+ Diag(Tok, diag::err_expected_lparen);
+ return;
+ }
+
+ // Parse the related class name.
+ if (Tok.isNot(tok::identifier)) {
+ Diag(Tok, diag::err_objcbridge_related_expected_related_class);
+ SkipUntil(tok::r_paren, StopAtSemi);
+ return;
+ }
+ IdentifierLoc *RelatedClass = ParseIdentifierLoc();
+ if (Tok.isNot(tok::comma)) {
+ Diag(Tok, diag::err_expected_comma);
+ SkipUntil(tok::r_paren, StopAtSemi);
+ return;
+ }
+ ConsumeToken();
+
+ // Parse optional class method name.
+ IdentifierLoc *ClassMethod = 0;
+ if (Tok.is(tok::identifier)) {
+ ClassMethod = ParseIdentifierLoc();
+ if (Tok.isNot(tok::colon)) {
+ Diag(Tok, diag::err_objcbridge_related_selector_name);
+ SkipUntil(tok::r_paren, StopAtSemi);
+ return;
+ }
+ ConsumeToken();
+ }
+ if (Tok.isNot(tok::comma)) {
+ if (Tok.is(tok::colon))
+ Diag(Tok, diag::err_objcbridge_related_selector_name);
+ else
+ Diag(Tok, diag::err_expected_comma);
+ SkipUntil(tok::r_paren, StopAtSemi);
+ return;
+ }
+ ConsumeToken();
+
+ // Parse optional instance method name.
+ IdentifierLoc *InstanceMethod = 0;
+ if (Tok.is(tok::identifier))
+ InstanceMethod = ParseIdentifierLoc();
+ else if (Tok.isNot(tok::r_paren)) {
+ Diag(Tok, diag::err_expected_rparen);
+ SkipUntil(tok::r_paren, StopAtSemi);
+ return;
+ }
+
+ // Closing ')'.
+ if (T.consumeClose())
+ return;
+
+ if (endLoc)
+ *endLoc = T.getCloseLocation();
+
+ // Record this attribute
+ attrs.addNew(&ObjCBridgeRelated,
+ SourceRange(ObjCBridgeRelatedLoc, T.getCloseLocation()),
+ 0, ObjCBridgeRelatedLoc,
+ RelatedClass,
+ ClassMethod,
+ InstanceMethod,
+ AttributeList::AS_GNU);
+
+}
// Late Parsed Attributes:
// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index c587452aeb4..5414453efc1 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3713,6 +3713,24 @@ static void handleObjCBridgeMutableAttr(Sema &S, Scope *Sc, Decl *D,
Attr.getAttributeSpellingListIndex()));
}
+static void handleObjCBridgeRelatedAttr(Sema &S, Scope *Sc, Decl *D,
+ const AttributeList &Attr) {
+ IdentifierInfo *RelatedClass =
+ Attr.isArgIdent(0) ? Attr.getArgAsIdent(0)->Ident : 0;
+ if (!RelatedClass) {
+ S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0;
+ return;
+ }
+ IdentifierInfo *ClassMethod =
+ Attr.getArgAsIdent(1) ? Attr.getArgAsIdent(1)->Ident : 0;
+ IdentifierInfo *InstanceMethod =
+ Attr.getArgAsIdent(2) ? Attr.getArgAsIdent(2)->Ident : 0;
+ D->addAttr(::new (S.Context)
+ ObjCBridgeRelatedAttr(Attr.getRange(), S.Context, RelatedClass,
+ ClassMethod, InstanceMethod,
+ Attr.getAttributeSpellingListIndex()));
+}
+
static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
const AttributeList &Attr) {
SourceLocation Loc = Attr.getLoc();
@@ -3986,6 +4004,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_ObjCBridgeMutable:
handleObjCBridgeMutableAttr(S, scope, D, Attr); break;
+
+ case AttributeList::AT_ObjCBridgeRelated:
+ handleObjCBridgeRelatedAttr(S, scope, D, Attr); break;
case AttributeList::AT_ObjCDesignatedInitializer:
handleObjCDesignatedInitializer(S, D, Attr); break;
OpenPOWER on IntegriCloud