Refactor the representation of qualifiers to bring ExtQualType out of the
Type hierarchy.  Demote 'volatile' to extended-qualifier status.  Audit our
use of qualifiers and fix a few places that weren't dealing with qualifiers
quite right;  many more remain.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82705 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 0a0d291..8934a67 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -1686,8 +1686,8 @@
         // FIXME: This is really ugly; should be refactored somehow
         unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
         llvm::Value *V = Builder.CreateStructGEP(LoadOfThis, idx, "tmp");
-        LHS = LValue::MakeAddr(V, FieldType.getCVRQualifiers(),
-                               QualType::GCNone, FieldType.getAddressSpace());
+        assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs");
+        LHS = LValue::MakeAddr(V, MakeQualifiers(FieldType));
       } else {
         LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
       }
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 1dbb6e6..0b9b3fc 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -629,7 +629,7 @@
                                            (Name + ".addr").c_str());
       // FIXME: What are the right qualifiers here?
       llvm::Function::arg_iterator End =
-        ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp,0), AI);
+        ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp, Qualifiers()), AI);
       EmitParmDecl(*Arg, Temp);
 
       // Name the arguments used in expansion and increment AI.
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 0074316..197fcac 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -788,7 +788,6 @@
   case Type::RValueReference:
   case Type::Vector:
   case Type::ExtVector:
-  case Type::ExtQual:
   case Type::FixedWidthInt:
   case Type::MemberPointer:
   case Type::TemplateSpecialization:
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index a7eebbf..309f38e 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -166,9 +166,7 @@
   ErrorUnsupported(E, Name);
   llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
   return LValue::MakeAddr(llvm::UndefValue::get(Ty),
-                          E->getType().getCVRQualifiers(),
-                          getContext().getObjCGCAttrKind(E->getType()),
-                          E->getType().getAddressSpace());
+                          MakeQualifiers(E->getType()));
 }
 
 /// EmitLValue - Emit code to compute a designator that specifies the location
@@ -746,17 +744,16 @@
       llvm::Value *V = CGM.GetAddrOfGlobalVar(VD);
       if (VD->getType()->isReferenceType())
         V = Builder.CreateLoad(V, "tmp");
-      LV = LValue::MakeAddr(V, E->getType().getCVRQualifiers(),
-                            getContext().getObjCGCAttrKind(E->getType()),
-                            E->getType().getAddressSpace());
+      LV = LValue::MakeAddr(V, MakeQualifiers(E->getType()));
     } else {
       llvm::Value *V = LocalDeclMap[VD];
       assert(V && "DeclRefExpr not entered in LocalDeclMap?");
+
+      Qualifiers Quals = MakeQualifiers(E->getType());
       // local variables do not get their gc attribute set.
-      QualType::GCAttrTypes attr = QualType::GCNone;
       // local static?
-      if (!NonGCable)
-        attr = getContext().getObjCGCAttrKind(E->getType());
+      if (NonGCable) Quals.removeObjCGCAttr();
+
       if (VD->hasAttr<BlocksAttr>()) {
         V = Builder.CreateStructGEP(V, 1, "forwarding");
         V = Builder.CreateLoad(V, false);
@@ -765,8 +762,7 @@
       }
       if (VD->getType()->isReferenceType())
         V = Builder.CreateLoad(V, "tmp");
-      LV = LValue::MakeAddr(V, E->getType().getCVRQualifiers(), attr,
-                            E->getType().getAddressSpace());
+      LV = LValue::MakeAddr(V, Quals);
     }
     LValue::SetObjCNonGC(LV, NonGCable);
     setObjCGCLValueClass(getContext(), E, LV);
@@ -775,9 +771,7 @@
     llvm::Value *V = CGM.GetAddrOfGlobalVar(VD);
     if (VD->getType()->isReferenceType())
       V = Builder.CreateLoad(V, "tmp");
-    LValue LV = LValue::MakeAddr(V, E->getType().getCVRQualifiers(),
-                                 getContext().getObjCGCAttrKind(E->getType()),
-                                 E->getType().getAddressSpace());
+    LValue LV = LValue::MakeAddr(V, MakeQualifiers(E->getType()));
     setObjCGCLValueClass(getContext(), E, LV);
     return LV;
   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
@@ -794,16 +788,12 @@
         V = Builder.CreateBitCast(V, ConvertType(NoProtoType), "tmp");
       }
     }
