diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp | 214 |
1 files changed, 205 insertions, 9 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp b/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp index a1600cb..280c412 100644 --- a/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp +++ b/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp @@ -239,6 +239,62 @@ ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration( void ObjCInterfaceDecl::anchor() { } +ObjCTypeParamList *ObjCInterfaceDecl::getTypeParamList() const { + // If this particular declaration has a type parameter list, return it. + if (ObjCTypeParamList *written = getTypeParamListAsWritten()) + return written; + + // If there is a definition, return its type parameter list. + if (const ObjCInterfaceDecl *def = getDefinition()) + return def->getTypeParamListAsWritten(); + + // Otherwise, look at previous declarations to determine whether any + // of them has a type parameter list, skipping over those + // declarations that do not. + for (auto decl = getMostRecentDecl(); decl; decl = decl->getPreviousDecl()) { + if (ObjCTypeParamList *written = decl->getTypeParamListAsWritten()) + return written; + } + + return nullptr; +} + +void ObjCInterfaceDecl::setTypeParamList(ObjCTypeParamList *TPL) { + TypeParamList = TPL; + if (!TPL) + return; + // Set the declaration context of each of the type parameters. + for (auto typeParam : *TypeParamList) + typeParam->setDeclContext(this); +} + +ObjCInterfaceDecl *ObjCInterfaceDecl::getSuperClass() const { + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return nullptr; + + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + if (const ObjCObjectType *superType = getSuperClassType()) { + if (ObjCInterfaceDecl *superDecl = superType->getInterface()) { + if (ObjCInterfaceDecl *superDef = superDecl->getDefinition()) + return superDef; + + return superDecl; + } + } + + return nullptr; +} + +SourceLocation ObjCInterfaceDecl::getSuperClassLoc() const { + if (TypeSourceInfo *superTInfo = getSuperClassTInfo()) + return superTInfo->getTypeLoc().getLocStart(); + + return SourceLocation(); +} + /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property /// with name 'PropertyId' in the primary class; including those in protocols /// (direct or indirect) used by the primary class. @@ -889,9 +945,13 @@ ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const { return family; } -void ObjCMethodDecl::createImplicitParams(ASTContext &Context, - const ObjCInterfaceDecl *OID) { +QualType ObjCMethodDecl::getSelfType(ASTContext &Context, + const ObjCInterfaceDecl *OID, + bool &selfIsPseudoStrong, + bool &selfIsConsumed) { QualType selfTy; + selfIsPseudoStrong = false; + selfIsConsumed = false; if (isInstanceMethod()) { // There may be no interface context due to error in declaration // of the interface (which has been reported). Recover gracefully. @@ -904,9 +964,6 @@ void ObjCMethodDecl::createImplicitParams(ASTContext &Context, } else // we have a factory method. selfTy = Context.getObjCClassType(); - bool selfIsPseudoStrong = false; - bool selfIsConsumed = false; - if (Context.getLangOpts().ObjCAutoRefCount) { if (isInstanceMethod()) { selfIsConsumed = hasAttr<NSConsumesSelfAttr>(); @@ -930,7 +987,14 @@ void ObjCMethodDecl::createImplicitParams(ASTContext &Context, selfIsPseudoStrong = true; } } + return selfTy; +} +void ObjCMethodDecl::createImplicitParams(ASTContext &Context, + const ObjCInterfaceDecl *OID) { + bool selfIsPseudoStrong, selfIsConsumed; + QualType selfTy = + getSelfType(Context, OID, selfIsPseudoStrong, selfIsConsumed); ImplicitParamDecl *self = ImplicitParamDecl::Create(Context, this, SourceLocation(), &Context.Idents.get("self"), selfTy); @@ -966,6 +1030,20 @@ SourceRange ObjCMethodDecl::getReturnTypeSourceRange() const { return SourceRange(); } +QualType ObjCMethodDecl::getSendResultType() const { + ASTContext &Ctx = getASTContext(); + return getReturnType().getNonLValueExprType(Ctx) + .substObjCTypeArgs(Ctx, {}, ObjCSubstitutionContext::Result); +} + +QualType ObjCMethodDecl::getSendResultType(QualType receiverType) const { + // FIXME: Handle related result types here. + + return getReturnType().getNonLValueExprType(getASTContext()) + .substObjCMemberType(receiverType, getDeclContext(), + ObjCSubstitutionContext::Result); +} + static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container, const ObjCMethodDecl *Method, SmallVectorImpl<const ObjCMethodDecl *> &Methods, @@ -1137,6 +1215,81 @@ ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const { } //===----------------------------------------------------------------------===// +// ObjCTypeParamDecl +//===----------------------------------------------------------------------===// + +void ObjCTypeParamDecl::anchor() { } + +ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc, + ObjCTypeParamVariance variance, + SourceLocation varianceLoc, + unsigned index, + SourceLocation nameLoc, + IdentifierInfo *name, + SourceLocation colonLoc, + TypeSourceInfo *boundInfo) { + return new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index, + nameLoc, name, colonLoc, boundInfo); +} + +ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx, + unsigned ID) { + return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr, + ObjCTypeParamVariance::Invariant, + SourceLocation(), 0, SourceLocation(), + nullptr, SourceLocation(), nullptr); +} + +SourceRange ObjCTypeParamDecl::getSourceRange() const { + SourceLocation startLoc = VarianceLoc; + if (startLoc.isInvalid()) + startLoc = getLocation(); + + if (hasExplicitBound()) { + return SourceRange(startLoc, + getTypeSourceInfo()->getTypeLoc().getEndLoc()); + } + + return SourceRange(startLoc); +} + +//===----------------------------------------------------------------------===// +// ObjCTypeParamList +//===----------------------------------------------------------------------===// +ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc, + ArrayRef<ObjCTypeParamDecl *> typeParams, + SourceLocation rAngleLoc) + : NumParams(typeParams.size()) +{ + Brackets.Begin = lAngleLoc.getRawEncoding(); + Brackets.End = rAngleLoc.getRawEncoding(); + std::copy(typeParams.begin(), typeParams.end(), begin()); +} + + +ObjCTypeParamList *ObjCTypeParamList::create( + ASTContext &ctx, + SourceLocation lAngleLoc, + ArrayRef<ObjCTypeParamDecl *> typeParams, + SourceLocation rAngleLoc) { + unsigned size = sizeof(ObjCTypeParamList) + + sizeof(ObjCTypeParamDecl *) * typeParams.size(); + static_assert(llvm::AlignOf<ObjCTypeParamList>::Alignment >= + llvm::AlignOf<ObjCTypeParamDecl *>::Alignment, + "type parameter list needs greater alignment"); + unsigned align = llvm::alignOf<ObjCTypeParamList>(); + void *mem = ctx.Allocate(size, align); + return new (mem) ObjCTypeParamList(lAngleLoc, typeParams, rAngleLoc); +} + +void ObjCTypeParamList::gatherDefaultTypeArgs( + SmallVectorImpl<QualType> &typeArgs) const { + typeArgs.reserve(size()); + for (auto typeParam : *this) + typeArgs.push_back(typeParam->getUnderlyingType()); +} + +//===----------------------------------------------------------------------===// // ObjCInterfaceDecl //===----------------------------------------------------------------------===// @@ -1144,11 +1297,13 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, + ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc, bool isInternal){ ObjCInterfaceDecl *Result = new (C, DC) - ObjCInterfaceDecl(C, DC, atLoc, Id, ClassLoc, PrevDecl, isInternal); + ObjCInterfaceDecl(C, DC, atLoc, Id, typeParamList, ClassLoc, PrevDecl, + isInternal); Result->Data.setInt(!C.getLangOpts().Modules); C.getObjCInterfaceType(Result, PrevDecl); return Result; @@ -1159,6 +1314,7 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C, ObjCInterfaceDecl *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, + nullptr, SourceLocation(), nullptr, false); Result->Data.setInt(!C.getLangOpts().Modules); @@ -1167,11 +1323,13 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C, ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc, IdentifierInfo *Id, + ObjCTypeParamList *typeParamList, SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, bool IsInternal) : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc), - redeclarable_base(C), TypeForDecl(nullptr), Data() { + redeclarable_base(C), TypeForDecl(nullptr), TypeParamList(nullptr), + Data() { setPreviousDecl(PrevDecl); // Copy the 'data' pointer over. @@ -1179,6 +1337,8 @@ ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, Data = PrevDecl->Data; setImplicit(IsInternal); + + setTypeParamList(typeParamList); } void ObjCInterfaceDecl::LoadExternalDefinition() const { @@ -1492,6 +1652,11 @@ const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const { } } +QualType ObjCIvarDecl::getUsageType(QualType objectType) const { + return getType().substObjCMemberType(objectType, getDeclContext(), + ObjCSubstitutionContext::Property); +} + //===----------------------------------------------------------------------===// // ObjCAtDefsFieldDecl //===----------------------------------------------------------------------===// @@ -1648,17 +1813,34 @@ ObjCProtocolDecl::getObjCRuntimeNameAsString() const { void ObjCCategoryDecl::anchor() { } +ObjCCategoryDecl::ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, + SourceLocation ClassNameLoc, + SourceLocation CategoryNameLoc, + IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, + ObjCTypeParamList *typeParamList, + SourceLocation IvarLBraceLoc, + SourceLocation IvarRBraceLoc) + : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc), + ClassInterface(IDecl), TypeParamList(nullptr), + NextClassCategory(nullptr), CategoryNameLoc(CategoryNameLoc), + IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) +{ + setTypeParamList(typeParamList); +} + ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, + ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc, SourceLocation IvarRBraceLoc) { ObjCCategoryDecl *CatDecl = new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id, - IDecl, IvarLBraceLoc, IvarRBraceLoc); + IDecl, typeParamList, IvarLBraceLoc, + IvarRBraceLoc); if (IDecl) { // Link this category into its class's category list. CatDecl->NextClassCategory = IDecl->getCategoryListRaw(); @@ -1676,7 +1858,7 @@ ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(), SourceLocation(), SourceLocation(), - nullptr, nullptr); + nullptr, nullptr, nullptr); } ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const { @@ -1688,6 +1870,15 @@ void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) { getASTContext().setObjCImplementation(this, ImplD); } +void ObjCCategoryDecl::setTypeParamList(ObjCTypeParamList *TPL) { + TypeParamList = TPL; + if (!TPL) + return; + // Set the declaration context of each of the type parameters. + for (auto typeParam : *TypeParamList) + typeParam->setDeclContext(this); +} + //===----------------------------------------------------------------------===// // ObjCCategoryImplDecl @@ -1876,6 +2067,11 @@ ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C, QualType(), nullptr, None); } +QualType ObjCPropertyDecl::getUsageType(QualType objectType) const { + return DeclType.substObjCMemberType(objectType, getDeclContext(), + ObjCSubstitutionContext::Property); +} + //===----------------------------------------------------------------------===// // ObjCPropertyImplDecl //===----------------------------------------------------------------------===// |