Add experimental support for address space qualified types. Address space
qualifiers use the __attribute__((address_space(id))) syntax.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46691 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index f45b339..f00ed7f 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -1760,6 +1760,19 @@
     else
       Diag(rawAttr->getAttributeLoc(), 
            diag::err_typecheck_ocu_vector_not_typedef);
+  } else if (attrLen == 13 && !memcmp(attrName, "address_space", 13)) {
+    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);
+    } 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);
+    }
   } else if (attrLen == 7 && !memcmp(attrName, "aligned", 7)) {
       HandleAlignedAttribute(New, rawAttr);
   }
@@ -1779,6 +1792,34 @@
   }
 }
 
+QualType Sema::HandleAddressSpaceTypeAttribute(QualType curType, 
+                                               AttributeList *rawAttr) {
+  // check the attribute arugments.
+  if (rawAttr->getNumArgs() != 1) {
+    Diag(rawAttr->getAttributeLoc(), 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->getAttributeLoc(), 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();