I believe I have resolved all issues.

There is an open issue regarding the legality of the following:

void foo();
void __attribute__((nomips16) foo();

Gcc does not allow this but right now clang would.
I'm not convinced that we have to mimick this gcc behavior.
Currently I am discussing this internally at Mips and on the gcc developers list.

On 01/14/2013 02:31 PM, Dmitri Gribenko wrote:
On Mon, Jan 14, 2013 at 8:42 AM, Reed Kotler <[email protected]> wrote:
Forget to say that I need to have this patch reviewd.
+__attribute((nomips16)) int a; // expected-warning {{attribute only
applies to functions}}

I am concerned by the fact that this is just a warning -- I would
suggest to make it an error.  This is a new attribute, so there's no
code abusing this attribute (we don't need to be compatible with it).

What does gcc do?

+void __attribute__((nomips16)) foo32(); // expected-warning {{unknown
attribute 'nomips16' ignored}}

Same here.  What does gcc do in this case?  (I know that this behavior
can not be changed without some refactoring.  But if GCC gives an
error, we should, too.  So we would leave a comment in the test, or
better -- do the required refactoring...)

Dmitri


diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 858df3a..cee4ea8 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -403,6 +403,11 @@ def MBlazeSaveVolatiles : InheritableAttr {
   let SemaHandler = 0;
 }
 
+def Mips16 : InheritableAttr {
+  let Spellings = [GNU<"mips16">];
+  let Subjects = [Function];
+}
+
 def Mode : Attr {
   let Spellings = [GNU<"mode">];
   let Args = [IdentifierArgument<"Mode">];
@@ -441,6 +446,11 @@ def NoInline : InheritableAttr {
   let Spellings = [GNU<"noinline">];
 }
 
+def NoMips16 : InheritableAttr {
+  let Spellings = [GNU<"nomips16">];
+  let Subjects = [Function];
+}
+
 def NonNull : InheritableAttr {
   let Spellings = [GNU<"nonnull">];
   let Args = [VariadicUnsignedArgument<"Args">];
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 5f2bd52..47005e7 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -3846,6 +3846,13 @@ public:
     return 29;
   }
 
+  void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                           CodeGen::CodeGenModule &CGM) const {
+    //
+    // can fill this in when new attribute work in llvm is done.
+    // attributes mips16 and nomips16 need to be handled here.
+    //
+  }
   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                                llvm::Value *Address) const;
 
diff --git a/lib/Sema/TargetAttributesSema.cpp 
b/lib/Sema/TargetAttributesSema.cpp
index 94f240c..1b8889d 100644
--- a/lib/Sema/TargetAttributesSema.cpp
+++ b/lib/Sema/TargetAttributesSema.cpp
@@ -262,6 +262,54 @@ namespace {
   };
 }
 
+static void HandleMips16Attr(Decl *D, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.hasParameterOrArguments()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+  // Attribute can only be applied to function types.
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << /* function */0;
+    return;
+  }
+  D->addAttr(::new (S.Context) Mips16Attr(Attr.getRange(), S.Context));
+}
+
+static void HandleNoMips16Attr(Decl *D, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.hasParameterOrArguments()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+    return;
+  }
+  // Attribute can only be applied to function types.
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << /* function */0;
+    return;
+  }
+  D->addAttr(::new (S.Context) NoMips16Attr(Attr.getRange(), S.Context));
+}
+
+namespace {
+  class MipsAttributesSema : public TargetAttributesSema {
+  public:
+    MipsAttributesSema() { }
+    bool ProcessDeclAttribute(Scope *scope, Decl *D, const AttributeList &Attr,
+                              Sema &S) const {
+      if (Attr.getName()->getName() == "mips16") {
+        HandleMips16Attr(D, Attr, S);
+        return true;
+      } else if (Attr.getName()->getName() == "nomips16") {
+        HandleNoMips16Attr(D, Attr, S);
+        return true;
+      }
+      return false;
+    }
+  };
+}
+
 const TargetAttributesSema &Sema::getTargetAttributesSema() const {
   if (TheTargetAttributesSema)
     return *TheTargetAttributesSema;
@@ -275,6 +323,9 @@ const TargetAttributesSema &Sema::getTargetAttributesSema() 
const {
   case llvm::Triple::x86:
   case llvm::Triple::x86_64:
     return *(TheTargetAttributesSema = new X86AttributesSema);
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+    return *(TheTargetAttributesSema = new MipsAttributesSema);
   default:
     return *(TheTargetAttributesSema = new TargetAttributesSema);
   }
diff --git a/test/Sema/mips16_attr_allowed.c b/test/Sema/mips16_attr_allowed.c
new file mode 100644
index 0000000..8ea7cc9
--- /dev/null
+++ b/test/Sema/mips16_attr_allowed.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple mipsel-linux-gnu -fsyntax-only -verify %s
+
+void foo32();
+void foo16();
+void __attribute__((nomips16)) foo32(); 
+void __attribute__((mips16)) foo16(); 
+
+void __attribute__((nomips16)) foo32_(); 
+void __attribute__((mips16)) foo16_(); 
+void foo32_();
+void foo16_();
+
+void foo32__() __attribute__((nomips16)); 
+void foo32__() __attribute__((mips16)); 
+
+void foo32() __attribute__((nomips16(xyz))) ; // expected-error {{attribute 
takes no arguments}}
+void __attribute__((mips16(xyz))) foo16a(); // expected-error {{attribute 
takes no arguments}}
+
+void __attribute__((nomips16(1, 2))) foo32b(); // expected-error {{attribute 
takes no arguments}}
+void __attribute__((mips16(1, 2))) foo16c(); // expected-error {{attribute 
takes no arguments}}
+
+
+__attribute((nomips16)) int a; // expected-error {{attribute only applies to 
functions}}
+
+__attribute((mips16)) int b; // expected-error {{attribute only applies to 
functions}}
+
+
diff --git a/test/Sema/mips16_attr_not_allowed.c 
b/test/Sema/mips16_attr_not_allowed.c
new file mode 100644
index 0000000..54f27d6
--- /dev/null
+++ b/test/Sema/mips16_attr_not_allowed.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+
+void __attribute__((nomips16)) foo32(); // expected-warning {{unknown 
attribute 'nomips16' ignored}}
+void __attribute__((mips16)) foo16(); // expected-warning {{unknown attribute 
'mips16' ignored}}
+
+
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to