| //===--- ASTContext.cpp - Context to hold long-lived AST nodes ------------===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | //  This file implements the ASTContext interface. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "clang/AST/ASTContext.h" | 
 | #include "clang/AST/DeclCXX.h" | 
 | #include "clang/AST/DeclObjC.h" | 
 | #include "clang/AST/DeclTemplate.h" | 
 | #include "clang/AST/Expr.h" | 
 | #include "clang/AST/ExternalASTSource.h" | 
 | #include "clang/AST/RecordLayout.h" | 
 | #include "clang/Basic/SourceManager.h" | 
 | #include "clang/Basic/TargetInfo.h" | 
 | #include "llvm/ADT/StringExtras.h" | 
 | #include "llvm/Support/MathExtras.h" | 
 | #include "llvm/Support/MemoryBuffer.h" | 
 | using namespace clang; | 
 |  | 
 | enum FloatingRank { | 
 |   FloatRank, DoubleRank, LongDoubleRank | 
 | }; | 
 |  | 
 | ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, | 
 |                        TargetInfo &t, | 
 |                        IdentifierTable &idents, SelectorTable &sels, | 
 |                        bool FreeMem, unsigned size_reserve, | 
 |                        bool InitializeBuiltins) :  | 
 |   GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0),  | 
 |   ObjCFastEnumerationStateTypeDecl(0), SourceMgr(SM), LangOpts(LOpts),  | 
 |   FreeMemory(FreeMem), Target(t), Idents(idents), Selectors(sels), | 
 |   ExternalSource(0) {   | 
 |   if (size_reserve > 0) Types.reserve(size_reserve);     | 
 |   InitBuiltinTypes(); | 
 |   TUDecl = TranslationUnitDecl::Create(*this); | 
 |   BuiltinInfo.InitializeTargetBuiltins(Target); | 
 |   if (InitializeBuiltins) | 
 |     this->InitializeBuiltins(idents); | 
 | } | 
 |  | 
 | ASTContext::~ASTContext() { | 
 |   // Deallocate all the types. | 
 |   while (!Types.empty()) { | 
 |     Types.back()->Destroy(*this); | 
 |     Types.pop_back(); | 
 |   } | 
 |  | 
 |   { | 
 |     llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator | 
 |       I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); | 
 |     while (I != E) { | 
 |       ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second); | 
 |       delete R; | 
 |     } | 
 |   } | 
 |  | 
 |   { | 
 |     llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>::iterator | 
 |       I = ObjCLayouts.begin(), E = ObjCLayouts.end(); | 
 |     while (I != E) { | 
 |       ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second); | 
 |       delete R; | 
 |     } | 
 |   } | 
 |  | 
 |   // Destroy nested-name-specifiers. | 
 |   for (llvm::FoldingSet<NestedNameSpecifier>::iterator | 
 |          NNS = NestedNameSpecifiers.begin(), | 
 |          NNSEnd = NestedNameSpecifiers.end();  | 
 |        NNS != NNSEnd;  | 
 |        /* Increment in loop */) | 
 |     (*NNS++).Destroy(*this); | 
 |  | 
 |   if (GlobalNestedNameSpecifier) | 
 |     GlobalNestedNameSpecifier->Destroy(*this); | 
 |  | 
 |   TUDecl->Destroy(*this); | 
 | } | 
 |  | 
 | void ASTContext::InitializeBuiltins(IdentifierTable &idents) { | 
 |   BuiltinInfo.InitializeBuiltins(idents, LangOpts.NoBuiltin); | 
 | } | 
 |  | 
 | void  | 
 | ASTContext::setExternalSource(llvm::OwningPtr<ExternalASTSource> &Source) { | 
 |   ExternalSource.reset(Source.take()); | 
 | } | 
 |  | 
 | void ASTContext::PrintStats() const { | 
 |   fprintf(stderr, "*** AST Context Stats:\n"); | 
 |   fprintf(stderr, "  %d types total.\n", (int)Types.size()); | 
 |  | 
 |   unsigned counts[] = { | 
 | #define TYPE(Name, Parent) 0,  | 
 | #define ABSTRACT_TYPE(Name, Parent) | 
 | #include "clang/AST/TypeNodes.def" | 
 |     0 // Extra | 
 |   }; | 
 |  | 
 |   for (unsigned i = 0, e = Types.size(); i != e; ++i) { | 
 |     Type *T = Types[i]; | 
 |     counts[(unsigned)T->getTypeClass()]++; | 
 |   } | 
 |  | 
 |   unsigned Idx = 0; | 
 |   unsigned TotalBytes = 0; | 
 | #define TYPE(Name, Parent)                                              \ | 
 |   if (counts[Idx])                                                      \ | 
 |     fprintf(stderr, "    %d %s types\n", (int)counts[Idx], #Name);      \ | 
 |   TotalBytes += counts[Idx] * sizeof(Name##Type);                       \ | 
 |   ++Idx; | 
 | #define ABSTRACT_TYPE(Name, Parent) | 
 | #include "clang/AST/TypeNodes.def" | 
 |    | 
 |   fprintf(stderr, "Total bytes = %d\n", int(TotalBytes)); | 
 |  | 
 |   if (ExternalSource.get()) { | 
 |     fprintf(stderr, "\n"); | 
 |     ExternalSource->PrintStats(); | 
 |   } | 
 | } | 
 |  | 
 |  | 
 | void ASTContext::InitBuiltinType(QualType &R, BuiltinType::Kind K) { | 
 |   Types.push_back((R = QualType(new (*this,8) BuiltinType(K),0)).getTypePtr()); | 
 | } | 
 |  | 
 | void ASTContext::InitBuiltinTypes() { | 
 |   assert(VoidTy.isNull() && "Context reinitialized?"); | 
 |    | 
 |   // C99 6.2.5p19. | 
 |   InitBuiltinType(VoidTy,              BuiltinType::Void); | 
 |    | 
 |   // C99 6.2.5p2. | 
 |   InitBuiltinType(BoolTy,              BuiltinType::Bool); | 
 |   // C99 6.2.5p3. | 
 |   if (Target.isCharSigned()) | 
 |     InitBuiltinType(CharTy,            BuiltinType::Char_S); | 
 |   else | 
 |     InitBuiltinType(CharTy,            BuiltinType::Char_U); | 
 |   // C99 6.2.5p4. | 
 |   InitBuiltinType(SignedCharTy,        BuiltinType::SChar); | 
 |   InitBuiltinType(ShortTy,             BuiltinType::Short); | 
 |   InitBuiltinType(IntTy,               BuiltinType::Int); | 
 |   InitBuiltinType(LongTy,              BuiltinType::Long); | 
 |   InitBuiltinType(LongLongTy,          BuiltinType::LongLong); | 
 |    | 
 |   // C99 6.2.5p6. | 
 |   InitBuiltinType(UnsignedCharTy,      BuiltinType::UChar); | 
 |   InitBuiltinType(UnsignedShortTy,     BuiltinType::UShort); | 
 |   InitBuiltinType(UnsignedIntTy,       BuiltinType::UInt); | 
 |   InitBuiltinType(UnsignedLongTy,      BuiltinType::ULong); | 
 |   InitBuiltinType(UnsignedLongLongTy,  BuiltinType::ULongLong); | 
 |    | 
 |   // C99 6.2.5p10. | 
 |   InitBuiltinType(FloatTy,             BuiltinType::Float); | 
 |   InitBuiltinType(DoubleTy,            BuiltinType::Double); | 
 |   InitBuiltinType(LongDoubleTy,        BuiltinType::LongDouble); | 
 |  | 
 |   // GNU extension, 128-bit integers. | 
 |   InitBuiltinType(Int128Ty,            BuiltinType::Int128); | 
 |   InitBuiltinType(UnsignedInt128Ty,    BuiltinType::UInt128); | 
 |  | 
 |   if (LangOpts.CPlusPlus) // C++ 3.9.1p5 | 
 |     InitBuiltinType(WCharTy,           BuiltinType::WChar); | 
 |   else // C99 | 
 |     WCharTy = getFromTargetType(Target.getWCharType()); | 
 |  | 
 |   // Placeholder type for functions. | 
 |   InitBuiltinType(OverloadTy,          BuiltinType::Overload); | 
 |  | 
 |   // Placeholder type for type-dependent expressions whose type is | 
 |   // completely unknown. No code should ever check a type against | 
 |   // DependentTy and users should never see it; however, it is here to | 
 |   // help diagnose failures to properly check for type-dependent | 
 |   // expressions. | 
 |   InitBuiltinType(DependentTy,         BuiltinType::Dependent); | 
 |  | 
 |   // C99 6.2.5p11. | 
 |   FloatComplexTy      = getComplexType(FloatTy); | 
 |   DoubleComplexTy     = getComplexType(DoubleTy); | 
 |   LongDoubleComplexTy = getComplexType(LongDoubleTy); | 
 |  | 
 |   BuiltinVaListType = QualType(); | 
 |   ObjCIdType = QualType(); | 
 |   IdStructType = 0; | 
 |   ObjCClassType = QualType(); | 
 |   ClassStructType = 0; | 
 |    | 
 |   ObjCConstantStringType = QualType(); | 
 |    | 
 |   // void * type | 
 |   VoidPtrTy = getPointerType(VoidTy); | 
 |  | 
 |   // nullptr type (C++0x 2.14.7) | 
 |   InitBuiltinType(NullPtrTy,           BuiltinType::NullPtr); | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | //                         Type Sizing and Analysis | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified | 
 | /// scalar floating point type. | 
 | const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { | 
 |   const BuiltinType *BT = T->getAsBuiltinType(); | 
 |   assert(BT && "Not a floating point type!"); | 
 |   switch (BT->getKind()) { | 
 |   default: assert(0 && "Not a floating point type!"); | 
 |   case BuiltinType::Float:      return Target.getFloatFormat(); | 
 |   case BuiltinType::Double:     return Target.getDoubleFormat(); | 
 |   case BuiltinType::LongDouble: return Target.getLongDoubleFormat(); | 
 |   } | 
 | } | 
 |  | 
 | /// getDeclAlign - Return a conservative estimate of the alignment of the | 
 | /// specified decl.  Note that bitfields do not have a valid alignment, so | 
 | /// this method will assert on them. | 
 | unsigned ASTContext::getDeclAlignInBytes(const Decl *D) { | 
 |   unsigned Align = Target.getCharWidth(); | 
 |  | 
 |   if (const AlignedAttr* AA = D->getAttr<AlignedAttr>()) | 
 |     Align = std::max(Align, AA->getAlignment()); | 
 |  | 
 |   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) { | 
 |     QualType T = VD->getType(); | 
 |     if (const ReferenceType* RT = T->getAsReferenceType()) { | 
 |       unsigned AS = RT->getPointeeType().getAddressSpace(); | 
 |       Align = Target.getPointerAlign(AS); | 
 |     } else if (!T->isIncompleteType() && !T->isFunctionType()) { | 
 |       // Incomplete or function types default to 1. | 
 |       while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T)) | 
 |         T = cast<ArrayType>(T)->getElementType(); | 
 |  | 
 |       Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr())); | 
 |     } | 
 |   } | 
 |  | 
 |   return Align / Target.getCharWidth(); | 
 | } | 
 |  | 
 | /// getTypeSize - Return the size of the specified type, in bits.  This method | 
 | /// does not work on incomplete types. | 
 | std::pair<uint64_t, unsigned> | 
 | ASTContext::getTypeInfo(const Type *T) { | 
 |   uint64_t Width=0; | 
 |   unsigned Align=8; | 
 |   switch (T->getTypeClass()) { | 
 | #define TYPE(Class, Base) | 
 | #define ABSTRACT_TYPE(Class, Base) | 
 | #define NON_CANONICAL_TYPE(Class, Base) | 
 | #define DEPENDENT_TYPE(Class, Base) case Type::Class: | 
 | #include "clang/AST/TypeNodes.def" | 
 |     assert(false && "Should not see dependent types"); | 
 |     break; | 
 |  | 
 |   case Type::FunctionNoProto: | 
 |   case Type::FunctionProto: | 
 |     // GCC extension: alignof(function) = 32 bits | 
 |     Width = 0; | 
 |     Align = 32; | 
 |     break; | 
 |  | 
 |   case Type::IncompleteArray: | 
 |   case Type::VariableArray: | 
 |     Width = 0; | 
 |     Align = getTypeAlign(cast<ArrayType>(T)->getElementType()); | 
 |     break; | 
 |  | 
 |   case Type::ConstantArray: { | 
 |     const ConstantArrayType *CAT = cast<ConstantArrayType>(T); | 
 |      | 
 |     std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType()); | 
 |     Width = EltInfo.first*CAT->getSize().getZExtValue(); | 
 |     Align = EltInfo.second; | 
 |     break; | 
 |   } | 
 |   case Type::ExtVector: | 
 |   case Type::Vector: { | 
 |     std::pair<uint64_t, unsigned> EltInfo =  | 
 |       getTypeInfo(cast<VectorType>(T)->getElementType()); | 
 |     Width = EltInfo.first*cast<VectorType>(T)->getNumElements(); | 
 |     Align = Width; | 
 |     // If the alignment is not a power of 2, round up to the next power of 2. | 
 |     // This happens for non-power-of-2 length vectors. | 
 |     // FIXME: this should probably be a target property. | 
 |     Align = 1 << llvm::Log2_32_Ceil(Align); | 
 |     break; | 
 |   } | 
 |  | 
 |   case Type::Builtin: | 
 |     switch (cast<BuiltinType>(T)->getKind()) { | 
 |     default: assert(0 && "Unknown builtin type!"); | 
 |     case BuiltinType::Void: | 
 |       // GCC extension: alignof(void) = 8 bits. | 
 |       Width = 0; | 
 |       Align = 8; | 
 |       break; | 
 |  | 
 |     case BuiltinType::Bool: | 
 |       Width = Target.getBoolWidth(); | 
 |       Align = Target.getBoolAlign(); | 
 |       break; | 
 |     case BuiltinType::Char_S: | 
 |     case BuiltinType::Char_U: | 
 |     case BuiltinType::UChar: | 
 |     case BuiltinType::SChar: | 
 |       Width = Target.getCharWidth(); | 
 |       Align = Target.getCharAlign(); | 
 |       break; | 
 |     case BuiltinType::WChar: | 
 |       Width = Target.getWCharWidth(); | 
 |       Align = Target.getWCharAlign(); | 
 |       break; | 
 |     case BuiltinType::UShort: | 
 |     case BuiltinType::Short: | 
 |       Width = Target.getShortWidth(); | 
 |       Align = Target.getShortAlign(); | 
 |       break; | 
 |     case BuiltinType::UInt: | 
 |     case BuiltinType::Int: | 
 |       Width = Target.getIntWidth(); | 
 |       Align = Target.getIntAlign(); | 
 |       break; | 
 |     case BuiltinType::ULong: | 
 |     case BuiltinType::Long: | 
 |       Width = Target.getLongWidth(); | 
 |       Align = Target.getLongAlign(); | 
 |       break; | 
 |     case BuiltinType::ULongLong: | 
 |     case BuiltinType::LongLong: | 
 |       Width = Target.getLongLongWidth(); | 
 |       Align = Target.getLongLongAlign(); | 
 |       break; | 
 |     case BuiltinType::Int128: | 
 |     case BuiltinType::UInt128: | 
 |       Width = 128; | 
 |       Align = 128; // int128_t is 128-bit aligned on all targets. | 
 |       break; | 
 |     case BuiltinType::Float: | 
 |       Width = Target.getFloatWidth(); | 
 |       Align = Target.getFloatAlign(); | 
 |       break; | 
 |     case BuiltinType::Double: | 
 |       Width = Target.getDoubleWidth(); | 
 |       Align = Target.getDoubleAlign(); | 
 |       break; | 
 |     case BuiltinType::LongDouble: | 
 |       Width = Target.getLongDoubleWidth(); | 
 |       Align = Target.getLongDoubleAlign(); | 
 |       break; | 
 |     case BuiltinType::NullPtr: | 
 |       Width = Target.getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t) | 
 |       Align = Target.getPointerAlign(0); //   == sizeof(void*) | 
 |       break; | 
 |     } | 
 |     break; | 
 |   case Type::FixedWidthInt: | 
 |     // FIXME: This isn't precisely correct; the width/alignment should depend | 
 |     // on the available types for the target | 
 |     Width = cast<FixedWidthIntType>(T)->getWidth(); | 
 |     Width = std::max(llvm::NextPowerOf2(Width - 1), (uint64_t)8); | 
 |     Align = Width; | 
 |     break; | 
 |   case Type::ExtQual: | 
 |     // FIXME: Pointers into different addr spaces could have different sizes and | 
 |     // alignment requirements: getPointerInfo should take an AddrSpace. | 
 |     return getTypeInfo(QualType(cast<ExtQualType>(T)->getBaseType(), 0)); | 
 |   case Type::ObjCQualifiedId: | 
 |   case Type::ObjCQualifiedInterface: | 
 |     Width = Target.getPointerWidth(0); | 
 |     Align = Target.getPointerAlign(0); | 
 |     break; | 
 |   case Type::BlockPointer: { | 
 |     unsigned AS = cast<BlockPointerType>(T)->getPointeeType().getAddressSpace(); | 
 |     Width = Target.getPointerWidth(AS); | 
 |     Align = Target.getPointerAlign(AS); | 
 |     break; | 
 |   } | 
 |   case Type::Pointer: { | 
 |     unsigned AS = cast<PointerType>(T)->getPointeeType().getAddressSpace(); | 
 |     Width = Target.getPointerWidth(AS); | 
 |     Align = Target.getPointerAlign(AS); | 
 |     break; | 
 |   } | 
 |   case Type::LValueReference: | 
 |   case Type::RValueReference: | 
 |     // "When applied to a reference or a reference type, the result is the size | 
 |     // of the referenced type." C++98 5.3.3p2: expr.sizeof. | 
 |     // FIXME: This is wrong for struct layout: a reference in a struct has | 
 |     // pointer size. | 
 |     return getTypeInfo(cast<ReferenceType>(T)->getPointeeType()); | 
 |   case Type::MemberPointer: { | 
 |     // FIXME: This is ABI dependent. We use the Itanium C++ ABI. | 
 |     // http://www.codesourcery.com/public/cxx-abi/abi.html#member-pointers | 
 |     // If we ever want to support other ABIs this needs to be abstracted. | 
 |  | 
 |     QualType Pointee = cast<MemberPointerType>(T)->getPointeeType(); | 
 |     std::pair<uint64_t, unsigned> PtrDiffInfo =  | 
 |       getTypeInfo(getPointerDiffType()); | 
 |     Width = PtrDiffInfo.first; | 
 |     if (Pointee->isFunctionType()) | 
 |       Width *= 2; | 
 |     Align = PtrDiffInfo.second; | 
 |     break; | 
 |   } | 
 |   case Type::Complex: { | 
 |     // Complex types have the same alignment as their elements, but twice the | 
 |     // size. | 
 |     std::pair<uint64_t, unsigned> EltInfo =  | 
 |       getTypeInfo(cast<ComplexType>(T)->getElementType()); | 
 |     Width = EltInfo.first*2; | 
 |     Align = EltInfo.second; | 
 |     break; | 
 |   } | 
 |   case Type::ObjCInterface: { | 
 |     const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T); | 
 |     const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); | 
 |     Width = Layout.getSize(); | 
 |     Align = Layout.getAlignment(); | 
 |     break; | 
 |   } | 
 |   case Type::Record: | 
 |   case Type::Enum: { | 
 |     const TagType *TT = cast<TagType>(T); | 
 |  | 
 |     if (TT->getDecl()->isInvalidDecl()) { | 
 |       Width = 1; | 
 |       Align = 1; | 
 |       break; | 
 |     } | 
 |      | 
 |     if (const EnumType *ET = dyn_cast<EnumType>(TT)) | 
 |       return getTypeInfo(ET->getDecl()->getIntegerType()); | 
 |  | 
 |     const RecordType *RT = cast<RecordType>(TT); | 
 |     const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl()); | 
 |     Width = Layout.getSize(); | 
 |     Align = Layout.getAlignment(); | 
 |     break; | 
 |   } | 
 |  | 
 |   case Type::Typedef: { | 
 |     const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl(); | 
 |     if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) { | 
 |       Align = Aligned->getAlignment(); | 
 |       Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr()); | 
 |     } else | 
 |       return getTypeInfo(Typedef->getUnderlyingType().getTypePtr()); | 
 |     break; | 
 |   } | 
 |  | 
 |   case Type::TypeOfExpr: | 
 |     return getTypeInfo(cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType() | 
 |                          .getTypePtr()); | 
 |  | 
 |   case Type::TypeOf: | 
 |     return getTypeInfo(cast<TypeOfType>(T)->getUnderlyingType().getTypePtr()); | 
 |  | 
 |   case Type::QualifiedName: | 
 |     return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr()); | 
 |      | 
 |   case Type::TemplateSpecialization: | 
 |     assert(getCanonicalType(T) != T &&  | 
 |            "Cannot request the size of a dependent type"); | 
 |     // FIXME: this is likely to be wrong once we support template | 
 |     // aliases, since a template alias could refer to a typedef that | 
 |     // has an __aligned__ attribute on it. | 
 |     return getTypeInfo(getCanonicalType(T)); | 
 |   } | 
 |    | 
 |   assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2"); | 
 |   return std::make_pair(Width, Align); | 
 | } | 
 |  | 
 | /// getPreferredTypeAlign - Return the "preferred" alignment of the specified | 
 | /// type for the current target in bits.  This can be different than the ABI | 
 | /// alignment in cases where it is beneficial for performance to overalign | 
 | /// a data type. | 
 | unsigned ASTContext::getPreferredTypeAlign(const Type *T) { | 
 |   unsigned ABIAlign = getTypeAlign(T); | 
 |  | 
 |   // Double and long long should be naturally aligned if possible. | 
 |   if (const ComplexType* CT = T->getAsComplexType()) | 
 |     T = CT->getElementType().getTypePtr(); | 
 |   if (T->isSpecificBuiltinType(BuiltinType::Double) || | 
 |       T->isSpecificBuiltinType(BuiltinType::LongLong)) | 
 |     return std::max(ABIAlign, (unsigned)getTypeSize(T)); | 
 |  | 
 |   return ABIAlign; | 
 | } | 
 |  | 
 |  | 
 | /// LayoutField - Field layout. | 
 | void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo, | 
 |                                   bool IsUnion, unsigned StructPacking, | 
 |                                   ASTContext &Context) { | 
 |   unsigned FieldPacking = StructPacking; | 
 |   uint64_t FieldOffset = IsUnion ? 0 : Size; | 
 |   uint64_t FieldSize; | 
 |   unsigned FieldAlign; | 
 |  | 
 |   // FIXME: Should this override struct packing? Probably we want to | 
 |   // take the minimum? | 
 |   if (const PackedAttr *PA = FD->getAttr<PackedAttr>()) | 
 |     FieldPacking = PA->getAlignment(); | 
 |    | 
 |   if (const Expr *BitWidthExpr = FD->getBitWidth()) { | 
 |     // TODO: Need to check this algorithm on other targets! | 
 |     //       (tested on Linux-X86) | 
 |     FieldSize = BitWidthExpr->EvaluateAsInt(Context).getZExtValue(); | 
 |      | 
 |     std::pair<uint64_t, unsigned> FieldInfo =  | 
 |       Context.getTypeInfo(FD->getType()); | 
 |     uint64_t TypeSize = FieldInfo.first; | 
 |      | 
 |     // Determine the alignment of this bitfield. The packing | 
 |     // attributes define a maximum and the alignment attribute defines | 
 |     // a minimum. | 
 |     // FIXME: What is the right behavior when the specified alignment | 
 |     // is smaller than the specified packing? | 
 |     FieldAlign = FieldInfo.second; | 
 |     if (FieldPacking) | 
 |       FieldAlign = std::min(FieldAlign, FieldPacking); | 
 |     if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>()) | 
 |       FieldAlign = std::max(FieldAlign, AA->getAlignment()); | 
 |      | 
 |     // Check if we need to add padding to give the field the correct | 
 |     // alignment. | 
 |     if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize) | 
 |       FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1); | 
 |      | 
 |     // Padding members don't affect overall alignment | 
 |     if (!FD->getIdentifier()) | 
 |       FieldAlign = 1; | 
 |   } else { | 
 |     if (FD->getType()->isIncompleteArrayType()) { | 
 |       // This is a flexible array member; we can't directly | 
 |       // query getTypeInfo about these, so we figure it out here. | 
 |       // Flexible array members don't have any size, but they | 
 |       // have to be aligned appropriately for their element type. | 
 |       FieldSize = 0; | 
 |       const ArrayType* ATy = Context.getAsArrayType(FD->getType()); | 
 |       FieldAlign = Context.getTypeAlign(ATy->getElementType()); | 
 |     } else if (const ReferenceType *RT = FD->getType()->getAsReferenceType()) { | 
 |       unsigned AS = RT->getPointeeType().getAddressSpace(); | 
 |       FieldSize = Context.Target.getPointerWidth(AS); | 
 |       FieldAlign = Context.Target.getPointerAlign(AS); | 
 |     } else { | 
 |       std::pair<uint64_t, unsigned> FieldInfo =  | 
 |         Context.getTypeInfo(FD->getType()); | 
 |       FieldSize = FieldInfo.first; | 
 |       FieldAlign = FieldInfo.second; | 
 |     } | 
 |      | 
 |     // Determine the alignment of this bitfield. The packing | 
 |     // attributes define a maximum and the alignment attribute defines | 
 |     // a minimum. Additionally, the packing alignment must be at least | 
 |     // a byte for non-bitfields. | 
 |     // | 
 |     // FIXME: What is the right behavior when the specified alignment | 
 |     // is smaller than the specified packing? | 
 |     if (FieldPacking) | 
 |       FieldAlign = std::min(FieldAlign, std::max(8U, FieldPacking)); | 
 |     if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>()) | 
 |       FieldAlign = std::max(FieldAlign, AA->getAlignment()); | 
 |      | 
 |     // Round up the current record size to the field's alignment boundary. | 
 |     FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1); | 
 |   } | 
 |    | 
 |   // Place this field at the current location. | 
 |   FieldOffsets[FieldNo] = FieldOffset; | 
 |    | 
 |   // Reserve space for this field. | 
 |   if (IsUnion) { | 
 |     Size = std::max(Size, FieldSize); | 
 |   } else { | 
 |     Size = FieldOffset + FieldSize; | 
 |   } | 
 |    | 
 |   // Remember the next available offset. | 
 |   NextOffset = Size; | 
 |  | 
 |   // Remember max struct/class alignment. | 
 |   Alignment = std::max(Alignment, FieldAlign); | 
 | } | 
 |  | 
 | static void CollectLocalObjCIvars(ASTContext *Ctx, | 
 |                                   const ObjCInterfaceDecl *OI, | 
 |                                   llvm::SmallVectorImpl<FieldDecl*> &Fields) { | 
 |   for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(), | 
 |        E = OI->ivar_end(); I != E; ++I) { | 
 |     ObjCIvarDecl *IVDecl = *I; | 
 |     if (!IVDecl->isInvalidDecl()) | 
 |       Fields.push_back(cast<FieldDecl>(IVDecl)); | 
 |   } | 
 | } | 
 |  | 
 | void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI, | 
 |                              llvm::SmallVectorImpl<FieldDecl*> &Fields) { | 
 |   if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass()) | 
 |     CollectObjCIvars(SuperClass, Fields); | 
 |   CollectLocalObjCIvars(this, OI, Fields); | 
 | } | 
 |  | 
 | void ASTContext::CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD, | 
 |                                 llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) { | 
 |   for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(*this), | 
 |        E = PD->prop_end(*this); I != E; ++I) | 
 |     if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl()) | 
 |       Ivars.push_back(Ivar); | 
 |    | 
 |   // Also look into nested protocols. | 
 |   for (ObjCProtocolDecl::protocol_iterator P = PD->protocol_begin(), | 
 |        E = PD->protocol_end(); P != E; ++P) | 
 |     CollectProtocolSynthesizedIvars(*P, Ivars); | 
 | } | 
 |  | 
 | /// CollectSynthesizedIvars - | 
 | /// This routine collect synthesized ivars for the designated class. | 
 | /// | 
 | void ASTContext::CollectSynthesizedIvars(const ObjCInterfaceDecl *OI, | 
 |                                 llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) { | 
 |   for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(*this), | 
 |        E = OI->prop_end(*this); I != E; ++I) { | 
 |     if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl()) | 
 |       Ivars.push_back(Ivar); | 
 |   } | 
 |   // Also look into interface's protocol list for properties declared | 
 |   // in the protocol and whose ivars are synthesized. | 
 |   for (ObjCInterfaceDecl::protocol_iterator P = OI->protocol_begin(), | 
 |        PE = OI->protocol_end(); P != PE; ++P) { | 
 |     ObjCProtocolDecl *PD = (*P); | 
 |     CollectProtocolSynthesizedIvars(PD, Ivars); | 
 |   } | 
 | } | 
 |  | 
 | /// getInterfaceLayoutImpl - Get or compute information about the | 
 | /// layout of the given interface. | 
 | /// | 
 | /// \param Impl - If given, also include the layout of the interface's | 
 | /// implementation. This may differ by including synthesized ivars. | 
 | const ASTRecordLayout & | 
 | ASTContext::getObjCLayout(const ObjCInterfaceDecl *D, | 
 |                           const ObjCImplementationDecl *Impl) { | 
 |   assert(!D->isForwardDecl() && "Invalid interface decl!"); | 
 |  | 
 |   // Look up this layout, if already laid out, return what we have. | 
 |   ObjCContainerDecl *Key =  | 
 |     Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D; | 
 |   if (const ASTRecordLayout *Entry = ObjCLayouts[Key]) | 
 |     return *Entry; | 
 |  | 
 |   unsigned FieldCount = D->ivar_size(); | 
 |   // Add in synthesized ivar count if laying out an implementation. | 
 |   if (Impl) { | 
 |     llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; | 
 |     CollectSynthesizedIvars(D, Ivars); | 
 |     FieldCount += Ivars.size(); | 
 |     // If there aren't any sythesized ivars then reuse the interface | 
 |     // entry. Note we can't cache this because we simply free all | 
 |     // entries later; however we shouldn't look up implementations | 
 |     // frequently. | 
 |     if (FieldCount == D->ivar_size()) | 
 |       return getObjCLayout(D, 0); | 
 |   } | 
 |  | 
 |   ASTRecordLayout *NewEntry = NULL; | 
 |   if (ObjCInterfaceDecl *SD = D->getSuperClass()) { | 
 |     const ASTRecordLayout &SL = getASTObjCInterfaceLayout(SD); | 
 |     unsigned Alignment = SL.getAlignment(); | 
 |  | 
 |     // We start laying out ivars not at the end of the superclass | 
 |     // structure, but at the next byte following the last field. | 
 |     uint64_t Size = llvm::RoundUpToAlignment(SL.NextOffset, 8); | 
 |  | 
 |     ObjCLayouts[Key] = NewEntry = new ASTRecordLayout(Size, Alignment); | 
 |     NewEntry->InitializeLayout(FieldCount); | 
 |   } else { | 
 |     ObjCLayouts[Key] = NewEntry = new ASTRecordLayout(); | 
 |     NewEntry->InitializeLayout(FieldCount); | 
 |   } | 
 |  | 
 |   unsigned StructPacking = 0; | 
 |   if (const PackedAttr *PA = D->getAttr<PackedAttr>()) | 
 |     StructPacking = PA->getAlignment(); | 
 |  | 
 |   if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) | 
 |     NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),  | 
 |                                     AA->getAlignment())); | 
 |  | 
 |   // Layout each ivar sequentially. | 
 |   unsigned i = 0; | 
 |   for (ObjCInterfaceDecl::ivar_iterator IVI = D->ivar_begin(),  | 
 |        IVE = D->ivar_end(); IVI != IVE; ++IVI) { | 
 |     const ObjCIvarDecl* Ivar = (*IVI); | 
 |     NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this); | 
 |   } | 
 |   // And synthesized ivars, if this is an implementation. | 
 |   if (Impl) { | 
 |     // FIXME. Do we need to colltect twice? | 
 |     llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; | 
 |     CollectSynthesizedIvars(D, Ivars); | 
 |     for (unsigned k = 0, e = Ivars.size(); k != e; ++k) | 
 |       NewEntry->LayoutField(Ivars[k], i++, false, StructPacking, *this); | 
 |   } | 
 |    | 
 |   // Finally, round the size of the total struct up to the alignment of the | 
 |   // struct itself. | 
 |   NewEntry->FinalizeLayout(); | 
 |   return *NewEntry; | 
 | } | 
 |  | 
 | const ASTRecordLayout & | 
 | ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) { | 
 |   return getObjCLayout(D, 0); | 
 | } | 
 |  | 
 | const ASTRecordLayout & | 
 | ASTContext::getASTObjCImplementationLayout(const ObjCImplementationDecl *D) { | 
 |   return getObjCLayout(D->getClassInterface(), D); | 
 | } | 
 |  | 
 | /// getASTRecordLayout - Get or compute information about the layout of the | 
 | /// specified record (struct/union/class), which indicates its size and field | 
 | /// position information. | 
 | const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) { | 
 |   D = D->getDefinition(*this); | 
 |   assert(D && "Cannot get layout of forward declarations!"); | 
 |  | 
 |   // Look up this layout, if already laid out, return what we have. | 
 |   const ASTRecordLayout *&Entry = ASTRecordLayouts[D]; | 
 |   if (Entry) return *Entry; | 
 |  | 
 |   // Allocate and assign into ASTRecordLayouts here.  The "Entry" reference can | 
 |   // be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into. | 
 |   ASTRecordLayout *NewEntry = new ASTRecordLayout(); | 
 |   Entry = NewEntry; | 
 |  | 
 |   // FIXME: Avoid linear walk through the fields, if possible. | 
 |   NewEntry->InitializeLayout(std::distance(D->field_begin(*this),  | 
 |                                            D->field_end(*this))); | 
 |   bool IsUnion = D->isUnion(); | 
 |  | 
 |   unsigned StructPacking = 0; | 
 |   if (const PackedAttr *PA = D->getAttr<PackedAttr>()) | 
 |     StructPacking = PA->getAlignment(); | 
 |  | 
 |   if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) | 
 |     NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),  | 
 |                                     AA->getAlignment())); | 
 |  | 
 |   // Layout each field, for now, just sequentially, respecting alignment.  In | 
 |   // the future, this will need to be tweakable by targets. | 
 |   unsigned FieldIdx = 0; | 
 |   for (RecordDecl::field_iterator Field = D->field_begin(*this), | 
 |                                FieldEnd = D->field_end(*this); | 
 |        Field != FieldEnd; (void)++Field, ++FieldIdx) | 
 |     NewEntry->LayoutField(*Field, FieldIdx, IsUnion, StructPacking, *this); | 
 |  | 
 |   // Finally, round the size of the total struct up to the alignment of the | 
 |   // struct itself. | 
 |   NewEntry->FinalizeLayout(getLangOptions().CPlusPlus); | 
 |   return *NewEntry; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | //                   Type creation/memoization methods | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | QualType ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) { | 
 |   QualType CanT = getCanonicalType(T); | 
 |   if (CanT.getAddressSpace() == AddressSpace) | 
 |     return T; | 
 |  | 
 |   // If we are composing extended qualifiers together, merge together into one | 
 |   // ExtQualType node. | 
 |   unsigned CVRQuals = T.getCVRQualifiers(); | 
 |   QualType::GCAttrTypes GCAttr = QualType::GCNone; | 
 |   Type *TypeNode = T.getTypePtr(); | 
 |    | 
 |   if (ExtQualType *EQT = dyn_cast<ExtQualType>(TypeNode)) { | 
 |     // If this type already has an address space specified, it cannot get | 
 |     // another one. | 
 |     assert(EQT->getAddressSpace() == 0 && | 
 |            "Type cannot be in multiple addr spaces!"); | 
 |     GCAttr = EQT->getObjCGCAttr(); | 
 |     TypeNode = EQT->getBaseType(); | 
 |   } | 
 |    | 
 |   // Check if we've already instantiated this type. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   ExtQualType::Profile(ID, TypeNode, AddressSpace, GCAttr);       | 
 |   void *InsertPos = 0; | 
 |   if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(EXTQy, CVRQuals); | 
 |  | 
 |   // If the base type isn't canonical, this won't be a canonical type either, | 
 |   // so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |   if (!TypeNode->isCanonical()) { | 
 |     Canonical = getAddrSpaceQualType(CanT, AddressSpace); | 
 |      | 
 |     // Update InsertPos, the previous call could have invalidated it. | 
 |     ExtQualType *NewIP = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |   ExtQualType *New = | 
 |     new (*this, 8) ExtQualType(TypeNode, Canonical, AddressSpace, GCAttr); | 
 |   ExtQualTypes.InsertNode(New, InsertPos); | 
 |   Types.push_back(New); | 
 |   return QualType(New, CVRQuals); | 
 | } | 
 |  | 
 | QualType ASTContext::getObjCGCQualType(QualType T, | 
 |                                        QualType::GCAttrTypes GCAttr) { | 
 |   QualType CanT = getCanonicalType(T); | 
 |   if (CanT.getObjCGCAttr() == GCAttr) | 
 |     return T; | 
 |    | 
 |   // If we are composing extended qualifiers together, merge together into one | 
 |   // ExtQualType node. | 
 |   unsigned CVRQuals = T.getCVRQualifiers(); | 
 |   Type *TypeNode = T.getTypePtr(); | 
 |   unsigned AddressSpace = 0; | 
 |    | 
 |   if (ExtQualType *EQT = dyn_cast<ExtQualType>(TypeNode)) { | 
 |     // If this type already has an address space specified, it cannot get | 
 |     // another one. | 
 |     assert(EQT->getObjCGCAttr() == QualType::GCNone && | 
 |            "Type cannot be in multiple addr spaces!"); | 
 |     AddressSpace = EQT->getAddressSpace(); | 
 |     TypeNode = EQT->getBaseType(); | 
 |   } | 
 |    | 
 |   // Check if we've already instantiated an gc qual'd type of this type. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   ExtQualType::Profile(ID, TypeNode, AddressSpace, GCAttr);       | 
 |   void *InsertPos = 0; | 
 |   if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(EXTQy, CVRQuals); | 
 |    | 
 |   // If the base type isn't canonical, this won't be a canonical type either, | 
 |   // so fill in the canonical type field. | 
 |   // FIXME: Isn't this also not canonical if the base type is a array | 
 |   // or pointer type?  I can't find any documentation for objc_gc, though... | 
 |   QualType Canonical; | 
 |   if (!T->isCanonical()) { | 
 |     Canonical = getObjCGCQualType(CanT, GCAttr); | 
 |      | 
 |     // Update InsertPos, the previous call could have invalidated it. | 
 |     ExtQualType *NewIP = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |   ExtQualType *New = | 
 |     new (*this, 8) ExtQualType(TypeNode, Canonical, AddressSpace, GCAttr); | 
 |   ExtQualTypes.InsertNode(New, InsertPos); | 
 |   Types.push_back(New); | 
 |   return QualType(New, CVRQuals); | 
 | } | 
 |  | 
 | /// getComplexType - Return the uniqued reference to the type for a complex | 
 | /// number with the specified element type. | 
 | QualType ASTContext::getComplexType(QualType T) { | 
 |   // Unique pointers, to guarantee there is only one pointer of a particular | 
 |   // structure. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   ComplexType::Profile(ID, T); | 
 |    | 
 |   void *InsertPos = 0; | 
 |   if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(CT, 0); | 
 |    | 
 |   // If the pointee type isn't canonical, this won't be a canonical type either, | 
 |   // so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |   if (!T->isCanonical()) { | 
 |     Canonical = getComplexType(getCanonicalType(T)); | 
 |      | 
 |     // Get the new insert position for the node we care about. | 
 |     ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |   ComplexType *New = new (*this,8) ComplexType(T, Canonical); | 
 |   Types.push_back(New); | 
 |   ComplexTypes.InsertNode(New, InsertPos); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | QualType ASTContext::getFixedWidthIntType(unsigned Width, bool Signed) { | 
 |   llvm::DenseMap<unsigned, FixedWidthIntType*> &Map = Signed ? | 
 |      SignedFixedWidthIntTypes : UnsignedFixedWidthIntTypes; | 
 |   FixedWidthIntType *&Entry = Map[Width]; | 
 |   if (!Entry) | 
 |     Entry = new FixedWidthIntType(Width, Signed); | 
 |   return QualType(Entry, 0); | 
 | } | 
 |  | 
 | /// getPointerType - Return the uniqued reference to the type for a pointer to | 
 | /// the specified type. | 
 | QualType ASTContext::getPointerType(QualType T) { | 
 |   // Unique pointers, to guarantee there is only one pointer of a particular | 
 |   // structure. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   PointerType::Profile(ID, T); | 
 |    | 
 |   void *InsertPos = 0; | 
 |   if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(PT, 0); | 
 |    | 
 |   // If the pointee type isn't canonical, this won't be a canonical type either, | 
 |   // so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |   if (!T->isCanonical()) { | 
 |     Canonical = getPointerType(getCanonicalType(T)); | 
 |     | 
 |     // Get the new insert position for the node we care about. | 
 |     PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |   PointerType *New = new (*this,8) PointerType(T, Canonical); | 
 |   Types.push_back(New); | 
 |   PointerTypes.InsertNode(New, InsertPos); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getBlockPointerType - Return the uniqued reference to the type for  | 
 | /// a pointer to the specified block. | 
 | QualType ASTContext::getBlockPointerType(QualType T) { | 
 |   assert(T->isFunctionType() && "block of function types only"); | 
 |   // Unique pointers, to guarantee there is only one block of a particular | 
 |   // structure. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   BlockPointerType::Profile(ID, T); | 
 |    | 
 |   void *InsertPos = 0; | 
 |   if (BlockPointerType *PT = | 
 |         BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(PT, 0); | 
 |    | 
 |   // If the block pointee type isn't canonical, this won't be a canonical  | 
 |   // type either so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |   if (!T->isCanonical()) { | 
 |     Canonical = getBlockPointerType(getCanonicalType(T)); | 
 |      | 
 |     // Get the new insert position for the node we care about. | 
 |     BlockPointerType *NewIP = | 
 |       BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |   BlockPointerType *New = new (*this,8) BlockPointerType(T, Canonical); | 
 |   Types.push_back(New); | 
 |   BlockPointerTypes.InsertNode(New, InsertPos); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getLValueReferenceType - Return the uniqued reference to the type for an | 
 | /// lvalue reference to the specified type. | 
 | QualType ASTContext::getLValueReferenceType(QualType T) { | 
 |   // Unique pointers, to guarantee there is only one pointer of a particular | 
 |   // structure. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   ReferenceType::Profile(ID, T); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   if (LValueReferenceType *RT = | 
 |         LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(RT, 0); | 
 |  | 
 |   // If the referencee type isn't canonical, this won't be a canonical type | 
 |   // either, so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |   if (!T->isCanonical()) { | 
 |     Canonical = getLValueReferenceType(getCanonicalType(T)); | 
 |  | 
 |     // Get the new insert position for the node we care about. | 
 |     LValueReferenceType *NewIP = | 
 |       LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |  | 
 |   LValueReferenceType *New = new (*this,8) LValueReferenceType(T, Canonical); | 
 |   Types.push_back(New); | 
 |   LValueReferenceTypes.InsertNode(New, InsertPos); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getRValueReferenceType - Return the uniqued reference to the type for an | 
 | /// rvalue reference to the specified type. | 
 | QualType ASTContext::getRValueReferenceType(QualType T) { | 
 |   // Unique pointers, to guarantee there is only one pointer of a particular | 
 |   // structure. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   ReferenceType::Profile(ID, T); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   if (RValueReferenceType *RT = | 
 |         RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(RT, 0); | 
 |  | 
 |   // If the referencee type isn't canonical, this won't be a canonical type | 
 |   // either, so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |   if (!T->isCanonical()) { | 
 |     Canonical = getRValueReferenceType(getCanonicalType(T)); | 
 |  | 
 |     // Get the new insert position for the node we care about. | 
 |     RValueReferenceType *NewIP = | 
 |       RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |  | 
 |   RValueReferenceType *New = new (*this,8) RValueReferenceType(T, Canonical); | 
 |   Types.push_back(New); | 
 |   RValueReferenceTypes.InsertNode(New, InsertPos); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getMemberPointerType - Return the uniqued reference to the type for a | 
 | /// member pointer to the specified type, in the specified class. | 
 | QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) | 
 | { | 
 |   // Unique pointers, to guarantee there is only one pointer of a particular | 
 |   // structure. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   MemberPointerType::Profile(ID, T, Cls); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   if (MemberPointerType *PT = | 
 |       MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(PT, 0); | 
 |  | 
 |   // If the pointee or class type isn't canonical, this won't be a canonical | 
 |   // type either, so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |   if (!T->isCanonical()) { | 
 |     Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls)); | 
 |  | 
 |     // Get the new insert position for the node we care about. | 
 |     MemberPointerType *NewIP = | 
 |       MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |   MemberPointerType *New = new (*this,8) MemberPointerType(T, Cls, Canonical); | 
 |   Types.push_back(New); | 
 |   MemberPointerTypes.InsertNode(New, InsertPos); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getConstantArrayType - Return the unique reference to the type for an  | 
 | /// array of the specified element type. | 
 | QualType ASTContext::getConstantArrayType(QualType EltTy,  | 
 |                                           const llvm::APInt &ArySizeIn, | 
 |                                           ArrayType::ArraySizeModifier ASM, | 
 |                                           unsigned EltTypeQuals) { | 
 |   assert((EltTy->isDependentType() || EltTy->isConstantSizeType()) && | 
 |          "Constant array of VLAs is illegal!"); | 
 |  | 
 |   // Convert the array size into a canonical width matching the pointer size for | 
 |   // the target. | 
 |   llvm::APInt ArySize(ArySizeIn); | 
 |   ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace())); | 
 |    | 
 |   llvm::FoldingSetNodeID ID; | 
 |   ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, EltTypeQuals); | 
 |        | 
 |   void *InsertPos = 0; | 
 |   if (ConstantArrayType *ATP =  | 
 |       ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(ATP, 0); | 
 |    | 
 |   // If the element type isn't canonical, this won't be a canonical type either, | 
 |   // so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |   if (!EltTy->isCanonical()) { | 
 |     Canonical = getConstantArrayType(getCanonicalType(EltTy), ArySize,  | 
 |                                      ASM, EltTypeQuals); | 
 |     // Get the new insert position for the node we care about. | 
 |     ConstantArrayType *NewIP =  | 
 |       ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |    | 
 |   ConstantArrayType *New = | 
 |     new(*this,8)ConstantArrayType(EltTy, Canonical, ArySize, ASM, EltTypeQuals); | 
 |   ConstantArrayTypes.InsertNode(New, InsertPos); | 
 |   Types.push_back(New); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getVariableArrayType - Returns a non-unique reference to the type for a | 
 | /// variable array of the specified element type. | 
 | QualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts, | 
 |                                           ArrayType::ArraySizeModifier ASM, | 
 |                                           unsigned EltTypeQuals) { | 
 |   // Since we don't unique expressions, it isn't possible to unique VLA's | 
 |   // that have an expression provided for their size. | 
 |  | 
 |   VariableArrayType *New = | 
 |     new(*this,8)VariableArrayType(EltTy,QualType(), NumElts, ASM, EltTypeQuals); | 
 |  | 
 |   VariableArrayTypes.push_back(New); | 
 |   Types.push_back(New); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getDependentSizedArrayType - Returns a non-unique reference to | 
 | /// the type for a dependently-sized array of the specified element | 
 | /// type. FIXME: We will need these to be uniqued, or at least | 
 | /// comparable, at some point. | 
 | QualType ASTContext::getDependentSizedArrayType(QualType EltTy, Expr *NumElts, | 
 |                                                 ArrayType::ArraySizeModifier ASM, | 
 |                                                 unsigned EltTypeQuals) { | 
 |   assert((NumElts->isTypeDependent() || NumElts->isValueDependent()) &&  | 
 |          "Size must be type- or value-dependent!"); | 
 |  | 
 |   // Since we don't unique expressions, it isn't possible to unique | 
 |   // dependently-sized array types. | 
 |  | 
 |   DependentSizedArrayType *New = | 
 |       new (*this,8) DependentSizedArrayType(EltTy, QualType(), NumElts,  | 
 |                                             ASM, EltTypeQuals); | 
 |  | 
 |   DependentSizedArrayTypes.push_back(New); | 
 |   Types.push_back(New); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | QualType ASTContext::getIncompleteArrayType(QualType EltTy, | 
 |                                             ArrayType::ArraySizeModifier ASM, | 
 |                                             unsigned EltTypeQuals) { | 
 |   llvm::FoldingSetNodeID ID; | 
 |   IncompleteArrayType::Profile(ID, EltTy, ASM, EltTypeQuals); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   if (IncompleteArrayType *ATP =  | 
 |        IncompleteArrayTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(ATP, 0); | 
 |  | 
 |   // If the element type isn't canonical, this won't be a canonical type | 
 |   // either, so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |  | 
 |   if (!EltTy->isCanonical()) { | 
 |     Canonical = getIncompleteArrayType(getCanonicalType(EltTy), | 
 |                                        ASM, EltTypeQuals); | 
 |  | 
 |     // Get the new insert position for the node we care about. | 
 |     IncompleteArrayType *NewIP = | 
 |       IncompleteArrayTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |  | 
 |   IncompleteArrayType *New = new (*this,8) IncompleteArrayType(EltTy, Canonical, | 
 |                                                            ASM, EltTypeQuals); | 
 |  | 
 |   IncompleteArrayTypes.InsertNode(New, InsertPos); | 
 |   Types.push_back(New); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getVectorType - Return the unique reference to a vector type of | 
 | /// the specified element type and size. VectorType must be a built-in type. | 
 | QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) { | 
 |   BuiltinType *baseType; | 
 |    | 
 |   baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr()); | 
 |   assert(baseType != 0 && "getVectorType(): Expecting a built-in type"); | 
 |           | 
 |   // Check if we've already instantiated a vector of this type. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   VectorType::Profile(ID, vecType, NumElts, Type::Vector);       | 
 |   void *InsertPos = 0; | 
 |   if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(VTP, 0); | 
 |  | 
 |   // If the element type isn't canonical, this won't be a canonical type either, | 
 |   // so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |   if (!vecType->isCanonical()) { | 
 |     Canonical = getVectorType(getCanonicalType(vecType), NumElts); | 
 |      | 
 |     // Get the new insert position for the node we care about. | 
 |     VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |   VectorType *New = new (*this,8) VectorType(vecType, NumElts, Canonical); | 
 |   VectorTypes.InsertNode(New, InsertPos); | 
 |   Types.push_back(New); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getExtVectorType - Return the unique reference to an extended vector type of | 
 | /// the specified element type and size. VectorType must be a built-in type. | 
 | QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) { | 
 |   BuiltinType *baseType; | 
 |    | 
 |   baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr()); | 
 |   assert(baseType != 0 && "getExtVectorType(): Expecting a built-in type"); | 
 |           | 
 |   // Check if we've already instantiated a vector of this type. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   VectorType::Profile(ID, vecType, NumElts, Type::ExtVector);       | 
 |   void *InsertPos = 0; | 
 |   if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(VTP, 0); | 
 |  | 
 |   // If the element type isn't canonical, this won't be a canonical type either, | 
 |   // so fill in the canonical type field. | 
 |   QualType Canonical; | 
 |   if (!vecType->isCanonical()) { | 
 |     Canonical = getExtVectorType(getCanonicalType(vecType), NumElts); | 
 |      | 
 |     // Get the new insert position for the node we care about. | 
 |     VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |   ExtVectorType *New = new (*this,8) ExtVectorType(vecType, NumElts, Canonical); | 
 |   VectorTypes.InsertNode(New, InsertPos); | 
 |   Types.push_back(New); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. | 
 | /// | 
 | QualType ASTContext::getFunctionNoProtoType(QualType ResultTy) { | 
 |   // Unique functions, to guarantee there is only one function of a particular | 
 |   // structure. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   FunctionNoProtoType::Profile(ID, ResultTy); | 
 |    | 
 |   void *InsertPos = 0; | 
 |   if (FunctionNoProtoType *FT =  | 
 |         FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(FT, 0); | 
 |    | 
 |   QualType Canonical; | 
 |   if (!ResultTy->isCanonical()) { | 
 |     Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy)); | 
 |      | 
 |     // Get the new insert position for the node we care about. | 
 |     FunctionNoProtoType *NewIP = | 
 |       FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |    | 
 |   FunctionNoProtoType *New =new(*this,8)FunctionNoProtoType(ResultTy,Canonical); | 
 |   Types.push_back(New); | 
 |   FunctionNoProtoTypes.InsertNode(New, InsertPos); | 
 |   return QualType(New, 0); | 
 | } | 
 |  | 
 | /// getFunctionType - Return a normal function type with a typed argument | 
 | /// list.  isVariadic indicates whether the argument list includes '...'. | 
 | QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, | 
 |                                      unsigned NumArgs, bool isVariadic, | 
 |                                      unsigned TypeQuals, bool hasExceptionSpec, | 
 |                                      bool hasAnyExceptionSpec, unsigned NumExs, | 
 |                                      const QualType *ExArray) { | 
 |   // Unique functions, to guarantee there is only one function of a particular | 
 |   // structure. | 
 |   llvm::FoldingSetNodeID ID; | 
 |   FunctionProtoType::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic, | 
 |                              TypeQuals, hasExceptionSpec, hasAnyExceptionSpec, | 
 |                              NumExs, ExArray); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   if (FunctionProtoType *FTP =  | 
 |         FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(FTP, 0); | 
 |  | 
 |   // Determine whether the type being created is already canonical or not. | 
 |   bool isCanonical = ResultTy->isCanonical(); | 
 |   if (hasExceptionSpec) | 
 |     isCanonical = false; | 
 |   for (unsigned i = 0; i != NumArgs && isCanonical; ++i) | 
 |     if (!ArgArray[i]->isCanonical()) | 
 |       isCanonical = false; | 
 |  | 
 |   // If this type isn't canonical, get the canonical version of it. | 
 |   // The exception spec is not part of the canonical type. | 
 |   QualType Canonical; | 
 |   if (!isCanonical) { | 
 |     llvm::SmallVector<QualType, 16> CanonicalArgs; | 
 |     CanonicalArgs.reserve(NumArgs); | 
 |     for (unsigned i = 0; i != NumArgs; ++i) | 
 |       CanonicalArgs.push_back(getCanonicalType(ArgArray[i])); | 
 |  | 
 |     Canonical = getFunctionType(getCanonicalType(ResultTy), | 
 |                                 CanonicalArgs.data(), NumArgs, | 
 |                                 isVariadic, TypeQuals); | 
 |  | 
 |     // Get the new insert position for the node we care about. | 
 |     FunctionProtoType *NewIP = | 
 |       FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; | 
 |   } | 
 |  | 
 |   // FunctionProtoType objects are allocated with extra bytes after them | 
 |   // for two variable size arrays (for parameter and exception types) at the | 
 |   // end of them. | 
 |   FunctionProtoType *FTP =  | 
 |     (FunctionProtoType*)Allocate(sizeof(FunctionProtoType) + | 
 |                                  NumArgs*sizeof(QualType) + | 
 |                                  NumExs*sizeof(QualType), 8); | 
 |   new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic, | 
 |                               TypeQuals, hasExceptionSpec, hasAnyExceptionSpec, | 
 |                               ExArray, NumExs, Canonical); | 
 |   Types.push_back(FTP); | 
 |   FunctionProtoTypes.InsertNode(FTP, InsertPos); | 
 |   return QualType(FTP, 0); | 
 | } | 
 |  | 
 | /// getTypeDeclType - Return the unique reference to the type for the | 
 | /// specified type declaration. | 
 | QualType ASTContext::getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl) { | 
 |   assert(Decl && "Passed null for Decl param"); | 
 |   if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); | 
 |    | 
 |   if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl)) | 
 |     return getTypedefType(Typedef); | 
 |   else if (isa<TemplateTypeParmDecl>(Decl)) { | 
 |     assert(false && "Template type parameter types are always available."); | 
 |   } else if (ObjCInterfaceDecl *ObjCInterface = dyn_cast<ObjCInterfaceDecl>(Decl)) | 
 |     return getObjCInterfaceType(ObjCInterface); | 
 |  | 
 |   if (RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) { | 
 |     if (PrevDecl) | 
 |       Decl->TypeForDecl = PrevDecl->TypeForDecl; | 
 |     else | 
 |       Decl->TypeForDecl = new (*this,8) RecordType(Record); | 
 |   } | 
 |   else if (EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) { | 
 |     if (PrevDecl) | 
 |       Decl->TypeForDecl = PrevDecl->TypeForDecl; | 
 |     else | 
 |       Decl->TypeForDecl = new (*this,8) EnumType(Enum); | 
 |   } | 
 |   else | 
 |     assert(false && "TypeDecl without a type?"); | 
 |  | 
 |   if (!PrevDecl) Types.push_back(Decl->TypeForDecl); | 
 |   return QualType(Decl->TypeForDecl, 0); | 
 | } | 
 |  | 
 | /// getTypedefType - Return the unique reference to the type for the | 
 | /// specified typename decl. | 
 | QualType ASTContext::getTypedefType(TypedefDecl *Decl) { | 
 |   if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); | 
 |    | 
 |   QualType Canonical = getCanonicalType(Decl->getUnderlyingType()); | 
 |   Decl->TypeForDecl = new(*this,8) TypedefType(Type::Typedef, Decl, Canonical); | 
 |   Types.push_back(Decl->TypeForDecl); | 
 |   return QualType(Decl->TypeForDecl, 0); | 
 | } | 
 |  | 
 | /// getObjCInterfaceType - Return the unique reference to the type for the | 
 | /// specified ObjC interface decl. | 
 | QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) { | 
 |   if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); | 
 |    | 
 |   ObjCInterfaceDecl *OID = const_cast<ObjCInterfaceDecl*>(Decl); | 
 |   Decl->TypeForDecl = new(*this,8) ObjCInterfaceType(Type::ObjCInterface, OID); | 
 |   Types.push_back(Decl->TypeForDecl); | 
 |   return QualType(Decl->TypeForDecl, 0); | 
 | } | 
 |  | 
 | /// \brief Retrieve the template type parameter type for a template | 
 | /// parameter with the given depth, index, and (optionally) name. | 
 | QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,  | 
 |                                              IdentifierInfo *Name) { | 
 |   llvm::FoldingSetNodeID ID; | 
 |   TemplateTypeParmType::Profile(ID, Depth, Index, Name); | 
 |   void *InsertPos = 0; | 
 |   TemplateTypeParmType *TypeParm  | 
 |     = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |  | 
 |   if (TypeParm) | 
 |     return QualType(TypeParm, 0); | 
 |    | 
 |   if (Name) | 
 |     TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, Name, | 
 |                                          getTemplateTypeParmType(Depth, Index)); | 
 |   else | 
 |     TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index); | 
 |  | 
 |   Types.push_back(TypeParm); | 
 |   TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos); | 
 |  | 
 |   return QualType(TypeParm, 0); | 
 | } | 
 |  | 
 | QualType  | 
 | ASTContext::getTemplateSpecializationType(TemplateName Template, | 
 |                                           const TemplateArgument *Args, | 
 |                                           unsigned NumArgs, | 
 |                                           QualType Canon) { | 
 |   if (!Canon.isNull()) | 
 |     Canon = getCanonicalType(Canon); | 
 |  | 
 |   llvm::FoldingSetNodeID ID; | 
 |   TemplateSpecializationType::Profile(ID, Template, Args, NumArgs); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   TemplateSpecializationType *Spec | 
 |     = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |  | 
 |   if (Spec) | 
 |     return QualType(Spec, 0); | 
 |    | 
 |   void *Mem = Allocate((sizeof(TemplateSpecializationType) +  | 
 |                         sizeof(TemplateArgument) * NumArgs), | 
 |                        8); | 
 |   Spec = new (Mem) TemplateSpecializationType(Template, Args, NumArgs, Canon); | 
 |   Types.push_back(Spec); | 
 |   TemplateSpecializationTypes.InsertNode(Spec, InsertPos); | 
 |  | 
 |   return QualType(Spec, 0);   | 
 | } | 
 |  | 
 | QualType  | 
 | ASTContext::getQualifiedNameType(NestedNameSpecifier *NNS, | 
 |                                  QualType NamedType) { | 
 |   llvm::FoldingSetNodeID ID; | 
 |   QualifiedNameType::Profile(ID, NNS, NamedType); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   QualifiedNameType *T  | 
 |     = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |   if (T) | 
 |     return QualType(T, 0); | 
 |  | 
 |   T = new (*this) QualifiedNameType(NNS, NamedType,  | 
 |                                     getCanonicalType(NamedType)); | 
 |   Types.push_back(T); | 
 |   QualifiedNameTypes.InsertNode(T, InsertPos); | 
 |   return QualType(T, 0); | 
 | } | 
 |  | 
 | QualType ASTContext::getTypenameType(NestedNameSpecifier *NNS,  | 
 |                                      const IdentifierInfo *Name, | 
 |                                      QualType Canon) { | 
 |   assert(NNS->isDependent() && "nested-name-specifier must be dependent"); | 
 |  | 
 |   if (Canon.isNull()) { | 
 |     NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); | 
 |     if (CanonNNS != NNS) | 
 |       Canon = getTypenameType(CanonNNS, Name); | 
 |   } | 
 |  | 
 |   llvm::FoldingSetNodeID ID; | 
 |   TypenameType::Profile(ID, NNS, Name); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   TypenameType *T  | 
 |     = TypenameTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |   if (T) | 
 |     return QualType(T, 0); | 
 |  | 
 |   T = new (*this) TypenameType(NNS, Name, Canon); | 
 |   Types.push_back(T); | 
 |   TypenameTypes.InsertNode(T, InsertPos); | 
 |   return QualType(T, 0);   | 
 | } | 
 |  | 
 | QualType  | 
 | ASTContext::getTypenameType(NestedNameSpecifier *NNS,  | 
 |                             const TemplateSpecializationType *TemplateId, | 
 |                             QualType Canon) { | 
 |   assert(NNS->isDependent() && "nested-name-specifier must be dependent"); | 
 |  | 
 |   if (Canon.isNull()) { | 
 |     NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); | 
 |     QualType CanonType = getCanonicalType(QualType(TemplateId, 0)); | 
 |     if (CanonNNS != NNS || CanonType != QualType(TemplateId, 0)) { | 
 |       const TemplateSpecializationType *CanonTemplateId | 
 |         = CanonType->getAsTemplateSpecializationType(); | 
 |       assert(CanonTemplateId && | 
 |              "Canonical type must also be a template specialization type"); | 
 |       Canon = getTypenameType(CanonNNS, CanonTemplateId); | 
 |     } | 
 |   } | 
 |  | 
 |   llvm::FoldingSetNodeID ID; | 
 |   TypenameType::Profile(ID, NNS, TemplateId); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   TypenameType *T  | 
 |     = TypenameTypes.FindNodeOrInsertPos(ID, InsertPos); | 
 |   if (T) | 
 |     return QualType(T, 0); | 
 |  | 
 |   T = new (*this) TypenameType(NNS, TemplateId, Canon); | 
 |   Types.push_back(T); | 
 |   TypenameTypes.InsertNode(T, InsertPos); | 
 |   return QualType(T, 0);     | 
 | } | 
 |  | 
 | /// CmpProtocolNames - Comparison predicate for sorting protocols | 
 | /// alphabetically. | 
 | static bool CmpProtocolNames(const ObjCProtocolDecl *LHS, | 
 |                             const ObjCProtocolDecl *RHS) { | 
 |   return LHS->getDeclName() < RHS->getDeclName(); | 
 | } | 
 |  | 
 | static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols, | 
 |                                    unsigned &NumProtocols) { | 
 |   ObjCProtocolDecl **ProtocolsEnd = Protocols+NumProtocols; | 
 |    | 
 |   // Sort protocols, keyed by name. | 
 |   std::sort(Protocols, Protocols+NumProtocols, CmpProtocolNames); | 
 |  | 
 |   // Remove duplicates. | 
 |   ProtocolsEnd = std::unique(Protocols, ProtocolsEnd); | 
 |   NumProtocols = ProtocolsEnd-Protocols; | 
 | } | 
 |  | 
 |  | 
 | /// getObjCQualifiedInterfaceType - Return a ObjCQualifiedInterfaceType type for | 
 | /// the given interface decl and the conforming protocol list. | 
 | QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl, | 
 |                        ObjCProtocolDecl **Protocols, unsigned NumProtocols) { | 
 |   // Sort the protocol list alphabetically to canonicalize it. | 
 |   SortAndUniqueProtocols(Protocols, NumProtocols); | 
 |    | 
 |   llvm::FoldingSetNodeID ID; | 
 |   ObjCQualifiedInterfaceType::Profile(ID, Decl, Protocols, NumProtocols); | 
 |    | 
 |   void *InsertPos = 0; | 
 |   if (ObjCQualifiedInterfaceType *QT = | 
 |       ObjCQualifiedInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(QT, 0); | 
 |    | 
 |   // No Match; | 
 |   ObjCQualifiedInterfaceType *QType = | 
 |     new (*this,8) ObjCQualifiedInterfaceType(Decl, Protocols, NumProtocols); | 
 |  | 
 |   Types.push_back(QType); | 
 |   ObjCQualifiedInterfaceTypes.InsertNode(QType, InsertPos); | 
 |   return QualType(QType, 0); | 
 | } | 
 |  | 
 | /// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for the 'id' decl | 
 | /// and the conforming protocol list. | 
 | QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols,  | 
 |                                             unsigned NumProtocols) { | 
 |   // Sort the protocol list alphabetically to canonicalize it. | 
 |   SortAndUniqueProtocols(Protocols, NumProtocols); | 
 |  | 
 |   llvm::FoldingSetNodeID ID; | 
 |   ObjCQualifiedIdType::Profile(ID, Protocols, NumProtocols); | 
 |    | 
 |   void *InsertPos = 0; | 
 |   if (ObjCQualifiedIdType *QT = | 
 |         ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos)) | 
 |     return QualType(QT, 0); | 
 |    | 
 |   // No Match; | 
 |   ObjCQualifiedIdType *QType = | 
 |     new (*this,8) ObjCQualifiedIdType(Protocols, NumProtocols); | 
 |   Types.push_back(QType); | 
 |   ObjCQualifiedIdTypes.InsertNode(QType, InsertPos); | 
 |   return QualType(QType, 0); | 
 | } | 
 |  | 
 | /// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique | 
 | /// TypeOfExprType AST's (since expression's are never shared). For example, | 
 | /// multiple declarations that refer to "typeof(x)" all contain different | 
 | /// DeclRefExpr's. This doesn't effect the type checker, since it operates  | 
 | /// on canonical type's (which are always unique). | 
 | QualType ASTContext::getTypeOfExprType(Expr *tofExpr) { | 
 |   QualType Canonical = getCanonicalType(tofExpr->getType()); | 
 |   TypeOfExprType *toe = new (*this,8) TypeOfExprType(tofExpr, Canonical); | 
 |   Types.push_back(toe); | 
 |   return QualType(toe, 0); | 
 | } | 
 |  | 
 | /// getTypeOfType -  Unlike many "get<Type>" functions, we don't unique | 
 | /// TypeOfType AST's. The only motivation to unique these nodes would be | 
 | /// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be | 
 | /// an issue. This doesn't effect the type checker, since it operates  | 
 | /// on canonical type's (which are always unique). | 
 | QualType ASTContext::getTypeOfType(QualType tofType) { | 
 |   QualType Canonical = getCanonicalType(tofType); | 
 |   TypeOfType *tot = new (*this,8) TypeOfType(tofType, Canonical); | 
 |   Types.push_back(tot); | 
 |   return QualType(tot, 0); | 
 | } | 
 |  | 
 | /// getTagDeclType - Return the unique reference to the type for the | 
 | /// specified TagDecl (struct/union/class/enum) decl. | 
 | QualType ASTContext::getTagDeclType(TagDecl *Decl) { | 
 |   assert (Decl); | 
 |   return getTypeDeclType(Decl); | 
 | } | 
 |  | 
 | /// getSizeType - Return the unique type for "size_t" (C99 7.17), the result  | 
 | /// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and  | 
 | /// needs to agree with the definition in <stddef.h>.  | 
 | QualType ASTContext::getSizeType() const { | 
 |   return getFromTargetType(Target.getSizeType()); | 
 | } | 
 |  | 
 | /// getSignedWCharType - Return the type of "signed wchar_t". | 
 | /// Used when in C++, as a GCC extension. | 
 | QualType ASTContext::getSignedWCharType() const { | 
 |   // FIXME: derive from "Target" ? | 
 |   return WCharTy; | 
 | } | 
 |  | 
 | /// getUnsignedWCharType - Return the type of "unsigned wchar_t". | 
 | /// Used when in C++, as a GCC extension. | 
 | QualType ASTContext::getUnsignedWCharType() const { | 
 |   // FIXME: derive from "Target" ? | 
 |   return UnsignedIntTy; | 
 | } | 
 |  | 
 | /// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?) | 
 | /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9). | 
 | QualType ASTContext::getPointerDiffType() const { | 
 |   return getFromTargetType(Target.getPtrDiffType(0)); | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | //                              Type Operators | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | /// getCanonicalType - Return the canonical (structural) type corresponding to | 
 | /// the specified potentially non-canonical type.  The non-canonical version | 
 | /// of a type may have many "decorated" versions of types.  Decorators can | 
 | /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed | 
 | /// to be free of any of these, allowing two canonical types to be compared | 
 | /// for exact equality with a simple pointer comparison. | 
 | QualType ASTContext::getCanonicalType(QualType T) { | 
 |   QualType CanType = T.getTypePtr()->getCanonicalTypeInternal(); | 
 |    | 
 |   // If the result has type qualifiers, make sure to canonicalize them as well. | 
 |   unsigned TypeQuals = T.getCVRQualifiers() | CanType.getCVRQualifiers(); | 
 |   if (TypeQuals == 0) return CanType; | 
 |  | 
 |   // If the type qualifiers are on an array type, get the canonical type of the | 
 |   // array with the qualifiers applied to the element type. | 
 |   ArrayType *AT = dyn_cast<ArrayType>(CanType); | 
 |   if (!AT) | 
 |     return CanType.getQualifiedType(TypeQuals); | 
 |    | 
 |   // Get the canonical version of the element with the extra qualifiers on it. | 
 |   // This can recursively sink qualifiers through multiple levels of arrays. | 
 |   QualType NewEltTy=AT->getElementType().getWithAdditionalQualifiers(TypeQuals); | 
 |   NewEltTy = getCanonicalType(NewEltTy); | 
 |    | 
 |   if (ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) | 
 |     return getConstantArrayType(NewEltTy, CAT->getSize(),CAT->getSizeModifier(), | 
 |                                 CAT->getIndexTypeQualifier()); | 
 |   if (IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) | 
 |     return getIncompleteArrayType(NewEltTy, IAT->getSizeModifier(), | 
 |                                   IAT->getIndexTypeQualifier()); | 
 |    | 
 |   if (DependentSizedArrayType *DSAT = dyn_cast<DependentSizedArrayType>(AT)) | 
 |     return getDependentSizedArrayType(NewEltTy, DSAT->getSizeExpr(), | 
 |                                       DSAT->getSizeModifier(), | 
 |                                       DSAT->getIndexTypeQualifier());     | 
 |  | 
 |   VariableArrayType *VAT = cast<VariableArrayType>(AT); | 
 |   return getVariableArrayType(NewEltTy, VAT->getSizeExpr(), | 
 |                               VAT->getSizeModifier(), | 
 |                               VAT->getIndexTypeQualifier()); | 
 | } | 
 |  | 
 | Decl *ASTContext::getCanonicalDecl(Decl *D) { | 
 |   if (!D) | 
 |     return 0; | 
 |  | 
 |   if (TagDecl *Tag = dyn_cast<TagDecl>(D)) { | 
 |     QualType T = getTagDeclType(Tag); | 
 |     return cast<TagDecl>(cast<TagType>(T.getTypePtr()->CanonicalType) | 
 |                          ->getDecl()); | 
 |   } | 
 |  | 
 |   if (ClassTemplateDecl *Template = dyn_cast<ClassTemplateDecl>(D)) { | 
 |     while (Template->getPreviousDeclaration()) | 
 |       Template = Template->getPreviousDeclaration(); | 
 |     return Template; | 
 |   } | 
 |  | 
 |   if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { | 
 |     while (Function->getPreviousDeclaration()) | 
 |       Function = Function->getPreviousDeclaration(); | 
 |     return const_cast<FunctionDecl *>(Function); | 
 |   } | 
 |  | 
 |   if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { | 
 |     while (Var->getPreviousDeclaration()) | 
 |       Var = Var->getPreviousDeclaration(); | 
 |     return const_cast<VarDecl *>(Var); | 
 |   } | 
 |  | 
 |   return D; | 
 | } | 
 |  | 
 | TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) { | 
 |   // If this template name refers to a template, the canonical | 
 |   // template name merely stores the template itself. | 
 |   if (TemplateDecl *Template = Name.getAsTemplateDecl()) | 
 |     return TemplateName(cast<TemplateDecl>(getCanonicalDecl(Template))); | 
 |  | 
 |   DependentTemplateName *DTN = Name.getAsDependentTemplateName(); | 
 |   assert(DTN && "Non-dependent template names must refer to template decls."); | 
 |   return DTN->CanonicalTemplateName; | 
 | } | 
 |  | 
 | NestedNameSpecifier * | 
 | ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) { | 
 |   if (!NNS)  | 
 |     return 0; | 
 |  | 
 |   switch (NNS->getKind()) { | 
 |   case NestedNameSpecifier::Identifier: | 
 |     // Canonicalize the prefix but keep the identifier the same. | 
 |     return NestedNameSpecifier::Create(*this,  | 
 |                          getCanonicalNestedNameSpecifier(NNS->getPrefix()), | 
 |                                        NNS->getAsIdentifier()); | 
 |  | 
 |   case NestedNameSpecifier::Namespace: | 
 |     // A namespace is canonical; build a nested-name-specifier with | 
 |     // this namespace and no prefix. | 
 |     return NestedNameSpecifier::Create(*this, 0, NNS->getAsNamespace()); | 
 |  | 
 |   case NestedNameSpecifier::TypeSpec: | 
 |   case NestedNameSpecifier::TypeSpecWithTemplate: { | 
 |     QualType T = getCanonicalType(QualType(NNS->getAsType(), 0)); | 
 |     NestedNameSpecifier *Prefix = 0; | 
 |  | 
 |     // FIXME: This isn't the right check! | 
 |     if (T->isDependentType()) | 
 |       Prefix = getCanonicalNestedNameSpecifier(NNS->getPrefix()); | 
 |  | 
 |     return NestedNameSpecifier::Create(*this, Prefix,  | 
 |                  NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,  | 
 |                                        T.getTypePtr()); | 
 |   } | 
 |  | 
 |   case NestedNameSpecifier::Global: | 
 |     // The global specifier is canonical and unique. | 
 |     return NNS; | 
 |   } | 
 |  | 
 |   // Required to silence a GCC warning | 
 |   return 0; | 
 | } | 
 |  | 
 |  | 
 | const ArrayType *ASTContext::getAsArrayType(QualType T) { | 
 |   // Handle the non-qualified case efficiently. | 
 |   if (T.getCVRQualifiers() == 0) { | 
 |     // Handle the common positive case fast. | 
 |     if (const ArrayType *AT = dyn_cast<ArrayType>(T)) | 
 |       return AT; | 
 |   } | 
 |    | 
 |   // Handle the common negative case fast, ignoring CVR qualifiers. | 
 |   QualType CType = T->getCanonicalTypeInternal(); | 
 |      | 
 |   // Make sure to look through type qualifiers (like ExtQuals) for the negative | 
 |   // test. | 
 |   if (!isa<ArrayType>(CType) && | 
 |       !isa<ArrayType>(CType.getUnqualifiedType())) | 
 |     return 0; | 
 |    | 
 |   // Apply any CVR qualifiers from the array type to the element type.  This | 
 |   // implements C99 6.7.3p8: "If the specification of an array type includes | 
 |   // any type qualifiers, the element type is so qualified, not the array type." | 
 |    | 
 |   // If we get here, we either have type qualifiers on the type, or we have | 
 |   // sugar such as a typedef in the way.  If we have type qualifiers on the type | 
 |   // we must propagate them down into the elemeng type. | 
 |   unsigned CVRQuals = T.getCVRQualifiers(); | 
 |   unsigned AddrSpace = 0; | 
 |   Type *Ty = T.getTypePtr(); | 
 |    | 
 |   // Rip through ExtQualType's and typedefs to get to a concrete type. | 
 |   while (1) { | 
 |     if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(Ty)) { | 
 |       AddrSpace = EXTQT->getAddressSpace(); | 
 |       Ty = EXTQT->getBaseType(); | 
 |     } else { | 
 |       T = Ty->getDesugaredType(); | 
 |       if (T.getTypePtr() == Ty && T.getCVRQualifiers() == 0) | 
 |         break; | 
 |       CVRQuals |= T.getCVRQualifiers(); | 
 |       Ty = T.getTypePtr(); | 
 |     } | 
 |   } | 
 |    | 
 |   // If we have a simple case, just return now. | 
 |   const ArrayType *ATy = dyn_cast<ArrayType>(Ty); | 
 |   if (ATy == 0 || (AddrSpace == 0 && CVRQuals == 0)) | 
 |     return ATy; | 
 |    | 
 |   // Otherwise, we have an array and we have qualifiers on it.  Push the | 
 |   // qualifiers into the array element type and return a new array type. | 
 |   // Get the canonical version of the element with the extra qualifiers on it. | 
 |   // This can recursively sink qualifiers through multiple levels of arrays. | 
 |   QualType NewEltTy = ATy->getElementType(); | 
 |   if (AddrSpace) | 
 |     NewEltTy = getAddrSpaceQualType(NewEltTy, AddrSpace); | 
 |   NewEltTy = NewEltTy.getWithAdditionalQualifiers(CVRQuals); | 
 |    | 
 |   if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(ATy)) | 
 |     return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(), | 
 |                                                 CAT->getSizeModifier(), | 
 |                                                 CAT->getIndexTypeQualifier())); | 
 |   if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(ATy)) | 
 |     return cast<ArrayType>(getIncompleteArrayType(NewEltTy, | 
 |                                                   IAT->getSizeModifier(), | 
 |                                                  IAT->getIndexTypeQualifier())); | 
 |  | 
 |   if (const DependentSizedArrayType *DSAT  | 
 |         = dyn_cast<DependentSizedArrayType>(ATy)) | 
 |     return cast<ArrayType>( | 
 |                      getDependentSizedArrayType(NewEltTy,  | 
 |                                                 DSAT->getSizeExpr(), | 
 |                                                 DSAT->getSizeModifier(), | 
 |                                                 DSAT->getIndexTypeQualifier())); | 
 |    | 
 |   const VariableArrayType *VAT = cast<VariableArrayType>(ATy); | 
 |   return cast<ArrayType>(getVariableArrayType(NewEltTy, VAT->getSizeExpr(), | 
 |                                               VAT->getSizeModifier(), | 
 |                                               VAT->getIndexTypeQualifier())); | 
 | } | 
 |  | 
 |  | 
 | /// getArrayDecayedType - Return the properly qualified result of decaying the | 
 | /// specified array type to a pointer.  This operation is non-trivial when | 
 | /// handling typedefs etc.  The canonical type of "T" must be an array type, | 
 | /// this returns a pointer to a properly qualified element of the array. | 
 | /// | 
 | /// See C99 6.7.5.3p7 and C99 6.3.2.1p3. | 
 | QualType ASTContext::getArrayDecayedType(QualType Ty) { | 
 |   // Get the element type with 'getAsArrayType' so that we don't lose any | 
 |   // typedefs in the element type of the array.  This also handles propagation | 
 |   // of type qualifiers from the array type into the element type if present | 
 |   // (C99 6.7.3p8). | 
 |   const ArrayType *PrettyArrayType = getAsArrayType(Ty); | 
 |   assert(PrettyArrayType && "Not an array type!"); | 
 |    | 
 |   QualType PtrTy = getPointerType(PrettyArrayType->getElementType()); | 
 |  | 
 |   // int x[restrict 4] ->  int *restrict | 
 |   return PtrTy.getQualifiedType(PrettyArrayType->getIndexTypeQualifier()); | 
 | } | 
 |  | 
 | QualType ASTContext::getBaseElementType(const VariableArrayType *VAT) { | 
 |   QualType ElemTy = VAT->getElementType(); | 
 |    | 
 |   if (const VariableArrayType *VAT = getAsVariableArrayType(ElemTy)) | 
 |     return getBaseElementType(VAT); | 
 |    | 
 |   return ElemTy; | 
 | } | 
 |  | 
 | /// getFloatingRank - Return a relative rank for floating point types. | 
 | /// This routine will assert if passed a built-in type that isn't a float. | 
 | static FloatingRank getFloatingRank(QualType T) { | 
 |   if (const ComplexType *CT = T->getAsComplexType()) | 
 |     return getFloatingRank(CT->getElementType()); | 
 |  | 
 |   assert(T->getAsBuiltinType() && "getFloatingRank(): not a floating type"); | 
 |   switch (T->getAsBuiltinType()->getKind()) { | 
 |   default: assert(0 && "getFloatingRank(): not a floating type"); | 
 |   case BuiltinType::Float:      return FloatRank; | 
 |   case BuiltinType::Double:     return DoubleRank; | 
 |   case BuiltinType::LongDouble: return LongDoubleRank; | 
 |   } | 
 | } | 
 |  | 
 | /// getFloatingTypeOfSizeWithinDomain - Returns a real floating  | 
 | /// point or a complex type (based on typeDomain/typeSize).  | 
 | /// 'typeDomain' is a real floating point or complex type. | 
 | /// 'typeSize' is a real floating point or complex type. | 
 | QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size, | 
 |                                                        QualType Domain) const { | 
 |   FloatingRank EltRank = getFloatingRank(Size); | 
 |   if (Domain->isComplexType()) { | 
 |     switch (EltRank) { | 
 |     default: assert(0 && "getFloatingRank(): illegal value for rank"); | 
 |     case FloatRank:      return FloatComplexTy; | 
 |     case DoubleRank:     return DoubleComplexTy; | 
 |     case LongDoubleRank: return LongDoubleComplexTy; | 
 |     } | 
 |   } | 
 |  | 
 |   assert(Domain->isRealFloatingType() && "Unknown domain!"); | 
 |   switch (EltRank) { | 
 |   default: assert(0 && "getFloatingRank(): illegal value for rank"); | 
 |   case FloatRank:      return FloatTy; | 
 |   case DoubleRank:     return DoubleTy; | 
 |   case LongDoubleRank: return LongDoubleTy; | 
 |   } | 
 | } | 
 |  | 
 | /// getFloatingTypeOrder - Compare the rank of the two specified floating | 
 | /// point types, ignoring the domain of the type (i.e. 'double' == | 
 | /// '_Complex double').  If LHS > RHS, return 1.  If LHS == RHS, return 0. If | 
 | /// LHS < RHS, return -1.  | 
 | int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) { | 
 |   FloatingRank LHSR = getFloatingRank(LHS); | 
 |   FloatingRank RHSR = getFloatingRank(RHS); | 
 |    | 
 |   if (LHSR == RHSR) | 
 |     return 0; | 
 |   if (LHSR > RHSR) | 
 |     return 1; | 
 |   return -1; | 
 | } | 
 |  | 
 | /// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This | 
 | /// routine will assert if passed a built-in type that isn't an integer or enum, | 
 | /// or if it is not canonicalized. | 
 | unsigned ASTContext::getIntegerRank(Type *T) { | 
 |   assert(T->isCanonical() && "T should be canonicalized"); | 
 |   if (EnumType* ET = dyn_cast<EnumType>(T)) | 
 |     T = ET->getDecl()->getIntegerType().getTypePtr(); | 
 |  | 
 |   // There are two things which impact the integer rank: the width, and | 
 |   // the ordering of builtins.  The builtin ordering is encoded in the | 
 |   // bottom three bits; the width is encoded in the bits above that. | 
 |   if (FixedWidthIntType* FWIT = dyn_cast<FixedWidthIntType>(T)) { | 
 |     return FWIT->getWidth() << 3; | 
 |   } | 
 |  | 
 |   switch (cast<BuiltinType>(T)->getKind()) { | 
 |   default: assert(0 && "getIntegerRank(): not a built-in integer"); | 
 |   case BuiltinType::Bool: | 
 |     return 1 + (getIntWidth(BoolTy) << 3); | 
 |   case BuiltinType::Char_S: | 
 |   case BuiltinType::Char_U: | 
 |   case BuiltinType::SChar: | 
 |   case BuiltinType::UChar: | 
 |     return 2 + (getIntWidth(CharTy) << 3); | 
 |   case BuiltinType::Short: | 
 |   case BuiltinType::UShort: | 
 |     return 3 + (getIntWidth(ShortTy) << 3); | 
 |   case BuiltinType::Int: | 
 |   case BuiltinType::UInt: | 
 |     return 4 + (getIntWidth(IntTy) << 3); | 
 |   case BuiltinType::Long: | 
 |   case BuiltinType::ULong: | 
 |     return 5 + (getIntWidth(LongTy) << 3); | 
 |   case BuiltinType::LongLong: | 
 |   case BuiltinType::ULongLong: | 
 |     return 6 + (getIntWidth(LongLongTy) << 3); | 
 |   case BuiltinType::Int128: | 
 |   case BuiltinType::UInt128: | 
 |     return 7 + (getIntWidth(Int128Ty) << 3); | 
 |   } | 
 | } | 
 |  | 
 | /// getIntegerTypeOrder - Returns the highest ranked integer type:  | 
 | /// C99 6.3.1.8p1.  If LHS > RHS, return 1.  If LHS == RHS, return 0. If | 
 | /// LHS < RHS, return -1.  | 
 | int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) { | 
 |   Type *LHSC = getCanonicalType(LHS).getTypePtr(); | 
 |   Type *RHSC = getCanonicalType(RHS).getTypePtr(); | 
 |   if (LHSC == RHSC) return 0; | 
 |    | 
 |   bool LHSUnsigned = LHSC->isUnsignedIntegerType(); | 
 |   bool RHSUnsigned = RHSC->isUnsignedIntegerType(); | 
 |    | 
 |   unsigned LHSRank = getIntegerRank(LHSC); | 
 |   unsigned RHSRank = getIntegerRank(RHSC); | 
 |    | 
 |   if (LHSUnsigned == RHSUnsigned) {  // Both signed or both unsigned. | 
 |     if (LHSRank == RHSRank) return 0; | 
 |     return LHSRank > RHSRank ? 1 : -1; | 
 |   } | 
 |    | 
 |   // Otherwise, the LHS is signed and the RHS is unsigned or visa versa. | 
 |   if (LHSUnsigned) { | 
 |     // If the unsigned [LHS] type is larger, return it. | 
 |     if (LHSRank >= RHSRank) | 
 |       return 1; | 
 |      | 
 |     // If the signed type can represent all values of the unsigned type, it | 
 |     // wins.  Because we are dealing with 2's complement and types that are | 
 |     // powers of two larger than each other, this is always safe.  | 
 |     return -1; | 
 |   } | 
 |  | 
 |   // If the unsigned [RHS] type is larger, return it. | 
 |   if (RHSRank >= LHSRank) | 
 |     return -1; | 
 |    | 
 |   // If the signed type can represent all values of the unsigned type, it | 
 |   // wins.  Because we are dealing with 2's complement and types that are | 
 |   // powers of two larger than each other, this is always safe.  | 
 |   return 1; | 
 | } | 
 |  | 
 | // getCFConstantStringType - Return the type used for constant CFStrings.  | 
 | QualType ASTContext::getCFConstantStringType() { | 
 |   if (!CFConstantStringTypeDecl) { | 
 |     CFConstantStringTypeDecl =  | 
 |       RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),  | 
 |                          &Idents.get("NSConstantString")); | 
 |     QualType FieldTypes[4]; | 
 |    | 
 |     // const int *isa; | 
 |     FieldTypes[0] = getPointerType(IntTy.getQualifiedType(QualType::Const));   | 
 |     // int flags; | 
 |     FieldTypes[1] = IntTy; | 
 |     // const char *str; | 
 |     FieldTypes[2] = getPointerType(CharTy.getQualifiedType(QualType::Const));   | 
 |     // long length; | 
 |     FieldTypes[3] = LongTy;   | 
 |    | 
 |     // Create fields | 
 |     for (unsigned i = 0; i < 4; ++i) { | 
 |       FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl,  | 
 |                                            SourceLocation(), 0, | 
 |                                            FieldTypes[i], /*BitWidth=*/0,  | 
 |                                            /*Mutable=*/false); | 
 |       CFConstantStringTypeDecl->addDecl(*this, Field); | 
 |     } | 
 |  | 
 |     CFConstantStringTypeDecl->completeDefinition(*this); | 
 |   } | 
 |    | 
 |   return getTagDeclType(CFConstantStringTypeDecl); | 
 | } | 
 |  | 
 | void ASTContext::setCFConstantStringType(QualType T) { | 
 |   const RecordType *Rec = T->getAsRecordType(); | 
 |   assert(Rec && "Invalid CFConstantStringType"); | 
 |   CFConstantStringTypeDecl = Rec->getDecl(); | 
 | } | 
 |  | 
 | QualType ASTContext::getObjCFastEnumerationStateType() | 
 | { | 
 |   if (!ObjCFastEnumerationStateTypeDecl) { | 
 |     ObjCFastEnumerationStateTypeDecl = | 
 |       RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), | 
 |                          &Idents.get("__objcFastEnumerationState")); | 
 |      | 
 |     QualType FieldTypes[] = { | 
 |       UnsignedLongTy, | 
 |       getPointerType(ObjCIdType), | 
 |       getPointerType(UnsignedLongTy), | 
 |       getConstantArrayType(UnsignedLongTy, | 
 |                            llvm::APInt(32, 5), ArrayType::Normal, 0) | 
 |     }; | 
 |      | 
 |     for (size_t i = 0; i < 4; ++i) { | 
 |       FieldDecl *Field = FieldDecl::Create(*this,  | 
 |                                            ObjCFastEnumerationStateTypeDecl,  | 
 |                                            SourceLocation(), 0,  | 
 |                                            FieldTypes[i], /*BitWidth=*/0,  | 
 |                                            /*Mutable=*/false); | 
 |       ObjCFastEnumerationStateTypeDecl->addDecl(*this, Field); | 
 |     } | 
 |      | 
 |     ObjCFastEnumerationStateTypeDecl->completeDefinition(*this); | 
 |   } | 
 |    | 
 |   return getTagDeclType(ObjCFastEnumerationStateTypeDecl); | 
 | } | 
 |  | 
 | void ASTContext::setObjCFastEnumerationStateType(QualType T) { | 
 |   const RecordType *Rec = T->getAsRecordType(); | 
 |   assert(Rec && "Invalid ObjCFAstEnumerationStateType"); | 
 |   ObjCFastEnumerationStateTypeDecl = Rec->getDecl(); | 
 | } | 
 |  | 
 | // This returns true if a type has been typedefed to BOOL: | 
 | // typedef <type> BOOL; | 
 | static bool isTypeTypedefedAsBOOL(QualType T) { | 
 |   if (const TypedefType *TT = dyn_cast<TypedefType>(T)) | 
 |     if (IdentifierInfo *II = TT->getDecl()->getIdentifier()) | 
 |       return II->isStr("BOOL"); | 
 |          | 
 |   return false; | 
 | } | 
 |  | 
 | /// getObjCEncodingTypeSize returns size of type for objective-c encoding | 
 | /// purpose. | 
 | int ASTContext::getObjCEncodingTypeSize(QualType type) { | 
 |   uint64_t sz = getTypeSize(type); | 
 |    | 
 |   // Make all integer and enum types at least as large as an int | 
 |   if (sz > 0 && type->isIntegralType()) | 
 |     sz = std::max(sz, getTypeSize(IntTy)); | 
 |   // Treat arrays as pointers, since that's how they're passed in. | 
 |   else if (type->isArrayType()) | 
 |     sz = getTypeSize(VoidPtrTy); | 
 |   return sz / getTypeSize(CharTy); | 
 | } | 
 |  | 
 | /// getObjCEncodingForMethodDecl - Return the encoded type for this method | 
 | /// declaration. | 
 | void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,  | 
 |                                               std::string& S) { | 
 |   // FIXME: This is not very efficient. | 
 |   // Encode type qualifer, 'in', 'inout', etc. for the return type. | 
 |   getObjCEncodingForTypeQualifier(Decl->getObjCDeclQualifier(), S); | 
 |   // Encode result type. | 
 |   getObjCEncodingForType(Decl->getResultType(), S); | 
 |   // Compute size of all parameters. | 
 |   // Start with computing size of a pointer in number of bytes. | 
 |   // FIXME: There might(should) be a better way of doing this computation! | 
 |   SourceLocation Loc; | 
 |   int PtrSize = getTypeSize(VoidPtrTy) / getTypeSize(CharTy); | 
 |   // The first two arguments (self and _cmd) are pointers; account for | 
 |   // their size. | 
 |   int ParmOffset = 2 * PtrSize; | 
 |   for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), | 
 |        E = Decl->param_end(); PI != E; ++PI) { | 
 |     QualType PType = (*PI)->getType(); | 
 |     int sz = getObjCEncodingTypeSize(PType); | 
 |     assert (sz > 0 && "getObjCEncodingForMethodDecl - Incomplete param type"); | 
 |     ParmOffset += sz; | 
 |   } | 
 |   S += llvm::utostr(ParmOffset); | 
 |   S += "@0:"; | 
 |   S += llvm::utostr(PtrSize); | 
 |    | 
 |   // Argument types. | 
 |   ParmOffset = 2 * PtrSize; | 
 |   for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), | 
 |        E = Decl->param_end(); PI != E; ++PI) { | 
 |     ParmVarDecl *PVDecl = *PI; | 
 |     QualType PType = PVDecl->getOriginalType();  | 
 |     if (const ArrayType *AT = | 
 |           dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { | 
 |       // Use array's original type only if it has known number of | 
 |       // elements. | 
 |       if (!isa<ConstantArrayType>(AT)) | 
 |         PType = PVDecl->getType(); | 
 |     } else if (PType->isFunctionType()) | 
 |       PType = PVDecl->getType(); | 
 |     // Process argument qualifiers for user supplied arguments; such as, | 
 |     // 'in', 'inout', etc. | 
 |     getObjCEncodingForTypeQualifier(PVDecl->getObjCDeclQualifier(), S); | 
 |     getObjCEncodingForType(PType, S); | 
 |     S += llvm::utostr(ParmOffset); | 
 |     ParmOffset += getObjCEncodingTypeSize(PType); | 
 |   } | 
 | } | 
 |  | 
 | /// getObjCEncodingForPropertyDecl - Return the encoded type for this | 
 | /// property declaration. If non-NULL, Container must be either an | 
 | /// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be | 
 | /// NULL when getting encodings for protocol properties. | 
 | /// Property attributes are stored as a comma-delimited C string. The simple  | 
 | /// attributes readonly and bycopy are encoded as single characters. The  | 
 | /// parametrized attributes, getter=name, setter=name, and ivar=name, are  | 
 | /// encoded as single characters, followed by an identifier. Property types  | 
 | /// are also encoded as a parametrized attribute. The characters used to encode  | 
 | /// these attributes are defined by the following enumeration: | 
 | /// @code | 
 | /// enum PropertyAttributes { | 
 | /// kPropertyReadOnly = 'R',   // property is read-only. | 
 | /// kPropertyBycopy = 'C',     // property is a copy of the value last assigned | 
 | /// kPropertyByref = '&',  // property is a reference to the value last assigned | 
 | /// kPropertyDynamic = 'D',    // property is dynamic | 
 | /// kPropertyGetter = 'G',     // followed by getter selector name | 
 | /// kPropertySetter = 'S',     // followed by setter selector name | 
 | /// kPropertyInstanceVariable = 'V'  // followed by instance variable  name | 
 | /// kPropertyType = 't'              // followed by old-style type encoding. | 
 | /// kPropertyWeak = 'W'              // 'weak' property | 
 | /// kPropertyStrong = 'P'            // property GC'able | 
 | /// kPropertyNonAtomic = 'N'         // property non-atomic | 
 | /// }; | 
 | /// @endcode | 
 | void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,  | 
 |                                                 const Decl *Container, | 
 |                                                 std::string& S) { | 
 |   // Collect information from the property implementation decl(s). | 
 |   bool Dynamic = false; | 
 |   ObjCPropertyImplDecl *SynthesizePID = 0; | 
 |  | 
 |   // FIXME: Duplicated code due to poor abstraction. | 
 |   if (Container) { | 
 |     if (const ObjCCategoryImplDecl *CID =  | 
 |         dyn_cast<ObjCCategoryImplDecl>(Container)) { | 
 |       for (ObjCCategoryImplDecl::propimpl_iterator | 
 |              i = CID->propimpl_begin(*this), e = CID->propimpl_end(*this); | 
 |            i != e; ++i) { | 
 |         ObjCPropertyImplDecl *PID = *i; | 
 |         if (PID->getPropertyDecl() == PD) { | 
 |           if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) { | 
 |             Dynamic = true; | 
 |           } else { | 
 |             SynthesizePID = PID; | 
 |           } | 
 |         } | 
 |       } | 
 |     } else { | 
 |       const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container); | 
 |       for (ObjCCategoryImplDecl::propimpl_iterator | 
 |              i = OID->propimpl_begin(*this), e = OID->propimpl_end(*this); | 
 |            i != e; ++i) { | 
 |         ObjCPropertyImplDecl *PID = *i; | 
 |         if (PID->getPropertyDecl() == PD) { | 
 |           if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) { | 
 |             Dynamic = true; | 
 |           } else { | 
 |             SynthesizePID = PID; | 
 |           } | 
 |         } | 
 |       }       | 
 |     } | 
 |   } | 
 |  | 
 |   // FIXME: This is not very efficient. | 
 |   S = "T"; | 
 |  | 
 |   // Encode result type. | 
 |   // GCC has some special rules regarding encoding of properties which | 
 |   // closely resembles encoding of ivars. | 
 |   getObjCEncodingForTypeImpl(PD->getType(), S, true, true, 0,  | 
 |                              true /* outermost type */, | 
 |                              true /* encoding for property */); | 
 |  | 
 |   if (PD->isReadOnly()) { | 
 |     S += ",R"; | 
 |   } else { | 
 |     switch (PD->getSetterKind()) { | 
 |     case ObjCPropertyDecl::Assign: break; | 
 |     case ObjCPropertyDecl::Copy:   S += ",C"; break; | 
 |     case ObjCPropertyDecl::Retain: S += ",&"; break;       | 
 |     } | 
 |   } | 
 |  | 
 |   // It really isn't clear at all what this means, since properties | 
 |   // are "dynamic by default". | 
 |   if (Dynamic) | 
 |     S += ",D"; | 
 |  | 
 |   if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic) | 
 |     S += ",N"; | 
 |    | 
 |   if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) { | 
 |     S += ",G"; | 
 |     S += PD->getGetterName().getAsString(); | 
 |   } | 
 |  | 
 |   if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) { | 
 |     S += ",S"; | 
 |     S += PD->getSetterName().getAsString(); | 
 |   } | 
 |  | 
 |   if (SynthesizePID) { | 
 |     const ObjCIvarDecl *OID = SynthesizePID->getPropertyIvarDecl(); | 
 |     S += ",V"; | 
 |     S += OID->getNameAsString(); | 
 |   } | 
 |  | 
 |   // FIXME: OBJCGC: weak & strong | 
 | } | 
 |  | 
 | /// getLegacyIntegralTypeEncoding - | 
 | /// Another legacy compatibility encoding: 32-bit longs are encoded as  | 
 | /// 'l' or 'L' , but not always.  For typedefs, we need to use  | 
 | /// 'i' or 'I' instead if encoding a struct field, or a pointer! | 
 | /// | 
 | void ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const { | 
 |   if (dyn_cast<TypedefType>(PointeeTy.getTypePtr())) { | 
 |     if (const BuiltinType *BT = PointeeTy->getAsBuiltinType()) { | 
 |       if (BT->getKind() == BuiltinType::ULong && | 
 |           ((const_cast<ASTContext *>(this))->getIntWidth(PointeeTy) == 32)) | 
 |         PointeeTy = UnsignedIntTy; | 
 |       else  | 
 |         if (BT->getKind() == BuiltinType::Long && | 
 |             ((const_cast<ASTContext *>(this))->getIntWidth(PointeeTy) == 32)) | 
 |           PointeeTy = IntTy; | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | void ASTContext::getObjCEncodingForType(QualType T, std::string& S, | 
 |                                         const FieldDecl *Field) { | 
 |   // We follow the behavior of gcc, expanding structures which are | 
 |   // directly pointed to, and expanding embedded structures. Note that | 
 |   // these rules are sufficient to prevent recursive encoding of the | 
 |   // same type. | 
 |   getObjCEncodingForTypeImpl(T, S, true, true, Field,  | 
 |                              true /* outermost type */); | 
 | } | 
 |  | 
 | static void EncodeBitField(const ASTContext *Context, std::string& S,  | 
 |                            const FieldDecl *FD) { | 
 |   const Expr *E = FD->getBitWidth(); | 
 |   assert(E && "bitfield width not there - getObjCEncodingForTypeImpl"); | 
 |   ASTContext *Ctx = const_cast<ASTContext*>(Context); | 
 |   unsigned N = E->EvaluateAsInt(*Ctx).getZExtValue(); | 
 |   S += 'b'; | 
 |   S += llvm::utostr(N); | 
 | } | 
 |  | 
 | void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, | 
 |                                             bool ExpandPointedToStructures, | 
 |                                             bool ExpandStructures, | 
 |                                             const FieldDecl *FD, | 
 |                                             bool OutermostType, | 
 |                                             bool EncodingProperty) { | 
 |   if (const BuiltinType *BT = T->getAsBuiltinType()) { | 
 |     if (FD && FD->isBitField()) { | 
 |       EncodeBitField(this, S, FD); | 
 |     } | 
 |     else { | 
 |       char encoding; | 
 |       switch (BT->getKind()) { | 
 |       default: assert(0 && "Unhandled builtin type kind");           | 
 |       case BuiltinType::Void:       encoding = 'v'; break; | 
 |       case BuiltinType::Bool:       encoding = 'B'; break; | 
 |       case BuiltinType::Char_U: | 
 |       case BuiltinType::UChar:      encoding = 'C'; break; | 
 |       case BuiltinType::UShort:     encoding = 'S'; break; | 
 |       case BuiltinType::UInt:       encoding = 'I'; break; | 
 |       case BuiltinType::ULong:       | 
 |           encoding =  | 
 |             (const_cast<ASTContext *>(this))->getIntWidth(T) == 32 ? 'L' : 'Q';  | 
 |           break; | 
 |       case BuiltinType::UInt128:    encoding = 'T'; break; | 
 |       case BuiltinType::ULongLong:  encoding = 'Q'; break; | 
 |       case BuiltinType::Char_S: | 
 |       case BuiltinType::SChar:      encoding = 'c'; break; | 
 |       case BuiltinType::Short:      encoding = 's'; break; | 
 |       case BuiltinType::Int:        encoding = 'i'; break; | 
 |       case BuiltinType::Long:        | 
 |         encoding =  | 
 |           (const_cast<ASTContext *>(this))->getIntWidth(T) == 32 ? 'l' : 'q';  | 
 |         break; | 
 |       case BuiltinType::LongLong:   encoding = 'q'; break; | 
 |       case BuiltinType::Int128:     encoding = 't'; break; | 
 |       case BuiltinType::Float:      encoding = 'f'; break; | 
 |       case BuiltinType::Double:     encoding = 'd'; break; | 
 |       case BuiltinType::LongDouble: encoding = 'd'; break; | 
 |       } | 
 |      | 
 |       S += encoding; | 
 |     } | 
 |   } else if (const ComplexType *CT = T->getAsComplexType()) { | 
 |     S += 'j'; | 
 |     getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, 0, false,  | 
 |                                false); | 
 |   } else if (T->isObjCQualifiedIdType()) { | 
 |     getObjCEncodingForTypeImpl(getObjCIdType(), S,  | 
 |                                ExpandPointedToStructures, | 
 |                                ExpandStructures, FD); | 
 |     if (FD || EncodingProperty) { | 
 |       // Note that we do extended encoding of protocol qualifer list | 
 |       // Only when doing ivar or property encoding. | 
 |       const ObjCQualifiedIdType *QIDT = T->getAsObjCQualifiedIdType(); | 
 |       S += '"'; | 
 |       for (ObjCQualifiedIdType::qual_iterator I = QIDT->qual_begin(), | 
 |            E = QIDT->qual_end(); I != E; ++I) { | 
 |         S += '<'; | 
 |         S += (*I)->getNameAsString(); | 
 |         S += '>'; | 
 |       } | 
 |       S += '"'; | 
 |     } | 
 |     return; | 
 |   } | 
 |   else if (const PointerType *PT = T->getAsPointerType()) { | 
 |     QualType PointeeTy = PT->getPointeeType(); | 
 |     bool isReadOnly = false; | 
 |     // For historical/compatibility reasons, the read-only qualifier of the | 
 |     // pointee gets emitted _before_ the '^'.  The read-only qualifier of | 
 |     // the pointer itself gets ignored, _unless_ we are looking at a typedef! | 
 |     // Also, do not emit the 'r' for anything but the outermost type!  | 
 |     if (dyn_cast<TypedefType>(T.getTypePtr())) { | 
 |       if (OutermostType && T.isConstQualified()) { | 
 |         isReadOnly = true; | 
 |         S += 'r'; | 
 |       } | 
 |     } | 
 |     else if (OutermostType) { | 
 |       QualType P = PointeeTy; | 
 |       while (P->getAsPointerType()) | 
 |         P = P->getAsPointerType()->getPointeeType(); | 
 |       if (P.isConstQualified()) { | 
 |         isReadOnly = true; | 
 |         S += 'r'; | 
 |       } | 
 |     } | 
 |     if (isReadOnly) { | 
 |       // Another legacy compatibility encoding. Some ObjC qualifier and type | 
 |       // combinations need to be rearranged. | 
 |       // Rewrite "in const" from "nr" to "rn" | 
 |       const char * s = S.c_str(); | 
 |       int len = S.length(); | 
 |       if (len >= 2 && s[len-2] == 'n' && s[len-1] == 'r') { | 
 |         std::string replace = "rn"; | 
 |         S.replace(S.end()-2, S.end(), replace); | 
 |       } | 
 |     } | 
 |     if (isObjCIdStructType(PointeeTy)) { | 
 |       S += '@'; | 
 |       return; | 
 |     } | 
 |     else if (PointeeTy->isObjCInterfaceType()) { | 
 |       if (!EncodingProperty && | 
 |           isa<TypedefType>(PointeeTy.getTypePtr())) { | 
 |         // Another historical/compatibility reason. | 
 |         // We encode the underlying type which comes out as  | 
 |         // {...}; | 
 |         S += '^'; | 
 |         getObjCEncodingForTypeImpl(PointeeTy, S,  | 
 |                                    false, ExpandPointedToStructures,  | 
 |                                    NULL); | 
 |         return; | 
 |       } | 
 |       S += '@'; | 
 |       if (FD || EncodingProperty) { | 
 |         const ObjCInterfaceType *OIT =  | 
 |                 PointeeTy.getUnqualifiedType()->getAsObjCInterfaceType(); | 
 |         ObjCInterfaceDecl *OI = OIT->getDecl(); | 
 |         S += '"'; | 
 |         S += OI->getNameAsCString(); | 
 |         for (ObjCInterfaceType::qual_iterator I = OIT->qual_begin(), | 
 |              E = OIT->qual_end(); I != E; ++I) { | 
 |           S += '<'; | 
 |           S += (*I)->getNameAsString(); | 
 |           S += '>'; | 
 |         }  | 
 |         S += '"'; | 
 |       } | 
 |       return; | 
 |     } else if (isObjCClassStructType(PointeeTy)) { | 
 |       S += '#'; | 
 |       return; | 
 |     } else if (isObjCSelType(PointeeTy)) { | 
 |       S += ':'; | 
 |       return; | 
 |     } | 
 |      | 
 |     if (PointeeTy->isCharType()) { | 
 |       // char pointer types should be encoded as '*' unless it is a | 
 |       // type that has been typedef'd to 'BOOL'. | 
 |       if (!isTypeTypedefedAsBOOL(PointeeTy)) { | 
 |         S += '*'; | 
 |         return; | 
 |       } | 
 |     } | 
 |      | 
 |     S += '^'; | 
 |     getLegacyIntegralTypeEncoding(PointeeTy); | 
 |  | 
 |     getObjCEncodingForTypeImpl(PointeeTy, S,  | 
 |                                false, ExpandPointedToStructures,  | 
 |                                NULL); | 
 |   } else if (const ArrayType *AT = | 
 |                // Ignore type qualifiers etc. | 
 |                dyn_cast<ArrayType>(T->getCanonicalTypeInternal())) { | 
 |     if (isa<IncompleteArrayType>(AT)) { | 
 |       // Incomplete arrays are encoded as a pointer to the array element. | 
 |       S += '^'; | 
 |  | 
 |       getObjCEncodingForTypeImpl(AT->getElementType(), S,  | 
 |                                  false, ExpandStructures, FD); | 
 |     } else { | 
 |       S += '['; | 
 |      | 
 |       if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) | 
 |         S += llvm::utostr(CAT->getSize().getZExtValue()); | 
 |       else { | 
 |         //Variable length arrays are encoded as a regular array with 0 elements. | 
 |         assert(isa<VariableArrayType>(AT) && "Unknown array type!"); | 
 |         S += '0'; | 
 |       } | 
 |      | 
 |       getObjCEncodingForTypeImpl(AT->getElementType(), S,  | 
 |                                  false, ExpandStructures, FD); | 
 |       S += ']'; | 
 |     } | 
 |   } else if (T->getAsFunctionType()) { | 
 |     S += '?'; | 
 |   } else if (const RecordType *RTy = T->getAsRecordType()) { | 
 |     RecordDecl *RDecl = RTy->getDecl(); | 
 |     S += RDecl->isUnion() ? '(' : '{'; | 
 |     // Anonymous structures print as '?' | 
 |     if (const IdentifierInfo *II = RDecl->getIdentifier()) { | 
 |       S += II->getName(); | 
 |     } else { | 
 |       S += '?'; | 
 |     } | 
 |     if (ExpandStructures) { | 
 |       S += '='; | 
 |       for (RecordDecl::field_iterator Field = RDecl->field_begin(*this), | 
 |                                    FieldEnd = RDecl->field_end(*this); | 
 |            Field != FieldEnd; ++Field) { | 
 |         if (FD) { | 
 |           S += '"'; | 
 |           S += Field->getNameAsString(); | 
 |           S += '"'; | 
 |         } | 
 |          | 
 |         // Special case bit-fields. | 
 |         if (Field->isBitField()) { | 
 |           getObjCEncodingForTypeImpl(Field->getType(), S, false, true,  | 
 |                                      (*Field)); | 
 |         } else { | 
 |           QualType qt = Field->getType(); | 
 |           getLegacyIntegralTypeEncoding(qt); | 
 |           getObjCEncodingForTypeImpl(qt, S, false, true,  | 
 |                                      FD); | 
 |         } | 
 |       } | 
 |     } | 
 |     S += RDecl->isUnion() ? ')' : '}'; | 
 |   } else if (T->isEnumeralType()) { | 
 |     if (FD && FD->isBitField()) | 
 |       EncodeBitField(this, S, FD); | 
 |     else | 
 |       S += 'i'; | 
 |   } else if (T->isBlockPointerType()) { | 
 |     S += "@?"; // Unlike a pointer-to-function, which is "^?". | 
 |   } else if (T->isObjCInterfaceType()) { | 
 |     // @encode(class_name) | 
 |     ObjCInterfaceDecl *OI = T->getAsObjCInterfaceType()->getDecl(); | 
 |     S += '{'; | 
 |     const IdentifierInfo *II = OI->getIdentifier(); | 
 |     S += II->getName(); | 
 |     S += '='; | 
 |     llvm::SmallVector<FieldDecl*, 32> RecFields; | 
 |     CollectObjCIvars(OI, RecFields); | 
 |     for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { | 
 |       if (RecFields[i]->isBitField()) | 
 |         getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,  | 
 |                                    RecFields[i]); | 
 |       else | 
 |         getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true,  | 
 |                                    FD); | 
 |     } | 
 |     S += '}'; | 
 |   } | 
 |   else | 
 |     assert(0 && "@encode for type not implemented!"); | 
 | } | 
 |  | 
 | void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,  | 
 |                                                  std::string& S) const { | 
 |   if (QT & Decl::OBJC_TQ_In) | 
 |     S += 'n'; | 
 |   if (QT & Decl::OBJC_TQ_Inout) | 
 |     S += 'N'; | 
 |   if (QT & Decl::OBJC_TQ_Out) | 
 |     S += 'o'; | 
 |   if (QT & Decl::OBJC_TQ_Bycopy) | 
 |     S += 'O'; | 
 |   if (QT & Decl::OBJC_TQ_Byref) | 
 |     S += 'R'; | 
 |   if (QT & Decl::OBJC_TQ_Oneway) | 
 |     S += 'V'; | 
 | } | 
 |  | 
 | void ASTContext::setBuiltinVaListType(QualType T) | 
 | { | 
 |   assert(BuiltinVaListType.isNull() && "__builtin_va_list type already set!"); | 
 |      | 
 |   BuiltinVaListType = T; | 
 | } | 
 |  | 
 | void ASTContext::setObjCIdType(QualType T) | 
 | { | 
 |   ObjCIdType = T; | 
 |  | 
 |   const TypedefType *TT = T->getAsTypedefType(); | 
 |   if (!TT) | 
 |     return; | 
 |  | 
 |   TypedefDecl *TD = TT->getDecl(); | 
 |  | 
 |   // typedef struct objc_object *id; | 
 |   const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType(); | 
 |   // User error - caller will issue diagnostics. | 
 |   if (!ptr) | 
 |     return; | 
 |   const RecordType *rec = ptr->getPointeeType()->getAsStructureType(); | 
 |   // User error - caller will issue diagnostics. | 
 |   if (!rec) | 
 |     return; | 
 |   IdStructType = rec; | 
 | } | 
 |  | 
 | void ASTContext::setObjCSelType(QualType T) | 
 | { | 
 |   ObjCSelType = T; | 
 |  | 
 |   const TypedefType *TT = T->getAsTypedefType(); | 
 |   if (!TT) | 
 |     return; | 
 |   TypedefDecl *TD = TT->getDecl(); | 
 |  | 
 |   // typedef struct objc_selector *SEL; | 
 |   const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType(); | 
 |   if (!ptr) | 
 |     return; | 
 |   const RecordType *rec = ptr->getPointeeType()->getAsStructureType(); | 
 |   if (!rec) | 
 |     return; | 
 |   SelStructType = rec; | 
 | } | 
 |  | 
 | void ASTContext::setObjCProtoType(QualType QT) | 
 | { | 
 |   ObjCProtoType = QT; | 
 | } | 
 |  | 
 | void ASTContext::setObjCClassType(QualType T) | 
 | { | 
 |   ObjCClassType = T; | 
 |  | 
 |   const TypedefType *TT = T->getAsTypedefType(); | 
 |   if (!TT) | 
 |     return; | 
 |   TypedefDecl *TD = TT->getDecl(); | 
 |  | 
 |   // typedef struct objc_class *Class; | 
 |   const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType(); | 
 |   assert(ptr && "'Class' incorrectly typed"); | 
 |   const RecordType *rec = ptr->getPointeeType()->getAsStructureType(); | 
 |   assert(rec && "'Class' incorrectly typed"); | 
 |   ClassStructType = rec; | 
 | } | 
 |  | 
 | void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) { | 
 |   assert(ObjCConstantStringType.isNull() &&  | 
 |          "'NSConstantString' type already set!"); | 
 |    | 
 |   ObjCConstantStringType = getObjCInterfaceType(Decl); | 
 | } | 
 |  | 
 | /// \brief Retrieve the template name that represents a qualified | 
 | /// template name such as \c std::vector. | 
 | TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,  | 
 |                                                   bool TemplateKeyword, | 
 |                                                   TemplateDecl *Template) { | 
 |   llvm::FoldingSetNodeID ID; | 
 |   QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   QualifiedTemplateName *QTN = | 
 |     QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos); | 
 |   if (!QTN) { | 
 |     QTN = new (*this,4) QualifiedTemplateName(NNS, TemplateKeyword, Template); | 
 |     QualifiedTemplateNames.InsertNode(QTN, InsertPos); | 
 |   } | 
 |  | 
 |   return TemplateName(QTN); | 
 | } | 
 |  | 
 | /// \brief Retrieve the template name that represents a dependent | 
 | /// template name such as \c MetaFun::template apply. | 
 | TemplateName ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,  | 
 |                                                   const IdentifierInfo *Name) { | 
 |   assert(NNS->isDependent() && "Nested name specifier must be dependent"); | 
 |  | 
 |   llvm::FoldingSetNodeID ID; | 
 |   DependentTemplateName::Profile(ID, NNS, Name); | 
 |  | 
 |   void *InsertPos = 0; | 
 |   DependentTemplateName *QTN = | 
 |     DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); | 
 |  | 
 |   if (QTN) | 
 |     return TemplateName(QTN); | 
 |  | 
 |   NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); | 
 |   if (CanonNNS == NNS) { | 
 |     QTN = new (*this,4) DependentTemplateName(NNS, Name); | 
 |   } else { | 
 |     TemplateName Canon = getDependentTemplateName(CanonNNS, Name); | 
 |     QTN = new (*this,4) DependentTemplateName(NNS, Name, Canon); | 
 |   } | 
 |  | 
 |   DependentTemplateNames.InsertNode(QTN, InsertPos); | 
 |   return TemplateName(QTN); | 
 | } | 
 |  | 
 | /// getFromTargetType - Given one of the integer types provided by | 
 | /// TargetInfo, produce the corresponding type. The unsigned @p Type | 
 | /// is actually a value of type @c TargetInfo::IntType. | 
 | QualType ASTContext::getFromTargetType(unsigned Type) const { | 
 |   switch (Type) { | 
 |   case TargetInfo::NoInt: return QualType();  | 
 |   case TargetInfo::SignedShort: return ShortTy; | 
 |   case TargetInfo::UnsignedShort: return UnsignedShortTy; | 
 |   case TargetInfo::SignedInt: return IntTy; | 
 |   case TargetInfo::UnsignedInt: return UnsignedIntTy; | 
 |   case TargetInfo::SignedLong: return LongTy; | 
 |   case TargetInfo::UnsignedLong: return UnsignedLongTy; | 
 |   case TargetInfo::SignedLongLong: return LongLongTy; | 
 |   case TargetInfo::UnsignedLongLong: return UnsignedLongLongTy; | 
 |   } | 
 |  | 
 |   assert(false && "Unhandled TargetInfo::IntType value"); | 
 |   return QualType(); | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | //                        Type Predicates. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | /// isObjCNSObjectType - Return true if this is an NSObject object using | 
 | /// NSObject attribute on a c-style pointer type. | 
 | /// FIXME - Make it work directly on types. | 
 | /// | 
 | bool ASTContext::isObjCNSObjectType(QualType Ty) const { | 
 |   if (TypedefType *TDT = dyn_cast<TypedefType>(Ty)) { | 
 |     if (TypedefDecl *TD = TDT->getDecl()) | 
 |       if (TD->getAttr<ObjCNSObjectAttr>()) | 
 |         return true; | 
 |   } | 
 |   return false;   | 
 | } | 
 |  | 
 | /// isObjCObjectPointerType - Returns true if type is an Objective-C pointer | 
 | /// to an object type.  This includes "id" and "Class" (two 'special' pointers | 
 | /// to struct), Interface* (pointer to ObjCInterfaceType) and id<P> (qualified | 
 | /// ID type). | 
 | bool ASTContext::isObjCObjectPointerType(QualType Ty) const { | 
 |   if (Ty->isObjCQualifiedIdType()) | 
 |     return true; | 
 |    | 
 |   // Blocks are objects. | 
 |   if (Ty->isBlockPointerType()) | 
 |     return true; | 
 |      | 
 |   // All other object types are pointers. | 
 |   const PointerType *PT = Ty->getAsPointerType(); | 
 |   if (PT == 0) | 
 |     return false; | 
 |    | 
 |   // If this a pointer to an interface (e.g. NSString*), it is ok. | 
 |   if (PT->getPointeeType()->isObjCInterfaceType() || | 
 |       // If is has NSObject attribute, OK as well. | 
 |       isObjCNSObjectType(Ty)) | 
 |     return true; | 
 |    | 
 |   // Check to see if this is 'id' or 'Class', both of which are typedefs for | 
 |   // pointer types.  This looks for the typedef specifically, not for the | 
 |   // underlying type.  Iteratively strip off typedefs so that we can handle | 
 |   // typedefs of typedefs. | 
 |   while (TypedefType *TDT = dyn_cast<TypedefType>(Ty)) { | 
 |     if (Ty.getUnqualifiedType() == getObjCIdType() || | 
 |         Ty.getUnqualifiedType() == getObjCClassType()) | 
 |       return true; | 
 |      | 
 |     Ty = TDT->getDecl()->getUnderlyingType(); | 
 |   } | 
 |    | 
 |   return false; | 
 | } | 
 |  | 
 | /// getObjCGCAttr - Returns one of GCNone, Weak or Strong objc's | 
 | /// garbage collection attribute. | 
 | /// | 
 | QualType::GCAttrTypes ASTContext::getObjCGCAttrKind(const QualType &Ty) const { | 
 |   QualType::GCAttrTypes GCAttrs = QualType::GCNone; | 
 |   if (getLangOptions().ObjC1 && | 
 |       getLangOptions().getGCMode() != LangOptions::NonGC) { | 
 |     GCAttrs = Ty.getObjCGCAttr(); | 
 |     // Default behavious under objective-c's gc is for objective-c pointers | 
 |     // (or pointers to them) be treated as though they were declared  | 
 |     // as __strong. | 
 |     if (GCAttrs == QualType::GCNone) { | 
 |       if (isObjCObjectPointerType(Ty)) | 
 |         GCAttrs = QualType::Strong; | 
 |       else if (Ty->isPointerType()) | 
 |         return getObjCGCAttrKind(Ty->getAsPointerType()->getPointeeType()); | 
 |     } | 
 |     // Non-pointers have none gc'able attribute regardless of the attribute | 
 |     // set on them. | 
 |     else if (!isObjCObjectPointerType(Ty) && !Ty->isPointerType()) | 
 |       return QualType::GCNone; | 
 |   } | 
 |   return GCAttrs; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | //                        Type Compatibility Testing | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | /// typesAreBlockCompatible - This routine is called when comparing two | 
 | /// block types. Types must be strictly compatible here. For example, | 
 | /// C unfortunately doesn't produce an error for the following: | 
 | ///  | 
 | ///   int (*emptyArgFunc)(); | 
 | ///   int (*intArgList)(int) = emptyArgFunc; | 
 | ///  | 
 | /// For blocks, we will produce an error for the following (similar to C++): | 
 | /// | 
 | ///   int (^emptyArgBlock)(); | 
 | ///   int (^intArgBlock)(int) = emptyArgBlock; | 
 | /// | 
 | /// FIXME: When the dust settles on this integration, fold this into mergeTypes. | 
 | /// | 
 | bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) { | 
 |   const FunctionType *lbase = lhs->getAsFunctionType(); | 
 |   const FunctionType *rbase = rhs->getAsFunctionType(); | 
 |   const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase); | 
 |   const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase); | 
 |   if (lproto && rproto == 0) | 
 |     return false; | 
 |   return !mergeTypes(lhs, rhs).isNull(); | 
 | } | 
 |  | 
 | /// areCompatVectorTypes - Return true if the two specified vector types are  | 
 | /// compatible. | 
 | static bool areCompatVectorTypes(const VectorType *LHS, | 
 |                                  const VectorType *RHS) { | 
 |   assert(LHS->isCanonical() && RHS->isCanonical()); | 
 |   return LHS->getElementType() == RHS->getElementType() && | 
 |          LHS->getNumElements() == RHS->getNumElements(); | 
 | } | 
 |  | 
 | /// canAssignObjCInterfaces - Return true if the two interface types are | 
 | /// compatible for assignment from RHS to LHS.  This handles validation of any | 
 | /// protocol qualifiers on the LHS or RHS. | 
 | /// | 
 | bool ASTContext::canAssignObjCInterfaces(const ObjCInterfaceType *LHS, | 
 |                                          const ObjCInterfaceType *RHS) { | 
 |   // Verify that the base decls are compatible: the RHS must be a subclass of | 
 |   // the LHS. | 
 |   if (!LHS->getDecl()->isSuperClassOf(RHS->getDecl())) | 
 |     return false; | 
 |    | 
 |   // RHS must have a superset of the protocols in the LHS.  If the LHS is not | 
 |   // protocol qualified at all, then we are good. | 
 |   if (!isa<ObjCQualifiedInterfaceType>(LHS)) | 
 |     return true; | 
 |    | 
 |   // Okay, we know the LHS has protocol qualifiers.  If the RHS doesn't, then it | 
 |   // isn't a superset. | 
 |   if (!isa<ObjCQualifiedInterfaceType>(RHS)) | 
 |     return true;  // FIXME: should return false! | 
 |    | 
 |   // Finally, we must have two protocol-qualified interfaces. | 
 |   const ObjCQualifiedInterfaceType *LHSP =cast<ObjCQualifiedInterfaceType>(LHS); | 
 |   const ObjCQualifiedInterfaceType *RHSP =cast<ObjCQualifiedInterfaceType>(RHS); | 
 |    | 
 |   // All LHS protocols must have a presence on the RHS.   | 
 |   assert(LHSP->qual_begin() != LHSP->qual_end() && "Empty LHS protocol list?"); | 
 |    | 
 |   for (ObjCQualifiedInterfaceType::qual_iterator LHSPI = LHSP->qual_begin(), | 
 |                                                  LHSPE = LHSP->qual_end(); | 
 |        LHSPI != LHSPE; LHSPI++) { | 
 |     bool RHSImplementsProtocol = false; | 
 |  | 
 |     // If the RHS doesn't implement the protocol on the left, the types | 
 |     // are incompatible. | 
 |     for (ObjCQualifiedInterfaceType::qual_iterator RHSPI = RHSP->qual_begin(), | 
 |                                                    RHSPE = RHSP->qual_end(); | 
 |          !RHSImplementsProtocol && (RHSPI != RHSPE); RHSPI++) { | 
 |       if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier())) | 
 |         RHSImplementsProtocol = true; | 
 |     } | 
 |     // FIXME: For better diagnostics, consider passing back the protocol name. | 
 |     if (!RHSImplementsProtocol) | 
 |       return false; | 
 |   } | 
 |   // The RHS implements all protocols listed on the LHS. | 
 |   return true; | 
 | } | 
 |  | 
 | bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) { | 
 |   // get the "pointed to" types | 
 |   const PointerType *LHSPT = LHS->getAsPointerType(); | 
 |   const PointerType *RHSPT = RHS->getAsPointerType(); | 
 |    | 
 |   if (!LHSPT || !RHSPT) | 
 |     return false; | 
 |      | 
 |   QualType lhptee = LHSPT->getPointeeType(); | 
 |   QualType rhptee = RHSPT->getPointeeType(); | 
 |   const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType(); | 
 |   const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType(); | 
 |   // ID acts sort of like void* for ObjC interfaces | 
 |   if (LHSIface && isObjCIdStructType(rhptee)) | 
 |     return true; | 
 |   if (RHSIface && isObjCIdStructType(lhptee)) | 
 |     return true; | 
 |   if (!LHSIface || !RHSIface) | 
 |     return false; | 
 |   return canAssignObjCInterfaces(LHSIface, RHSIface) || | 
 |          canAssignObjCInterfaces(RHSIface, LHSIface); | 
 | } | 
 |  | 
 | /// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,  | 
 | /// both shall have the identically qualified version of a compatible type. | 
 | /// 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) { | 
 |   return !mergeTypes(LHS, RHS).isNull(); | 
 | } | 
 |  | 
 | QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) { | 
 |   const FunctionType *lbase = lhs->getAsFunctionType(); | 
 |   const FunctionType *rbase = rhs->getAsFunctionType(); | 
 |   const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase); | 
 |   const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase); | 
 |   bool allLTypes = true; | 
 |   bool allRTypes = true; | 
 |  | 
 |   // Check return type | 
 |   QualType retType = mergeTypes(lbase->getResultType(), rbase->getResultType()); | 
 |   if (retType.isNull()) return QualType(); | 
 |   if (getCanonicalType(retType) != getCanonicalType(lbase->getResultType())) | 
 |     allLTypes = false; | 
 |   if (getCanonicalType(retType) != getCanonicalType(rbase->getResultType())) | 
 |     allRTypes = false; | 
 |  | 
 |   if (lproto && rproto) { // two C99 style function prototypes | 
 |     assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() && | 
 |            "C++ shouldn't be here"); | 
 |     unsigned lproto_nargs = lproto->getNumArgs(); | 
 |     unsigned rproto_nargs = rproto->getNumArgs(); | 
 |  | 
 |     // Compatible functions must have the same number of arguments | 
 |     if (lproto_nargs != rproto_nargs) | 
 |       return QualType(); | 
 |  | 
 |     // Variadic and non-variadic functions aren't compatible | 
 |     if (lproto->isVariadic() != rproto->isVariadic()) | 
 |       return QualType(); | 
 |  | 
 |     if (lproto->getTypeQuals() != rproto->getTypeQuals()) | 
 |       return QualType(); | 
 |  | 
 |     // Check argument compatibility | 
 |     llvm::SmallVector<QualType, 10> types; | 
 |     for (unsigned i = 0; i < lproto_nargs; i++) { | 
 |       QualType largtype = lproto->getArgType(i).getUnqualifiedType(); | 
 |       QualType rargtype = rproto->getArgType(i).getUnqualifiedType(); | 
 |       QualType argtype = mergeTypes(largtype, rargtype); | 
 |       if (argtype.isNull()) return QualType(); | 
 |       types.push_back(argtype); | 
 |       if (getCanonicalType(argtype) != getCanonicalType(largtype)) | 
 |         allLTypes = false; | 
 |       if (getCanonicalType(argtype) != getCanonicalType(rargtype)) | 
 |         allRTypes = false; | 
 |     } | 
 |     if (allLTypes) return lhs; | 
 |     if (allRTypes) return rhs; | 
 |     return getFunctionType(retType, types.begin(), types.size(), | 
 |                            lproto->isVariadic(), lproto->getTypeQuals()); | 
 |   } | 
 |  | 
 |   if (lproto) allRTypes = false; | 
 |   if (rproto) allLTypes = false; | 
 |  | 
 |   const FunctionProtoType *proto = lproto ? lproto : rproto; | 
 |   if (proto) { | 
 |     assert(!proto->hasExceptionSpec() && "C++ shouldn't be here"); | 
 |     if (proto->isVariadic()) return QualType(); | 
 |     // Check that the types are compatible with the types that | 
 |     // would result from default argument promotions (C99 6.7.5.3p15). | 
 |     // The only types actually affected are promotable integer | 
 |     // types and floats, which would be passed as a different | 
 |     // type depending on whether the prototype is visible. | 
 |     unsigned proto_nargs = proto->getNumArgs(); | 
 |     for (unsigned i = 0; i < proto_nargs; ++i) { | 
 |       QualType argTy = proto->getArgType(i); | 
 |       if (argTy->isPromotableIntegerType() || | 
 |           getCanonicalType(argTy).getUnqualifiedType() == FloatTy) | 
 |         return QualType(); | 
 |     } | 
 |  | 
 |     if (allLTypes) return lhs; | 
 |     if (allRTypes) return rhs; | 
 |     return getFunctionType(retType, proto->arg_type_begin(), | 
 |                            proto->getNumArgs(), lproto->isVariadic(), | 
 |                            lproto->getTypeQuals()); | 
 |   } | 
 |  | 
 |   if (allLTypes) return lhs; | 
 |   if (allRTypes) return rhs; | 
 |   return getFunctionNoProtoType(retType); | 
 | } | 
 |  | 
 | QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) { | 
 |   // C++ [expr]: If an expression initially has the type "reference to T", the | 
 |   // type is adjusted to "T" prior to any further analysis, the expression | 
 |   // designates the object or function denoted by the reference, and the | 
 |   // expression is an lvalue unless the reference is an rvalue reference and | 
 |   // the expression is a function call (possibly inside parentheses). | 
 |   // FIXME: C++ shouldn't be going through here!  The rules are different | 
 |   // enough that they should be handled separately. | 
 |   // FIXME: Merging of lvalue and rvalue references is incorrect. C++ *really* | 
 |   // shouldn't be going through here! | 
 |   if (const ReferenceType *RT = LHS->getAsReferenceType()) | 
 |     LHS = RT->getPointeeType(); | 
 |   if (const ReferenceType *RT = RHS->getAsReferenceType()) | 
 |     RHS = RT->getPointeeType(); | 
 |  | 
 |   QualType LHSCan = getCanonicalType(LHS), | 
 |            RHSCan = getCanonicalType(RHS); | 
 |  | 
 |   // If two types are identical, they are compatible. | 
 |   if (LHSCan == RHSCan) | 
 |     return LHS; | 
 |  | 
 |   // If the qualifiers are different, the types aren't compatible | 
 |   // Note that we handle extended qualifiers later, in the | 
 |   // case for ExtQualType. | 
 |   if (LHSCan.getCVRQualifiers() != RHSCan.getCVRQualifiers()) | 
 |     return QualType(); | 
 |  | 
 |   Type::TypeClass LHSClass = LHSCan.getUnqualifiedType()->getTypeClass(); | 
 |   Type::TypeClass RHSClass = RHSCan.getUnqualifiedType()->getTypeClass(); | 
 |  | 
 |   // We want to consider the two function types to be the same for these | 
 |   // comparisons, just force one to the other. | 
 |   if (LHSClass == Type::FunctionProto) LHSClass = Type::FunctionNoProto; | 
 |   if (RHSClass == Type::FunctionProto) RHSClass = Type::FunctionNoProto; | 
 |  | 
 |   // Same as above for arrays | 
 |   if (LHSClass == Type::VariableArray || LHSClass == Type::IncompleteArray) | 
 |     LHSClass = Type::ConstantArray; | 
 |   if (RHSClass == Type::VariableArray || RHSClass == Type::IncompleteArray) | 
 |     RHSClass = Type::ConstantArray; | 
 |    | 
 |   // Canonicalize ExtVector -> Vector. | 
 |   if (LHSClass == Type::ExtVector) LHSClass = Type::Vector; | 
 |   if (RHSClass == Type::ExtVector) RHSClass = Type::Vector; | 
 |    | 
 |   // Consider qualified interfaces and interfaces the same. | 
 |   if (LHSClass == Type::ObjCQualifiedInterface) LHSClass = Type::ObjCInterface; | 
 |   if (RHSClass == Type::ObjCQualifiedInterface) RHSClass = Type::ObjCInterface; | 
 |  | 
 |   // If the canonical type classes don't match. | 
 |   if (LHSClass != RHSClass) { | 
 |     const ObjCInterfaceType* LHSIface = LHS->getAsObjCInterfaceType(); | 
 |     const ObjCInterfaceType* RHSIface = RHS->getAsObjCInterfaceType(); | 
 |      | 
 |     // 'id' and 'Class' act sort of like void* for ObjC interfaces | 
 |     if (LHSIface && (isObjCIdStructType(RHS) || isObjCClassStructType(RHS))) | 
 |       return LHS; | 
 |     if (RHSIface && (isObjCIdStructType(LHS) || isObjCClassStructType(LHS))) | 
 |       return RHS; | 
 |      | 
 |     // ID is compatible with all qualified id types. | 
 |     if (LHS->isObjCQualifiedIdType()) { | 
 |       if (const PointerType *PT = RHS->getAsPointerType()) { | 
 |         QualType pType = PT->getPointeeType(); | 
 |         if (isObjCIdStructType(pType) || isObjCClassStructType(pType)) | 
 |           return LHS; | 
 |         // FIXME: need to use ObjCQualifiedIdTypesAreCompatible(LHS, RHS, true). | 
 |         // Unfortunately, this API is part of Sema (which we don't have access | 
 |         // to. Need to refactor. The following check is insufficient, since we  | 
 |         // need to make sure the class implements the protocol. | 
 |         if (pType->isObjCInterfaceType()) | 
 |           return LHS; | 
 |       } | 
 |     } | 
 |     if (RHS->isObjCQualifiedIdType()) { | 
 |       if (const PointerType *PT = LHS->getAsPointerType()) { | 
 |         QualType pType = PT->getPointeeType(); | 
 |         if (isObjCIdStructType(pType) || isObjCClassStructType(pType)) | 
 |           return RHS; | 
 |         // FIXME: need to use ObjCQualifiedIdTypesAreCompatible(LHS, RHS, true). | 
 |         // Unfortunately, this API is part of Sema (which we don't have access | 
 |         // to. Need to refactor. The following check is insufficient, since we  | 
 |         // need to make sure the class implements the protocol. | 
 |         if (pType->isObjCInterfaceType()) | 
 |           return RHS; | 
 |       } | 
 |     } | 
 |     // C99 6.7.2.2p4: Each enumerated type shall be compatible with char, | 
 |     // a signed integer type, or an unsigned integer type.  | 
 |     if (const EnumType* ETy = LHS->getAsEnumType()) { | 
 |       if (ETy->getDecl()->getIntegerType() == RHSCan.getUnqualifiedType()) | 
 |         return RHS; | 
 |     } | 
 |     if (const EnumType* ETy = RHS->getAsEnumType()) { | 
 |       if (ETy->getDecl()->getIntegerType() == LHSCan.getUnqualifiedType()) | 
 |         return LHS; | 
 |     } | 
 |  | 
 |     return QualType(); | 
 |   } | 
 |  | 
 |   // The canonical type classes match. | 
 |   switch (LHSClass) { | 
 | #define TYPE(Class, Base) | 
 | #define ABSTRACT_TYPE(Class, Base) | 
 | #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: | 
 | #define DEPENDENT_TYPE(Class, Base) case Type::Class: | 
 | #include "clang/AST/TypeNodes.def" | 
 |     assert(false && "Non-canonical and dependent types shouldn't get here"); | 
 |     return QualType(); | 
 |  | 
 |   case Type::LValueReference: | 
 |   case Type::RValueReference: | 
 |   case Type::MemberPointer: | 
 |     assert(false && "C++ should never be in mergeTypes"); | 
 |     return QualType(); | 
 |  | 
 |   case Type::IncompleteArray: | 
 |   case Type::VariableArray: | 
 |   case Type::FunctionProto: | 
 |   case Type::ExtVector: | 
 |   case Type::ObjCQualifiedInterface: | 
 |     assert(false && "Types are eliminated above"); | 
 |     return QualType(); | 
 |  | 
 |   case Type::Pointer: | 
 |   { | 
 |     // Merge two pointer types, while trying to preserve typedef info | 
 |     QualType LHSPointee = LHS->getAsPointerType()->getPointeeType(); | 
 |     QualType RHSPointee = RHS->getAsPointerType()->getPointeeType(); | 
 |     QualType ResultType = mergeTypes(LHSPointee, RHSPointee); | 
 |     if (ResultType.isNull()) return QualType(); | 
 |     if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType)) | 
 |       return LHS; | 
 |     if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType)) | 
 |       return RHS; | 
 |     return getPointerType(ResultType); | 
 |   } | 
 |   case Type::BlockPointer: | 
 |   { | 
 |     // Merge two block pointer types, while trying to preserve typedef info | 
 |     QualType LHSPointee = LHS->getAsBlockPointerType()->getPointeeType(); | 
 |     QualType RHSPointee = RHS->getAsBlockPointerType()->getPointeeType(); | 
 |     QualType ResultType = mergeTypes(LHSPointee, RHSPointee); | 
 |     if (ResultType.isNull()) return QualType(); | 
 |     if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType)) | 
 |       return LHS; | 
 |     if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType)) | 
 |       return RHS; | 
 |     return getBlockPointerType(ResultType); | 
 |   } | 
 |   case Type::ConstantArray: | 
 |   { | 
 |     const ConstantArrayType* LCAT = getAsConstantArrayType(LHS); | 
 |     const ConstantArrayType* RCAT = getAsConstantArrayType(RHS); | 
 |     if (LCAT && RCAT && RCAT->getSize() != LCAT->getSize()) | 
 |       return QualType(); | 
 |  | 
 |     QualType LHSElem = getAsArrayType(LHS)->getElementType(); | 
 |     QualType RHSElem = getAsArrayType(RHS)->getElementType(); | 
 |     QualType ResultType = mergeTypes(LHSElem, RHSElem); | 
 |     if (ResultType.isNull()) return QualType(); | 
 |     if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType)) | 
 |       return LHS; | 
 |     if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType)) | 
 |       return RHS; | 
 |     if (LCAT) return getConstantArrayType(ResultType, LCAT->getSize(), | 
 |                                           ArrayType::ArraySizeModifier(), 0); | 
 |     if (RCAT) return getConstantArrayType(ResultType, RCAT->getSize(), | 
 |                                           ArrayType::ArraySizeModifier(), 0); | 
 |     const VariableArrayType* LVAT = getAsVariableArrayType(LHS); | 
 |     const VariableArrayType* RVAT = getAsVariableArrayType(RHS); | 
 |     if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType)) | 
 |       return LHS; | 
 |     if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType)) | 
 |       return RHS; | 
 |     if (LVAT) { | 
 |       // FIXME: This isn't correct! But tricky to implement because | 
 |       // the array's size has to be the size of LHS, but the type | 
 |       // has to be different. | 
 |       return LHS; | 
 |     } | 
 |     if (RVAT) { | 
 |       // FIXME: This isn't correct! But tricky to implement because | 
 |       // the array's size has to be the size of RHS, but the type | 
 |       // has to be different. | 
 |       return RHS; | 
 |     } | 
 |     if (getCanonicalType(LHSElem) == getCanonicalType(ResultType)) return LHS; | 
 |     if (getCanonicalType(RHSElem) == getCanonicalType(ResultType)) return RHS; | 
 |     return getIncompleteArrayType(ResultType, ArrayType::ArraySizeModifier(),0); | 
 |   } | 
 |   case Type::FunctionNoProto: | 
 |     return mergeFunctionTypes(LHS, RHS); | 
 |   case Type::Record: | 
 |   case Type::Enum: | 
 |     // FIXME: Why are these compatible? | 
 |     if (isObjCIdStructType(LHS) && isObjCClassStructType(RHS)) return LHS; | 
 |     if (isObjCClassStructType(LHS) && isObjCIdStructType(RHS)) return LHS; | 
 |     return QualType(); | 
 |   case Type::Builtin: | 
 |     // Only exactly equal builtin types are compatible, which is tested above. | 
 |     return QualType(); | 
 |   case Type::Complex: | 
 |     // Distinct complex types are incompatible. | 
 |     return QualType(); | 
 |   case Type::Vector: | 
 |     // FIXME: The merged type should be an ExtVector! | 
 |     if (areCompatVectorTypes(LHS->getAsVectorType(), RHS->getAsVectorType())) | 
 |       return LHS; | 
 |     return QualType(); | 
 |   case Type::ObjCInterface: { | 
 |     // Check if the interfaces are assignment compatible. | 
 |     // FIXME: This should be type compatibility, e.g. whether | 
 |     // "LHS x; RHS x;" at global scope is legal. | 
 |     const ObjCInterfaceType* LHSIface = LHS->getAsObjCInterfaceType(); | 
 |     const ObjCInterfaceType* RHSIface = RHS->getAsObjCInterfaceType(); | 
 |     if (LHSIface && RHSIface && | 
 |         canAssignObjCInterfaces(LHSIface, RHSIface)) | 
 |       return LHS; | 
 |  | 
 |     return QualType(); | 
 |   } | 
 |   case Type::ObjCQualifiedId: | 
 |     // Distinct qualified id's are not compatible. | 
 |     return QualType(); | 
 |   case Type::FixedWidthInt: | 
 |     // Distinct fixed-width integers are not compatible. | 
 |     return QualType(); | 
 |   case Type::ExtQual: | 
 |     // FIXME: ExtQual types can be compatible even if they're not | 
 |     // identical! | 
 |     return QualType(); | 
 |     // First attempt at an implementation, but I'm not really sure it's | 
 |     // right... | 
 | #if 0 | 
 |     ExtQualType* LQual = cast<ExtQualType>(LHSCan); | 
 |     ExtQualType* RQual = cast<ExtQualType>(RHSCan); | 
 |     if (LQual->getAddressSpace() != RQual->getAddressSpace() || | 
 |         LQual->getObjCGCAttr() != RQual->getObjCGCAttr()) | 
 |       return QualType(); | 
 |     QualType LHSBase, RHSBase, ResultType, ResCanUnqual; | 
 |     LHSBase = QualType(LQual->getBaseType(), 0); | 
 |     RHSBase = QualType(RQual->getBaseType(), 0); | 
 |     ResultType = mergeTypes(LHSBase, RHSBase); | 
 |     if (ResultType.isNull()) return QualType(); | 
 |     ResCanUnqual = getCanonicalType(ResultType).getUnqualifiedType(); | 
 |     if (LHSCan.getUnqualifiedType() == ResCanUnqual) | 
 |       return LHS; | 
 |     if (RHSCan.getUnqualifiedType() == ResCanUnqual) | 
 |       return RHS; | 
 |     ResultType = getAddrSpaceQualType(ResultType, LQual->getAddressSpace()); | 
 |     ResultType = getObjCGCQualType(ResultType, LQual->getObjCGCAttr()); | 
 |     ResultType.setCVRQualifiers(LHSCan.getCVRQualifiers()); | 
 |     return ResultType; | 
 | #endif | 
 |  | 
 |   case Type::TemplateSpecialization: | 
 |     assert(false && "Dependent types have no size"); | 
 |     break; | 
 |   } | 
 |  | 
 |   return QualType(); | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | //                         Integer Predicates | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | unsigned ASTContext::getIntWidth(QualType T) { | 
 |   if (T == BoolTy) | 
 |     return 1; | 
 |   if (FixedWidthIntType* FWIT = dyn_cast<FixedWidthIntType>(T)) { | 
 |     return FWIT->getWidth(); | 
 |   } | 
 |   // For builtin types, just use the standard type sizing method | 
 |   return (unsigned)getTypeSize(T); | 
 | } | 
 |  | 
 | QualType ASTContext::getCorrespondingUnsignedType(QualType T) { | 
 |   assert(T->isSignedIntegerType() && "Unexpected type"); | 
 |   if (const EnumType* ETy = T->getAsEnumType()) | 
 |     T = ETy->getDecl()->getIntegerType(); | 
 |   const BuiltinType* BTy = T->getAsBuiltinType(); | 
 |   assert (BTy && "Unexpected signed integer type"); | 
 |   switch (BTy->getKind()) { | 
 |   case BuiltinType::Char_S: | 
 |   case BuiltinType::SChar: | 
 |     return UnsignedCharTy; | 
 |   case BuiltinType::Short: | 
 |     return UnsignedShortTy; | 
 |   case BuiltinType::Int: | 
 |     return UnsignedIntTy; | 
 |   case BuiltinType::Long: | 
 |     return UnsignedLongTy; | 
 |   case BuiltinType::LongLong: | 
 |     return UnsignedLongLongTy; | 
 |   case BuiltinType::Int128: | 
 |     return UnsignedInt128Ty; | 
 |   default: | 
 |     assert(0 && "Unexpected signed integer type"); | 
 |     return QualType(); | 
 |   } | 
 | } | 
 |  | 
 | ExternalASTSource::~ExternalASTSource() { } | 
 |  | 
 | void ExternalASTSource::PrintStats() { } |