//===---------- PlistSupport.h - Plist Output Utilities ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_PLISTSUPPORT_H #define LLVM_CLANG_PLISTSUPPORT_H #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "llvm/Support/raw_ostream.h" namespace clang { namespace markup { typedef llvm::DenseMap FIDMap; static const char *PlistHeader = "\n" "\n" "\n"; static void AddFID(FIDMap &FIDs, SmallVectorImpl &V, const SourceManager &SM, SourceLocation L) { FileID FID = SM.getFileID(SM.getExpansionLoc(L)); FIDMap::iterator I = FIDs.find(FID); if (I != FIDs.end()) return; FIDs[FID] = V.size(); V.push_back(FID); } static unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM, SourceLocation L) { FileID FID = SM.getFileID(SM.getExpansionLoc(L)); FIDMap::const_iterator I = FIDs.find(FID); assert(I != FIDs.end()); return I->second; } static raw_ostream &Indent(raw_ostream &o, const unsigned indent) { for (unsigned i = 0; i < indent; ++i) o << ' '; return o; } static void EmitLocation(raw_ostream &o, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation L, const FIDMap &FM, unsigned indent, bool extend = false) { FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast(SM)); // Add in the length of the token, so that we cover multi-char tokens. unsigned offset = extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0; Indent(o, indent) << "\n"; Indent(o, indent) << " line" << Loc.getExpansionLineNumber() << "\n"; Indent(o, indent) << " col" << Loc.getExpansionColumnNumber() + offset << "\n"; Indent(o, indent) << " file" << GetFID(FM, SM, Loc) << "\n"; Indent(o, indent) << "\n"; } static inline void EmitRange(raw_ostream &o, const SourceManager &SM, const LangOptions &LangOpts, CharSourceRange R, const FIDMap &FM, unsigned indent) { Indent(o, indent) << "\n"; EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent + 1); EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent + 1, R.isTokenRange()); Indent(o, indent) << "\n"; } static raw_ostream &EmitString(raw_ostream &o, StringRef s) { o << ""; for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) { char c = *I; switch (c) { default: o << c; break; case '&': o << "&"; break; case '<': o << "<"; break; case '>': o << ">"; break; case '\'': o << "'"; break; case '\"': o << """; break; } } o << ""; return o; } } } #endif