PDBSymbolCompiland.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //===- PDBSymbolCompiland.cpp - compiland details ---------------*- 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. #include "llvm/DebugInfo/PDB/IPDBSession.h"
  9. #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
  10. #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
  11. #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
  12. #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
  13. #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
  14. #include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
  15. #include "llvm/ADT/StringSwitch.h"
  16. #include "llvm/Support/Path.h"
  17. #include <utility>
  18. using namespace llvm;
  19. using namespace llvm::pdb;
  20. void PDBSymbolCompiland::dump(PDBSymDumper &Dumper) const {
  21. Dumper.dump(*this);
  22. }
  23. std::string PDBSymbolCompiland::getSourceFileName() const {
  24. return sys::path::filename(getSourceFileFullPath()).str();
  25. }
  26. std::string PDBSymbolCompiland::getSourceFileFullPath() const {
  27. std::string SourceFileFullPath;
  28. // RecordedResult could be the basename, relative path or full path of the
  29. // source file. Usually it is retrieved and recorded from the command that
  30. // compiles this compiland.
  31. //
  32. // cmd FileName -> RecordedResult = .\\FileName
  33. // cmd (Path)\\FileName -> RecordedResult = (Path)\\FileName
  34. //
  35. std::string RecordedResult = RawSymbol->getSourceFileName();
  36. if (RecordedResult.empty()) {
  37. if (auto Envs = findAllChildren<PDBSymbolCompilandEnv>()) {
  38. std::string EnvWorkingDir, EnvSrc;
  39. while (auto Env = Envs->getNext()) {
  40. std::string Var = Env->getName();
  41. if (Var == "cwd") {
  42. EnvWorkingDir = Env->getValue();
  43. continue;
  44. }
  45. if (Var == "src") {
  46. EnvSrc = Env->getValue();
  47. if (sys::path::is_absolute(EnvSrc))
  48. return EnvSrc;
  49. RecordedResult = EnvSrc;
  50. continue;
  51. }
  52. }
  53. if (!EnvWorkingDir.empty() && !EnvSrc.empty()) {
  54. auto Len = EnvWorkingDir.length();
  55. if (EnvWorkingDir[Len - 1] != '/' && EnvWorkingDir[Len - 1] != '\\') {
  56. std::string Path = EnvWorkingDir + "\\" + EnvSrc;
  57. std::replace(Path.begin(), Path.end(), '/', '\\');
  58. // We will return it as full path if we can't find a better one.
  59. if (sys::path::is_absolute(Path))
  60. SourceFileFullPath = Path;
  61. }
  62. }
  63. }
  64. }
  65. if (!RecordedResult.empty()) {
  66. if (sys::path::is_absolute(RecordedResult))
  67. return RecordedResult;
  68. // This searches name that has same basename as the one in RecordedResult.
  69. auto OneSrcFile = Session.findOneSourceFile(
  70. this, RecordedResult, PDB_NameSearchFlags::NS_CaseInsensitive);
  71. if (OneSrcFile)
  72. return OneSrcFile->getFileName();
  73. }
  74. // At this point, we have to walk through all source files of this compiland,
  75. // and determine the right source file if any that is used to generate this
  76. // compiland based on language indicated in compilanddetails language field.
  77. auto Details = findOneChild<PDBSymbolCompilandDetails>();
  78. PDB_Lang Lang = Details ? Details->getLanguage() : PDB_Lang::Cpp;
  79. auto SrcFiles = Session.getSourceFilesForCompiland(*this);
  80. if (SrcFiles) {
  81. while (auto File = SrcFiles->getNext()) {
  82. std::string FileName = File->getFileName();
  83. auto file_extension = sys::path::extension(FileName);
  84. if (StringSwitch<bool>(file_extension.lower())
  85. .Case(".cpp", Lang == PDB_Lang::Cpp)
  86. .Case(".cc", Lang == PDB_Lang::Cpp)
  87. .Case(".cxx", Lang == PDB_Lang::Cpp)
  88. .Case(".c", Lang == PDB_Lang::C)
  89. .Case(".asm", Lang == PDB_Lang::Masm)
  90. .Case(".swift", Lang == PDB_Lang::Swift)
  91. .Case(".rs", Lang == PDB_Lang::Rust)
  92. .Default(false))
  93. return File->getFileName();
  94. }
  95. }
  96. return SourceFileFullPath;
  97. }