//===--- HeaderIncludes.cpp - Insert/Delete #includes --*- C++ -*----------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "clang/Tooling/Inclusions/HeaderIncludes.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" #include <optional> namespace clang { namespace tooling { namespace { LangOptions createLangOpts() { … } // Returns the offset after skipping a sequence of tokens, matched by \p // GetOffsetAfterSequence, from the start of the code. // \p GetOffsetAfterSequence should be a function that matches a sequence of // tokens and returns an offset after the sequence. unsigned getOffsetAfterTokenSequence( StringRef FileName, StringRef Code, const IncludeStyle &Style, llvm::function_ref<unsigned(const SourceManager &, Lexer &, Token &)> GetOffsetAfterSequence) { … } // Check if a sequence of tokens is like "#<Name> <raw_identifier>". If it is, // \p Tok will be the token after this directive; otherwise, it can be any token // after the given \p Tok (including \p Tok). If \p RawIDName is provided, the // (second) raw_identifier name is checked. bool checkAndConsumeDirectiveWithName( Lexer &Lex, StringRef Name, Token &Tok, std::optional<StringRef> RawIDName = std::nullopt) { … } void skipComments(Lexer &Lex, Token &Tok) { … } // Returns the offset after header guard directives and any comments // before/after header guards (e.g. #ifndef/#define pair, #pragma once). If no // header guard is present in the code, this will return the offset after // skipping all comments from the start of the code. unsigned getOffsetAfterHeaderGuardsAndComments(StringRef FileName, StringRef Code, const IncludeStyle &Style) { … } // Check if a sequence of tokens is like // "#include ("header.h" | <header.h>)". // If it is, \p Tok will be the token after this directive; otherwise, it can be // any token after the given \p Tok (including \p Tok). bool checkAndConsumeInclusiveDirective(Lexer &Lex, Token &Tok) { … } // Returns the offset of the last #include directive after which a new // #include can be inserted. This ignores #include's after the #include block(s) // in the beginning of a file to avoid inserting headers into code sections // where new #include's should not be added by default. // These code sections include: // - raw string literals (containing #include). // - #if blocks. // - Special #include's among declarations (e.g. functions). // // If no #include after which a new #include can be inserted, this returns the // offset after skipping all comments from the start of the code. // Inserting after an #include is not allowed if it comes after code that is not // #include (e.g. pre-processing directive that is not #include, declarations). unsigned getMaxHeaderInsertionOffset(StringRef FileName, StringRef Code, const IncludeStyle &Style) { … } inline StringRef trimInclude(StringRef IncludeName) { … } const char IncludeRegexPattern[] = …; // The filename of Path excluding extension. // Used to match implementation with headers, this differs from sys::path::stem: // - in names with multiple dots (foo.cu.cc) it terminates at the *first* // - an empty stem is never returned: /foo/.bar.x => .bar // - we don't bother to handle . and .. specially StringRef matchingStem(llvm::StringRef Path) { … } } // anonymous namespace IncludeCategoryManager::IncludeCategoryManager(const IncludeStyle &Style, StringRef FileName) : … { … } int IncludeCategoryManager::getIncludePriority(StringRef IncludeName, bool CheckMainHeader) const { … } int IncludeCategoryManager::getSortIncludePriority(StringRef IncludeName, bool CheckMainHeader) const { … } bool IncludeCategoryManager::isMainHeader(StringRef IncludeName) const { … } const llvm::Regex HeaderIncludes::IncludeRegex(IncludeRegexPattern); HeaderIncludes::HeaderIncludes(StringRef FileName, StringRef Code, const IncludeStyle &Style) : … { … } // \p Offset: the start of the line following this include directive. void HeaderIncludes::addExistingInclude(Include IncludeToAdd, unsigned NextLineOffset) { … } std::optional<tooling::Replacement> HeaderIncludes::insert(llvm::StringRef IncludeName, bool IsAngled, IncludeDirective Directive) const { … } tooling::Replacements HeaderIncludes::remove(llvm::StringRef IncludeName, bool IsAngled) const { … } } // namespace tooling } // namespace clang