CIndexInclusionStack.cpp revision f62d43d2afe1960755a1b5813cae1e5983bcac1b
116b55a71695a33c094383295cc7b7a2080e098daTed Kremenek//===- CIndexInclusionStack.cpp - Clang-C Source Indexing Library ---------===//
216b55a71695a33c094383295cc7b7a2080e098daTed Kremenek//
316b55a71695a33c094383295cc7b7a2080e098daTed Kremenek//                     The LLVM Compiler Infrastructure
416b55a71695a33c094383295cc7b7a2080e098daTed Kremenek//
516b55a71695a33c094383295cc7b7a2080e098daTed Kremenek// This file is distributed under the University of Illinois Open Source
616b55a71695a33c094383295cc7b7a2080e098daTed Kremenek// License. See LICENSE.TXT for details.
716b55a71695a33c094383295cc7b7a2080e098daTed Kremenek//
816b55a71695a33c094383295cc7b7a2080e098daTed Kremenek//===----------------------------------------------------------------------===//
916b55a71695a33c094383295cc7b7a2080e098daTed Kremenek//
1016b55a71695a33c094383295cc7b7a2080e098daTed Kremenek// This file defines a callback mechanism for clients to get the inclusion
1116b55a71695a33c094383295cc7b7a2080e098daTed Kremenek// stack from a translation unit.
1216b55a71695a33c094383295cc7b7a2080e098daTed Kremenek//
1316b55a71695a33c094383295cc7b7a2080e098daTed Kremenek//===----------------------------------------------------------------------===//
1416b55a71695a33c094383295cc7b7a2080e098daTed Kremenek
1516b55a71695a33c094383295cc7b7a2080e098daTed Kremenek#include "CIndexer.h"
160a90d32523bfe5fa63e11b648686c9699f786d15Ted Kremenek#include "CXTranslationUnit.h"
1716b55a71695a33c094383295cc7b7a2080e098daTed Kremenek#include "CXSourceLocation.h"
1816b55a71695a33c094383295cc7b7a2080e098daTed Kremenek#include "clang/AST/DeclVisitor.h"
19b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/ASTUnit.h"
2016b55a71695a33c094383295cc7b7a2080e098daTed Kremenek#include "llvm/ADT/SmallString.h"
2116b55a71695a33c094383295cc7b7a2080e098daTed Kremenek#include "llvm/Support/raw_ostream.h"
22b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramerusing namespace clang;
2316b55a71695a33c094383295cc7b7a2080e098daTed Kremenek
2416b55a71695a33c094383295cc7b7a2080e098daTed Kremenekextern "C" {
2516b55a71695a33c094383295cc7b7a2080e098daTed Kremenekvoid clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
2616b55a71695a33c094383295cc7b7a2080e098daTed Kremenek                         CXClientData clientData) {
2716b55a71695a33c094383295cc7b7a2080e098daTed Kremenek
28a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
2916b55a71695a33c094383295cc7b7a2080e098daTed Kremenek  SourceManager &SM = CXXUnit->getSourceManager();
3016b55a71695a33c094383295cc7b7a2080e098daTed Kremenek  ASTContext &Ctx = CXXUnit->getASTContext();
3116b55a71695a33c094383295cc7b7a2080e098daTed Kremenek
3216b55a71695a33c094383295cc7b7a2080e098daTed Kremenek  llvm::SmallVector<CXSourceLocation, 10> InclusionStack;
33f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  unsigned n =  SM.local_sloc_entry_size();
3416b55a71695a33c094383295cc7b7a2080e098daTed Kremenek
3516b55a71695a33c094383295cc7b7a2080e098daTed Kremenek  // In the case where all the SLocEntries are in an external source, traverse
3616b55a71695a33c094383295cc7b7a2080e098daTed Kremenek  // those SLocEntries as well.  This is the case where we are looking
3716b55a71695a33c094383295cc7b7a2080e098daTed Kremenek  // at the inclusion stack of an AST/PCH file.
38f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  const SrcMgr::SLocEntry &(SourceManager::*Getter)(unsigned, bool*) const;
39f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  if (n == 1) {
40f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    Getter = &SourceManager::getLoadedSLocEntry;
41f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    n = SM.loaded_sloc_entry_size();
42f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  } else
43f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    Getter = &SourceManager::getLocalSLocEntry;
44f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor
45f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor  for (unsigned i = 0 ; i < n ; ++i) {
46e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor    bool Invalid = false;
47f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor    const SrcMgr::SLocEntry &SL = (SM.*Getter)(i, &Invalid);
4816b55a71695a33c094383295cc7b7a2080e098daTed Kremenek
49e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor    if (!SL.isFile() || Invalid)
5016b55a71695a33c094383295cc7b7a2080e098daTed Kremenek      continue;
5116b55a71695a33c094383295cc7b7a2080e098daTed Kremenek
5216b55a71695a33c094383295cc7b7a2080e098daTed Kremenek    const SrcMgr::FileInfo &FI = SL.getFile();
53b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    if (!FI.getContentCache()->OrigEntry)
5416b55a71695a33c094383295cc7b7a2080e098daTed Kremenek      continue;
5516b55a71695a33c094383295cc7b7a2080e098daTed Kremenek
5616b55a71695a33c094383295cc7b7a2080e098daTed Kremenek    // Build the inclusion stack.
5716b55a71695a33c094383295cc7b7a2080e098daTed Kremenek    SourceLocation L = FI.getIncludeLoc();
5816b55a71695a33c094383295cc7b7a2080e098daTed Kremenek    InclusionStack.clear();
5916b55a71695a33c094383295cc7b7a2080e098daTed Kremenek    while (L.isValid()) {
6016b55a71695a33c094383295cc7b7a2080e098daTed Kremenek      PresumedLoc PLoc = SM.getPresumedLoc(L);
6116b55a71695a33c094383295cc7b7a2080e098daTed Kremenek      InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L));
62cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      L = PLoc.isValid()? PLoc.getIncludeLoc() : SourceLocation();
6316b55a71695a33c094383295cc7b7a2080e098daTed Kremenek    }
6416b55a71695a33c094383295cc7b7a2080e098daTed Kremenek
6516b55a71695a33c094383295cc7b7a2080e098daTed Kremenek    // Callback to the client.
6616b55a71695a33c094383295cc7b7a2080e098daTed Kremenek    // FIXME: We should have a function to construct CXFiles.
67b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis    CB((CXFile) FI.getContentCache()->OrigEntry,
6816b55a71695a33c094383295cc7b7a2080e098daTed Kremenek       InclusionStack.data(), InclusionStack.size(), clientData);
6916b55a71695a33c094383295cc7b7a2080e098daTed Kremenek  }
7016b55a71695a33c094383295cc7b7a2080e098daTed Kremenek}
7116b55a71695a33c094383295cc7b7a2080e098daTed Kremenek} // end extern C
72