@@ -113,6 +113,7 @@ class CodeGen {
113113 void generateTraits (const NodePtr &n);
114114 void generateRecordTraits (const NodePtr &n);
115115 void generateUnionTraits (const NodePtr &n);
116+ void generateDocComment (const NodePtr &n, const char *indent = " " );
116117 void emitCopyright ();
117118 void emitGeneratedWarning ();
118119
@@ -253,6 +254,7 @@ string CodeGen::generateRecordType(const NodePtr &n) {
253254 return it->second ;
254255 }
255256
257+ generateDocComment (n);
256258 os_ << " struct " << decoratedName << " {\n " ;
257259 if (!noUnion_) {
258260 for (size_t i = 0 ; i < c; ++i) {
@@ -271,6 +273,7 @@ string CodeGen::generateRecordType(const NodePtr &n) {
271273 // the nameAt(i) does not take c++ reserved words into account
272274 // so we need to call decorate on it
273275 std::string decoratedNameAt = decorate (n->nameAt (i));
276+ generateDocComment (n->leafAt (i), " " );
274277 os_ << " " << types[i];
275278 os_ << ' ' << decoratedNameAt << " ;\n " ;
276279 }
@@ -409,7 +412,7 @@ string CodeGen::generateUnionType(const NodePtr &n) {
409412 for (size_t i = 0 ; i < c; ++i) {
410413 // escape reserved literals for c++
411414 auto branch_name = decorate (names[i]);
412- // avoid rare collisions, e.g. somone might name their struct int_
415+ // avoid rare collisions, e.g. someone might name their struct int_
413416 if (used_branch_names.find (branch_name) != used_branch_names.end ()) {
414417 size_t postfix = 2 ;
415418 std::string escaped_name = branch_name + " _" + std::to_string (postfix);
@@ -739,6 +742,32 @@ void CodeGen::generateTraits(const NodePtr &n) {
739742 }
740743}
741744
745+ void CodeGen::generateDocComment (const NodePtr &n, const char *indent) {
746+ if (!n->getDoc ().empty ()) {
747+ std::vector<std::string> lines;
748+ boost::algorithm::split (lines, n->getDoc (), boost::algorithm::is_any_of (" \n " ));
749+ for (auto &line : lines) {
750+ boost::algorithm::replace_all (line, " \r " , " " );
751+
752+ if (line.empty ()) {
753+ os_ << indent << " //\n " ;
754+ } else {
755+ // If a comment line ends with a backslash or backslash and whitespace,
756+ // avoid generating code which will generate multi-line comment warnings
757+ // on GCC. We can't just append whitespace here as escaped newlines ignore
758+ // trailing whitespace.
759+ auto lastBackslash = std::find (line.rbegin (), line.rend (), ' \\ ' );
760+ auto lastNonWs = std::find_if (line.rbegin (), line.rend (), [](char c) { return !std::isspace (static_cast <int >(c)); });
761+ // Note: lastBackslash <= lastNonWs because the iterators are reversed, "less" is later in the string.
762+ if (lastBackslash != line.rend () && lastBackslash <= lastNonWs) {
763+ line.append (" (backslash)" );
764+ }
765+ os_ << indent << " // " << line << " \n " ;
766+ }
767+ }
768+ }
769+ }
770+
742771void CodeGen::emitCopyright () {
743772 os_ << " /**\n "
744773 " * Licensed to the Apache Software Foundation (ASF) under one\n "
@@ -954,4 +983,4 @@ bool UnionCodeTracker::unionTraitsAlreadyGenerated(const std::string &unionClass
954983
955984void UnionCodeTracker::setTraitsGenerated (const std::string &unionClassName) {
956985 generatedUnionTraits_.insert (unionClassName);
957- }
986+ }
0 commit comments