[cfe-commits] r52844 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def lib/Sema/Sema.h lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaType.cpp

Chris Lattner sabre at nondot.org
Fri Jun 27 15:18:37 PDT 2008


Author: lattner
Date: Fri Jun 27 17:18:37 2008
New Revision: 52844

URL: http://llvm.org/viewvc/llvm-project?rev=52844&view=rev
Log:
the 'mode' attribute is a decl attribute, not a type attribute.  Move it to
SemaDeclAttr, and do some cleanups.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=52844&r1=52843&r2=52844&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Jun 27 17:18:37 2008
@@ -650,6 +650,8 @@
      "mode attribute only supported for integer and floating-point types")
 DIAG(err_mode_wrong_type, ERROR,
      "type of machine mode does not match type of base type")
+DIAG(err_mode_wrong_decl, ERROR,
+     "declaration does not allow mode attribute")
 
 // Function Parameter Semantic Analysis.
 DIAG(err_param_with_void_type, ERROR,

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=52844&r1=52843&r2=52844&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Jun 27 17:18:37 2008
@@ -307,11 +307,10 @@
   QualType HandleAddressSpaceTypeAttribute(QualType curType, 
                                            const AttributeList *rawAttr);
 
-  /// HandleModeTypeAttribute - this attribute modifies the width of a
+  /// HandleModeAttribute - this attribute modifies the width of a decl with
   /// primitive type.  Note that this is a variable attribute, and not
   /// a type attribute.
-  QualType HandleModeTypeAttribute(QualType curType, 
-                                   const AttributeList *rawAttr);
+  void HandleModeAttribute(Decl *d, const AttributeList &Attr);
 
   // HandleVectorTypeAttribute - this attribute is only applicable to 
   // integral and float scalars, although arrays, pointers, and function

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=52844&r1=52843&r2=52844&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Jun 27 17:18:37 2008
@@ -13,7 +13,7 @@
 
 #include "Sema.h"
 #include "clang/AST/ASTContext.h"
-
+#include "clang/Basic/TargetInfo.h"
 using namespace clang;
 
 static const FunctionTypeProto *getFunctionProto(Decl *d) {
@@ -80,20 +80,7 @@
   case AttributeList::AT_address_space:
     // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
     break;
-  case AttributeList::AT_mode:
-    // Despite what would be logical, the mode attribute is a decl attribute,
-    // not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
-    // 'G' be HImode, not an intermediate pointer.
-    if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
-      QualType newType = HandleModeTypeAttribute(tDecl->getUnderlyingType(),
-                                                 Attr);
-      tDecl->setUnderlyingType(newType);
-    } else if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
-      QualType newType = HandleModeTypeAttribute(vDecl->getType(), Attr);
-      vDecl->setType(newType);
-    }
-    // FIXME: Diagnostic?
-    break;
+  case AttributeList::AT_mode:       HandleModeAttribute(New, *Attr);  break;
   case AttributeList::AT_alias:      HandleAliasAttribute(New, Attr); break;
   case AttributeList::AT_deprecated: HandleDeprecatedAttribute(New, Attr);break;
   case AttributeList::AT_visibility: HandleVisibilityAttribute(New, Attr);break;
@@ -653,3 +640,129 @@
 
   d->addAttr(new AlignedAttr(Align));
 }
+
+/// HandleModeAttribute - Process a mode attribute on the specified decl.
+///
+/// Despite what would be logical, the mode attribute is a decl attribute,
+/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
+/// 'G' be HImode, not an intermediate pointer.
+///
+void Sema::HandleModeAttribute(Decl *D, const AttributeList &Attr) {
+  // This attribute isn't documented, but glibc uses it.  It changes
+  // the width of an int or unsigned int to the specified size.
+
+  // Check that there aren't any arguments
+  if (Attr.getNumArgs() != 0) {
+    Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+
+  IdentifierInfo *Name = Attr.getParameterName();
+  if (!Name) {
+    Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
+    return;
+  }
+  const char *Str = Name->getName();
+  unsigned Len = Name->getLength();
+
+  // Normalize the attribute name, __foo__ becomes foo.
+  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
+      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
+    Str += 2;
+    Len -= 4;
+  }
+
+  unsigned DestWidth = 0;
+  bool IntegerMode = true;
+  switch (Len) {
+  case 2:
+    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
+    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
+    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
+    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
+    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
+    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
+    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
+    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
+    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
+    break;
+  case 4:
+    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
+    // pointer on PIC16 and other embedded platforms.
+    if (!memcmp(Str, "word", 4))
+      DestWidth = Context.Target.getPointerWidth(0);
+    if (!memcmp(Str, "byte", 4))
+      DestWidth = Context.Target.getCharWidth();
+    break;
+  case 7:
+    if (!memcmp(Str, "pointer", 7))
+      DestWidth = Context.Target.getPointerWidth(0);
+    break;
+  }
+
+  QualType OldTy;
+  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
+    OldTy = TD->getUnderlyingType();
+  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+    OldTy = VD->getType();
+  else {
+    Diag(D->getLocation(), diag::err_mode_wrong_decl,
+         SourceRange(Attr.getLoc(), Attr.getLoc()));
+    return;
+  }
+  
+  // FIXME: Need proper fixed-width types
+  QualType NewTy;
+  switch (DestWidth) {
+  case 0:
+    Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
+    return;
+  default:
+    Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
+    return;
+  case 8:
+    assert(IntegerMode);
+    if (OldTy->isSignedIntegerType())
+      NewTy = Context.SignedCharTy;
+    else
+      NewTy = Context.UnsignedCharTy;
+    break;
+  case 16:
+    assert(IntegerMode);
+    if (OldTy->isSignedIntegerType())
+      NewTy = Context.ShortTy;
+    else
+      NewTy = Context.UnsignedShortTy;
+    break;
+  case 32:
+    if (!IntegerMode)
+      NewTy = Context.FloatTy;
+    else if (OldTy->isSignedIntegerType())
+      NewTy = Context.IntTy;
+    else
+      NewTy = Context.UnsignedIntTy;
+    break;
+  case 64:
+    if (!IntegerMode)
+      NewTy = Context.DoubleTy;
+    else if (OldTy->isSignedIntegerType())
+      NewTy = Context.LongLongTy;
+    else
+      NewTy = Context.UnsignedLongLongTy;
+    break;
+  }
+
+  if (!OldTy->getAsBuiltinType())
+    Diag(Attr.getLoc(), diag::err_mode_not_primitive);
+  else if (!(IntegerMode && OldTy->isIntegerType()) &&
+           !(!IntegerMode && OldTy->isFloatingType())) {
+    Diag(Attr.getLoc(), diag::err_mode_wrong_type);
+  }
+
+  // Install the new type.
+  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
+    TD->setUnderlyingType(NewTy);
+  else
+    cast<ValueDecl>(D)->setType(NewTy);
+}

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=52844&r1=52843&r2=52844&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Jun 27 17:18:37 2008
@@ -560,123 +560,4 @@
   return Context.getASQualType(Type, ASIdx);
 }
 
