-
Notifications
You must be signed in to change notification settings - Fork 10
/
Console.h
159 lines (127 loc) · 3.93 KB
/
Console.h
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#ifndef CCONS_CONSOLE_H
#define CCONS_CONSOLE_H
//
// Defines the IConsole interface used by ccons.cpp to process user input,
// as well as the concrete Console class, implementing said interface and
// providing C input processing using the clang and llvm libraries.
//
// Part of ccons, the interactive console for the C programming language.
//
// Copyright (c) 2009 Alexei Svitkine. This file is distributed under the
// terms of MIT Open Source License. See file LICENSE for details.
//
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <llvm/ADT/OwningPtr.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/Support/raw_os_ostream.h>
#include <clang/Basic/LangOptions.h>
#include <clang/Basic/TargetOptions.h>
namespace llvm {
struct GenericValue;
class ExecutionEngine;
class Function;
class Linker;
class Module;
} // namespace llvm
namespace clang {
class DeclStmt;
class Expr;
class Preprocessor;
class QualType;
class SourceManager;
class Stmt;
class VarDecl;
} // namespace clang
namespace ccons {
class Parser;
class DiagnosticsProvider;
class MacroDetector;
//
// IConsole interface
//
class IConsole {
public:
virtual ~IConsole() {}
// Returns the prompt that should be presented to the user.
virtual const char * prompt() const = 0;
// Returns the initial input string that should be prepended.
virtual const char * input() const = 0;
// Process the specified line of user input.
virtual void process(const char *line) = 0;
};
//
// Console implementation
//
class Console : public IConsole {
public:
Console(bool _debugMode,
std::ostream& out = std::cout,
std::ostream& err = std::cerr);
virtual ~Console();
const char * prompt() const;
const char * input() const;
void process(const char *line);
private:
enum LineType {
StmtLine,
DeclLine,
PrprLine,
};
typedef std::pair<std::string, LineType> CodeLine;
void reportInputError();
bool shouldPrintCString(const char *p);
void printGV(const llvm::Function *F,
const llvm::GenericValue& GV,
const clang::QualType& QT);
void processVarDecl(const std::string& src,
const clang::VarDecl *VD,
std::vector<std::string> *decls,
std::vector<std::string> *stmts,
std::string *appendix);
bool handleDeclStmt(const clang::DeclStmt *DS,
const std::string& src,
std::string *appendix,
std::string *funcBody,
std::vector<CodeLine> *moreLines);
std::string genAppendix(const char *source,
const char *line,
std::string *fName,
clang::QualType& QT,
std::vector<CodeLine> *moreLines,
bool *hadErrors);
std::string genSource(const std::string& appendix) const;
int splitInput(const std::string& source,
const std::string& input,
std::vector<std::string> *statements);
clang::Stmt * locateStmt(const std::string& line,
std::string *src);
bool compileLinkAndRun(const std::string& src,
const std::string& fName,
const clang::QualType& retType);
bool _debugMode;
std::ostream& _out;
std::ostream& _err;
mutable llvm::raw_os_ostream _raw_err;
clang::LangOptions _options;
clang::TargetOptions _targetOptions;
llvm::OwningPtr<Parser> _parser;
llvm::LLVMContext _context;
llvm::OwningPtr<llvm::Module> _linkerModule;
llvm::OwningPtr<llvm::Linker> _linker;
llvm::OwningPtr<llvm::ExecutionEngine> _engine;
llvm::OwningPtr<DiagnosticsProvider> _dp;
MacroDetector *_macros;
std::vector<std::string> _prevMacros;
std::vector<CodeLine> _lines;
std::string _buffer;
std::string _prompt;
std::string _input;
unsigned _funcNo;
FILE *_tempFile;
};
} // namespace ccons
#endif // CCONS_CONSOLE_H