-    return LValue::MakeAddr(V, E->getType().getCVRQualifiers(),
-                            getContext().getObjCGCAttrKind(E->getType()),
-                            E->getType().getAddressSpace());
+    return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
   } else if (const ImplicitParamDecl *IPD =
       dyn_cast<ImplicitParamDecl>(E->getDecl())) {
     llvm::Value *V = LocalDeclMap[IPD];
     assert(V && "BlockVarDecl not entered in LocalDeclMap?");
-    return LValue::MakeAddr(V, E->getType().getCVRQualifiers(),
-                            getContext().getObjCGCAttrKind(E->getType()),
-                            E->getType().getAddressSpace());
+    return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
   }
   assert(0 && "Unimp declref");
   //an invalid LValue, but the assert will
@@ -812,10 +802,7 @@
 }
 
 LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) {
-  return LValue::MakeAddr(GetAddrOfBlockDecl(E),
-                          E->getType().getCVRQualifiers(),
-                          getContext().getObjCGCAttrKind(E->getType()),
-                          E->getType().getAddressSpace());
+  return LValue::MakeAddr(GetAddrOfBlockDecl(E), MakeQualifiers(E->getType()));
 }
 
 LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
@@ -831,10 +818,10 @@
       QualType T = E->getSubExpr()->getType()->getPointeeType();
       assert(!T.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
 
-      LValue LV = LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()),
-                                   T.getCVRQualifiers(),
-                                   getContext().getObjCGCAttrKind(T),
-                                   ExprTy.getAddressSpace());
+      Qualifiers Quals = MakeQualifiers(T);
+      Quals.setAddressSpace(ExprTy.getAddressSpace());
+
+      LValue LV = LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()), Quals);
      // We should not generate __weak write barrier on indirect reference
      // of a pointer to object; as in void foo (__weak id *param); *param = 0;
      // But, we continue to generate __strong write barrier on indirect write
@@ -851,18 +838,18 @@
     unsigned Idx = E->getOpcode() == UnaryOperator::Imag;
     return LValue::MakeAddr(Builder.CreateStructGEP(LV.getAddress(),
                                                     Idx, "idx"),
-                            ExprTy.getCVRQualifiers(),
-                            QualType::GCNone,
-                            ExprTy.getAddressSpace());
+                            MakeQualifiers(ExprTy));
   }
 }
 
 LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
-  return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromLiteral(E), 0);
+  return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromLiteral(E),
+                          Qualifiers());
 }
 
 LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {
-  return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromObjCEncode(E), 0);
+  return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromObjCEncode(E),
+                          Qualifiers());
 }
 
 
@@ -894,7 +881,7 @@
 
   llvm::Constant *C =
     CGM.GetAddrOfConstantCString(FunctionName, GlobalVarName.c_str());
-  return LValue::MakeAddr(C, 0);
+  return LValue::MakeAddr(C, Qualifiers());
 }
 
 LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
@@ -923,7 +910,7 @@
     Idx = Builder.CreateIntCast(Idx,
                           llvm::Type::getInt32Ty(VMContext), IdxSigned, "vidx");
     return LValue::MakeVectorElt(LHS.getAddress(), Idx,
-      E->getBase()->getType().getCVRQualifiers());
+                                 E->getBase()->getType().getCVRQualifiers());
   }
 
   // The base must be a pointer, which is not an aggregate.  Emit it.
@@ -973,10 +960,10 @@
   assert(!T.isNull() &&
          "CodeGenFunction::EmitArraySubscriptExpr(): Illegal base type");
 
-  LValue LV = LValue::MakeAddr(Address,
-                               T.getCVRQualifiers(),
-                               getContext().getObjCGCAttrKind(T),
-                               E->getBase()->getType().getAddressSpace());
+  Qualifiers Quals = MakeQualifiers(T);
+  Quals.setAddressSpace(E->getBase()->getType().getAddressSpace());
+
+  LValue LV = LValue::MakeAddr(Address, Quals);
   if (getContext().getLangOptions().ObjC1 &&
       getContext().getLangOptions().getGCMode() != LangOptions::NonGC) {
     LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
@@ -1009,9 +996,9 @@
   } else {
     const PointerType *PT = E->getBase()->getType()->getAs<PointerType>();
     llvm::Value *Ptr = EmitScalarExpr(E->getBase());
-    Base = LValue::MakeAddr(Ptr, PT->getPointeeType().getCVRQualifiers(),
-                            QualType::GCNone,
-                            PT->getPointeeType().getAddressSpace());
+    Qualifiers Quals = MakeQualifiers(PT->getPointeeType());
+    Quals.removeObjCGCAttr();
+    Base = LValue::MakeAddr(Ptr, Quals);
   }
 
   // Encode the element access list into a vector of unsigned indices.
