diff options
| -rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 13 | ||||
| -rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 14 | ||||
| -rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 35 |
3 files changed, 45 insertions, 17 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index fc8e9588469..72622531157 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -956,6 +956,12 @@ public: /// has type parameters, skipping any declarations that do not. ObjCTypeParamList *getTypeParamList() const; + /// Set the type parameters of this class. + /// + /// This function is used by the AST importer, which must import the type + /// parameters after creating their DeclContext to avoid loops. + void setTypeParamList(ObjCTypeParamList *TPL); + /// Retrieve the type parameters written on this particular declaration of /// the class. ObjCTypeParamList *getTypeParamListAsWritten() const { @@ -1963,6 +1969,13 @@ public: /// extension. ObjCTypeParamList *getTypeParamList() const { return TypeParamList; } + /// Set the type parameters of this category. + /// + /// This function is used by the AST importer, which must import the type + /// parameters after creating their DeclContext to avoid loops. + void setTypeParamList(ObjCTypeParamList *TPL); + + ObjCCategoryImplDecl *getImplementation() const; void setImplementation(ObjCCategoryImplDecl *ImplD); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 8460030b4b2..35c0f690db8 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3491,13 +3491,16 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) { Importer.Import(D->getCategoryNameLoc()), Name.getAsIdentifierInfo(), ToInterface, - ImportObjCTypeParamList( - D->getTypeParamList()), + /*TypeParamList=*/nullptr, Importer.Import(D->getIvarLBraceLoc()), Importer.Import(D->getIvarRBraceLoc())); ToCategory->setLexicalDeclContext(LexicalDC); LexicalDC->addDeclInternal(ToCategory); Importer.Imported(D, ToCategory); + // Import the type parameter list after calling Imported, to avoid + // loops when bringing in their DeclContext. + ToCategory->setTypeParamList(ImportObjCTypeParamList( + D->getTypeParamList())); // Import protocols SmallVector<ObjCProtocolDecl *, 4> Protocols; @@ -3819,14 +3822,17 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC, Importer.Import(D->getAtStartLoc()), Name.getAsIdentifierInfo(), - ImportObjCTypeParamList( - D->getTypeParamListAsWritten()), + /*TypeParamList=*/nullptr, /*PrevDecl=*/nullptr, Loc, D->isImplicitInterfaceDecl()); ToIface->setLexicalDeclContext(LexicalDC); LexicalDC->addDeclInternal(ToIface); } Importer.Imported(D, ToIface); + // Import the type parameter list after calling Imported, to avoid + // loops when bringing in their DeclContext. + ToIface->setTypeParamList(ImportObjCTypeParamList( + D->getTypeParamListAsWritten())); if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface)) return nullptr; diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index da4bc549cf4..b540e37cd07 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -259,6 +259,15 @@ ObjCTypeParamList *ObjCInterfaceDecl::getTypeParamList() const { 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()) @@ -1302,7 +1311,7 @@ ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, ObjCInterfaceDecl *PrevDecl, bool IsInternal) : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc), - redeclarable_base(C), TypeForDecl(nullptr), TypeParamList(typeParamList), + redeclarable_base(C), TypeForDecl(nullptr), TypeParamList(nullptr), Data() { setPreviousDecl(PrevDecl); @@ -1312,11 +1321,7 @@ ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, setImplicit(IsInternal); - // Update the declaration context of the type parameters. - if (typeParamList) { - for (auto typeParam : *typeParamList) - typeParam->setDeclContext(this); - } + setTypeParamList(typeParamList); } void ObjCInterfaceDecl::LoadExternalDefinition() const { @@ -1799,16 +1804,11 @@ ObjCCategoryDecl::ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, SourceLocation IvarLBraceLoc, SourceLocation IvarRBraceLoc) : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc), - ClassInterface(IDecl), TypeParamList(typeParamList), + ClassInterface(IDecl), TypeParamList(nullptr), NextClassCategory(nullptr), CategoryNameLoc(CategoryNameLoc), IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) { - // Set the declaration context of each of the type parameters. - if (typeParamList) { - for (auto typeParam : *typeParamList) { - typeParam->setDeclContext(this); - } - } + setTypeParamList(typeParamList); } ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC, @@ -1853,6 +1853,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 |

