Repository: apple/swift
File: lib/ClangImporter/SwiftDeclSynthesizer.cpp (C++)

Code before:
    clone = new (C) FloatLiteralExpr(floatLit->getDigitsText(), expr->getLoc(),
                                     /*implicit*/ true);
    if (floatLit->isNegative())
      cast<FloatLiteralExpr>(clone)->setNegative(expr->getLoc());
  } else {
    llvm_unreachable("invalid raw literal expr");
  }
  clone->setImplicit();
  return clone;
}

/// Synthesize the body of \c init?(rawValue:RawType) for an imported enum.
///
/// For non-frozen (open) enums, this generates:
///   init?(rawValue: RawType) {
///     self = Builtin.reinterpretCast(rawValue)
///   }
/// This allows arbitrary raw values for C compatibility.
///
/// For frozen (closed) enums, this generates:
///   init?(rawValue: RawType) {
///     switch rawValue {
///     case <value1>:
///       self = Builtin.reinterpretCast(rawValue)
///     case <value2>:
///       self = Builtin.reinterpretCast(rawValue)
///     ...
///     default:
///       return nil
///     }
///   }
/// This ensures that only declared raw values are accepted.
static std::pair<BraceStmt *, bool>
synthesizeEnumRawValueConstructorBody(AbstractFunctionDecl *afd,
                                      void *context) {
  ASTContext &ctx = afd->getASTContext();

  auto ctorDecl = cast<ConstructorDecl>(afd);
  auto enumDecl = static_cast<EnumDecl *>(context);
  auto selfDecl = ctorDecl->getImplicitSelfDecl();
  auto selfRef = new (ctx) DeclRefExpr(selfDecl, DeclNameLoc(),
                                       /*implicit*/ true);
  selfRef->setType(LValueType::get(selfDecl->getTypeInContext()));

  auto param = ctorDecl->getParameters()->get(0);
  auto paramRef = new (ctx) DeclRefExpr(param, DeclNameLoc(),
                                        /*implicit*/ true);
  paramRef->setType(param->getTypeInContext());

  auto reinterpretCast = cast<FuncDecl>(
      getBuiltinValueDecl(ctx, ctx.getIdentifier("reinterpretCast")));

Review comment (suggestion):
nit: this comment should be updated to reflect the most recent change:

```suggestion
///   init?(rawValue: RawType) {
///     switch rawValue {
///     case <value1>, <value2>, ...:
///       self = Builtin.reinterpretCast(rawValue)
///     default:
///       return nil
```

Code after:
    clone = new (C) FloatLiteralExpr(floatLit->getDigitsText(), expr->getLoc(),
                                     /*implicit*/ true);
    if (floatLit->isNegative())
      cast<FloatLiteralExpr>(clone)->setNegative(expr->getLoc());
  } else {
    llvm_unreachable("invalid raw literal expr");
  }
  clone->setImplicit();
  return clone;
}

/// Synthesize the body of \c init?(rawValue:RawType) for an imported enum.
///
/// For non-frozen (open) enums, this generates:
///   init?(rawValue: RawType) {
///     self = Builtin.reinterpretCast(rawValue)
///   }
/// This allows arbitrary raw values for C compatibility.
///
/// For frozen (closed) enums, this generates:
///   init?(rawValue: RawType) {
///     switch rawValue {
///     case <value1>, <value2>, ...:
///       self = Builtin.reinterpretCast(rawValue)
///     default:
///       return nil
///     }
///   }
/// This ensures that only declared raw values are accepted.
static std::pair<BraceStmt *, bool>
synthesizeEnumRawValueConstructorBody(AbstractFunctionDecl *afd,
                                      void *context) {
  ASTContext &ctx = afd->getASTContext();

  auto ctorDecl = cast<ConstructorDecl>(afd);
  auto enumDecl = static_cast<EnumDecl *>(context);
  auto selfDecl = ctorDecl->getImplicitSelfDecl();
  auto selfRef = new (ctx) DeclRefExpr(selfDecl, DeclNameLoc(),
                                       /*implicit*/ true);
  selfRef->setType(LValueType::get(selfDecl->getTypeInContext()));

  auto param = ctorDecl->getParameters()->get(0);
  auto paramRef = new (ctx) DeclRefExpr(param, DeclNameLoc(),
                                        /*implicit*/ true);
  paramRef->setType(param->getTypeInContext());

  auto reinterpretCast = cast<FuncDecl>(
      getBuiltinValueDecl(ctx, ctx.getIdentifier("reinterpretCast")));
  auto rawTy = enumDecl->getRawType();
  auto enumTy = enumDecl->getDeclaredInterfaceType();
  SubstitutionMap subMap = SubstitutionMap::get(