]> granicus.if.org Git - clang/commitdiff
Correctly handle address space qualifiers in declspecs. This
authorChris Lattner <sabre@nondot.org>
Thu, 21 Feb 2008 00:48:22 +0000 (00:48 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 21 Feb 2008 00:48:22 +0000 (00:48 +0000)
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

Sema/SemaDecl.cpp
Sema/SemaType.cpp
include/clang/Basic/DiagnosticKinds.def

index 69058ef1aa848bd734c48023c0852ab37bcceee1..9db0e0145eefad8a7d01bd9698365016a32d7833 100644 (file)
@@ -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();
index f17afd466db00bdc8dfa97a90d9c49e09e3b011c..2002bd371914e612455ae2caff2de759b969d124 100644 (file)
@@ -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) {
index b380b76d4c5ef3bac3857ef4745cb0a37f38ca34..882ca92e517d6f66d49afcba3ab2589654dae72d 100644 (file)
@@ -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,