[cfe-commits] r96992 - in /cfe/trunk: include/clang/AST/Attr.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/AttributeList.h lib/AST/AttrImpl.cpp lib/CodeGen/CodeGenModule.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriter.cpp lib/Parse/AttributeList.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/attributes.c test/SemaCXX/attr-weakref.cpp
Rafael Espindola
rafael.espindola at gmail.com
Tue Feb 23 14:00:30 PST 2010
Author: rafael
Date: Tue Feb 23 16:00:30 2010
New Revision: 96992
URL: http://llvm.org/viewvc/llvm-project?rev=96992&view=rev
Log:
Add support for the weakref attribute. We still produce "alias weak" as llvm-gcc does, but are more strict on what uses of weakref we accept.
Added:
cfe/trunk/test/SemaCXX/attr-weakref.cpp
Modified:
cfe/trunk/include/clang/AST/Attr.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Parse/AttributeList.h
cfe/trunk/lib/AST/AttrImpl.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
cfe/trunk/lib/Frontend/PCHWriter.cpp
cfe/trunk/lib/Parse/AttributeList.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/test/CodeGen/attributes.c
Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=96992&r1=96991&r2=96992&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Tue Feb 23 16:00:30 2010
@@ -94,6 +94,7 @@
WarnUnusedResult,
Weak,
WeakImport,
+ WeakRef,
FIRST_TARGET_ATTRIBUTE,
DLLExport,
@@ -357,6 +358,7 @@
DEF_SIMPLE_ATTR(Used);
DEF_SIMPLE_ATTR(Weak);
DEF_SIMPLE_ATTR(WeakImport);
+DEF_SIMPLE_ATTR(WeakRef);
DEF_SIMPLE_ATTR(NoThrow);
DEF_SIMPLE_ATTR(Const);
DEF_SIMPLE_ATTR(Pure);
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=96992&r1=96991&r2=96992&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Feb 23 16:00:30 2010
@@ -747,6 +747,12 @@
"weak declaration of '%0' must be public">;
def warn_attribute_weak_import_invalid_on_definition : Warning<
"'weak_import' attribute cannot be specified on a definition">;
+def err_attribute_weakref_not_static : Error<
+ "weakref declaration of '%0' must be static">;
+def err_attribute_weakref_not_global_context : Error<
+ "weakref declaration of '%0' must be in a global context">;
+def err_attribute_weakref_without_alias : Error<
+ "weakref declaration of '%0' must also have an alias attribute">;
def warn_attribute_wrong_decl_type : Warning<
"%0 attribute only applies to %select{function|union|"
"variable and function|function or method|parameter|"
Modified: cfe/trunk/include/clang/Parse/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/AttributeList.h?rev=96992&r1=96991&r2=96992&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/AttributeList.h (original)
+++ cfe/trunk/include/clang/Parse/AttributeList.h Tue Feb 23 16:00:30 2010
@@ -109,6 +109,7 @@
AT_visibility,
AT_warn_unused_result,
AT_weak,
+ AT_weakref,
AT_weak_import,
AT_reqd_wg_size,
IgnoredAttribute,
Modified: cfe/trunk/lib/AST/AttrImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/AttrImpl.cpp?rev=96992&r1=96991&r2=96992&view=diff
==============================================================================
--- cfe/trunk/lib/AST/AttrImpl.cpp (original)
+++ cfe/trunk/lib/AST/AttrImpl.cpp Tue Feb 23 16:00:30 2010
@@ -107,6 +107,7 @@
DEF_SIMPLE_ATTR_CLONE(WarnUnusedResult)
DEF_SIMPLE_ATTR_CLONE(Weak)
DEF_SIMPLE_ATTR_CLONE(WeakImport)
+DEF_SIMPLE_ATTR_CLONE(WeakRef)
DEF_SIMPLE_ATTR_CLONE(X86ForceAlignArgPointer)
Attr* PragmaPackAttr::clone(ASTContext &C) const {
@@ -196,5 +197,3 @@
Attr *MSP430InterruptAttr::clone(ASTContext &C) const {
return ::new (C) MSP430InterruptAttr(Number);
}
-
-
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=96992&r1=96991&r2=96992&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Feb 23 16:00:30 2010
@@ -1327,6 +1327,7 @@
GA->setLinkage(llvm::Function::DLLExportLinkage);
}
} else if (D->hasAttr<WeakAttr>() ||
+ D->hasAttr<WeakRefAttr>() ||
D->hasAttr<WeakImportAttr>()) {
GA->setLinkage(llvm::Function::WeakAnyLinkage);
}
Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=96992&r1=96991&r2=96992&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Tue Feb 23 16:00:30 2010
@@ -586,6 +586,7 @@
SIMPLE_ATTR(WarnUnusedResult);
SIMPLE_ATTR(Weak);
+ SIMPLE_ATTR(WeakRef);
SIMPLE_ATTR(WeakImport);
}
Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=96992&r1=96991&r2=96992&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Tue Feb 23 16:00:30 2010
@@ -1916,6 +1916,7 @@
case Attr::WarnUnusedResult:
case Attr::Weak:
+ case Attr::WeakRef:
case Attr::WeakImport:
break;
}
@@ -2335,4 +2336,3 @@
break;
}
}
-
Modified: cfe/trunk/lib/Parse/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/AttributeList.cpp?rev=96992&r1=96991&r2=96992&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/AttributeList.cpp (original)
+++ cfe/trunk/lib/Parse/AttributeList.cpp Tue Feb 23 16:00:30 2010
@@ -57,6 +57,7 @@
// FIXME: Hand generating this is neither smart nor efficient.
return llvm::StringSwitch<AttributeList::Kind>(AttrName)
.Case("weak", AT_weak)
+ .Case("weakref", AT_weakref)
.Case("pure", AT_pure)
.Case("mode", AT_mode)
.Case("used", AT_used)
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=96992&r1=96991&r2=96992&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Feb 23 16:00:30 2010
@@ -329,6 +329,86 @@
d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size));
}
+static bool isStaticVarOrStaticFunciton(Decl *D) {
+ if (VarDecl *VD = dyn_cast<VarDecl>(D))
+ return VD->getStorageClass() == VarDecl::Static;
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ return FD->getStorageClass() == FunctionDecl::Static;
+ return false;
+}
+
+static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+ // Check the attribute arguments.
+ if (Attr.getNumArgs() > 1) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ return;
+ }
+
+ // gcc rejects
+ // class c {
+ // static int a __attribute__((weakref ("v2")));
+ // static int b() __attribute__((weakref ("f3")));
+ // };
+ // and ignores the attributes of
+ // void f(void) {
+ // static int a __attribute__((weakref ("v2")));
+ // }
+ // we reject them
+ if (const DeclContext *Ctx = d->getDeclContext()) {
+ Ctx = Ctx->getLookupContext();
+ if (!isa<TranslationUnitDecl>(Ctx) && !isa<NamespaceDecl>(Ctx) ) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
+ dyn_cast<NamedDecl>(d)->getNameAsString();
+ return;
+ }
+ }
+
+ // The GCC manual says
+ //
+ // At present, a declaration to which `weakref' is attached can only
+ // be `static'.
+ //
+ // It also says
+ //
+ // Without a TARGET,
+ // given as an argument to `weakref' or to `alias', `weakref' is
+ // equivalent to `weak'.
+ //
+ // gcc 4.4.1 will accept
+ // int a7 __attribute__((weakref));
+ // as
+ // int a7 __attribute__((weak));
+ // This looks like a bug in gcc. We reject that for now. We should revisit
+ // it if this behaviour is actually used.
+
+ if (!isStaticVarOrStaticFunciton(d)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) <<
+ dyn_cast<NamedDecl>(d)->getNameAsString();
+ return;
+ }
+
+ // GCC rejects
+ // static ((alias ("y"), weakref)).
+ // Should we? How to check that weakref is before or after alias?
+
+ if (Attr.getNumArgs() == 1) {
+ Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
+ Arg = Arg->IgnoreParenCasts();
+ StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+
+ if (Str == 0 || Str->isWide()) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
+ << "weakref" << 1;
+ return;
+ }
+ // GCC will accept anything as the argument of weakref. Should we
+ // check for an existing decl?
+ d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+ }
+
+ d->addAttr(::new (S.Context) WeakRefAttr());
+}
+
static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() != 1) {
@@ -777,13 +857,7 @@
}
/* weak only applies to non-static declarations */
- bool isStatic = false;
- if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
- isStatic = VD->getStorageClass() == VarDecl::Static;
- } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- isStatic = FD->getStorageClass() == FunctionDecl::Static;
- }
- if (isStatic) {
+ if (isStaticVarOrStaticFunciton(D)) {
S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) <<
dyn_cast<NamedDecl>(D)->getNameAsString();
return;
@@ -1809,6 +1883,7 @@
case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
break;
case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break;
+ case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break;
case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break;
case AttributeList::AT_transparent_union:
HandleTransparentUnionAttr(D, Attr, S);
@@ -1847,9 +1922,17 @@
/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
/// attribute list to the specified decl, ignoring any type attributes.
void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) {
- while (AttrList) {
- ProcessDeclAttribute(S, D, *AttrList, *this);
- AttrList = AttrList->getNext();
+ for (const AttributeList* l = AttrList; l; l = l->getNext()) {
+ ProcessDeclAttribute(S, D, *l, *this);
+ }
+
+ // GCC accepts
+ // static int a9 __attribute__((weakref));
+ // but that looks really pointless. We reject it.
+ if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
+ Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
+ dyn_cast<NamedDecl>(D)->getNameAsString();
+ return;
}
}
Modified: cfe/trunk/test/CodeGen/attributes.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attributes.c?rev=96992&r1=96991&r2=96992&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/attributes.c (original)
+++ cfe/trunk/test/CodeGen/attributes.c Tue Feb 23 16:00:30 2010
@@ -30,6 +30,12 @@
void __t8() {}
void t9() __attribute__((weak, alias("__t8")));
+static void t22(void) __attribute__((weakref("t8")));
+// CHECK: @t22 = alias weak void ()* @t8
+
+static void t23(void) __attribute__((weakref, alias("t8")));
+// CHECK: @t23 = alias weak void ()* @t8
+
// CHECK: declare extern_weak i32 @t15()
int __attribute__((weak_import)) t15(void);
int t17() {
Added: cfe/trunk/test/SemaCXX/attr-weakref.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-weakref.cpp?rev=96992&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-weakref.cpp (added)
+++ cfe/trunk/test/SemaCXX/attr-weakref.cpp Tue Feb 23 16:00:30 2010
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// GCC will accept anything as the argument of weakref. Should we
+// check for an existing decl?
+static int a1() __attribute__((weakref ("foo")));
+static int a2() __attribute__((weakref, alias ("foo")));
+
+static int a3 __attribute__((weakref ("foo")));
+static int a4 __attribute__((weakref, alias ("foo")));
+
+// gcc rejects, clang accepts
+static int a5 __attribute__((alias ("foo"), weakref));
+
+// this is pointless, but accepted by gcc. We reject it.
+static int a6 __attribute__((weakref)); //expected-error {{weakref declaration of 'a6' must also have an alias attribute}}
+
+// gcc warns, clang rejects
+void f(void) {
+ static int a __attribute__((weakref ("v2"))); // expected-error {{declaration of 'a' must be in a global context}}
+}
+
+// both gcc and clang reject
+class c {
+ static int a __attribute__((weakref ("v2"))); // expected-error {{declaration of 'a' must be in a global context}}
+ static int b() __attribute__((weakref ("f3"))); // expected-error {{declaration of 'b' must be in a global context}}
+};
+int a7() __attribute__((weakref ("f1"))); // expected-error {{declaration of 'a7' must be static}}
+int a8 __attribute__((weakref ("v1"))); // expected-error {{declaration of 'a8' must be static}}
+
+// gcc accepts this
+int a9 __attribute__((weakref)); // expected-error {{declaration of 'a9' must be static}}
More information about the cfe-commits
mailing list