@@ -1021,7 +1008,7 @@
   if (Base.isSimple()) {
     llvm::Constant *CV = GenerateConstantVector(VMContext, Indices);
     return LValue::MakeExtVectorElt(Base.getAddress(), CV,
-                                    Base.getQualifiers());
+                                    Base.getVRQualifiers());
   }
   assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!");
 
@@ -1037,7 +1024,7 @@
   }
   llvm::Constant *CV = llvm::ConstantVector::get(&CElts[0], CElts.size());
   return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV,
-                                  Base.getQualifiers());
+                                  Base.getVRQualifiers());
 }
 
 LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
@@ -1045,7 +1032,7 @@
   bool isNonGC = false;
   Expr *BaseExpr = E->getBase();
   llvm::Value *BaseValue = NULL;
-  unsigned CVRQualifiers=0;
+  Qualifiers BaseQuals;
 
   // If this is s.x, emit s as an lvalue.  If it is s->x, emit s as a scalar.
   if (E->isArrow()) {
@@ -1054,7 +1041,7 @@
       BaseExpr->getType()->getAs<PointerType>();
     if (PTy->getPointeeType()->isUnionType())
       isUnion = true;
-    CVRQualifiers = PTy->getPointeeType().getCVRQualifiers();
+    BaseQuals = PTy->getPointeeType().getQualifiers();
   } else if (isa<ObjCPropertyRefExpr>(BaseExpr->IgnoreParens()) ||
              isa<ObjCImplicitSetterGetterRefExpr>(
                BaseExpr->IgnoreParens())) {
@@ -1062,7 +1049,7 @@
     BaseValue = RV.getAggregateAddr();
     if (BaseExpr->getType()->isUnionType())
       isUnion = true;
-    CVRQualifiers = BaseExpr->getType().getCVRQualifiers();
+    BaseQuals = BaseExpr->getType().getQualifiers();
   } else {
     LValue BaseLV = EmitLValue(BaseExpr);
     if (BaseLV.isNonGC())
@@ -1072,14 +1059,14 @@
     QualType BaseTy = BaseExpr->getType();
     if (BaseTy->isUnionType())
       isUnion = true;
-    CVRQualifiers = BaseTy.getCVRQualifiers();
+    BaseQuals = BaseTy.getQualifiers();
   }
 
   FieldDecl *Field = dyn_cast<FieldDecl>(E->getMemberDecl());
   // FIXME: Handle non-field member expressions
   assert(Field && "No code generation for non-field member references");
   LValue MemExpLV = EmitLValueForField(BaseValue, Field, isUnion,
-                                       CVRQualifiers);
+                                       BaseQuals.getCVRQualifiers());
   LValue::SetObjCNonGC(MemExpLV, isNonGC);
   setObjCGCLValueClass(getContext(), E, MemExpLV);
   return MemExpLV;
@@ -1133,17 +1120,14 @@
   }
   if (Field->getType()->isReferenceType())
     V = Builder.CreateLoad(V, "tmp");
-  QualType::GCAttrTypes attr = getContext().getObjCGCAttrKind(Field->getType());
+
+  Qualifiers Quals = MakeQualifiers(Field->getType());
+  Quals.addCVRQualifiers(CVRQualifiers);
   // __weak attribute on a field is ignored.
-  if (attr == QualType::Weak)
-    attr = QualType::GCNone;
+  if (Quals.getObjCGCAttr() == Qualifiers::Weak)
+    Quals.removeObjCGCAttr();
   
