It is possible that main input file does not have any symbol with debug info. To handle this edge case, always create main compile unit first.
This fixes PR 4228.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73520 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 049e716..1f17692 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -50,6 +50,24 @@
/// getOrCreateCompileUnit - Get the compile unit from the cache or create a new
/// one if necessary. This returns null for invalid source locations.
llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) {
+
+ // 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. Create main
+ // compile unit if there is not one available.
+ const LangOptions &LO = M->getLangOptions();
+ if (isMainCompileUnitCreated == false) {
+ if (LO.getMainFileName()) {
+ createCompileUnit(LO.getMainFileName(), true /* isMain */);
+ isMainCompileUnitCreated = true;
+ }
+ }
+
// Get source file information.
const char *FileName = "<unknown>";
SourceManager &SM = M->getContext().getSourceManager();
@@ -72,25 +90,26 @@
AbsFileName = tmp;
}
- // See if thie compile unit is representing main source file. Each source
- // file has corresponding compile unit. There is only one main source
- // file at a time.
- bool isMain = false;
- const LangOptions &LO = M->getLangOptions();
- const char *MainFileName = LO.getMainFileName();
- if (isMainCompileUnitCreated == false) {
- if (MainFileName) {
- if (!strcmp(AbsFileName.getLast().c_str(), MainFileName))
- isMain = true;
- } else {
- if (Loc.isValid() && SM.isFromMainFile(Loc))
- isMain = true;
- }
- if (isMain)
- isMainCompileUnitCreated = true;
+ // There is only one main source file at a time whose compile unit
+ // is already created.
+ Unit = createCompileUnit(FileName, false /* isMain */);
+ return Unit;
+}
+
+/// createCompileUnit - Create a new unit for the given file.
+llvm::DICompileUnit CGDebugInfo::createCompileUnit(const char *FileName,
+ bool isMain) {
+
+ // Get absolute path name.
+ llvm::sys::Path AbsFileName(FileName);
+ if (!AbsFileName.isAbsolute()) {
+ llvm::sys::Path tmp = llvm::sys::Path::GetCurrentDirectory();
+ tmp.appendComponent(FileName);
+ AbsFileName = tmp;
}
unsigned LangTag;
+ const LangOptions &LO = M->getLangOptions();
if (LO.CPlusPlus) {
if (LO.ObjC1)
LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
@@ -114,12 +133,13 @@
RuntimeVers = LO.ObjCNonFragileABI ? 2 : 1;
// Create new compile unit.
- return Unit = DebugFactory.CreateCompileUnit(LangTag, AbsFileName.getLast(),
- AbsFileName.getDirname(),
- Producer, isMain, isOptimized,
- Flags, RuntimeVers);
+ return DebugFactory.CreateCompileUnit(LangTag, AbsFileName.getLast(),
+ AbsFileName.getDirname(),
+ Producer, isMain, isOptimized,
+ Flags, RuntimeVers);
}
+
/// CreateType - Get the Basic type from the cache or create a new
/// one if necessary.
llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index de65580..8f3368e 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -111,7 +111,9 @@
void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
CGBuilderTy &Builder);
-
+ /// createCompileUnit - Create a new unit for the given file.
+ llvm::DICompileUnit createCompileUnit(const char *FileName, bool isMain);
+
/// getOrCreateCompileUnit - Get the compile unit from the cache or create a
/// new one if necessary.
llvm::DICompileUnit getOrCreateCompileUnit(SourceLocation Loc);
diff --git a/test/CodeGen/2009-06-16-inc_test.c b/test/CodeGen/2009-06-16-inc_test.c
new file mode 100644
index 0000000..b28f63a
--- /dev/null
+++ b/test/CodeGen/2009-06-16-inc_test.c
@@ -0,0 +1,3 @@
+// RUN: clang -c -g %s -o /dev/null
+// PR 4228
+#include "2009-06-16-test.c"
diff --git a/test/CodeGen/2009-06-16-test.c b/test/CodeGen/2009-06-16-test.c
new file mode 100644
index 0000000..4189d06
--- /dev/null
+++ b/test/CodeGen/2009-06-16-test.c
@@ -0,0 +1,15 @@
+
+#ifndef TEST
+#define TEST
+#define INSIDE_RECURSION
+#include "2009-06-16-test.c"
+#undef INSIDE_RECURSION
+#endif
+
+#ifndef INSIDE_RECURSION
+int i;
+#endif
+
+#ifdef INSIDE_RECURSION
+int j;
+#endif