-/// HandleModeTypeAttribute - Process a mode attribute on the
-/// specified type.
-QualType Sema::HandleModeTypeAttribute(QualType Type, 
-                                       const AttributeList *Attr) {
-  // This attribute isn't documented, but glibc uses it.  It changes
-  // the width of an int or unsigned int to the specified size.
-
-  // Check that there aren't any arguments
-  if (Attr->getNumArgs() != 0) {
-    Diag(Attr->getLoc(), diag::err_attribute_wrong_number_arguments,
-         std::string("0"));
-    return Type;
-  }
-
-  IdentifierInfo * Name = Attr->getParameterName();
-  if (!Name) {
-    Diag(Attr->getLoc(), diag::err_attribute_missing_parameter_name);
-    return Type;
-  }
-  const char *Str = Name->getName();
-  unsigned Len = Name->getLength();
-
-  // Normalize the attribute name, __foo__ becomes foo.
-  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
-      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
-    Str += 2;
-    Len -= 4;
-  }
-
-  unsigned DestWidth = 0;
-  bool IntegerMode = true;
-
-  switch (Len) {
-  case 2:
-    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
-    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
-    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
-    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
-    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
-    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
-    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
-    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
-    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
-    break;
-  case 4:
-    if (!memcmp(Str, "word", 4)) {
-      // FIXME: glibc uses this to define register_t; this is
-      // narrover than a pointer on PIC16 and other embedded
-      // platforms
-      DestWidth = Context.getTypeSize(Context.VoidPtrTy);
-      break;
-    }
-    if (!memcmp(Str, "byte", 4)) {
-      DestWidth = Context.getTypeSize(Context.CharTy);
-      break;
-    }
-    break;
-  case 7:
-    if (!memcmp(Str, "pointer", 7)) {
-      DestWidth = Context.getTypeSize(Context.VoidPtrTy);
-      IntegerMode = true;
-      break;
-    }
-    break;
-  }
-
-  // FIXME: Need proper fixed-width types
-  QualType RetTy;
-  switch (DestWidth) {
-  case 0:
-    Diag(Attr->getLoc(), diag::err_unknown_machine_mode, 
-         std::string(Str, Len));
-    return Type;
-  case 8:
-    assert(IntegerMode);
-    if (Type->isSignedIntegerType())
-      RetTy = Context.SignedCharTy;
-    else
-      RetTy = Context.UnsignedCharTy;
-    break;
-  case 16:
-    assert(IntegerMode);
-    if (Type->isSignedIntegerType())
-      RetTy = Context.ShortTy;
-    else
-      RetTy = Context.UnsignedShortTy;
-    break;
-  case 32:
-    if (!IntegerMode)
-      RetTy = Context.FloatTy;
-    else if (Type->isSignedIntegerType())
-      RetTy = Context.IntTy;
-    else
-      RetTy = Context.UnsignedIntTy;
-    break;
-  case 64:
-    if (!IntegerMode)
-      RetTy = Context.DoubleTy;
-    else if (Type->isSignedIntegerType())
-      RetTy = Context.LongLongTy;
-    else
-      RetTy = Context.UnsignedLongLongTy;
-    break;
-  default:
-    Diag(Attr->getLoc(), diag::err_unsupported_machine_mode,
-         std::string(Str, Len));
-    return Type;
-  }
-
-  if (!Type->getAsBuiltinType())
-    Diag(Attr->getLoc(), diag::err_mode_not_primitive);
-  else if (!(IntegerMode && Type->isIntegerType()) &&
-           !(!IntegerMode && Type->isFloatingType())) {
-    Diag(Attr->getLoc(), diag::err_mode_wrong_type);
-  }
-
-  return RetTy;
-}
-
 





More information about the cfe-commits mailing list