Make --no_fwd_decls respect local forward decls

Before this, the --no_fwd_decls mode would force-remove existing forward
decls:

    class Foo;
    void Bar(const Foo*);

Add an additional rule that we avoid promoting uses of forward-
declarations in the same file to full uses, to retain forward-decls like
the above.

This makes the behavior of --no_fwd_decls simpler and more consistent:
optimize for fewer redeclarations instead of fewer includes. Whenever
there's a choice between a forward-decl and an include, choose the
include.

Add test coverage for more variants of included forward decls.
This commit is contained in:
Kim Grasman 2019-01-27 18:13:16 +01:00 committed by Kim Gräsman
parent 34a1d7b107
commit a7d99d15b3
4 changed files with 70 additions and 2 deletions

View File

@ -1105,8 +1105,12 @@ void ProcessForwardDeclare(OneUse* use,
}
}
// (A7) If --no_fwd_decls has been passed, recategorize as a full use.
if (GlobalFlags().no_fwd_decls) {
// (A7) If --no_fwd_decls has been passed, recategorize as a full use unless
// the decl is in this file (in which case it must be a self-sufficient decl
// being used, so we can just let IWYU do its work).
if (!use->ignore_use() &&
GlobalFlags().no_fwd_decls &&
GetFileEntry(use->decl_loc()) != GetFileEntry(use->use_loc())) {
use->set_full_use();
}
}

View File

@ -0,0 +1,15 @@
//===--- no_fwd_decls-fwd.h - test input file for iwyu --------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef INCLUDE_WHAT_YOU_USE_TESTS_CXX_NO_FWD_DECLS_FWD_H_
#define INCLUDE_WHAT_YOU_USE_TESTS_CXX_NO_FWD_DECLS_FWD_H_
class Fwd;
#endif // INCLUDE_WHAT_YOU_USE_TESTS_CXX_NO_FWD_DECLS-FWD_H_

View File

@ -0,0 +1,19 @@
//===--- no_fwd_decls-nameonly.h - test input file for iwyu ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef INCLUDE_WHAT_YOU_USE_TESTS_CXX_NO_FWD_DECLS_NAMEONLY_H_
#define INCLUDE_WHAT_YOU_USE_TESTS_CXX_NO_FWD_DECLS_NAMEONLY_H_
class NameOnly;
const void* AddressOf(const NameOnly& a) {
return reinterpret_cast<const void*>(&a);
}
#endif // INCLUDE_WHAT_YOU_USE_TESTS_CXX_NO_FWD_DECLS-NAMEONLY_H_

View File

@ -9,12 +9,38 @@
// Test that passing the --no_fwd_decls switch to IWYU suggests including the
// corresponding header file even when the use is not a full use.
//
// The normal IWYU policy is to minimize the number of #include directives
// without introducing unnecessary coupling.
// The --no_fwd_decls policy is to minimize the number of redeclarations to
// avoid over-loose coupling, which might lead to errors and busy-work when a
// type eventually changes.
#include "tests/cxx/direct.h"
#include "tests/cxx/no_fwd_decls-fwd.h"
#include "tests/cxx/no_fwd_decls-nameonly.h"
// IWYU: IndirectClass is...*indirect.h
IndirectClass* global;
// Existing forward-declares that don't exist anywhere else should stay,
// because we don't know where a declaration would come from otherwise.
class LocalFwd;
void ForwardDeclareUse(const LocalFwd*);
// A forward-declare that also exists in an included header can be removed.
// Normally IWYU would optimize for fewer includes, but in --no_fwd_decls mode
// we optimize for fewer redeclarations instead.
class Fwd;
void ForwardDeclareUse(const Fwd&);
// Make sure a forward-declare included from a desired header is not repeated
// here.
bool AreSame(const NameOnly& a, const NameOnly& b) {
return AddressOf(a) == AddressOf(b);
}
/**** IWYU_SUMMARY
tests/cxx/no_fwd_decls.cc should add these lines:
@ -22,8 +48,12 @@ tests/cxx/no_fwd_decls.cc should add these lines:
tests/cxx/no_fwd_decls.cc should remove these lines:
- #include "tests/cxx/direct.h" // lines XX-XX
- class Fwd; // lines XX-XX
The full include-list for tests/cxx/no_fwd_decls.cc:
#include "tests/cxx/indirect.h" // for IndirectClass
#include "tests/cxx/no_fwd_decls-fwd.h" // for Fwd
#include "tests/cxx/no_fwd_decls-nameonly.h" // for AddressOf, NameOnly
class LocalFwd; // lines XX-XX
***** IWYU_SUMMARY */