-  LValue LV =
-    LValue::MakeAddr(V,
-                     Field->getType().getCVRQualifiers()|CVRQualifiers,
-                     attr,
-                     Field->getType().getAddressSpace());
-  return LV;
+  return LValue::MakeAddr(V, Quals);
 }
 
 LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E){
@@ -1151,9 +1135,7 @@
   llvm::Value *DeclPtr = CreateTempAlloca(LTy, ".compoundliteral");
 
   const Expr* InitExpr = E->getInitializer();
-  LValue Result = LValue::MakeAddr(DeclPtr, E->getType().getCVRQualifiers(),
-                                   QualType::GCNone,
-                                   E->getType().getAddressSpace());
+  LValue Result = LValue::MakeAddr(DeclPtr, MakeQualifiers(E->getType()));
 
   if (E->getType()->isComplexType()) {
     EmitComplexExprIntoAddr(InitExpr, DeclPtr, false);
@@ -1199,9 +1181,7 @@
     EmitBlock(ContBlock);
     
     Temp = Builder.CreateLoad(Temp, "lv");
-    return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers(),
-                            getContext().getObjCGCAttrKind(E->getType()),
-                            E->getType().getAddressSpace());
+    return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
   }
   
   // ?: here should be an aggregate.
@@ -1212,9 +1192,7 @@
   llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType()));
   EmitAggExpr(E, Temp, false);
 
-  return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers(),
-                          getContext().getObjCGCAttrKind(E->getType()),
-                          E->getType().getAddressSpace());
+  return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
 }
 
 /// EmitCastLValue - Casts are never lvalues.  If a cast is needed by the code
@@ -1254,18 +1232,14 @@
       GetAddressCXXOfBaseClass(LV.getAddress(), DerivedClassDecl, 
                                BaseClassDecl, /*NullCheckValue=*/false);
     
-    return LValue::MakeAddr(Base, E->getType().getCVRQualifiers(),
-                            getContext().getObjCGCAttrKind(E->getType()),
-                            E->getType().getAddressSpace());
+    return LValue::MakeAddr(Base, MakeQualifiers(E->getType()));
   }
 
   case CastExpr::CK_ToUnion: {
     llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType()));
     EmitAnyExpr(E->getSubExpr(), Temp, false);
 
-    return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers(),
-                            getContext().getObjCGCAttrKind(E->getType()),
-                            E->getType().getAddressSpace());
+    return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
     }
   }
 }
@@ -1327,9 +1301,7 @@
   llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType()));
   EmitAggExpr(E, Temp, false);
   // FIXME: Are these qualifiers correct?
-  return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers(),
-                          getContext().getObjCGCAttrKind(E->getType()),
-                          E->getType().getAddressSpace());
+  return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
 }
 
 LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
@@ -1340,23 +1312,17 @@
            "Can't have a scalar return unless the return type is a "
            "reference type!");
 
-    return LValue::MakeAddr(RV.getScalarVal(), E->getType().getCVRQualifiers(),
-                            getContext().getObjCGCAttrKind(E->getType()),
-                            E->getType().getAddressSpace());
+    return LValue::MakeAddr(RV.getScalarVal(), MakeQualifiers(E->getType()));
   }
 
-  return LValue::MakeAddr(RV.getAggregateAddr(),
-                          E->getType().getCVRQualifiers(),
-                          getContext().getObjCGCAttrKind(E->getType()),
-                          E->getType().getAddressSpace());
+  return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType()));
 }
 
 LValue CodeGenFunction::EmitVAArgExprLValue(const VAArgExpr *E) {
   // FIXME: This shouldn't require another copy.
   llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType()));
   EmitAggExpr(E, Temp, false);
-  return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers(),
-                          QualType::GCNone, E->getType().getAddressSpace());
+  return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
 }
 
 LValue
@@ -1368,8 +1334,7 @@
 LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
   llvm::Value *Temp = CreateTempAlloca(ConvertTypeForMem(E->getType()), "tmp");
   EmitCXXConstructExpr(Temp, E);
-  return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers(),
-                          QualType::GCNone, E->getType().getAddressSpace());
+  return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
 }
 
 LValue
@@ -1385,10 +1350,7 @@
   // Can only get l-value for message expression returning aggregate type
   RValue RV = EmitObjCMessageExpr(E);
   // FIXME: can this be volatile?
-  return LValue::MakeAddr(RV.getAggregateAddr(),
-                          E->getType().getCVRQualifiers(),
-                          getContext().getObjCGCAttrKind(E->getType()),
-                          E->getType().getAddressSpace());
+  return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType()));
 }
 
 llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface,
@@ -1408,22 +1370,23 @@
   // FIXME: A lot of the code below could be shared with EmitMemberExpr.
   llvm::Value *BaseValue = 0;
   const Expr *BaseExpr = E->getBase();
