|
14 | 14 | #include "flang/Evaluate/fold.h"
|
15 | 15 | #include "flang/Evaluate/tools.h"
|
16 | 16 | #include "flang/Parser/characters.h"
|
| 17 | +#include "flang/Semantics/semantics.h" |
17 | 18 | #include "flang/Semantics/symbol.h"
|
18 | 19 | #include "llvm/Support/raw_ostream.h"
|
19 | 20 |
|
@@ -53,7 +54,7 @@ static void ShapeAsFortran(llvm::raw_ostream &o,
|
53 | 54 |
|
54 | 55 | template <typename RESULT, typename VALUE>
|
55 | 56 | llvm::raw_ostream &ConstantBase<RESULT, VALUE>::AsFortran(
|
56 |
| - llvm::raw_ostream &o, const parser::CharBlock *derivedTypeRename) const { |
| 57 | + llvm::raw_ostream &o) const { |
57 | 58 | bool hasNonDefaultLowerBound{printLbounds && HasNonDefaultLowerBound()};
|
58 | 59 | if (Rank() > 1 || hasNonDefaultLowerBound) {
|
59 | 60 | o << "reshape(";
|
@@ -85,8 +86,7 @@ llvm::raw_ostream &ConstantBase<RESULT, VALUE>::AsFortran(
|
85 | 86 | o << ".false." << '_' << Result::kind;
|
86 | 87 | }
|
87 | 88 | } else {
|
88 |
| - StructureConstructor{result_.derivedTypeSpec(), value}.AsFortran( |
89 |
| - o, derivedTypeRename); |
| 89 | + StructureConstructor{result_.derivedTypeSpec(), value}.AsFortran(o); |
90 | 90 | }
|
91 | 91 | }
|
92 | 92 | if (Rank() > 0) {
|
@@ -124,9 +124,89 @@ llvm::raw_ostream &Constant<Type<TypeCategory::Character, KIND>>::AsFortran(
|
124 | 124 | return o;
|
125 | 125 | }
|
126 | 126 |
|
| 127 | +llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const Symbol &symbol, |
| 128 | + std::optional<parser::CharBlock> name = std::nullopt) { |
| 129 | + const auto &renamings{symbol.owner().context().moduleFileOutputRenamings()}; |
| 130 | + if (auto iter{renamings.find(&symbol)}; iter != renamings.end()) { |
| 131 | + return o << iter->second.ToString(); |
| 132 | + } else if (name) { |
| 133 | + return o << name->ToString(); |
| 134 | + } else { |
| 135 | + return o << symbol.name().ToString(); |
| 136 | + } |
| 137 | +} |
| 138 | + |
| 139 | +llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::string &lit) { |
| 140 | + return o << parser::QuoteCharacterLiteral(lit); |
| 141 | +} |
| 142 | + |
| 143 | +llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::u16string &lit) { |
| 144 | + return o << parser::QuoteCharacterLiteral(lit); |
| 145 | +} |
| 146 | + |
| 147 | +llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::u32string &lit) { |
| 148 | + return o << parser::QuoteCharacterLiteral(lit); |
| 149 | +} |
| 150 | + |
| 151 | +template <typename A> |
| 152 | +llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const A &x) { |
| 153 | + return x.AsFortran(o); |
| 154 | +} |
| 155 | + |
| 156 | +template <typename A> |
| 157 | +llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, common::Reference<A> x) { |
| 158 | + return EmitVar(o, *x); |
| 159 | +} |
| 160 | + |
| 161 | +template <typename A> |
| 162 | +llvm::raw_ostream &EmitVar( |
| 163 | + llvm::raw_ostream &o, const A *p, const char *kw = nullptr) { |
| 164 | + if (p) { |
| 165 | + if (kw) { |
| 166 | + o << kw; |
| 167 | + } |
| 168 | + EmitVar(o, *p); |
| 169 | + } |
| 170 | + return o; |
| 171 | +} |
| 172 | + |
| 173 | +template <typename A> |
| 174 | +llvm::raw_ostream &EmitVar( |
| 175 | + llvm::raw_ostream &o, const std::optional<A> &x, const char *kw = nullptr) { |
| 176 | + if (x) { |
| 177 | + if (kw) { |
| 178 | + o << kw; |
| 179 | + } |
| 180 | + EmitVar(o, *x); |
| 181 | + } |
| 182 | + return o; |
| 183 | +} |
| 184 | + |
| 185 | +template <typename A, bool COPY> |
| 186 | +llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, |
| 187 | + const common::Indirection<A, COPY> &p, const char *kw = nullptr) { |
| 188 | + if (kw) { |
| 189 | + o << kw; |
| 190 | + } |
| 191 | + EmitVar(o, p.value()); |
| 192 | + return o; |
| 193 | +} |
| 194 | + |
| 195 | +template <typename A> |
| 196 | +llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::shared_ptr<A> &p) { |
| 197 | + CHECK(p); |
| 198 | + return EmitVar(o, *p); |
| 199 | +} |
| 200 | + |
| 201 | +template <typename... A> |
| 202 | +llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::variant<A...> &u) { |
| 203 | + common::visit([&](const auto &x) { EmitVar(o, x); }, u); |
| 204 | + return o; |
| 205 | +} |
| 206 | + |
127 | 207 | llvm::raw_ostream &ActualArgument::AssumedType::AsFortran(
|
128 | 208 | llvm::raw_ostream &o) const {
|
129 |
| - return o << symbol_->name().ToString(); |
| 209 | + return EmitVar(o, *symbol_); |
130 | 210 | }
|
131 | 211 |
|
132 | 212 | llvm::raw_ostream &ActualArgument::AsFortran(llvm::raw_ostream &o) const {
|
@@ -504,15 +584,37 @@ llvm::raw_ostream &ExpressionBase<RESULT>::AsFortran(
|
504 | 584 | return o;
|
505 | 585 | }
|
506 | 586 |
|
507 |
| -llvm::raw_ostream &StructureConstructor::AsFortran( |
508 |
| - llvm::raw_ostream &o, const parser::CharBlock *derivedTypeRename) const { |
509 |
| - o << DerivedTypeSpecAsFortran(result_.derivedTypeSpec(), derivedTypeRename); |
| 587 | +static std::string DerivedTypeSpecAsFortran( |
| 588 | + const semantics::DerivedTypeSpec &spec) { |
| 589 | + std::string buf; |
| 590 | + llvm::raw_string_ostream ss{buf}; |
| 591 | + EmitVar(ss, spec.typeSymbol(), spec.name()); |
| 592 | + char ch{'('}; |
| 593 | + for (const auto &[name, value] : spec.parameters()) { |
| 594 | + ss << ch << name.ToString() << '='; |
| 595 | + ch = ','; |
| 596 | + if (value.isAssumed()) { |
| 597 | + ss << '*'; |
| 598 | + } else if (value.isDeferred()) { |
| 599 | + ss << ':'; |
| 600 | + } else { |
| 601 | + value.GetExplicit()->AsFortran(ss); |
| 602 | + } |
| 603 | + } |
| 604 | + if (ch != '(') { |
| 605 | + ss << ')'; |
| 606 | + } |
| 607 | + return ss.str(); |
| 608 | +} |
| 609 | + |
| 610 | +llvm::raw_ostream &StructureConstructor::AsFortran(llvm::raw_ostream &o) const { |
| 611 | + o << DerivedTypeSpecAsFortran(result_.derivedTypeSpec()); |
510 | 612 | if (values_.empty()) {
|
511 | 613 | o << '(';
|
512 | 614 | } else {
|
513 | 615 | char ch{'('};
|
514 | 616 | for (const auto &[symbol, value] : values_) {
|
515 |
| - value.value().AsFortran(o << ch << symbol->name().ToString() << '='); |
| 617 | + value.value().AsFortran(EmitVar(o << ch, *symbol) << '='); |
516 | 618 | ch = ',';
|
517 | 619 | }
|
518 | 620 | }
|
@@ -568,101 +670,6 @@ std::string SomeDerived::AsFortran() const {
|
568 | 670 | }
|
569 | 671 | }
|
570 | 672 |
|
571 |
| -std::string DerivedTypeSpecAsFortran(const semantics::DerivedTypeSpec &spec, |
572 |
| - const parser::CharBlock *derivedTypeRename) { |
573 |
| - std::string buf; |
574 |
| - llvm::raw_string_ostream ss{buf}; |
575 |
| - ss << (derivedTypeRename ? *derivedTypeRename : spec.name()).ToString(); |
576 |
| - char ch{'('}; |
577 |
| - for (const auto &[name, value] : spec.parameters()) { |
578 |
| - ss << ch << name.ToString() << '='; |
579 |
| - ch = ','; |
580 |
| - if (value.isAssumed()) { |
581 |
| - ss << '*'; |
582 |
| - } else if (value.isDeferred()) { |
583 |
| - ss << ':'; |
584 |
| - } else { |
585 |
| - value.GetExplicit()->AsFortran(ss); |
586 |
| - } |
587 |
| - } |
588 |
| - if (ch != '(') { |
589 |
| - ss << ')'; |
590 |
| - } |
591 |
| - return ss.str(); |
592 |
| -} |
593 |
| - |
594 |
| -llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const Symbol &symbol) { |
595 |
| - return o << symbol.name().ToString(); |
596 |
| -} |
597 |
| - |
598 |
| -llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::string &lit) { |
599 |
| - return o << parser::QuoteCharacterLiteral(lit); |
600 |
| -} |
601 |
| - |
602 |
| -llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::u16string &lit) { |
603 |
| - return o << parser::QuoteCharacterLiteral(lit); |
604 |
| -} |
605 |
| - |
606 |
| -llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::u32string &lit) { |
607 |
| - return o << parser::QuoteCharacterLiteral(lit); |
608 |
| -} |
609 |
| - |
610 |
| -template <typename A> |
611 |
| -llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const A &x) { |
612 |
| - return x.AsFortran(o); |
613 |
| -} |
614 |
| - |
615 |
| -template <typename A> |
616 |
| -llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, common::Reference<A> x) { |
617 |
| - return EmitVar(o, *x); |
618 |
| -} |
619 |
| - |
620 |
| -template <typename A> |
621 |
| -llvm::raw_ostream &EmitVar( |
622 |
| - llvm::raw_ostream &o, const A *p, const char *kw = nullptr) { |
623 |
| - if (p) { |
624 |
| - if (kw) { |
625 |
| - o << kw; |
626 |
| - } |
627 |
| - EmitVar(o, *p); |
628 |
| - } |
629 |
| - return o; |
630 |
| -} |
631 |
| - |
632 |
| -template <typename A> |
633 |
| -llvm::raw_ostream &EmitVar( |
634 |
| - llvm::raw_ostream &o, const std::optional<A> &x, const char *kw = nullptr) { |
635 |
| - if (x) { |
636 |
| - if (kw) { |
637 |
| - o << kw; |
638 |
| - } |
639 |
| - EmitVar(o, *x); |
640 |
| - } |
641 |
| - return o; |
642 |
| -} |
643 |
| - |
644 |
| -template <typename A, bool COPY> |
645 |
| -llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, |
646 |
| - const common::Indirection<A, COPY> &p, const char *kw = nullptr) { |
647 |
| - if (kw) { |
648 |
| - o << kw; |
649 |
| - } |
650 |
| - EmitVar(o, p.value()); |
651 |
| - return o; |
652 |
| -} |
653 |
| - |
654 |
| -template <typename A> |
655 |
| -llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::shared_ptr<A> &p) { |
656 |
| - CHECK(p); |
657 |
| - return EmitVar(o, *p); |
658 |
| -} |
659 |
| - |
660 |
| -template <typename... A> |
661 |
| -llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::variant<A...> &u) { |
662 |
| - common::visit([&](const auto &x) { EmitVar(o, x); }, u); |
663 |
| - return o; |
664 |
| -} |
665 |
| - |
666 | 673 | llvm::raw_ostream &BaseObject::AsFortran(llvm::raw_ostream &o) const {
|
667 | 674 | return EmitVar(o, u);
|
668 | 675 | }
|
|
0 commit comments