Alternate address spaces work:

rename QualType::getQualifiers to getCVRQualifiers.
Add some fixme's and clean up some code relevant to qualifiers.
Change ASQualType to contain a Type* instead of a QualType.  
Any CVR qualifiers should be on the outer qual type.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47398 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp
index bd7215d..a636e8d 100644
--- a/AST/ASTContext.cpp
+++ b/AST/ASTContext.cpp
@@ -257,7 +257,7 @@
     break;
   }
   case Type::ASQual:
-    return getTypeInfo(cast<ASQualType>(T)->getBaseType(), L);
+    return getTypeInfo(QualType(cast<ASQualType>(T)->getBaseType(), 0), L);
   case Type::ObjCQualifiedId:
     Target.getPointerInfo(Size, Align, getFullLoc(L));
     break;
@@ -436,9 +436,18 @@
 //===----------------------------------------------------------------------===//
 
 QualType ASTContext::getASQualType(QualType T, unsigned AddressSpace) {
-  // Check if we've already instantiated an address space qual'd type of this type.
+  if (T.getCanonicalType().getAddressSpace() == AddressSpace)
+    return T;
+  
+  // Type's cannot have multiple ASQuals, therefore we know we only have to deal
+  // with CVR qualifiers from here on out.
+  assert(T.getCanonicalType().getAddressSpace() == 0 &&
+         "Type is already address space qualified");
+  
+  // Check if we've already instantiated an address space qual'd type of this
+  // type.
   llvm::FoldingSetNodeID ID;
-  ASQualType::Profile(ID, T, AddressSpace);      
+  ASQualType::Profile(ID, T.getTypePtr(), AddressSpace);      
   void *InsertPos = 0;
   if (ASQualType *ASQy = ASQualTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(ASQy, 0);
@@ -453,10 +462,10 @@
     ASQualType *NewIP = ASQualTypes.FindNodeOrInsertPos(ID, InsertPos);
     assert(NewIP == 0 && "Shouldn't be in the map!");
   }
-  ASQualType *New = new ASQualType(T, Canonical, AddressSpace);
+  ASQualType *New = new ASQualType(T.getTypePtr(), Canonical, AddressSpace);
   ASQualTypes.InsertNode(New, InsertPos);
   Types.push_back(New);
-  return QualType(New, 0);
+  return QualType(New, T.getCVRQualifiers());
 }
 
 
@@ -1621,7 +1630,8 @@
 bool ASTContext::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
   // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be 
   // identically qualified and both shall be pointers to compatible types.
-  if (lhs.getQualifiers() != rhs.getQualifiers())
+  if (lhs.getCVRQualifiers() != rhs.getCVRQualifiers() ||
+      lhs.getAddressSpace() != rhs.getAddressSpace())
     return false;
     
   QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
@@ -1713,7 +1723,8 @@
 /// C99 6.2.7p1: Two types have compatible types if their types are the 
 /// same. See 6.7.[2,3,5] for additional rules.
 bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) {
-  if (lhs.getQualifiers() != rhs.getQualifiers())
+  if (lhs.getCVRQualifiers() != rhs.getCVRQualifiers() ||
+      lhs.getAddressSpace() != rhs.getAddressSpace())
     return false;
 
   QualType lcanon = lhs.getCanonicalType();
diff --git a/AST/Expr.cpp b/AST/Expr.cpp
index 27dfa78..7a9a78e 100644
--- a/AST/Expr.cpp
+++ b/AST/Expr.cpp
@@ -358,7 +358,7 @@
     return LV_NotObjectType;
 
   // Allow qualified void which is an incomplete type other than void (yuck).
-  if (TR->isVoidType() && !TR.getCanonicalType().getQualifiers())
+  if (TR->isVoidType() && !TR.getCanonicalType().getCVRQualifiers())
     return LV_IncompleteVoidType;
 
   if (TR->isReferenceType()) // C++ [expr]
@@ -1000,7 +1000,8 @@
     // Check that it is a cast to void*.
     if (const PointerType *PT = CE->getType()->getAsPointerType()) {
       QualType Pointee = PT->getPointeeType();
-      if (Pointee.getQualifiers() == 0 && Pointee->isVoidType() && // to void*
+      if (Pointee.getCVRQualifiers() == 0 && 
+          Pointee->isVoidType() &&                                 // to void*
           CE->getSubExpr()->getType()->isIntegerType())            // from int.
         return CE->getSubExpr()->isNullPointerConstant(Ctx);
     }
diff --git a/AST/Type.cpp b/AST/Type.cpp
index 7e72d82..f5f7f3d 100644
--- a/AST/Type.cpp
+++ b/AST/Type.cpp
@@ -709,7 +709,12 @@
   const TypedefType *TDT = this;
   while (1) {
     QualType CurType = TDT->getDecl()->getUnderlyingType();
-    TypeQuals |= CurType.getQualifiers();
+    
+    
+    /// FIXME:
+    /// FIXME: This is incorrect for ASQuals!
+    /// FIXME:
+    TypeQuals |= CurType.getCVRQualifiers();
 
     TDT = dyn_cast<TypedefType>(CurType);
     if (TDT == 0)
@@ -755,8 +760,7 @@
   }
   
   // Print qualifiers as appropriate.
-  unsigned TQ = getQualifiers();
-  if (TQ) {
+  if (unsigned TQ = getCVRQualifiers()) {
     std::string TQS;
     AppendTypeQualList(TQS, TQ);
     if (!S.empty())
diff --git a/AST/TypeSerialization.cpp b/AST/TypeSerialization.cpp
index e2ccd3c..e1e8ef0 100644
--- a/AST/TypeSerialization.cpp
+++ b/AST/TypeSerialization.cpp
@@ -25,7 +25,7 @@
 
 void QualType::Emit(Serializer& S) const {
   S.EmitPtr(getTypePtr());
-  S.EmitInt(getQualifiers());
+  S.EmitInt(getCVRQualifiers());
 }
 
 QualType QualType::ReadVal(Deserializer& D) {
@@ -118,7 +118,7 @@
 //===----------------------------------------------------------------------===//
 
 void ASQualType::EmitImpl(Serializer& S) const {
-  S.Emit(getBaseType());
+  S.EmitPtr(getBaseType());
   S.EmitInt(getAddressSpace());
 }