From: Argyrios Kyrtzidis Date: Sat, 22 Sep 2012 01:58:06 +0000 (+0000) Subject: When importing a FunctionProtoType::ExtProtoInfo, its ExceptionSpecDecl can point... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f0fdefc13a58db2a8b32bb47ac23bc16efad6fda;p=clang When importing a FunctionProtoType::ExtProtoInfo, its ExceptionSpecDecl can point to the FunctionDecl that we are importing the FunctionProtoType for, in which case we'll have infinite recursion when importing. Initially create a FunctionProtoType with null ExceptionSpecDecl/ExceptionSpecTemplate and update the type in ASTNodeImporter::VisitFunctionDecl after the FunctionDecl has been created. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164450 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index e196387248..7639493cc5 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -1482,7 +1482,9 @@ ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) { T->getExtInfo()); } -QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) { +static QualType importFunctionProtoType(ASTImporter &Importer, + const FunctionProtoType *T, + bool importExceptionSpecDecls) { QualType ToResultType = Importer.Import(T->getResultType()); if (ToResultType.isNull()) return QualType(); @@ -1509,16 +1511,38 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) { ExceptionTypes.push_back(ExceptionType); } - FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo(); - EPI.Exceptions = ExceptionTypes.data(); - EPI.NoexceptExpr = Importer.Import(EPI.NoexceptExpr); - EPI.ExceptionSpecDecl - = cast_or_null(Importer.Import(EPI.ExceptionSpecDecl)); - EPI.ExceptionSpecTemplate - = cast_or_null(Importer.Import(EPI.ExceptionSpecTemplate)); - + FunctionProtoType::ExtProtoInfo FromEPI = T->getExtProtoInfo(); + FunctionProtoType::ExtProtoInfo ToEPI; + + ToEPI.ExtInfo = FromEPI.ExtInfo; + ToEPI.Variadic = FromEPI.Variadic; + ToEPI.HasTrailingReturn = FromEPI.HasTrailingReturn; + ToEPI.TypeQuals = FromEPI.TypeQuals; + ToEPI.RefQualifier = FromEPI.RefQualifier; + ToEPI.NumExceptions = ExceptionTypes.size(); + ToEPI.Exceptions = ExceptionTypes.data(); + ToEPI.ConsumedArguments = FromEPI.ConsumedArguments; + + if (importExceptionSpecDecls) { + ToEPI.ExceptionSpecType = FromEPI.ExceptionSpecType; + ToEPI.NoexceptExpr = Importer.Import(FromEPI.NoexceptExpr); + ToEPI.ExceptionSpecDecl = cast_or_null( + Importer.Import(FromEPI.ExceptionSpecDecl)); + ToEPI.ExceptionSpecTemplate = cast_or_null( + Importer.Import(FromEPI.ExceptionSpecTemplate)); + } + return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(), - ArgTypes.size(), EPI); + ArgTypes.size(), ToEPI); +} + +QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) { + // FunctionProtoType::ExtProtoInfo's ExceptionSpecDecl can point to the + // FunctionDecl that we are importing this FunctionProtoType for. + // Update it in ASTNodeImporter::VisitFunctionDecl after the FunctionDecl has + // been created. + return importFunctionProtoType(Importer, T, + /*importExceptionSpecDecls=*/false); } QualType ASTNodeImporter::VisitParenType(const ParenType *T) { @@ -2577,6 +2601,16 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { } ToFunction->setParams(Parameters); + // Update FunctionProtoType::ExtProtoInfo. + if (const FunctionProtoType * + FromFPT = D->getType()->getAs()) { + FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo(); + if (FromEPI.ExceptionSpecDecl || FromEPI.ExceptionSpecTemplate) { + ToFunction->setType(importFunctionProtoType(Importer, FromFPT, + /*importExceptionSpecDecls=*/true)); + } + } + // FIXME: Other bits to merge? // Add this function to the lexical context.