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" 1616b55a71695a33c094383295cc7b7a2080e098daTed Kremenek#include "CXSourceLocation.h" 17f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "CXTranslationUnit.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) { 27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (cxtu::isNotUsableTU(TU)) { 28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LOG_BAD_TU(TU); 29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 325694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 3316b55a71695a33c094383295cc7b7a2080e098daTed Kremenek SourceManager &SM = CXXUnit->getSourceManager(); 3416b55a71695a33c094383295cc7b7a2080e098daTed Kremenek ASTContext &Ctx = CXXUnit->getASTContext(); 3516b55a71695a33c094383295cc7b7a2080e098daTed Kremenek 365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXSourceLocation, 10> InclusionStack; 37f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor unsigned n = SM.local_sloc_entry_size(); 3816b55a71695a33c094383295cc7b7a2080e098daTed Kremenek 3916b55a71695a33c094383295cc7b7a2080e098daTed Kremenek // In the case where all the SLocEntries are in an external source, traverse 4016b55a71695a33c094383295cc7b7a2080e098daTed Kremenek // those SLocEntries as well. This is the case where we are looking 4116b55a71695a33c094383295cc7b7a2080e098daTed Kremenek // at the inclusion stack of an AST/PCH file. 42f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SrcMgr::SLocEntry &(SourceManager::*Getter)(unsigned, bool*) const; 43f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (n == 1) { 44f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Getter = &SourceManager::getLoadedSLocEntry; 45f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor n = SM.loaded_sloc_entry_size(); 46f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor } else 47f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor Getter = &SourceManager::getLocalSLocEntry; 48f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 49f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor for (unsigned i = 0 ; i < n ; ++i) { 50e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 51f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor const SrcMgr::SLocEntry &SL = (SM.*Getter)(i, &Invalid); 5216b55a71695a33c094383295cc7b7a2080e098daTed Kremenek 53e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!SL.isFile() || Invalid) 5416b55a71695a33c094383295cc7b7a2080e098daTed Kremenek continue; 5516b55a71695a33c094383295cc7b7a2080e098daTed Kremenek 5616b55a71695a33c094383295cc7b7a2080e098daTed Kremenek const SrcMgr::FileInfo &FI = SL.getFile(); 57b1c86492f9a9bef01a4567408c22f961bbd604feArgyrios Kyrtzidis if (!FI.getContentCache()->OrigEntry) 5816b55a71695a33c094383295cc7b7a2080e098daTed Kremenek continue; 5916b55a71695a33c094383295cc7b7a2080e098daTed Kremenek 6016b55a71695a33c094383295cc7b7a2080e098daTed Kremenek // Build the inclusion stack. 6116b55a71695a33c094383295cc7b7a2080e098daTed Kremenek SourceLocation L = FI.getIncludeLoc(); 6216b55a71695a33c094383295cc7b7a2080e098daTed Kremenek InclusionStack.clear(); 6316b55a71695a33c094383295cc7b7a2080e098daTed Kremenek while (L.isValid()) { 6416b55a71695a33c094383295cc7b7a2080e098daTed Kremenek PresumedLoc PLoc = SM.getPresumedLoc(L); 6516b55a71695a33c094383295cc7b7a2080e098daTed Kremenek InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L)); 66cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor L = PLoc.isValid()? PLoc.getIncludeLoc() : SourceLocation(); 6716b55a71695a33c094383295cc7b7a2080e098daTed Kremenek } 6816b55a71695a33c094383295cc7b7a2080e098daTed Kremenek 6916b55a71695a33c094383295cc7b7a2080e098daTed Kremenek // Callback to the client. 7016b55a71695a33c094383295cc7b7a2080e098daTed Kremenek // FIXME: We should have a function to construct CXFiles. 7161eacf0f4f912ef4834ff4ed5d7072b655fe91bfDavid Greene CB(static_cast<CXFile>( 7261eacf0f4f912ef4834ff4ed5d7072b655fe91bfDavid Greene const_cast<FileEntry *>(FI.getContentCache()->OrigEntry)), 7316b55a71695a33c094383295cc7b7a2080e098daTed Kremenek InclusionStack.data(), InclusionStack.size(), clientData); 7416b55a71695a33c094383295cc7b7a2080e098daTed Kremenek } 7516b55a71695a33c094383295cc7b7a2080e098daTed Kremenek} 7616b55a71695a33c094383295cc7b7a2080e098daTed Kremenek} // end extern C 77