Each input file is encoded as a separate compile unit in LLVM debugging
authorDevang Patel <dpatel@apple.com>
Fri, 30 Jan 2009 18:20:31 +0000 (18:20 +0000)
committerDevang Patel <dpatel@apple.com>
Fri, 30 Jan 2009 18:20:31 +0000 (18:20 +0000)
information output. However, many target specific tool chains prefer to encode
only one compile unit in an object file. In this situation, the LLVM code
generator will include  debugging information entities in the compile unit
that is marked as main compile unit. The code generator accepts maximum one main
compile unit per module. If a module does not contain any main compile unit
then the code generator will emit multiple compile units in the output object
file.

[Part 1]

Update DebugInfo APIs to accept optional boolean value while creating DICompileUnit  to mark the unit as "main" unit. By defaults all units are considered  non-main.  Update SourceLevelDebugging.html to document "main" compile unit.

Update DebugInfo APIs to not accept and encode separate source file/directory entries while creating various llvm.dbg.* entities. There was a recent, yet to be documented, change to include this additional information so no documentation changes are required here.

Update DwarfDebug to handle "main" compile unit. If "main" compile unit is seen then all DIEs are inserted into "main" compile unit. All other compile units are used to find source location for llvm.dbg.* values. If there is not any "main" compile unit then create unique compile unit DIEs for each llvm.dbg.compile_unit.

[Part 2]

Create separate llvm.dbg.compile_unit for each input file. Mark compile unit create for main_input_filename as "main" compile unit. Use appropriate compile unit, based on source location information collected from the tree node, while creating llvm.dbg.* values using DebugInfo APIs.

---

This is Part 1.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63400 91177308-0d34-0410-b5e6-96231b3b80d8

docs/SourceLevelDebugging.html
include/llvm/Analysis/DebugInfo.h
lib/Analysis/DebugInfo.cpp
lib/CodeGen/AsmPrinter/DwarfWriter.cpp
test/DebugInfo/2009-01-29-HeaderLocation.ll [new file with mode: 0644]

index 4a55a1c1a2ad781f445ce5e9cf9d9fc44fdcb17a..263f40c6ebc08f5ae92ec11f03c4b57fe9e39af7 100644 (file)
@@ -378,6 +378,7 @@ deleted.</p>
     sbyte*, ;; Source file name
     sbyte*, ;; Source file directory (includes trailing slash)
     sbyte*  ;; Producer (ex. "4.0.1 LLVM (LLVM research group)")
+    bool    ;; True if this is a main compile unit. 
   }
 </pre>
 
@@ -392,6 +393,14 @@ specific source file.  Global variables and top level functions would be defined
 using this context.  Compile unit descriptors also provide context for source
 line correspondence.</p>  
 
+<p> Each input file is encoded as a separate compile unit in LLVM debugging
+information output. However, many target specific tool chains prefer to encode
+only one compile unit in an object file. In this situation, the LLVM code
+generator will include  debugging information entities in the compile unit 
+that is marked as main compile unit. The code generator accepts maximum one main
+compile unit per module. If a module does not contain any main compile unit 
+then the code generator will emit multiple compile units in the output object 
+file.
 </div>
 
 <!-- ======================================================================= -->
