MCPcopy Create free account
hub / github.com/andreasfertig/cppinsights / InsertCoroutine

Method InsertCoroutine

CoroutinesCodeGenerator.cpp:415–709  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

413//-----------------------------------------------------------------------------
414
415void CoroutinesCodeGenerator::InsertCoroutine(const FunctionDecl& fd, const CoroutineBodyStmt* stmt)
416{
417 mOutputFormatHelper.OpenScope();
418
419 auto& ctx = GetGlobalAST();
420
421 mFSMName = [&] {
422 OutputFormatHelper ofm{};
423 CodeGeneratorVariant codeGenerator{ofm};
424
425 // Coroutines can be templates and then we end up with the same FSM name but different template parameters.
426 // XXX: This will fail with NTTP's like 3.14
427 if(const auto* args = fd.getTemplateSpecializationArgs()) {
428 ofm.Append('_');
429
430 for(OnceFalse needsUnderscore{}; const auto& arg : args->asArray()) {
431 if(needsUnderscore) {
432 ofm.Append('_');
433 }
434
435 codeGenerator->InsertTemplateArg(arg);
436 }
437 }
438
439 auto str = std::move(ofm.GetString());
440 ReplaceAll(str, "<"sv, ""sv);
441 ReplaceAll(str, ":"sv, ""sv);
442 ReplaceAll(str, ">"sv, ""sv);
443
444 str = BuildTemplateParamObjectName(str);
445
446 if(fd.isOverloadedOperator()) {
447 return StrCat(MakeLineColumnName(ctx.getSourceManager(), stmt->getBeginLoc(), "operator_"sv), str);
448 } else {
449 return StrCat(GetName(fd), str);
450 }
451 }();
452
453 mFrameName = BuildInternalVarName(StrCat(mFSMName, "Frame"sv));
454
455 // Insert a made up struct which holds the "captured" parameters stored in the coroutine frame
456 mASTData.mFrameType = Struct(mFrameName);
457 mASTData.mFrameAccessDeclRef = mkVarDeclRefExpr(CORO_FRAME_NAME, GetFrameType());
458
459 // The coroutine frame starts with two function pointers to the resume and destroy function. See:
460 // https://gcc.gnu.org/legacy-ml/gcc-patches/2020-01/msg01096.html:
461 // "The ABI mandates that pointers into the coroutine frame point to an area
462 // begining with two function pointers (to the resume and destroy functions
463 // described below); these are immediately followed by the "promise object"
464 // described in the standard."
465 //
466 // and
467 // https://llvm.org/docs/Coroutines.html#id72 "Coroutine Representation"
468 auto* resumeFnFd = Function(hlpResumeFn, VoidTy(), {{CORO_FRAME_NAME, GetFramePointerType()}});
469 auto resumeFnType = Ptr(resumeFnFd->getType());
470 mASTData.mResumeFnField = AddField(hlpResumeFn, resumeFnType);
471
472 auto* destroyFnFd = Function(hlpDestroyFn, VoidTy(), {{CORO_FRAME_NAME, GetFramePointerType()}});

Callers 1

InsertMethodBodyMethod · 0.80

Calls 15

ReplaceAllFunction · 0.85
StrCatFunction · 0.85
MakeLineColumnNameFunction · 0.85
GetNameFunction · 0.85
BuildInternalVarNameFunction · 0.85
StructFunction · 0.85
mkVarDeclRefExprFunction · 0.85
FunctionFunction · 0.85
VoidTyFunction · 0.85
PtrFunction · 0.85
AddFieldFunction · 0.85

Tested by

no test coverage detected