[cfe-commits] r54257 - in /cfe/trunk: include/clang/AST/Attr.h include/clang/Parse/AttributeList.h lib/Parse/AttributeList.cpp lib/Sema/SemaDeclAttr.cpp test/Sema/constructor-attribute.c
Daniel Dunbar
daniel at zuster.org
Thu Jul 31 15:40:50 PDT 2008
Author: ddunbar
Date: Thu Jul 31 17:40:48 2008
New Revision: 54257
URL: http://llvm.org/viewvc/llvm-project?rev=54257&view=rev
Log:
Support __attribute__(({con,de}structor)) in Parse & Sema
- Including possible priority argument
- In other news, the attribute parsing code really needs a cleanup
Added:
cfe/trunk/test/Sema/constructor-attribute.c
Modified:
cfe/trunk/include/clang/AST/Attr.h
cfe/trunk/include/clang/Parse/AttributeList.h
cfe/trunk/lib/Parse/AttributeList.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=54257&r1=54256&r2=54257&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Thu Jul 31 17:40:48 2008
@@ -28,7 +28,9 @@
Alias,
Aligned,
Annotate,
+ Constructor,
Deprecated,
+ Destructor,
DLLImport,
DLLExport,
FastCall,
@@ -125,7 +127,27 @@
static bool classof(const Attr *A) { return A->getKind() == Alias; }
static bool classof(const AliasAttr *A) { return true; }
};
+
+class ConstructorAttr : public Attr {
+ int priority;
+public:
+ ConstructorAttr(int p) : Attr(Constructor), priority(p) {}
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Constructor; }
+ static bool classof(const ConstructorAttr *A) { return true; }
+};
+class DestructorAttr : public Attr {
+ int priority;
+public:
+ DestructorAttr(int p) : Attr(Destructor), priority(p) {}
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) { return A->getKind() == Destructor; }
+ static bool classof(const DestructorAttr *A) { return true; }
+};
+
class IBOutletAttr : public Attr {
public:
IBOutletAttr() : Attr(IBOutletKind) {}
Modified: cfe/trunk/include/clang/Parse/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/AttributeList.h?rev=54257&r1=54256&r2=54257&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/AttributeList.h (original)
+++ cfe/trunk/include/clang/Parse/AttributeList.h Thu Jul 31 17:40:48 2008
@@ -46,7 +46,9 @@
AT_alias,
AT_aligned,
AT_annotate,
+ AT_constructor,
AT_deprecated,
+ AT_destructor,
AT_dllimport,
AT_dllexport,
AT_ext_vector_type,
Modified: cfe/trunk/lib/Parse/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/AttributeList.cpp?rev=54257&r1=54256&r2=54257&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/AttributeList.cpp (original)
+++ cfe/trunk/lib/Parse/AttributeList.cpp Thu Jul 31 17:40:48 2008
@@ -50,6 +50,7 @@
Len -= 4;
}
+ // FIXME: Hand generating this is neither smart nor efficient.
switch (Len) {
case 4:
if (!memcmp(Str, "weak", 4)) return AT_weak;
@@ -85,9 +86,11 @@
case 10:
if (!memcmp(Str, "deprecated", 10)) return AT_deprecated;
if (!memcmp(Str, "visibility", 10)) return AT_visibility;
+ if (!memcmp(Str, "destructor", 10)) return AT_destructor;
break;
case 11:
if (!memcmp(Str, "vector_size", 11)) return AT_vector_size;
+ if (!memcmp(Str, "constructor", 11)) return AT_constructor;
break;
case 13:
if (!memcmp(Str, "address_space", 13)) return AT_address_space;
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=54257&r1=54256&r2=54257&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Jul 31 17:40:48 2008
@@ -61,6 +61,10 @@
// Attribute Implementations
//===----------------------------------------------------------------------===//
+// FIXME: All this manual attribute parsing code is gross. At the
+// least add some helper functions to check most argument patterns (#
+// and types of args).
+
static void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
Sema &S) {
TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
@@ -353,6 +357,64 @@
d->addAttr(new UnusedAttr());
}
+static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+ // check the attribute arguments.
+ if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
+ return;
+ }
+
+ int priority = 65535; // FIXME: Do not hardcode such constants.
+ if (Attr.getNumArgs() > 0) {
+ Expr *E = static_cast<Expr *>(Attr.getArg(0));
+ llvm::APSInt Idx(32);
+ if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
+ "constructor", "1", E->getSourceRange());
+ return;
+ }
+ priority = Idx.getZExtValue();
+ }
+
+ FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
+ if (!Fn) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
+ "constructor", "function");
+ return;
+ }
+
+ d->addAttr(new ConstructorAttr(priority));
+}
+
+static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+ // check the attribute arguments.
+ if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
+ return;
+ }
+
+ int priority = 65535; // FIXME: Do not hardcode such constants.
+ if (Attr.getNumArgs() > 0) {
+ Expr *E = static_cast<Expr *>(Attr.getArg(0));
+ llvm::APSInt Idx(32);
+ if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
+ "destructor", "1", E->getSourceRange());
+ return;
+ }
+ priority = Idx.getZExtValue();
+ }
+
+ FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
+ if (!Fn) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
+ "destructor", "function");
+ return;
+ }
+
+ d->addAttr(new DestructorAttr(priority));
+}
+
static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0) {
@@ -816,31 +878,33 @@
/// silently ignore it.
static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
switch (Attr.getKind()) {
+ case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break;
case AttributeList::AT_address_space:
// Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
break;
- case AttributeList::AT_ext_vector_type:
- HandleExtVectorTypeAttr(D, Attr, S);
- break;
- case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
- case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break;
+ case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break;
+ case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break;
+ case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break;
- case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break;
- case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break;
- case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break;
+ case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break;
case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break;
- case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
- case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break;
+ case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break;
+ case AttributeList::AT_ext_vector_type:
+ HandleExtVectorTypeAttr(D, Attr, S);
+ break;
case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break;
- case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break;
- case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
- case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break;
- case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
- case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break;
+ case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
+ case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
+ case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
+ case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
+ case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break;
case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break;
+ case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
+ case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break;
+ case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break;
case AttributeList::AT_transparent_union:
HandleTransparentUnionAttr(D, Attr, S);
break;
Added: cfe/trunk/test/Sema/constructor-attribute.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/constructor-attribute.c?rev=54257&view=auto
==============================================================================
--- cfe/trunk/test/Sema/constructor-attribute.c (added)
+++ cfe/trunk/test/Sema/constructor-attribute.c Thu Jul 31 17:40:48 2008
@@ -0,0 +1,15 @@
+// RUN: clang -fsyntax-only -verify %s
+
+int x __attribute__((constructor)); // expected-warning {{'constructor' attribute only applies to function types}}
+int f() __attribute__((constructor));
+int f() __attribute__((constructor(1)));
+int f() __attribute__((constructor(1,2))); // expected-error {{attribute requires 0 or 1 argument(s)}}
+int f() __attribute__((constructor(1.0))); // expected-error {{'constructor' attribute requires parameter 1 to be an integer constant}}
+
+int x __attribute__((destructor)); // expected-warning {{'destructor' attribute only applies to function types}}
+int f() __attribute__((destructor));
+int f() __attribute__((destructor(1)));
+int f() __attribute__((destructor(1,2))); // expected-error {{attribute requires 0 or 1 argument(s)}}
+int f() __attribute__((destructor(1.0))); // expected-error {{'destructor' attribute requires parameter 1 to be an integer constant}}
+
+
More information about the cfe-commits
mailing list