Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:56

0001 //===- clang/Lex/DependencyDirectivesScanner.h ---------------------*- C++ -*-//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This is the interface for scanning header and source files to get the
0011 /// minimum necessary preprocessor directives for evaluating includes. It
0012 /// reduces the source down to #define, #include, #import, @import, and any
0013 /// conditional preprocessor logic that contains one of those.
0014 ///
0015 //===----------------------------------------------------------------------===//
0016 
0017 #ifndef LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H
0018 #define LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H
0019 
0020 #include "clang/Basic/SourceLocation.h"
0021 #include "llvm/ADT/ArrayRef.h"
0022 
0023 namespace clang {
0024 
0025 namespace tok {
0026 enum TokenKind : unsigned short;
0027 }
0028 
0029 class DiagnosticsEngine;
0030 
0031 namespace dependency_directives_scan {
0032 
0033 /// Token lexed as part of dependency directive scanning.
0034 struct Token {
0035   /// Offset into the original source input.
0036   unsigned Offset;
0037   unsigned Length;
0038   tok::TokenKind Kind;
0039   unsigned short Flags;
0040 
0041   Token(unsigned Offset, unsigned Length, tok::TokenKind Kind,
0042         unsigned short Flags)
0043       : Offset(Offset), Length(Length), Kind(Kind), Flags(Flags) {}
0044 
0045   unsigned getEnd() const { return Offset + Length; }
0046 
0047   bool is(tok::TokenKind K) const { return Kind == K; }
0048   bool isNot(tok::TokenKind K) const { return Kind != K; }
0049   bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
0050     return is(K1) || is(K2);
0051   }
0052   template <typename... Ts> bool isOneOf(tok::TokenKind K1, Ts... Ks) const {
0053     return is(K1) || isOneOf(Ks...);
0054   }
0055 };
0056 
0057 /// Represents the kind of preprocessor directive or a module declaration that
0058 /// is tracked by the scanner in its token output.
0059 enum DirectiveKind : uint8_t {
0060   pp_none,
0061   pp_include,
0062   pp___include_macros,
0063   pp_define,
0064   pp_undef,
0065   pp_import,
0066   pp_pragma_import,
0067   pp_pragma_once,
0068   pp_pragma_push_macro,
0069   pp_pragma_pop_macro,
0070   pp_pragma_include_alias,
0071   pp_pragma_system_header,
0072   pp_include_next,
0073   pp_if,
0074   pp_ifdef,
0075   pp_ifndef,
0076   pp_elif,
0077   pp_elifdef,
0078   pp_elifndef,
0079   pp_else,
0080   pp_endif,
0081   decl_at_import,
0082   cxx_module_decl,
0083   cxx_import_decl,
0084   cxx_export_module_decl,
0085   cxx_export_import_decl,
0086   /// Indicates that there are tokens present between the last scanned directive
0087   /// and eof. The \p Directive::Tokens array will be empty for this kind.
0088   tokens_present_before_eof,
0089   pp_eof,
0090 };
0091 
0092 /// Represents a directive that's lexed as part of the dependency directives
0093 /// scanning. It's used to track various preprocessor directives that could
0094 /// potentially have an effect on the dependencies.
0095 struct Directive {
0096   ArrayRef<Token> Tokens;
0097 
0098   /// The kind of token.
0099   DirectiveKind Kind = pp_none;
0100 
0101   Directive() = default;
0102   Directive(DirectiveKind K, ArrayRef<Token> Tokens)
0103       : Tokens(Tokens), Kind(K) {}
0104 };
0105 
0106 } // end namespace dependency_directives_scan
0107 
0108 /// Scan the input for the preprocessor directives that might have
0109 /// an effect on the dependencies for a compilation unit.
0110 ///
0111 /// This function ignores all non-preprocessor code and anything that
0112 /// can't affect what gets included.
0113 ///
0114 /// \returns false on success, true on error. If the diagnostic engine is not
0115 /// null, an appropriate error is reported using the given input location
0116 /// with the offset that corresponds to the \p Input buffer offset.
0117 bool scanSourceForDependencyDirectives(
0118     StringRef Input, SmallVectorImpl<dependency_directives_scan::Token> &Tokens,
0119     SmallVectorImpl<dependency_directives_scan::Directive> &Directives,
0120     DiagnosticsEngine *Diags = nullptr,
0121     SourceLocation InputSourceLoc = SourceLocation());
0122 
0123 /// Print the previously scanned dependency directives as minimized source text.
0124 ///
0125 /// \param Source The original source text that the dependency directives were
0126 /// scanned from.
0127 /// \param Directives The previously scanned dependency
0128 /// directives.
0129 /// \param OS the stream to print the dependency directives on.
0130 ///
0131 /// This is used primarily for testing purposes, during dependency scanning the
0132 /// \p Lexer uses the tokens directly, not their printed version.
0133 void printDependencyDirectivesAsSource(
0134     StringRef Source,
0135     ArrayRef<dependency_directives_scan::Directive> Directives,
0136     llvm::raw_ostream &OS);
0137 
0138 } // end namespace clang
0139 
0140 #endif // LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H