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 325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner 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