Skip to content

Commit 5614fe4

Browse files
committed
Commit changes:
- Moved ConditionalBlock to private section in FlowTree class. - Removed unwanted debug code from the preprocessor tool. - Fixed output streams issues in the preprocessor tool.
1 parent 4f40db8 commit 5614fe4

File tree

3 files changed

+277
-45
lines changed

3 files changed

+277
-45
lines changed

verilog/analysis/flow_tree.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,6 @@ class FlowTree {
4545
// It should be initialized to last location in this "TokenSequence",
4646
// For example in "GenerateControlFlowTree" is initialized to
4747
// 'source_sequence_.end()'.
48-
struct ConditionalBlock {
49-
// "if_location" points to `ifdef or `ifndef.
50-
TokenSequenceConstIterator if_location;
51-
52-
// When "positive_condition" equals 1, then "if_location" points to `ifdef,
53-
// Otherwise it points to `ifndef.
54-
bool positive_condition;
55-
std::vector<TokenSequenceConstIterator> elsif_locations;
56-
TokenSequenceConstIterator else_location;
57-
TokenSequenceConstIterator endif_location;
58-
};
5948

6049
struct Variant {
6150
// Contains the token sequence of the variant.
@@ -99,6 +88,18 @@ class FlowTree {
9988
}
10089

10190
private:
91+
struct ConditionalBlock {
92+
// "if_location" points to `ifdef or `ifndef.
93+
TokenSequenceConstIterator if_location;
94+
95+
// When "positive_condition" equals 1, then "if_location" points to `ifdef,
96+
// Otherwise it points to `ifndef.
97+
bool positive_condition;
98+
std::vector<TokenSequenceConstIterator> elsif_locations;
99+
TokenSequenceConstIterator else_location;
100+
TokenSequenceConstIterator endif_location;
101+
};
102+
102103
// Constructs the control flow tree by adding the tree edges in edges_.
103104
absl::Status GenerateControlFlowTree();
104105

verilog/tools/preprocessor/verilog_preprocessor.cc

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,12 @@ static absl::Status StripComments(const SubcommandArgsRange& args,
7373
}
7474

7575
static absl::Status PreprocessSingleFile(const char* source_file, std::istream&,
76-
std::ostream& outs, std::ostream&) {
76+
std::ostream& outs,
77+
std::ostream& message_stream) {
7778
std::string source_contents;
7879
if (auto status = verible::file::GetContents(source_file, &source_contents);
7980
!status.ok()) {
80-
std::cerr << "ERROR: passed file can't be open\n.";
81+
message_stream << source_file << status;
8182
return status;
8283
}
8384
verilog::VerilogPreprocess::Config config;
@@ -101,36 +102,19 @@ static absl::Status PreprocessSingleFile(const char* source_file, std::istream&,
101102
preprocessor.ScanStream(lexed_streamview);
102103
auto& preprocessed_stream = preprocessed_data.preprocessed_token_stream;
103104
for (auto u : preprocessed_stream) outs << *u << '\n';
104-
// for debugging.
105105
for (auto& u : preprocessed_data.errors) outs << u.error_message << '\n';
106106

107-
// parsing just as a trial
108-
std::string post_preproc;
109-
for (auto u : preprocessed_stream) post_preproc += std::string{u->text()};
110-
std::string source_view{post_preproc};
111-
verilog::VerilogAnalyzer analyzer(source_view, "file1", config);
112-
auto analyze_status = analyzer.Analyze();
113-
/* const auto& mydata = analyzer.Data().Contents(); */
114-
/* outs<<mydata; */
115-
116-
/* TODO(karimtera): regarding conditionals
117-
1) Modify VerilogPreprocess config to have a configuration to generate SV
118-
source codes for all possible variants. 2) Then use parser, directly from
119-
VerilogAnalyzer or from VerilogParser to have less dependences. 3) Now, we
120-
should have multiple trees, we need to merge them as described by Tom in
121-
Verible's issue. 4) Finally, travese the tree and output the chosen path
122-
based on definitions.
123-
*/
124107
return absl::OkStatus();
125108
}
126109

127110
static absl::Status MultipleCU(const SubcommandArgsRange& args, std::istream&,
128-
std::ostream& outs, std::ostream&) {
111+
std::ostream& outs,
112+
std::ostream& message_stream) {
129113
if (args.empty()) {
130114
return absl::InvalidArgumentError("Missing file arguments.");
131115
}
132116
for (const char* source_file : args) {
133-
outs << source_file << ":\n";
117+
message_stream << source_file << ":\n";
134118
auto status = PreprocessSingleFile(source_file, std::cin, outs, std::cerr);
135119
if (!status.ok()) return status;
136120
outs << '\n';
@@ -140,7 +124,7 @@ static absl::Status MultipleCU(const SubcommandArgsRange& args, std::istream&,
140124

141125
static absl::Status GenerateVariants(const SubcommandArgsRange& args,
142126
std::istream&, std::ostream& outs,
143-
std::ostream&) {
127+
std::ostream& message_stream) {
144128
const int limit_variants = absl::GetFlag(FLAGS_limit_variants);
145129
if (args.size() > 1) {
146130
return absl::InvalidArgumentError(
@@ -150,8 +134,8 @@ static absl::Status GenerateVariants(const SubcommandArgsRange& args,
150134
std::string source_contents;
151135
if (auto status = verible::file::GetContents(source_file, &source_contents);
152136
!status.ok()) {
153-
std::cerr << "ERROR: passed file can't be open\n.";
154-
return status; // check if the the file is not readable or doesn't exist.
137+
message_stream << source_file << status;
138+
return status;
155139
}
156140

157141
// Lexing the input SV source code.
@@ -171,12 +155,15 @@ static absl::Status GenerateVariants(const SubcommandArgsRange& args,
171155
verilog::FlowTree control_flow_tree(lexed_sequence);
172156
int counter = 0;
173157
auto status = control_flow_tree.GenerateVariants(
174-
[limit_variants, &counter](const verilog::FlowTree::Variant& variant) {
158+
[limit_variants, &outs, &message_stream,
159+
&counter](const verilog::FlowTree::Variant& variant) {
175160
if (counter == limit_variants) return false;
176161
counter++;
177-
std::cout << "Variant number " << counter << ":\n";
178-
for (auto token : variant.sequence) std::cout << token << '\n';
179-
puts("");
162+
message_stream << "Variant number " << counter << ":\n";
163+
for (auto token : variant.sequence) outs << token << '\n';
164+
// TODO(karimtera): Consider creating an output file per vairant,
165+
// Such that the files naming reflects which defines are
166+
// defined/undefined.
180167
return true;
181168
});
182169
if (!status.ok()) {
@@ -202,26 +189,32 @@ static const std::pair<absl::string_view, SubcommandEntry> kCommands[] = {
202189
Output: (stdout)
203190
Contents of original file with // and /**/ comments removed.
204191
)"}},
205-
{"multiple-cu",
192+
{"multiple-compilation-unit",
206193
{&MultipleCU,
207-
R"(multiple-cu file [more_files]
194+
R"(multiple-compilation-unit file [more_files]
208195
Inputs:
209196
'file' is a Verilog or SystemVerilog source file.
210197
There can be multiple SystemVerilog source files.
211-
Each one of them will be compiled in a separate compilation unit.
198+
Each one of them will be prepropcessed separatly which means that declarations
199+
scoopes will end by the end of each file, and won't be seen from other files.
212200
Output: (stdout)
213201
The preprocessed files content (same contents with directives interpreted).
214202
)"}},
215203
{"generate-variants",
216204
{&GenerateVariants,
217-
R"(genera-variants file [-limit_variants number]
205+
R"(generate-variants file [-limit_variants number]
218206
Inputs:
219207
'file' is a Verilog or SystemVerilog source file.
220208
'-limit_variants' flag limits variants to 'number' (20 by default).
221209
Output: (stdout)
222210
Generates every possible variant considering the conditional directives.
223211
)"}},
212+
// TODO(karimtera): We can add another argument to `generate-variants`,
213+
// Which allows us to set some defines, as if we are only interested
214+
// in the variants in which these defines are set.
224215

216+
// TODO(karimtera): Another candidate subcommand is `list-defines`,
217+
// Which would be the output of `GetUsedMacros()`.
225218
};
226219

227220
int main(int argc, char* argv[]) {

0 commit comments

Comments
 (0)