1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===---------- PlistSupport.h - Plist Output Utilities ---------*- C++ -*-===// 2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// The LLVM Compiler Infrastructure 4651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 5651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// This file is distributed under the University of Illinois Open Source 6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// License. See LICENSE.TXT for details. 7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// 8651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===// 9651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 10651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#ifndef LLVM_CLANG_PLISTSUPPORT_H 11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#define LLVM_CLANG_PLISTSUPPORT_H 12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Basic/FileManager.h" 14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Basic/SourceManager.h" 15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Lex/Lexer.h" 16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/raw_ostream.h" 17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace clang { 19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace markup { 20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef llvm::DenseMap<FileID, unsigned> FIDMap; 21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 22ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesinline void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V, 23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const SourceManager &SM, SourceLocation L) { 24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FileID FID = SM.getFileID(SM.getExpansionLoc(L)); 25651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FIDMap::iterator I = FIDs.find(FID); 26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I != FIDs.end()) 27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FIDs[FID] = V.size(); 29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines V.push_back(FID); 30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 32ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesinline unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM, 33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation L) { 34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FileID FID = SM.getFileID(SM.getExpansionLoc(L)); 35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FIDMap::const_iterator I = FIDs.find(FID); 36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(I != FIDs.end()); 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return I->second; 38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 40ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesinline raw_ostream &Indent(raw_ostream &o, const unsigned indent) { 41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (unsigned i = 0; i < indent; ++i) 42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines o << ' '; 43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return o; 44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 46ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesinline raw_ostream &EmitPlistHeader(raw_ostream &o) { 47ef8225444452a1486bd721f3285301fe84643b00Stephen Hines static const char *PlistHeader = 48ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 49ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" " 50ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" 51ef8225444452a1486bd721f3285301fe84643b00Stephen Hines "<plist version=\"1.0\">\n"; 52ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return o << PlistHeader; 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 55ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesinline raw_ostream &EmitInteger(raw_ostream &o, int64_t value) { 56ef8225444452a1486bd721f3285301fe84643b00Stephen Hines o << "<integer>"; 57ef8225444452a1486bd721f3285301fe84643b00Stephen Hines o << value; 58ef8225444452a1486bd721f3285301fe84643b00Stephen Hines o << "</integer>"; 59ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return o; 60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 62ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesinline raw_ostream &EmitString(raw_ostream &o, StringRef s) { 63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines o << "<string>"; 64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) { 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines char c = *I; 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines switch (c) { 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines default: 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines o << c; 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case '&': 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines o << "&"; 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case '<': 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines o << "<"; 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case '>': 77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines o << ">"; 78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case '\'': 80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines o << "'"; 81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case '\"': 83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines o << """; 84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines o << "</string>"; 88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return o; 89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 90ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 91ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesinline void EmitLocation(raw_ostream &o, const SourceManager &SM, 92ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const LangOptions &LangOpts, SourceLocation L, 93ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const FIDMap &FM, unsigned indent, 94ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool extend = false) { 95ef8225444452a1486bd721f3285301fe84643b00Stephen Hines FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM)); 96ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 97ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Add in the length of the token, so that we cover multi-char tokens. 98ef8225444452a1486bd721f3285301fe84643b00Stephen Hines unsigned offset = 99ef8225444452a1486bd721f3285301fe84643b00Stephen Hines extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0; 100ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 101ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Indent(o, indent) << "<dict>\n"; 102ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Indent(o, indent) << " <key>line</key>"; 103ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EmitInteger(o, Loc.getExpansionLineNumber()) << '\n'; 104ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Indent(o, indent) << " <key>col</key>"; 105ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EmitInteger(o, Loc.getExpansionColumnNumber() + offset) << '\n'; 106ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Indent(o, indent) << " <key>file</key>"; 107ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EmitInteger(o, GetFID(FM, SM, Loc)) << '\n'; 108ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Indent(o, indent) << "</dict>\n"; 109ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 110ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 111ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesinline void EmitRange(raw_ostream &o, const SourceManager &SM, 112ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const LangOptions &LangOpts, CharSourceRange R, 113ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const FIDMap &FM, unsigned indent) { 114ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Indent(o, indent) << "<array>\n"; 115ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent + 1); 116ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent + 1, R.isTokenRange()); 117ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Indent(o, indent) << "</array>\n"; 118ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 123