summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolodymyr Sapsai <vsapsai@users.noreply.github.com>2017-07-03 14:36:21 -0700
committerKim Grasman <kim.grasman@gmail.com>2017-07-16 11:26:23 +0200
commit6a7b17546b630fe8587d2af37e8446199adfa26b (patch)
tree4532c750d19bb011813193d9750dc04a5e009eec
parent79083f40153b3e21425d988bde031f1a206c3c5a (diff)
Fix requiring allocator for getting container iterator with libc++. (#448)
libc++ code is template <class _Tp, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::begin() _NOEXCEPT { return __make_iter(this->__begin_); } and we reported use of allocator when visiting `vector<_Tp, _Allocator>` because here `_Allocator` is not a default template argument. There was no such problem in libstdc++ because there `begin` is defined inside a class. Also I wasn't able to reproduce the issue with non-STL types because for not precomputed types we replayed template arguments usage. And when we populate the cache we see which template arguments are default so there are no problems during replay. Update test to remove method calls using object template arguments. As result, on macOS it fixed errors tests/cxx/badinc.cc:1534: Unexpected diagnostic: I2_Enum is defined in "tests/cxx/badinc-i2.h", which isn't directly #included. tests/cxx/badinc.cc:1580: Unexpected diagnostic: I2_Enum is defined in "tests/cxx/badinc-i2.h", which isn't directly #included. but introduced another error tests/cxx/badinc.cc:1527: Unmatched regex: I2_Enum is...*badinc-i2.h I think it's a reasonable trade-off.
-rw-r--r--iwyu.cc21
-rw-r--r--tests/cxx/badinc.cc3
-rw-r--r--tests/cxx/stl_container_provides_allocator.cc1
3 files changed, 22 insertions, 3 deletions
diff --git a/iwyu.cc b/iwyu.cc
index f9b1982..a861712 100644
--- a/iwyu.cc
+++ b/iwyu.cc
@@ -2552,7 +2552,26 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
// If we're in an nns (e.g. the Foo in Foo::bar), we're never
// forward-declarable, even if we're part of a pointer type, or in
// a template argument, or whatever.
- current_ast_node()->set_in_forward_declare_context(false);
+ ASTNode* ast_node = current_ast_node();
+ ast_node->set_in_forward_declare_context(false);
+
+ // For method calls it doesn't matter if a method is defined inside
+ // a class or outside of it. We detect out-of-class method calls with
+ // the pattern
+ //
+ // CallExpr
+ // `-CXXMethodDecl
+ // `-NestedNameSpecifier
+ //
+ // and skip traversing method qualifier as in-class methods don't have it.
+ if (const CXXMethodDecl* parent = ast_node->GetParentAs<CXXMethodDecl>()) {
+ if ((nns == parent->getQualifier()) &&
+ ast_node->AncestorIsA<CallExpr>(2)) {
+ VERRS(7) << "Skipping traversal of CXXMethodDecl qualifier "
+ << PrintableNestedNameSpecifier(nns) << "\n";
+ return false;
+ }
+ }
return true;
}
diff --git a/tests/cxx/badinc.cc b/tests/cxx/badinc.cc
index 921ecc7..c6bd5e2 100644
--- a/tests/cxx/badinc.cc
+++ b/tests/cxx/badinc.cc
@@ -1844,7 +1844,6 @@ int main() {
// IWYU: I1_Class needs a declaration
H_TemplateFunction<I1_Class*>(&i1_class);
H_TemplateFunction(&i1_class);
- // IWYU: I1_Enum is...*badinc-i1.h
// IWYU: I22 is...*badinc-i2.h
h_templateclass2.static_out_of_line(I22);
// IWYU: I22 is...*badinc-i2.h
@@ -1947,7 +1946,7 @@ The full include-list for tests/cxx/badinc.cc:
#include <fstream> // for fstream
#include <list> // for list
#include <new> // for operator new
-#include <string> // for allocator, basic_string, basic_string<>::iterator, operator+, string
+#include <string> // for basic_string, basic_string<>::iterator, operator+, string
#include <typeinfo> // for type_info
#include "tests/cxx/badinc-d1.h" // for D1CopyClassFn, D1Function, D1_Class, D1_CopyClass, D1_Enum, D1_Enum::D11, D1_I1_Typedef, D1_StructPtr, D1_Subclass, D1_TemplateClass, D1_TemplateStructWithDefaultParam, MACRO_CALLING_I4_FUNCTION
#include "tests/cxx/badinc-d4.h" // for D4_ClassForOperator, operator<<
diff --git a/tests/cxx/stl_container_provides_allocator.cc b/tests/cxx/stl_container_provides_allocator.cc
index 10732aa..aadc1ec 100644
--- a/tests/cxx/stl_container_provides_allocator.cc
+++ b/tests/cxx/stl_container_provides_allocator.cc
@@ -27,6 +27,7 @@ void foo() {
std::uninitialized_fill(buffer, buffer + 4, 0);
std::vector<int> v;
+ (void)v.begin();
}
/**** IWYU_SUMMARY