From aa0d25b44e510a5a62e7345f4fa3840a886841d2 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 23 Aug 2008 23:22:21 +0000 Subject: [PATCH] Add support for parsing the objc_gc attribute. Tests will come shortly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55269 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang.xcodeproj/project.pbxproj | 4 ++-- include/clang/AST/Attr.h | 20 ++++++++++++++++++ include/clang/Parse/AttributeList.h | 1 + lib/Parse/AttributeList.cpp | 1 + lib/Sema/SemaDeclAttr.cpp | 32 +++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index c92c04ad12..7acc745bd2 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -375,7 +375,7 @@ DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprComplex.cpp; path = lib/CodeGen/CGExprComplex.cpp; sourceTree = ""; }; DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprScalar.cpp; path = lib/CodeGen/CGExprScalar.cpp; sourceTree = ""; }; DE2255FB0C8004E600D370A5 /* ParseDeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseDeclCXX.cpp; path = lib/Parse/ParseDeclCXX.cpp; sourceTree = ""; }; - DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclAttr.cpp; path = lib/Sema/SemaDeclAttr.cpp; sourceTree = ""; }; + DE22BCF10E14197E0094DC60 /* SemaDeclAttr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDeclAttr.cpp; path = lib/Sema/SemaDeclAttr.cpp; sourceTree = ""; tabWidth = 2; }; DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HeaderSearch.h; sourceTree = ""; }; DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HeaderSearch.cpp; sourceTree = ""; }; DE3450D60AEB543100DBC861 /* DirectoryLookup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DirectoryLookup.h; sourceTree = ""; }; @@ -434,7 +434,7 @@ DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExpr.cpp; path = lib/Sema/SemaExpr.cpp; sourceTree = ""; }; DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaDecl.cpp; path = lib/Sema/SemaDecl.cpp; sourceTree = ""; tabWidth = 8; usesTabs = 0; }; DE67E7140C020EDF00F66BC5 /* Sema.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Sema.h; path = lib/Sema/Sema.h; sourceTree = ""; }; - DE67E7160C020EE400F66BC5 /* Sema.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Sema.cpp; path = lib/Sema/Sema.cpp; sourceTree = ""; }; + DE67E7160C020EE400F66BC5 /* Sema.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Sema.cpp; path = lib/Sema/Sema.cpp; sourceTree = ""; tabWidth = 2; }; DE67E7190C020F4F00F66BC5 /* ParseAST.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseAST.cpp; path = lib/Sema/ParseAST.cpp; sourceTree = ""; }; DE67E7270C02109800F66BC5 /* ParseAST.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ParseAST.h; path = clang/Sema/ParseAST.h; sourceTree = ""; }; DE6951C60C4D1F5D00A5826B /* RecordLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = RecordLayout.h; path = clang/AST/RecordLayout.h; sourceTree = ""; }; diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 54f1714715..0d4c355ad1 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -40,6 +40,7 @@ public: NonNull, NoReturn, NoThrow, + ObjCGC, Packed, StdCall, TransparentUnion, @@ -343,6 +344,25 @@ public: static bool classof(const TransparentUnionAttr *A) { return true; } }; +class ObjCGCAttr : public Attr { +public: + enum GCAttrTypes { + Weak = 0, + Strong + }; +private: + GCAttrTypes GCAttrType; +public: + ObjCGCAttr(GCAttrTypes t) : Attr(ObjCGC), GCAttrType(t) {} + + GCAttrTypes getType() const { return GCAttrType; } + + // Implement isa/cast/dyncast/etc. + + static bool classof(const Attr *A) { return A->getKind() == ObjCGC; } + static bool classof(const ObjCGCAttr *A) { return true; } +}; + } // end namespace clang #endif diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index 0b27860699..b6efce388f 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -70,6 +70,7 @@ public: AT_visibility, AT_warn_unused_result, AT_weak, + AT_objc_gc, UnknownAttribute }; diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp index b120f7eda8..00da27cf0e 100644 --- a/lib/Parse/AttributeList.cpp +++ b/lib/Parse/AttributeList.cpp @@ -70,6 +70,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { if (!memcmp(Str, "aligned", 7)) return AT_aligned; if (!memcmp(Str, "nothrow", 7)) return AT_nothrow; if (!memcmp(Str, "nonnull", 7)) return AT_nonnull; + if (!memcmp(Str, "objc_gc", 7)) return AT_objc_gc; if (!memcmp(Str, "stdcall", 7)) return AT_stdcall; break; case 8: diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index fd1b3e7a49..2cfb3b9b96 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -466,6 +466,37 @@ static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { d->addAttr(new VisibilityAttr(type)); } +static void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) { + if (!Attr.getParameterName()) { + S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, + "objc_gc", std::string("1")); + return; + } + + if (Attr.getNumArgs() != 0) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, + std::string("1")); + return; + } + + const char *TypeStr = Attr.getParameterName()->getName(); + unsigned TypeLen = Attr.getParameterName()->getLength(); + + ObjCGCAttr::GCAttrTypes type; + + if (TypeLen == 4 && !memcmp(TypeStr, "weak", 4)) + type = ObjCGCAttr::Weak; + else if (TypeLen == 5 && !memcmp(TypeStr, "strong", 5)) + type = ObjCGCAttr::Strong; + else { + S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, + "objc_gc", TypeStr); + return; + } + + d->addAttr(new ObjCGCAttr(type)); +} + static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { // check the attribute arguments. if (Attr.getNumArgs() != 0) { @@ -909,6 +940,7 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { case AttributeList::AT_transparent_union: HandleTransparentUnionAttr(D, Attr, S); break; + case AttributeList::AT_objc_gc: HandleObjCGCAttr (D, Attr, S); break; default: #if 0 // TODO: when we have the full set of attributes, warn about unknown ones. -- 2.40.0