-  unsigned CVRQualifiers = 0;
+  Qualifiers BaseQuals;
   QualType ObjectTy;
   if (E->isArrow()) {
     BaseValue = EmitScalarExpr(BaseExpr);
     ObjectTy = BaseExpr->getType()->getPointeeType();
-    CVRQualifiers = ObjectTy.getCVRQualifiers();
+    BaseQuals = ObjectTy.getQualifiers();
   } else {
     LValue BaseLV = EmitLValue(BaseExpr);
     // FIXME: this isn't right for bitfields.
     BaseValue = BaseLV.getAddress();
     ObjectTy = BaseExpr->getType();
-    CVRQualifiers = ObjectTy.getCVRQualifiers();
+    BaseQuals = ObjectTy.getQualifiers();
   }
 
   LValue LV = 
-    EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(), CVRQualifiers);
+    EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(),
+                      BaseQuals.getCVRQualifiers());
   setObjCGCLValueClass(getContext(), E, LV);
   return LV;
 }
@@ -1453,10 +1416,7 @@
   // Can only get l-value for message expression returning aggregate type
   RValue RV = EmitAnyExprToTemp(E);
   // FIXME: can this be volatile?
-  return LValue::MakeAddr(RV.getAggregateAddr(),
-                          E->getType().getCVRQualifiers(),
-                          getContext().getObjCGCAttrKind(E->getType()),
-                          E->getType().getAddressSpace());
+  return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType()));
 }
 
 
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 2e7e868..e19fb00 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -181,7 +181,7 @@
     llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr,
                                                  CGF.ConvertType(PtrTy));
     EmitInitializationToLValue(E->getSubExpr(),
-                               LValue::MakeAddr(CastPtr, 0));
+                               LValue::MakeAddr(CastPtr, Qualifiers()));
     return;
   }
 
@@ -316,7 +316,7 @@
     return;
   }
 
-  EmitFinalDestCopy(VE, LValue::MakeAddr(ArgPtr, 0));
+  EmitFinalDestCopy(VE, LValue::MakeAddr(ArgPtr, Qualifiers()));
 }
 
 void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
@@ -429,15 +429,16 @@
     QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
     ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType();
 
-    unsigned CVRqualifier = ElementType.getCVRQualifiers();
+    // FIXME: were we intentionally ignoring address spaces and GC attributes?
+    Qualifiers Quals = CGF.MakeQualifiers(ElementType);
 
     for (uint64_t i = 0; i != NumArrayElements; ++i) {
       llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
       if (i < NumInitElements)
         EmitInitializationToLValue(E->getInit(i),
-                                   LValue::MakeAddr(NextVal, CVRqualifier));
+                                   LValue::MakeAddr(NextVal, Quals));
       else
-        EmitNullInitializationToLValue(LValue::MakeAddr(NextVal, CVRqualifier),
+        EmitNullInitializationToLValue(LValue::MakeAddr(NextVal, Quals),
                                        ElementType);
     }
     return;
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index b9569f5..21b4558 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -791,8 +791,7 @@
         NextVal = Builder.CreateGEP(InVal, Inc, "add.ptr");
         llvm::Value *lhs = LV.getAddress();
         lhs = Builder.CreateBitCast(lhs, llvm::PointerType::getUnqual(i8Ty));
-        LV = LValue::MakeAddr(lhs, ValTy.getCVRQualifiers(),
-                              CGF.getContext().getObjCGCAttrKind(ValTy));
+        LV = LValue::MakeAddr(lhs, CGF.MakeQualifiers(ValTy));
       } else
         NextVal = Builder.CreateInBoundsGEP(InVal, Inc, "ptrincdec");
     } else {
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index df60583..b9f4f34 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -112,6 +112,9 @@
   V = CGF.Builder.CreateGEP(V, Offset, "add.ptr");
   V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));
 
+  Qualifiers Quals = CGF.MakeQualifiers(IvarTy);
+  Quals.addCVRQualifiers(CVRQualifiers);
+
   if (Ivar->isBitField()) {
     // We need to compute the bit offset for the bit-field, the offset
     // is to the byte. Note, there is a subtle invariant here: we can
@@ -124,11 +127,11 @@
       Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue();
     return LValue::MakeBitfield(V, BitOffset, BitFieldSize,
                                 IvarTy->isSignedIntegerType(),
-                                IvarTy.getCVRQualifiers()|CVRQualifiers);
+                                Quals.getCVRQualifiers());
   }
 
