clang: lib/Lex/HeaderMap.cpp Source File (original) (raw)

68 return false;

69 const char *FileStart = File.getBufferStart();

70

71

73

74

75

78 NeedsByteSwap = false;

81 NeedsByteSwap = true;

82 else

83 return false;

84

86 return false;

87

88

89

90 uint32_t NumBuckets =

91 NeedsByteSwap ? llvm::byteswap(Header->NumBuckets) : Header->NumBuckets;

92 if (!llvm::isPowerOf2_32(NumBuckets))

93 return false;

94 if (File.getBufferSize() <

96 return false;

97

98

99 return true;

100}

101

102

103

104

105

106

107

109 return FileBuffer->getBufferIdentifier();

110}

111

112unsigned HeaderMapImpl::getEndianAdjustedWord(unsigned X) const {

113 if (!NeedsBSwap) return X;

114 return llvm::byteswap<uint32_t>(X);

115}

116

117

118

119const HMapHeader &HeaderMapImpl::getHeader() const {

120

121 return *reinterpret_cast<const HMapHeader*>(FileBuffer->getBufferStart());

122}

123

124

125

126

127HMapBucket HeaderMapImpl::getBucket(unsigned BucketNo) const {

128 assert(FileBuffer->getBufferSize() >=

129 sizeof(HMapHeader) + sizeof(HMapBucket) * BucketNo &&

130 "Expected bucket to be in range");

131

134

135 const HMapBucket *BucketArray =

136 reinterpret_cast<const HMapBucket*>(FileBuffer->getBufferStart() +

137 sizeof(HMapHeader));

138 const HMapBucket *BucketPtr = BucketArray+BucketNo;

139

140

141 Result.Key = getEndianAdjustedWord(BucketPtr->Key);

142 Result.Prefix = getEndianAdjustedWord(BucketPtr->Prefix);

143 Result.Suffix = getEndianAdjustedWord(BucketPtr->Suffix);

145}

146

147std::optional HeaderMapImpl::getString(unsigned StrTabIdx) const {

148

149 StrTabIdx += getEndianAdjustedWord(getHeader().StringsOffset);

150

151

152 if (StrTabIdx >= FileBuffer->getBufferSize())

153 return std::nullopt;

154

155 const char *Data = FileBuffer->getBufferStart() + StrTabIdx;

156 unsigned MaxLen = FileBuffer->getBufferSize() - StrTabIdx;

157

158 if (MaxLen == 0)

159 return std::nullopt;

160

161 unsigned Len = strnlen(Data, MaxLen);

162

163

164 if (Len == MaxLen && Data[Len - 1])

165 return std::nullopt;

166

167 return StringRef(Data, Len);

168}

169

170

171

172

173

174

177 unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);

178

179 llvm::dbgs() << "Header Map " << getFileName() << ":\n " << NumBuckets

180 << ", " << getEndianAdjustedWord(Hdr.NumEntries) << "\n";

181

182 auto getStringOrInvalid = [this](unsigned Id) -> StringRef {

183 if (std::optional S = getString(Id))

184 return *S;

185 return "";

186 };

187

188 for (unsigned i = 0; i != NumBuckets; ++i) {

191

192 StringRef Key = getStringOrInvalid(B.Key);

193 StringRef Prefix = getStringOrInvalid(B.Prefix);

194 StringRef Suffix = getStringOrInvalid(B.Suffix);

195 llvm::dbgs() << " " << i << ". " << Key << " -> '" << Prefix << "' '"

196 << Suffix << "'\n";

197 }

198}

199

203 unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);

204

205

206 assert(llvm::isPowerOf2_32(NumBuckets) && "Expected power of 2");

207

208

209 for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) {

210 HMapBucket B = getBucket(Bucket & (NumBuckets-1));

212

213

214 std::optional Key = getString(B.Key);

215 if (LLVM_UNLIKELY(!Key))

216 continue;

217 if (!Filename.equals_insensitive(*Key))

218 continue;

219

220

221

222 std::optional Prefix = getString(B.Prefix);

223 std::optional Suffix = getString(B.Suffix);

224

225 DestPath.clear();

226 if (LLVM_LIKELY(Prefix && Suffix)) {

227 DestPath.append(Prefix->begin(), Prefix->end());

228 DestPath.append(Suffix->begin(), Suffix->end());

229 }

230 return StringRef(DestPath.begin(), DestPath.size());

231 }

232}

233

235 if (!ReverseMap.empty())

236 return ReverseMap.lookup(DestPath);

237

239 unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);

240 StringRef RetKey;

241 for (unsigned i = 0; i != NumBuckets; ++i) {

244 continue;

245

246 std::optional Key = getString(B.Key);

247 std::optional Prefix = getString(B.Prefix);

248 std::optional Suffix = getString(B.Suffix);

249 if (LLVM_LIKELY(Key && Prefix && Suffix)) {

251 Buf.append(Prefix->begin(), Prefix->end());

252 Buf.append(Suffix->begin(), Suffix->end());

253 StringRef Value(Buf.begin(), Buf.size());

254 ReverseMap[Value] = *Key;

255

256 if (DestPath == Value)

257 RetKey = *Key;

258 }

259 }

260 return RetKey;

261}