Author: aaronballman
Date: Tue Sep 10 20:37:41 2013
New Revision: 190476

URL: http://llvm.org/viewvc/llvm-project?rev=190476&view=rev
Log:
The cleanup attribute no longer uses an unresolved, simple identifier as its 
argument.  Instead, it takes an expression that is fully resolved.

Added:
    cfe/trunk/test/CodeGenCXX/attr-cleanup.cpp
    cfe/trunk/test/SemaCXX/attr-cleanup-gcc.cpp
    cfe/trunk/test/SemaCXX/attr-cleanup.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Sema/attr-cleanup.c
    cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=190476&r1=190475&r2=190476&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep 10 20:37:41 
2013
@@ -2350,10 +2350,14 @@ def err_attribute_sentinel_less_than_zer
   "'sentinel' parameter 1 less than zero">;
 def err_attribute_sentinel_not_zero_or_one : Error<
   "'sentinel' parameter 2 not 0 or 1">;
+def warn_cleanup_ext : Warning<
+  "GCC does not allow the 'cleanup' attribute argument to be anything other "
+  "than a simple identifier">, 
+  InGroup<GccCompat>;
 def err_attribute_cleanup_arg_not_found : Error<
   "'cleanup' argument %0 not found">;
 def err_attribute_cleanup_arg_not_function : Error<
-  "'cleanup' argument %0 is not a function">;
+  "'cleanup' argument %select{|%1 }0is not a function">;
 def err_attribute_cleanup_func_must_take_one_arg : Error<
   "'cleanup' function %0 must take 1 parameter">;
 def err_attribute_cleanup_func_arg_incompatible_type : Error<

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=190476&r1=190475&r2=190476&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Sep 10 20:37:41 2013
@@ -2831,40 +2831,44 @@ static void handlePureAttr(Sema &S, Decl
 }
 
 static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!Attr.isArgIdent(0)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 1;
-    return;
-  }
-  
   VarDecl *VD = dyn_cast<VarDecl>(D);
-
   if (!VD || !VD->hasLocalStorage()) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
-    return;
-  }
-
-  IdentifierLoc *IL = Attr.getArgAsIdent(0);
-
-  // Look up the function
-  // FIXME: Lookup probably isn't looking in the right place
-  NamedDecl *CleanupDecl
-    = S.LookupSingleName(S.TUScope, IL->Ident, IL->Loc,
-                         Sema::LookupOrdinaryName);
-  if (!CleanupDecl) {
-    S.Diag(IL->Loc, diag::err_attribute_cleanup_arg_not_found) << IL->Ident;
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
     return;
   }
 
-  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
-  if (!FD) {
-    S.Diag(IL->Loc, diag::err_attribute_cleanup_arg_not_function) << IL->Ident;
+  Expr *E = Attr.getArgAsExpr(0);
+  SourceLocation Loc = E->getExprLoc();
+  FunctionDecl *FD = 0;
+  DeclarationNameInfo NI;
+
+  // gcc only allows for simple identifiers. Since we support more than gcc, we
+  // will warn the user.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+    if (DRE->hasQualifier())
+      S.Diag(Loc, diag::warn_cleanup_ext);
+    FD = dyn_cast<FunctionDecl>(DRE->getDecl());
+    NI = DRE->getNameInfo();
+    if (!FD) {
+      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
+        << NI.getName();
+      return;
+    }
+  } else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
+    if (ULE->hasExplicitTemplateArgs())
+      S.Diag(Loc, diag::warn_cleanup_ext);
+
+    // This will diagnose the case where the function cannot be found.
+    FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
+    NI = ULE->getNameInfo();
+  } else {
+    S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
     return;
   }
 
   if (FD->getNumParams() != 1) {
-    S.Diag(IL->Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
-      << IL->Ident;
+    S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
+      << NI.getName();
     return;
   }
 
@@ -2874,16 +2878,14 @@ static void handleCleanupAttr(Sema &S, D
   QualType ParamTy = FD->getParamDecl(0)->getType();
   if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
                                    ParamTy, Ty) != Sema::Compatible) {
-    S.Diag(IL->Loc, diag::err_attribute_cleanup_func_arg_incompatible_type) <<
-      IL->Ident << ParamTy << Ty;
+    S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
+      << NI.getName() << ParamTy << Ty;
     return;
   }
 
   D->addAttr(::new (S.Context)
              CleanupAttr(Attr.getRange(), S.Context, FD,
                          Attr.getAttributeSpellingListIndex()));
-  S.MarkFunctionReferenced(IL->Loc, FD);
-  S.DiagnoseUseOfDecl(FD, IL->Loc);
 }
 
 /// Handle __attribute__((format_arg((idx)))) attribute based on