index 310c1acf08fa2bdd2338de2c026c52a78b81a80f..5113d5f77370c97b2ff98994366e4537ec6d2e07 100644 (file)
@@ -109,8 +109,18 @@ namespace llvm {
     std::string getFilename() const  { return getStringField(3); }
     std::string getDirectory() const { return getStringField(4); }
     std::string getProducer() const  { return getStringField(5); }
-    bool isOptimized() const         { return getUnsignedField(6); }
-    std::string getFlags() const     { return getStringField(7); }
+    
+    /// isMain - Each input file is encoded as a separate compile unit in LLVM
+    /// debugging information output. However, many target specific tool chains
+    /// prefer to encode only one compile unit in an object file. In this 
+    /// situation, the LLVM code generator will include  debugging information
+    /// entities in the compile unit that is marked as main compile unit. The 
+    /// code generator accepts maximum one main compile unit per module. If a
+    /// module does not contain any main compile unit then the code generator 
+    /// will emit multiple compile units in the output object file.
+    bool isMain() const             { return getUnsignedField(6); }
+    bool isOptimized() const         { return getUnsignedField(7); }
+    std::string getFlags() const     { return getStringField(8); }
 
     /// Verify - Verify that a compile unit is well formed.
     bool Verify() const;
@@ -183,16 +193,6 @@ namespace llvm {
     bool isProtected() const            { return (getFlags() & FlagProtected) != 0; }
     bool isForwardDecl() const          { return (getFlags() & FlagFwdDecl) != 0; }
 
-    virtual std::string getFilename() const { 
-      assert (0 && "Invalid DIDescriptor");
-      return "";
-    }
-
-    virtual std::string getDirectory() const { 
-      assert (0 && "Invalid DIDescriptor");
-      return "";
-    }
-
     /// dump - print type.
     void dump() const;
   };
@@ -201,10 +201,7 @@ namespace llvm {
   class DIBasicType : public DIType {
   public:
     explicit DIBasicType(GlobalVariable *GV);
-
     unsigned getEncoding() const { return getUnsignedField(9); }
-    std::string getFilename() const { return getStringField(10); }
-    std::string getDirectory() const { return getStringField(11); }
 
     /// dump - print basic type.
     void dump() const;
@@ -218,10 +215,7 @@ namespace llvm {
       : DIType(GV, true, true) {}
   public:
     explicit DIDerivedType(GlobalVariable *GV);
-
     DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
-    std::string getFilename() const { return getStringField(10); }
-    std::string getDirectory() const { return getStringField(11); }
 
     /// dump - print derived type.
     void dump() const;
@@ -233,10 +227,7 @@ namespace llvm {
   class DICompositeType : public DIDerivedType {
   public:
     explicit DICompositeType(GlobalVariable *GV);
-
     DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
-    std::string getFilename() const { return getStringField(11); }
-    std::string getDirectory() const { return getStringField(12); }
 
     /// Verify - Verify that a composite type descriptor is well formed.
     bool Verify() const;
@@ -279,16 +270,6 @@ namespace llvm {
     unsigned isLocalToUnit() const      { return getUnsignedField(9); }
     unsigned isDefinition() const       { return getUnsignedField(10); }
 
-    virtual std::string getFilename() const { 
-      assert (0 && "Invalid DIDescriptor");
-      return "";
-    }
-
-    virtual std::string getDirectory() const { 
-      assert (0 && "Invalid DIDescriptor");
-      return "";
-    }
-    
     /// dump - print global.
     void dump() const;
   };
@@ -297,8 +278,6 @@ namespace llvm {
   class DISubprogram : public DIGlobal {
   public:
     explicit DISubprogram(GlobalVariable *GV = 0);
-    std::string getFilename() const { return getStringField(11); }
-    std::string getDirectory() const { return getStringField(12); }
     DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
 
     /// Verify - Verify that a subprogram descriptor is well formed.
@@ -312,10 +291,7 @@ namespace llvm {
   class DIGlobalVariable : public DIGlobal {
   public:
     explicit DIGlobalVariable(GlobalVariable *GV = 0);
-
     GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
-    std::string getFilename() const { return getStringField(12); }
-    std::string getDirectory() const { return getStringField(13); }
 
     /// Verify - Verify that a global variable descriptor is well formed.
     bool Verify() const;
@@ -335,8 +311,6 @@ namespace llvm {
     DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
     unsigned getLineNumber() const      { return getUnsignedField(4); }
     DIType getType() const              { return getFieldAs<DIType>(5); }
-    std::string getFilename() const { return getStringField(6); }
-    std::string getDirectory() const { return getStringField(7); }
 
     /// isVariable - Return true if the specified tag is legal for DIVariable.
     static bool isVariable(unsigned Tag);
@@ -402,6 +376,7 @@ namespace llvm {
                                     const std::string &Filename,
                                     const std::string &Directory,
                                     const std::string &Producer,
+                                    bool isMain = false,
                                     bool isOptimized = false,
                                     const char *Flags = "");
 
@@ -413,9 +388,7 @@ namespace llvm {
                                 DICompileUnit CompileUnit, unsigned LineNumber,
                                 uint64_t SizeInBits, uint64_t AlignInBits,
                                 uint64_t OffsetInBits, unsigned Flags,
-                                unsigned Encoding,
-                                const std::string *FileName = 0,
-                                const std::string *Directory = 0);
+                                unsigned Encoding);
 
     /// CreateDerivedType - Create a derived type like const qualified type,
     /// pointer, typedef, etc.
@@ -425,9 +398,7 @@ namespace llvm {
                                     unsigned LineNumber,
                                     uint64_t SizeInBits, uint64_t AlignInBits,
                                     uint64_t OffsetInBits, unsigned Flags,
-                                    DIType DerivedFrom,
-                                    const std::string *FileName = 0,
-                                    const std::string *Directory = 0);
+                                    DIType DerivedFrom);
 
     /// CreateCompositeType - Create a composite type like array, struct, etc.
     DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
@@ -438,9 +409,7 @@ namespace llvm {
                                         uint64_t AlignInBits,
                                         uint64_t OffsetInBits, unsigned Flags,
                                         DIType DerivedFrom,
-                                        DIArray Elements,
-                                        const std::string *FileName = 0,
-                                        const std::string *Directory = 0);
+                                        DIArray Elements);
 
     /// CreateSubprogram - Create a new descriptor for the specified subprogram.
     /// See comments in DISubprogram for descriptions of these fields.
@@ -449,9 +418,7 @@ namespace llvm {
                                   const std::string &LinkageName,
                                   DICompileUnit CompileUnit, unsigned LineNo,
                                   DIType Type, bool isLocalToUnit,
-                                  bool isDefinition,
-                                  const std::string *FileName = 0,
-                                  const std::string *Directory = 0);
+                                  bool isDefinition);
 
     /// CreateGlobalVariable - Create a new descriptor for the specified global.
     DIGlobalVariable
@@ -460,17 +427,13 @@ namespace llvm {
                          const std::string &LinkageName, 
                          DICompileUnit CompileUnit,
                          unsigned LineNo, DIType Type, bool isLocalToUnit,
-                         bool isDefinition, llvm::GlobalVariable *GV,
-                         const std::string *FileName = 0,
-                         const std::string *Directory = 0);
+                         bool isDefinition, llvm::GlobalVariable *GV);
 
     /// CreateVariable - Create a new descriptor for the specified variable.
     DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
                               const std::string &Name,
                               DICompileUnit CompileUnit, unsigned LineNo,
-                              DIType Type,
-                              const std::string *FileName = 0,
-                              const std::string *Directory = 0);
+                              DIType Type);
 
     /// CreateBlock - This creates a descriptor for a lexical block with the
     /// specified parent context.
index e5bbbd5aab09fdcb155061a44606a7aad1f6f72e..0ec80894f11cd14bba3e41b606a2f705d99e1aab 100644 (file)
@@ -442,6 +442,7 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
                                            const std::string &Filename,
                                            const std::string &Directory,
                                            const std::string &Producer,
+                                           bool isMain,
                                            bool isOptimized,
                                            const char *Flags) {
   Constant *Elts[] = {
@@ -451,6 +452,7 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
     GetStringConstant(Filename),
     GetStringConstant(Directory),
     GetStringConstant(Producer),
+    ConstantInt::get(Type::Int1Ty, isMain),
     ConstantInt::get(Type::Int1Ty, isOptimized),
     GetStringConstant(Flags)
   };
@@ -492,9 +494,7 @@ DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
                                        uint64_t SizeInBits,
                                        uint64_t AlignInBits,
                                        uint64_t OffsetInBits, unsigned Flags,
-                                       unsigned Encoding,
-                                       const std::string *FileName,
-                                       const std::string *Directory) {
+                                       unsigned Encoding) {
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_base_type),
     getCastToEmpty(Context),
@@ -505,9 +505,7 @@ DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
     ConstantInt::get(Type::Int64Ty, AlignInBits),
     ConstantInt::get(Type::Int64Ty, OffsetInBits),
     ConstantInt::get(Type::Int32Ty, Flags),
-    ConstantInt::get(Type::Int32Ty, Encoding),
-    GetStringConstant(FileName ? FileName->c_str() : ""),
-    GetStringConstant(Directory ? Directory->c_str() : "")
+    ConstantInt::get(Type::Int32Ty, Encoding)
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -531,9 +529,7 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
                                            uint64_t AlignInBits,
                                            uint64_t OffsetInBits,
                                            unsigned Flags,
-                                           DIType DerivedFrom,
-                                           const std::string *FileName,
-                                           const std::string *Directory) {
+                                           DIType DerivedFrom) {
   Constant *Elts[] = {
     GetTagConstant(Tag),
     getCastToEmpty(Context),
@@ -544,9 +540,7 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
     ConstantInt::get(Type::Int64Ty, AlignInBits),
     ConstantInt::get(Type::Int64Ty, OffsetInBits),
     ConstantInt::get(Type::Int32Ty, Flags),
-    getCastToEmpty(DerivedFrom),
-    GetStringConstant(FileName ? FileName->c_str() : ""),
-    GetStringConstant(Directory ? Directory->c_str() : "")
+    getCastToEmpty(DerivedFrom)
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -570,9 +564,7 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
                                                uint64_t OffsetInBits,
                                                unsigned Flags,
                                                DIType DerivedFrom,
-                                               DIArray Elements,
-                                               const std::string *FileName,
-                                               const std::string *Directory) {
+                                               DIArray Elements) {
 
   Constant *Elts[] = {
     GetTagConstant(Tag),
@@ -585,9 +577,7 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
     ConstantInt::get(Type::Int64Ty, OffsetInBits),
     ConstantInt::get(Type::Int32Ty, Flags),
     getCastToEmpty(DerivedFrom),
-    getCastToEmpty(Elements),
-    GetStringConstant(FileName ? FileName->c_str() : ""),
-    GetStringConstant(Directory ? Directory->c_str() : "")
+    getCastToEmpty(Elements)
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -611,9 +601,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
                                          DICompileUnit CompileUnit,
                                          unsigned LineNo, DIType Type,
                                          bool isLocalToUnit,
-                                         bool isDefinition,
-                                         const std::string *FileName,
-                                         const std::string *Directory) {
+                                         bool isDefinition) {
 
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_subprogram),
@@ -626,9 +614,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
     ConstantInt::get(Type::Int32Ty, LineNo),
     getCastToEmpty(Type),
     ConstantInt::get(Type::Int1Ty, isLocalToUnit),
-    ConstantInt::get(Type::Int1Ty, isDefinition),
-    GetStringConstant(FileName ? FileName->c_str() : ""),
-    GetStringConstant(Directory ? Directory->c_str() : "")
+    ConstantInt::get(Type::Int1Ty, isDefinition)
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -648,9 +634,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
                                 const std::string &LinkageName,
                                 DICompileUnit CompileUnit,
                                 unsigned LineNo, DIType Type,bool isLocalToUnit,
-                                bool isDefinition, llvm::GlobalVariable *Val,
-                                const std::string *FileName,
-                                const std::string *Directory) {
+                                bool isDefinition, llvm::GlobalVariable *Val) {
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_variable),
     getCastToEmpty(GetOrCreateGlobalVariableAnchor()),
@@ -663,9 +647,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
     getCastToEmpty(Type),
     ConstantInt::get(Type::Int1Ty, isLocalToUnit),
     ConstantInt::get(Type::Int1Ty, isDefinition),
-    ConstantExpr::getBitCast(Val, EmptyStructPtr),
-    GetStringConstant(FileName ? FileName->c_str() : ""),
-    GetStringConstant(Directory ? Directory->c_str() : "")
+    ConstantExpr::getBitCast(Val, EmptyStructPtr)
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -683,20 +665,14 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
 DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
                                      const std::string &Name,
                                      DICompileUnit CompileUnit, unsigned LineNo,
-                                     DIType Type,
-                                     const std::string *FileName,
-                                     const std::string *Directory) {
-
-  
+                                     DIType Type) {
   Constant *Elts[] = {
     GetTagConstant(Tag),
     getCastToEmpty(Context),
     GetStringConstant(Name),
     getCastToEmpty(CompileUnit),
     ConstantInt::get(Type::Int32Ty, LineNo),
-    getCastToEmpty(Type),
-    GetStringConstant(FileName ? FileName->c_str() : ""),
-    GetStringConstant(Directory ? Directory->c_str() : "")
+    getCastToEmpty(Type)
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
index b2a52cabe0e719bff4238195ca3c00f540537604..95990cfe6718fa7319beb615520e6e9e26e6610a 100644 (file)
@@ -1274,6 +1274,9 @@ private:
   /// of each entry in this vector corresponds to the sources in MMI.
   DenseMap<Value *, CompileUnit *> DW_CUs;
 
+  /// MainCU - Some platform prefers one compile unit per .o file. In such
+  /// cases, all dies are inserted in MainCU.
+  CompileUnit *MainCU;
   /// AbbreviationsSet - Used to uniquely define abbreviations.
   ///
   FoldingSet<DIEAbbrev> AbbreviationsSet;
@@ -1559,16 +1562,8 @@ private:
   void AddSourceLine(DIE *Die, const DIVariable *V) {
     unsigned FileID = 0;
     unsigned Line = V->getLineNumber();
-    if (V->getVersion() <= LLVMDebugVersion6) {
-      // Version6 or earlier. Use compile unit info to get file id.
-      CompileUnit *Unit = FindCompileUnit(V->getCompileUnit());
-      FileID = Unit->getID();
-    } else {
-      // Version7 or newer, use filename and directory info from DIVariable
-      // directly.
-      unsigned DID = Directories.idFor(V->getDirectory());
-      FileID = SrcFiles.idFor(SrcFileInfo(DID, V->getFilename()));
-    }
+    CompileUnit *Unit = FindCompileUnit(V->getCompileUnit());
+    FileID = Unit->getID();
     AddUInt(Die, DW_AT_decl_file, 0, FileID);
     AddUInt(Die, DW_AT_decl_line, 0, Line);
   }
@@ -1578,16 +1573,8 @@ private:
   void AddSourceLine(DIE *Die, const DIGlobal *G) {
     unsigned FileID = 0;
     unsigned Line = G->getLineNumber();
-    if (G->getVersion() <= LLVMDebugVersion6) {
-      // Version6 or earlier. Use compile unit info to get file id.
-      CompileUnit *Unit = FindCompileUnit(G->getCompileUnit());
-      FileID = Unit->getID();
-    } else {
-      // Version7 or newer, use filename and directory info from DIGlobal
-      // directly.
-      unsigned DID = Directories.idFor(G->getDirectory());
-      FileID = SrcFiles.idFor(SrcFileInfo(DID, G->getFilename()));
-    }
+    CompileUnit *Unit = FindCompileUnit(G->getCompileUnit());
+    FileID = Unit->getID();
     AddUInt(Die, DW_AT_decl_file, 0, FileID);
     AddUInt(Die, DW_AT_decl_line, 0, Line);
   }
@@ -1595,16 +1582,11 @@ private:
   void AddSourceLine(DIE *Die, const DIType *Ty) {
     unsigned FileID = 0;
     unsigned Line = Ty->getLineNumber();
-    if (Ty->getVersion() <= LLVMDebugVersion6) {
-      // Version6 or earlier. Use compile unit info to get file id.
-      CompileUnit *Unit = FindCompileUnit(Ty->getCompileUnit());
-      FileID = Unit->getID();
-    } else {
-      // Version7 or newer, use filename and directory info from DIType
-      // directly.
-      unsigned DID = Directories.idFor(Ty->getDirectory());
-      FileID = SrcFiles.idFor(SrcFileInfo(DID, Ty->getFilename()));
-    }
+    DICompileUnit CU = Ty->getCompileUnit();
+    if (CU.isNull())
+      return;
+    CompileUnit *Unit = FindCompileUnit(CU);
+    FileID = Unit->getID();
     AddUInt(Die, DW_AT_decl_file, 0, FileID);
     AddUInt(Die, DW_AT_decl_line, 0, Line);
   }
@@ -2091,7 +2073,9 @@ private:
     DISubprogram SPD(Desc.getGV());
 
     // Get the compile unit context.
-    CompileUnit *Unit = FindCompileUnit(SPD.getCompileUnit());
+    CompileUnit *Unit = MainCU;
+    if (!Unit)
+      Unit = FindCompileUnit(SPD.getCompileUnit());
 
     // Get the subprogram die.
     DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV());
@@ -2122,7 +2106,9 @@ private:
 
       if (SPD.getName() == MF->getFunction()->getName()) {
         // Get the compile unit context.
-        CompileUnit *Unit = FindCompileUnit(SPD.getCompileUnit());
+        CompileUnit *Unit = MainCU;
+        if (!Unit)
+          Unit = FindCompileUnit(SPD.getCompileUnit());
 
         // Get the subprogram die.
         DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV());
@@ -2294,6 +2280,15 @@ private:
   ///
   void SizeAndOffsets() {
     // Process base compile unit.
+    if (MainCU) {
+      // Compute size of compile unit header
+      unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info
+        sizeof(int16_t) + // DWARF version number
+        sizeof(int32_t) + // Offset Into Abbrev. Section
+        sizeof(int8_t);   // Pointer Size (in bytes)
+      SizeAndOffsetDie(MainCU->getDie(), Offset, true);
+      return;
+    }
     for (DenseMap<Value *, CompileUnit *>::iterator CI = DW_CUs.begin(),
            CE = DW_CUs.end(); CI != CE; ++CI) {
       CompileUnit *Unit = CI->second;
@@ -2315,6 +2310,8 @@ private:
     for (DenseMap<Value *, CompileUnit *>::iterator CI = DW_CUs.begin(),
            CE = DW_CUs.end(); CI != CE; ++CI) {
       CompileUnit *Unit = CI->second;
+      if (MainCU)
+        Unit = MainCU;
       DIE *Die = Unit->getDie();
       // Emit the compile units header.
       EmitLabel("info_begin", Unit->getID());
@@ -2340,6 +2337,8 @@ private:
       EmitLabel("info_end", Unit->getID());
       
       Asm->EOL();
+      if (MainCU)
+        return;
     }
   }
 
@@ -2639,6 +2638,8 @@ private:
     for (DenseMap<Value *, CompileUnit *>::iterator CI = DW_CUs.begin(),
            CE = DW_CUs.end(); CI != CE; ++CI) {
       CompileUnit *Unit = CI->second;
+      if (MainCU)
+        Unit = MainCU;
 
       EmitDifference("pubnames_end", Unit->getID(),
                      "pubnames_begin", Unit->getID(), true);
@@ -2672,6 +2673,8 @@ private:
       EmitLabel("pubnames_end", Unit->getID());
       
       Asm->EOL();
+      if (MainCU)
+        return;
     }
   }
 
@@ -2789,6 +2792,10 @@ private:
         AddString(Die, DW_AT_APPLE_flags, DW_FORM_string, Flags);
 
       CompileUnit *Unit = new CompileUnit(ID, Die);
+      if (DIUnit.isMain()) {
+        assert (!MainCU && "Multiple main compile units are found!");
+        MainCU = Unit;
+      }
       DW_CUs[DIUnit.getGV()] = Unit;
     }
   }
@@ -2802,7 +2809,9 @@ private:
     for (std::vector<GlobalVariable *>::iterator GVI = Result.begin(),
            GVE = Result.end(); GVI != GVE; ++GVI) {
       DIGlobalVariable DI_GV(*GVI);
-      CompileUnit *DW_Unit = FindCompileUnit(DI_GV.getCompileUnit());
+      CompileUnit *DW_Unit = MainCU;
+      if (!DW_Unit)
+        DW_Unit = FindCompileUnit(DI_GV.getCompileUnit());
 
       // Check for pre-existence.
       DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV());
@@ -2839,7 +2848,9 @@ private:
            RE = Result.end(); RI != RE; ++RI) {
 
       DISubprogram SP(*RI);
-      CompileUnit *Unit = FindCompileUnit(SP.getCompileUnit());
+      CompileUnit *Unit = MainCU;
+      if (!Unit)
+        Unit = FindCompileUnit(SP.getCompileUnit());
 
       // Check for pre-existence.
       DIE *&Slot = Unit->getDieMapSlotFor(SP.getGV());
@@ -2862,6 +2873,7 @@ public:
   //
   DwarfDebug(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
   : Dwarf(OS, A, T, "dbg")
+  , MainCU(NULL)
   , AbbreviationsSet(InitAbbreviationsSetSize)
   , Abbreviations()
   , ValuesSet(InitValuesSetSize)
diff --git a/test/DebugInfo/2009-01-29-HeaderLocation.ll b/test/DebugInfo/2009-01-29-HeaderLocation.ll
new file mode 100644 (file)
index 0000000..c59a1c7
--- /dev/null
@@ -0,0 +1,46 @@
+; RUN: llvm-as < %s | llc | grep "m.h" | count 1
+target triple = "i386-apple-darwin9.6"
+       %llvm.dbg.anchor.type = type { i32, i32 }
+       %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
+       %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
+       %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* }
+       %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
+@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata"              ; <%llvm.dbg.anchor.type*> [#uses=1]
+@.str = internal constant [4 x i8] c"m.c\00", section "llvm.metadata"          ; <[4 x i8]*> [#uses=1]
+@.str1 = internal constant [26 x i8] c"/Volumes/Nanpura/dbg.test\00", section "llvm.metadata"          ; <[26 x i8]*> [#uses=1]
+@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build)\00", section "llvm.metadata"                ; <[52 x i8]*> [#uses=1]
+@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata"         ; <%llvm.dbg.compile_unit.type*> [#uses=1]
+@.str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata"         ; <[4 x i8]*> [#uses=1]
+@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata"               ; <%llvm.dbg.basictype.type*> [#uses=1]
+@llvm.dbg.array = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata"               ; <[1 x { }*]*> [#uses=1]
+@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata"           ; <%llvm.dbg.composite.type*> [#uses=1]
+@.str4 = internal constant [4 x i8] c"m.h\00", section "llvm.metadata"         ; <[4 x i8]*> [#uses=1]
+@llvm.dbg.compile_unit5 = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null }, section "llvm.metadata"              ; <%llvm.dbg.compile_unit.type*> [#uses=1]
+@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata"                ; <%llvm.dbg.anchor.type*> [#uses=1]
+@.str6 = internal constant [5 x i8] c"main\00", section "llvm.metadata"                ; <[5 x i8]*> [#uses=1]
+@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to { }*), i32 2, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata"             ; <%llvm.dbg.subprogram.type*> [#uses=1]
+
+define i32 @main() nounwind {
+entry:
+       %retval = alloca i32            ; <i32*> [#uses=2]
+       %0 = alloca i32         ; <i32*> [#uses=2]
+       %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+       call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
+       call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to { }*))
+       store i32 0, i32* %0, align 4
+       %1 = load i32* %0, align 4              ; <i32> [#uses=1]
+       store i32 %1, i32* %retval, align 4
+       br label %return
+
+return:                ; preds = %entry
+       %retval1 = load i32* %retval            ; <i32> [#uses=1]
+       call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to { }*))
+       call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
+       ret i32 %retval1
+}
+
+declare void @llvm.dbg.func.start({ }*) nounwind
+
+declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
+
+declare void @llvm.dbg.region.end({ }*) nounwind