diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/AttributeList.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 38 |
2 files changed, 39 insertions, 0 deletions
diff --git a/clang/lib/Parse/AttributeList.cpp b/clang/lib/Parse/AttributeList.cpp index 6b58a001bca..9cee6abebbd 100644 --- a/clang/lib/Parse/AttributeList.cpp +++ b/clang/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/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index d97747c35b3..57cd3d2bcb2 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/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<FunctionDecl>(D) && !isa<VarDecl>(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<VarDecl>(D)) { + isDef = (!VD->hasExternalStorage() || VD->getInit()); + } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(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; |