Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:50

0001 //===- PlistSupport.h - Plist Output Utilities ------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_BASIC_PLISTSUPPORT_H
0010 #define LLVM_CLANG_BASIC_PLISTSUPPORT_H
0011 
0012 #include "clang/Basic/LLVM.h"
0013 #include "clang/Basic/SourceLocation.h"
0014 #include "clang/Basic/SourceManager.h"
0015 #include "llvm/ADT/DenseMap.h"
0016 #include "llvm/ADT/SmallVector.h"
0017 #include "llvm/ADT/StringRef.h"
0018 #include "llvm/Support/raw_ostream.h"
0019 #include <cassert>
0020 #include <cstdint>
0021 
0022 namespace clang {
0023 namespace markup {
0024 
0025 using FIDMap = llvm::DenseMap<FileID, unsigned>;
0026 
0027 inline unsigned AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
0028                    FileID FID) {
0029   auto [I, Inserted] = FIDs.try_emplace(FID, V.size());
0030   if (Inserted)
0031     V.push_back(FID);
0032   return I->second;
0033 }
0034 
0035 inline unsigned AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
0036                    const SourceManager &SM, SourceLocation L) {
0037   FileID FID = SM.getFileID(SM.getExpansionLoc(L));
0038   return AddFID(FIDs, V, FID);
0039 }
0040 
0041 inline unsigned GetFID(const FIDMap &FIDs, FileID FID) {
0042   FIDMap::const_iterator I = FIDs.find(FID);
0043   assert(I != FIDs.end());
0044   return I->second;
0045 }
0046 
0047 inline unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM,
0048                        SourceLocation L) {
0049   FileID FID = SM.getFileID(SM.getExpansionLoc(L));
0050   return GetFID(FIDs, FID);
0051 }
0052 
0053 inline raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
0054   for (unsigned i = 0; i < indent; ++i)
0055     o << ' ';
0056   return o;
0057 }
0058 
0059 inline raw_ostream &EmitPlistHeader(raw_ostream &o) {
0060   static const char *PlistHeader =
0061       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
0062       "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
0063       "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
0064       "<plist version=\"1.0\">\n";
0065   return o << PlistHeader;
0066 }
0067 
0068 inline raw_ostream &EmitInteger(raw_ostream &o, int64_t value) {
0069   o << "<integer>";
0070   o << value;
0071   o << "</integer>";
0072   return o;
0073 }
0074 
0075 inline raw_ostream &EmitString(raw_ostream &o, StringRef s) {
0076   o << "<string>";
0077   for (char c : s) {
0078     switch (c) {
0079     default:
0080       o << c;
0081       break;
0082     case '&':
0083       o << "&amp;";
0084       break;
0085     case '<':
0086       o << "&lt;";
0087       break;
0088     case '>':
0089       o << "&gt;";
0090       break;
0091     case '\'':
0092       o << "&apos;";
0093       break;
0094     case '\"':
0095       o << "&quot;";
0096       break;
0097     }
0098   }
0099   o << "</string>";
0100   return o;
0101 }
0102 
0103 inline void EmitLocation(raw_ostream &o, const SourceManager &SM,
0104                          SourceLocation L, const FIDMap &FM, unsigned indent) {
0105   if (L.isInvalid()) return;
0106 
0107   FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM));
0108 
0109   Indent(o, indent) << "<dict>\n";
0110   Indent(o, indent) << " <key>line</key>";
0111   EmitInteger(o, Loc.getExpansionLineNumber()) << '\n';
0112   Indent(o, indent) << " <key>col</key>";
0113   EmitInteger(o, Loc.getExpansionColumnNumber()) << '\n';
0114   Indent(o, indent) << " <key>file</key>";
0115   EmitInteger(o, GetFID(FM, SM, Loc)) << '\n';
0116   Indent(o, indent) << "</dict>\n";
0117 }
0118 
0119 inline void EmitRange(raw_ostream &o, const SourceManager &SM,
0120                       CharSourceRange R, const FIDMap &FM, unsigned indent) {
0121   if (R.isInvalid()) return;
0122 
0123   assert(R.isCharRange() && "cannot handle a token range");
0124   Indent(o, indent) << "<array>\n";
0125   EmitLocation(o, SM, R.getBegin(), FM, indent + 1);
0126 
0127   // The ".getLocWithOffset(-1)" emulates the behavior of an off-by-one bug
0128   // in Lexer that is already fixed. It is here for backwards compatibility
0129   // even though it is incorrect.
0130   EmitLocation(o, SM, R.getEnd().getLocWithOffset(-1), FM, indent + 1);
0131   Indent(o, indent) << "</array>\n";
0132 }
0133 
0134 } // namespace markup
0135 } // namespace clang
0136 
0137 #endif // LLVM_CLANG_BASIC_PLISTSUPPORT_H