aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm14/utils/TableGen/GlobalISel/CodeExpander.cpp
blob: 42b4aabf2755e7f8afe714c63309f51b283962bb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//===- 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);
  }
}