<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div><div>Hi Aleksei,</div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" cite="mid:CAH6rKyCELnyVYeguSFfi=i_N+UyVMvJYaO=RnaZM2Mr3q_dCDQ@mail.gmail.com" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><blockquote type="cite" class=""><pre wrap="" class="">
The problem of improving readability of these checks is a bit harder. The
most straightforward approach is to create a macro like:

#define IMPORT_PTR_INTO_VAR(VarName, Type, From) \
  Type *VarName = nullptr;                                 \
  {                                                        \
    auto MacroImportRes = Importer.Import(From);           \
    if (!MacroImportRes)                                   \
      return MacroImportRes.getError();                    \
    VarName = *MacroImportRes;                             \
  }

Same for non-pointer type. So, the final code will look like this:

ErrorOr<Expr *> ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr
*E) {
  IMPORT_QUAL_TYPE_INTO_VAR(T, E->getType())
  IMPORT_PTR_INTO_VAR(ToFn, Expr, E->getCallee())

  SmallVector<Expr *, 4> ToArgs(E->getNumArgs());
  IMPORT_CONTAINER(E->arguments(), ToArgs);

  return new (Importer.getToContext()) CXXMemberCallExpr(
        Importer.getToContext(), ToFn, ToArgs, T, E->getValueKind(),
        Importer.Import(E->getRParenLoc()));
}

But macros don't look clean. Unfortunately, I still haven't found a better
option so any suggestions are very welcome.
</pre></blockquote></blockquote></div></blockquote></div></div></div></blockquote><div><div><br class=""></div><div>Macros are indeed ugly, and exceptions are even worse.</div><div>I think a better solution would be to return an Optional, and make `Importer.Import` accept an out-parameter `Error`, passed by reference.</div><div>Then you could write:</div><div><br class=""></div><div>Optional<Expr*> VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {</div><div>  Error e;</div><div>  if (auto T = Importer.import(E->getType(), e))</div><div>    if (auto ToFn = Importer.import(E->getCallee(), e))</div><div>      if (auto ToArgs = Importer.import(E->arguments(), e)</div><div>        return new (Importer.getToContext()) CXXMemberCallExpr(…)</div><div>  outE = e;</div><div>  return none;</div><div>}</div><div><br class=""></div><div>That’s even more concise than your example, explicit and does not need macros.</div><div><br class=""></div><div>This would be less verbose in C++17 where you would not need nested if’s,</div><div>but sadly we don’t have that in LLVM yet.<span class="Apple-tab-span" style="white-space:pre">        </span></div><div><br class=""></div><div>George</div></div></div></body></html>