Avoid 'autocast' reporting for function definition
A function may just transmit passed-by-reference parameter somewhere. Requirement to explicitly write forward declaration in the same file (.cpp-file) to avoid '#include' suggestion is impractical when that type is already fwd-declared in the corresponding header. 'Autocast' may still make sense for header-defined functions, due to unlimited number of possible callers, so analysis of those fuctions is kept. Both function declaration site handling and call site handling are changed.
This commit is contained in:
parent
8b3da1112e
commit
862812049a
7
iwyu.cc
7
iwyu.cc
|
@ -1484,6 +1484,8 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
|
|||
GetFileEntry(call_expr), GetFileEntry(*fn_redecl))) {
|
||||
continue;
|
||||
}
|
||||
if (fn_redecl->isThisDeclarationADefinition() && !IsInHeader(*fn_redecl))
|
||||
continue;
|
||||
for (set<const Type*>::iterator it = retval.begin();
|
||||
it != retval.end(); ) {
|
||||
if (!CodeAuthorWantsJustAForwardDeclare(*it, GetLocation(*fn_redecl))) {
|
||||
|
@ -1768,6 +1770,11 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
|
|||
while ((redecl = redecl->getPreviousDecl()))
|
||||
ReportDeclUse(CurrentLoc(), redecl);
|
||||
}
|
||||
if (!IsInHeader(decl)) {
|
||||
// No point in author-intent analysis of function definitions
|
||||
// in source files.
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Make all our types forward-declarable...
|
||||
current_ast_node()->set_in_forward_declare_context(true);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "iwyu_location_util.h"
|
||||
|
||||
#include "iwyu_ast_util.h"
|
||||
#include "iwyu_port.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
|
@ -28,6 +29,7 @@ using clang::CXXMethodDecl;
|
|||
using clang::CXXOperatorCallExpr;
|
||||
using clang::ClassTemplateSpecializationDecl;
|
||||
using clang::ConditionalOperator;
|
||||
using clang::FileEntry;
|
||||
using clang::FunctionDecl;
|
||||
using clang::MemberExpr;
|
||||
using clang::SourceLocation;
|
||||
|
@ -170,4 +172,10 @@ bool IsInScratchSpace(SourceLocation loc) {
|
|||
return StartsWith(PrintableLoc(GetSpellingLoc(loc)), "<scratch space>");
|
||||
}
|
||||
|
||||
bool IsInHeader(const clang::Decl* decl) {
|
||||
const FileEntry* containing_file = GetFileEntry(decl);
|
||||
CHECK_(containing_file);
|
||||
return !GlobalSourceManager()->isMainFile(*containing_file);
|
||||
}
|
||||
|
||||
} // namespace include_what_you_use
|
||||
|
|
|
@ -228,6 +228,9 @@ inline bool IsBeforeInSameFile(const T& a, const U& b) {
|
|||
return IsBeforeInTranslationUnit(a, b);
|
||||
}
|
||||
|
||||
// Returns true if the given declaration is located in a header file.
|
||||
bool IsInHeader(const clang::Decl*);
|
||||
|
||||
} // namespace include_what_you_use
|
||||
|
||||
#endif // INCLUDE_WHAT_YOU_USE_IWYU_LOCATION_UTIL_H_
|
||||
|
|
|
@ -22,6 +22,14 @@ int ImplicitCtorFn(IndirectWithImplicitCtor);
|
|||
// IWYU: IndirectWithImplicitCtor is...*implicit_ctor-i2.h.*for autocast
|
||||
int ImplicitCtorRefFn(const IndirectWithImplicitCtor&);
|
||||
|
||||
// Reporting types for "autocast" for header-defined functions still makes sense
|
||||
// as opposed to function definitions in source files.
|
||||
// IWYU: IndirectWithImplicitCtor needs a declaration
|
||||
// IWYU: IndirectWithImplicitCtor is...*implicit_ctor-i2.h.*for autocast
|
||||
inline int InlineImplicitCtorRefFn(const IndirectWithImplicitCtor&) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Test parameter type uses that do not require special handling for "autocast".
|
||||
int NoAutocastFn(
|
||||
// A subtle c++ point: forward-declaring is ok for nonconst, because
|
||||
|
|
|
@ -22,6 +22,18 @@
|
|||
|
||||
#include "tests/cxx/implicit_ctor-d1.h"
|
||||
|
||||
// No reporting types for "autocast" for .cpp-file-local functions...
|
||||
// IWYU: IndirectWithImplicitCtor needs a declaration
|
||||
static int LocalFn(const IndirectWithImplicitCtor&) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ... or for .cpp-file-definitions of functions declared in a header.
|
||||
// IWYU: IndirectWithImplicitCtor needs a declaration
|
||||
int ImplicitCtorRefFn(const IndirectWithImplicitCtor&) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
// We don't need IndirectWithImplicitCtor even though we must convert to it.
|
||||
int a = ImplicitCtorFn(1);
|
||||
int b = ImplicitCtorRefFn(2);
|
||||
|
@ -32,6 +44,13 @@ int c = ImplicitCtorFn(IndirectWithImplicitCtor(3));
|
|||
// IWYU: IndirectWithImplicitCtor is...*implicit_ctor-i2.h
|
||||
int d = ImplicitCtorRefFn(IndirectWithImplicitCtor(4));
|
||||
|
||||
// LocalFn doesn't provide IndirectWithImplicitCtor type info.
|
||||
// IWYU: IndirectWithImplicitCtor is...*implicit_ctor-i2.h
|
||||
int e = LocalFn(5);
|
||||
// InlineImplicitCtorRefFn should provide parameter type info,
|
||||
// hence no reporting.
|
||||
int f = InlineImplicitCtorRefFn(6);
|
||||
|
||||
// Make sure we are responsible for the conversion when it's not for a
|
||||
// function call.
|
||||
// IWYU: IndirectWithImplicitCtor is...*implicit_ctor-i2.h
|
||||
|
@ -48,7 +67,7 @@ tests/cxx/implicit_ctor.cc should add these lines:
|
|||
tests/cxx/implicit_ctor.cc should remove these lines:
|
||||
|
||||
The full include-list for tests/cxx/implicit_ctor.cc:
|
||||
#include "tests/cxx/implicit_ctor-d1.h" // for ImplicitCtorFn, ImplicitCtorRefFn
|
||||
#include "tests/cxx/implicit_ctor-d1.h" // for ImplicitCtorFn, ImplicitCtorRefFn, InlineImplicitCtorRefFn
|
||||
#include "tests/cxx/implicit_ctor-i2.h" // for IndirectWithImplicitCtor
|
||||
|
||||
***** IWYU_SUMMARY */
|
||||
|
|
Loading…
Reference in New Issue