Skip to content

Commit 347c1c2

Browse files
committed
Add support for .h2 headers
A `.cpp2` is emitted as a `.cpp` that contains two parts: Cpp2 declarations in-place interleaved where declared in the Cpp1 source, then all the Cpp2 definitions. This is what gives Cpp2 order-independent semantics. A `.h2` is emitted the same way, but: - authoring: split into two files (`.h` for the declarations and Cpp1 source, `.hpp` for the definitions) - consumption: any `#include "something.h2"` is emitted as an `#include "something.h"` in its original location relative to the Cpp1 source, and an `#include "something.hpp"` at the beginning of the Cpp2 definitions section
1 parent 8a67027 commit 347c1c2

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

source/cppfront.cpp

+38-7
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ static auto flag_cpp1_filename = std::string{};
110110
static cmdline_processor::register_flag cmd_cpp1_filename(
111111
9,
112112
"output",
113-
"Output filename, or 'stdout' (default is *.cpp)",
113+
"Output filename, or 'stdout' (default is *.cpp/*.h)",
114114
nullptr,
115115
[](std::string const& name) { flag_cpp1_filename = name; }
116116
);
@@ -423,6 +423,16 @@ class positional_printer
423423
pcomments = &comments;
424424
}
425425

426+
auto reopen() -> void
427+
{
428+
assert (is_open() && "ICE: tried to call .reopen without first calling .open");
429+
if (cpp1_filename.ends_with(".h"))
430+
{
431+
out_file.close();
432+
out_file.open(cpp1_filename + "pp");
433+
}
434+
}
435+
426436
auto is_open() -> bool {
427437
if (out) {
428438
assert (pcomments && "ICE: if is_open, pcomments should also be set");
@@ -753,11 +763,11 @@ class cppfront
753763
// "Constraints enable creativity in the right directions"
754764
// sort of applies here
755765
//
756-
if (!sourcefile.ends_with(".cpp2"))
766+
if (!sourcefile.ends_with(".cpp2") && !sourcefile.ends_with(".h2"))
757767
{
758768
errors.emplace_back(
759769
source_position(-1, -1),
760-
"source filename must end with .cpp2: " + sourcefile
770+
"source filename must end with .cpp2 or .h2: " + sourcefile
761771
);
762772
}
763773

@@ -812,7 +822,7 @@ class cppfront
812822
//-----------------------------------------------------------------------
813823
// lower_to_cpp1
814824
//
815-
// Emits the target file with the last '2' stripped -> .cpp
825+
// Emits the target file with the last '2' stripped
816826
//
817827
auto lower_to_cpp1() -> void
818828
{
@@ -821,7 +831,7 @@ class cppfront
821831
return;
822832
}
823833

824-
// Now we'll open the .cpp file
834+
// Now we'll open the Cpp1 file
825835
auto cpp1_filename = sourcefile.substr(0, std::ssize(sourcefile) - 1);
826836
if (!flag_cpp1_filename.empty()) {
827837
cpp1_filename = flag_cpp1_filename; // use override if present
@@ -862,6 +872,7 @@ class cppfront
862872
}
863873

864874
auto map_iter = tokens.get_map().cbegin();
875+
auto hpp_includes = std::string{};
865876

866877
// First, echo the non-Cpp2 parts
867878
//
@@ -899,7 +910,15 @@ class cppfront
899910
return;
900911
}
901912

902-
printer.print_cpp1( line.text, curr_lineno );
913+
if (line.cat == source_line::category::preprocessor && line.text.ends_with(".h2\"")) {
914+
// Strip off the 2"
915+
auto h_include = line.text.substr(0, line.text.size()-2);
916+
printer.print_cpp1( h_include + "\"", curr_lineno );
917+
hpp_includes += h_include + "pp\"\n";
918+
}
919+
else {
920+
printer.print_cpp1( line.text, curr_lineno );
921+
}
903922
}
904923

905924
// If it's a Cpp2 line...
@@ -939,6 +958,16 @@ class cppfront
939958
}
940959

941960
// If there is Cpp2 code, we have more to do...
961+
// First, if this is a .h2 we need to switch filenames
962+
printer.reopen();
963+
if (!printer.is_open()) {
964+
errors.emplace_back(
965+
source_position{},
966+
"could not open second output file " + cpp1_filename
967+
);
968+
return;
969+
}
970+
942971
// Next, bring in the Cpp2 helpers
943972
//
944973
if (!flag_clean_cpp1) {
@@ -947,6 +976,8 @@ class cppfront
947976

948977
// Next, emit the Cpp2 definitions
949978
//
979+
printer.print_extra( hpp_includes );
980+
950981
printer.enable_definitions();
951982

952983
for (auto& section : tokens.get_map())
@@ -2911,7 +2942,7 @@ auto main(int argc, char* argv[]) -> int
29112942
return EXIT_FAILURE;
29122943
}
29132944

2914-
// For each .cpp2 source file
2945+
// For each Cpp2 source file
29152946
int exit_status = EXIT_SUCCESS;
29162947
for (auto const& arg : cmdline.arguments())
29172948
{

0 commit comments

Comments
 (0)