зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
fab5b45729
Коммит
74788ba1dc
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче