diff options
| author | John McCall <rjmccall@apple.com> | 2011-09-29 07:17:38 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2011-09-29 07:17:38 +0000 |
| commit | f1e8b34f6c709fd54cee25efb3c59bc4a7c643fa (patch) | |
| tree | 1e86a634c83d4a3d1dd745c75afe3c7442f9c9c2 /clang/lib/Sema | |
| parent | 7fd172361945131ee5d7d7766609e21296fa64a5 (diff) | |
| download | bcm5719-llvm-f1e8b34f6c709fd54cee25efb3c59bc4a7c643fa.tar.gz bcm5719-llvm-f1e8b34f6c709fd54cee25efb3c59bc4a7c643fa.zip | |
Add an ns_bridged attribute, used to specify that a
pointer to the annotated struct type can be used as an
Objective-C object pointer. If an argument is given, the
type is actually "toll-free bridged" to the specific type
named there, rather than just to 'id'.
For now, we cannot rely on all types being so annotated,
and we'll always have to have exceptions for things like
CFTypeRef (aka const void*), but this is clearly a good
foundation for improving toolage in this area.
llvm-svn: 140779
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/AttributeList.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 34 |
2 files changed, 35 insertions, 0 deletions
diff --git a/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp index d9f17b42da4..5cd21a645d2 100644 --- a/clang/lib/Sema/AttributeList.cpp +++ b/clang/lib/Sema/AttributeList.cpp @@ -171,6 +171,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { .Case("analyzer_noreturn", AT_analyzer_noreturn) .Case("warn_unused_result", AT_warn_unused_result) .Case("carries_dependency", AT_carries_dependency) + .Case("ns_bridged", AT_ns_bridged) .Case("ns_consumed", AT_ns_consumed) .Case("ns_consumes_self", AT_ns_consumes_self) .Case("ns_returns_autoreleased", AT_ns_returns_autoreleased) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 435507f9d78..eca6874b367 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -22,6 +22,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/DelayedDiagnostic.h" +#include "clang/Sema/Lookup.h" #include "llvm/ADT/StringExtras.h" using namespace clang; using namespace sema; @@ -3262,6 +3263,36 @@ static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context)); } +static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, + const AttributeList &Attr) { + RecordDecl *RD = dyn_cast<RecordDecl>(D); + if (!RD || RD->isUnion()) { + S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) + << Attr.getRange() << Attr.getName() << 14 /*struct */; + } + + IdentifierInfo *ParmName = Attr.getParameterName(); + + // In Objective-C, verify that the type names an Objective-C type. + // We don't want to check this outside of ObjC because people sometimes + // do crazy C declarations of Objective-C types. + if (ParmName && S.getLangOptions().ObjC1) { + // Check for an existing type with this name. + LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(), + Sema::LookupOrdinaryName); + if (S.LookupName(R, Sc)) { + NamedDecl *Target = R.getFoundDecl(); + if (Target && !isa<ObjCInterfaceDecl>(Target)) { + S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface); + S.Diag(Target->getLocStart(), diag::note_declared_at); + } + } + } + + D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context, + ParmName)); +} + static void handleObjCOwnershipAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (hasDeclarator(D)) return; @@ -3465,6 +3496,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_objc_returns_inner_pointer: handleObjCReturnsInnerPointerAttr(S, D, Attr); break; + case AttributeList::AT_ns_bridged: + handleNSBridgedAttr(S, scope, D, Attr); break; + // Checker-specific. case AttributeList::AT_cf_consumed: case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break; |

