blob: 9b2883546305bf996ff45ec78abb25ec704612da [file] [log] [blame]
Aaron Smithc0a5c012018-04-10 15:25:04 +00001//===- PDBSymbolCompiland.cpp - compiland details ---------------*- C++ -*-===//
Zachary Turner21473f72015-02-08 00:29:29 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Zachary Turner21473f72015-02-08 00:29:29 +00006//
7//===----------------------------------------------------------------------===//
8
Aaron Smithda611202018-03-19 21:20:04 +00009#include "llvm/DebugInfo/PDB/IPDBSession.h"
10#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
11
Zachary Turner52c9f882015-02-14 03:53:56 +000012#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
Aaron Smithda611202018-03-19 21:20:04 +000013#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
Aaron Smithc0a5c012018-04-10 15:25:04 +000014#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
Zachary Turner9a818ad2015-02-22 22:03:38 +000015#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
Zachary Turner52c9f882015-02-14 03:53:56 +000016
Aaron Smithda611202018-03-19 21:20:04 +000017#include "llvm/ADT/StringSwitch.h"
18#include "llvm/Support/Path.h"
Chandler Carruth71f308a2015-02-13 09:09:03 +000019#include <utility>
Zachary Turner21473f72015-02-08 00:29:29 +000020
21using namespace llvm;
Zachary Turnerec28fc32016-05-04 20:32:13 +000022using namespace llvm::pdb;
Zachary Turner21473f72015-02-08 00:29:29 +000023
Zachary Turnerb52d08d2015-03-01 06:51:29 +000024void PDBSymbolCompiland::dump(PDBSymDumper &Dumper) const {
25 Dumper.dump(*this);
Zachary Turner21473f72015-02-08 00:29:29 +000026}
Zachary Turner43ec3af2016-02-18 18:47:29 +000027
Aaron Smithda611202018-03-19 21:20:04 +000028std::string PDBSymbolCompiland::getSourceFileName() const {
Aaron Smithc0a5c012018-04-10 15:25:04 +000029 return sys::path::filename(getSourceFileFullPath()).str();
Aaron Smithda611202018-03-19 21:20:04 +000030}
31
32std::string PDBSymbolCompiland::getSourceFileFullPath() const {
33 std::string SourceFileFullPath;
34
35 // RecordedResult could be the basename, relative path or full path of the
36 // source file. Usually it is retrieved and recorded from the command that
37 // compiles this compiland.
38 //
39 // cmd FileName -> RecordedResult = .\\FileName
40 // cmd (Path)\\FileName -> RecordedResult = (Path)\\FileName
41 //
42 std::string RecordedResult = RawSymbol->getSourceFileName();
43
44 if (RecordedResult.empty()) {
45 if (auto Envs = findAllChildren<PDBSymbolCompilandEnv>()) {
46 std::string EnvWorkingDir, EnvSrc;
47
48 while (auto Env = Envs->getNext()) {
Zachary Turner43ec3af2016-02-18 18:47:29 +000049 std::string Var = Env->getName();
Aaron Smithda611202018-03-19 21:20:04 +000050 if (Var == "cwd") {
51 EnvWorkingDir = Env->getValue();
52 continue;
53 }
54 if (Var == "src") {
55 EnvSrc = Env->getValue();
Aaron Smithc0a5c012018-04-10 15:25:04 +000056 if (sys::path::is_absolute(EnvSrc))
Aaron Smithda611202018-03-19 21:20:04 +000057 return EnvSrc;
58 RecordedResult = EnvSrc;
59 continue;
60 }
61 }
62 if (!EnvWorkingDir.empty() && !EnvSrc.empty()) {
63 auto Len = EnvWorkingDir.length();
64 if (EnvWorkingDir[Len - 1] != '/' && EnvWorkingDir[Len - 1] != '\\') {
65 std::string Path = EnvWorkingDir + "\\" + EnvSrc;
66 std::replace(Path.begin(), Path.end(), '/', '\\');
67 // We will return it as full path if we can't find a better one.
Aaron Smithc0a5c012018-04-10 15:25:04 +000068 if (sys::path::is_absolute(Path))
Aaron Smithda611202018-03-19 21:20:04 +000069 SourceFileFullPath = Path;
70 }
71 }
Zachary Turner43ec3af2016-02-18 18:47:29 +000072 }
Aaron Smithda611202018-03-19 21:20:04 +000073 }
74
75 if (!RecordedResult.empty()) {
Aaron Smithc0a5c012018-04-10 15:25:04 +000076 if (sys::path::is_absolute(RecordedResult))
Aaron Smithda611202018-03-19 21:20:04 +000077 return RecordedResult;
78
79 // This searches name that has same basename as the one in RecordedResult.
Aaron Smithc0a5c012018-04-10 15:25:04 +000080 auto OneSrcFile = Session.findOneSourceFile(
81 this, RecordedResult, PDB_NameSearchFlags::NS_CaseInsensitive);
Aaron Smithda611202018-03-19 21:20:04 +000082 if (OneSrcFile)
83 return OneSrcFile->getFileName();
84 }
85
86 // At this point, we have to walk through all source files of this compiland,
87 // and determine the right source file if any that is used to generate this
88 // compiland based on language indicated in compilanddetails language field.
89 auto Details = findOneChild<PDBSymbolCompilandDetails>();
90 PDB_Lang Lang = Details ? Details->getLanguage() : PDB_Lang::Cpp;
91 auto SrcFiles = Session.getSourceFilesForCompiland(*this);
92 if (SrcFiles) {
Aaron Smithda611202018-03-19 21:20:04 +000093 while (auto File = SrcFiles->getNext()) {
94 std::string FileName = File->getFileName();
Aaron Smithc0a5c012018-04-10 15:25:04 +000095 auto file_extension = sys::path::extension(FileName);
Aaron Smithda611202018-03-19 21:20:04 +000096 if (StringSwitch<bool>(file_extension.lower())
Nathan Lanzacc51dc62019-03-11 23:27:59 +000097 .Case(".cpp", Lang == PDB_Lang::Cpp)
98 .Case(".cc", Lang == PDB_Lang::Cpp)
99 .Case(".cxx", Lang == PDB_Lang::Cpp)
100 .Case(".c", Lang == PDB_Lang::C)
Aaron Smithc0a5c012018-04-10 15:25:04 +0000101 .Case(".asm", Lang == PDB_Lang::Masm)
Nathan Lanzacc51dc62019-03-11 23:27:59 +0000102 .Case(".swift", Lang == PDB_Lang::Swift)
Aaron Smithc0a5c012018-04-10 15:25:04 +0000103 .Default(false))
Aaron Smithda611202018-03-19 21:20:04 +0000104 return File->getFileName();
105 }
106 }
107
108 return SourceFileFullPath;
Zachary Turner43ec3af2016-02-18 18:47:29 +0000109}