mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Debug Info: Migrate from MDModule to DIModule.
MDModule was a bitcode-incompatible internal-only extension that has since been replaced with a blessed IR node on trunk. <rdar://problem/20965932> Upstream DIModule and support it in clang-700, swiftlang-700, and lldb-700 Swift SVN r29832
This commit is contained in:
@@ -72,30 +72,6 @@ StringRef IRGenDebugInfo::BumpAllocatedString(StringRef S) {
|
||||
return BumpAllocatedString(S.data(), S.size());
|
||||
}
|
||||
|
||||
static bool isNonAscii(StringRef str) {
|
||||
for (unsigned char c : str) {
|
||||
if (c >= 0x80)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Mangle a single non-operator identifier.
|
||||
static void mangleIdent(llvm::raw_string_ostream &OS, StringRef Id) {
|
||||
// If the identifier contains non-ASCII character, we mangle with an initial
|
||||
// X and Punycode the identifier string.
|
||||
std::string PunycodeBuf;
|
||||
(void) isNonAscii;
|
||||
if (isNonAscii(Id)) {
|
||||
OS << 'X';
|
||||
Punycode::encodePunycodeUTF8(Id, PunycodeBuf);
|
||||
Id = PunycodeBuf;
|
||||
}
|
||||
OS << Id.size() << Id;
|
||||
OS.flush();
|
||||
return;
|
||||
}
|
||||
|
||||
/// Return the size reported by a type.
|
||||
static unsigned getSizeInBits(llvm::DIType *Ty, const TrackingDIRefMap &Map) {
|
||||
// Follow derived types until we reach a type that
|
||||
@@ -191,14 +167,9 @@ IRGenDebugInfo::IRGenDebugInfo(const IRGenOptions &Opts,
|
||||
}
|
||||
|
||||
// Create a module for the current compile unit.
|
||||
MainModule = getOrCreateModule(TheCU, Opts.ModuleName, MainFile);
|
||||
std::string Mangled("_TF");
|
||||
llvm::raw_string_ostream MS(Mangled);
|
||||
if (Opts.ModuleName == IGM.Context.StdlibModuleName.str())
|
||||
MS << "S";
|
||||
else
|
||||
mangleIdent(MS, Opts.ModuleName);
|
||||
createImportedModule(Opts.ModuleName, MS.str(), MainModule, 1);
|
||||
MainModule =
|
||||
getOrCreateModule(Opts.ModuleName, TheCU, Opts.ModuleName, MainFilename);
|
||||
DBuilder.createImportedModule(MainFile, MainModule, 1);
|
||||
}
|
||||
|
||||
static const char *getFilenameFromDC(const DeclContext *DC) {
|
||||
@@ -587,17 +558,15 @@ llvm::DIScope *IRGenDebugInfo::getOrCreateContext(DeclContext *DC) {
|
||||
case DeclContextKind::AbstractFunctionDecl:
|
||||
|
||||
// We don't model these in DWARF.
|
||||
|
||||
case DeclContextKind::SerializedLocal:
|
||||
case DeclContextKind::Initializer:
|
||||
case DeclContextKind::ExtensionDecl:
|
||||
return getOrCreateContext(DC->getParent());
|
||||
|
||||
case DeclContextKind::TopLevelCodeDecl:
|
||||
return cast<llvm::DIScope>(EntryPointFn);
|
||||
case DeclContextKind::Module: {
|
||||
auto File = getOrCreateFile(getFilenameFromDC(DC));
|
||||
return getOrCreateModule(TheCU, cast<Module>(DC)->getName().str(), File);
|
||||
}
|
||||
case DeclContextKind::Module:
|
||||
return getOrCreateModule({Module::AccessPathTy(), cast<ModuleDecl>(DC)});
|
||||
case DeclContextKind::FileUnit:
|
||||
// A module may contain multiple files.
|
||||
return getOrCreateContext(DC->getParent());
|
||||
@@ -788,69 +757,60 @@ void IRGenDebugInfo::emitImport(ImportDecl *D) {
|
||||
if (Opts.DebugInfoKind == IRGenDebugInfoKind::LineTables)
|
||||
return;
|
||||
|
||||
// Imports are visited after SILFunctions.
|
||||
llvm::MDModule *Module = MainModule;
|
||||
swift::Module *M = IGM.Context.getModule(D->getModulePath());
|
||||
if (!M && D->getModulePath()[0].first.str() == "Builtin")
|
||||
if (!M &&
|
||||
D->getModulePath()[0].first == IGM.Context.TheBuiltinModule->getName())
|
||||
M = IGM.Context.TheBuiltinModule;
|
||||
if (!M) {
|
||||
assert(M && "Could not find module for import decl.");
|
||||
return;
|
||||
}
|
||||
auto File = getOrCreateFile(getFilenameFromDC(M->getFiles().front()));
|
||||
auto DIMod = getOrCreateModule({D->getModulePath(), M});
|
||||
Location L = getLoc(SM, D);
|
||||
DBuilder.createImportedModule(getOrCreateFile(L.Filename), DIMod, L.Line);
|
||||
}
|
||||
|
||||
std::string Printed, Mangled("_T");
|
||||
{
|
||||
llvm::raw_string_ostream MS(Mangled), PS(Printed);
|
||||
bool first = true;
|
||||
for (auto elt : D->getModulePath()) {
|
||||
llvm::DIModule *
|
||||
IRGenDebugInfo::getOrCreateModule(ModuleDecl::ImportedModule M) {
|
||||
const char *fn = getFilenameFromDC(M.second);
|
||||
StringRef Path(fn ? fn : "");
|
||||
if (M.first.empty()) {
|
||||
StringRef Name = M.second->getName().str();
|
||||
return getOrCreateModule(Name, TheCU, Name, Path);
|
||||
}
|
||||
|
||||
unsigned I = 0;
|
||||
SmallString<128> AccessPath;
|
||||
llvm::DIScope *Scope = TheCU;
|
||||
llvm::raw_svector_ostream OS(AccessPath);
|
||||
for (auto elt : M.first) {
|
||||
auto Component = elt.first.str();
|
||||
|
||||
// We model each component of the access path as a module.
|
||||
if (first && Component == D->getASTContext().StdlibModuleName.str())
|
||||
MS << "S";
|
||||
else
|
||||
mangleIdent(MS, Component);
|
||||
Module = getOrCreateModule(Module, Component, File);
|
||||
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
PS << '.';
|
||||
PS << Component;
|
||||
if (++I > 1)
|
||||
OS << '.';
|
||||
OS << Component;
|
||||
OS.flush();
|
||||
Scope = getOrCreateModule(AccessPath, Scope, Component, Path);
|
||||
}
|
||||
}
|
||||
|
||||
StringRef Name = BumpAllocatedString(Printed);
|
||||
unsigned Line = getLoc(SM, D).Line;
|
||||
createImportedModule(Name, Mangled, Module, Line);
|
||||
}
|
||||
|
||||
// Create an imported module and import declarations for all functions
|
||||
// from that module.
|
||||
void IRGenDebugInfo::createImportedModule(StringRef Name, StringRef Mangled,
|
||||
llvm::MDModule *Module,
|
||||
unsigned Line) {
|
||||
llvm::SmallString<512> Path(Module->getDirectory());
|
||||
llvm::sys::path::append(Path, Module->getFilename());
|
||||
auto File = getOrCreateFile(BumpAllocatedString(Path).data());
|
||||
DBuilder.createImportedModule(File, Module, Line);
|
||||
return cast<llvm::DIModule>(Scope);
|
||||
}
|
||||
|
||||
/// Return a cached module for an access path or create a new one.
|
||||
llvm::MDModule *IRGenDebugInfo::getOrCreateModule(llvm::DIScope *Parent,
|
||||
std::string Name,
|
||||
llvm::DIFile *File) {
|
||||
llvm::DIModule *IRGenDebugInfo::getOrCreateModule(StringRef Key,
|
||||
llvm::DIScope *Parent,
|
||||
StringRef Name,
|
||||
StringRef Filename) {
|
||||
// Look in the cache first.
|
||||
auto CachedM = DIModuleCache.find(Name);
|
||||
auto Val = DIModuleCache.find(Key);
|
||||
if (Val != DIModuleCache.end())
|
||||
return cast<llvm::DIModule>(Val->second);
|
||||
|
||||
if (CachedM != DIModuleCache.end())
|
||||
// Verify that the information still exists.
|
||||
if (llvm::Metadata *Val = CachedM->second)
|
||||
return cast<llvm::MDModule>(Val);
|
||||
|
||||
auto M = DBuilder.createModule(Parent, Name, File, 1);
|
||||
DIModuleCache[Name] = llvm::TrackingMDNodeRef(M);
|
||||
StringRef ConfigMacros;
|
||||
StringRef Sysroot = IGM.Context.SearchPathOpts.SDKPath;
|
||||
SmallString<256> IncludePath(Filename);
|
||||
llvm::sys::path::remove_filename(IncludePath);
|
||||
auto M =
|
||||
DBuilder.createModule(Parent, Name, ConfigMacros, IncludePath, Sysroot);
|
||||
DIModuleCache.insert({Key, llvm::TrackingMDNodeRef(M)});
|
||||
return M;
|
||||
}
|
||||
|
||||
@@ -1538,15 +1498,24 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
|
||||
L.Filename = ClangSM.getBufferName(ClangSrcLoc);
|
||||
|
||||
// Use "ObjectiveC" as default for implicit decls.
|
||||
// FIXME 1: Do something more clever based on the decl's mangled name.
|
||||
// FIXME 2: Clang submodules are not handled here.
|
||||
// FIXME: Do something more clever based on the decl's mangled name.
|
||||
StringRef ModulePath;
|
||||
StringRef ModuleName = "ObjectiveC";
|
||||
if (auto *OwningModule = ClangDecl->getImportedOwningModule())
|
||||
ModuleName = OwningModule->getTopLevelModuleName();
|
||||
|
||||
auto ModuleFile = getOrCreateFile(L.Filename);
|
||||
// This placeholder gets RAUW'd by finalize().
|
||||
Scope = getOrCreateModule(ModuleFile, ModuleName, ModuleFile);
|
||||
if (auto *SwiftModule = Decl->getParentModule())
|
||||
if (auto *ClangModule = SwiftModule->findUnderlyingClangModule()) {
|
||||
// FIXME: Clang submodules are not handled here.
|
||||
// FIXME: Clang module config macros are not handled here.
|
||||
ModuleName = ClangModule->getFullModuleName();
|
||||
// FIXME: A clang module's Directory is supposed to be the
|
||||
// directory containing the module map, but ClangImporter
|
||||
// sets it to the module cache directory.
|
||||
if (ClangModule->Directory)
|
||||
ModulePath = ClangModule->Directory->getName();
|
||||
}
|
||||
Scope = getOrCreateModule(ModuleName, TheCU, ModuleName, ModulePath);
|
||||
}
|
||||
return createPointerSizedStruct(Scope, Decl->getNameStr(),
|
||||
getOrCreateFile(L.Filename), L.Line, Flags,
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "llvm/IR/DIBuilder.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
|
||||
#include "swift/AST/Module.h"
|
||||
#include "swift/SIL/SILLocation.h"
|
||||
#include "swift/SIL/SILBasicBlock.h"
|
||||
|
||||
@@ -84,7 +85,7 @@ class IRGenDebugInfo {
|
||||
llvm::DenseMap<SILDebugScope *, llvm::TrackingMDNodeRef> ScopeCache;
|
||||
llvm::DenseMap<const char *, llvm::TrackingMDNodeRef> DIFileCache;
|
||||
llvm::DenseMap<TypeBase *, llvm::TrackingMDNodeRef> DITypeCache;
|
||||
std::map<std::string, llvm::TrackingMDNodeRef> DIModuleCache;
|
||||
llvm::StringMap<llvm::TrackingMDNodeRef> DIModuleCache;
|
||||
TrackingDIRefMap DIRefMap;
|
||||
|
||||
llvm::SmallString<256> MainFilename;
|
||||
@@ -92,7 +93,7 @@ class IRGenDebugInfo {
|
||||
StringRef CWDName; /// The current working directory.
|
||||
llvm::DICompileUnit *TheCU = nullptr; /// The current compilation unit.
|
||||
llvm::DIFile *MainFile = nullptr; /// The main file.
|
||||
llvm::MDModule *MainModule = nullptr; /// The current module.
|
||||
llvm::DIModule *MainModule = nullptr; /// The current module.
|
||||
llvm::MDNode *EntryPointFn; /// Scope of SWIFT_ENTRY_POINT_FUNCTION.
|
||||
TypeAliasDecl *MetadataTypeDecl; /// The type decl for swift.type.
|
||||
llvm::DIType *InternalType; /// Catch-all type for opaque internal types.
|
||||
@@ -247,9 +248,6 @@ private:
|
||||
StringRef BumpAllocatedString(std::string S);
|
||||
StringRef BumpAllocatedString(StringRef S);
|
||||
|
||||
void createImportedModule(StringRef Name, StringRef MangledPrefix,
|
||||
llvm::MDModule *Module, unsigned Line);
|
||||
|
||||
llvm::DIType *createType(DebugTypeInfo DbgTy, StringRef MangledName,
|
||||
llvm::DIScope *Scope, llvm::DIFile *File);
|
||||
llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy);
|
||||
@@ -275,8 +273,9 @@ private:
|
||||
DeclContext *DeclContext,
|
||||
unsigned &SizeInBits);
|
||||
llvm::DIFile *getFile(llvm::DIScope *Scope);
|
||||
llvm::MDModule *getOrCreateModule(llvm::DIScope *Parent, std::string Name,
|
||||
llvm::DIFile *File);
|
||||
llvm::DIModule *getOrCreateModule(ModuleDecl::ImportedModule M);
|
||||
llvm::DIModule *getOrCreateModule(StringRef Key, llvm::DIScope *Parent,
|
||||
StringRef Name, StringRef Filename);
|
||||
llvm::DIScope *getModule(StringRef MangledName);
|
||||
llvm::DINodeArray getStructMembers(NominalTypeDecl *D, Type BaseTy,
|
||||
llvm::DIScope *Scope, llvm::DIFile *File,
|
||||
|
||||
@@ -5,15 +5,14 @@
|
||||
// RUN: %target-swift-frontend -c -module-name Foo %s -I %t -g -o %t.o
|
||||
// RUN: llvm-dwarfdump %t.o | FileCheck --check-prefix=DWARF %s
|
||||
|
||||
// CHECK-DAG: ![[FOOMODULE:[0-9]+]] = !MDModule(name: "Foo"
|
||||
// CHECK-DAG: ![[FOOMODULE:[0-9]+]] = !DIModule({{.*}}, name: "Foo", includePath: "{{.*}}test{{.*}}DebugInfo{{.*}}", isysroot:
|
||||
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[THISFILE:[0-9]+]], entity: ![[FOOMODULE]]
|
||||
// CHECK-DAG: ![[THISFILE]] = !DIFile(filename: "Imports.swift", directory: "{{.*}}test/DebugInfo")
|
||||
// CHECK-DAG: ![[SWIFTFILE:[0-9]+]] = !DIFile(filename: "Swift.swiftmodule"
|
||||
// CHECK-DAG: ![[SWIFTMODULE:[0-9]+]] = !MDModule(name: "Swift"
|
||||
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[SWIFTFILE]], entity: ![[SWIFTMODULE]]
|
||||
// CHECK-DAG: ![[BASICFILE:[0-9]+]] = !DIFile(filename: "basic.swiftmodule"
|
||||
// CHECK-DAG: ![[BASICMODULE:[0-9]+]] = !MDModule(name: "basic"
|
||||
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[BASICFILE]], entity: ![[BASICMODULE]]
|
||||
// CHECK-DAG: ![[SWIFTMODULE:[0-9]+]] = !DIModule({{.*}}, name: "Swift"
|
||||
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[THISFILE]], entity: ![[SWIFTMODULE]]
|
||||
// CHECK-DAG: ![[BASICMODULE:[0-9]+]] = !DIModule({{.*}}, name: "basic"
|
||||
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[THISFILE]], entity: ![[BASICMODULE]]
|
||||
import basic
|
||||
import typealias Swift.Optional
|
||||
|
||||
@@ -22,12 +21,16 @@ markUsed(basic.foo(1, 2))
|
||||
|
||||
// DWARF: .debug_info
|
||||
// DWARF: DW_TAG_module
|
||||
// DWARF-DAG: "Foo"
|
||||
// DWARF-DAG: "Swift"
|
||||
// DWARF-DAG: "basic"
|
||||
// DWARF: DW_AT_name {{.*}}"Swift"
|
||||
// DWARF: DW_AT_LLVM_include_path
|
||||
// DWARF: DW_AT_LLVM_isysroot
|
||||
// DWARF: DW_TAG_module
|
||||
// DWARF: DW_AT_name {{.*}}"Foo"
|
||||
// DWARF: DW_AT_LLVM_include_path
|
||||
// DWARF: DW_AT_LLVM_isysroot
|
||||
// DWARF: DW_TAG_module
|
||||
// DWARF: DW_AT_name {{.*}}"basic"
|
||||
|
||||
// DWARF-NOT: "Swift.Optional"
|
||||
|
||||
// DWARF-DAG: file_names{{.*}} Imports.swift
|
||||
// DWARF-DAG: file_names{{.*}} Swift.swiftmodule
|
||||
// DWARF-DAG: file_names{{.*}} basic.swift
|
||||
|
||||
@@ -65,14 +65,9 @@ func foo(var a: Int64, var _ b: Int64) -> Int64 {
|
||||
// Function type for foo.
|
||||
// CHECK-DAG: ![[FOOTYPE]] = !DISubroutineType(types: ![[PARAMTYPES:[0-9]+]])
|
||||
// CHECK-DAG: ![[PARAMTYPES]] = !{!"_TtVSs5Int64", !"_TtVSs5Int64", !"_TtVSs5Int64"}
|
||||
// Import of the main module.
|
||||
// Import of the main module with the implicit name.
|
||||
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[MAINFILE]], entity: ![[MAINMODULE:[0-9]+]], line: 1)
|
||||
// CHECK-DAG: ![[MAINMODULE]] = !MDModule(name: "basic"
|
||||
|
||||
// Import of the swift standard library.
|
||||
// CHECK-DAG: ![[SWIFTFILE:[0-9]+]] = !DIFile(filename: "{{.*}}Swift.swiftmodule",
|
||||
// CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, scope: ![[SWIFTFILE]], entity: ![[SWIFTMODULE:[0-9]+]])
|
||||
// CHECK-DAG: ![[SWIFTMODULE]] = !MDModule(name: "Swift"
|
||||
// CHECK-DAG: ![[MAINMODULE]] = !DIModule({{.*}}, name: "basic"
|
||||
|
||||
// DWARF Version
|
||||
// CHECK-DAG: i32 2, !"Dwarf Version", i32 3}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Protocol",
|
||||
// CHECK-SAME: scope: ![[ObjectiveC:[0-9]+]]
|
||||
// CHECK-SAME: identifier: "_TtCSo8Protocol"
|
||||
// CHECK: ![[ObjectiveC]] = !MDModule(name: "ObjectiveC"
|
||||
// CHECK: ![[ObjectiveC]] = !DIModule({{.*}}, name: "ObjectiveC"
|
||||
import Foundation
|
||||
|
||||
public func f() {
|
||||
|
||||
@@ -37,10 +37,8 @@ class MyObject : NSObject {
|
||||
// LOC-CHECK: ret
|
||||
var MyArr = NSArray()
|
||||
// IMPORT-CHECK: filename: "test-foundation.swift"
|
||||
// IMPORT-CHECK: !MDModule(name: "ObjectiveC"
|
||||
// IMPORT-CHECK: [[FOUNDATION:[0-9]+]] = !MDModule(name: "Foundation",
|
||||
// IMPORT-CHECK-SAME: {{.*}}file: ![[FOUNDATION_FILE:[0-9]+]]
|
||||
// IMPORT-CHECK: ![[FOUNDATION_FILE]] = !DIFile(filename: "Foundation-{{.*}}.pcm"
|
||||
// IMPORT-CHECK: [[FOUNDATION:[0-9]+]] = !DIModule({{.*}} name: "Foundation",
|
||||
// IMPORT-CHECK-SAME: {{.*}} includePath:
|
||||
// IMPORT-CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "NSArray",
|
||||
// IMPORT-CHECK-SAME: scope: ![[FOUNDATION]]
|
||||
// IMPORT-CHECK: !DIImportedEntity(tag: DW_TAG_imported_module, {{.*}}entity: ![[FOUNDATION]]
|
||||
|
||||
@@ -6,7 +6,7 @@ markUsed(a)
|
||||
// Verify that global variables are emitted once in main, once as
|
||||
// global variable.
|
||||
// CHECK: ![[MAIN:.*]] = !DISubprogram(name: "main",{{.*}} line: 1
|
||||
// CHECK: ![[MOD:.*]] = !MDModule(name: "top_level_var"
|
||||
// CHECK: ![[MOD:.*]] = !DIModule({{.*}}, name: "top_level_var"
|
||||
// CHECK: !DIGlobalVariable(name: "a",
|
||||
// CHECK-SAME: scope: ![[MOD]]
|
||||
// CHECK-SAME: isDefinition: true
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// Test variables-interpreter.swift runs this code with `swift -g -i`.
|
||||
// Test variables-repl.swift runs this code with `swift -g < variables.swift`.
|
||||
|
||||
// CHECK-DAG: ![[TLC:.*]] = !MDModule(name: "variables"
|
||||
// CHECK-DAG: ![[TLC:.*]] = !DIModule({{.*}}, name: "variables"
|
||||
|
||||
// Global variables.
|
||||
var glob_i8: Int8 = 8;
|
||||
|
||||
Reference in New Issue
Block a user