-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Add error check for HeuristicResolver #155561
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -658,13 +658,15 @@ class ASTBuilderAction : public ToolAction { | |
| Invocation->getDiagnosticOpts(), | ||
| DiagConsumer, | ||
| /*ShouldOwnClient=*/false), | ||
| Files); | ||
| Files, false, CaptureKinds); | ||
| if (!AST) | ||
| return false; | ||
|
|
||
| ASTs.push_back(std::move(AST)); | ||
| return true; | ||
| } | ||
|
|
||
| CaptureDiagsKind CaptureKinds{CaptureDiagsKind::None}; | ||
|
||
| }; | ||
|
|
||
| } // namespace | ||
|
|
@@ -692,10 +694,13 @@ std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs( | |
| StringRef Code, const std::vector<std::string> &Args, StringRef FileName, | ||
| StringRef ToolName, std::shared_ptr<PCHContainerOperations> PCHContainerOps, | ||
| ArgumentsAdjuster Adjuster, const FileContentMappings &VirtualMappedFiles, | ||
| DiagnosticConsumer *DiagConsumer, | ||
| DiagnosticConsumer *DiagConsumer, CaptureDiagsKind CaptureKind, | ||
| IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) { | ||
| std::vector<std::unique_ptr<ASTUnit>> ASTs; | ||
|
|
||
| ASTBuilderAction Action(ASTs); | ||
| Action.CaptureKinds = CaptureDiagsKind::All; | ||
|
||
|
|
||
| auto OverlayFileSystem = | ||
| llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>( | ||
| std::move(BaseFS)); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,7 +8,9 @@ | |||||||||||||||
| #include "clang/Sema/HeuristicResolver.h" | ||||||||||||||||
| #include "clang/ASTMatchers/ASTMatchFinder.h" | ||||||||||||||||
| #include "clang/ASTMatchers/ASTMatchers.h" | ||||||||||||||||
| #include "clang/Basic/Diagnostic.h" | ||||||||||||||||
| #include "clang/Tooling/Tooling.h" | ||||||||||||||||
| #include "llvm/ADT/SmallSet.h" | ||||||||||||||||
| #include "gmock/gmock-matchers.h" | ||||||||||||||||
| #include "gtest/gtest.h" | ||||||||||||||||
|
|
||||||||||||||||
|
|
@@ -31,6 +33,24 @@ template <typename InputNode> | |||||||||||||||
| using ResolveFnT = std::function<std::vector<const NamedDecl *>( | ||||||||||||||||
| const HeuristicResolver *, InputNode)>; | ||||||||||||||||
|
|
||||||||||||||||
| std::string format_error(const clang::StoredDiagnostic *D) { | ||||||||||||||||
| std::ostringstream Msg{}; | ||||||||||||||||
| if (D->getLevel() == DiagnosticsEngine::Level::Ignored) | ||||||||||||||||
| Msg << "Ignored: "; | ||||||||||||||||
| if (D->getLevel() == DiagnosticsEngine::Level::Note) | ||||||||||||||||
| Msg << "Note: "; | ||||||||||||||||
| if (D->getLevel() == DiagnosticsEngine::Level::Remark) | ||||||||||||||||
| Msg << "Remark: "; | ||||||||||||||||
| if (D->getLevel() == DiagnosticsEngine::Level::Warning) | ||||||||||||||||
| Msg << "Warning: "; | ||||||||||||||||
| if (D->getLevel() == DiagnosticsEngine::Level::Error) | ||||||||||||||||
| Msg << "Error: "; | ||||||||||||||||
| if (D->getLevel() == DiagnosticsEngine::Level::Fatal) | ||||||||||||||||
| Msg << "Fatal: "; | ||||||||||||||||
| Msg << D->getID() << ": " << D->getMessage().str(); | ||||||||||||||||
| return Msg.str(); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| // Test heuristic resolution on `Code` using the resolution procedure | ||||||||||||||||
| // `ResolveFn`, which takes a `HeuristicResolver` and an input AST node of type | ||||||||||||||||
| // `InputNode` and returns a `std::vector<const NamedDecl *>`. | ||||||||||||||||
|
|
@@ -41,7 +61,16 @@ template <typename InputNode, typename ParamT, typename InputMatcher, | |||||||||||||||
| typename... OutputMatchers> | ||||||||||||||||
| void expectResolution(llvm::StringRef Code, ResolveFnT<ParamT> ResolveFn, | ||||||||||||||||
| const InputMatcher &IM, const OutputMatchers &...OMS) { | ||||||||||||||||
| llvm::SmallSet<unsigned int, 16> IgnoredDiagnostics{}; | ||||||||||||||||
|
||||||||||||||||
| void expectResolution(llvm::StringRef Code, ResolveFnT<ParamT> ResolveFn, | |
| const InputMatcher &IM, const OutputMatchers &...OMS) { | |
| llvm::SmallSet<unsigned int, 16> IgnoredDiagnostics{}; | |
| void expectResolution(llvm::StringRef Code, | |
| llvm::SmallSet<unsigned int, 16> IgnoredDiagnostics, | |
| ResolveFnT<ParamT> ResolveFn, const InputMatcher &IM, | |
| const OutputMatchers &...OMS) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would hold off on adding something like IgnoreDiagnostics until we actually have a use case for it
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to be actually passing CaptureDiagsKind::All here
(A good way to validate that the mechanism we're adding is actually working is to change the -std=c++23 to -std=c++20 here. That should cause MemberExpr_ExplicitObjectParameter to fail, and it currently doesn't.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
omg totally forgot about this, sorry!
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only tangentially related, but since we're touching libTooling code anyways (and since it's not 1998 any more 😆), shall we take the opportunity to add a range wrapper similar to this to ASTUnit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if that was okay lol, I'll go ahead and do that as well.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you intentionally disallowing warnings by default?
(I don't particularly feel strongly either way, but in the clangd test infra the check is level < Error, so I was just curious if you're deliberately being stricter.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you intentionally disallowing warnings by default?
Yeah, I thought this was helpful when language conveniences are enabled without explicit opt-in. I wasn't sure what the norm was; I'll update it to < Error, which is the norm (thanks for the heads-up!)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a public API, and likely one with a fair number of downstream users.
While clang doesn't make any stability guarantees about it's C++ API, I think it's still good practice to avoid API breaks that are unnecessary, since it takes work for downstreams to rebase across them.
So, in a case like this, where we're adding a new optional argument to an API function, I think we should add it to the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, I'll do that