From 2799596ffc8bed3eeb2195baa8d2a2fdc085d4ad Mon Sep 17 00:00:00 2001 From: Bhavin Umatiya Date: Tue, 24 Dec 2024 14:24:41 +0530 Subject: [PATCH 1/2] fixe #2278 --- .vscode/launch.json | 39 ++++++++++++++++++++++ verible/verilog/analysis/descriptions.h | 24 +++++++------ verible/verilog/analysis/verilog-linter.cc | 9 ++++- 3 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..3af66b728 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,39 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Attach", + "type": "cppdbg", + "request": "attach", + "program": "enter program name, for example ${workspaceFolder}/a.exe", + "MIMode": "gdb", + "miDebuggerPath": "/path/to/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + }, + { + "name": "(Windows) Launch", + "type": "cppvsdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceFolder}/a.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "console": "externalTerminal" + } + ] +} \ No newline at end of file diff --git a/verible/verilog/analysis/descriptions.h b/verible/verilog/analysis/descriptions.h index 973e28a3f..502dbf524 100644 --- a/verible/verilog/analysis/descriptions.h +++ b/verible/verilog/analysis/descriptions.h @@ -35,14 +35,16 @@ struct LintConfigParameterDescriptor { std::string description; }; -struct LintRuleDescriptor { - LintRuleId name; // ID/name of the rule. - absl::string_view topic; // section in style-guide - std::string desc; // Detailed description. - std::vector param; -}; - -} // namespace analysis -} // namespace verilog - -#endif // VERIBLE_VERILOG_ANALYSIS_DESCRIPTIONS_H_ +std::string format_long_description(const std::string& description) { + const size_t max_length = 80; + std::string formatted_desc; + size_t start = 0; + + while (start < description.size()) { + size_t end = std::min(start + max_length, description.size()); + formatted_desc += description.substr(start, end - start) + "\n "; + start = end; + } + + return formatted_desc; +} diff --git a/verible/verilog/analysis/verilog-linter.cc b/verible/verilog/analysis/verilog-linter.cc index 84d4431e1..e7a70aaa5 100644 --- a/verible/verilog/analysis/verilog-linter.cc +++ b/verible/verilog/analysis/verilog-linter.cc @@ -360,7 +360,8 @@ absl::Status PrintRuleInfo(std::ostream *os, } void GetLintRuleDescriptionsHelpFlag(std::ostream *os, - absl::string_view flag_value) { + absl::string_view flag_value, + bool verbose) { // Set up the map. auto rule_map = analysis::GetAllRuleDescriptions(); for (const auto &rule_id : analysis::kDefaultRuleSet) { @@ -380,9 +381,15 @@ void GetLintRuleDescriptionsHelpFlag(std::ostream *os, *os << status.message(); return; } + + // If verbose flag is set, print example for the rule + if (verbose) { + *os << "\nExample: " << rule.second.GetExample() << "\n"; // Assuming rule.second has GetExample() + } } } + void GetLintRuleFile(std::ostream *os, const LinterConfiguration &config) { // This rule bundle contains only a list of enabled rules. There // are also no param's defined (an empty string), unless the user From 912bb4731c5ad9c08d4dc2f96e30054dbacb26a5 Mon Sep 17 00:00:00 2001 From: Bhavin Umatiya Date: Wed, 25 Dec 2024 18:22:03 +0530 Subject: [PATCH 2/2] fixe: #2171 --- .../preprocessor/verilog-preprocess.cc | 72 +++++++++++-------- .../preprocessor/verilog-preprocess_test.cc | 26 +++++++ 2 files changed, 67 insertions(+), 31 deletions(-) diff --git a/verible/verilog/preprocessor/verilog-preprocess.cc b/verible/verilog/preprocessor/verilog-preprocess.cc index 049c07a52..5bcd3ddde 100644 --- a/verible/verilog/preprocessor/verilog-preprocess.cc +++ b/verible/verilog/preprocessor/verilog-preprocess.cc @@ -40,6 +40,11 @@ #include "verible/verilog/parser/verilog-parser.h" // for verilog_symbol_name() #include "verible/verilog/parser/verilog-token-enum.h" +std::string GenerateConditionComment(const std::vector& stack) { + if (stack.empty()) return ""; + return " // " + absl::StrJoin(stack, " && "); +} + namespace verilog { using verible::TokenGenerator; @@ -492,13 +497,8 @@ absl::Status VerilogPreprocess::HandleUndef( } absl::Status VerilogPreprocess::HandleIf( - const TokenStreamView::const_iterator ifpos, // `ifdef, `ifndef, `elseif + const TokenStreamView::const_iterator ifpos, const StreamIteratorGenerator &generator) { - if (!config_.filter_branches) { // nothing to do. - preprocess_data_.preprocessed_token_stream.push_back(*ifpos); - return absl::OkStatus(); - } - auto macro_name_extract = ExtractMacroName(generator); if (!macro_name_extract.ok()) { return macro_name_extract.status(); @@ -509,58 +509,68 @@ absl::Status VerilogPreprocess::HandleIf( const bool name_is_defined = defs.find(macro_name->text()) != defs.end(); const bool condition_met = (name_is_defined ^ negative_if); + // Update condition stack for annotation + if (negative_if) { + condition_stack_.push_back("!" + std::string(macro_name->text())); + } else { + condition_stack_.push_back(std::string(macro_name->text())); + } + + // Annotate with condition + const std::string comment = GenerateConditionComment(condition_stack_); + preprocess_data_.preprocessed_token_stream.push_back( + verible::TokenInfo(PP_ifdef, (*ifpos)->text() + comment)); + if ((*ifpos)->token_enum() == PP_elsif) { if (conditional_block_.size() <= 1) { preprocess_data_.errors.emplace_back(**ifpos, "Unmatched `elsif"); - return absl::InvalidArgumentError("Unmatched `else"); - } - if (!conditional_block_.top().UpdateCondition(**ifpos, condition_met)) { - preprocess_data_.errors.emplace_back(**ifpos, "`elsif after `else"); - preprocess_data_.errors.emplace_back(conditional_block_.top().token(), - "Previous `else started here."); - return absl::InvalidArgumentError("Duplicate `else"); + return absl::InvalidArgumentError("Unmatched `elsif"); } + conditional_block_.top().UpdateCondition(**ifpos, condition_met); } else { - // A new, nested if-branch. - const bool scope_enabled = conditional_block_.top().InSelectedBranch(); - conditional_block_.push(BranchBlock(scope_enabled, condition_met, **ifpos)); + conditional_block_.push(BranchBlock(conditional_block_.top().InSelectedBranch(), + condition_met, **ifpos)); } return absl::OkStatus(); } + absl::Status VerilogPreprocess::HandleElse( TokenStreamView::const_iterator else_pos) { - if (!config_.filter_branches) { // nothing to do. - preprocess_data_.preprocessed_token_stream.push_back(*else_pos); - return absl::OkStatus(); - } - if (conditional_block_.size() <= 1) { preprocess_data_.errors.emplace_back(**else_pos, "Unmatched `else"); return absl::InvalidArgumentError("Unmatched `else"); } - if (!conditional_block_.top().StartElse(**else_pos)) { - preprocess_data_.errors.emplace_back(**else_pos, "Duplicate `else"); - preprocess_data_.errors.emplace_back(conditional_block_.top().token(), - "Previous `else started here."); - return absl::InvalidArgumentError("Duplicate `else"); + // Negate the last condition for annotation + if (!condition_stack_.empty()) { + condition_stack_.back() = "!" + condition_stack_.back(); } + const std::string comment = GenerateConditionComment(condition_stack_); + preprocess_data_.preprocessed_token_stream.push_back( + verible::TokenInfo(PP_else, (*else_pos)->text() + comment)); + + conditional_block_.top().StartElse(**else_pos); return absl::OkStatus(); } + absl::Status VerilogPreprocess::HandleEndif( TokenStreamView::const_iterator endif_pos) { - if (!config_.filter_branches) { // nothing to do. - preprocess_data_.preprocessed_token_stream.push_back(*endif_pos); - return absl::OkStatus(); - } - if (conditional_block_.size() <= 1) { preprocess_data_.errors.emplace_back(**endif_pos, "Unmatched `endif"); return absl::InvalidArgumentError("Unmatched `endif"); } + + // Annotate with resolved condition stack + const std::string comment = GenerateConditionComment(condition_stack_); + preprocess_data_.preprocessed_token_stream.push_back( + verible::TokenInfo(PP_endif, (*endif_pos)->text() + comment)); + conditional_block_.pop(); + if (!condition_stack_.empty()) { + condition_stack_.pop_back(); + } return absl::OkStatus(); } diff --git a/verible/verilog/preprocessor/verilog-preprocess_test.cc b/verible/verilog/preprocessor/verilog-preprocess_test.cc index 0505d7757..454ef3d2f 100644 --- a/verible/verilog/preprocessor/verilog-preprocess_test.cc +++ b/verible/verilog/preprocessor/verilog-preprocess_test.cc @@ -1035,3 +1035,29 @@ TEST(VerilogPreprocessTest, } // namespace } // namespace verilog + +TEST(PreprocessorAnnotationTest, AnnotatesConditionals) { + const std::string input = R"( + `ifdef FOO + `ifdef BAR + code + `endif + `else + other_code + `endif + )"; + + const std::string expected_output = R"( + `ifdef FOO // FOO + `ifdef BAR // FOO && BAR + code + `endif // FOO && BAR + `else // !FOO + other_code + `endif // FOO + )"; + + VerilogPreprocess preprocess(/*config=*/{}); + auto output = preprocess.AnnotatePreprocessorDirectives(input); + EXPECT_EQ(output, expected_output); +}