/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Lex/DependencyDirectivesScanner.h
Line | Count | Source |
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 | 1.89M | : Offset(Offset), Length(Length), Kind(Kind), Flags(Flags) {} |
44 | | |
45 | 327k | unsigned getEnd() const { return Offset + Length; } |
46 | | |
47 | 1.55M | bool is(tok::TokenKind K) const { return Kind == K; } |
48 | 326k | bool isNot(tok::TokenKind K) const { return Kind != K; } |
49 | 446 | bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const { |
50 | 446 | return is(K1) || is(K2)441 ; |
51 | 446 | } |
52 | 1.20k | template <typename... Ts> bool isOneOf(tok::TokenKind K1, Ts... Ks) const { |
53 | 1.20k | return is(K1) || isOneOf(Ks...)1.16k ; |
54 | 1.20k | } bool clang::dependency_directives_scan::Token::isOneOf<clang::tok::TokenKind, clang::tok::TokenKind, clang::tok::TokenKind>(clang::tok::TokenKind, clang::tok::TokenKind, clang::tok::TokenKind, clang::tok::TokenKind) const Line | Count | Source | 52 | 455 | template <typename... Ts> bool isOneOf(tok::TokenKind K1, Ts... Ks) const { | 53 | 455 | return is(K1) || isOneOf(Ks...)443 ; | 54 | 455 | } |
bool clang::dependency_directives_scan::Token::isOneOf<clang::tok::TokenKind, clang::tok::TokenKind, clang::tok::TokenKind, clang::tok::TokenKind>(clang::tok::TokenKind, clang::tok::TokenKind, clang::tok::TokenKind, clang::tok::TokenKind, clang::tok::TokenKind) const Line | Count | Source | 52 | 288 | template <typename... Ts> bool isOneOf(tok::TokenKind K1, Ts... Ks) const { | 53 | 288 | return is(K1) || isOneOf(Ks...)279 ; | 54 | 288 | } |
bool clang::dependency_directives_scan::Token::isOneOf<clang::tok::TokenKind, clang::tok::TokenKind>(clang::tok::TokenKind, clang::tok::TokenKind, clang::tok::TokenKind) const Line | Count | Source | 52 | 459 | template <typename... Ts> bool isOneOf(tok::TokenKind K1, Ts... Ks) const { | 53 | 459 | return is(K1) || isOneOf(Ks...)446 ; | 54 | 459 | } |
|
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 | | pp_eof, |
86 | | }; |
87 | | |
88 | | /// Represents a directive that's lexed as part of the dependency directives |
89 | | /// scanning. It's used to track various preprocessor directives that could |
90 | | /// potentially have an effect on the depedencies. |
91 | | struct Directive { |
92 | | ArrayRef<Token> Tokens; |
93 | | |
94 | | /// The kind of token. |
95 | | DirectiveKind Kind = pp_none; |
96 | | |
97 | | Directive() = default; |
98 | | Directive(DirectiveKind K, ArrayRef<Token> Tokens) |
99 | 240k | : Tokens(Tokens), Kind(K) {} |
100 | | }; |
101 | | |
102 | | } // end namespace dependency_directives_scan |
103 | | |
104 | | /// Scan the input for the preprocessor directives that might have |
105 | | /// an effect on the dependencies for a compilation unit. |
106 | | /// |
107 | | /// This function ignores all non-preprocessor code and anything that |
108 | | /// can't affect what gets included. |
109 | | /// |
110 | | /// \returns false on success, true on error. If the diagnostic engine is not |
111 | | /// null, an appropriate error is reported using the given input location |
112 | | /// with the offset that corresponds to the \p Input buffer offset. |
113 | | bool scanSourceForDependencyDirectives( |
114 | | StringRef Input, SmallVectorImpl<dependency_directives_scan::Token> &Tokens, |
115 | | SmallVectorImpl<dependency_directives_scan::Directive> &Directives, |
116 | | DiagnosticsEngine *Diags = nullptr, |
117 | | SourceLocation InputSourceLoc = SourceLocation()); |
118 | | |
119 | | /// Print the previously scanned dependency directives as minimized source text. |
120 | | /// |
121 | | /// \param Source The original source text that the dependency directives were |
122 | | /// scanned from. |
123 | | /// \param Directives The previously scanned dependency |
124 | | /// directives. |
125 | | /// \param OS the stream to print the dependency directives on. |
126 | | /// |
127 | | /// This is used primarily for testing purposes, during dependency scanning the |
128 | | /// \p Lexer uses the tokens directly, not their printed version. |
129 | | void printDependencyDirectivesAsSource( |
130 | | StringRef Source, |
131 | | ArrayRef<dependency_directives_scan::Directive> Directives, |
132 | | llvm::raw_ostream &OS); |
133 | | |
134 | | } // end namespace clang |
135 | | |
136 | | #endif // LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H |