Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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