Repository: carbon-language/carbon-lang
File: toolchain/check/import_cpp.cpp (C++)

Code before:
#include "toolchain/check/type.h"
#include "toolchain/diagnostics/diagnostic.h"
#include "toolchain/diagnostics/format_providers.h"
#include "toolchain/parse/node_ids.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/name_scope.h"
#include "toolchain/sem_ir/typed_insts.h"

namespace Carbon::Check {

// Generates C++ file contents to #include all requested imports.
static auto GenerateCppIncludesHeaderCode(
    Context& context, llvm::ArrayRef<Parse::Tree::PackagingNames> imports)
    -> std::string {
  std::string code;
  llvm::raw_string_ostream code_stream(code);
  for (const Parse::Tree::PackagingNames& import : imports) {
    // Add a line marker directive pointing at the location of the `import Cpp`
    // declaration in the Carbon source file. This will cause Clang's
    // diagnostics machinery to track and report the location in Carbon code
    // where the import was written.
    auto import_loc = context.tokens().TokenToDiagnosticLoc(
        context.parse_tree().node_token(import.node_id));
    code_stream << "# " << import_loc.loc.line_number << " \"";
    code_stream.write_escaped(import_loc.loc.filename);
    code_stream << "\"\n";

    code_stream << "#include \""
                << FormatEscaped(
                       context.string_literal_values().Get(import.library_id))
                << "\"\n";
  }
  return code;
}

// Adds the name to the scope with the given `inst_id`, if the `inst_id` is not
// `None`.
static auto AddNameToScope(Context& context, SemIR::NameScopeId scope_id,
                           SemIR::NameId name_id, SemIR::InstId inst_id)
    -> void {
  if (inst_id.has_value()) {
    context.name_scopes().AddRequiredName(scope_id, name_id, inst_id);
  }
}

// Maps a Clang name to a Carbon `NameId`.
static auto AddIdentifierName(Context& context, llvm::StringRef name)
    -> SemIR::NameId {
  return SemIR::NameId::ForIdentifier(context.identifiers().Add(name));
}


Review comment (security):
There's a helper for write_escaped:

```suggestion
    code_stream << "# " << import_loc.loc.line_number << " \"" << FormatEscaped(import_loc.loc.filename) << "\"\n";
```

Code after:
#include "toolchain/check/pattern_match.h"
#include "toolchain/check/type.h"
#include "toolchain/diagnostics/diagnostic.h"
#include "toolchain/diagnostics/format_providers.h"
#include "toolchain/parse/node_ids.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/name_scope.h"
#include "toolchain/sem_ir/typed_insts.h"

namespace Carbon::Check {

// Generates C++ file contents to #include all requested imports.
static auto GenerateCppIncludesHeaderCode(
    Context& context, llvm::ArrayRef<Parse::Tree::PackagingNames> imports)
    -> std::string {
  std::string code;
  llvm::raw_string_ostream code_stream(code);
  for (const Parse::Tree::PackagingNames& import : imports) {
    // Add a line marker directive pointing at the location of the `import Cpp`
    // declaration in the Carbon source file. This will cause Clang's
    // diagnostics machinery to track and report the location in Carbon code
    // where the import was written.
    auto token = context.parse_tree().node_token(import.node_id);
    code_stream << "# " << context.tokens().GetLineNumber(token) << " \""
                << FormatEscaped(context.tokens().source().filename())
                << "\"\n";

    code_stream << "#include \""
                << FormatEscaped(
                       context.string_literal_values().Get(import.library_id))
                << "\"\n";
  }
  return code;
}

// Adds the name to the scope with the given `inst_id`, if the `inst_id` is not
// `None`.
static auto AddNameToScope(Context& context, SemIR::NameScopeId scope_id,
                           SemIR::NameId name_id, SemIR::InstId inst_id)
    -> void {
  if (inst_id.has_value()) {
    context.name_scopes().AddRequiredName(scope_id, name_id, inst_id);
  }
}

// Maps a Clang name to a Carbon `NameId`.
static auto AddIdentifierName(Context& context, llvm::StringRef name)
    -> SemIR::NameId {
  return SemIR::NameId::ForIdentifier(context.identifiers().Add(name));
}