summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/DeclObjC.h13
-rw-r--r--clang/lib/AST/ASTImporter.cpp14
-rw-r--r--clang/lib/AST/DeclObjC.cpp35
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
OpenPOWER on IntegriCloud