| 1 | //===- JSONFormatImpl.h -----------------------------------------*- C++ -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // Internal implementation header shared by all translation units in the |
| 10 | // JSONFormat subdirectory. Not part of the public API. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef LLVM_CLANG_LIB_ScalableStaticAnalysis_CORE_SERIALIZATION_JSONFORMAT_JSONFORMATIMPL_H |
| 15 | #define LLVM_CLANG_LIB_ScalableStaticAnalysis_CORE_SERIALIZATION_JSONFORMAT_JSONFORMATIMPL_H |
| 16 | |
| 17 | #include "../../ModelStringConversions.h" |
| 18 | #include "JSONEntitySummaryEncoding.h" |
| 19 | #include "clang/ScalableStaticAnalysis/Core/EntityLinker/EntitySummaryEncoding.h" |
| 20 | #include "clang/ScalableStaticAnalysis/Core/Model/EntityLinkage.h" |
| 21 | #include "clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h" |
| 22 | #include "clang/ScalableStaticAnalysis/Core/Support/ErrorBuilder.h" |
| 23 | #include "clang/ScalableStaticAnalysis/Core/Support/FormatProviders.h" |
| 24 | #include "clang/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisName.h" |
| 25 | #include "llvm/ADT/STLExtras.h" |
| 26 | #include "llvm/ADT/StringExtras.h" |
| 27 | #include "llvm/Support/ErrorHandling.h" |
| 28 | #include "llvm/Support/FileSystem.h" |
| 29 | #include "llvm/Support/FormatVariadic.h" |
| 30 | #include "llvm/Support/JSON.h" |
| 31 | #include "llvm/Support/MemoryBuffer.h" |
| 32 | #include "llvm/Support/Path.h" |
| 33 | #include "llvm/Support/Registry.h" |
| 34 | |
| 35 | namespace clang::ssaf { |
| 36 | |
| 37 | using Array = llvm::json::Array; |
| 38 | using Object = llvm::json::Object; |
| 39 | using Value = llvm::json::Value; |
| 40 | |
| 41 | //---------------------------------------------------------------------------- |
| 42 | // File Format Constant |
| 43 | //---------------------------------------------------------------------------- |
| 44 | |
| 45 | inline constexpr const char *JSONFormatFileExtension = ".json" ; |
| 46 | |
| 47 | //---------------------------------------------------------------------------- |
| 48 | // Error Message Constants |
| 49 | //---------------------------------------------------------------------------- |
| 50 | |
| 51 | namespace ErrorMessages { |
| 52 | |
| 53 | inline constexpr const char *FailedToReadFile = |
| 54 | "failed to read file '{0}': {1}" ; |
| 55 | inline constexpr const char *FailedToWriteFile = |
| 56 | "failed to write file '{0}': {1}" ; |
| 57 | inline constexpr const char *FileNotFound = "file does not exist" ; |
| 58 | inline constexpr const char *FileIsDirectory = |
| 59 | "path is a directory, not a file" ; |
| 60 | inline constexpr const char *FileIsNotJSON = |
| 61 | "file does not end with '{0}' extension" ; |
| 62 | inline constexpr const char *FileExists = "file already exists" ; |
| 63 | inline constexpr const char *ParentDirectoryNotFound = |
| 64 | "parent directory does not exist" ; |
| 65 | |
| 66 | inline constexpr const char *ReadingFromField = "reading {0} from field '{1}'" ; |
| 67 | inline constexpr const char *WritingToField = "writing {0} to field '{1}'" ; |
| 68 | inline constexpr const char *ReadingFromIndex = "reading {0} from index '{1}'" ; |
| 69 | inline constexpr const char *WritingToIndex = "writing {0} to index '{1}'" ; |
| 70 | inline constexpr const char *ReadingFromFile = "reading {0} from file '{1}'" ; |
| 71 | inline constexpr const char *WritingToFile = "writing {0} to file '{1}'" ; |
| 72 | |
| 73 | inline constexpr const char *FailedInsertionOnDuplication = |
| 74 | "failed to insert {0} at index '{1}': encountered duplicate '{2}'" ; |
| 75 | |
| 76 | inline constexpr const char *FailedToReadObject = |
| 77 | "failed to read {0}: expected JSON {1}" ; |
| 78 | inline constexpr const char *FailedToReadObjectAtField = |
| 79 | "failed to read {0} from field '{1}': expected JSON {2}" ; |
| 80 | inline constexpr const char *FailedToReadObjectAtIndex = |
| 81 | "failed to read {0} from index '{1}': expected JSON {2}" ; |
| 82 | |
| 83 | inline constexpr const char *MismatchedSummaryType = |
| 84 | "expected '{0}' for field '{1}' but got '{2}'" ; |
| 85 | inline constexpr const char *UnknownArtifactType = |
| 86 | "unknown value '{0}' for field '{1}': expected '{2}', '{3}', or '{4}'" ; |
| 87 | inline constexpr const char *UnknownArtifactEncodingType = |
| 88 | "unknown value '{0}' for field '{1}': expected '{2}', or '{3}'" ; |
| 89 | |
| 90 | inline constexpr const char *FailedToDeserializeEntitySummaryNoFormatInfo = |
| 91 | "failed to deserialize EntitySummary: no FormatInfo registered for '{0}'" ; |
| 92 | inline constexpr const char *FailedToSerializeEntitySummaryNoFormatInfo = |
| 93 | "failed to serialize EntitySummary: no FormatInfo registered for '{0}'" ; |
| 94 | |
| 95 | inline constexpr const char *FailedToDeserializeEntitySummaryMissingData = |
| 96 | "failed to deserialize EntitySummary: null EntitySummary data for '{0}'" ; |
| 97 | inline constexpr const char *FailedToSerializeEntitySummaryMissingData = |
| 98 | "JSONFormat - null EntitySummary data for '{0}'" ; |
| 99 | |
| 100 | inline constexpr const char |
| 101 | *FailedToDeserializeEntitySummaryMismatchedSummaryName = |
| 102 | "failed to deserialize EntitySummary: EntitySummary data for '{0}' " |
| 103 | "reports mismatched '{1}'" ; |
| 104 | inline constexpr const char |
| 105 | *FailedToSerializeEntitySummaryMismatchedSummaryName = |
| 106 | "JSONFormat - EntitySummary data for '{0}' reports mismatched '{1}'" ; |
| 107 | |
| 108 | inline constexpr const char *InvalidBuildNamespaceKind = |
| 109 | "invalid BuildNamespaceKind value '{0}' for field 'kind'" ; |
| 110 | |
| 111 | inline constexpr const char *InvalidEntityLinkageType = |
| 112 | "invalid EntityLinkageType value '{0}' for field 'type'" ; |
| 113 | |
| 114 | inline constexpr const char * = |
| 115 | "failed to deserialize LinkageTable: extra '{0}' not present in IdTable" ; |
| 116 | |
| 117 | inline constexpr const char *FailedToDeserializeLinkageTableMissingId = |
| 118 | "failed to deserialize LinkageTable: missing '{0}' present in IdTable" ; |
| 119 | |
| 120 | inline constexpr const char *FailedToReadEntityIdObject = |
| 121 | "failed to read EntityId: expected JSON object with a single '{0}' key " |
| 122 | "mapped to a number (unsigned 64-bit integer)" ; |
| 123 | |
| 124 | inline constexpr const char *FailedToPatchEntityIdNotInTable = |
| 125 | "failed to patch EntityId: '{0}' not found in entity resolution table" ; |
| 126 | |
| 127 | inline constexpr const char *TargetTripleNotNormalized = |
| 128 | "target triple '{0}' is not in normalized form (expected '{1}')" ; |
| 129 | |
| 130 | } // namespace ErrorMessages |
| 131 | |
| 132 | //---------------------------------------------------------------------------- |
| 133 | // Entity Id JSON Representation |
| 134 | //---------------------------------------------------------------------------- |
| 135 | |
| 136 | /// An entity ID is encoded as the single-key object {"@": <index>}. |
| 137 | inline constexpr const char *JSONEntityIdKey = "@" ; |
| 138 | |
| 139 | //---------------------------------------------------------------------------- |
| 140 | // Summary Type JSON Representation |
| 141 | //---------------------------------------------------------------------------- |
| 142 | |
| 143 | /// Root-object key naming the summary kind so files are self-describing. |
| 144 | inline constexpr const char *JSONTypeKey = "type" ; |
| 145 | |
| 146 | /// Value written to \c JSONTypeKey for serialized \c TUSummary files. |
| 147 | inline constexpr const char *JSONTypeValueTUSummary = "TUSummary" ; |
| 148 | |
| 149 | /// Value written to \c JSONTypeKey for serialized \c LUSummary files. |
| 150 | inline constexpr const char *JSONTypeValueLUSummary = "LUSummary" ; |
| 151 | |
| 152 | /// Value written to \c JSONTypeKey for serialized \c WPASuite files. |
| 153 | inline constexpr const char *JSONTypeValueWPASuite = "WPASuite" ; |
| 154 | |
| 155 | /// Reads the \c JSONTypeKey field from the root object and verifies it |
| 156 | /// equals \p ExpectedType. Returns success or an error with the field |
| 157 | /// missing/mismatch detail. |
| 158 | llvm::Error checkSummaryType(const Object &RootObject, |
| 159 | llvm::StringRef ExpectedType); |
| 160 | |
| 161 | /// Reads the \c JSONTypeKey field from the root object as a string. |
| 162 | /// Returns the string on success; on error, the message is suitable for |
| 163 | /// callers that want to report the missing field themselves. |
| 164 | llvm::Expected<llvm::StringRef> readSummaryType(const Object &RootObject); |
| 165 | |
| 166 | //---------------------------------------------------------------------------- |
| 167 | // JSON Reader and Writer |
| 168 | //---------------------------------------------------------------------------- |
| 169 | |
| 170 | llvm::Expected<Value> readJSON(llvm::StringRef Path); |
| 171 | llvm::Error writeJSON(Value &&V, llvm::StringRef Path); |
| 172 | |
| 173 | //---------------------------------------------------------------------------- |
| 174 | // SummaryName helpers (free functions, anonymous-namespace in .cpp) |
| 175 | //---------------------------------------------------------------------------- |
| 176 | |
| 177 | SummaryName summaryNameFromJSON(llvm::StringRef SummaryNameStr); |
| 178 | llvm::StringRef summaryNameToJSON(const SummaryName &SN); |
| 179 | |
| 180 | //---------------------------------------------------------------------------- |
| 181 | // AnalysisName helpers |
| 182 | //---------------------------------------------------------------------------- |
| 183 | |
| 184 | AnalysisName analysisNameFromJSON(llvm::StringRef AnalysisNameStr); |
| 185 | llvm::StringRef analysisNameToJSON(const AnalysisName &AN); |
| 186 | |
| 187 | //---------------------------------------------------------------------------- |
| 188 | // BuildNamespaceKind helpers |
| 189 | //---------------------------------------------------------------------------- |
| 190 | |
| 191 | llvm::Expected<BuildNamespaceKind> |
| 192 | buildNamespaceKindFromJSON(llvm::StringRef BuildNamespaceKindStr); |
| 193 | |
| 194 | // Provided for consistency with respect to rest of the codebase. |
| 195 | llvm::StringRef buildNamespaceKindToJSON(BuildNamespaceKind BNK); |
| 196 | |
| 197 | //---------------------------------------------------------------------------- |
| 198 | // EntityLinkageType helpers |
| 199 | //---------------------------------------------------------------------------- |
| 200 | |
| 201 | llvm::Expected<EntityLinkageType> |
| 202 | entityLinkageTypeFromJSON(llvm::StringRef EntityLinkageTypeStr); |
| 203 | |
| 204 | // Provided for consistency with respect to rest of the codebase. |
| 205 | llvm::StringRef entityLinkageTypeToJSON(EntityLinkageType LT); |
| 206 | |
| 207 | //---------------------------------------------------------------------------- |
| 208 | // TargetTriple helpers |
| 209 | //---------------------------------------------------------------------------- |
| 210 | |
| 211 | /// Validates that \p Triple is a target triple string in normalized form. |
| 212 | /// Returns success if \p Triple equals \c llvm::Triple::normalize(Triple), |
| 213 | /// otherwise returns an \c invalid_argument error describing the expected |
| 214 | /// normalized form. |
| 215 | llvm::Error validateNormalizedTargetTriple(llvm::StringRef Triple); |
| 216 | |
| 217 | } // namespace clang::ssaf |
| 218 | |
| 219 | #endif // LLVM_CLANG_LIB_ScalableStaticAnalysis_CORE_SERIALIZATION_JSONFORMAT_JSONFORMATIMPL_H |
| 220 | |