DependencyDirectivesScanner.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- clang/Lex/DependencyDirectivesScanner.h ---------------------*- C++ -*-//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. ///
  14. /// \file
  15. /// This is the interface for scanning header and source files to get the
  16. /// minimum necessary preprocessor directives for evaluating includes. It
  17. /// reduces the source down to #define, #include, #import, @import, and any
  18. /// conditional preprocessor logic that contains one of those.
  19. ///
  20. //===----------------------------------------------------------------------===//
  21. #ifndef LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H
  22. #define LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H
  23. #include "clang/Basic/SourceLocation.h"
  24. #include "llvm/ADT/ArrayRef.h"
  25. namespace clang {
  26. namespace tok {
  27. enum TokenKind : unsigned short;
  28. }
  29. class DiagnosticsEngine;
  30. namespace dependency_directives_scan {
  31. /// Token lexed as part of dependency directive scanning.
  32. struct Token {
  33. /// Offset into the original source input.
  34. unsigned Offset;
  35. unsigned Length;
  36. tok::TokenKind Kind;
  37. unsigned short Flags;
  38. Token(unsigned Offset, unsigned Length, tok::TokenKind Kind,
  39. unsigned short Flags)
  40. : Offset(Offset), Length(Length), Kind(Kind), Flags(Flags) {}
  41. unsigned getEnd() const { return Offset + Length; }
  42. bool is(tok::TokenKind K) const { return Kind == K; }
  43. bool isNot(tok::TokenKind K) const { return Kind != K; }
  44. bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
  45. return is(K1) || is(K2);
  46. }
  47. template <typename... Ts> bool isOneOf(tok::TokenKind K1, Ts... Ks) const {
  48. return is(K1) || isOneOf(Ks...);
  49. }
  50. };
  51. /// Represents the kind of preprocessor directive or a module declaration that
  52. /// is tracked by the scanner in its token output.
  53. enum DirectiveKind : uint8_t {
  54. pp_none,
  55. pp_include,
  56. pp___include_macros,
  57. pp_define,
  58. pp_undef,
  59. pp_import,
  60. pp_pragma_import,
  61. pp_pragma_once,
  62. pp_pragma_push_macro,
  63. pp_pragma_pop_macro,
  64. pp_pragma_include_alias,
  65. pp_include_next,
  66. pp_if,
  67. pp_ifdef,
  68. pp_ifndef,
  69. pp_elif,
  70. pp_elifdef,
  71. pp_elifndef,
  72. pp_else,
  73. pp_endif,
  74. decl_at_import,
  75. cxx_module_decl,
  76. cxx_import_decl,
  77. cxx_export_module_decl,
  78. cxx_export_import_decl,
  79. /// Indicates that there are tokens present between the last scanned directive
  80. /// and eof. The \p Directive::Tokens array will be empty for this kind.
  81. tokens_present_before_eof,
  82. pp_eof,
  83. };
  84. /// Represents a directive that's lexed as part of the dependency directives
  85. /// scanning. It's used to track various preprocessor directives that could
  86. /// potentially have an effect on the dependencies.
  87. struct Directive {
  88. ArrayRef<Token> Tokens;
  89. /// The kind of token.
  90. DirectiveKind Kind = pp_none;
  91. Directive() = default;
  92. Directive(DirectiveKind K, ArrayRef<Token> Tokens)
  93. : Tokens(Tokens), Kind(K) {}
  94. };
  95. } // end namespace dependency_directives_scan
  96. /// Scan the input for the preprocessor directives that might have
  97. /// an effect on the dependencies for a compilation unit.
  98. ///
  99. /// This function ignores all non-preprocessor code and anything that
  100. /// can't affect what gets included.
  101. ///
  102. /// \returns false on success, true on error. If the diagnostic engine is not
  103. /// null, an appropriate error is reported using the given input location
  104. /// with the offset that corresponds to the \p Input buffer offset.
  105. bool scanSourceForDependencyDirectives(
  106. StringRef Input, SmallVectorImpl<dependency_directives_scan::Token> &Tokens,
  107. SmallVectorImpl<dependency_directives_scan::Directive> &Directives,
  108. DiagnosticsEngine *Diags = nullptr,
  109. SourceLocation InputSourceLoc = SourceLocation());
  110. /// Print the previously scanned dependency directives as minimized source text.
  111. ///
  112. /// \param Source The original source text that the dependency directives were
  113. /// scanned from.
  114. /// \param Directives The previously scanned dependency
  115. /// directives.
  116. /// \param OS the stream to print the dependency directives on.
  117. ///
  118. /// This is used primarily for testing purposes, during dependency scanning the
  119. /// \p Lexer uses the tokens directly, not their printed version.
  120. void printDependencyDirectivesAsSource(
  121. StringRef Source,
  122. ArrayRef<dependency_directives_scan::Directive> Directives,
  123. llvm::raw_ostream &OS);
  124. } // end namespace clang
  125. #endif // LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H
  126. #ifdef __GNUC__
  127. #pragma GCC diagnostic pop
  128. #endif