Instead of include location use included filename location in
GetIncludeNameAsTyped. In case of macro use spelling location (issue #67).
This commit is contained in:
parent
15d0d83049
commit
1e43b5df1a
|
@ -36,6 +36,22 @@ using clang::UnresolvedMemberExpr;
|
|||
|
||||
namespace include_what_you_use {
|
||||
|
||||
// Instead of returning spelling location of 'macro_loc', obtain expansion info
|
||||
// for macro at this location and return spelling location of expansion info.
|
||||
SourceLocation GetMacroStartSpellingLoc(SourceLocation macro_loc) {
|
||||
CHECK_(macro_loc.isValid() && macro_loc.isMacroID()
|
||||
&& "Must call GetMacroStartSpellingLoc with valid macro location");
|
||||
std::pair<clang::FileID, unsigned> macro_loc_info =
|
||||
GlobalSourceManager()->getDecomposedLoc(macro_loc);
|
||||
bool invalid = false;
|
||||
const clang::SrcMgr::SLocEntry& loc_entry =
|
||||
GlobalSourceManager()->getSLocEntry(macro_loc_info.first, &invalid);
|
||||
CHECK_(!invalid && loc_entry.isExpansion()
|
||||
&& "Should be able to obtain expansion info for macro location");
|
||||
const clang::SrcMgr::ExpansionInfo& expansion_info = loc_entry.getExpansion();
|
||||
return expansion_info.getSpellingLoc();
|
||||
}
|
||||
|
||||
// This works around two bugs(?) in clang where decl->getLocation()
|
||||
// can be wrong for implicit template instantiations and functions.
|
||||
// (1) Consider the following code:
|
||||
|
|
|
@ -122,6 +122,10 @@ inline int GetLineNumber(clang::SourceLocation loc) {
|
|||
return retval;
|
||||
}
|
||||
|
||||
// For macro at macro_loc returns spelling location of macro start.
|
||||
// macro_loc can point anywhere in macro.
|
||||
clang::SourceLocation GetMacroStartSpellingLoc(clang::SourceLocation macro_loc);
|
||||
|
||||
// The rest of this section of the file is for returning the
|
||||
// FileEntry* corresponding to a source location: the file that the
|
||||
// location is in. This is a surprising amount of work.
|
||||
|
|
|
@ -36,11 +36,11 @@ using clang::FileEntry;
|
|||
using clang::FileID;
|
||||
using clang::MacroInfo;
|
||||
using clang::Preprocessor;
|
||||
using clang::PresumedLoc;
|
||||
using clang::SourceLocation;
|
||||
using clang::SourceRange;
|
||||
using clang::Token;
|
||||
using llvm::errs;
|
||||
using llvm::StringRef;
|
||||
using std::make_pair;
|
||||
using std::string;
|
||||
|
||||
|
@ -590,6 +590,21 @@ void IwyuPreprocessorInfo::Ifndef(SourceLocation loc, const Token& id) {
|
|||
FindAndReportMacroUse(GetName(id), id.getLocation());
|
||||
}
|
||||
|
||||
void IwyuPreprocessorInfo::InclusionDirective(
|
||||
SourceLocation hash_loc,
|
||||
const Token& include_token,
|
||||
StringRef filename,
|
||||
bool is_angled,
|
||||
const FileEntry* file,
|
||||
SourceLocation last_include_token_loc,
|
||||
StringRef search_path,
|
||||
StringRef relative_path) {
|
||||
if (last_include_token_loc.isMacroID())
|
||||
include_filename_loc_ = GetMacroStartSpellingLoc(last_include_token_loc);
|
||||
else
|
||||
include_filename_loc_ = last_include_token_loc;
|
||||
}
|
||||
|
||||
void IwyuPreprocessorInfo::FileChanged(SourceLocation loc,
|
||||
FileChangeReason reason,
|
||||
SrcMgr::CharacteristicKind file_type,
|
||||
|
@ -619,8 +634,12 @@ void IwyuPreprocessorInfo::FileChanged(SourceLocation loc,
|
|||
void IwyuPreprocessorInfo::FileSkipped(const FileEntry& file,
|
||||
const Token &filename,
|
||||
SrcMgr::CharacteristicKind file_type) {
|
||||
const SourceLocation include_loc = filename.getLocation();
|
||||
const string include_name_as_typed = GetIncludeNameAsTyped(include_loc);
|
||||
CHECK_(include_filename_loc_.isValid() &&
|
||||
"Must skip file only for actual inclusion directive");
|
||||
const string include_name_as_typed =
|
||||
GetIncludeNameAsTyped(include_filename_loc_);
|
||||
const SourceLocation include_loc =
|
||||
GetInstantiationLoc(filename.getLocation());
|
||||
ERRSYM(GetFileEntry(include_loc))
|
||||
<< "[ (#include) ] " << include_name_as_typed
|
||||
<< " (" << GetFilePath(&file) << ")\n";
|
||||
|
@ -633,12 +652,13 @@ void IwyuPreprocessorInfo::FileChanged_EnterFile(
|
|||
SourceLocation file_beginning) {
|
||||
// Get the location of the #include directive that resulted in the
|
||||
// include of the file that file_beginning is in.
|
||||
const PresumedLoc presumed =
|
||||
GlobalSourceManager()->getPresumedLoc(file_beginning);
|
||||
const SourceLocation include_loc = presumed.getIncludeLoc();
|
||||
const SourceLocation include_loc = GlobalSourceManager()->getIncludeLoc(
|
||||
GlobalSourceManager()->getFileID(file_beginning));
|
||||
string include_name_as_typed = "";
|
||||
if (!IsBuiltinOrCommandLineFile(GetFileEntry(include_loc))) {
|
||||
include_name_as_typed = GetIncludeNameAsTyped(include_loc);
|
||||
CHECK_(include_filename_loc_.isValid() &&
|
||||
"Include from not built-in file must have inclusion directive");
|
||||
include_name_as_typed = GetIncludeNameAsTyped(include_filename_loc_);
|
||||
}
|
||||
ERRSYM(GetFileEntry(include_loc))
|
||||
<< "[ #include ] " << include_name_as_typed
|
||||
|
|
|
@ -185,6 +185,15 @@ class IwyuPreprocessorInfo : public clang::PPCallbacks,
|
|||
// virtual void Else();
|
||||
// virtual void Endif();
|
||||
|
||||
virtual void InclusionDirective(clang::SourceLocation hash_loc,
|
||||
const clang::Token& include_token,
|
||||
llvm::StringRef filename,
|
||||
bool is_angled,
|
||||
const clang::FileEntry* file,
|
||||
clang::SourceLocation last_include_token_loc,
|
||||
llvm::StringRef search_path,
|
||||
llvm::StringRef relative_path);
|
||||
|
||||
virtual void FileChanged(clang::SourceLocation loc, FileChangeReason reason,
|
||||
clang::SrcMgr::CharacteristicKind file_type,
|
||||
clang::FileID PrevFID);
|
||||
|
@ -331,6 +340,13 @@ class IwyuPreprocessorInfo : public clang::PPCallbacks,
|
|||
// "begin_exports". There should be at most one item in this stack
|
||||
// per file in the current inclusion chain..
|
||||
stack<clang::SourceLocation> begin_exports_location_stack_;
|
||||
|
||||
// Filename spelling location in the last encountered inclusion directive.
|
||||
// Should be used only in FileChanged_EnterFile, FileSkipped when
|
||||
// corresponding callback is caused by inclusion directive. Don't use in
|
||||
// other places because it is unclear which inclusion directive filename
|
||||
// location corresponds to.
|
||||
clang::SourceLocation include_filename_loc_;
|
||||
};
|
||||
|
||||
} // namespace include_what_you_use
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
//===--- computed_include.cc - 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Tests computed #includes, i.e. #includes with macros.
|
||||
|
||||
#include "tests/computed_include.h"
|
||||
|
||||
// Test macro defined in another file.
|
||||
#include MACRO_INC
|
||||
// Test when #include with macro from another file is skipped.
|
||||
#include MACRO_INC
|
||||
|
||||
// Macros with angle brackets differ from macros with quotation marks: the last
|
||||
// include token is '>' and '"foo.h"' respectively.
|
||||
#define MACRO_ANGLED_INC <stdio.h>
|
||||
#include MACRO_ANGLED_INC
|
||||
// And test how such #include is skipped.
|
||||
#include MACRO_ANGLED_INC
|
||||
|
||||
// Test macro with arguments.
|
||||
#define STRINGIZE(x) #x
|
||||
#include STRINGIZE(tests/computed_include.h)
|
||||
|
||||
IndirectClass ic;
|
||||
|
||||
/**** IWYU_SUMMARY
|
||||
|
||||
tests/computed_include.cc should add these lines:
|
||||
|
||||
tests/computed_include.cc should remove these lines:
|
||||
- #include "tests/computed_include.h" // lines XX-XX
|
||||
- #include <stdio.h> // lines XX-XX
|
||||
- #include <stdio.h> // lines XX-XX
|
||||
- #include "tests/indirect.h" // lines XX-XX
|
||||
|
||||
The full include-list for tests/computed_include.cc:
|
||||
#include "tests/computed_include.h"
|
||||
#include "tests/indirect.h" // for IndirectClass
|
||||
|
||||
***** IWYU_SUMMARY */
|
|
@ -0,0 +1,16 @@
|
|||
//===--- computed_include.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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define MACRO_INC "tests/indirect.h"
|
||||
|
||||
/**** IWYU_SUMMARY
|
||||
|
||||
(tests/computed_include.h has correct #includes/fwd-decls)
|
||||
|
||||
***** IWYU_SUMMARY */
|
Loading…
Reference in New Issue