diff options
author | Alex Denisov <1101.debian@gmail.com> | 2015-06-26 05:28:36 +0000 |
---|---|---|
committer | Alex Denisov <1101.debian@gmail.com> | 2015-06-26 05:28:36 +0000 |
commit | fde64956f95c4f8733423be393281d8461a99447 (patch) | |
tree | 5767784a7a1b175d02f7a94e6da29dc83340b53e /clang/lib/Sema/SemaDeclAttr.cpp | |
parent | b41c0b44af467c9112b696077afa67dc0ad79b5a (diff) | |
download | bcm5719-llvm-fde64956f95c4f8733423be393281d8461a99447.tar.gz bcm5719-llvm-fde64956f95c4f8733423be393281d8461a99447.zip |
[ObjC] Add NSValue support for objc_boxed_expressions
Patch extends ObjCBoxedExpr to accept records (structs and unions):
typedef struct __attribute__((objc_boxable)) _Color {
int r, g, b;
} Color;
Color color;
NSValue *boxedColor = @(color); // [NSValue valueWithBytes:&color objCType:@encode(Color)];
llvm-svn: 240761
Diffstat (limited to 'clang/lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 43790c2f37e..b8d08306859 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -20,6 +20,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/Mangle.h" +#include "clang/AST/ASTMutationListener.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -3990,6 +3991,34 @@ static void handleObjCRuntimeName(Sema &S, Decl *D, Attr.getAttributeSpellingListIndex())); } +// when a user wants to use objc_boxable with a union or struct +// but she doesn't have access to the declaration (legacy/third-party code) +// then she can 'enable' this feature via trick with a typedef +// e.g.: +// typedef struct __attribute((objc_boxable)) legacy_struct legacy_struct; +static void handleObjCBoxable(Sema &S, Decl *D, const AttributeList &Attr) { + bool notify = false; + + RecordDecl *RD = dyn_cast<RecordDecl>(D); + if (RD && RD->getDefinition()) { + RD = RD->getDefinition(); + notify = true; + } + + if (RD) { + ObjCBoxableAttr *BoxableAttr = ::new (S.Context) + ObjCBoxableAttr(Attr.getRange(), S.Context, + Attr.getAttributeSpellingListIndex()); + RD->addAttr(BoxableAttr); + if (notify) { + // we need to notify ASTReader/ASTWriter about + // modification of existing declaration + if (ASTMutationListener *L = S.getASTMutationListener()) + L->AddedAttributeToRecord(BoxableAttr, RD); + } + } +} + static void handleObjCOwnershipAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (hasDeclarator(D)) return; @@ -4758,6 +4787,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_ObjCRuntimeName: handleObjCRuntimeName(S, D, Attr); break; + + case AttributeList::AT_ObjCBoxable: + handleObjCBoxable(S, D, Attr); + break; case AttributeList::AT_CFAuditedTransfer: handleCFAuditedTransferAttr(S, D, Attr); |