|  | //===- CodeExpander.cpp - Expand variables in a string --------------------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | /// \file Expand the variables in a string. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "CodeExpander.h" | 
|  | #include "CodeExpansions.h" | 
|  | #include "llvm/Support/raw_ostream.h" | 
|  | #include "llvm/TableGen/Error.h" | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | void CodeExpander::emit(raw_ostream &OS) const { | 
|  | StringRef Current = Code; | 
|  |  | 
|  | while (!Current.empty()) { | 
|  | size_t Pos = Current.find_first_of("$\n\\"); | 
|  | if (Pos == StringRef::npos) { | 
|  | OS << Current; | 
|  | Current = ""; | 
|  | continue; | 
|  | } | 
|  |  | 
|  | OS << Current.substr(0, Pos); | 
|  | Current = Current.substr(Pos); | 
|  |  | 
|  | if (Current.startswith("\n")) { | 
|  | OS << "\n" << Indent; | 
|  | Current = Current.drop_front(1); | 
|  | continue; | 
|  | } | 
|  |  | 
|  | if (Current.startswith("\\$") || Current.startswith("\\\\")) { | 
|  | OS << Current[1]; | 
|  | Current = Current.drop_front(2); | 
|  | continue; | 
|  | } | 
|  |  | 
|  | if (Current.startswith("\\")) { | 
|  | Current = Current.drop_front(1); | 
|  | continue; | 
|  | } | 
|  |  | 
|  | if (Current.startswith("${")) { | 
|  | StringRef StartVar = Current; | 
|  | Current = Current.drop_front(2); | 
|  | StringRef Var; | 
|  | std::tie(Var, Current) = Current.split("}"); | 
|  |  | 
|  | // Warn if we split because no terminator was found. | 
|  | StringRef EndVar = StartVar.drop_front(2 /* ${ */ + Var.size()); | 
|  | if (EndVar.empty()) { | 
|  | PrintWarning(Loc, "Unterminated expansion '${" + Var + "'"); | 
|  | PrintNote("Code: [{" + Code + "}]"); | 
|  | } | 
|  |  | 
|  | auto ValueI = Expansions.find(Var); | 
|  | if (ValueI == Expansions.end()) { | 
|  | PrintError(Loc, | 
|  | "Attempt to expand an undeclared variable '" + Var + "'"); | 
|  | PrintNote("Code: [{" + Code + "}]"); | 
|  | } | 
|  | if (ShowExpansions) | 
|  | OS << "/*$" << Var << "{*/"; | 
|  | OS << Expansions.lookup(Var); | 
|  | if (ShowExpansions) | 
|  | OS << "/*}*/"; | 
|  | continue; | 
|  | } | 
|  |  | 
|  | PrintWarning(Loc, "Assuming missing escape character: \\$"); | 
|  | PrintNote("Code: [{" + Code + "}]"); | 
|  | OS << "$"; | 
|  | Current = Current.drop_front(1); | 
|  | } | 
|  | } |