//===--------------------------------------------------------------------===//
// Type Analysis / Processing: SemaType.cpp.
//
- QualType ConvertDeclSpecToType(DeclSpec &DS);
- AttributeList *ProcessTypeAttributes(QualType &Result, AttributeList *AL);
+ QualType ConvertDeclSpecToType(const DeclSpec &DS);
+ void ProcessTypeAttributes(QualType &Result, const AttributeList *AL);
QualType GetTypeForDeclarator(Declarator &D, Scope *S);
/// The raw attribute contains 1 argument, the id of the address space
/// for the type.
QualType HandleAddressSpaceTypeAttribute(QualType curType,
- AttributeList *rawAttr);
+ const AttributeList *rawAttr);
/// HandleModeTypeAttribute - this attribute modifies the width of a
/// primitive type. Note that this is a variable attribute, and not
diag::err_typecheck_ext_vector_not_typedef);
break;
case AttributeList::AT_address_space:
- if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
- QualType newType = HandleAddressSpaceTypeAttribute(
- tDecl->getUnderlyingType(),
- Attr);
- tDecl->setUnderlyingType(newType);
- } else if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
- QualType newType = HandleAddressSpaceTypeAttribute(vDecl->getType(),
- Attr);
- // install the new addr spaced type into the decl
- vDecl->setType(newType);
- }
+ // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
break;
case AttributeList::AT_mode:
if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
void Sema::HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix,
AttributeList *declarator_postfix) {
+ if (declspec_prefix == 0 && declarator_postfix == 0) return;
+
while (declspec_prefix) {
HandleDeclAttribute(New, declspec_prefix);
declspec_prefix = declspec_prefix->getNext();
}
+
+ // If there are any type attributes that were in the declarator, apply them to
+ // its top level type.
+ if (ValueDecl *VD = dyn_cast<ValueDecl>(New)) {
+ QualType DT = VD->getType();
+ ProcessTypeAttributes(DT, declarator_postfix);
+ VD->setType(DT);
+ } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(New)) {
+ QualType DT = TD->getUnderlyingType();
+ ProcessTypeAttributes(DT, declarator_postfix);
+ TD->setUnderlyingType(DT);
+ }
+
while (declarator_postfix) {
HandleDeclAttribute(New, declarator_postfix);
declarator_postfix = declarator_postfix->getNext();
/// ConvertDeclSpecToType - Convert the specified declspec to the appropriate
/// type object. This returns null on error.
-QualType Sema::ConvertDeclSpecToType(DeclSpec &DS) {
+QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
// FIXME: Should move the logic from DeclSpec::Finish to here for validity
// checking.
QualType Result;
// See if there are any attributes on the declspec that apply to the type (as
// opposed to the decl).
- if (AttributeList *AL = DS.getAttributes())
- DS.SetAttributes(ProcessTypeAttributes(Result, AL));
+ if (const AttributeList *AL = DS.getAttributes())
+ ProcessTypeAttributes(Result, AL);
// Apply const/volatile/restrict qualifiers to T.
if (unsigned TypeQuals = DS.getTypeQualifiers()) {
T = Context.getPointerType(T).getQualifiedType(DeclType.Ptr.TypeQuals);
// See if there are any attributes on the pointer that apply to it.
- if (AttributeList *AL = DeclType.Ptr.AttrList)
- DeclType.Ptr.AttrList = ProcessTypeAttributes(T, AL);
+ if (const AttributeList *AL = DeclType.Ptr.AttrList)
+ ProcessTypeAttributes(T, AL);
break;
case DeclaratorChunk::Reference:
T.addRestrict();
// See if there are any attributes on the pointer that apply to it.
- if (AttributeList *AL = DeclType.Ref.AttrList)
- DeclType.Ref.AttrList = ProcessTypeAttributes(T, AL);
+ if (const AttributeList *AL = DeclType.Ref.AttrList)
+ ProcessTypeAttributes(T, AL);
break;
case DeclaratorChunk::Array: {
DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
return T.getAsOpaquePtr();
}
-AttributeList *Sema::ProcessTypeAttributes(QualType &Result, AttributeList *AL){
+void Sema::ProcessTypeAttributes(QualType &Result, const 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<AttributeList *, 8> LeftOverAttrs;
- while (AL) {
- // Unlink this attribute from the chain, so we can process it independently.
- AttributeList *ThisAttr = AL;
- AL = AL->getNext();
- ThisAttr->setNext(0);
-
+ // apply to the decl. Here we apply type attributes and ignore the rest.
+ for (; AL; AL = AL->getNext()) {
// If this is an attribute we can handle, do so now, otherwise, add it to
// the LeftOverAttrs list for rechaining.
- switch (ThisAttr->getKind()) {
+ switch (AL->getKind()) {
default: break;
case AttributeList::AT_address_space:
- Result = HandleAddressSpaceTypeAttribute(Result, ThisAttr);
- delete ThisAttr; // Consume the attribute.
+ Result = HandleAddressSpaceTypeAttribute(Result, AL);
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) {
+ const 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."