Haojian Wu | 7e3c74b | 2019-09-24 11:14:06 +0000 | [diff] [blame] | 1 | //===--- CollectMacros.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 | #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_COLLECTEDMACROS_H |
| 10 | #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COLLECTEDMACROS_H |
| 11 | |
Utkarsh Saxena | 2054ed0 | 2019-11-07 12:14:38 +0100 | [diff] [blame] | 12 | #include "AST.h" |
Haojian Wu | 7e3c74b | 2019-09-24 11:14:06 +0000 | [diff] [blame] | 13 | #include "Protocol.h" |
| 14 | #include "SourceCode.h" |
Utkarsh Saxena | 2054ed0 | 2019-11-07 12:14:38 +0100 | [diff] [blame] | 15 | #include "index/SymbolID.h" |
Haojian Wu | 7e3c74b | 2019-09-24 11:14:06 +0000 | [diff] [blame] | 16 | #include "clang/Basic/IdentifierTable.h" |
| 17 | #include "clang/Lex/PPCallbacks.h" |
Utkarsh Saxena | 2054ed0 | 2019-11-07 12:14:38 +0100 | [diff] [blame] | 18 | #include "llvm/ADT/DenseMap.h" |
Haojian Wu | 7e3c74b | 2019-09-24 11:14:06 +0000 | [diff] [blame] | 19 | #include <string> |
| 20 | |
| 21 | namespace clang { |
| 22 | namespace clangd { |
| 23 | |
| 24 | struct MainFileMacros { |
| 25 | llvm::StringSet<> Names; |
| 26 | // Instead of storing SourceLocation, we have to store the token range because |
| 27 | // SourceManager from preamble is not available when we build the AST. |
Utkarsh Saxena | 2054ed0 | 2019-11-07 12:14:38 +0100 | [diff] [blame] | 28 | llvm::DenseMap<SymbolID, std::vector<Range>> MacroRefs; |
| 29 | // Somtimes it is not possible to compute the SymbolID for the Macro, e.g. a |
| 30 | // reference to an undefined macro. Store them separately, e.g. for semantic |
| 31 | // highlighting. |
| 32 | std::vector<Range> UnknownMacros; |
Nathan Ridge | b2e6c2b | 2019-09-24 18:17:55 -0400 | [diff] [blame] | 33 | // Ranges skipped by the preprocessor due to being inactive. |
| 34 | std::vector<Range> SkippedRanges; |
Haojian Wu | 7e3c74b | 2019-09-24 11:14:06 +0000 | [diff] [blame] | 35 | }; |
| 36 | |
Haojian Wu | 2fa81d2 | 2019-10-07 10:10:31 +0000 | [diff] [blame] | 37 | /// Collects macro references (e.g. definitions, expansions) in the main file. |
| 38 | /// It is used to: |
Haojian Wu | 7e3c74b | 2019-09-24 11:14:06 +0000 | [diff] [blame] | 39 | /// - collect macros in the preamble section of the main file (in Preamble.cpp) |
| 40 | /// - collect macros after the preamble of the main file (in ParsedAST.cpp) |
| 41 | class CollectMainFileMacros : public PPCallbacks { |
| 42 | public: |
Kadir Cetinkaya | 3755039 | 2020-03-01 16:05:12 +0100 | [diff] [blame] | 43 | explicit CollectMainFileMacros(const SourceManager &SM, MainFileMacros &Out) |
| 44 | : SM(SM), Out(Out) {} |
Haojian Wu | 7e3c74b | 2019-09-24 11:14:06 +0000 | [diff] [blame] | 45 | |
| 46 | void FileChanged(SourceLocation Loc, FileChangeReason, |
| 47 | SrcMgr::CharacteristicKind, FileID) override { |
| 48 | InMainFile = isInsideMainFile(Loc, SM); |
| 49 | } |
| 50 | |
| 51 | void MacroDefined(const Token &MacroName, const MacroDirective *MD) override { |
| 52 | add(MacroName, MD->getMacroInfo()); |
| 53 | } |
| 54 | |
| 55 | void MacroExpands(const Token &MacroName, const MacroDefinition &MD, |
| 56 | SourceRange Range, const MacroArgs *Args) override { |
| 57 | add(MacroName, MD.getMacroInfo()); |
| 58 | } |
| 59 | |
Haojian Wu | 2fa81d2 | 2019-10-07 10:10:31 +0000 | [diff] [blame] | 60 | void MacroUndefined(const clang::Token &MacroName, |
| 61 | const clang::MacroDefinition &MD, |
| 62 | const clang::MacroDirective *Undef) override { |
| 63 | add(MacroName, MD.getMacroInfo()); |
| 64 | } |
| 65 | |
| 66 | void Ifdef(SourceLocation Loc, const Token &MacroName, |
| 67 | const MacroDefinition &MD) override { |
| 68 | add(MacroName, MD.getMacroInfo()); |
| 69 | } |
| 70 | |
| 71 | void Ifndef(SourceLocation Loc, const Token &MacroName, |
| 72 | const MacroDefinition &MD) override { |
| 73 | add(MacroName, MD.getMacroInfo()); |
| 74 | } |
| 75 | |
| 76 | void Defined(const Token &MacroName, const MacroDefinition &MD, |
| 77 | SourceRange Range) override { |
| 78 | add(MacroName, MD.getMacroInfo()); |
| 79 | } |
| 80 | |
Nathan Ridge | b2e6c2b | 2019-09-24 18:17:55 -0400 | [diff] [blame] | 81 | void SourceRangeSkipped(SourceRange R, SourceLocation EndifLoc) override { |
| 82 | if (!InMainFile) |
| 83 | return; |
| 84 | Position Begin = sourceLocToPosition(SM, R.getBegin()); |
| 85 | Position End = sourceLocToPosition(SM, R.getEnd()); |
| 86 | Out.SkippedRanges.push_back(Range{Begin, End}); |
| 87 | } |
| 88 | |
Haojian Wu | 7e3c74b | 2019-09-24 11:14:06 +0000 | [diff] [blame] | 89 | private: |
Kadir Cetinkaya | 3755039 | 2020-03-01 16:05:12 +0100 | [diff] [blame] | 90 | void add(const Token &MacroNameTok, const MacroInfo *MI); |
Haojian Wu | 7e3c74b | 2019-09-24 11:14:06 +0000 | [diff] [blame] | 91 | const SourceManager &SM; |
Haojian Wu | 7e3c74b | 2019-09-24 11:14:06 +0000 | [diff] [blame] | 92 | bool InMainFile = true; |
| 93 | MainFileMacros &Out; |
| 94 | }; |
| 95 | |
| 96 | } // namespace clangd |
| 97 | } // namespace clang |
| 98 | |
| 99 | #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_COLLECTEDMACROS_H |