llvm.org GIT mirror llvm / c41978f
Revert "Fix Bug 30978 by emitting cv file checksums." This reverts commit 6389e7aa724ea7671d096f4770f016c3d86b0d54. There is a bug in this implementation where the string value of the checksum is outputted, instead of the actual hex bytes. Therefore the checksum is incorrect, and this prevent pdbs from being loaded by visual studio. Revert this until the checksum is emitted correctly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313431 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Beckmann 2 years ago
16 changed file(s) with 85 addition(s) and 314 deletion(s). Raw diff Collapse all Expand all
472472 friend class MDNode;
473473
474474 public:
475 // These values must be explictly set, as they end up in the final object
476 // file.
477475 enum ChecksumKind {
478 CSK_None = 0,
479 CSK_MD5 = 1,
480 CSK_SHA1 = 2,
476 CSK_None,
477 CSK_MD5,
478 CSK_SHA1,
481479 CSK_Last = CSK_SHA1 // Should be last enumeration.
482480 };
483481
511509 ChecksumKind CSK = CSK_None,
512510 StringRef CS = StringRef()),
513511 (Filename, Directory, CSK, CS))
514 DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
512 DEFINE_MDNODE_GET(DIFile, (MDString *Filename, MDString *Directory,
515513 ChecksumKind CSK = CSK_None,
516514 MDString *CS = nullptr),
517515 (Filename, Directory, CSK, CS))
160160 ~CodeViewContext();
161161
162162 bool isValidFileNumber(unsigned FileNumber) const;
163 bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename,
164 StringRef Checksum, uint8_t ChecksumKind);
163 bool addFile(unsigned FileNumber, StringRef Filename);
164 ArrayRef getFilenames() { return Filenames; }
165165
166166 /// Records the function id of a normal function. Returns false if the
167167 /// function id has already been used, and true otherwise.
272272 /// Emits the file checksum substream.
273273 void emitFileChecksums(MCObjectStreamer &OS);
274274
275 /// Emits the offset into the checksum table of the given file number.
276 void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo);
277
278275 private:
279276 /// The current CodeView line information from the last .cv_loc directive.
280277 MCCVLoc CurrentCVLoc = MCCVLoc(0, 0, 0, 0, false, true);
289286
290287 MCDataFragment *getStringTableFragment();
291288
292 /// Add something to the string table. Returns the final string as well as
293 /// offset into the string table.
294 std::pair addToStringTable(StringRef S);
289 /// Add something to the string table.
290 StringRef addToStringTable(StringRef S);
295291
296292 /// Get a string table offset.
297293 unsigned getStringTableOffset(StringRef S);
298294
299 struct FileInfo {
300 unsigned StringTableOffset;
301
302 // Checksum offset stored as a symbol because it might be requested
303 // before it has been calculated, so a fixup may be needed.
304 MCSymbol *ChecksumTableOffset;
305
306 // Indicates if this FileInfo corresponds to an actual file, or hasn't been
307 // set yet.
308 bool Assigned = false;
309
310 std::string Checksum;
311 uint8_t ChecksumKind;
312 };
313
314 /// Array storing added file information.
315 SmallVector Files;
295 /// An array of absolute paths. Eventually this may include the file checksum.
296 SmallVector Filenames;
316297
317298 /// The offset of the first and last .cv_loc directive for a given function
318299 /// id.
323304
324305 /// All known functions and inlined call sites, indexed by function id.
325306 std::vector Functions;
326
327 /// Indicate whether we have already laid out the checksum table addresses or
328 /// not.
329 bool ChecksumOffsetsAssigned = false;
330307 };
331308
332309 } // end namespace llvm
139139 StringRef FixedSizePortion) override;
140140 void EmitCVStringTableDirective() override;
141141 void EmitCVFileChecksumsDirective() override;
142 void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
143142 void EmitDTPRel32Value(const MCExpr *Value) override;
144143 void EmitDTPRel64Value(const MCExpr *Value) override;
145144 void EmitTPRel32Value(const MCExpr *Value) override;
732732 unsigned Isa, unsigned Discriminator,
733733 StringRef FileName);
734734
735 /// Associate a filename with a specified logical file number, and also
736 /// specify that file's checksum information. This implements the '.cv_file 4
737 /// "foo.c"' assembler directive. Returns true on success.
738 virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
739 StringRef Checksum, unsigned ChecksumKind);
735 /// \brief Associate a filename with a specified logical file number. This
736 /// implements the '.cv_file 4 "foo.c"' assembler directive. Returns true on
737 /// success.
738 virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename);
740739
741740 /// \brief Introduces a function id for use with .cv_loc.
742741 virtual bool EmitCVFuncIdDirective(unsigned FunctionId);
777776
778777 /// \brief This implements the CodeView '.cv_filechecksums' assembler directive.
779778 virtual void EmitCVFileChecksumsDirective() {}
780
781 /// This implements the CodeView '.cv_filechecksumoffset' assembler
782 /// directive.
783 virtual void EmitCVFileChecksumOffsetDirective(unsigned FileNo) {}
784779
785780 /// Emit the absolute difference between two symbols.
786781 ///
158158 if (Insertion.second) {
159159 // We have to compute the full filepath and emit a .cv_file directive.
160160 StringRef FullPath = getFullFilepath(F);
161 StringRef Checksum = F->getChecksum();
162 DIFile::ChecksumKind ChecksumKind = F->getChecksumKind();
163 bool Success = OS.EmitCVFileDirective(NextId, FullPath, Checksum,
164 static_cast(ChecksumKind));
161 bool Success = OS.EmitCVFileDirective(NextId, FullPath);
165162 (void)Success;
166163 assert(Success && ".cv_file directive failed");
167164 }
683680 OS.AddComment("Inlinee lines subsection");
684681 MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines);
685682
686 // We emit the checksum info for files. This is used by debuggers to
687 // determine if a pdb matches the source before loading it. Visual Studio,
688 // for instance, will display a warning that the breakpoints are not valid if
689 // the pdb does not match the source.
683 // We don't provide any extra file info.
684 // FIXME: Find out if debuggers use this info.
690685 OS.AddComment("Inlinee lines signature");
691686 OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4);
692687
699694 OS.AddComment("Inlined function " + SP->getName() + " starts at " +
700695 SP->getFilename() + Twine(':') + Twine(SP->getLine()));
701696 OS.AddBlankLine();
697 // The filechecksum table uses 8 byte entries for now, and file ids start at
698 // 1.
699 unsigned FileOffset = (FileId - 1) * 8;
702700 OS.AddComment("Type index of inlined function");
703701 OS.EmitIntValue(InlineeIdx.getIndex(), 4);
704702 OS.AddComment("Offset into filechecksum table");
705 OS.EmitCVFileChecksumOffsetDirective(FileId);
703 OS.EmitIntValue(FileOffset, 4);
706704 OS.AddComment("Starting line number");
707705 OS.EmitIntValue(SP->getLine(), 4);
708706 }
353353 DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
354354 }
355355
356 // FIXME: Implement this string-enum correspondence with a .def file and macros,
357 // so that the association is explicit rather than implied.
358356 static const char *ChecksumKindName[DIFile::CSK_Last + 1] = {
359357 "CSK_None",
360358 "CSK_MD5",
224224 StringRef FileName) override;
225225 MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
226226
227 bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
228 StringRef Checksum, unsigned ChecksumKind) override;
227 bool EmitCVFileDirective(unsigned FileNo, StringRef Filename) override;
229228 bool EmitCVFuncIdDirective(unsigned FuncId) override;
230229 bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
231230 unsigned IAFile, unsigned IALine,
245244 StringRef FixedSizePortion) override;
246245 void EmitCVStringTableDirective() override;
247246 void EmitCVFileChecksumsDirective() override;
248 void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
249247
250248 void EmitIdent(StringRef IdentString) override;
251249 void EmitCFISections(bool EH, bool Debug) override;
11211119 return MCStreamer::getDwarfLineTableSymbol(0);
11221120 }
11231121
1124 bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
1125 StringRef Checksum,
1126 unsigned ChecksumKind) {
1127 if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
1128 ChecksumKind))
1122 bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) {
1123 if (!getContext().getCVContext().addFile(FileNo, Filename))
11291124 return false;
11301125
11311126 OS << "\t.cv_file\t" << FileNo << ' ';
1127
11321128 PrintQuotedString(Filename, OS);
1133
1134 if (!ChecksumKind) {
1135 EmitEOL();
1136 return true;
1137 }
1138
1139 OS << ' ';
1140 PrintQuotedString(Checksum, OS);
1141 OS << ' ' << ChecksumKind;
1142
11431129 EmitEOL();
11441130 return true;
11451131 }
12381224
12391225 void MCAsmStreamer::EmitCVFileChecksumsDirective() {
12401226 OS << "\t.cv_filechecksums";
1241 EmitEOL();
1242 }
1243
1244 void MCAsmStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
1245 OS << "\t.cv_filechecksumoffset\t" << FileNo;
12461227 EmitEOL();
12471228 }
12481229
3838 /// for it.
3939 bool CodeViewContext::isValidFileNumber(unsigned FileNumber) const {
4040 unsigned Idx = FileNumber - 1;
41 if (Idx < Files.size())
42 return Files[Idx].Assigned;
41 if (Idx < Filenames.size())
42 return !Filenames[Idx].empty();
4343 return false;
4444 }
4545
46 bool CodeViewContext::addFile(MCStreamer &OS, unsigned FileNumber,
47 StringRef Filename, StringRef Checksum,
48 uint8_t ChecksumKind) {
46 bool CodeViewContext::addFile(unsigned FileNumber, StringRef Filename) {
4947 assert(FileNumber > 0);
50 auto FilenameOffset = addToStringTable(Filename);
51 Filename = FilenameOffset.first;
48 Filename = addToStringTable(Filename);
5249 unsigned Idx = FileNumber - 1;
53 if (Idx >= Files.size())
54 Files.resize(Idx + 1);
50 if (Idx >= Filenames.size())
51 Filenames.resize(Idx + 1);
5552
5653 if (Filename.empty())
5754 Filename = "";
5855
59 if (Files[Idx].Assigned)
56 if (!Filenames[Idx].empty())
6057 return false;
6158
62 FilenameOffset = addToStringTable(Filename);
63 Filename = FilenameOffset.first;
64 unsigned Offset = FilenameOffset.second;
65
66 auto ChecksumOffsetSymbol =
67 OS.getContext().createTempSymbol("checksum_offset", false);
68 Files[Idx].StringTableOffset = Offset;
69 Files[Idx].ChecksumTableOffset = ChecksumOffsetSymbol;
70 Files[Idx].Assigned = true;
71 Files[Idx].Checksum = Checksum.str();
72 Files[Idx].ChecksumKind = ChecksumKind;
73
59 // FIXME: We should store the string table offset of the filename, rather than
60 // the filename itself for efficiency.
61 Filename = addToStringTable(Filename);
62
63 Filenames[Idx] = Filename;
7464 return true;
7565 }
7666
127117 return StrTabFragment;
128118 }
129119
130 std::pair CodeViewContext::addToStringTable(StringRef S) {
120 StringRef CodeViewContext::addToStringTable(StringRef S) {
131121 SmallVectorImpl &Contents = getStringTableFragment()->getContents();
132122 auto Insertion =
133123 StringTable.insert(std::make_pair(S, unsigned(Contents.size())));
134124 // Return the string from the table, since it is stable.
135 std::pair Ret =
136 std::make_pair(Insertion.first->first(), Insertion.first->second);
125 S = Insertion.first->first();
137126 if (Insertion.second) {
138127 // The string map key is always null terminated.
139 Contents.append(Ret.first.begin(), Ret.first.end() + 1);
140 }
141 return Ret;
128 Contents.append(S.begin(), S.end() + 1);
129 }
130 return S;
142131 }
143132
144133 unsigned CodeViewContext::getStringTableOffset(StringRef S) {
175164 void CodeViewContext::emitFileChecksums(MCObjectStreamer &OS) {
176165 // Do nothing if there are no file checksums. Microsoft's linker rejects empty
177166 // CodeView substreams.
178 if (Files.empty())
167 if (Filenames.empty())
179168 return;
180169
181170 MCContext &Ctx = OS.getContext();
186175 OS.emitAbsoluteSymbolDiff(FileEnd, FileBegin, 4);
187176 OS.EmitLabel(FileBegin);
188177
189 unsigned CurrentOffset = 0;
190
191178 // Emit an array of FileChecksum entries. We index into this table using the
192 // user-provided file number. Each entry may be a variable number of bytes
193 // determined by the checksum kind and size.
194 for (auto File : Files) {
195 OS.EmitAssignment(File.ChecksumTableOffset,
196 MCConstantExpr::create(CurrentOffset, Ctx));
197 CurrentOffset += 4; // String table offset.
198 if (!File.ChecksumKind) {
199 CurrentOffset +=
200 4; // One byte each for checksum size and kind, then align to 4 bytes.
201 } else {
202 CurrentOffset += 2; // One byte each for checksum size and kind.
203 CurrentOffset += File.Checksum.size();
204 CurrentOffset = alignTo(CurrentOffset, 4);
205 }
206
207 OS.EmitIntValue(File.StringTableOffset, 4);
208
209 if (!File.ChecksumKind) {
210 // There is no checksum. Therefore zero the next two fields and align
211 // back to 4 bytes.
212 OS.EmitIntValue(0, 4);
213 continue;
214 }
215 OS.EmitIntValue(static_cast(File.Checksum.size()), 1);
216 OS.EmitIntValue(File.ChecksumKind, 1);
217 OS.EmitBytes(File.Checksum);
218 OS.EmitValueToAlignment(4);
179 // user-provided file number. Each entry is currently 8 bytes, as we don't
180 // emit checksums.
181 for (StringRef Filename : Filenames) {
182 OS.EmitIntValue(getStringTableOffset(Filename), 4);
183 // Zero the next two fields and align back to 4 bytes. This indicates that
184 // no checksum is present.
185 OS.EmitIntValue(0, 4);
219186 }
220187
221188 OS.EmitLabel(FileEnd);
222
223 ChecksumOffsetsAssigned = true;
224 }
225
226 // Output checksum table offset of the given file number. It is possible that
227 // not all files have been registered yet, and so the offset cannot be
228 // calculated. In this case a symbol representing the offset is emitted, and
229 // the value of this symbol will be fixed up at a later time.
230 void CodeViewContext::emitFileChecksumOffset(MCObjectStreamer &OS,
231 unsigned FileNo) {
232 unsigned Idx = FileNo - 1;
233
234 if (Idx >= Files.size())
235 Files.resize(Idx + 1);
236
237 if (ChecksumOffsetsAssigned) {
238 OS.EmitSymbolValue(Files[Idx].ChecksumTableOffset, 4);
239 return;
240 }
241
242 const MCSymbolRefExpr *SRE =
243 MCSymbolRefExpr::create(Files[Idx].ChecksumTableOffset, OS.getContext());
244
245 OS.EmitValueImpl(SRE, 4);
246189 }
247190
248191 void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS,
275218 return Loc.getFileNum() != CurFileNum;
276219 });
277220 unsigned EntryCount = FileSegEnd - I;
278 OS.AddComment(
279 "Segment for file '" +
280 Twine(getStringTableFragment()
281 ->getContents()[Files[CurFileNum - 1].StringTableOffset]) +
282 "' begins");
283 OS.EmitCVFileChecksumOffsetDirective(CurFileNum);
221 OS.AddComment("Segment for file '" + Twine(Filenames[CurFileNum - 1]) +
222 "' begins");
223 OS.EmitIntValue(8 * (CurFileNum - 1), 4);
284224 OS.EmitIntValue(EntryCount, 4);
285225 uint32_t SegmentSize = 12;
286226 SegmentSize += 8 * EntryCount;
460400 HaveOpenRange = true;
461401
462402 if (CurSourceLoc.File != LastSourceLoc.File) {
463 unsigned FileOffset = static_cast(
464 Files[CurSourceLoc.File - 1]
465 .ChecksumTableOffset->getVariableValue())
466 ->getValue();
403 // File ids are 1 based, and each file checksum table entry is 8 bytes
404 // long. See emitFileChecksums above.
405 unsigned FileOffset = 8 * (CurSourceLoc.File - 1);
467406 compressAnnotation(BinaryAnnotationsOpCode::ChangeFile, Buffer);
468407 compressAnnotation(FileOffset, Buffer);
469408 }
425425 getContext().getCVContext().emitFileChecksums(*this);
426426 }
427427
428 void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
429 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
430 }
431428
432429 void MCObjectStreamer::EmitBytes(StringRef Data) {
433430 MCCVLineEntry::Make(this);
500500 DK_CV_DEF_RANGE,
501501 DK_CV_STRINGTABLE,
502502 DK_CV_FILECHECKSUMS,
503 DK_CV_FILECHECKSUM_OFFSET,
504503 DK_CFI_SECTIONS,
505504 DK_CFI_STARTPROC,
506505 DK_CFI_ENDPROC,
576575 bool parseDirectiveCVDefRange();
577576 bool parseDirectiveCVStringTable();
578577 bool parseDirectiveCVFileChecksums();
579 bool parseDirectiveCVFileChecksumOffset();
580578
581579 // .cfi directives
582580 bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
20312029 return parseDirectiveCVStringTable();
20322030 case DK_CV_FILECHECKSUMS:
20332031 return parseDirectiveCVFileChecksums();
2034 case DK_CV_FILECHECKSUM_OFFSET:
2035 return parseDirectiveCVFileChecksumOffset();
20362032 case DK_CFI_SECTIONS:
20372033 return parseDirectiveCFISections();
20382034 case DK_CFI_STARTPROC:
34603456 }
34613457
34623458 /// parseDirectiveCVFile
3463 /// ::= .cv_file number filename [checksum] [checksumkind]
3459 /// ::= .cv_file number filename
34643460 bool AsmParser::parseDirectiveCVFile() {
34653461 SMLoc FileNumberLoc = getTok().getLoc();
34663462 int64_t FileNumber;
34673463 std::string Filename;
3468 std::string Checksum;
3469 int64_t ChecksumKind = 0;
34703464
34713465 if (parseIntToken(FileNumber,
34723466 "expected file number in '.cv_file' directive") ||
34733467 check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
34743468 check(getTok().isNot(AsmToken::String),
34753469 "unexpected token in '.cv_file' directive") ||
3476 parseEscapedString(Filename))
3477 return true;
3478 if (!parseOptionalToken(AsmToken::EndOfStatement)) {
3479 if (check(getTok().isNot(AsmToken::String),
3480 "unexpected token in '.cv_file' directive") ||
3481 parseEscapedString(Checksum) ||
3482 parseIntToken(ChecksumKind,
3483 "expected checksum kind in '.cv_file' directive") ||
3484 parseToken(AsmToken::EndOfStatement,
3485 "unexpected token in '.cv_file' directive"))
3486 return true;
3487 }
3488
3489 if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, Checksum,
3490 static_cast(ChecksumKind)))
3470 // Usually directory and filename are together, otherwise just
3471 // directory. Allow the strings to have escaped octal character sequence.
3472 parseEscapedString(Filename) ||
3473 parseToken(AsmToken::EndOfStatement,
3474 "unexpected token in '.cv_file' directive"))
3475 return true;
3476
3477 if (!getStreamer().EmitCVFileDirective(FileNumber, Filename))
34913478 return Error(FileNumberLoc, "file number already allocated");
34923479
34933480 return false;
37633750 /// ::= .cv_filechecksums
37643751 bool AsmParser::parseDirectiveCVFileChecksums() {
37653752 getStreamer().EmitCVFileChecksumsDirective();
3766 return false;
3767 }
3768
3769 /// parseDirectiveCVFileChecksumOffset
3770 /// ::= .cv_filechecksumoffset fileno
3771 bool AsmParser::parseDirectiveCVFileChecksumOffset() {
3772 int64_t FileNo;
3773 if (parseIntToken(FileNo, "expected identifier in directive"))
3774 return true;
3775 if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
3776 return true;
3777 getStreamer().EmitCVFileChecksumOffsetDirective(FileNo);
37783753 return false;
37793754 }
37803755
51605135 DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
51615136 DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
51625137 DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5163 DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
51645138 DirectiveKindMap[".sleb128"] = DK_SLEB128;
51655139 DirectiveKindMap[".uleb128"] = DK_ULEB128;
51665140 DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
227227 report_fatal_error("No open frame");
228228 }
229229
230 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
231 StringRef Checksum,
232 unsigned ChecksumKind) {
233 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
234 ChecksumKind);
230 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) {
231 return getContext().getCVContext().addFile(FileNo, Filename);
235232 }
236233
237234 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
4848 ; ASM: .long 0
4949 ; ASM: # Inlined function bar starts at t.cpp:8
5050 ; ASM: .long 4098 # Type index of inlined function
51 ; ASM: .cv_filechecksumoffset 1 # Offset into filechecksum table
51 ; ASM: .long 0 # Offset into filechecksum table
5252 ; ASM: .long 8 # Starting line number
5353 ; ASM: # Inlined function foo starts at t.cpp:2
5454 ; ASM: .long 4099
55 ; ASM: .cv_filechecksumoffset 1 # Offset into filechecksum table
55 ; ASM: .long 0
5656 ; ASM: .long 2
5757 ; ASM: [[inline_end]]:
5858
7070 ; ASM: .cv_inline_linetable 2 1 2 Lfunc_begin0 Lfunc_end0
7171 ; ASM: .short 4430
7272 ; ASM: .short 4430
73
74 ; ASM: .cv_filechecksums
7573
7674 ; ASM: .section .debug$T,"dr"
7775 ; ASM: .long 4 # Debug section magic
1717
1818 ; X86-LABEL: _f:
1919 ; X86: # BB
20 ; X86: .cv_file 1 "D:\\one.c" "70b51f534d80639d033ae92c6a856af6" 1
20 ; X86: .cv_file 1 "D:\\one.c"
2121 ; X86: .cv_loc 0 1 1 0 is_stmt 0 # one.c:1:0
2222 ; X86: calll _g
23 ; X86: .cv_file 2 "D:\\two.c" "70b51f534d80639d033ae92c6a856af6" 1
23 ; X86: .cv_file 2 "D:\\two.c"
2424 ; X86: .cv_loc 0 2 2 0 # two.c:2:0
2525 ; X86: calll _g
2626 ; X86: .cv_loc 0 1 7 0 # one.c:7:0
5050 ; OBJ32-NEXT: ProcEnd {
5151 ; OBJ32: }
5252 ; OBJ32-NEXT: ]
53 ; OBJ32: Subsection [
54 ; OBJ32: SubSectionType: FileChecksums (0xF4)
55 ; OBJ32-NEXT: SubSectionSize: 0x50
56 ; OBJ32-NEXT: FileChecksum {
57 ; OBJ32-NEXT: Filename: D:\one.c (0x1)
58 ; OBJ32-NEXT: ChecksumSize: 0x20
59 ; OBJ32-NEXT: ChecksumKind: MD5 (0x1)
60 ; OBJ32-NEXT: ChecksumBytes (
61 ; OBJ32-NEXT: 0000: 37306235 31663533 34643830 36333964 |70b51f534d80639d|
62 ; OBJ32-NEXT: 0010: 30333361 65393263 36613835 36616636 |033ae92c6a856af6|
63 ; OBJ32-NEXT: )
64 ; OBJ32-NEXT: }
65 ; OBJ32-NEXT: FileChecksum {
66 ; OBJ32-NEXT: Filename: D:\two.c (0xA)
67 ; OBJ32-NEXT: ChecksumSize: 0x20
68 ; OBJ32-NEXT: ChecksumKind: MD5 (0x1)
69 ; OBJ32-NEXT: ChecksumBytes (
70 ; OBJ32-NEXT: 0000: 37306235 31663533 34643830 36333964 |70b51f534d80639d|
71 ; OBJ32-NEXT: 0010: 30333361 65393263 36613835 36616636 |033ae92c6a856af6|
72 ; OBJ32-NEXT: )
73 ; OBJ32-NEXT: }
74 ; OBJ32-NEXT: ]
7553 ; OBJ32: FunctionLineTable [
7654 ; OBJ32-NEXT: Name: _f
7755 ; OBJ32-NEXT: Flags: 0x0
10987
11088 ; X64-LABEL: f:
11189 ; X64-NEXT: .L{{.*}}:{{$}}
112 ; X64: .cv_file 1 "D:\\input.c" "70b51f534d80639d033ae92c6a856af6" 1
90 ; X64: .cv_file 1 "D:\\input.c"
11391 ; X64: .cv_loc 0 1 3 0 is_stmt 0 # input.c:3:0
11492 ; X64: # BB
11593 ; X64: subq $40, %rsp
116 ; X64: .cv_file 2 "D:\\one.c" "70b51f534d80639d033ae92c6a856af6" 1
94 ; X64: .cv_file 2 "D:\\one.c"
11795 ; X64: .cv_loc 0 2 1 0 # one.c:1:0
11896 ; X64: callq g
119 ; X64: .cv_file 3 "D:\\two.c" "70b51f534d80639d033ae92c6a856af6" 1
97 ; X64: .cv_file 3 "D:\\two.c"
12098 ; X64: .cv_loc 0 3 2 0 # two.c:2:0
12199 ; X64: callq g
122100 ; X64: .cv_loc 0 2 7 0 # one.c:7:0
144122 ; OBJ64-NEXT: ProcEnd {
145123 ; OBJ64: }
146124 ; OBJ64-NEXT: ]
147 ; OBJ64: Subsection [
148 ; OBJ64: SubSectionType: FileChecksums (0xF4)
149 ; OBJ64-NEXT: SubSectionSize: 0x78
150 ; OBJ64-NEXT: FileChecksum {
151 ; OBJ64-NEXT: Filename: D:\input.c (0x1)
152 ; OBJ64-NEXT: ChecksumSize: 0x20
153 ; OBJ64-NEXT: ChecksumKind: MD5 (0x1)
154 ; OBJ64-NEXT: ChecksumBytes (
155 ; OBJ64-NEXT: 0000: 37306235 31663533 34643830 36333964 |70b51f534d80639d|
156 ; OBJ64-NEXT: 0010: 30333361 65393263 36613835 36616636 |033ae92c6a856af6|
157 ; OBJ64-NEXT: )
158 ; OBJ64-NEXT: }
159 ; OBJ64-NEXT: FileChecksum {
160 ; OBJ64-NEXT: Filename: D:\one.c (0xC)
161 ; OBJ64-NEXT: ChecksumSize: 0x20
162 ; OBJ64-NEXT: ChecksumKind: MD5 (0x1)
163 ; OBJ64-NEXT: ChecksumBytes (
164 ; OBJ64-NEXT: 0000: 37306235 31663533 34643830 36333964 |70b51f534d80639d|
165 ; OBJ64-NEXT: 0010: 30333361 65393263 36613835 36616636 |033ae92c6a856af6|
166 ; OBJ64-NEXT: )
167 ; OBJ64-NEXT: }
168 ; OBJ64-NEXT: FileChecksum {
169 ; OBJ64-NEXT: Filename: D:\two.c (0x15)
170 ; OBJ64-NEXT: ChecksumSize: 0x20
171 ; OBJ64-NEXT: ChecksumKind: MD5 (0x1)
172 ; OBJ64-NEXT: ChecksumBytes (
173 ; OBJ64-NEXT: 0000: 37306235 31663533 34643830 36333964 |70b51f534d80639d|
174 ; OBJ64-NEXT: 0010: 30333361 65393263 36613835 36616636 |033ae92c6a856af6|
175 ; OBJ64-NEXT: )
176 ; OBJ64-NEXT: }
177 ; OBJ64-NEXT: ]
178125 ; OBJ64: FunctionLineTable [
179126 ; OBJ64-NEXT: Name: f
180127 ; OBJ64-NEXT: Flags: 0x0
237184 !llvm.ident = !{!11}
238185
239186 !0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5 ", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
240 !1 = !DIFile(filename: "", directory: "D:\5C", checksumkind: CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
187 !1 = !DIFile(filename: "", directory: "D:\5C")
241188 !2 = !{}
242189 !4 = distinct !DISubprogram(name: "f", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 3, file: !5, scope: !6, type: !7, variables: !2)
243 !5 = !DIFile(filename: "input.c", directory: "D:\5C", checksumkind: CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
244 !6 = !DIFile(filename: "input.c", directory: "D:C", checksumkind: CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
190 !5 = !DIFile(filename: "input.c", directory: "D:\5C")
191 !6 = !DIFile(filename: "input.c", directory: "D:C")
245192 !7 = !DISubroutineType(types: !8)
246193 !8 = !{null}
247194 !9 = !{i32 2, !"CodeView", i32 1}
249196 !11 = !{!"clang version 3.5 "}
250197 !12 = !DILocation(line: 1, scope: !13)
251198 !13 = !DILexicalBlockFile(discriminator: 0, file: !14, scope: !4)
252 !14 = !DIFile(filename: "one.c", directory: "D:\5C", checksumkind: CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
199 !14 = !DIFile(filename: "one.c", directory: "D:\5C")
253200 !15 = !DILocation(line: 2, scope: !16)
254201 !16 = !DILexicalBlockFile(discriminator: 0, file: !17, scope: !4)
255 !17 = !DIFile(filename: "two.c", directory: "D:\5C", checksumkind: CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
202 !17 = !DIFile(filename: "two.c", directory: "D:\5C")
256203 !18 = !DILocation(line: 7, scope: !13)
257204 !19 = !DILocation(line: 8, scope: !13)
1616
1717 ; X86-LABEL: _f:
1818 ; X86: # BB
19 ; X86: .cv_file 1 "D:\\test.c" "f310ab26998ca831cbdf169e4eecacfa" 1
19 ; X86: .cv_file 1 "D:\\test.c"
2020 ; X86: .cv_loc 0 1 4 2 is_stmt 0 # test.c:4:2
2121 ; X86: calll _g
2222 ; X86: .cv_loc 0 1 5 0 # test.c:5:0
8484 ; OBJ32-NEXT: ProcEnd {
8585 ; OBJ32: }
8686 ; OBJ32-NEXT: ]
87 ; OBJ32: Subsection [
88 ; OBJ32: SubSectionType: FileChecksums (0xF4)
89 ; OBJ32-NEXT: SubSectionSize: 0x28
90 ; OBJ32-NEXT: FileChecksum {
91 ; OBJ32-NEXT: Filename: D:\test.c (0x1)
92 ; OBJ32-NEXT: ChecksumSize: 0x20
93 ; OBJ32-NEXT: ChecksumKind: MD5 (0x1)
94 ; OBJ32-NEXT: ChecksumBytes (
95 ; OBJ32-NEXT: 0000: 66333130 61623236 39393863 61383331 |f310ab26998ca831|
96 ; OBJ32-NEXT: 0010: 63626466 31363965 34656563 61636661 |cbdf169e4eecacfa|
97 ; OBJ32-NEXT: )
98 ; OBJ32-NEXT: }
99 ; OBJ32-NEXT: ]
10087 ; OBJ32: FunctionLineTable [
10188 ; OBJ32-NEXT: Name: _f
10289 ; OBJ32-NEXT: Flags: 0x1
122109
123110 ; X64-LABEL: f:
124111 ; X64-NEXT: .L{{.*}}:{{$}}
125 ; X64: .cv_file 1 "D:\\test.c" "f310ab26998ca831cbdf169e4eecacfa" 1
112 ; X64: .cv_file 1 "D:\\test.c"
126113 ; X64: .cv_loc 0 1 3 0 is_stmt 0 # test.c:3:0
127114 ; X64: # BB
128115 ; X64: subq $40, %rsp
194181 ; OBJ64-NEXT: ProcEnd {
195182 ; OBJ64: }
196183 ; OBJ64-NEXT: ]
197 ; OBJ64: Subsection [
198 ; OBJ64: SubSectionType: FileChecksums (0xF4)
199 ; OBJ64-NEXT: SubSectionSize: 0x28
200 ; OBJ64-NEXT: FileChecksum {
201 ; OBJ64-NEXT: Filename: D:\test.c (0x1)
202 ; OBJ64-NEXT: ChecksumSize: 0x20
203 ; OBJ64-NEXT: ChecksumKind: MD5 (0x1)
204 ; OBJ64-NEXT: ChecksumBytes (
205 ; OBJ64-NEXT: 0000: 66333130 61623236 39393863 61383331 |f310ab26998ca831|
206 ; OBJ64-NEXT: 0010: 63626466 31363965 34656563 61636661 |cbdf169e4eecacfa|
207 ; OBJ64-NEXT: )
208 ; OBJ64-NEXT: }
209 ; OBJ64-NEXT: ]
210184 ; OBJ64: FunctionLineTable [
211185 ; OBJ64-NEXT: Name: f
212186 ; OBJ64-NEXT: Flags: 0x1
257231 !1 = !DIFile(filename: "", directory: "D:\5C")
258232 !2 = !{}
259233 !4 = distinct !DISubprogram(name: "f", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 3, file: !5, scope: !6, type: !7, variables: !2)
260 !5 = !DIFile(filename: "test.c", directory: "D:\5C", checksumkind: CSK_MD5, checksum: "f310ab26998ca831cbdf169e4eecacfa")
261 !6 = !DIFile(filename: "test.c", directory: "D:C", checksumkind: CSK_MD5, checksum: "f310ab26998ca831cbdf169e4eecacfa")
234 !5 = !DIFile(filename: "test.c", directory: "D:\5C")
235 !6 = !DIFile(filename: "test.c", directory: "D:C")
262236 !7 = !DISubroutineType(types: !8)
263237 !8 = !{null}
264238 !9 = !{i32 2, !"CodeView", i32 1}
102102 ; CHECK: SubSectionType: FileChecksums (0xF4)
103103 ; CHECK: FileChecksum {
104104 ; CHECK: ChecksumSize: 0x0
105 ; CHECK: ChecksumKind: MD5 (0x1)
105 ; CHECK: ChecksumKind: None (0x0)
106106 ; CHECK: ChecksumBytes: ()
107107 ; CHECK: }
108108 ; CHECK: ]
13821382
13831383 EXPECT_NE(N, DIFile::get(Context, "other", Directory, CSKind, Checksum));
13841384 EXPECT_NE(N, DIFile::get(Context, Filename, "other", CSKind, Checksum));
1385 EXPECT_NE(
1386 N, DIFile::get(Context, Filename, Directory, DIFile::CSK_SHA1, Checksum));
1385 EXPECT_NE(N, DIFile::get(Context, Filename, Directory, DIFile::CSK_SHA1, Checksum));
13871386 EXPECT_NE(N, DIFile::get(Context, Filename, Directory));
13881387
13891388 TempDIFile Temp = N->clone();