From: Daniel Dunbar Date: Fri, 6 Mar 2009 06:39:57 +0000 (+0000) Subject: Add Parse/Sema support for weak_import attribute. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6e775dbafba2ab6634decc489eb3b4301b4b506b;p=clang Add Parse/Sema support for weak_import attribute. - Also, diagnose weak applied to types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66259 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 0d6ed01e51..cd98ef1a8b 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -31,21 +31,27 @@ public: AlwaysInline, Annotate, AsmLabel, // Represent GCC asm label extension. + Blocks, + Cleanup, + Const, Constructor, + DLLExport, + DLLImport, Deprecated, Destructor, - DLLImport, - DLLExport, FastCall, Format, IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with - NonNull, NoReturn, NoThrow, - ObjCNSObject, + Nodebug, + Noinline, + NonNull, ObjCException, + ObjCNSObject, Overloadable, // Clang-specific Packed, + Pure, Section, StdCall, TransparentUnion, @@ -55,12 +61,7 @@ public: Visibility, WarnUnusedResult, Weak, - Blocks, - Const, - Pure, - Cleanup, - Nodebug, - Noinline + WeakImport }; private: @@ -298,6 +299,16 @@ public: static bool classof(const WeakAttr *A) { return true; } }; +class WeakImportAttr : public Attr { +public: + WeakImportAttr() : Attr(WeakImport) {} + + // Implement isa/cast/dyncast/etc. + + static bool classof(const Attr *A) { return A->getKind() == WeakImport; } + static bool classof(const WeakImportAttr *A) { return true; } +}; + class NoThrowAttr : public Attr { public: NoThrowAttr() : Attr(NoThrow) {} @@ -520,7 +531,7 @@ public: WarnUnusedResultAttr() : Attr(WarnUnusedResult) {} // Implement isa/cast/dyncast/etc. - static bool classof(const Attr *A) { return A->getKind() == WarnUnusedResult;} + static bool classof(const Attr *A) { return A->getKind() == WarnUnusedResult;} static bool classof(const WarnUnusedResultAttr *A) { return true; } }; diff --git a/include/clang/Basic/DiagnosticSemaKinds.def b/include/clang/Basic/DiagnosticSemaKinds.def index beefc02ef5..ef6f7eeb9c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.def +++ b/include/clang/Basic/DiagnosticSemaKinds.def @@ -376,6 +376,8 @@ DIAG(warn_attribute_weak_on_field, WARNING, "__weak attribute cannot be specified on a field declaration") DIAG(warn_attribute_weak_on_local, WARNING, "__weak attribute cannot be specified on an automatic variable") +DIAG(warn_attribute_weak_import_invalid_on_definition, WARNING, + "'weak_import' attribute cannot be specified on a definition") DIAG(warn_attribute_wrong_decl_type, WARNING, "'%0' attribute only applies to %select{function|union|" "variable and function|function or method}1 types") diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index bfa03571d6..2f71e4d758 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -44,29 +44,37 @@ public: ~AttributeList(); enum Kind { // Please keep this list alphabetized. + AT_IBOutlet, // Clang-specific. AT_address_space, AT_alias, AT_aligned, AT_always_inline, AT_annotate, + AT_blocks, + AT_cleanup, + AT_const, AT_constructor, AT_deprecated, AT_destructor, - AT_dllimport, AT_dllexport, + AT_dllimport, AT_ext_vector_type, AT_fastcall, AT_format, - AT_IBOutlet, // Clang-specific. AT_mode, + AT_nodebug, AT_noinline, AT_nonnull, AT_noreturn, AT_nothrow, + AT_nsobject, + AT_objc_exception, + AT_objc_gc, AT_overloadable, // Clang-specific AT_packed, AT_pure, AT_section, + AT_sentinel, AT_stdcall, AT_transparent_union, AT_unavailable, @@ -76,14 +84,7 @@ public: AT_visibility, AT_warn_unused_result, AT_weak, - AT_objc_gc, - AT_objc_exception, - AT_blocks, - AT_sentinel, - AT_const, - AT_nsobject, - AT_cleanup, - AT_nodebug, + AT_weak_import, IgnoredAttribute, UnknownAttribute }; diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp index 6b58a001bc..9cee6abebb 100644 --- a/lib/Parse/AttributeList.cpp +++ b/lib/Parse/AttributeList.cpp @@ -105,6 +105,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { return IgnoredAttribute; // FIXME: printf format string checking. break; case 11: + if (!memcmp(Str, "weak_import", 11)) return AT_weak_import; if (!memcmp(Str, "vector_size", 11)) return AT_vector_size; if (!memcmp(Str, "constructor", 11)) return AT_constructor; if (!memcmp(Str, "unavailable", 11)) return AT_unavailable; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index d97747c35b..57cd3d2bcb 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -730,10 +730,47 @@ static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; return; } + + // TODO: could also be applied to methods? + if (!isa(D) && !isa(D)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) + << "weak" << 2 /*variable and function*/; + return; + } D->addAttr(::new (S.Context) WeakAttr()); } +static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { + // check the attribute arguments. + if (Attr.getNumArgs() != 0) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; + return; + } + + // weak_import only applies to variable & function declarations. + bool isDef = false; + if (VarDecl *VD = dyn_cast(D)) { + isDef = (!VD->hasExternalStorage() || VD->getInit()); + } else if (FunctionDecl *FD = dyn_cast(D)) { + isDef = FD->getBody(); + } else { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) + << "weak_import" << 2 /*variable and function*/; + return; + } + + // Merge should handle any subsequent violations. + if (isDef) { + S.Diag(Attr.getLoc(), + diag::warn_attribute_weak_import_invalid_on_definition) + << "weak_import" << 2 /*variable and function*/; + return; + } + + D->addAttr(::new (S.Context) WeakImportAttr()); +} + static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { // check the attribute arguments. if (Attr.getNumArgs() != 0) { @@ -1441,6 +1478,7 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); break; case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; + case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; case AttributeList::AT_transparent_union: HandleTransparentUnionAttr(D, Attr, S); break; diff --git a/test/Sema/attr-weak.c b/test/Sema/attr-weak.c new file mode 100644 index 0000000000..a58e61e627 --- /dev/null +++ b/test/Sema/attr-weak.c @@ -0,0 +1,13 @@ +// RUN: clang -verify -fsyntax-only %s + +extern int g0 __attribute__((weak)); +extern int g1 __attribute__((weak_import)); +int g2 __attribute__((weak)); +int g3 __attribute__((weak_import)); // expected-warning {{'weak_import' attribute cannot be specified on a definition}} +int __attribute__((weak_import)) g4(void); +int __attribute__((weak_import)) g5(void) { +} + +struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only applies to variable and function types}} +struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' attribute only applies to variable and function types}} +