164ab3302SCarolineConcatto //===-- lib/Parser/provenance.cpp -----------------------------------------===// 264ab3302SCarolineConcatto // 364ab3302SCarolineConcatto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 464ab3302SCarolineConcatto // See https://llvm.org/LICENSE.txt for license information. 564ab3302SCarolineConcatto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 664ab3302SCarolineConcatto // 764ab3302SCarolineConcatto //===----------------------------------------------------------------------===// 864ab3302SCarolineConcatto 964ab3302SCarolineConcatto #include "flang/Parser/provenance.h" 1064ab3302SCarolineConcatto #include "flang/Common/idioms.h" 118670e499SCaroline Concatto #include "llvm/Support/raw_ostream.h" 1264ab3302SCarolineConcatto #include <algorithm> 13e12ffe6aSPeter Klausler #include <set> 1464ab3302SCarolineConcatto #include <utility> 1564ab3302SCarolineConcatto 1664ab3302SCarolineConcatto namespace Fortran::parser { 1764ab3302SCarolineConcatto 1864ab3302SCarolineConcatto ProvenanceRangeToOffsetMappings::ProvenanceRangeToOffsetMappings() {} 1964ab3302SCarolineConcatto ProvenanceRangeToOffsetMappings::~ProvenanceRangeToOffsetMappings() {} 2064ab3302SCarolineConcatto 2164ab3302SCarolineConcatto void ProvenanceRangeToOffsetMappings::Put( 2264ab3302SCarolineConcatto ProvenanceRange range, std::size_t offset) { 2364ab3302SCarolineConcatto auto fromTo{map_.equal_range(range)}; 2464ab3302SCarolineConcatto for (auto iter{fromTo.first}; iter != fromTo.second; ++iter) { 2564ab3302SCarolineConcatto if (range == iter->first) { 2664ab3302SCarolineConcatto iter->second = std::min(offset, iter->second); 2764ab3302SCarolineConcatto return; 2864ab3302SCarolineConcatto } 2964ab3302SCarolineConcatto } 3064ab3302SCarolineConcatto if (fromTo.second != map_.end()) { 3164ab3302SCarolineConcatto map_.emplace_hint(fromTo.second, range, offset); 3264ab3302SCarolineConcatto } else { 3364ab3302SCarolineConcatto map_.emplace(range, offset); 3464ab3302SCarolineConcatto } 3564ab3302SCarolineConcatto } 3664ab3302SCarolineConcatto 3764ab3302SCarolineConcatto std::optional<std::size_t> ProvenanceRangeToOffsetMappings::Map( 3864ab3302SCarolineConcatto ProvenanceRange range) const { 3964ab3302SCarolineConcatto auto fromTo{map_.equal_range(range)}; 4064ab3302SCarolineConcatto std::optional<std::size_t> result; 4164ab3302SCarolineConcatto for (auto iter{fromTo.first}; iter != fromTo.second; ++iter) { 4264ab3302SCarolineConcatto ProvenanceRange that{iter->first}; 4364ab3302SCarolineConcatto if (that.Contains(range)) { 4464ab3302SCarolineConcatto std::size_t offset{iter->second + that.MemberOffset(range.start())}; 4564ab3302SCarolineConcatto if (!result || offset < *result) { 4664ab3302SCarolineConcatto result = offset; 4764ab3302SCarolineConcatto } 4864ab3302SCarolineConcatto } 4964ab3302SCarolineConcatto } 5064ab3302SCarolineConcatto return result; 5164ab3302SCarolineConcatto } 5264ab3302SCarolineConcatto 5364ab3302SCarolineConcatto bool ProvenanceRangeToOffsetMappings::WhollyPrecedes::operator()( 5464ab3302SCarolineConcatto ProvenanceRange before, ProvenanceRange after) const { 5564ab3302SCarolineConcatto return before.start() + before.size() <= after.start(); 5664ab3302SCarolineConcatto } 5764ab3302SCarolineConcatto 5864ab3302SCarolineConcatto void OffsetToProvenanceMappings::clear() { provenanceMap_.clear(); } 5964ab3302SCarolineConcatto 6064ab3302SCarolineConcatto void OffsetToProvenanceMappings::swap(OffsetToProvenanceMappings &that) { 6164ab3302SCarolineConcatto provenanceMap_.swap(that.provenanceMap_); 6264ab3302SCarolineConcatto } 6364ab3302SCarolineConcatto 6464ab3302SCarolineConcatto void OffsetToProvenanceMappings::shrink_to_fit() { 6564ab3302SCarolineConcatto provenanceMap_.shrink_to_fit(); 6664ab3302SCarolineConcatto } 6764ab3302SCarolineConcatto 6864ab3302SCarolineConcatto std::size_t OffsetToProvenanceMappings::SizeInBytes() const { 6964ab3302SCarolineConcatto if (provenanceMap_.empty()) { 7064ab3302SCarolineConcatto return 0; 7164ab3302SCarolineConcatto } else { 7264ab3302SCarolineConcatto const ContiguousProvenanceMapping &last{provenanceMap_.back()}; 7364ab3302SCarolineConcatto return last.start + last.range.size(); 7464ab3302SCarolineConcatto } 7564ab3302SCarolineConcatto } 7664ab3302SCarolineConcatto 7764ab3302SCarolineConcatto void OffsetToProvenanceMappings::Put(ProvenanceRange range) { 7864ab3302SCarolineConcatto if (provenanceMap_.empty()) { 7964ab3302SCarolineConcatto provenanceMap_.push_back({0, range}); 8064ab3302SCarolineConcatto } else { 8164ab3302SCarolineConcatto ContiguousProvenanceMapping &last{provenanceMap_.back()}; 8264ab3302SCarolineConcatto if (!last.range.AnnexIfPredecessor(range)) { 8364ab3302SCarolineConcatto provenanceMap_.push_back({last.start + last.range.size(), range}); 8464ab3302SCarolineConcatto } 8564ab3302SCarolineConcatto } 8664ab3302SCarolineConcatto } 8764ab3302SCarolineConcatto 8864ab3302SCarolineConcatto void OffsetToProvenanceMappings::Put(const OffsetToProvenanceMappings &that) { 8964ab3302SCarolineConcatto for (const auto &map : that.provenanceMap_) { 9064ab3302SCarolineConcatto Put(map.range); 9164ab3302SCarolineConcatto } 9264ab3302SCarolineConcatto } 9364ab3302SCarolineConcatto 9464ab3302SCarolineConcatto ProvenanceRange OffsetToProvenanceMappings::Map(std::size_t at) const { 950eb3299dSpeter klausler if (provenanceMap_.empty()) { 960eb3299dSpeter klausler CHECK(at == 0); 970eb3299dSpeter klausler return {}; 980eb3299dSpeter klausler } 9964ab3302SCarolineConcatto std::size_t low{0}, count{provenanceMap_.size()}; 10064ab3302SCarolineConcatto while (count > 1) { 10164ab3302SCarolineConcatto std::size_t mid{low + (count >> 1)}; 10264ab3302SCarolineConcatto if (provenanceMap_[mid].start > at) { 10364ab3302SCarolineConcatto count = mid - low; 10464ab3302SCarolineConcatto } else { 10564ab3302SCarolineConcatto count -= mid - low; 10664ab3302SCarolineConcatto low = mid; 10764ab3302SCarolineConcatto } 10864ab3302SCarolineConcatto } 10964ab3302SCarolineConcatto std::size_t offset{at - provenanceMap_[low].start}; 11064ab3302SCarolineConcatto return provenanceMap_[low].range.Suffix(offset); 11164ab3302SCarolineConcatto } 11264ab3302SCarolineConcatto 11364ab3302SCarolineConcatto void OffsetToProvenanceMappings::RemoveLastBytes(std::size_t bytes) { 11464ab3302SCarolineConcatto for (; bytes > 0; provenanceMap_.pop_back()) { 11564ab3302SCarolineConcatto CHECK(!provenanceMap_.empty()); 11664ab3302SCarolineConcatto ContiguousProvenanceMapping &last{provenanceMap_.back()}; 11764ab3302SCarolineConcatto std::size_t chunk{last.range.size()}; 11864ab3302SCarolineConcatto if (bytes < chunk) { 11964ab3302SCarolineConcatto last.range = last.range.Prefix(chunk - bytes); 12064ab3302SCarolineConcatto break; 12164ab3302SCarolineConcatto } 12264ab3302SCarolineConcatto bytes -= chunk; 12364ab3302SCarolineConcatto } 12464ab3302SCarolineConcatto } 12564ab3302SCarolineConcatto 12664ab3302SCarolineConcatto ProvenanceRangeToOffsetMappings OffsetToProvenanceMappings::Invert( 12764ab3302SCarolineConcatto const AllSources &allSources) const { 12864ab3302SCarolineConcatto ProvenanceRangeToOffsetMappings result; 12964ab3302SCarolineConcatto for (const auto &contig : provenanceMap_) { 13064ab3302SCarolineConcatto ProvenanceRange range{contig.range}; 13164ab3302SCarolineConcatto while (!range.empty()) { 13264ab3302SCarolineConcatto ProvenanceRange source{allSources.IntersectionWithSourceFiles(range)}; 13364ab3302SCarolineConcatto if (source.empty()) { 13464ab3302SCarolineConcatto break; 13564ab3302SCarolineConcatto } 13664ab3302SCarolineConcatto result.Put( 13764ab3302SCarolineConcatto source, contig.start + contig.range.MemberOffset(source.start())); 13864ab3302SCarolineConcatto Provenance after{source.NextAfter()}; 13964ab3302SCarolineConcatto if (range.Contains(after)) { 14064ab3302SCarolineConcatto range = range.Suffix(range.MemberOffset(after)); 14164ab3302SCarolineConcatto } else { 14264ab3302SCarolineConcatto break; 14364ab3302SCarolineConcatto } 14464ab3302SCarolineConcatto } 14564ab3302SCarolineConcatto } 14664ab3302SCarolineConcatto return result; 14764ab3302SCarolineConcatto } 14864ab3302SCarolineConcatto 14964ab3302SCarolineConcatto AllSources::AllSources() : range_{1, 1} { 15064ab3302SCarolineConcatto // Start the origin_ array with a dummy entry that has a forced provenance, 15164ab3302SCarolineConcatto // so that provenance offset 0 remains reserved as an uninitialized 15264ab3302SCarolineConcatto // value. 15364ab3302SCarolineConcatto origin_.emplace_back(range_, std::string{'?'}); 15464ab3302SCarolineConcatto } 15564ab3302SCarolineConcatto 15664ab3302SCarolineConcatto AllSources::~AllSources() {} 15764ab3302SCarolineConcatto 15864ab3302SCarolineConcatto const char &AllSources::operator[](Provenance at) const { 15964ab3302SCarolineConcatto const Origin &origin{MapToOrigin(at)}; 16064ab3302SCarolineConcatto return origin[origin.covers.MemberOffset(at)]; 16164ab3302SCarolineConcatto } 16264ab3302SCarolineConcatto 16352a1346bSPeter Klausler void AllSources::ClearSearchPath() { searchPath_.clear(); } 16452a1346bSPeter Klausler 1656110e771Speter klausler void AllSources::AppendSearchPathDirectory(std::string directory) { 16664ab3302SCarolineConcatto // gfortran and ifort append to current path, PGI prepends 16764ab3302SCarolineConcatto searchPath_.push_back(directory); 16864ab3302SCarolineConcatto } 16964ab3302SCarolineConcatto 170f7a15e00SPeter Klausler const SourceFile *AllSources::OpenPath( 171f7a15e00SPeter Klausler std::string path, llvm::raw_ostream &error) { 172f7a15e00SPeter Klausler std::unique_ptr<SourceFile> source{std::make_unique<SourceFile>(encoding_)}; 173f7a15e00SPeter Klausler if (source->Open(path, error)) { 174f7a15e00SPeter Klausler return ownedSourceFiles_.emplace_back(std::move(source)).get(); 175f7a15e00SPeter Klausler } else { 176f7a15e00SPeter Klausler return nullptr; 177f7a15e00SPeter Klausler } 178f7a15e00SPeter Klausler } 179f7a15e00SPeter Klausler 1806110e771Speter klausler const SourceFile *AllSources::Open(std::string path, llvm::raw_ostream &error, 1816110e771Speter klausler std::optional<std::string> &&prependPath) { 18264ab3302SCarolineConcatto std::unique_ptr<SourceFile> source{std::make_unique<SourceFile>(encoding_)}; 1836110e771Speter klausler if (prependPath) { 1846110e771Speter klausler // Set to "." for the initial source file; set to the directory name 1856110e771Speter klausler // of the including file for #include "quoted-file" directives & 1866110e771Speter klausler // INCLUDE statements. 1876110e771Speter klausler searchPath_.emplace_front(std::move(*prependPath)); 1886110e771Speter klausler } 1896110e771Speter klausler std::optional<std::string> found{LocateSourceFile(path, searchPath_)}; 1906110e771Speter klausler if (prependPath) { 1916110e771Speter klausler searchPath_.pop_front(); 1926110e771Speter klausler } 193f7a15e00SPeter Klausler if (found) { 194f7a15e00SPeter Klausler return OpenPath(*found, error); 19564ab3302SCarolineConcatto } else { 196f7a15e00SPeter Klausler error << "Source file '" << path << "' was not found"; 19764ab3302SCarolineConcatto return nullptr; 19864ab3302SCarolineConcatto } 19964ab3302SCarolineConcatto } 20064ab3302SCarolineConcatto 2018670e499SCaroline Concatto const SourceFile *AllSources::ReadStandardInput(llvm::raw_ostream &error) { 20264ab3302SCarolineConcatto std::unique_ptr<SourceFile> source{std::make_unique<SourceFile>(encoding_)}; 20364ab3302SCarolineConcatto if (source->ReadStandardInput(error)) { 20464ab3302SCarolineConcatto return ownedSourceFiles_.emplace_back(std::move(source)).get(); 20564ab3302SCarolineConcatto } 20664ab3302SCarolineConcatto return nullptr; 20764ab3302SCarolineConcatto } 20864ab3302SCarolineConcatto 20964ab3302SCarolineConcatto ProvenanceRange AllSources::AddIncludedFile( 21064ab3302SCarolineConcatto const SourceFile &source, ProvenanceRange from, bool isModule) { 21164ab3302SCarolineConcatto ProvenanceRange covers{range_.NextAfter(), source.bytes()}; 21264ab3302SCarolineConcatto CHECK(range_.AnnexIfPredecessor(covers)); 21364ab3302SCarolineConcatto CHECK(origin_.back().covers.ImmediatelyPrecedes(covers)); 21464ab3302SCarolineConcatto origin_.emplace_back(covers, source, from, isModule); 21564ab3302SCarolineConcatto return covers; 21664ab3302SCarolineConcatto } 21764ab3302SCarolineConcatto 21864ab3302SCarolineConcatto ProvenanceRange AllSources::AddMacroCall( 21964ab3302SCarolineConcatto ProvenanceRange def, ProvenanceRange use, const std::string &expansion) { 22064ab3302SCarolineConcatto ProvenanceRange covers{range_.NextAfter(), expansion.size()}; 22164ab3302SCarolineConcatto CHECK(range_.AnnexIfPredecessor(covers)); 22264ab3302SCarolineConcatto CHECK(origin_.back().covers.ImmediatelyPrecedes(covers)); 22364ab3302SCarolineConcatto origin_.emplace_back(covers, def, use, expansion); 22464ab3302SCarolineConcatto return covers; 22564ab3302SCarolineConcatto } 22664ab3302SCarolineConcatto 22764ab3302SCarolineConcatto ProvenanceRange AllSources::AddCompilerInsertion(std::string text) { 22864ab3302SCarolineConcatto ProvenanceRange covers{range_.NextAfter(), text.size()}; 22964ab3302SCarolineConcatto CHECK(range_.AnnexIfPredecessor(covers)); 23064ab3302SCarolineConcatto CHECK(origin_.back().covers.ImmediatelyPrecedes(covers)); 23164ab3302SCarolineConcatto origin_.emplace_back(covers, text); 23264ab3302SCarolineConcatto return covers; 23364ab3302SCarolineConcatto } 23464ab3302SCarolineConcatto 2358df63a23SPeixin Qiao static void EmitPrefix(llvm::raw_ostream &o, llvm::raw_ostream::Colors color, 2368df63a23SPeixin Qiao const std::string &prefix, bool showColors) { 2378df63a23SPeixin Qiao if (prefix.empty()) { 2388df63a23SPeixin Qiao return; 2398df63a23SPeixin Qiao } 2408df63a23SPeixin Qiao if (showColors) { 2418df63a23SPeixin Qiao o.changeColor(color, true); 2428df63a23SPeixin Qiao } 2438df63a23SPeixin Qiao o << prefix; 2448df63a23SPeixin Qiao if (showColors) { 2458df63a23SPeixin Qiao o.resetColor(); 2468df63a23SPeixin Qiao } 2478df63a23SPeixin Qiao } 2488df63a23SPeixin Qiao 2490ee0eeb4SValentin Clement (バレンタイン クレメン) std::optional<ProvenanceRange> AllSources::GetInclusionInfo( 2500ee0eeb4SValentin Clement (バレンタイン クレメン) const std::optional<ProvenanceRange> &range) const { 251*c1a750b8SValentin Clement (バレンタイン クレメン) if (!range || !IsValid(range->start())) 2520ee0eeb4SValentin Clement (バレンタイン クレメン) return std::nullopt; 2530ee0eeb4SValentin Clement (バレンタイン クレメン) const Origin &origin{MapToOrigin(range->start())}; 2540ee0eeb4SValentin Clement (バレンタイン クレメン) 2550ee0eeb4SValentin Clement (バレンタイン クレメン) return common::visit( 2560ee0eeb4SValentin Clement (バレンタイン クレメン) common::visitors{ 2570ee0eeb4SValentin Clement (バレンタイン クレメン) [&](const Inclusion &inc) -> std::optional<ProvenanceRange> { 2580ee0eeb4SValentin Clement (バレンタイン クレメン) if (IsValid(origin.replaces) && 2590ee0eeb4SValentin Clement (バレンタイン クレメン) range_.Contains(origin.replaces.start())) 2600ee0eeb4SValentin Clement (バレンタイン クレメン) return origin.replaces; 2610ee0eeb4SValentin Clement (バレンタイン クレメン) return std::nullopt; 2620ee0eeb4SValentin Clement (バレンタイン クレメン) }, 2630ee0eeb4SValentin Clement (バレンタイン クレメン) [&](const auto &) -> std::optional<ProvenanceRange> { 2640ee0eeb4SValentin Clement (バレンタイン クレメン) return std::nullopt; 2650ee0eeb4SValentin Clement (バレンタイン クレメン) }, 2660ee0eeb4SValentin Clement (バレンタイン クレメン) }, 2670ee0eeb4SValentin Clement (バレンタイン クレメン) origin.u); 2680ee0eeb4SValentin Clement (バレンタイン クレメン) } 2690ee0eeb4SValentin Clement (バレンタイン クレメン) 2708670e499SCaroline Concatto void AllSources::EmitMessage(llvm::raw_ostream &o, 27164ab3302SCarolineConcatto const std::optional<ProvenanceRange> &range, const std::string &message, 2728df63a23SPeixin Qiao const std::string &prefix, llvm::raw_ostream::Colors color, 27364ab3302SCarolineConcatto bool echoSourceLine) const { 27464ab3302SCarolineConcatto if (!range) { 2758df63a23SPeixin Qiao EmitPrefix(o, color, prefix, this->getShowColors()); 27664ab3302SCarolineConcatto o << message << '\n'; 27764ab3302SCarolineConcatto return; 27864ab3302SCarolineConcatto } 27964ab3302SCarolineConcatto CHECK(IsValid(*range)); 28064ab3302SCarolineConcatto const Origin &origin{MapToOrigin(range->start())}; 281cd03e96fSPeter Klausler common::visit( 28264ab3302SCarolineConcatto common::visitors{ 28364ab3302SCarolineConcatto [&](const Inclusion &inc) { 28464ab3302SCarolineConcatto std::size_t offset{origin.covers.MemberOffset(range->start())}; 285e12ffe6aSPeter Klausler SourcePosition pos{inc.source.GetSourcePosition(offset)}; 286e12ffe6aSPeter Klausler o << pos.path << ':' << pos.line << ':' << pos.column << ": "; 2878df63a23SPeixin Qiao EmitPrefix(o, color, prefix, this->getShowColors()); 2888df63a23SPeixin Qiao o << message << '\n'; 28964ab3302SCarolineConcatto if (echoSourceLine) { 29013ea73e4SDavid Truby const char *text{inc.source.content().data() + 291e12ffe6aSPeter Klausler inc.source.GetLineStartOffset(pos.trueLineNumber)}; 29264ab3302SCarolineConcatto o << " "; 29364ab3302SCarolineConcatto for (const char *p{text}; *p != '\n'; ++p) { 29464ab3302SCarolineConcatto o << *p; 29564ab3302SCarolineConcatto } 29664ab3302SCarolineConcatto o << "\n "; 29764ab3302SCarolineConcatto for (int j{1}; j < pos.column; ++j) { 29864ab3302SCarolineConcatto char ch{text[j - 1]}; 29964ab3302SCarolineConcatto o << (ch == '\t' ? '\t' : ' '); 30064ab3302SCarolineConcatto } 30164ab3302SCarolineConcatto o << '^'; 30264ab3302SCarolineConcatto if (range->size() > 1) { 30364ab3302SCarolineConcatto auto last{range->start() + range->size() - 1}; 30464ab3302SCarolineConcatto if (&MapToOrigin(last) == &origin) { 30564ab3302SCarolineConcatto auto endOffset{origin.covers.MemberOffset(last)}; 306e12ffe6aSPeter Klausler auto endPos{inc.source.GetSourcePosition(endOffset)}; 30764ab3302SCarolineConcatto if (pos.line == endPos.line) { 30864ab3302SCarolineConcatto for (int j{pos.column}; j < endPos.column; ++j) { 30964ab3302SCarolineConcatto o << '^'; 31064ab3302SCarolineConcatto } 31164ab3302SCarolineConcatto } 31264ab3302SCarolineConcatto } 31364ab3302SCarolineConcatto } 31464ab3302SCarolineConcatto o << '\n'; 31564ab3302SCarolineConcatto } 31664ab3302SCarolineConcatto if (IsValid(origin.replaces)) { 31764ab3302SCarolineConcatto EmitMessage(o, origin.replaces, 3188df63a23SPeixin Qiao inc.isModule ? "used here"s : "included here"s, prefix, color, 31964ab3302SCarolineConcatto echoSourceLine); 32064ab3302SCarolineConcatto } 32164ab3302SCarolineConcatto }, 32264ab3302SCarolineConcatto [&](const Macro &mac) { 32364ab3302SCarolineConcatto EmitMessage( 3248df63a23SPeixin Qiao o, origin.replaces, message, prefix, color, echoSourceLine); 325042c964dSPeter Klausler EmitMessage(o, mac.definition, "in a macro defined here", ""s, 3268df63a23SPeixin Qiao color, echoSourceLine); 32764ab3302SCarolineConcatto if (echoSourceLine) { 32864ab3302SCarolineConcatto o << "that expanded to:\n " << mac.expansion << "\n "; 32964ab3302SCarolineConcatto for (std::size_t j{0}; 33064ab3302SCarolineConcatto origin.covers.OffsetMember(j) < range->start(); ++j) { 33164ab3302SCarolineConcatto o << (mac.expansion[j] == '\t' ? '\t' : ' '); 33264ab3302SCarolineConcatto } 33364ab3302SCarolineConcatto o << "^\n"; 33464ab3302SCarolineConcatto } 33564ab3302SCarolineConcatto }, 3368df63a23SPeixin Qiao [&](const CompilerInsertion &) { 3378df63a23SPeixin Qiao EmitPrefix(o, color, prefix, this->getShowColors()); 3388df63a23SPeixin Qiao o << message << '\n'; 3398df63a23SPeixin Qiao }, 34064ab3302SCarolineConcatto }, 34164ab3302SCarolineConcatto origin.u); 34264ab3302SCarolineConcatto } 34364ab3302SCarolineConcatto 34464ab3302SCarolineConcatto const SourceFile *AllSources::GetSourceFile( 3455024a6ecSPeter Klausler Provenance at, std::size_t *offset, bool topLevel) const { 34664ab3302SCarolineConcatto const Origin &origin{MapToOrigin(at)}; 347cd03e96fSPeter Klausler return common::visit(common::visitors{ 34864ab3302SCarolineConcatto [&](const Inclusion &inc) { 3495024a6ecSPeter Klausler if (topLevel && !origin.replaces.empty()) { 3505024a6ecSPeter Klausler return GetSourceFile( 3515024a6ecSPeter Klausler origin.replaces.start(), offset, topLevel); 3525024a6ecSPeter Klausler } else { 35364ab3302SCarolineConcatto if (offset) { 35464ab3302SCarolineConcatto *offset = origin.covers.MemberOffset(at); 35564ab3302SCarolineConcatto } 35664ab3302SCarolineConcatto return &inc.source; 3575024a6ecSPeter Klausler } 35864ab3302SCarolineConcatto }, 35964ab3302SCarolineConcatto [&](const Macro &) { 360cd03e96fSPeter Klausler return GetSourceFile( 361cd03e96fSPeter Klausler origin.replaces.start(), offset); 36264ab3302SCarolineConcatto }, 36364ab3302SCarolineConcatto [offset](const CompilerInsertion &) { 36464ab3302SCarolineConcatto if (offset) { 36564ab3302SCarolineConcatto *offset = 0; 36664ab3302SCarolineConcatto } 36764ab3302SCarolineConcatto return static_cast<const SourceFile *>(nullptr); 36864ab3302SCarolineConcatto }, 36964ab3302SCarolineConcatto }, 37064ab3302SCarolineConcatto origin.u); 37164ab3302SCarolineConcatto } 37264ab3302SCarolineConcatto 3735881bf00Speter klausler const char *AllSources::GetSource(ProvenanceRange range) const { 3745881bf00Speter klausler Provenance start{range.start()}; 3755881bf00Speter klausler const Origin &origin{MapToOrigin(start)}; 3765881bf00Speter klausler return origin.covers.Contains(range) 3775881bf00Speter klausler ? &origin[origin.covers.MemberOffset(start)] 3785881bf00Speter klausler : nullptr; 3795881bf00Speter klausler } 3805881bf00Speter klausler 38164ab3302SCarolineConcatto std::optional<SourcePosition> AllSources::GetSourcePosition( 38264ab3302SCarolineConcatto Provenance prov) const { 38364ab3302SCarolineConcatto const Origin &origin{MapToOrigin(prov)}; 384cd03e96fSPeter Klausler return common::visit( 3853338ef93Speter klausler common::visitors{ 3863338ef93Speter klausler [&](const Inclusion &inc) -> std::optional<SourcePosition> { 38764ab3302SCarolineConcatto std::size_t offset{origin.covers.MemberOffset(prov)}; 388e12ffe6aSPeter Klausler return inc.source.GetSourcePosition(offset); 3893338ef93Speter klausler }, 3903338ef93Speter klausler [&](const Macro &) { 3913338ef93Speter klausler return GetSourcePosition(origin.replaces.start()); 3923338ef93Speter klausler }, 3933338ef93Speter klausler [](const CompilerInsertion &) -> std::optional<SourcePosition> { 39464ab3302SCarolineConcatto return std::nullopt; 3953338ef93Speter klausler }, 3963338ef93Speter klausler }, 3973338ef93Speter klausler origin.u); 39864ab3302SCarolineConcatto } 39964ab3302SCarolineConcatto 40064ab3302SCarolineConcatto std::optional<ProvenanceRange> AllSources::GetFirstFileProvenance() const { 40164ab3302SCarolineConcatto for (const auto &origin : origin_) { 40264ab3302SCarolineConcatto if (std::holds_alternative<Inclusion>(origin.u)) { 40364ab3302SCarolineConcatto return origin.covers; 40464ab3302SCarolineConcatto } 40564ab3302SCarolineConcatto } 40664ab3302SCarolineConcatto return std::nullopt; 40764ab3302SCarolineConcatto } 40864ab3302SCarolineConcatto 4095024a6ecSPeter Klausler std::string AllSources::GetPath(Provenance at, bool topLevel) const { 410e12ffe6aSPeter Klausler std::size_t offset{0}; 4115024a6ecSPeter Klausler const SourceFile *source{GetSourceFile(at, &offset, topLevel)}; 412e12ffe6aSPeter Klausler return source ? *source->GetSourcePosition(offset).path : ""s; 41364ab3302SCarolineConcatto } 41464ab3302SCarolineConcatto 41564ab3302SCarolineConcatto int AllSources::GetLineNumber(Provenance at) const { 41664ab3302SCarolineConcatto std::size_t offset{0}; 41764ab3302SCarolineConcatto const SourceFile *source{GetSourceFile(at, &offset)}; 418e12ffe6aSPeter Klausler return source ? source->GetSourcePosition(offset).line : 0; 41964ab3302SCarolineConcatto } 42064ab3302SCarolineConcatto 42164ab3302SCarolineConcatto Provenance AllSources::CompilerInsertionProvenance(char ch) { 42264ab3302SCarolineConcatto auto iter{compilerInsertionProvenance_.find(ch)}; 42364ab3302SCarolineConcatto if (iter != compilerInsertionProvenance_.end()) { 42464ab3302SCarolineConcatto return iter->second; 42564ab3302SCarolineConcatto } 42664ab3302SCarolineConcatto ProvenanceRange newCharRange{AddCompilerInsertion(std::string{ch})}; 42764ab3302SCarolineConcatto Provenance newCharProvenance{newCharRange.start()}; 42864ab3302SCarolineConcatto compilerInsertionProvenance_.insert(std::make_pair(ch, newCharProvenance)); 42964ab3302SCarolineConcatto return newCharProvenance; 43064ab3302SCarolineConcatto } 43164ab3302SCarolineConcatto 43264ab3302SCarolineConcatto ProvenanceRange AllSources::IntersectionWithSourceFiles( 43364ab3302SCarolineConcatto ProvenanceRange range) const { 43464ab3302SCarolineConcatto if (range.empty()) { 43564ab3302SCarolineConcatto return {}; 43664ab3302SCarolineConcatto } else { 43764ab3302SCarolineConcatto const Origin &origin{MapToOrigin(range.start())}; 43864ab3302SCarolineConcatto if (std::holds_alternative<Inclusion>(origin.u)) { 43964ab3302SCarolineConcatto return range.Intersection(origin.covers); 44064ab3302SCarolineConcatto } else { 44164ab3302SCarolineConcatto auto skip{ 44264ab3302SCarolineConcatto origin.covers.size() - origin.covers.MemberOffset(range.start())}; 44364ab3302SCarolineConcatto return IntersectionWithSourceFiles(range.Suffix(skip)); 44464ab3302SCarolineConcatto } 44564ab3302SCarolineConcatto } 44664ab3302SCarolineConcatto } 44764ab3302SCarolineConcatto 44864ab3302SCarolineConcatto AllSources::Origin::Origin(ProvenanceRange r, const SourceFile &source) 44964ab3302SCarolineConcatto : u{Inclusion{source}}, covers{r} {} 45064ab3302SCarolineConcatto AllSources::Origin::Origin(ProvenanceRange r, const SourceFile &included, 45164ab3302SCarolineConcatto ProvenanceRange from, bool isModule) 45264ab3302SCarolineConcatto : u{Inclusion{included, isModule}}, covers{r}, replaces{from} {} 45364ab3302SCarolineConcatto AllSources::Origin::Origin(ProvenanceRange r, ProvenanceRange def, 45464ab3302SCarolineConcatto ProvenanceRange use, const std::string &expansion) 45564ab3302SCarolineConcatto : u{Macro{def, expansion}}, covers{r}, replaces{use} {} 45664ab3302SCarolineConcatto AllSources::Origin::Origin(ProvenanceRange r, const std::string &text) 45764ab3302SCarolineConcatto : u{CompilerInsertion{text}}, covers{r} {} 45864ab3302SCarolineConcatto 45964ab3302SCarolineConcatto const char &AllSources::Origin::operator[](std::size_t n) const { 460cd03e96fSPeter Klausler return common::visit( 46164ab3302SCarolineConcatto common::visitors{ 46264ab3302SCarolineConcatto [n](const Inclusion &inc) -> const char & { 46364ab3302SCarolineConcatto return inc.source.content()[n]; 46464ab3302SCarolineConcatto }, 46564ab3302SCarolineConcatto [n](const Macro &mac) -> const char & { return mac.expansion[n]; }, 46664ab3302SCarolineConcatto [n](const CompilerInsertion &ins) -> const char & { 46764ab3302SCarolineConcatto return ins.text[n]; 46864ab3302SCarolineConcatto }, 46964ab3302SCarolineConcatto }, 47064ab3302SCarolineConcatto u); 47164ab3302SCarolineConcatto } 47264ab3302SCarolineConcatto 47364ab3302SCarolineConcatto const AllSources::Origin &AllSources::MapToOrigin(Provenance at) const { 47464ab3302SCarolineConcatto CHECK(range_.Contains(at)); 47564ab3302SCarolineConcatto std::size_t low{0}, count{origin_.size()}; 47664ab3302SCarolineConcatto while (count > 1) { 47764ab3302SCarolineConcatto std::size_t mid{low + (count >> 1)}; 47864ab3302SCarolineConcatto if (at < origin_[mid].covers.start()) { 47964ab3302SCarolineConcatto count = mid - low; 48064ab3302SCarolineConcatto } else { 48164ab3302SCarolineConcatto count -= mid - low; 48264ab3302SCarolineConcatto low = mid; 48364ab3302SCarolineConcatto } 48464ab3302SCarolineConcatto } 48564ab3302SCarolineConcatto CHECK(origin_[low].covers.Contains(at)); 48664ab3302SCarolineConcatto return origin_[low]; 48764ab3302SCarolineConcatto } 48864ab3302SCarolineConcatto 489c87e94b0SjeanPerier Provenance AllSources::GetReplacedProvenance(Provenance provenance) const { 490c87e94b0SjeanPerier const Origin &origin{MapToOrigin(provenance)}; 491c87e94b0SjeanPerier if (std::holds_alternative<Macro>(origin.u)) { 492c87e94b0SjeanPerier return origin.replaces.start(); 493c87e94b0SjeanPerier } 494c87e94b0SjeanPerier return provenance; 495c87e94b0SjeanPerier } 496c87e94b0SjeanPerier 49764ab3302SCarolineConcatto std::optional<ProvenanceRange> CookedSource::GetProvenanceRange( 49864ab3302SCarolineConcatto CharBlock cookedRange) const { 4995881bf00Speter klausler if (!AsCharBlock().Contains(cookedRange)) { 50064ab3302SCarolineConcatto return std::nullopt; 50164ab3302SCarolineConcatto } 50264ab3302SCarolineConcatto ProvenanceRange first{provenanceMap_.Map(cookedRange.begin() - &data_[0])}; 503d7ea6068SPeter Klausler if (cookedRange.size() <= first.size()) { // always true when empty 50464ab3302SCarolineConcatto return first.Prefix(cookedRange.size()); 50564ab3302SCarolineConcatto } 506d7ea6068SPeter Klausler ProvenanceRange last{provenanceMap_.Map(cookedRange.end() - 1 - &data_[0])}; 507d7ea6068SPeter Klausler if (first.start() <= last.start()) { 508d7ea6068SPeter Klausler return {ProvenanceRange{first.start(), last.start() - first.start() + 1}}; 509d7ea6068SPeter Klausler } else { 510c87e94b0SjeanPerier // cookedRange may start (resp. end) in a macro expansion while it does not 511c87e94b0SjeanPerier // end (resp. start) in this macro expansion. Attempt to build a range 512c87e94b0SjeanPerier // over the replaced source. 513c87e94b0SjeanPerier Provenance firstStart{allSources_.GetReplacedProvenance(first.start())}; 514c87e94b0SjeanPerier Provenance lastStart{allSources_.GetReplacedProvenance(last.start())}; 515c87e94b0SjeanPerier if (firstStart <= lastStart) { 516c87e94b0SjeanPerier return {ProvenanceRange{firstStart, lastStart - firstStart + 1}}; 517c87e94b0SjeanPerier } else { 518d7ea6068SPeter Klausler return std::nullopt; 519d7ea6068SPeter Klausler } 52064ab3302SCarolineConcatto } 521c87e94b0SjeanPerier } 52264ab3302SCarolineConcatto 52364ab3302SCarolineConcatto std::optional<CharBlock> CookedSource::GetCharBlock( 52464ab3302SCarolineConcatto ProvenanceRange range) const { 52564ab3302SCarolineConcatto CHECK(!invertedMap_.empty() && 52664ab3302SCarolineConcatto "CompileProvenanceRangeToOffsetMappings not called"); 52764ab3302SCarolineConcatto if (auto to{invertedMap_.Map(range)}) { 52864ab3302SCarolineConcatto return CharBlock{data_.c_str() + *to, range.size()}; 52964ab3302SCarolineConcatto } else { 53064ab3302SCarolineConcatto return std::nullopt; 53164ab3302SCarolineConcatto } 53264ab3302SCarolineConcatto } 53364ab3302SCarolineConcatto 53464ab3302SCarolineConcatto std::size_t CookedSource::BufferedBytes() const { return buffer_.bytes(); } 53564ab3302SCarolineConcatto 53646ade6d0Speter klausler void CookedSource::Marshal(AllCookedSources &allCookedSources) { 53764ab3302SCarolineConcatto CHECK(provenanceMap_.SizeInBytes() == buffer_.bytes()); 53846ade6d0Speter klausler provenanceMap_.Put(allCookedSources.allSources().AddCompilerInsertion( 53946ade6d0Speter klausler "(after end of source)")); 54064ab3302SCarolineConcatto data_ = buffer_.Marshal(); 54164ab3302SCarolineConcatto buffer_.clear(); 54286bee819SPeter Klausler for (std::size_t ffStart : possibleFixedFormContinuations_) { 54386bee819SPeter Klausler if (ffStart > 0 && ffStart + 1 < data_.size() && 54486bee819SPeter Klausler data_[ffStart - 1] == '\n' && data_[ffStart] == ' ') { 54586bee819SPeter Klausler // This fixed form include line is the first source line in an 54686bee819SPeter Klausler // #include file (or after an empty one). Connect it with the previous 54786bee819SPeter Klausler // source line by deleting its terminal newline. 54886bee819SPeter Klausler data_[ffStart - 1] = ' '; 54986bee819SPeter Klausler } 55086bee819SPeter Klausler } 55186bee819SPeter Klausler possibleFixedFormContinuations_.clear(); 55246ade6d0Speter klausler allCookedSources.Register(*this); 55364ab3302SCarolineConcatto } 55464ab3302SCarolineConcatto 55592a54197Speter klausler void CookedSource::CompileProvenanceRangeToOffsetMappings( 55692a54197Speter klausler AllSources &allSources) { 55764ab3302SCarolineConcatto if (invertedMap_.empty()) { 55892a54197Speter klausler invertedMap_ = provenanceMap_.Invert(allSources); 55964ab3302SCarolineConcatto } 56064ab3302SCarolineConcatto } 56164ab3302SCarolineConcatto 5628670e499SCaroline Concatto static void DumpRange(llvm::raw_ostream &o, const ProvenanceRange &r) { 56364ab3302SCarolineConcatto o << "[" << r.start().offset() << ".." << r.Last().offset() << "] (" 56464ab3302SCarolineConcatto << r.size() << " bytes)"; 56564ab3302SCarolineConcatto } 56664ab3302SCarolineConcatto 5678670e499SCaroline Concatto llvm::raw_ostream &ProvenanceRangeToOffsetMappings::Dump( 5688670e499SCaroline Concatto llvm::raw_ostream &o) const { 56964ab3302SCarolineConcatto for (const auto &m : map_) { 57064ab3302SCarolineConcatto o << "provenances "; 57164ab3302SCarolineConcatto DumpRange(o, m.first); 57264ab3302SCarolineConcatto o << " -> offsets [" << m.second << ".." << (m.second + m.first.size() - 1) 57364ab3302SCarolineConcatto << "]\n"; 57464ab3302SCarolineConcatto } 57564ab3302SCarolineConcatto return o; 57664ab3302SCarolineConcatto } 57764ab3302SCarolineConcatto 5788670e499SCaroline Concatto llvm::raw_ostream &OffsetToProvenanceMappings::Dump( 5798670e499SCaroline Concatto llvm::raw_ostream &o) const { 58064ab3302SCarolineConcatto for (const ContiguousProvenanceMapping &m : provenanceMap_) { 58164ab3302SCarolineConcatto std::size_t n{m.range.size()}; 58264ab3302SCarolineConcatto o << "offsets [" << m.start << ".." << (m.start + n - 1) 58364ab3302SCarolineConcatto << "] -> provenances "; 58464ab3302SCarolineConcatto DumpRange(o, m.range); 58564ab3302SCarolineConcatto o << '\n'; 58664ab3302SCarolineConcatto } 58764ab3302SCarolineConcatto return o; 58864ab3302SCarolineConcatto } 58964ab3302SCarolineConcatto 5908670e499SCaroline Concatto llvm::raw_ostream &AllSources::Dump(llvm::raw_ostream &o) const { 59164ab3302SCarolineConcatto o << "AllSources range_ "; 59264ab3302SCarolineConcatto DumpRange(o, range_); 59364ab3302SCarolineConcatto o << '\n'; 594e12ffe6aSPeter Klausler std::set<const SourceFile *> sources; 59564ab3302SCarolineConcatto for (const Origin &m : origin_) { 59664ab3302SCarolineConcatto o << " "; 59764ab3302SCarolineConcatto DumpRange(o, m.covers); 59864ab3302SCarolineConcatto o << " -> "; 599cd03e96fSPeter Klausler common::visit(common::visitors{ 60064ab3302SCarolineConcatto [&](const Inclusion &inc) { 60164ab3302SCarolineConcatto if (inc.isModule) { 60264ab3302SCarolineConcatto o << "module "; 60364ab3302SCarolineConcatto } 60464ab3302SCarolineConcatto o << "file " << inc.source.path(); 605e12ffe6aSPeter Klausler sources.emplace(&inc.source); 60664ab3302SCarolineConcatto }, 60764ab3302SCarolineConcatto [&](const Macro &mac) { o << "macro " << mac.expansion; }, 60864ab3302SCarolineConcatto [&](const CompilerInsertion &ins) { 60964ab3302SCarolineConcatto o << "compiler '" << ins.text << '\''; 61064ab3302SCarolineConcatto if (ins.text.length() == 1) { 61164ab3302SCarolineConcatto int ch = ins.text[0]; 6128670e499SCaroline Concatto o << "(0x"; 6138670e499SCaroline Concatto o.write_hex(ch & 0xff) << ")"; 61464ab3302SCarolineConcatto } 61564ab3302SCarolineConcatto }, 61664ab3302SCarolineConcatto }, 61764ab3302SCarolineConcatto m.u); 61864ab3302SCarolineConcatto if (IsValid(m.replaces)) { 61964ab3302SCarolineConcatto o << " replaces "; 62064ab3302SCarolineConcatto DumpRange(o, m.replaces); 62164ab3302SCarolineConcatto } 62264ab3302SCarolineConcatto o << '\n'; 62364ab3302SCarolineConcatto } 624e12ffe6aSPeter Klausler for (const SourceFile *sf : sources) { 625e12ffe6aSPeter Klausler sf->Dump(o); 626e12ffe6aSPeter Klausler } 62764ab3302SCarolineConcatto return o; 62864ab3302SCarolineConcatto } 62964ab3302SCarolineConcatto 6308670e499SCaroline Concatto llvm::raw_ostream &CookedSource::Dump(llvm::raw_ostream &o) const { 63164ab3302SCarolineConcatto o << "CookedSource::provenanceMap_:\n"; 63264ab3302SCarolineConcatto provenanceMap_.Dump(o); 63364ab3302SCarolineConcatto o << "CookedSource::invertedMap_:\n"; 63464ab3302SCarolineConcatto invertedMap_.Dump(o); 63564ab3302SCarolineConcatto return o; 63664ab3302SCarolineConcatto } 63792a54197Speter klausler 63892a54197Speter klausler AllCookedSources::AllCookedSources(AllSources &s) : allSources_{s} {} 63992a54197Speter klausler AllCookedSources::~AllCookedSources() {} 64092a54197Speter klausler 64192a54197Speter klausler CookedSource &AllCookedSources::NewCookedSource() { 642c87e94b0SjeanPerier return cooked_.emplace_back(allSources_); 64392a54197Speter klausler } 64492a54197Speter klausler 64546ade6d0Speter klausler const CookedSource *AllCookedSources::Find(CharBlock x) const { 64646ade6d0Speter klausler auto pair{index_.equal_range(x)}; 64746ade6d0Speter klausler for (auto iter{pair.first}; iter != pair.second; ++iter) { 64846ade6d0Speter klausler if (iter->second.AsCharBlock().Contains(x)) { 64946ade6d0Speter klausler return &iter->second; 65046ade6d0Speter klausler } 65146ade6d0Speter klausler } 65246ade6d0Speter klausler return nullptr; 65346ade6d0Speter klausler } 65446ade6d0Speter klausler 65592a54197Speter klausler std::optional<ProvenanceRange> AllCookedSources::GetProvenanceRange( 65692a54197Speter klausler CharBlock cb) const { 65792a54197Speter klausler if (const CookedSource * c{Find(cb)}) { 65892a54197Speter klausler return c->GetProvenanceRange(cb); 65992a54197Speter klausler } else { 66092a54197Speter klausler return std::nullopt; 66192a54197Speter klausler } 66292a54197Speter klausler } 66392a54197Speter klausler 66492a54197Speter klausler std::optional<CharBlock> AllCookedSources::GetCharBlockFromLineAndColumns( 66592a54197Speter klausler int line, int startColumn, int endColumn) const { 66692a54197Speter klausler // 2nd column is exclusive, meaning it is target column + 1. 66792a54197Speter klausler CHECK(line > 0 && startColumn > 0 && endColumn > 0); 66892a54197Speter klausler CHECK(startColumn < endColumn); 66992a54197Speter klausler auto provenanceStart{allSources_.GetFirstFileProvenance().value().start()}; 67092a54197Speter klausler if (auto sourceFile{allSources_.GetSourceFile(provenanceStart)}) { 67192a54197Speter klausler CHECK(line <= static_cast<int>(sourceFile->lines())); 67292a54197Speter klausler return GetCharBlock(ProvenanceRange(sourceFile->GetLineStartOffset(line) + 67392a54197Speter klausler provenanceStart.offset() + startColumn - 1, 67492a54197Speter klausler endColumn - startColumn)); 67592a54197Speter klausler } 67692a54197Speter klausler return std::nullopt; 67792a54197Speter klausler } 67892a54197Speter klausler 67992a54197Speter klausler std::optional<std::pair<SourcePosition, SourcePosition>> 68092a54197Speter klausler AllCookedSources::GetSourcePositionRange(CharBlock cookedRange) const { 68192a54197Speter klausler if (auto range{GetProvenanceRange(cookedRange)}) { 68292a54197Speter klausler if (auto firstOffset{allSources_.GetSourcePosition(range->start())}) { 68392a54197Speter klausler if (auto secondOffset{ 68492a54197Speter klausler allSources_.GetSourcePosition(range->start() + range->size())}) { 68592a54197Speter klausler return std::pair{*firstOffset, *secondOffset}; 68692a54197Speter klausler } 68792a54197Speter klausler } 68892a54197Speter klausler } 68992a54197Speter klausler return std::nullopt; 69092a54197Speter klausler } 69192a54197Speter klausler 69292a54197Speter klausler std::optional<CharBlock> AllCookedSources::GetCharBlock( 69392a54197Speter klausler ProvenanceRange range) const { 69492a54197Speter klausler for (const auto &c : cooked_) { 69592a54197Speter klausler if (auto result{c.GetCharBlock(range)}) { 69692a54197Speter klausler return result; 69792a54197Speter klausler } 69892a54197Speter klausler } 6993338ef93Speter klausler return std::nullopt; 70092a54197Speter klausler } 70192a54197Speter klausler 70292a54197Speter klausler void AllCookedSources::Dump(llvm::raw_ostream &o) const { 70392a54197Speter klausler o << "AllSources:\n"; 70492a54197Speter klausler allSources_.Dump(o); 70592a54197Speter klausler for (const auto &c : cooked_) { 70692a54197Speter klausler c.Dump(o); 70792a54197Speter klausler } 70892a54197Speter klausler } 70992a54197Speter klausler 71046ade6d0Speter klausler bool AllCookedSources::Precedes(CharBlock x, CharBlock y) const { 71146ade6d0Speter klausler if (const CookedSource * xSource{Find(x)}) { 7120d8331c0Speter klausler if (xSource->AsCharBlock().Contains(y)) { 7130d8331c0Speter klausler return x.begin() < y.begin(); 7140d8331c0Speter klausler } else if (const CookedSource * ySource{Find(y)}) { 7150d8331c0Speter klausler return xSource->number() < ySource->number(); 71646ade6d0Speter klausler } else { 71746ade6d0Speter klausler return true; // by fiat, all cooked source < anything outside 71846ade6d0Speter klausler } 7190d8331c0Speter klausler } else if (Find(y)) { 72046ade6d0Speter klausler return false; 72146ade6d0Speter klausler } else { 72246ade6d0Speter klausler // Both names are compiler-created (SaveTempName). 72346ade6d0Speter klausler return x < y; 72446ade6d0Speter klausler } 72546ade6d0Speter klausler } 72646ade6d0Speter klausler 72746ade6d0Speter klausler void AllCookedSources::Register(CookedSource &cooked) { 72846ade6d0Speter klausler index_.emplace(cooked.AsCharBlock(), cooked); 72946ade6d0Speter klausler cooked.set_number(static_cast<int>(index_.size())); 73046ade6d0Speter klausler } 73146ade6d0Speter klausler 7321f879005STim Keith } // namespace Fortran::parser 733