diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp index e5477c030d..45bae6d2f0 100644 --- a/Sema/SemaType.cpp +++ b/Sema/SemaType.cpp @@ -148,73 +148,6 @@ QualType Sema::ConvertDeclSpecToType(DeclSpec &DS) { return Result; } -AttributeList *Sema::ProcessTypeAttributes(QualType &Result, AttributeList *AL){ - // Scan through and apply attributes to this type where it makes sense. Some - // attributes (such as __address_space__, __vector_size__, etc) apply to the - // type, but others can be present in the type specifiers even though they - // apply to the decl. Here we apply and delete attributes that apply to the - // type and leave the others alone. - llvm::SmallVector LeftOverAttrs; - 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); - } - - // Rechain any attributes that haven't been deleted to the DeclSpec. - AttributeList *List = 0; - for (unsigned i = 0, e = LeftOverAttrs.size(); i != e; ++i) { - LeftOverAttrs[i]->setNext(List); - List = LeftOverAttrs[i]; - } - - return List; -} - -/// 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(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(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) { @@ -485,3 +418,70 @@ Sema::TypeResult Sema::ActOnParamDeclaratorType(Scope *S, Declarator &D) { // though it will not reflect the user specified type. return T.getAsOpaquePtr(); } + +AttributeList *Sema::ProcessTypeAttributes(QualType &Result, AttributeList *AL){ + // Scan through and apply attributes to this type where it makes sense. Some + // attributes (such as __address_space__, __vector_size__, etc) apply to the + // type, but others can be present in the type specifiers even though they + // apply to the decl. Here we apply and delete attributes that apply to the + // type and leave the others alone. + llvm::SmallVector LeftOverAttrs; + 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); + } + + // Rechain any attributes that haven't been deleted to the DeclSpec. + AttributeList *List = 0; + for (unsigned i = 0, e = LeftOverAttrs.size(); i != e; ++i) { + LeftOverAttrs[i]->setNext(List); + List = LeftOverAttrs[i]; + } + + return List; +} + +/// 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(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(addrSpace.getZExtValue()); + return Context.getASQualType(Type, ASIdx); +} +