brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 1e7d765 Raw
155 lines · cpp
1//===--- CollectMacros.cpp ---------------------------------------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "CollectMacros.h"10#include "AST.h"11#include "Protocol.h"12#include "SourceCode.h"13#include "clang/Basic/SourceLocation.h"14#include "clang/Tooling/Syntax/Tokens.h"15#include "llvm/ADT/STLExtras.h"16#include <cstddef>17 18namespace clang {19namespace clangd {20 21CharSourceRange MacroOccurrence::toSourceRange(const SourceManager &SM) const {22  auto MainFile = SM.getMainFileID();23  return syntax::FileRange(MainFile, StartOffset, EndOffset).toCharRange(SM);24}25 26Range MacroOccurrence::toRange(const SourceManager &SM) const {27  return halfOpenToRange(SM, toSourceRange(SM));28}29 30void CollectMainFileMacros::add(const Token &MacroNameTok, const MacroInfo *MI,31                                bool IsDefinition, bool InIfCondition) {32  if (!InMainFile)33    return;34  auto Loc = MacroNameTok.getLocation();35  if (Loc.isInvalid() || Loc.isMacroID())36    return;37 38  assert(isInsideMainFile(Loc, SM));39  auto Name = MacroNameTok.getIdentifierInfo()->getName();40  Out.Names.insert(Name);41  size_t Start = SM.getFileOffset(Loc);42  size_t End = SM.getFileOffset(MacroNameTok.getEndLoc());43  if (auto SID = getSymbolID(Name, MI, SM))44    Out.MacroRefs[SID].push_back({Start, End, IsDefinition, InIfCondition});45  else46    Out.UnknownMacros.push_back({Start, End, IsDefinition, InIfCondition});47}48 49void CollectMainFileMacros::FileChanged(SourceLocation Loc, FileChangeReason,50                                        SrcMgr::CharacteristicKind, FileID) {51  InMainFile = isInsideMainFile(Loc, SM);52}53 54void CollectMainFileMacros::MacroExpands(const Token &MacroName,55                                         const MacroDefinition &MD,56                                         SourceRange Range,57                                         const MacroArgs *Args) {58  add(MacroName, MD.getMacroInfo());59}60 61void CollectMainFileMacros::MacroUndefined(const clang::Token &MacroName,62                                           const clang::MacroDefinition &MD,63                                           const clang::MacroDirective *Undef) {64  add(MacroName, MD.getMacroInfo());65}66 67void CollectMainFileMacros::Ifdef(SourceLocation Loc, const Token &MacroName,68                                  const MacroDefinition &MD) {69  add(MacroName, MD.getMacroInfo(), /*IsDefinition=*/false,70      /*InConditionalDirective=*/true);71}72 73void CollectMainFileMacros::Ifndef(SourceLocation Loc, const Token &MacroName,74                                   const MacroDefinition &MD) {75  add(MacroName, MD.getMacroInfo(), /*IsDefinition=*/false,76      /*InConditionalDirective=*/true);77}78 79void CollectMainFileMacros::Elifdef(SourceLocation Loc, const Token &MacroName,80                                    const MacroDefinition &MD) {81  add(MacroName, MD.getMacroInfo(), /*IsDefinition=*/false,82      /*InConditionalDirective=*/true);83}84 85void CollectMainFileMacros::Elifndef(SourceLocation Loc, const Token &MacroName,86                                     const MacroDefinition &MD) {87  add(MacroName, MD.getMacroInfo(), /*IsDefinition=*/false,88      /*InConditionalDirective=*/true);89}90 91void CollectMainFileMacros::Defined(const Token &MacroName,92                                    const MacroDefinition &MD,93                                    SourceRange Range) {94  add(MacroName, MD.getMacroInfo(), /*IsDefinition=*/false,95      /*InConditionalDirective=*/true);96}97 98void CollectMainFileMacros::SourceRangeSkipped(SourceRange R,99                                               SourceLocation EndifLoc) {100  if (!InMainFile)101    return;102  Position Begin = sourceLocToPosition(SM, R.getBegin());103  Position End = sourceLocToPosition(SM, R.getEnd());104  Out.SkippedRanges.push_back(Range{Begin, End});105}106 107class CollectPragmaMarks : public PPCallbacks {108public:109  explicit CollectPragmaMarks(const SourceManager &SM,110                              std::vector<clangd::PragmaMark> &Out)111      : SM(SM), Out(Out) {}112 113  void PragmaMark(SourceLocation Loc, StringRef Trivia) override {114    if (isInsideMainFile(Loc, SM)) {115      // FIXME: This range should just cover `XX` in `#pragma mark XX` and116      // `- XX` in `#pragma mark - XX`.117      Position Start = sourceLocToPosition(SM, Loc);118      Position End = {Start.line + 1, 0};119      Out.emplace_back(clangd::PragmaMark{{Start, End}, Trivia.str()});120    }121  }122 123private:124  const SourceManager &SM;125  std::vector<clangd::PragmaMark> &Out;126};127 128std::unique_ptr<PPCallbacks>129collectPragmaMarksCallback(const SourceManager &SM,130                           std::vector<PragmaMark> &Out) {131  return std::make_unique<CollectPragmaMarks>(SM, Out);132}133 134void CollectMainFileMacros::MacroDefined(const Token &MacroName,135                                         const MacroDirective *MD) {136 137  if (!InMainFile)138    return;139  const auto *MI = MD->getMacroInfo();140  add(MacroName, MD->getMacroInfo(), true);141  if (MI)142    for (const auto &Tok : MI->tokens()) {143      auto *II = Tok.getIdentifierInfo();144      // Could this token be a reference to a macro? (Not param to this macro).145      if (!II || !II->hadMacroDefinition() ||146          llvm::is_contained(MI->params(), II))147        continue;148      if (const MacroInfo *MI = PP.getMacroInfo(II))149        add(Tok, MI);150    }151}152 153} // namespace clangd154} // namespace clang155