1//===---------- PlistSupport.h - Plist Output Utilities ---------*- C++ -*-===// 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#ifndef LLVM_CLANG_BASIC_PLISTSUPPORT_H 11#define LLVM_CLANG_BASIC_PLISTSUPPORT_H 12 13#include "clang/Basic/FileManager.h" 14#include "clang/Basic/SourceManager.h" 15#include "llvm/Support/raw_ostream.h" 16 17namespace clang { 18namespace markup { 19typedef llvm::DenseMap<FileID, unsigned> FIDMap; 20 21inline void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V, 22 const SourceManager &SM, SourceLocation L) { 23 FileID FID = SM.getFileID(SM.getExpansionLoc(L)); 24 FIDMap::iterator I = FIDs.find(FID); 25 if (I != FIDs.end()) 26 return; 27 FIDs[FID] = V.size(); 28 V.push_back(FID); 29} 30 31inline unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM, 32 SourceLocation L) { 33 FileID FID = SM.getFileID(SM.getExpansionLoc(L)); 34 FIDMap::const_iterator I = FIDs.find(FID); 35 assert(I != FIDs.end()); 36 return I->second; 37} 38 39inline raw_ostream &Indent(raw_ostream &o, const unsigned indent) { 40 for (unsigned i = 0; i < indent; ++i) 41 o << ' '; 42 return o; 43} 44 45inline raw_ostream &EmitPlistHeader(raw_ostream &o) { 46 static const char *PlistHeader = 47 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 48 "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" " 49 "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" 50 "<plist version=\"1.0\">\n"; 51 return o << PlistHeader; 52} 53 54inline raw_ostream &EmitInteger(raw_ostream &o, int64_t value) { 55 o << "<integer>"; 56 o << value; 57 o << "</integer>"; 58 return o; 59} 60 61inline raw_ostream &EmitString(raw_ostream &o, StringRef s) { 62 o << "<string>"; 63 for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) { 64 char c = *I; 65 switch (c) { 66 default: 67 o << c; 68 break; 69 case '&': 70 o << "&"; 71 break; 72 case '<': 73 o << "<"; 74 break; 75 case '>': 76 o << ">"; 77 break; 78 case '\'': 79 o << "'"; 80 break; 81 case '\"': 82 o << """; 83 break; 84 } 85 } 86 o << "</string>"; 87 return o; 88} 89 90inline void EmitLocation(raw_ostream &o, const SourceManager &SM, 91 SourceLocation L, const FIDMap &FM, unsigned indent) { 92 if (L.isInvalid()) return; 93 94 FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM)); 95 96 Indent(o, indent) << "<dict>\n"; 97 Indent(o, indent) << " <key>line</key>"; 98 EmitInteger(o, Loc.getExpansionLineNumber()) << '\n'; 99 Indent(o, indent) << " <key>col</key>"; 100 EmitInteger(o, Loc.getExpansionColumnNumber()) << '\n'; 101 Indent(o, indent) << " <key>file</key>"; 102 EmitInteger(o, GetFID(FM, SM, Loc)) << '\n'; 103 Indent(o, indent) << "</dict>\n"; 104} 105 106inline void EmitRange(raw_ostream &o, const SourceManager &SM, 107 CharSourceRange R, const FIDMap &FM, unsigned indent) { 108 if (R.isInvalid()) return; 109 110 assert(R.isCharRange() && "cannot handle a token range"); 111 Indent(o, indent) << "<array>\n"; 112 EmitLocation(o, SM, R.getBegin(), FM, indent + 1); 113 EmitLocation(o, SM, R.getEnd(), FM, indent + 1); 114 Indent(o, indent) << "</array>\n"; 115} 116} 117} 118 119#endif 120