This patch adds a new AST matcher called isInTopNamespace. It is used to
check if a Decl is in a specific top-level namespace. before this, we can
only check if a Decl in std namespace or not. I believe that it is
useful to implement some clang-tidy checks like replacing some old
3rd-party component to new STL facility, like boost::shared_ptr.
Details
- Reviewers
rtrieu gribozavr aaron.ballman klimek
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Time | Test | |
---|---|---|
60 ms | x64 debian > LLVM.Bindings/Go::go.test |
Event Timeline
These changes lack test coverage or uses of the new API, so it's a bit hard to tell whether it's being used correctly or not.
clang/include/clang/AST/DeclBase.h | ||
---|---|---|
470 | I think this API needs some comments and explanation. Is the given namespace expected to be fully qualified or will this match partial namespaces? Is it checking whether the declaration is lexically in the namespace or semantically? How does it handle inline namespaces? That sort of thing. e.g., namespace foo { void decl(); namespace bar { int x; // Does isInNamespace("foo") return true for this declaration? } inline namespace baz { int y; // Does isInNamespace("foo") return true for this declaration? } } void foo::decl() {} // Does isInNamespace("foo") return true for this specific declaration? | |
clang/lib/AST/DeclBase.cpp | ||
396 | Same concerns here as above. It's not at all clear what "in" means for this. |
After Aarron's comments, I realize what I really want to do is add a new
ASTMatcher that matches declarations what in the top level namespace like std.
This update fixed previous broken one, added some comments and unit tests.
clang/include/clang/AST/DeclBase.h | ||
---|---|---|
465–467 | I'm not entirely sold on this API as it's super specific to just one use case of checking the initial namespace component -- that can already be done trivially by calling getQualifiedNameAsString() and doing a string compare up to the first ::, basically (at least for named declarations). Also, it's still not clear whether this is talking about a lexical or semantic lookup. e.g., namespace foo { void bar(); // This decl is lexically and semantically in foo } void foo::bar() {} // This decl is lexically in the global namespace but is semantically within foo. Does isInTopNamespace("foo") return true for both declarations, or just the first? I think it'd be nice to generalize this a bit more, into something like bool isInNamespace(llvm::StringRef FullyQualifiedNamespace, LookupContext Kind) (and make a new enum for LookupContext [feel free to pick a better name, too] that specifies semantic vs lexical so the user can pick which behavior they want). However, even this is a bit of a tough API because of namespace aliases. e.g., namespace foo { void bar(); } namespace frobble = foo; void frobble::bar() {} // What should isInNamespace("foo") do here? My inclination is to return true, maybe? |
I'm not entirely sold on this API as it's super specific to just one use case of checking the initial namespace component -- that can already be done trivially by calling getQualifiedNameAsString() and doing a string compare up to the first ::, basically (at least for named declarations).
Also, it's still not clear whether this is talking about a lexical or semantic lookup. e.g.,
Does isInTopNamespace("foo") return true for both declarations, or just the first?
I think it'd be nice to generalize this a bit more, into something like bool isInNamespace(llvm::StringRef FullyQualifiedNamespace, LookupContext Kind) (and make a new enum for LookupContext [feel free to pick a better name, too] that specifies semantic vs lexical so the user can pick which behavior they want).
However, even this is a bit of a tough API because of namespace aliases. e.g.,