diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ASTContext.cpp | 516 |
1 files changed, 335 insertions, 181 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp index 0833286..acf5e0b 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp @@ -74,12 +74,14 @@ ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID, if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { ID.AddInteger(1); ID.AddBoolean(NTTP->isParameterPack()); - ID.AddPointer(NTTP->getType().getAsOpaquePtr()); + ID.AddPointer(NTTP->getType().getCanonicalType().getAsOpaquePtr()); if (NTTP->isExpandedParameterPack()) { ID.AddBoolean(true); ID.AddInteger(NTTP->getNumExpansionTypes()); - for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) - ID.AddPointer(NTTP->getExpansionType(I).getAsOpaquePtr()); + for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) { + QualType T = NTTP->getExpansionType(I); + ID.AddPointer(T.getCanonicalType().getAsOpaquePtr()); + } } else ID.AddBoolean(false); continue; @@ -193,7 +195,7 @@ CXXABI *ASTContext::createCXXABI(const TargetInfo &T) { case CXXABI_Microsoft: return CreateMicrosoftCXXABI(*this); } - return 0; + llvm_unreachable("Invalid CXXABI type!"); } static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T, @@ -224,13 +226,14 @@ ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM, SubstTemplateTemplateParmPacks(this_()), GlobalNestedNameSpecifier(0), Int128Decl(0), UInt128Decl(0), - ObjCIdDecl(0), ObjCSelDecl(0), ObjCClassDecl(0), + ObjCIdDecl(0), ObjCSelDecl(0), ObjCClassDecl(0), ObjCProtocolClassDecl(0), CFConstantStringTypeDecl(0), ObjCInstanceTypeDecl(0), FILEDecl(0), jmp_bufDecl(0), sigjmp_bufDecl(0), ucontext_tDecl(0), BlockDescriptorType(0), BlockDescriptorExtendedType(0), cudaConfigureCallDecl(0), - NullTypeSourceInfo(QualType()), + NullTypeSourceInfo(QualType()), + FirstLocalImport(), LastLocalImport(), SourceMgr(SM), LangOpts(LOpts), AddrSpaceMap(0), Target(t), PrintingPolicy(LOpts), Idents(idents), Selectors(sels), @@ -258,12 +261,6 @@ ASTContext::~ASTContext() { for (unsigned I = 0, N = Deallocations.size(); I != N; ++I) Deallocations[I].first(Deallocations[I].second); - // Release all of the memory associated with overridden C++ methods. - for (llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::iterator - OM = OverriddenMethods.begin(), OMEnd = OverriddenMethods.end(); - OM != OMEnd; ++OM) - OM->second.Destroy(); - // ASTRecordLayout objects in ASTRecordLayouts must always be destroyed // because they can contain DenseMaps. for (llvm::DenseMap<const ObjCContainerDecl*, @@ -291,7 +288,7 @@ void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) { } void -ASTContext::setExternalSource(llvm::OwningPtr<ExternalASTSource> &Source) { +ASTContext::setExternalSource(OwningPtr<ExternalASTSource> &Source) { ExternalSource.reset(Source.take()); } @@ -331,14 +328,14 @@ void ASTContext::PrintStats() const { llvm::errs() << NumImplicitCopyConstructorsDeclared << "/" << NumImplicitCopyConstructors << " implicit copy constructors created\n"; - if (getLangOptions().CPlusPlus) + if (getLangOpts().CPlusPlus) llvm::errs() << NumImplicitMoveConstructorsDeclared << "/" << NumImplicitMoveConstructors << " implicit move constructors created\n"; llvm::errs() << NumImplicitCopyAssignmentOperatorsDeclared << "/" << NumImplicitCopyAssignmentOperators << " implicit copy assignment operators created\n"; - if (getLangOptions().CPlusPlus) + if (getLangOpts().CPlusPlus) llvm::errs() << NumImplicitMoveAssignmentOperatorsDeclared << "/" << NumImplicitMoveAssignmentOperators << " implicit move assignment operators created\n"; @@ -462,9 +459,15 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { // Placeholder type for bound members. InitBuiltinType(BoundMemberTy, BuiltinType::BoundMember); + // Placeholder type for pseudo-objects. + InitBuiltinType(PseudoObjectTy, BuiltinType::PseudoObject); + // "any" type; useful for debugger-like clients. InitBuiltinType(UnknownAnyTy, BuiltinType::UnknownAny); + // Placeholder type for unbridged ARC casts. + InitBuiltinType(ARCUnbridgedCastTy, BuiltinType::ARCUnbridgedCast); + // C99 6.2.5p11. FloatComplexTy = getComplexType(FloatTy); DoubleComplexTy = getComplexType(DoubleTy); @@ -476,7 +479,10 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId); InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass); InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); - + + // Builtin type for __objc_yes and __objc_no + ObjCBuiltinBoolTy = SignedCharTy; + ObjCConstantStringType = QualType(); // void * type @@ -676,6 +682,19 @@ void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method, OverriddenMethods[Method].push_back(Overridden); } +void ASTContext::addedLocalImportDecl(ImportDecl *Import) { + assert(!Import->NextLocalImport && "Import declaration already in the chain"); + assert(!Import->isFromASTFile() && "Non-local import declaration"); + if (!FirstLocalImport) { + FirstLocalImport = Import; + LastLocalImport = Import; + return; + } + + LastLocalImport->NextLocalImport = Import; + LastLocalImport = Import; +} + //===----------------------------------------------------------------------===// // Type Sizing and Analysis //===----------------------------------------------------------------------===// @@ -796,14 +815,24 @@ ASTContext::getTypeInfoInChars(QualType T) const { return getTypeInfoInChars(T.getTypePtr()); } -/// 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) const { + TypeInfoMap::iterator it = MemoizedTypeInfo.find(T); + if (it != MemoizedTypeInfo.end()) + return it->second; + + std::pair<uint64_t, unsigned> Info = getTypeInfoImpl(T); + MemoizedTypeInfo.insert(std::make_pair(T, Info)); + return Info; +} + +/// getTypeInfoImpl - Return the size of the specified type, in bits. This +/// method does not work on incomplete types. /// /// FIXME: Pointers into different addr spaces could have different sizes and /// alignment requirements: getPointerInfo should take an AddrSpace, this /// should take a QualType, &c. std::pair<uint64_t, unsigned> -ASTContext::getTypeInfo(const Type *T) const { +ASTContext::getTypeInfoImpl(const Type *T) const { uint64_t Width=0; unsigned Align=8; switch (T->getTypeClass()) { @@ -813,7 +842,6 @@ ASTContext::getTypeInfo(const Type *T) const { #define DEPENDENT_TYPE(Class, Base) case Type::Class: #include "clang/AST/TypeNodes.def" llvm_unreachable("Should not see dependent types"); - break; case Type::FunctionNoProto: case Type::FunctionProto: @@ -832,7 +860,10 @@ ASTContext::getTypeInfo(const Type *T) const { const ConstantArrayType *CAT = cast<ConstantArrayType>(T); std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType()); - Width = EltInfo.first*CAT->getSize().getZExtValue(); + uint64_t Size = CAT->getSize().getZExtValue(); + assert((Size == 0 || EltInfo.first <= (uint64_t)(-1)/Size) && + "Overflow in array type bit size evaluation"); + Width = EltInfo.first*Size; Align = EltInfo.second; Width = llvm::RoundUpToAlignment(Width, Align); break; @@ -1134,7 +1165,8 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { if (const ComplexType* CT = T->getAs<ComplexType>()) T = CT->getElementType().getTypePtr(); if (T->isSpecificBuiltinType(BuiltinType::Double) || - T->isSpecificBuiltinType(BuiltinType::LongLong)) + T->isSpecificBuiltinType(BuiltinType::LongLong) || + T->isSpecificBuiltinType(BuiltinType::ULongLong)) return std::max(ABIAlign, (unsigned)getTypeSize(T)); return ABIAlign; @@ -1173,10 +1205,10 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl, for (ObjCInterfaceDecl::all_protocol_iterator P = OI->all_referenced_protocol_begin(), PE = OI->all_referenced_protocol_end(); P != PE; ++P) { ObjCProtocolDecl *Proto = (*P); - Protocols.insert(Proto); + Protocols.insert(Proto->getCanonicalDecl()); for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), PE = Proto->protocol_end(); P != PE; ++P) { - Protocols.insert(*P); + Protocols.insert((*P)->getCanonicalDecl()); CollectInheritedProtocols(*P, Protocols); } } @@ -1194,7 +1226,7 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl, for (ObjCCategoryDecl::protocol_iterator P = OC->protocol_begin(), PE = OC->protocol_end(); P != PE; ++P) { ObjCProtocolDecl *Proto = (*P); - Protocols.insert(Proto); + Protocols.insert(Proto->getCanonicalDecl()); for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), PE = Proto->protocol_end(); P != PE; ++P) CollectInheritedProtocols(*P, Protocols); @@ -1203,7 +1235,7 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl, for (ObjCProtocolDecl::protocol_iterator P = OP->protocol_begin(), PE = OP->protocol_end(); P != PE; ++P) { ObjCProtocolDecl *Proto = (*P); - Protocols.insert(Proto); + Protocols.insert(Proto->getCanonicalDecl()); for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), PE = Proto->protocol_end(); P != PE; ++P) CollectInheritedProtocols(*P, Protocols); @@ -1226,6 +1258,24 @@ unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const { return count; } +bool ASTContext::isSentinelNullExpr(const Expr *E) { + if (!E) + return false; + + // nullptr_t is always treated as null. + if (E->getType()->isNullPtrType()) return true; + + if (E->getType()->isAnyPointerType() && + E->IgnoreParenCasts()->isNullPointerConstant(*this, + Expr::NPC_ValueDependentIsNull)) + return true; + + // Unfortunately, __null has type 'int'. + if (isa<GNUNullExpr>(E)) return true; + + return false; +} + /// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists. ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) { llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator @@ -1256,6 +1306,17 @@ void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD, ObjCImpls[CatD] = ImplD; } +ObjCInterfaceDecl *ASTContext::getObjContainingInterface(NamedDecl *ND) const { + if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(ND->getDeclContext())) + return ID; + if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ND->getDeclContext())) + return CD->getClassInterface(); + if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(ND->getDeclContext())) + return IMD->getClassInterface(); + + return 0; +} + /// \brief Get the copy initialization expression of VarDecl,or NULL if /// none exists. Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) { @@ -1337,8 +1398,8 @@ ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const { QualType canon; if (!baseType->isCanonicalUnqualified()) { SplitQualType canonSplit = baseType->getCanonicalTypeInternal().split(); - canonSplit.second.addConsistentQualifiers(quals); - canon = getExtQualType(canonSplit.first, canonSplit.second); + canonSplit.Quals.addConsistentQualifiers(quals); + canon = getExtQualType(canonSplit.Ty, canonSplit.Quals); // Re-find the insert position. (void) ExtQualNodes.FindNodeOrInsertPos(ID, insertPos); @@ -1640,9 +1701,9 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, QualType Canon; if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) { SplitQualType canonSplit = getCanonicalType(EltTy).split(); - Canon = getConstantArrayType(QualType(canonSplit.first, 0), ArySize, + Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize, ASM, IndexTypeQuals); - Canon = getQualifiedType(Canon, canonSplit.second); + Canon = getQualifiedType(Canon, canonSplit.Quals); // Get the new insert position for the node we care about. ConstantArrayType *NewIP = @@ -1667,7 +1728,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const { QualType result; SplitQualType split = type.getSplitDesugaredType(); - const Type *ty = split.first; + const Type *ty = split.Ty; switch (ty->getTypeClass()) { #define TYPE(Class, Base) #define ABSTRACT_TYPE(Class, Base) @@ -1786,7 +1847,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const { } // Apply the top-level qualifiers from the original. - return getQualifiedType(result, split.second); + return getQualifiedType(result, split.Quals); } /// getVariableArrayType - Returns a non-unique reference to the type for a @@ -1803,9 +1864,9 @@ QualType ASTContext::getVariableArrayType(QualType EltTy, // Be sure to pull qualifiers off the element type. if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) { SplitQualType canonSplit = getCanonicalType(EltTy).split(); - Canon = getVariableArrayType(QualType(canonSplit.first, 0), NumElts, ASM, + Canon = getVariableArrayType(QualType(canonSplit.Ty, 0), NumElts, ASM, IndexTypeQuals, Brackets); - Canon = getQualifiedType(Canon, canonSplit.second); + Canon = getQualifiedType(Canon, canonSplit.Quals); } VariableArrayType *New = new(*this, TypeAlignment) @@ -1850,7 +1911,7 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType, void *insertPos = 0; llvm::FoldingSetNodeID ID; DependentSizedArrayType::Profile(ID, *this, - QualType(canonElementType.first, 0), + QualType(canonElementType.Ty, 0), ASM, elementTypeQuals, numElements); // Look for an existing type with these properties. @@ -1860,7 +1921,7 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType, // If we don't have one, build one. if (!canonTy) { canonTy = new (*this, TypeAlignment) - DependentSizedArrayType(*this, QualType(canonElementType.first, 0), + DependentSizedArrayType(*this, QualType(canonElementType.Ty, 0), QualType(), numElements, ASM, elementTypeQuals, brackets); DependentSizedArrayTypes.InsertNode(canonTy, insertPos); @@ -1869,11 +1930,11 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType, // Apply qualifiers from the element type to the array. QualType canon = getQualifiedType(QualType(canonTy,0), - canonElementType.second); + canonElementType.Quals); // If we didn't need extra canonicalization for the element type, // then just use that as our result. - if (QualType(canonElementType.first, 0) == elementType) + if (QualType(canonElementType.Ty, 0) == elementType) return canon; // Otherwise, we need to build a type which follows the spelling @@ -1904,9 +1965,9 @@ QualType ASTContext::getIncompleteArrayType(QualType elementType, if (!elementType.isCanonical() || elementType.hasLocalQualifiers()) { SplitQualType canonSplit = getCanonicalType(elementType).split(); - canon = getIncompleteArrayType(QualType(canonSplit.first, 0), + canon = getIncompleteArrayType(QualType(canonSplit.Ty, 0), ASM, elementTypeQuals); - canon = getQualifiedType(canon, canonSplit.second); + canon = getQualifiedType(canon, canonSplit.Quals); // Get the new insert position for the node we care about. IncompleteArrayType *existing = @@ -2082,7 +2143,9 @@ ASTContext::getFunctionType(QualType ResultTy, return QualType(FTP, 0); // Determine whether the type being created is already canonical or not. - bool isCanonical= EPI.ExceptionSpecType == EST_None && ResultTy.isCanonical(); + bool isCanonical = + EPI.ExceptionSpecType == EST_None && ResultTy.isCanonical() && + !EPI.HasTrailingReturn; for (unsigned i = 0; i != NumArgs && isCanonical; ++i) if (!ArgArray[i].isCanonicalAsParam()) isCanonical = false; @@ -2101,6 +2164,7 @@ ASTContext::getFunctionType(QualType ResultTy, CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i])); FunctionProtoType::ExtProtoInfo CanonicalEPI = EPI; + CanonicalEPI.HasTrailingReturn = false; CanonicalEPI.ExceptionSpecType = EST_None; CanonicalEPI.NumExceptions = 0; CanonicalEPI.ExtInfo @@ -2162,7 +2226,7 @@ QualType ASTContext::getInjectedClassNameType(CXXRecordDecl *Decl, assert(NeedsInjectedClassNameType(Decl)); if (Decl->TypeForDecl) { assert(isa<InjectedClassNameType>(Decl->TypeForDecl)); - } else if (CXXRecordDecl *PrevDecl = Decl->getPreviousDeclaration()) { + } else if (CXXRecordDecl *PrevDecl = Decl->getPreviousDecl()) { assert(PrevDecl->TypeForDecl && "previous declaration has no type"); Decl->TypeForDecl = PrevDecl->TypeForDecl; assert(isa<InjectedClassNameType>(Decl->TypeForDecl)); @@ -2188,12 +2252,12 @@ QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const { "Template type parameter types are always available."); if (const RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) { - assert(!Record->getPreviousDeclaration() && + assert(!Record->getPreviousDecl() && "struct/union has previous declaration"); assert(!NeedsInjectedClassNameType(Record)); return getRecordType(Record); } else if (const EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) { - assert(!Enum->getPreviousDeclaration() && + assert(!Enum->getPreviousDecl() && "enum has previous declaration"); return getEnumType(Enum); } else if (const UnresolvedUsingTypenameDecl *Using = @@ -2226,7 +2290,7 @@ ASTContext::getTypedefType(const TypedefNameDecl *Decl, QualType ASTContext::getRecordType(const RecordDecl *Decl) const { if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); - if (const RecordDecl *PrevDecl = Decl->getPreviousDeclaration()) + if (const RecordDecl *PrevDecl = Decl->getPreviousDecl()) if (PrevDecl->TypeForDecl) return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0); @@ -2239,7 +2303,7 @@ QualType ASTContext::getRecordType(const RecordDecl *Decl) const { QualType ASTContext::getEnumType(const EnumDecl *Decl) const { if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); - if (const EnumDecl *PrevDecl = Decl->getPreviousDeclaration()) + if (const EnumDecl *PrevDecl = Decl->getPreviousDecl()) if (PrevDecl->TypeForDecl) return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0); @@ -2374,6 +2438,7 @@ ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name, TypeSourceInfo *DI = CreateTypeSourceInfo(TST); TemplateSpecializationTypeLoc TL = cast<TemplateSpecializationTypeLoc>(DI->getTypeLoc()); + TL.setTemplateKeywordLoc(SourceLocation()); TL.setTemplateNameLoc(NameLoc); TL.setLAngleLoc(Args.getLAngleLoc()); TL.setRAngleLoc(Args.getRAngleLoc()); @@ -2400,6 +2465,17 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, Underlying); } +#ifndef NDEBUG +static bool hasAnyPackExpansions(const TemplateArgument *Args, + unsigned NumArgs) { + for (unsigned I = 0; I != NumArgs; ++I) + if (Args[I].isPackExpansion()) + return true; + + return true; +} +#endif + QualType ASTContext::getTemplateSpecializationType(TemplateName Template, const TemplateArgument *Args, @@ -2411,16 +2487,18 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) Template = TemplateName(QTN->getTemplateDecl()); - bool isTypeAlias = + bool IsTypeAlias = Template.getAsTemplateDecl() && isa<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()); - QualType CanonType; if (!Underlying.isNull()) CanonType = getCanonicalType(Underlying); else { - assert(!isTypeAlias && - "Underlying type for template alias must be computed by caller"); + // We can get here with an alias template when the specialization contains + // a pack expansion that does not match up with a parameter pack. + assert((!IsTypeAlias || hasAnyPackExpansions(Args, NumArgs)) && + "Caller must compute aliased type"); + IsTypeAlias = false; CanonType = getCanonicalTemplateSpecializationType(Template, Args, NumArgs); } @@ -2430,13 +2508,11 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, // we don't unique and don't want to lose. void *Mem = Allocate(sizeof(TemplateSpecializationType) + sizeof(TemplateArgument) * NumArgs + - (isTypeAlias ? sizeof(QualType) : 0), + (IsTypeAlias? sizeof(QualType) : 0), TypeAlignment); TemplateSpecializationType *Spec - = new (Mem) TemplateSpecializationType(Template, - Args, NumArgs, - CanonType, - isTypeAlias ? Underlying : QualType()); + = new (Mem) TemplateSpecializationType(Template, Args, NumArgs, CanonType, + IsTypeAlias ? Underlying : QualType()); Types.push_back(Spec); return QualType(Spec, 0); @@ -2448,9 +2524,6 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template, unsigned NumArgs) const { assert(!Template.getAsDependentTemplateName() && "No dependent template names here!"); - assert((!Template.getAsTemplateDecl() || - !isa<TypeAliasTemplateDecl>(Template.getAsTemplateDecl())) && - "Underlying type for template alias must be computed by caller"); // Look through qualified template names. if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) @@ -2677,8 +2750,12 @@ static bool areSortedAndUniqued(ObjCProtocolDecl * const *Protocols, unsigned NumProtocols) { if (NumProtocols == 0) return true; + if (Protocols[0]->getCanonicalDecl() != Protocols[0]) + return false; + for (unsigned i = 1; i != NumProtocols; ++i) - if (!CmpProtocolNames(Protocols[i-1], Protocols[i])) + if (!CmpProtocolNames(Protocols[i-1], Protocols[i]) || + Protocols[i]->getCanonicalDecl() != Protocols[i]) return false; return true; } @@ -2690,6 +2767,10 @@ static void SortAndUniqueProtocols(ObjCProtocolDecl **Protocols, // Sort protocols, keyed by name. std::sort(Protocols, Protocols+NumProtocols, CmpProtocolNames); + // Canonicalize. + for (unsigned I = 0, N = NumProtocols; I != N; ++I) + Protocols[I] = Protocols[I]->getCanonicalDecl(); + // Remove duplicates. ProtocolsEnd = std::unique(Protocols, ProtocolsEnd); NumProtocols = ProtocolsEnd-Protocols; @@ -2775,11 +2856,21 @@ QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const { /// getObjCInterfaceType - Return the unique reference to the type for the /// specified ObjC interface decl. The list of protocols is optional. -QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const { +QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl, + ObjCInterfaceDecl *PrevDecl) const { if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); - // FIXME: redeclarations? + if (PrevDecl) { + assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl"); + Decl->TypeForDecl = PrevDecl->TypeForDecl; + return QualType(PrevDecl->TypeForDecl, 0); + } + + // Prefer the definition, if there is one. + if (const ObjCInterfaceDecl *Def = Decl->getDefinition()) + Decl = Def; + void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment); ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl); Decl->TypeForDecl = T; @@ -2833,44 +2924,13 @@ QualType ASTContext::getTypeOfType(QualType tofType) const { return QualType(tot, 0); } -/// getDecltypeForExpr - Given an expr, will return the decltype for that -/// expression, according to the rules in C++0x [dcl.type.simple]p4 -static QualType getDecltypeForExpr(const Expr *e, const ASTContext &Context) { - if (e->isTypeDependent()) - return Context.DependentTy; - - // If e is an id expression or a class member access, decltype(e) is defined - // as the type of the entity named by e. - if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(e)) { - if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())) - return VD->getType(); - } - if (const MemberExpr *ME = dyn_cast<MemberExpr>(e)) { - if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) - return FD->getType(); - } - // If e is a function call or an invocation of an overloaded operator, - // (parentheses around e are ignored), decltype(e) is defined as the - // return type of that function. - if (const CallExpr *CE = dyn_cast<CallExpr>(e->IgnoreParens())) - return CE->getCallReturnType(); - - QualType T = e->getType(); - - // Otherwise, where T is the type of e, if e is an lvalue, decltype(e) is - // defined as T&, otherwise decltype(e) is defined as T. - if (e->isLValue()) - T = Context.getLValueReferenceType(T); - - return T; -} /// getDecltypeType - Unlike many "get<Type>" functions, we don't unique /// DecltypeType AST's. The only motivation to unique these nodes would be /// memory savings. Since decltype(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::getDecltypeType(Expr *e) const { +/// on canonical types (which are always unique). +QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const { DecltypeType *dt; // C++0x [temp.type]p2: @@ -2896,8 +2956,8 @@ QualType ASTContext::getDecltypeType(Expr *e) const { dt = Canon; } } else { - QualType T = getDecltypeForExpr(e, *this); - dt = new (*this, TypeAlignment) DecltypeType(e, T, getCanonicalType(T)); + dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType, + getCanonicalType(UnderlyingType)); } Types.push_back(dt); return QualType(dt, 0); @@ -2913,7 +2973,7 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType, new (*this, TypeAlignment) UnaryTransformType (BaseType, UnderlyingType, Kind, UnderlyingType->isDependentType() ? - QualType() : UnderlyingType); + QualType() : getCanonicalType(UnderlyingType)); Types.push_back(Ty); return QualType(Ty, 0); } @@ -2996,6 +3056,16 @@ CanQualType ASTContext::getSizeType() const { return getFromTargetType(Target->getSizeType()); } +/// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5). +CanQualType ASTContext::getIntMaxType() const { + return getFromTargetType(Target->getIntMaxType()); +} + +/// getUIntMaxType - Return the unique type for "uintmax_t" (C99 7.18.1.5). +CanQualType ASTContext::getUIntMaxType() const { + return getFromTargetType(Target->getUIntMaxType()); +} + /// getSignedWCharType - Return the type of "signed wchar_t". /// Used when in C++, as a GCC extension. QualType ASTContext::getSignedWCharType() const { @@ -3010,7 +3080,7 @@ QualType ASTContext::getUnsignedWCharType() const { return UnsignedIntTy; } -/// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?) +/// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17) /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9). QualType ASTContext::getPointerDiffType() const { return getFromTargetType(Target->getPtrDiffType(0)); @@ -3047,12 +3117,12 @@ QualType ASTContext::getUnqualifiedArrayType(QualType type, // We then have to strip that sugar back off with // getUnqualifiedDesugaredType(), which is silly. const ArrayType *AT = - dyn_cast<ArrayType>(splitType.first->getUnqualifiedDesugaredType()); + dyn_cast<ArrayType>(splitType.Ty->getUnqualifiedDesugaredType()); // If we don't have an array, just use the results in splitType. if (!AT) { - quals = splitType.second; - return QualType(splitType.first, 0); + quals = splitType.Quals; + return QualType(splitType.Ty, 0); } // Otherwise, recurse on the array's element type. @@ -3063,13 +3133,13 @@ QualType ASTContext::getUnqualifiedArrayType(QualType type, // can just use the results in splitType. if (elementType == unqualElementType) { assert(quals.empty()); // from the recursive call - quals = splitType.second; - return QualType(splitType.first, 0); + quals = splitType.Quals; + return QualType(splitType.Ty, 0); } // Otherwise, add in the qualifiers from the outermost type, then // build the type back up. - quals.addConsistentQualifiers(splitType.second); + quals.addConsistentQualifiers(splitType.Quals); if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) { return getConstantArrayType(unqualElementType, CAT->getSize(), @@ -3121,7 +3191,7 @@ bool ASTContext::UnwrapSimilarPointerTypes(QualType &T1, QualType &T2) { return true; } - if (getLangOptions().ObjC1) { + if (getLangOpts().ObjC1) { const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(), *T2OPType = T2->getAs<ObjCObjectPointerType>(); if (T1OPType && T2OPType) { @@ -3243,8 +3313,11 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const { case TemplateArgument::Expression: return Arg; - case TemplateArgument::Declaration: - return TemplateArgument(Arg.getAsDecl()->getCanonicalDecl()); + case TemplateArgument::Declaration: { + if (Decl *D = Arg.getAsDecl()) + return TemplateArgument(D->getCanonicalDecl()); + return TemplateArgument((Decl*)0); + } case TemplateArgument::Template: return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate())); @@ -3317,26 +3390,13 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const { // types, e.g., // typedef typename T::type T1; // typedef typename T1::type T2; - if (const DependentNameType *DNT = T->getAs<DependentNameType>()) { - NestedNameSpecifier *Prefix - = getCanonicalNestedNameSpecifier(DNT->getQualifier()); - return NestedNameSpecifier::Create(*this, Prefix, + if (const DependentNameType *DNT = T->getAs<DependentNameType>()) + return NestedNameSpecifier::Create(*this, DNT->getQualifier(), const_cast<IdentifierInfo *>(DNT->getIdentifier())); - } - // Do the same thing as above, but with dependent-named specializations. - if (const DependentTemplateSpecializationType *DTST - = T->getAs<DependentTemplateSpecializationType>()) { - NestedNameSpecifier *Prefix - = getCanonicalNestedNameSpecifier(DTST->getQualifier()); - - T = getDependentTemplateSpecializationType(DTST->getKeyword(), - Prefix, DTST->getIdentifier(), - DTST->getNumArgs(), - DTST->getArgs()); - T = getCanonicalType(T); - } - + // Otherwise, just canonicalize the type, and force it to be a TypeSpec. + // FIXME: Why are TypeSpec and TypeSpecWithTemplate distinct in the + // first place? return NestedNameSpecifier::Create(*this, 0, false, const_cast<Type*>(T.getTypePtr())); } @@ -3346,8 +3406,7 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const { return NNS; } - // Required to silence a GCC warning - return 0; + llvm_unreachable("Invalid NestedNameSpecifier::Kind!"); } @@ -3372,10 +3431,10 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const { // we must propagate them down into the element type. SplitQualType split = T.getSplitDesugaredType(); - Qualifiers qs = split.second; + Qualifiers qs = split.Quals; // If we have a simple case, just return now. - const ArrayType *ATy = dyn_cast<ArrayType>(split.first); + const ArrayType *ATy = dyn_cast<ArrayType>(split.Ty); if (ATy == 0 || qs.empty()) return ATy; @@ -3462,11 +3521,11 @@ QualType ASTContext::getBaseElementType(QualType type) const { Qualifiers qs; while (true) { SplitQualType split = type.getSplitDesugaredType(); - const ArrayType *array = split.first->getAsArrayTypeUnsafe(); + const ArrayType *array = split.Ty->getAsArrayTypeUnsafe(); if (!array) break; type = array->getElementType(); - qs.addConsistentQualifiers(split.second); + qs.addConsistentQualifiers(split.Quals); } return getQualifiedType(type, qs); @@ -3508,7 +3567,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size, FloatingRank EltRank = getFloatingRank(Size); if (Domain->isComplexType()) { switch (EltRank) { - default: llvm_unreachable("getFloatingRank(): illegal value for rank"); + case HalfRank: llvm_unreachable("Complex half is not supported"); case FloatRank: return FloatComplexTy; case DoubleRank: return DoubleComplexTy; case LongDoubleRank: return LongDoubleComplexTy; @@ -3517,11 +3576,12 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size, assert(Domain->isRealFloatingType() && "Unknown domain!"); switch (EltRank) { - default: llvm_unreachable("getFloatingRank(): illegal value for rank"); + case HalfRank: llvm_unreachable("Half ranks are not valid here"); case FloatRank: return FloatTy; case DoubleRank: return DoubleTy; case LongDoubleRank: return LongDoubleTy; } + llvm_unreachable("getFloatingRank(): illegal value for rank"); } /// getFloatingTypeOrder - Compare the rank of the two specified floating @@ -3544,18 +3604,6 @@ int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) const { /// or if it is not canonicalized. unsigned ASTContext::getIntegerRank(const Type *T) const { assert(T->isCanonicalUnqualified() && "T should be canonicalized"); - if (const EnumType* ET = dyn_cast<EnumType>(T)) - T = ET->getDecl()->getPromotionType().getTypePtr(); - - if (T->isSpecificBuiltinType(BuiltinType::WChar_S) || - T->isSpecificBuiltinType(BuiltinType::WChar_U)) - T = getFromTargetType(Target->getWCharType()).getTypePtr(); - - if (T->isSpecificBuiltinType(BuiltinType::Char16)) - T = getFromTargetType(Target->getChar16Type()).getTypePtr(); - - if (T->isSpecificBuiltinType(BuiltinType::Char32)) - T = getFromTargetType(Target->getChar32Type()).getTypePtr(); switch (cast<BuiltinType>(T)->getKind()) { default: llvm_unreachable("getIntegerRank(): not a built-in integer"); @@ -3625,6 +3673,34 @@ QualType ASTContext::getPromotedIntegerType(QualType Promotable) const { assert(Promotable->isPromotableIntegerType()); if (const EnumType *ET = Promotable->getAs<EnumType>()) return ET->getDecl()->getPromotionType(); + + if (const BuiltinType *BT = Promotable->getAs<BuiltinType>()) { + // C++ [conv.prom]: A prvalue of type char16_t, char32_t, or wchar_t + // (3.9.1) can be converted to a prvalue of the first of the following + // types that can represent all the values of its underlying type: + // int, unsigned int, long int, unsigned long int, long long int, or + // unsigned long long int [...] + // FIXME: Is there some better way to compute this? + if (BT->getKind() == BuiltinType::WChar_S || + BT->getKind() == BuiltinType::WChar_U || + BT->getKind() == BuiltinType::Char16 || + BT->getKind() == BuiltinType::Char32) { + bool FromIsSigned = BT->getKind() == BuiltinType::WChar_S; + uint64_t FromSize = getTypeSize(BT); + QualType PromoteTypes[] = { IntTy, UnsignedIntTy, LongTy, UnsignedLongTy, + LongLongTy, UnsignedLongLongTy }; + for (size_t Idx = 0; Idx < llvm::array_lengthof(PromoteTypes); ++Idx) { + uint64_t ToSize = getTypeSize(PromoteTypes[Idx]); + if (FromSize < ToSize || + (FromSize == ToSize && + FromIsSigned == PromoteTypes[Idx]->isSignedIntegerType())) + return PromoteTypes[Idx]; + } + llvm_unreachable("char type should fit into long long"); + } + } + + // At this point, we should have a signed or unsigned integer type. if (Promotable->isSignedIntegerType()) return IntTy; uint64_t PromotableSize = getTypeSize(Promotable); @@ -3697,7 +3773,7 @@ static RecordDecl * CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK, DeclContext *DC, IdentifierInfo *Id) { SourceLocation Loc; - if (Ctx.getLangOptions().CPlusPlus) + if (Ctx.getLangOpts().CPlusPlus) return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id); else return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id); @@ -3832,7 +3908,7 @@ QualType ASTContext::getBlockDescriptorExtendedType() const { bool ASTContext::BlockRequiresCopying(QualType Ty) const { if (Ty->isObjCRetainableType()) return true; - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { if (const RecordType *RT = Ty->getAs<RecordType>()) { CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); return RD->hasConstCopyConstructor(); @@ -3857,7 +3933,7 @@ ASTContext::BuildByRefType(StringRef DeclName, QualType Ty) const { bool HasCopyAndDispose = BlockRequiresCopying(Ty); // FIXME: Move up - llvm::SmallString<36> Name; + SmallString<36> Name; llvm::raw_svector_ostream(Name) << "__Block_byref_" << ++UniqueBlockByRefTypeID << '_' << DeclName; RecordDecl *T; @@ -4037,15 +4113,32 @@ bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, return false; } +/// getObjCEncodingForMethodParameter - Return the encoded type for a single +/// method parameter or return type. If Extended, include class names and +/// block object types. +void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, + QualType T, std::string& S, + bool Extended) const { + // Encode type qualifer, 'in', 'inout', etc. for the parameter. + getObjCEncodingForTypeQualifier(QT, S); + // Encode parameter type. + getObjCEncodingForTypeImpl(T, S, true, true, 0, + true /*OutermostType*/, + false /*EncodingProperty*/, + false /*StructField*/, + Extended /*EncodeBlockParameters*/, + Extended /*EncodeClassNames*/); +} + /// getObjCEncodingForMethodDecl - Return the encoded type for this method /// declaration. bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, - std::string& S) const { + std::string& S, + bool Extended) const { // 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); + // Encode return type. + getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(), + Decl->getResultType(), S, Extended); // 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! @@ -4083,10 +4176,8 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, 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); + getObjCEncodingForMethodParameter(PVDecl->getObjCDeclQualifier(), + PType, S, Extended); S += charUnitsToString(ParmOffset); ParmOffset += getObjCEncodingTypeSize(PType); } @@ -4113,7 +4204,7 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, /// 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. +/// kPropertyType = 'T' // followed by old-style type encoding. /// kPropertyWeak = 'W' // 'weak' property /// kPropertyStrong = 'P' // property GC'able /// kPropertyNonAtomic = 'N' // property non-atomic @@ -4293,7 +4384,7 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S, // information is not especially sensible, but we're stuck with it for // compatibility with GCC, although providing it breaks anything that // actually uses runtime introspection and wants to work on both runtimes... - if (!Ctx->getLangOptions().NeXTRuntime) { + if (!Ctx->getLangOpts().NeXTRuntime) { const RecordDecl *RD = FD->getParent(); const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD); S += llvm::utostr(RL.getFieldOffset(FD->getFieldIndex())); @@ -4312,7 +4403,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, const FieldDecl *FD, bool OutermostType, bool EncodingProperty, - bool StructField) const { + bool StructField, + bool EncodeBlockParameters, + bool EncodeClassNames) const { if (T->getAs<BuiltinType>()) { if (FD && FD->isBitField()) return EncodeBitField(this, S, T, FD); @@ -4491,8 +4584,40 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, return; } - if (T->isBlockPointerType()) { + if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) { S += "@?"; // Unlike a pointer-to-function, which is "^?". + if (EncodeBlockParameters) { + const FunctionType *FT = BT->getPointeeType()->getAs<FunctionType>(); + + S += '<'; + // Block return type + getObjCEncodingForTypeImpl(FT->getResultType(), S, + ExpandPointedToStructures, ExpandStructures, + FD, + false /* OutermostType */, + EncodingProperty, + false /* StructField */, + EncodeBlockParameters, + EncodeClassNames); + // Block self + S += "@?"; + // Block parameters + if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) { + for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(), + E = FPT->arg_type_end(); I && (I != E); ++I) { + getObjCEncodingForTypeImpl(*I, S, + ExpandPointedToStructures, + ExpandStructures, + FD, + false /* OutermostType */, + EncodingProperty, + false /* StructField */, + EncodeBlockParameters, + EncodeClassNames); + } + } + S += '>'; + } return; } @@ -4538,7 +4663,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, getObjCEncodingForTypeImpl(getObjCIdType(), S, ExpandPointedToStructures, ExpandStructures, FD); - if (FD || EncodingProperty) { + if (FD || EncodingProperty || EncodeClassNames) { // Note that we do extended encoding of protocol qualifer list // Only when doing ivar or property encoding. S += '"'; @@ -4567,7 +4692,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, } S += '@'; - if (OPT->getInterfaceDecl() && (FD || EncodingProperty)) { + if (OPT->getInterfaceDecl() && + (FD || EncodingProperty || EncodeClassNames)) { S += '"'; S += OPT->getInterfaceDecl()->getIdentifier()->getName(); for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(), @@ -4780,10 +4906,6 @@ TypedefDecl *ASTContext::getObjCSelDecl() const { return ObjCSelDecl; } -void ASTContext::setObjCProtoType(QualType QT) { - ObjCProtoType = QT; -} - TypedefDecl *ASTContext::getObjCClassDecl() const { if (!ObjCClassDecl) { QualType T = getObjCObjectType(ObjCBuiltinClassTy, 0, 0); @@ -4798,6 +4920,19 @@ TypedefDecl *ASTContext::getObjCClassDecl() const { return ObjCClassDecl; } +ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const { + if (!ObjCProtocolClassDecl) { + ObjCProtocolClassDecl + = ObjCInterfaceDecl::Create(*this, getTranslationUnitDecl(), + SourceLocation(), + &Idents.get("Protocol"), + /*PrevDecl=*/0, + SourceLocation(), true); + } + + return ObjCProtocolClassDecl; +} + void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) { assert(ObjCConstantStringType.isNull() && "'NSConstantString' type already set!"); @@ -4987,10 +5122,10 @@ CanQualType ASTContext::getFromTargetType(unsigned Type) const { /// garbage collection attribute. /// Qualifiers::GC ASTContext::getObjCGCAttrKind(QualType Ty) const { - if (getLangOptions().getGC() == LangOptions::NonGC) + if (getLangOpts().getGC() == LangOptions::NonGC) return Qualifiers::GCNone; - assert(getLangOptions().ObjC1); + assert(getLangOpts().ObjC1); Qualifiers::GC GCAttrs = Ty.getObjCGCAttr(); // Default behaviour under objective-C's gc is for ObjC pointers @@ -5059,7 +5194,7 @@ bool ASTContext::areCompatibleVectorTypes(QualType FirstVec, bool ASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, ObjCProtocolDecl *rProto) const { - if (lProto == rProto) + if (declaresSameEntity(lProto, rProto)) return true; for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(), E = rProto->protocol_end(); PI != E; ++PI) @@ -5360,7 +5495,7 @@ QualType ASTContext::areCommonBaseCompatible( const ObjCObjectType *RHS = Rptr->getObjectType(); const ObjCInterfaceDecl* LDecl = LHS->getInterface(); const ObjCInterfaceDecl* RDecl = RHS->getInterface(); - if (!LDecl || !RDecl || (LDecl == RDecl)) + if (!LDecl || !RDecl || (declaresSameEntity(LDecl, RDecl))) return QualType(); do { @@ -5484,7 +5619,7 @@ bool ASTContext::canBindObjCObjectType(QualType To, QualType From) { /// same. See 6.7.[2,3,5] for additional rules. bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS, bool CompareUnqualified) { - if (getLangOptions().CPlusPlus) + if (getLangOpts().CPlusPlus) return hasSameType(LHS, RHS); return !mergeTypes(LHS, RHS, false, CompareUnqualified).isNull(); @@ -5791,14 +5926,23 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, // Compatibility is based on the underlying type, not the promotion // type. if (const EnumType* ETy = LHS->getAs<EnumType>()) { - if (ETy->getDecl()->getIntegerType() == RHSCan.getUnqualifiedType()) + QualType TINT = ETy->getDecl()->getIntegerType(); + if (!TINT.isNull() && hasSameType(TINT, RHSCan.getUnqualifiedType())) return RHS; } if (const EnumType* ETy = RHS->getAs<EnumType>()) { - if (ETy->getDecl()->getIntegerType() == LHSCan.getUnqualifiedType()) + QualType TINT = ETy->getDecl()->getIntegerType(); + if (!TINT.isNull() && hasSameType(TINT, LHSCan.getUnqualifiedType())) return LHS; } - + // allow block pointer type to match an 'id' type. + if (OfBlockPointer && !BlockReturnType) { + if (LHS->isObjCIdType() && RHS->isBlockPointerType()) + return LHS; + if (RHS->isObjCIdType() && LHS->isBlockPointerType()) + return RHS; + } + return QualType(); } @@ -5959,7 +6103,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, LHS->getAs<ObjCObjectPointerType>(), RHS->getAs<ObjCObjectPointerType>(), BlockReturnType)) - return LHS; + return LHS; return QualType(); } if (canAssignObjCInterfaces(LHS->getAs<ObjCObjectPointerType>(), @@ -5967,10 +6111,10 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, return LHS; return QualType(); - } + } } - return QualType(); + llvm_unreachable("Invalid Type::Class!"); } bool ASTContext::FunctionTypesMatchOnNSConsumedAttrs( @@ -6333,6 +6477,9 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context, case 'D': Type = Context.getVolatileType(Type); break; + case 'R': + Type = Type.withRestrict(); + break; } } @@ -6425,7 +6572,7 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) { if (!FD->isInlined()) return External; - if (!getLangOptions().CPlusPlus || FD->hasAttr<GNUInlineAttr>()) { + if (!getLangOpts().CPlusPlus || FD->hasAttr<GNUInlineAttr>()) { // GNU or C99 inline semantics. Determine whether this symbol should be // externally visible. if (FD->isInlineDefinitionExternallyVisible()) @@ -6457,7 +6604,7 @@ GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { TSK = VD->getTemplateSpecializationKind(); Linkage L = VD->getLinkage(); - if (L == ExternalLinkage && getLangOptions().CPlusPlus && + if (L == ExternalLinkage && getLangOpts().CPlusPlus && VD->getType()->getLinkage() == UniqueExternalLinkage) L = UniqueExternalLinkage; @@ -6485,7 +6632,7 @@ GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { } } - return GVA_StrongExternal; + llvm_unreachable("Invalid Linkage!"); } bool ASTContext::DeclMustBeEmitted(const Decl *D) { @@ -6602,6 +6749,13 @@ size_t ASTContext::getSideTableAllocatedMemory() const { + llvm::capacity_in_bytes(ClassScopeSpecializationPattern); } +unsigned ASTContext::getLambdaManglingNumber(CXXMethodDecl *CallOperator) { + CXXRecordDecl *Lambda = CallOperator->getParent(); + return LambdaMangleContexts[Lambda->getDeclContext()] + .getManglingNumber(CallOperator); +} + + void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) { ParamIndices[D] = index; } |