-  LValue LV = LValue::MakeAddr(V, IvarTy.getCVRQualifiers()|CVRQualifiers,
-                               CGF.CGM.getContext().getObjCGCAttrKind(IvarTy));
+  
+  LValue LV = LValue::MakeAddr(V, Quals);
   return LV;
 }
 
@@ -2992,21 +2995,20 @@
   return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
 }
 
-static QualType::GCAttrTypes GetGCAttrTypeForType(ASTContext &Ctx,
-                                                  QualType FQT) {
+static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
   if (FQT.isObjCGCStrong())
-    return QualType::Strong;
+    return Qualifiers::Strong;
 
   if (FQT.isObjCGCWeak())
-    return QualType::Weak;
+    return Qualifiers::Weak;
 
   if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
-    return QualType::Strong;
+    return Qualifiers::Strong;
 
   if (const PointerType *PT = FQT->getAs<PointerType>())
     return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
 
-  return QualType::GCNone;
+  return Qualifiers::GCNone;
 }
 
 void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
@@ -3123,11 +3125,11 @@
     }
     // At this point, we are done with Record/Union and array there of.
     // For other arrays we are down to its element type.
-    QualType::GCAttrTypes GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
+    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
 
     unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
-    if ((ForStrongLayout && GCAttr == QualType::Strong)
-        || (!ForStrongLayout && GCAttr == QualType::Weak)) {
+    if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
+        || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
       if (IsUnion) {
         uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
         if (UnionIvarSize > MaxUnionIvarSize) {
@@ -3140,8 +3142,8 @@
                                     FieldSize / WordSizeInBits));
       }
     } else if ((ForStrongLayout &&
-                (GCAttr == QualType::GCNone || GCAttr == QualType::Weak))
-               || (!ForStrongLayout && GCAttr != QualType::Weak)) {
+                (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
+               || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
       if (IsUnion) {
         // FIXME: Why the asymmetry? We divide by word size in bits on other
         // side.
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index d9dd94d..ee9dc52 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -118,12 +118,6 @@
                   // use getKVCRefExpr
   } LVType;
 
-  enum ObjCType {
-    None = 0,     // object with no gc attribute.
-    Weak,         // __weak object expression
-    Strong        // __strong object expression
-  };
-
   llvm::Value *V;
 
   union {
@@ -146,9 +140,8 @@
     const ObjCImplicitSetterGetterRefExpr *KVCRefExpr;
   };
 
-  bool Volatile:1;
-  // FIXME: set but never used, what effect should it have?
-  bool Restrict:1;
+  // 'const' is unused here
+  Qualifiers Quals;
 
   // objective-c's ivar
   bool Ivar:1;
@@ -163,20 +156,13 @@
   // Lvalue is a global reference of an objective-c object
   bool GlobalObjCRef : 1;
 
-  // objective-c's gc attributes
-  unsigned ObjCType : 2;
-
-  // address space
-  unsigned AddressSpace;
-
 private:
-  static void SetQualifiers(unsigned Qualifiers, LValue& R) {
-    R.Volatile = (Qualifiers&QualType::Volatile)!=0;
-    R.Restrict = (Qualifiers&QualType::Restrict)!=0;
+  void SetQualifiers(Qualifiers Quals) {
+    this->Quals = Quals;
+    
     // FIXME: Convenient place to set objc flags to 0. This should really be
     // done in a user-defined constructor instead.
-    R.ObjCType = None;
-    R.Ivar = R.ObjIsArray = R.NonGC = R.GlobalObjCRef = false;
+    this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
   }
 
 public:
@@ -187,21 +173,20 @@
   bool isPropertyRef() const { return LVType == PropertyRef; }
   bool isKVCRef() const { return LVType == KVCRef; }
 
-  bool isVolatileQualified() const { return Volatile; }
-  bool isRestrictQualified() const { return Restrict; }
-  unsigned getQualifiers() const {
-    return (Volatile ? QualType::Volatile : 0) |
-           (Restrict ? QualType::Restrict : 0);
+  bool isVolatileQualified() const { return Quals.hasVolatile(); }
+  bool isRestrictQualified() const { return Quals.hasRestrict(); }
+  unsigned getVRQualifiers() const {
+    return Quals.getCVRQualifiers() & ~Qualifiers::Const;
   }
 
   bool isObjCIvar() const { return Ivar; }
   bool isObjCArray() const { return ObjIsArray; }
   bool isNonGC () const { return NonGC; }
   bool isGlobalObjCRef() const { return GlobalObjCRef; }
-  bool isObjCWeak() const { return ObjCType == Weak; }
-  bool isObjCStrong() const { return ObjCType == Strong; }
+  bool isObjCWeak() const { return Quals.getObjCGCAttr() == Qualifiers::Weak; }
+  bool isObjCStrong() const { return Quals.getObjCGCAttr() == Qualifiers::Strong; }
 
-  unsigned getAddressSpace() const { return AddressSpace; }
+  unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
 
   static void SetObjCIvar(LValue& R, bool iValue) {
     R.Ivar = iValue;
@@ -216,14 +201,6 @@
   static void SetObjCNonGC(LValue& R, bool iValue) {
     R.NonGC = iValue;
   }
-  static void SetObjCType(QualType::GCAttrTypes GCAttrs, LValue& R) {
-    if (GCAttrs == QualType::Weak)
-      R.ObjCType = Weak;
-    else if (GCAttrs == QualType::Strong)
-      R.ObjCType = Strong;
-    else
-     R.ObjCType = None;
-  }
 
   // simple lvalue
   llvm::Value *getAddress() const { assert(isSimple()); return V; }
@@ -262,48 +239,44 @@
     return KVCRefExpr;
   }
 
-  static LValue MakeAddr(llvm::Value *V, unsigned Qualifiers,
-                         QualType::GCAttrTypes GCAttrs = QualType::GCNone,
-                         unsigned AddressSpace = 0) {
+  static LValue MakeAddr(llvm::Value *V, Qualifiers Quals) {
     LValue R;
     R.LVType = Simple;
     R.V = V;
-    SetQualifiers(Qualifiers,R);
-    R.AddressSpace = AddressSpace;
-    SetObjCType(GCAttrs, R);
+    R.SetQualifiers(Quals);
     return R;
   }
 
   static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
-                              unsigned Qualifiers) {
+                              unsigned CVR) {
     LValue R;
     R.LVType = VectorElt;
     R.V = Vec;
     R.VectorIdx = Idx;
-    SetQualifiers(Qualifiers,R);
+    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     return R;
   }
 
   static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
-                                 unsigned Qualifiers) {
+                                 unsigned CVR) {
     LValue R;
     R.LVType = ExtVectorElt;
     R.V = Vec;
     R.VectorElts = Elts;
-    SetQualifiers(Qualifiers,R);
+    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     return R;
   }
 
   static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
                              unsigned short Size, bool IsSigned,
-                             unsigned Qualifiers) {
+                             unsigned CVR) {
     LValue R;
     R.LVType = BitField;
     R.V = V;
     R.BitfieldData.StartBit = StartBit;
     R.BitfieldData.Size = Size;
     R.BitfieldData.IsSigned = IsSigned;
-    SetQualifiers(Qualifiers,R);
+    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     return R;
   }
 
@@ -311,20 +284,20 @@
   // the lvalue. However, this complicates the code a bit, and I haven't figured
   // out how to make it go wrong yet.
   static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
-                                unsigned Qualifiers) {
+                                unsigned CVR) {
     LValue R;
     R.LVType = PropertyRef;
     R.PropertyRefExpr = E;
-    SetQualifiers(Qualifiers,R);
+    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     return R;
   }
 
   static LValue MakeKVCRef(const ObjCImplicitSetterGetterRefExpr *E,
-                           unsigned Qualifiers) {
+                           unsigned CVR) {
     LValue R;
     R.LVType = KVCRef;
     R.KVCRefExpr = E;
-    SetQualifiers(Qualifiers,R);
+    R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     return R;
   }
 };
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 651dc95..6b6b149 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -496,6 +496,12 @@
   //                                  Helpers
   //===--------------------------------------------------------------------===//
 
