1 //===- CodeExpander.cpp - Expand variables in a string --------------------===//
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
7 //===----------------------------------------------------------------------===//
9 /// \file Expand the variables in a string.
11 //===----------------------------------------------------------------------===//
13 #include "CodeExpander.h"
14 #include "CodeExpansions.h"
15 #include "llvm/Support/CommandLine.h"
16 #include "llvm/Support/raw_ostream.h"
17 #include "llvm/TableGen/Error.h"
21 void CodeExpander::emit(raw_ostream
&OS
) const {
22 StringRef Current
= Code
;
24 while (!Current
.empty()) {
25 size_t Pos
= Current
.find_first_of("$\n\\");
26 if (Pos
== StringRef::npos
) {
32 OS
<< Current
.substr(0, Pos
);
33 Current
= Current
.substr(Pos
);
35 if (Current
.startswith("\n")) {
37 Current
= Current
.drop_front(1);
41 if (Current
.startswith("\\$") || Current
.startswith("\\\\")) {
43 Current
= Current
.drop_front(2);
47 if (Current
.startswith("\\")) {
48 Current
= Current
.drop_front(1);
52 if (Current
.startswith("${")) {
53 StringRef StartVar
= Current
;
54 Current
= Current
.drop_front(2);
56 std::tie(Var
, Current
) = Current
.split("}");
58 // Warn if we split because no terminator was found.
59 StringRef EndVar
= StartVar
.drop_front(2 /* ${ */ + Var
.size());
61 size_t LocOffset
= StartVar
.data() - Code
.data();
63 Loc
.size() > 0 && Loc
[0].isValid()
64 ? SMLoc::getFromPointer(Loc
[0].getPointer() + LocOffset
)
66 "Unterminated expansion");
69 auto ValueI
= Expansions
.find(Var
);
70 if (ValueI
== Expansions
.end()) {
71 size_t LocOffset
= StartVar
.data() - Code
.data();
72 PrintError(Loc
.size() > 0 && Loc
[0].isValid()
73 ? SMLoc::getFromPointer(Loc
[0].getPointer() + LocOffset
)
75 "Attempting to expand an undeclared variable " + Var
);
78 OS
<< "/*$" << Var
<< "{*/";
79 OS
<< Expansions
.lookup(Var
);
85 size_t LocOffset
= Current
.data() - Code
.data();
86 PrintWarning(Loc
.size() > 0 && Loc
[0].isValid()
87 ? SMLoc::getFromPointer(Loc
[0].getPointer() + LocOffset
)
89 "Assuming missing escape character");
91 Current
= Current
.drop_front(1);