[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