diff options
-rw-r--r-- | include/clang/Basic/DiagnosticKinds.def | 4 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 14 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 72 |
3 files changed, 46 insertions, 44 deletions
diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 27e4e57532..9ea8d51249 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -650,8 +650,8 @@ DIAG(err_mode_not_primitive, ERROR, "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") +DIAG(err_attr_wrong_decl, ERROR, + "'%0' attribute invalid on this declaration, requires typedef or value") // Function Parameter Semantic Analysis. DIAG(err_param_with_void_type, ERROR, diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index ea551093b8..65c197ea3a 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -312,21 +312,9 @@ private: QualType HandleAddressSpaceTypeAttribute(QualType curType, const AttributeList &Attr); - /// HandleModeAttribute - this attribute modifies the width of a decl with - /// primitive type. Note that this is a variable attribute, and not - /// a type attribute. void HandleModeAttribute(Decl *d, const AttributeList &Attr); - // HandleVectorTypeAttribute - this attribute is only applicable to - // integral and float scalars, although arrays, pointers, and function - // return values are allowed in conjunction with this construct. Aggregates - // with this attribute are invalid, even if they are of the same size as a - // corresponding scalar. - // The raw attribute should contain precisely 1 argument, the vector size - // for the variable, measured in bytes. If curType and rawAttr are well - // formed, this routine will return a new vector type. - QualType HandleVectorTypeAttribute(QualType curType, - const AttributeList &Attr); + void HandleVectorSizeAttribute(Decl *d, const AttributeList &Attr); void HandleExtVectorTypeAttribute(Decl *d, const AttributeList &Attr); void HandleAlignedAttribute(Decl *d, const AttributeList &Attr); void HandleAliasAttribute(Decl *d, const AttributeList &Attr); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index c8396ad707..d2e5c9186b 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -89,19 +89,7 @@ void Sema::HandleDeclAttribute(Decl *New, const AttributeList &Attr) { case AttributeList::AT_address_space: // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. break; - case AttributeList::AT_vector_size: - if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) { - QualType newType = HandleVectorTypeAttribute(vDecl->getType(), Attr); - if (!newType.isNull()) // install the new vector type into the decl - vDecl->setType(newType); - } - if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) { - QualType newType = HandleVectorTypeAttribute(tDecl->getUnderlyingType(), - Attr); - if (!newType.isNull()) // install the new vector type into the decl - tDecl->setUnderlyingType(newType); - } - break; + case AttributeList::AT_vector_size:HandleVectorSizeAttribute(New, Attr);break; case AttributeList::AT_ext_vector_type: HandleExtVectorTypeAttribute(New, Attr); break; @@ -177,24 +165,43 @@ void Sema::HandleExtVectorTypeAttribute(Decl *d, const AttributeList &Attr) { ExtVectorDecls.push_back(tDecl); } -QualType Sema::HandleVectorTypeAttribute(QualType curType, - const AttributeList &Attr) { - // check the attribute arugments. + +/// HandleVectorSizeAttribute - this attribute is only applicable to +/// integral and float scalars, although arrays, pointers, and function +/// return values are allowed in conjunction with this construct. Aggregates +/// with this attribute are invalid, even if they are of the same size as a +/// corresponding scalar. +/// The raw attribute should contain precisely 1 argument, the vector size +/// for the variable, measured in bytes. If curType and rawAttr are well +/// formed, this routine will return a new vector type. +void Sema::HandleVectorSizeAttribute(Decl *D, const AttributeList &Attr) { + QualType CurType; + if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) + CurType = VD->getType(); + else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) + CurType = TD->getUnderlyingType(); + else { + Diag(D->getLocation(), diag::err_attr_wrong_decl,std::string("vector_size"), + SourceRange(Attr.getLoc(), Attr.getLoc())); + return; + } + + // Check the attribute arugments. if (Attr.getNumArgs() != 1) { Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, std::string("1")); - return QualType(); + return; } Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); llvm::APSInt vecSize(32); if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) { Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, "vector_size", sizeExpr->getSourceRange()); - return QualType(); + return; } // navigate to the base type - we need to provide for vector pointers, // vector arrays, and functions returning vectors. - Type *canonType = curType.getCanonicalType().getTypePtr(); + Type *canonType = CurType.getCanonicalType().getTypePtr(); if (canonType->isPointerType() || canonType->isArrayType() || canonType->isFunctionType()) { @@ -214,10 +221,10 @@ QualType Sema::HandleVectorTypeAttribute(QualType curType, // the base type must be integer or float. if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) { Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, - curType.getCanonicalType().getAsString()); - return QualType(); + CurType.getCanonicalType().getAsString()); + return; } - unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(curType)); + unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(CurType)); // vecSize is specified in bytes - convert to bits. unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); @@ -225,16 +232,22 @@ QualType Sema::HandleVectorTypeAttribute(QualType curType, if (vectorSize % typeSize) { Diag(Attr.getLoc(), diag::err_attribute_invalid_size, sizeExpr->getSourceRange()); - return QualType(); + return; } if (vectorSize == 0) { Diag(Attr.getLoc(), diag::err_attribute_zero_size, sizeExpr->getSourceRange()); - return QualType(); + return; } - // Instantiate the vector type, the number of elements is > 0, and not - // required to be a power of 2, unlike GCC. - return Context.getVectorType(curType, vectorSize/typeSize); + + // Success! Instantiate the vector type, the number of elements is > 0, and + // not required to be a power of 2, unlike GCC. + CurType = Context.getVectorType(CurType, vectorSize/typeSize); + + if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) + VD->setType(CurType); + else + cast<TypedefDecl>(D)->setUnderlyingType(CurType); } void Sema::HandlePackedAttribute(Decl *d, const AttributeList &Attr) { @@ -644,7 +657,8 @@ void Sema::HandleAlignedAttribute(Decl *d, const AttributeList &Attr) { d->addAttr(new AlignedAttr(Align)); } -/// HandleModeAttribute - Process a mode attribute on the specified decl. +/// HandleModeAttribute - This attribute modifies the width of a decl with +/// primitive type. /// /// Despite what would be logical, the mode attribute is a decl attribute, /// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make @@ -710,7 +724,7 @@ void Sema::HandleModeAttribute(Decl *D, const AttributeList &Attr) { else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) OldTy = VD->getType(); else { - Diag(D->getLocation(), diag::err_mode_wrong_decl, + Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode", SourceRange(Attr.getLoc(), Attr.getLoc())); return; } |