+  Qualifiers MakeQualifiers(QualType T) {
+    Qualifiers Quals = T.getQualifiers();
+    Quals.setObjCGCAttr(getContext().getObjCGCAttrKind(T));
+    return Quals;
+  }
+
   /// CreateTempAlloca - This creates a alloca and inserts it into the entry
   /// block.
   llvm::AllocaInst *CreateTempAlloca(const llvm::Type *Ty,
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 6826122..87b3d11 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -267,7 +267,7 @@
 
   case Type::VariableArray: {
     const VariableArrayType &A = cast<VariableArrayType>(Ty);
-    assert(A.getIndexTypeQualifier() == 0 &&
+    assert(A.getIndexTypeCVRQualifiers() == 0 &&
            "FIXME: We only handle trivial array types so far!");
     // VLAs resolve to the innermost element type; this matches
     // the return of alloca, and there isn't any obviously better choice.
@@ -275,7 +275,7 @@
   }
   case Type::IncompleteArray: {
     const IncompleteArrayType &A = cast<IncompleteArrayType>(Ty);
-    assert(A.getIndexTypeQualifier() == 0 &&
+    assert(A.getIndexTypeCVRQualifiers() == 0 &&
            "FIXME: We only handle trivial array types so far!");
     // int X[] -> [0 x int]
     return llvm::ArrayType::get(ConvertTypeForMemRecursive(A.getElementType()), 0);
@@ -312,10 +312,6 @@
     return GetFunctionType(getFunctionInfo(FNPT), true);
   }
 
-  case Type::ExtQual:
-    return
-      ConvertTypeRecursive(QualType(cast<ExtQualType>(Ty).getBaseType(), 0));
-
   case Type::ObjCInterface: {
     // Objective-C interfaces are always opaque (outside of the
     // runtime, which can do whatever it likes); we never refine
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index 878f13d..83dc0e6 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -84,7 +84,7 @@
     void manglePrefix(const DeclContext *DC);
     void mangleTemplatePrefix(const NamedDecl *ND);
     void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
-    void mangleCVQualifiers(unsigned Quals);
+    void mangleQualifiers(Qualifiers Quals);
     void mangleType(QualType T);
 
     // Declare manglers for every type class.
@@ -459,7 +459,7 @@
   // FIXME: no class template support
   Out << 'N';
   if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND))
-    mangleCVQualifiers(Method->getTypeQualifiers());
+    mangleQualifiers(Qualifiers::fromCVRMask(Method->getTypeQualifiers()));
   
   // Check if we have a template.
   const TemplateArgumentList *TemplateArgs = 0;
@@ -637,14 +637,16 @@
   }
 }
 
