[cfe-commits] r63462 - in /cfe/trunk: include/clang/AST/Attr.h include/clang/Basic/DiagnosticSemaKinds.def include/clang/Parse/AttributeList.h lib/Parse/AttributeList.cpp lib/Sema/SemaDeclAttr.cpp
Anders Carlsson
andersca at mac.com
Fri Jan 30 17:16:18 PST 2009
Author: andersca
Date: Fri Jan 30 19:16:18 2009
New Revision: 63462
URL: http://llvm.org/viewvc/llvm-project?rev=63462&view=rev
Log:
Add sema support for the cleanup attribute.
Modified:
cfe/trunk/include/clang/AST/Attr.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
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=63462&r1=63461&r2=63462&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Fri Jan 30 19:16:18 2009
@@ -52,7 +52,8 @@
Weak,
Blocks,
Const,
- Pure
+ Pure,
+ Cleanup
};
private:
@@ -446,6 +447,22 @@
static bool classof(const BlocksAttr *A) { return true; }
};
+class FunctionDecl;
+
+class CleanupAttr : public Attr {
+ FunctionDecl *FD;
+
+public:
+ CleanupAttr(FunctionDecl *fd) : Attr(Cleanup), FD(fd) {}
+
+ const FunctionDecl *getFunctionDecl() const { return FD; }
+
+ // Implement isa/cast/dyncast/etc.
+
+ static bool classof(const Attr *A) { return A->getKind() == Cleanup; }
+ static bool classof(const CleanupAttr *A) { return true; }
+};
+
} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def?rev=63462&r1=63461&r2=63462&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Fri Jan 30 19:16:18 2009
@@ -377,7 +377,13 @@
"'sentinel' parameter 1 less than zero")
DIAG(err_attribute_sentinel_not_zero_or_one, ERROR,
"'sentinel' parameter 2 not 0 or 1")
-
+DIAG(err_attribute_cleanup_arg_not_found, ERROR,
+ "'cleanup' argument %0 not found")
+DIAG(err_attribute_cleanup_arg_not_function, ERROR,
+ "'cleanup' argument %0 is not a function")
+DIAG(err_attribute_cleanup_arg_must_take_one_arg, ERROR,
+ "'cleanup' function %0 must take 1 parameter")
+
// Clang-Specific Attributes
DIAG(err_attribute_iboutlet_non_ivar, ERROR,
"'iboutlet' attribute can only be applied to instance variables")
Modified: cfe/trunk/include/clang/Parse/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/AttributeList.h?rev=63462&r1=63461&r2=63462&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/AttributeList.h (original)
+++ cfe/trunk/include/clang/Parse/AttributeList.h Fri Jan 30 19:16:18 2009
@@ -77,6 +77,7 @@
AT_sentinel,
AT_const,
AT_nsobject,
+ AT_cleanup,
UnknownAttribute
};
Modified: cfe/trunk/lib/Parse/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/AttributeList.cpp?rev=63462&r1=63461&r2=63462&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/AttributeList.cpp (original)
+++ cfe/trunk/lib/Parse/AttributeList.cpp Fri Jan 30 19:16:18 2009
@@ -73,6 +73,7 @@
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;
+ if (!memcmp(Str, "cleanup", 7)) return AT_cleanup;
break;
case 8:
if (!memcmp(Str, "annotate", 8)) return AT_annotate;
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=63462&r1=63461&r2=63462&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Jan 30 19:16:18 2009
@@ -846,6 +846,51 @@
d->addAttr(new PureAttr());
}
+static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+ if (!Attr.getParameterName()) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ return;
+ }
+
+ if (Attr.getNumArgs() != 0) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ return;
+ }
+
+ VarDecl *VD = dyn_cast<VarDecl>(d);
+
+ if (!VD || !VD->hasLocalStorage()) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
+ return;
+ }
+
+ // Look up the function
+ Decl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
+ Sema::LookupOrdinaryName);
+ if (!CleanupDecl) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
+ Attr.getParameterName();
+ return;
+ }
+
+ FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
+ if (!FD) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
+ Attr.getParameterName();
+ return;
+ }
+
+ // FIXME: This needs to work with C++ overloading.
+ // FIXME: This should verify that the function type is compatible
+ if (FD->getNumParams() != 1) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_must_take_one_arg)<<
+ Attr.getParameterName();
+ return;
+ }
+
+ d->addAttr(new CleanupAttr(FD));
+}
+
/// Handle __attribute__((format(type,idx,firstarg))) attributes
/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1248,6 +1293,7 @@
case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break;
case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break;
case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break;
+ case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break;
default:
#if 0
// TODO: when we have the full set of attributes, warn about unknown ones.
More information about the cfe-commits
mailing list