diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index c2061206ebb..41579586d98 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -87,6 +87,7 @@ namespace llvm { bool isSubprogram() const; bool isGlobalVariable() const; bool isScope() const; + bool isFile() const; bool isCompileUnit() const; bool isNameSpace() const; bool isLexicalBlock() const; @@ -158,6 +159,18 @@ namespace llvm { void dump() const; }; + /// DIFile - This is a wrapper for a file. + class DIFile : public DIScope { + public: + explicit DIFile(MDNode *N = 0) : DIScope(N) { + if (DbgNode && !isFile()) + DbgNode = 0; + } + StringRef getFilename() const { return getStringField(1); } + StringRef getDirectory() const { return getStringField(2); } + DICompileUnit getCompileUnit() const{ return getFieldAs(3); } + }; + /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). /// FIXME: it seems strange that this doesn't have either a reference to the /// type/precision or a file/line pair for location info. @@ -502,6 +515,9 @@ namespace llvm { StringRef Flags = "", unsigned RunTimeVer = 0); + /// CreateFile - Create a new descriptor for the specified file. + DIFile CreateFile(StringRef Filename, StringRef Directory, DICompileUnit CU); + /// CreateEnumerator - Create a single enumerator value. DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val); diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 4ea1ce94b16..49b2e6b2c54 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -219,6 +219,11 @@ bool DIDescriptor::isCompileUnit() const { return DbgNode && getTag() == dwarf::DW_TAG_compile_unit; } +/// isFile - Return true if the specified tag is DW_TAG_file_type. +bool DIDescriptor::isFile() const { + return DbgNode && getTag() == dwarf::DW_TAG_file_type; +} + /// isNameSpace - Return true if the specified tag is DW_TAG_namespace. bool DIDescriptor::isNameSpace() const { return DbgNode && getTag() == dwarf::DW_TAG_namespace; @@ -424,6 +429,8 @@ StringRef DIScope::getFilename() const { return DINameSpace(DbgNode).getFilename(); if (isType()) return DIType(DbgNode).getFilename(); + if (isFile()) + return DIFile(DbgNode).getFilename(); assert(0 && "Invalid DIScope!"); return StringRef(); } @@ -441,6 +448,8 @@ StringRef DIScope::getDirectory() const { return DINameSpace(DbgNode).getDirectory(); if (isType()) return DIType(DbgNode).getDirectory(); + if (isFile()) + return DIFile(DbgNode).getDirectory(); assert(0 && "Invalid DIScope!"); return StringRef(); } @@ -661,6 +670,20 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID, return DICompileUnit(MDNode::get(VMContext, &Elts[0], 10)); } +/// CreateFile - Create a new descriptor for the specified file. +DIFile DIFactory::CreateFile(StringRef Filename, + StringRef Directory, + DICompileUnit CU) { + Value *Elts[] = { + GetTagConstant(dwarf::DW_TAG_file_type), + MDString::get(VMContext, Filename), + MDString::get(VMContext, Directory), + CU.getNode() + }; + + return DIFile(MDNode::get(VMContext, &Elts[0], 4)); +} + /// CreateEnumerator - Create a single enumerator value. DIEnumerator DIFactory::CreateEnumerator(StringRef Name, uint64_t Val){ Value *Elts[] = {