17#ifndef FORTRAN_LOWER_PFTBUILDER_H
18#define FORTRAN_LOWER_PFTBUILDER_H
20#include "flang/Common/reference.h"
21#include "flang/Common/template.h"
22#include "flang/Lower/HostAssociations.h"
23#include "flang/Lower/PFTDefs.h"
24#include "flang/Parser/parse-tree.h"
25#include "flang/Semantics/attr.h"
26#include "flang/Semantics/scope.h"
27#include "flang/Semantics/semantics.h"
28#include "flang/Semantics/symbol.h"
29#include "llvm/Support/ErrorHandling.h"
30#include "llvm/Support/raw_ostream.h"
33namespace Fortran::lower::pft {
41using ContainedUnit = std::variant<CompilerDirectiveUnit, FunctionLikeUnit>;
42using ContainedUnitList = std::list<ContainedUnit>;
43using EvaluationList = std::list<Evaluation>;
48template <
bool isConst,
typename... A>
49class ReferenceVariantBase {
52 using BaseType = std::conditional_t<isConst, const B, B>;
56 ReferenceVariantBase() =
delete;
57 ReferenceVariantBase(std::variant<Ref<A>...> b) : u(b) {}
59 ReferenceVariantBase(Ref<T> b) : u(b) {}
62 constexpr BaseType<B> &get()
const {
63 return std::get<Ref<B>>(u).get();
66 constexpr BaseType<B> &getStatement()
const {
67 return std::get<Ref<parser::Statement<B>>>(u).get().statement;
70 constexpr BaseType<B> *getIf()
const {
71 const Ref<B> *ptr = std::get_if<Ref<B>>(&u);
72 return ptr ? &ptr->get() :
nullptr;
75 constexpr bool isA()
const {
76 return std::holds_alternative<Ref<B>>(u);
78 template <
typename VISITOR>
79 constexpr auto visit(VISITOR &&visitor)
const {
80 return Fortran::common::visit(
86 std::variant<Ref<A>...> u;
88template <
typename... A>
90template <
typename... A>
100using ActionStmts = std::tuple<
116using OtherStmts = std::tuple<parser::EntryStmt, parser::FormatStmt>;
118using ConstructStmts = std::tuple<
130 std::tuple<parser::EndProgramStmt, parser::EndFunctionStmt,
131 parser::EndSubroutineStmt, parser::EndMpSubprogramStmt>;
152static constexpr bool isActionStmt{common::HasMember<A, ActionStmts>};
155static constexpr bool isOtherStmt{common::HasMember<A, OtherStmts>};
158static constexpr bool isConstructStmt{common::HasMember<A, ConstructStmts>};
161static constexpr bool isEndStmt{common::HasMember<A, EndStmts>};
164static constexpr bool isConstruct{common::HasMember<A, Constructs>};
167static constexpr bool isDirective{common::HasMember<A, Directives>};
170static constexpr bool isDeclConstruct{common::HasMember<A, DeclConstructs>};
173static constexpr bool isIntermediateConstructStmt{common::HasMember<
174 A, std::tuple<parser::CaseStmt, parser::ElseIfStmt, parser::ElseStmt,
175 parser::SelectRankCaseStmt, parser::TypeGuardStmt>>};
178static constexpr bool isNopConstructStmt{common::HasMember<
179 A, std::tuple<parser::CaseStmt, parser::ElseIfStmt, parser::ElseStmt,
180 parser::EndIfStmt, parser::SelectRankCaseStmt,
181 parser::TypeGuardStmt>>};
184static constexpr bool isExecutableDirective{common::HasMember<
185 A, std::tuple<parser::CompilerDirective, parser::OpenACCConstruct,
186 parser::OpenMPConstruct, parser::CUFKernelDoConstruct>>};
189static constexpr bool isOpenMPDirective{
190 common::HasMember<A, std::tuple<parser::OpenMPConstruct,
191 parser::OpenMPDeclarativeConstruct>>};
194static constexpr bool isFunctionLike{common::HasMember<
195 A, std::tuple<parser::MainProgram, parser::FunctionSubprogram,
196 parser::SubroutineSubprogram,
197 parser::SeparateModuleSubprogram>>};
201template <
typename... A>
203 using type = ReferenceVariant<A...>;
205template <
typename... A>
207 using type = ReferenceVariant<A...>;
212using EvaluationTuple =
213 common::CombineTuples<ActionStmts, OtherStmts, ConstructStmts, EndStmts,
214 Constructs, Directives>;
218using EvaluationVariant = MakeReferenceVariant<EvaluationTuple>;
225 template <
typename A>
228 const std::optional<parser::Label> &label)
229 : EvaluationVariant{a}, parent{parent}, position{position}, label{label} {
233 template <
typename A>
235 : EvaluationVariant{a}, parent{parent} {
236 static_assert(pft::isConstruct<A> || pft::isDirective<A>,
237 "must be a construct or directive");
243 [](
auto &r) {
return pft::isActionStmt<std::decay_t<
decltype(r)>>; }});
245 constexpr bool isOtherStmt()
const {
247 [](
auto &r) {
return pft::isOtherStmt<std::decay_t<
decltype(r)>>; }});
249 constexpr bool isConstructStmt()
const {
250 return visit(common::visitors{[](
auto &r) {
251 return pft::isConstructStmt<std::decay_t<
decltype(r)>>;
254 constexpr bool isEndStmt()
const {
255 return visit(common::visitors{
256 [](
auto &r) {
return pft::isEndStmt<std::decay_t<
decltype(r)>>; }});
258 constexpr bool isConstruct()
const {
259 return visit(common::visitors{
260 [](
auto &r) {
return pft::isConstruct<std::decay_t<
decltype(r)>>; }});
262 constexpr bool isDirective()
const {
263 return visit(common::visitors{
264 [](
auto &r) {
return pft::isDirective<std::decay_t<
decltype(r)>>; }});
266 constexpr bool isNopConstructStmt()
const {
267 return visit(common::visitors{[](
auto &r) {
268 return pft::isNopConstructStmt<std::decay_t<
decltype(r)>>;
271 constexpr bool isExecutableDirective()
const {
272 return visit(common::visitors{[](
auto &r) {
273 return pft::isExecutableDirective<std::decay_t<
decltype(r)>>;
276 constexpr bool isOpenMPDirective()
const {
277 return visit(common::visitors{[](
auto &r) {
278 return pft::isOpenMPDirective<std::decay_t<
decltype(r)>>;
286 return pft::isIntermediateConstructStmt<std::decay_t<
decltype(r)>>;
290 LLVM_DUMP_METHOD
void dump()
const;
296 if (successor && successor->isNopConstructStmt())
297 successor = successor->parentConstruct->constructExit;
298 assert(successor &&
"missing successor");
304 return evaluationList && !evaluationList->empty();
309 assert(evaluationList &&
"no nested evaluations");
310 return *evaluationList;
315 return evaluationList->front();
320 return evaluationList->back();
347 controlFlow = std::max(controlFlow, kind);
356 controlFlow = std::min(controlFlow, kind);
365 bool hasUnstructuredInternals()
const {
374 bool lowerAsStructured()
const;
375 bool lowerAsUnstructured()
const;
376 bool forceAsUnstructured()
const;
413 std::optional<parser::Label> label{};
414 std::unique_ptr<EvaluationList> evaluationList;
423 llvm::SmallVector<Evaluation *, 0> extraControlSuccessors;
425 bool isNewBlock{
false};
427 bool negateCondition{
false};
428 bool activeConstruct{
false};
431 bool skipNextLowering{
false};
432 mlir::Block *block{
nullptr};
436using ProgramVariant =
437 ReferenceVariant<parser::MainProgram, parser::FunctionSubprogram,
438 parser::SubroutineSubprogram, parser::Module,
439 parser::Submodule, parser::SeparateModuleSubprogram,
440 parser::BlockData, parser::CompilerDirective,
441 parser::OpenACCRoutineConstruct>;
444struct ProgramUnit : ProgramVariant {
445 template <
typename A>
446 ProgramUnit(
const A &p,
const PftNode &parent)
447 : ProgramVariant{p}, parent{parent} {}
448 ProgramUnit(ProgramUnit &&) =
default;
449 ProgramUnit(
const ProgramUnit &) =
delete;
475 : symbol{symbol}, depth{depth}, global{global} {}
478 bool isGlobal()
const {
return global; }
486 std::size_t aliasOffset{};
490 using Interval = std::tuple<std::size_t, std::size_t>;
495 struct AggregateStore {
498 bool isGlobal =
false)
503 :
interval{initialValueSym.offset(), initialValueSym.size()},
532 : var{
Nominal(&sym, depth, global)} {}
533 explicit Variable(AggregateStore &&istore) : var{std::move(istore)} {}
537 assert(
hasSymbol() &&
"variable is not nominal");
538 return *std::get<Nominal>(var).symbol;
547 return std::get<AggregateStore>(var);
553 return std::get<AggregateStore>(var).interval;
557 bool hasSymbol()
const {
return std::holds_alternative<Nominal>(var); }
561 return std::holds_alternative<AggregateStore>(var);
566 return Fortran::common::visit([](
const auto &x) {
return x.isGlobal(); },
573 return scope && scope->kind() == Fortran::semantics::Scope::Kind::Module;
577 return Fortran::common::visit(
579 [](
const Nominal &x) {
return &x.symbol->GetUltimate().owner(); },
580 [](
const AggregateStore &agg) {
return &agg.getOwningScope(); }},
584 bool isHeapAlloc()
const {
585 if (
auto *s = std::get_if<Nominal>(&var))
589 bool isPointer()
const {
590 if (
auto *s = std::get_if<Nominal>(&var))
594 bool isTarget()
const {
595 if (
auto *s = std::get_if<Nominal>(&var))
603 if (
auto *s = std::get_if<Nominal>(&var))
607 std::size_t getAliasOffset()
const {
608 if (
auto *s = std::get_if<Nominal>(&var))
609 return s->aliasOffset;
612 void setAlias(std::size_t offset) {
613 if (
auto *s = std::get_if<Nominal>(&var)) {
615 s->aliasOffset = offset;
617 llvm_unreachable(
"not a nominal var");
621 void setHeapAlloc(
bool to =
true) {
622 if (
auto *s = std::get_if<Nominal>(&var))
625 llvm_unreachable(
"not a nominal var");
627 void setPointer(
bool to =
true) {
628 if (
auto *s = std::get_if<Nominal>(&var))
631 llvm_unreachable(
"not a nominal var");
633 void setTarget(
bool to =
true) {
634 if (
auto *s = std::get_if<Nominal>(&var))
637 llvm_unreachable(
"not a nominal var");
642 if (
auto *s = std::get_if<Nominal>(&var))
647 LLVM_DUMP_METHOD
void dump()
const;
650 std::variant<Nominal, AggregateStore> var;
653using VariableList = std::vector<Variable>;
654using ScopeVariableListMap =
655 std::map<const Fortran::semantics::Scope *, VariableList>;
660 ScopeVariableListMap &map);
670struct FunctionLikeUnit;
675VariableList getHostModuleVariableList(
const FunctionLikeUnit &funit);
677void dump(VariableList &, std::string s = {});
681struct FunctionLikeUnit :
public ProgramUnit {
683 using FunctionStatement =
684 ReferenceVariant<parser::Statement<parser::ProgramStmt>,
705 FunctionLikeUnit(FunctionLikeUnit &&) =
default;
706 FunctionLikeUnit(
const FunctionLikeUnit &) =
delete;
708 bool isMainProgram()
const {
715 void setActiveEntry(
int entryIndex) {
716 assert(entryIndex >= 0 && entryIndex < (
int)
entryPointList.size() &&
717 "invalid entry point index");
727 llvm::report_fatal_error(
728 "not inside a procedure; do not call on main program.");
735 if (!isMainProgram()) {
736 llvm::report_fatal_error(
"call only on main program.");
751 void setHostAssociatedSymbols(
752 const llvm::SetVector<const semantics::Symbol *> &symbols) {
774 LLVM_DUMP_METHOD
void dump()
const;
781 FunctionStatement endStmt;
783 LabelEvalMap labelEvaluationMap;
784 SymbolLabelMap assignSymbolLabelMap;
790 ContainedUnitList containedUnitList;
791 EvaluationList evaluationList;
804 bool hasIeeeAccess{
false};
805 bool mayModifyHaltingMode{
false};
806 bool mayModifyRoundingMode{
false};
807 bool mayModifyUnderflowMode{
false};
816struct ModuleLikeUnit :
public ProgramUnit {
818 using ModuleStatement =
819 ReferenceVariant<parser::Statement<parser::ModuleStmt>,
826 ~ModuleLikeUnit() =
default;
827 ModuleLikeUnit(ModuleLikeUnit &&) =
default;
828 ModuleLikeUnit(
const ModuleLikeUnit &) =
delete;
830 LLVM_DUMP_METHOD
void dump()
const;
838 ModuleStatement beginStmt;
839 ModuleStatement endStmt;
840 ContainedUnitList containedUnitList;
841 EvaluationList evaluationList;
848struct BlockDataUnit :
public ProgramUnit {
851 BlockDataUnit(BlockDataUnit &&) =
default;
852 BlockDataUnit(
const BlockDataUnit &) =
delete;
854 LLVM_DUMP_METHOD
void dump()
const;
860struct CompilerDirectiveUnit :
public ProgramUnit {
862 const PftNode &parent)
863 : ProgramUnit{directive, parent} {};
864 CompilerDirectiveUnit(CompilerDirectiveUnit &&) =
default;
865 CompilerDirectiveUnit(
const CompilerDirectiveUnit &) =
delete;
869struct OpenACCDirectiveUnit :
public ProgramUnit {
871 const PftNode &parent)
872 : ProgramUnit{directive, parent}, routine{directive} {};
873 OpenACCDirectiveUnit(OpenACCDirectiveUnit &&) =
default;
874 OpenACCDirectiveUnit(
const OpenACCDirectiveUnit &) =
delete;
883 Program(semantics::CommonBlockList &&commonBlocks)
884 : commonBlocks{std::move(commonBlocks)} {}
885 Program(Program &&) =
default;
886 Program(
const Program &) =
delete;
888 const std::list<Units> &getUnits()
const {
return units; }
889 std::list<Units> &getUnits() {
return units; }
890 const semantics::CommonBlockList &getCommonBlocks()
const {
893 ScopeVariableListMap &getScopeVariableListMap() {
894 return scopeVariableListMap;
898 LLVM_DUMP_METHOD
void dump()
const;
901 std::list<Units> units;
902 semantics::CommonBlockList commonBlocks;
903 ScopeVariableListMap scopeVariableListMap;
910 return stmt.visit(
common::visitors{[](
const auto &x) {
return x.source; }});
914template <
typename ParentType,
typename A>
915ParentType *getAncestor(A &node) {
916 if (
auto *seekedParent = node.parent.template getIf<ParentType>())
918 return node.parent.visit(common::visitors{
919 [](Program &p) -> ParentType * {
return nullptr; },
920 [](
auto &p) -> ParentType * {
return getAncestor<ParentType>(p); }});
925ScopeVariableListMap &getScopeVariableListMap(A &node) {
926 Program *pftRoot = getAncestor<Program>(node);
927 assert(pftRoot &&
"pft must have a root");
928 return pftRoot->getScopeVariableListMap();
934 std::function<
void(
const semantics::Symbol &)> callBack);
939 std::function<
void(
const semantics::Symbol &)> callBack);
944bool isWrappableConstruct(
const Evaluation &eval,
945 const semantics::SemanticsContext &semaCtx);
960std::unique_ptr<pft::Program>
962 const Fortran::semantics::SemanticsContext &semanticsContext,
Definition reference.h:18
Definition HostAssociations.h:28
void addSymbolsToBind(const llvm::SetVector< const Fortran::semantics::Symbol * > &symbols, const Fortran::semantics::Scope &hostScope)
Definition HostAssociations.cpp:541
Definition LoweringOptions.h:48
Definition PFTBuilder.h:49
Definition char-block.h:27
Definition semantics.h:71
Definition ParserActions.h:24
void dumpPFT(llvm::raw_ostream &outputStream, const pft::Program &pft)
Dumper for displaying a PFT.
Definition PFTBuilder.cpp:2233
std::unique_ptr< pft::Program > createPFT(const parser::Program &root, const Fortran::semantics::SemanticsContext &semanticsContext, const LoweringOptions &loweringOptions)
Definition PFTBuilder.cpp:2225
Definition PFTBuilder.h:848
LLVM_DUMP_METHOD void dump() const
The BlockDataUnit dump is just the associated symbol table.
Definition PFTBuilder.cpp:2293
Definition PFTBuilder.h:860
Definition PFTBuilder.h:222
FunctionLikeUnit * getOwningProcedure() const
Return the FunctionLikeUnit containing this evaluation (or nullptr).
Definition PFTBuilder.cpp:1767
Evaluation(const A &a, const PftNode &parent)
Construct and Directive ctor.
Definition PFTBuilder.h:234
bool lowerBodyAsWrappedRegion() const
Definition PFTBuilder.cpp:1758
EvaluationList & getNestedEvaluations()
Return nested evaluation list.
Definition PFTBuilder.h:308
Evaluation(const A &a, const PftNode &parent, const parser::CharBlock &position, const std::optional< parser::Label > &label)
General ctor.
Definition PFTBuilder.h:226
Evaluation & nonNopSuccessor() const
Definition PFTBuilder.h:294
constexpr bool isIntermediateConstructStmt() const
Definition PFTBuilder.h:284
constexpr bool isActionStmt() const
Evaluation classification predicates.
Definition PFTBuilder.h:241
bool isUnstructured() const
Definition PFTBuilder.h:361
void markControlFlow(ControlFlow kind)
Definition PFTBuilder.h:346
bool hasNestedEvaluations() const
Return true if this Evaluation has at least one nested evaluation.
Definition PFTBuilder.h:303
void weakenControlFlow(ControlFlow kind)
Definition PFTBuilder.h:355
ControlFlow
Definition PFTBuilder.h:329
@ StructuredWithUnstructuredInternals
Definition PFTBuilder.h:338
@ Structured
Lowered structurally.
Definition PFTBuilder.h:331
@ Unstructured
Lowered as unstructured blocks.
Definition PFTBuilder.h:340
Definition PFTBuilder.h:681
Evaluation * getEntryEval() const
Definition PFTBuilder.h:743
llvm::SmallVector< std::pair< const semantics::Symbol *, Evaluation * >, 1 > entryPointList
Definition PFTBuilder.h:798
HostAssociations & parentHostAssoc()
Definition PFTBuilder.cpp:2130
bool parentHasHostAssoc()
Definition PFTBuilder.cpp:2142
int activeEntry
Current index into entryPointList. Index 0 is the primary entry point.
Definition PFTBuilder.h:800
mlir::Block * finalBlock
Terminal basic block (if any)
Definition PFTBuilder.h:809
std::list< Fortran::semantics::PreservedUseStmt > preservedUseStmts
Preserved USE statements for debug info generation.
Definition PFTBuilder.h:812
parser::CharBlock getStartingSourceLoc() const
Get the starting source location for this function like unit.
Definition PFTBuilder.cpp:2149
HostAssociations & getHostAssoc()
Definition PFTBuilder.h:771
IncomingBranchMap incomingBranches
Definition PFTBuilder.h:789
const semantics::Symbol * primaryResult
Definition PFTBuilder.h:803
std::optional< FunctionStatement > beginStmt
Anonymous programs do not have a begin statement.
Definition PFTBuilder.h:780
const semantics::Symbol * getMainProgramSymbol() const
Definition PFTBuilder.h:734
const Fortran::semantics::Scope & getScope() const
Get the function scope.
Definition PFTBuilder.h:777
const semantics::Symbol & getSubprogramSymbol() const
Definition PFTBuilder.h:724
bool parentHasTupleHostAssoc()
Definition PFTBuilder.cpp:2136
Definition PFTBuilder.h:200
Module-like units contain a list of function-like units.
Definition PFTBuilder.h:816
parser::CharBlock getStartingSourceLoc() const
Get the starting source location for this module like unit.
Definition PFTBuilder.cpp:2180
std::list< Fortran::semantics::PreservedUseStmt > preservedUseStmts
Preserved USE statements for debug info generation.
Definition PFTBuilder.h:843
const Fortran::semantics::Scope & getScope() const
Get the module scope.
Definition PFTBuilder.cpp:2184
Definition PFTBuilder.h:869
A Program is the top-level root of the PFT.
Definition PFTBuilder.h:879
LLVM_DUMP_METHOD void dump() const
LLVM dump method on a Program.
Definition PFTBuilder.cpp:2238
Definition PFTBuilder.h:495
std::size_t getOffset() const
Get offset of the aggregate inside its scope.
Definition PFTBuilder.h:509
const semantics::Symbol & getNamingSymbol() const
Returns the symbol that gives its name to the aggregate.
Definition PFTBuilder.h:515
const semantics::Symbol * namingSymbol
Symbol that gives its name to the aggregate. Always set by constructor.
Definition PFTBuilder.h:523
const semantics::Symbol * initialValueSymbol
Compiler generated symbol with the aggregate initial value if any.
Definition PFTBuilder.h:525
bool isGlobalAggregate
Is this a global aggregate?
Definition PFTBuilder.h:527
Interval interval
<offset, size> of the aggregate in its scope.
Definition PFTBuilder.h:521
const semantics::Symbol * getInitialValueSymbol() const
Returns symbols holding the aggregate initial value if any.
Definition PFTBuilder.h:511
const semantics::Scope & getOwningScope() const
Scope to which the aggregates belongs to.
Definition PFTBuilder.h:517
Definition PFTBuilder.h:473
Definition PFTBuilder.h:469
bool isAggregateStore() const
Is this an aggregate store?
Definition PFTBuilder.h:560
bool isRuntimeTypeInfoData() const
Is this variable a compiler generated global to describe derived types?
Definition PFTBuilder.cpp:2207
bool isGlobal() const
Is this variable a global?
Definition PFTBuilder.h:565
bool isModuleOrSubmoduleVariable() const
Is this a module or submodule variable?
Definition PFTBuilder.h:571
bool isAlias() const
Definition PFTBuilder.h:602
std::tuple< std::size_t, std::size_t > Interval
<offset, size> pair
Definition PFTBuilder.h:490
bool hasSymbol() const
Only nominal variable have front-end symbols.
Definition PFTBuilder.h:557
const Interval & getInterval() const
Return the interval range of an aggregate store.
Definition PFTBuilder.h:551
const Fortran::semantics::Symbol & getSymbol() const
Return the front-end symbol for a nominal variable.
Definition PFTBuilder.h:536
int getDepth() const
The depth is recorded for nominal variables as a debugging aid.
Definition PFTBuilder.h:641
const AggregateStore & getAggregateStore() const
Return the aggregate store.
Definition PFTBuilder.h:545
Definition parse-tree.h:2033
Definition parse-tree.h:3555
Definition parse-tree.h:3560
Definition parse-tree.h:3565
Definition parse-tree.h:2059
Definition parse-tree.h:2214
Definition parse-tree.h:2205
Definition parse-tree.h:2236
Definition parse-tree.h:3075
Definition parse-tree.h:6021
Definition parse-tree.h:3357
Definition parse-tree.h:2477
Definition parse-tree.h:2465
Definition parse-tree.h:2267
Definition parse-tree.h:2252
Definition parse-tree.h:2736
Definition parse-tree.h:3444
Definition parse-tree.h:2564
Definition parse-tree.h:2283
Definition parse-tree.h:2274
Definition parse-tree.h:2053
Definition parse-tree.h:2379
Definition parse-tree.h:2399
Definition parse-tree.h:2261
Definition parse-tree.h:2618
Definition parse-tree.h:2632
Definition parse-tree.h:2149
Definition parse-tree.h:2184
Definition parse-tree.h:2161
Definition parse-tree.h:3377
Definition parse-tree.h:2413
Definition parse-tree.h:2429
Definition parse-tree.h:2392
Definition parse-tree.h:2962
Definition parse-tree.h:2658
Definition parse-tree.h:2983
Definition parse-tree.h:2116
Definition parse-tree.h:3019
Definition parse-tree.h:2362
Definition parse-tree.h:2586
Definition parse-tree.h:5995
Definition parse-tree.h:5966
Definition parse-tree.h:5857
Definition parse-tree.h:5681
Definition parse-tree.h:5533
Definition parse-tree.h:2081
Definition parse-tree.h:2836
Definition parse-tree.h:2799
Definition parse-tree.h:2436
Definition parse-tree.h:2500
Definition parse-tree.h:2512
Definition parse-tree.h:2491
Definition parse-tree.h:2546
Definition parse-tree.h:2526
Definition parse-tree.h:3403
Definition parse-tree.h:362
Definition parse-tree.h:2578
Definition parse-tree.h:3061
Definition parse-tree.h:3387
Definition parse-tree.h:2596
Definition parse-tree.h:2609
Definition parse-tree.h:2535
Definition parse-tree.h:2668
Definition parse-tree.h:2100
Definition parse-tree.h:2131
Definition parse-tree.h:2094
Definition parse-tree.h:2821