HeaderIncludeGen.cpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //===--- HeaderIncludes.cpp - Generate Header Includes --------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "clang/Frontend/Utils.h"
  10. #include "clang/Basic/SourceManager.h"
  11. #include "clang/Lex/Preprocessor.h"
  12. using namespace clang;
  13. namespace {
  14. class HeaderIncludesCallback : public PPCallbacks {
  15. SourceManager &SM;
  16. unsigned CurrentIncludeDepth;
  17. bool ShowAllHeaders;
  18. bool HasProcessedPredefines;
  19. public:
  20. HeaderIncludesCallback(const Preprocessor *PP, bool ShowAllHeaders_)
  21. : SM(PP->getSourceManager()), CurrentIncludeDepth(0),
  22. ShowAllHeaders(ShowAllHeaders_), HasProcessedPredefines(false) {}
  23. virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
  24. SrcMgr::CharacteristicKind FileType);
  25. };
  26. }
  27. void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders,
  28. llvm::StringRef OutputPath) {
  29. PP.addPPCallbacks(new HeaderIncludesCallback(&PP, ShowAllHeaders));
  30. }
  31. void HeaderIncludesCallback::FileChanged(SourceLocation Loc,
  32. FileChangeReason Reason,
  33. SrcMgr::CharacteristicKind NewFileType) {
  34. // Unless we are exiting a #include, make sure to skip ahead to the line the
  35. // #include directive was at.
  36. PresumedLoc UserLoc = SM.getPresumedLoc(Loc);
  37. if (UserLoc.isInvalid())
  38. return;
  39. // Adjust the current include depth.
  40. if (Reason == PPCallbacks::EnterFile) {
  41. ++CurrentIncludeDepth;
  42. } else {
  43. if (CurrentIncludeDepth)
  44. --CurrentIncludeDepth;
  45. // We track when we are done with the predefines by watching for the first
  46. // place where we drop back to a nesting depth of 0.
  47. if (CurrentIncludeDepth == 0 && !HasProcessedPredefines)
  48. HasProcessedPredefines = true;
  49. }
  50. // Show the header if we are (a) past the predefines, or (b) showing all
  51. // headers and in the predefines at a depth past the initial file and command
  52. // line buffers.
  53. bool ShowHeader = (HasProcessedPredefines ||
  54. (ShowAllHeaders && CurrentIncludeDepth > 2));
  55. // Dump the header include information we are past the predefines buffer or
  56. // are showing all headers.
  57. if (ShowHeader && Reason == PPCallbacks::EnterFile) {
  58. // Write to a temporary string to avoid unnecessary flushing on errs().
  59. llvm::SmallString<512> Filename(UserLoc.getFilename());
  60. Lexer::Stringify(Filename);
  61. llvm::SmallString<256> Msg;
  62. for (unsigned i = 0; i != CurrentIncludeDepth; ++i)
  63. Msg += '.';
  64. Msg += ' ';
  65. Msg += Filename;
  66. Msg += '\n';
  67. llvm::errs() << Msg;
  68. }
  69. }