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