Added: cfe/trunk/test/CodeGenCXX/attr-cleanup.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/attr-cleanup.cpp?rev=190476&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/attr-cleanup.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/attr-cleanup.cpp Tue Sep 10 20:37:41 2013
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+namespace N {
+  void free(void *i) {}
+}
+
+int main(void) {
+  // CHECK: call void @_ZN1N4freeEPv(i8* %0)
+  void *fp __attribute__((cleanup(N::free)));
+  return 0;
+}

Modified: cfe/trunk/test/Sema/attr-cleanup.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-cleanup.c?rev=190476&r1=190475&r2=190476&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-cleanup.c (original)
+++ cfe/trunk/test/Sema/attr-cleanup.c Tue Sep 10 20:37:41 2013
@@ -2,18 +2,18 @@
 
 void c1(int *a);
 
-extern int g1 __attribute((cleanup(c1))); // expected-warning {{cleanup 
attribute ignored}}
-int g2 __attribute((cleanup(c1))); // expected-warning {{cleanup attribute 
ignored}}
-static int g3 __attribute((cleanup(c1))); // expected-warning {{cleanup 
attribute ignored}}
+extern int g1 __attribute((cleanup(c1))); // expected-warning {{'cleanup' 
attribute ignored}}
+int g2 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute 
ignored}}
+static int g3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' 
attribute ignored}}
 
 void t1()
 {
     int v1 __attribute((cleanup)); // expected-error {{'cleanup' attribute 
takes one argument}}
     int v2 __attribute((cleanup(1, 2))); // expected-error {{'cleanup' 
attribute takes one argument}}
 
-    static int v3 __attribute((cleanup(c1))); // expected-warning {{cleanup 
attribute ignored}}
+    static int v3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' 
attribute ignored}}
 
-    int v4 __attribute((cleanup(h))); // expected-error {{'cleanup' argument 
'h' not found}}
+    int v4 __attribute((cleanup(h))); // expected-error {{use of undeclared 
identifier 'h'}}
 
     int v5 __attribute((cleanup(c1)));
     int v6 __attribute((cleanup(v3))); // expected-error {{'cleanup' argument 
'v3' is not a function}}
@@ -42,3 +42,7 @@ void c5(void*) __attribute__((deprecated
 void t5() {
   int i __attribute__((cleanup(c5)));  // expected-warning {{'c5' is 
deprecated}}
 }
+
+void t6(void) {
+  int i __attribute__((cleanup((void *)0)));  // expected-error {{'cleanup' 
argument is not a function}}
+}

Added: cfe/trunk/test/SemaCXX/attr-cleanup-gcc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-cleanup-gcc.cpp?rev=190476&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-cleanup-gcc.cpp (added)
+++ cfe/trunk/test/SemaCXX/attr-cleanup-gcc.cpp Tue Sep 10 20:37:41 2013
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wgcc-compat
+
+namespace N {
+  void c1(int *a) {}
+}
+
+void c2(int *a) {}
+
+template <typename Ty>
+void c3(Ty *a) {}
+
+void t3() {
+  int v1 __attribute__((cleanup(N::c1)));  // expected-warning  {{GCC does not 
allow the 'cleanup' attribute argument to be anything other than a simple 
identifier}}
+  int v2 __attribute__((cleanup(c2)));
+  int v3 __attribute__((cleanup(c3<int>)));  // expected-warning  {{GCC does 
not allow the 'cleanup' attribute argument to be anything other than a simple 
identifier}}
+}

Added: cfe/trunk/test/SemaCXX/attr-cleanup.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-cleanup.cpp?rev=190476&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-cleanup.cpp (added)
+++ cfe/trunk/test/SemaCXX/attr-cleanup.cpp Tue Sep 10 20:37:41 2013
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-gcc-compat
+
+namespace N {
+  void c1(int *a) {}
+}
+
+void t1() {
+  int v1 __attribute__((cleanup(N::c1)));
+  int v2 __attribute__((cleanup(N::c2)));  // expected-error {{no member named 
'c2' in namespace 'N'}}
+}

Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=190476&r1=190475&r2=190476&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Tue Sep 10 20:37:41 2013
@@ -1069,6 +1069,7 @@ void EmitClangAttrExprArgsList(RecordKee
           .Case("AlignedArgument", true)
           .Case("BoolArgument", true)
           .Case("DefaultIntArgument", true)
+          .Case("FunctionArgument", true)
           .Case("IntArgument", true)
           .Case("ExprArgument", true)
           .Case("StringArgument", true)


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to