CodeExpander.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //===- CodeExpander.cpp - Expand variables in a string --------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. /// \file Expand the variables in a string.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "CodeExpander.h"
  13. #include "CodeExpansions.h"
  14. #include "llvm/Support/raw_ostream.h"
  15. #include "llvm/TableGen/Error.h"
  16. using namespace llvm;
  17. void CodeExpander::emit(raw_ostream &OS) const {
  18. StringRef Current = Code;
  19. while (!Current.empty()) {
  20. size_t Pos = Current.find_first_of("$\n\\");
  21. if (Pos == StringRef::npos) {
  22. OS << Current;
  23. Current = "";
  24. continue;
  25. }
  26. OS << Current.substr(0, Pos);
  27. Current = Current.substr(Pos);
  28. if (Current.startswith("\n")) {
  29. OS << "\n" << Indent;
  30. Current = Current.drop_front(1);
  31. continue;
  32. }
  33. if (Current.startswith("\\$") || Current.startswith("\\\\")) {
  34. OS << Current[1];
  35. Current = Current.drop_front(2);
  36. continue;
  37. }
  38. if (Current.startswith("\\")) {
  39. Current = Current.drop_front(1);
  40. continue;
  41. }
  42. if (Current.startswith("${")) {
  43. StringRef StartVar = Current;
  44. Current = Current.drop_front(2);
  45. StringRef Var;
  46. std::tie(Var, Current) = Current.split("}");
  47. // Warn if we split because no terminator was found.
  48. StringRef EndVar = StartVar.drop_front(2 /* ${ */ + Var.size());
  49. if (EndVar.empty()) {
  50. PrintWarning(Loc, "Unterminated expansion '${" + Var + "'");
  51. PrintNote("Code: [{" + Code + "}]");
  52. }
  53. auto ValueI = Expansions.find(Var);
  54. if (ValueI == Expansions.end()) {
  55. PrintError(Loc,
  56. "Attempt to expand an undeclared variable '" + Var + "'");
  57. PrintNote("Code: [{" + Code + "}]");
  58. }
  59. if (ShowExpansions)
  60. OS << "/*$" << Var << "{*/";
  61. OS << Expansions.lookup(Var);
  62. if (ShowExpansions)
  63. OS << "/*}*/";
  64. continue;
  65. }
  66. PrintWarning(Loc, "Assuming missing escape character: \\$");
  67. PrintNote("Code: [{" + Code + "}]");
  68. OS << "$";
  69. Current = Current.drop_front(1);
  70. }
  71. }