Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 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 |