1f4a2713aSLionel Sambuc //===- CIndexInclusionStack.cpp - Clang-C Source Indexing Library ---------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file defines a callback mechanism for clients to get the inclusion
11f4a2713aSLionel Sambuc // stack from a translation unit.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc
15f4a2713aSLionel Sambuc #include "CIndexer.h"
16f4a2713aSLionel Sambuc #include "CXSourceLocation.h"
17f4a2713aSLionel Sambuc #include "CXTranslationUnit.h"
18f4a2713aSLionel Sambuc #include "clang/AST/DeclVisitor.h"
19f4a2713aSLionel Sambuc #include "clang/Frontend/ASTUnit.h"
20f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
21f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
22f4a2713aSLionel Sambuc using namespace clang;
23f4a2713aSLionel Sambuc
24f4a2713aSLionel Sambuc extern "C" {
clang_getInclusions(CXTranslationUnit TU,CXInclusionVisitor CB,CXClientData clientData)25f4a2713aSLionel Sambuc void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
26f4a2713aSLionel Sambuc CXClientData clientData) {
27*0a6a1f1dSLionel Sambuc if (cxtu::isNotUsableTU(TU)) {
28*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
29*0a6a1f1dSLionel Sambuc return;
30*0a6a1f1dSLionel Sambuc }
31f4a2713aSLionel Sambuc
32f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
33f4a2713aSLionel Sambuc SourceManager &SM = CXXUnit->getSourceManager();
34f4a2713aSLionel Sambuc ASTContext &Ctx = CXXUnit->getASTContext();
35f4a2713aSLionel Sambuc
36f4a2713aSLionel Sambuc SmallVector<CXSourceLocation, 10> InclusionStack;
37f4a2713aSLionel Sambuc unsigned n = SM.local_sloc_entry_size();
38f4a2713aSLionel Sambuc
39f4a2713aSLionel Sambuc // In the case where all the SLocEntries are in an external source, traverse
40f4a2713aSLionel Sambuc // those SLocEntries as well. This is the case where we are looking
41f4a2713aSLionel Sambuc // at the inclusion stack of an AST/PCH file.
42f4a2713aSLionel Sambuc const SrcMgr::SLocEntry &(SourceManager::*Getter)(unsigned, bool*) const;
43f4a2713aSLionel Sambuc if (n == 1) {
44f4a2713aSLionel Sambuc Getter = &SourceManager::getLoadedSLocEntry;
45f4a2713aSLionel Sambuc n = SM.loaded_sloc_entry_size();
46f4a2713aSLionel Sambuc } else
47f4a2713aSLionel Sambuc Getter = &SourceManager::getLocalSLocEntry;
48f4a2713aSLionel Sambuc
49f4a2713aSLionel Sambuc for (unsigned i = 0 ; i < n ; ++i) {
50f4a2713aSLionel Sambuc bool Invalid = false;
51f4a2713aSLionel Sambuc const SrcMgr::SLocEntry &SL = (SM.*Getter)(i, &Invalid);
52f4a2713aSLionel Sambuc
53f4a2713aSLionel Sambuc if (!SL.isFile() || Invalid)
54f4a2713aSLionel Sambuc continue;
55f4a2713aSLionel Sambuc
56f4a2713aSLionel Sambuc const SrcMgr::FileInfo &FI = SL.getFile();
57f4a2713aSLionel Sambuc if (!FI.getContentCache()->OrigEntry)
58f4a2713aSLionel Sambuc continue;
59f4a2713aSLionel Sambuc
60f4a2713aSLionel Sambuc // Build the inclusion stack.
61f4a2713aSLionel Sambuc SourceLocation L = FI.getIncludeLoc();
62f4a2713aSLionel Sambuc InclusionStack.clear();
63f4a2713aSLionel Sambuc while (L.isValid()) {
64f4a2713aSLionel Sambuc PresumedLoc PLoc = SM.getPresumedLoc(L);
65f4a2713aSLionel Sambuc InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L));
66f4a2713aSLionel Sambuc L = PLoc.isValid()? PLoc.getIncludeLoc() : SourceLocation();
67f4a2713aSLionel Sambuc }
68f4a2713aSLionel Sambuc
69f4a2713aSLionel Sambuc // Callback to the client.
70f4a2713aSLionel Sambuc // FIXME: We should have a function to construct CXFiles.
71f4a2713aSLionel Sambuc CB(static_cast<CXFile>(
72f4a2713aSLionel Sambuc const_cast<FileEntry *>(FI.getContentCache()->OrigEntry)),
73f4a2713aSLionel Sambuc InclusionStack.data(), InclusionStack.size(), clientData);
74f4a2713aSLionel Sambuc }
75f4a2713aSLionel Sambuc }
76f4a2713aSLionel Sambuc } // end extern C
77