@@ -149,65 +149,6 @@ substituteFunctionTypeAndParamList(ASTContext &ctx, AbstractFunctionDecl *fdecl,
149149 return {newFnType, newParamList};
150150}
151151
152- static ValueDecl *generateSpecializedCXXFunctionTemplate (
153- ASTContext &ctx, AbstractFunctionDecl *oldDecl, SubstitutionMap subst,
154- clang::FunctionDecl *specialized) {
155- auto newFnTypeAndParams = substituteFunctionTypeAndParamList (ctx, oldDecl, subst);
156- auto newFnType = newFnTypeAndParams.first ;
157- auto paramList = newFnTypeAndParams.second ;
158-
159- SmallVector<ParamDecl *, 4 > newParamsWithoutMetatypes;
160- for (auto param : *paramList ) {
161- if (isa<FuncDecl>(oldDecl) &&
162- isa<MetatypeType>(param->getType ().getPointer ())) {
163- // Metatype parameters are added synthetically to account for template
164- // params that don't make it to the function signature. These shouldn't
165- // exist in the resulting specialized FuncDecl. Note that this doesn't
166- // affect constructors because all template params for a constructor
167- // must be in the function signature by design.
168- continue ;
169- }
170- newParamsWithoutMetatypes.push_back (param);
171- }
172- auto *newParamList =
173- ParameterList::create (ctx, SourceLoc (), newParamsWithoutMetatypes, SourceLoc ());
174-
175- if (isa<ConstructorDecl>(oldDecl)) {
176- DeclName ctorName (ctx, DeclBaseName::createConstructor (), newParamList);
177- auto newCtorDecl = ConstructorDecl::createImported (
178- ctx, specialized, ctorName, oldDecl->getLoc (),
179- /* failable=*/ false , /* failabilityLoc=*/ SourceLoc (),
180- /* Async=*/ false , /* AsyncLoc=*/ SourceLoc (),
181- /* throws=*/ false , /* throwsLoc=*/ SourceLoc (),
182- newParamList, /* genericParams=*/ nullptr ,
183- oldDecl->getDeclContext ());
184- return newCtorDecl;
185- }
186-
187- // Generate a name for the specialized function.
188- std::string newNameStr;
189- llvm::raw_string_ostream buffer (newNameStr);
190- std::unique_ptr<clang::MangleContext> mangler (
191- specialized->getASTContext ().createMangleContext ());
192- mangler->mangleName (specialized, buffer);
193- buffer.flush ();
194- // Add all parameters as empty parameters.
195- auto newName = DeclName (
196- ctx, DeclName (ctx.getIdentifier (newNameStr)).getBaseName (), newParamList);
197-
198- auto newFnDecl = FuncDecl::createImported (
199- ctx, oldDecl->getLoc (), newName, oldDecl->getNameLoc (),
200- /* Async=*/ false , oldDecl->hasThrows (), newParamList,
201- newFnType->getResult (), /* GenericParams=*/ nullptr ,
202- oldDecl->getDeclContext (), specialized);
203- if (oldDecl->isStatic ()) {
204- newFnDecl->setStatic ();
205- newFnDecl->setImportAsStaticMember ();
206- }
207- newFnDecl->setSelfAccessKind (cast<FuncDecl>(oldDecl)->getSelfAccessKind ());
208- return newFnDecl;
209- }
210-
211152// Synthesizes the body of a thunk that takes extra metatype arguments and
212153// skips over them to forward them along to the FuncDecl contained by context.
213154// This is used when importing a C++ templated function where the template params
@@ -285,8 +226,13 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
285226 const_cast <clang::FunctionTemplateDecl *>(
286227 cast<clang::FunctionTemplateDecl>(decl->getClangDecl ())),
287228 subst);
288- auto newDecl = generateSpecializedCXXFunctionTemplate (
289- decl->getASTContext (), cast<AbstractFunctionDecl>(decl), subst, newFn);
229+ // We failed to specialize this function template. The compiler is going to
230+ // exit soon. Return something valid in the meantime.
231+ if (!newFn)
232+ return ConcreteDeclRef (decl);
233+
234+ auto newDecl = cast<ValueDecl>(decl->getASTContext ().getClangModuleLoader ()->importDeclDirectly (newFn));
235+
290236 if (auto fn = dyn_cast<FuncDecl>(decl)) {
291237 if (newFn->getNumParams () != fn->getParameters ()->size ()) {
292238 // We added additional metatype parameters to aid template
0 commit comments