diff options
author | Chris Lattner <sabre@nondot.org> | 2008-02-21 00:48:22 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-02-21 00:48:22 +0000 |
commit | 74788ba1dc1dd836edd1956c1a4b071b2bb71574 (patch) | |
tree | 093a5f0d477b6cd1152282c4c8899b82353a9163 | |
parent | fab5b45729db4e24ba43bb94d1bce5f73106be78 (diff) |
Correctly handle address space qualifiers in declspecs. This
allows us to correctly handle stuff like:
_AS1 float *B;
and to reject stuff like:
_AS1 _AS2* x;
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47417 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | Sema/SemaDecl.cpp | 54 | ||||
-rw-r--r-- | Sema/SemaType.cpp | 43 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticKinds.def | 2 |
3 files changed, 58 insertions, 41 deletions
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 69058ef1aa..9db0e0145e 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1735,48 +1735,47 @@ Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc, return new LinkageSpecDecl(Loc, Language, dcl); } -void Sema::HandleDeclAttribute(Decl *New, AttributeList *rawAttr) { +void Sema::HandleDeclAttribute(Decl *New, AttributeList *Attr) { - switch (rawAttr->getKind()) { + switch (Attr->getKind()) { case AttributeList::AT_vector_size: if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) { - QualType newType = HandleVectorTypeAttribute(vDecl->getType(), rawAttr); + 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(), - rawAttr); + Attr); if (!newType.isNull()) // install the new vector type into the decl tDecl->setUnderlyingType(newType); } break; case AttributeList::AT_ocu_vector_type: if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) - HandleOCUVectorTypeAttribute(tDecl, rawAttr); + HandleOCUVectorTypeAttribute(tDecl, Attr); else - Diag(rawAttr->getLoc(), + Diag(Attr->getLoc(), diag::err_typecheck_ocu_vector_not_typedef); break; case AttributeList::AT_address_space: if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) { QualType newType = HandleAddressSpaceTypeAttribute( tDecl->getUnderlyingType(), - rawAttr); - if (!newType.isNull()) // install the new addr spaced type into the decl - tDecl->setUnderlyingType(newType); + Attr); + tDecl->setUnderlyingType(newType); } else if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) { QualType newType = HandleAddressSpaceTypeAttribute(vDecl->getType(), - rawAttr); - if (!newType.isNull()) // install the new addr spaced type into the decl - vDecl->setType(newType); + Attr); + // install the new addr spaced type into the decl + vDecl->setType(newType); } break; case AttributeList::AT_aligned: - HandleAlignedAttribute(New, rawAttr); + HandleAlignedAttribute(New, Attr); break; case AttributeList::AT_packed: - HandlePackedAttribute(New, rawAttr); + HandlePackedAttribute(New, Attr); break; default: // FIXME: add other attributes... @@ -1796,33 +1795,6 @@ void Sema::HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix, } } -QualType Sema::HandleAddressSpaceTypeAttribute(QualType curType, - AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 1) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("1")); - return QualType(); - } - Expr *addrSpaceExpr = static_cast<Expr *>(rawAttr->getArg(0)); - llvm::APSInt addrSpace(32); - if (!addrSpaceExpr->isIntegerConstantExpr(addrSpace, Context)) { - Diag(rawAttr->getLoc(), diag::err_attribute_address_space_not_int, - addrSpaceExpr->getSourceRange()); - return QualType(); - } - unsigned addressSpace = static_cast<unsigned>(addrSpace.getZExtValue()); - - // Zero is the default memory space, so no qualification is needed - if (addressSpace == 0) - return curType; - - // TODO: Should we convert contained types of address space - // qualified types here or or where they directly participate in conversions - // (i.e. elsewhere) - return Context.getASQualType(curType, addressSpace); -} - void Sema::HandleOCUVectorTypeAttribute(TypedefDecl *tDecl, AttributeList *rawAttr) { QualType curType = tDecl->getUnderlyingType(); diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp index f17afd466d..2002bd3719 100644 --- a/Sema/SemaType.cpp +++ b/Sema/SemaType.cpp @@ -153,8 +153,20 @@ QualType Sema::ConvertDeclSpecToType(DeclSpec &DS) { llvm::SmallVector<AttributeList *, 8> LeftOverAttrs; AttributeList *AL = DS.getAttributes(); while (AL) { + // Unlink this attribute from the chain, so we can process it independently. AttributeList *ThisAttr = AL; AL = AL->getNext(); + ThisAttr->setNext(0); + + // If this is an attribute we can handle, do so now, otherwise, add it to + // the LeftOverAttrs list for rechaining. + switch (ThisAttr->getKind()) { + default: break; + case AttributeList::AT_address_space: + Result = HandleAddressSpaceTypeAttribute(Result, ThisAttr); + delete ThisAttr; // Consume the attribute. + continue; + } LeftOverAttrs.push_back(ThisAttr); } @@ -172,6 +184,37 @@ QualType Sema::ConvertDeclSpecToType(DeclSpec &DS) { return Result; } +/// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the +/// specified type. +QualType Sema::HandleAddressSpaceTypeAttribute(QualType Type, + AttributeList *Attr) { + // If this type is already address space qualified, reject it. + // Clause 6.7.3 - Type qualifiers: "No type shall be qualified by qualifiers + // for two or more different address spaces." + if (Type.getAddressSpace()) { + Diag(Attr->getLoc(), diag::err_attribute_address_multiple_qualifiers); + return Type; + } + + // Check the attribute arguments. + if (Attr->getNumArgs() != 1) { + Diag(Attr->getLoc(), diag::err_attribute_wrong_number_arguments, + std::string("1")); + return Type; + } + Expr *ASArgExpr = static_cast<Expr *>(Attr->getArg(0)); + llvm::APSInt addrSpace(32); + if (!ASArgExpr->isIntegerConstantExpr(addrSpace, Context)) { + Diag(Attr->getLoc(), diag::err_attribute_address_space_not_int, + ASArgExpr->getSourceRange()); + return Type; + } + + unsigned ASIdx = static_cast<unsigned>(addrSpace.getZExtValue()); + return Context.getASQualType(Type, ASIdx); +} + + /// GetTypeForDeclarator - Convert the type for the specified declarator to Type /// instances. QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index b380b76d4c..882ca92e51 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -579,6 +579,8 @@ DIAG(err_ocuvector_component_access, ERROR, "vector component access limited to variables") DIAG(err_attribute_address_space_not_int, ERROR, "address space attribute requires an integer constant") +DIAG(err_attribute_address_multiple_qualifiers, ERROR, + "multiple address spaces specified for type") DIAG(warn_attribute_ignored, WARNING, "'%0' attribute ignored") DIAG(warn_attribute_ignored_for_field_of_type, WARNING, |