brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 8c7e175 Raw
94 lines · cpp
1//===- CIndexInclusionStack.cpp - Clang-C Source Indexing Library ---------===//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// This file defines a callback mechanism for clients to get the inclusion10// stack from a translation unit.11//12//===----------------------------------------------------------------------===//13 14#include "CIndexer.h"15#include "CXFile.h"16#include "CXSourceLocation.h"17#include "CXTranslationUnit.h"18#include "clang/AST/DeclVisitor.h"19#include "clang/Frontend/ASTUnit.h"20using namespace clang;21 22namespace {23void getInclusions(bool IsLocal, unsigned n, CXTranslationUnit TU,24                   CXInclusionVisitor CB, CXClientData clientData) {25  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);26  SourceManager &SM = CXXUnit->getSourceManager();27  ASTContext &Ctx = CXXUnit->getASTContext();28  SmallVector<CXSourceLocation, 10> InclusionStack;29  const bool HasPreamble = SM.getPreambleFileID().isValid();30 31  for (unsigned i = 0 ; i < n ; ++i) {32    bool Invalid = false;33    const SrcMgr::SLocEntry &SL =34        IsLocal ? SM.getLocalSLocEntry(i) : SM.getLoadedSLocEntry(i, &Invalid);35    if (!SL.isFile() || Invalid)36      continue;37 38    const SrcMgr::FileInfo &FI = SL.getFile();39    if (!FI.getContentCache().OrigEntry)40      continue;41 42    // If this is the main file, and there is a preamble, skip this SLoc. The43    // inclusions of the preamble already showed it.44    SourceLocation L = FI.getIncludeLoc();45    if (HasPreamble && CXXUnit->isInMainFileID(L))46      continue;47 48    // Build the inclusion stack.49    InclusionStack.clear();50    while (L.isValid()) {51      PresumedLoc PLoc = SM.getPresumedLoc(L);52      InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L));53      L = PLoc.isValid()? PLoc.getIncludeLoc() : SourceLocation();54    }55 56    // If there is a preamble, the last entry is the "inclusion" of that57    // preamble into the main file, which has the bogus entry of main.c:1:158    if (HasPreamble && !InclusionStack.empty())59      InclusionStack.pop_back();60 61    // Callback to the client.62    CB(cxfile::makeCXFile(*FI.getContentCache().OrigEntry),63       InclusionStack.data(), InclusionStack.size(), clientData);64  }65}66} // namespace67 68void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,69                         CXClientData clientData) {70  if (cxtu::isNotUsableTU(TU)) {71    LOG_BAD_TU(TU);72    return;73  }74 75  SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();76  const unsigned n =  SM.local_sloc_entry_size();77 78  // In the case where all the SLocEntries are in an external source, traverse79  // those SLocEntries as well.  This is the case where we are looking80  // at the inclusion stack of an AST/PCH file. Also, if we are not looking at81  // a AST/PCH file, but this file has a pre-compiled preamble, we also need82  // to look in that file.83  if (n == 1 || SM.getPreambleFileID().isValid()) {84    getInclusions(/*IsLocal=*/false, SM.loaded_sloc_entry_size(), TU, CB,85                  clientData);86  }87 88  // Not a PCH/AST file. Note, if there is a preamble, it could still be that89  // there are #includes in this file (e.g. for any include after the first90  // declaration).91  if (n != 1)92    getInclusions(/*IsLocal=*/true, n, TU, CB, clientData);93}94