-void CXXNameMangler::mangleCVQualifiers(unsigned Quals) {
+void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
   // <CV-qualifiers> ::= [r] [V] [K]    # restrict (C99), volatile, const
-  if (Quals & QualType::Restrict)
+  if (Quals.hasRestrict())
     Out << 'r';
-  if (Quals & QualType::Volatile)
+  if (Quals.hasVolatile())
     Out << 'V';
-  if (Quals & QualType::Const)
+  if (Quals.hasConst())
     Out << 'K';
+
+  // FIXME: For now, just drop all extension qualifiers on the floor.
 }
 
 void CXXNameMangler::mangleType(QualType T) {
@@ -655,10 +657,10 @@
   if (IsSubstitutable && mangleSubstitution(T))
     return;
 
-  if (unsigned CVRQualifiers = T.getCVRQualifiers()) {
-    //  <type> ::= <CV-qualifiers> <type>
-    mangleCVQualifiers(CVRQualifiers);
-
+  if (Qualifiers Quals = T.getQualifiers()) {
+    mangleQualifiers(Quals);
+    // Recurse:  even if the qualified type isn't yet substitutable,
+    // the unqualified type might be.
     mangleType(T.getUnqualifiedType());
   } else {
     switch (T->getTypeClass()) {
@@ -669,7 +671,7 @@
       return;
 #define TYPE(CLASS, PARENT) \
     case Type::CLASS: \
-      mangleType(static_cast<CLASS##Type*>(T.getTypePtr())); \
+      mangleType(static_cast<const CLASS##Type*>(T.getTypePtr())); \
       break;
 #include "clang/AST/TypeNodes.def"
     }
@@ -830,7 +832,7 @@
   mangleType(QualType(T->getClass(), 0));
   QualType PointeeType = T->getPointeeType();
   if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
-    mangleCVQualifiers(FPT->getTypeQuals());
+    mangleQualifiers(Qualifiers::fromCVRMask(FPT->getTypeQuals()));
     mangleType(FPT);
   } else
     mangleType(PointeeType);
@@ -912,11 +914,6 @@
   assert(false && "can't mangle dependent typenames yet");
 }
 
-// FIXME: For now, just drop all extension qualifiers on the floor.
-void CXXNameMangler::mangleType(const ExtQualType *T) {
-  mangleType(QualType(T->getBaseType(), 0));
-}
-
 void CXXNameMangler::mangleExpression(const Expr *E) {
   // <expression> ::= <unary operator-name> <expression>
 	//              ::= <binary operator-name> <expression> <expression>