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