add COFF support for COMDAT sections, patch by Nathan Jeffords!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103304 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index b74ed56..00e1e83 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -912,11 +912,17 @@
   unsigned Flags = 0;
 
   if (!K.isMetadata())
-    Flags |= MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE;
+    Flags |=
+      MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE;
   else if (K.isText())
     Flags |=
       MCSectionCOFF::IMAGE_SCN_MEM_EXECUTE |
       MCSectionCOFF::IMAGE_SCN_CNT_CODE;
+  else if (K.isBSS ())
+    Flags |=
+      MCSectionCOFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
+      MCSectionCOFF::IMAGE_SCN_MEM_READ |
+      MCSectionCOFF::IMAGE_SCN_MEM_WRITE;
   else if (K.isReadOnly())
     Flags |=
       MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -941,6 +947,8 @@
 static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
   if (Kind.isText())
     return ".text$linkonce";
+  if (Kind.isBSS ())
+    return ".bss$linkonce";
   if (Kind.isWriteable())
     return ".data$linkonce";
   return ".rdata$linkonce";
@@ -959,9 +967,13 @@
     SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
     MCSymbol *Sym = Mang->getSymbol(GV);
     Name.append(Sym->getName().begin(), Sym->getName().end());
-    return getContext().getCOFFSection(Name.str(),
-                                       getCOFFSectionFlags(Kind),
-                                       Kind);
+
+    unsigned Characteristics = getCOFFSectionFlags(Kind);
+
+    Characteristics |= MCSectionCOFF::IMAGE_SCN_LNK_COMDAT;
+
+    return getContext().getCOFFSection(Name.str(), Characteristics,
+                          MCSectionCOFF::IMAGE_COMDAT_SELECT_EXACT_MATCH, Kind);
   }
 
   if (Kind.isText())
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index 93388c0..5a65b8a 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -126,8 +126,10 @@
   return Result;
 }
 
-const MCSection *MCContext::
-getCOFFSection(StringRef Section, unsigned Flags, SectionKind Kind) {
+const MCSection *MCContext::getCOFFSection(StringRef Section,
+                                           unsigned Characteristics,
+                                           int Selection,
+                                           SectionKind Kind) {
   if (COFFUniquingMap == 0)
     COFFUniquingMap = new COFFUniqueMapTy();
   COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
@@ -136,8 +138,9 @@
   StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
   if (Entry.getValue()) return Entry.getValue();
   
-  MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(), Flags,
-                                                    Kind);
+  MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
+                                                    Characteristics,
+                                                    Selection, Kind);
   
   Entry.setValue(Result);
   return Result;
diff --git a/lib/MC/MCSectionCOFF.cpp b/lib/MC/MCSectionCOFF.cpp
index f26768a..d151466 100644
--- a/lib/MC/MCSectionCOFF.cpp
+++ b/lib/MC/MCSectionCOFF.cpp
@@ -43,7 +43,7 @@
     OS << 'w';
   else
     OS << 'r';
-  if (getFlags() & MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE)
+  if (getCharacteristics() & MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE)
     OS << 'n';
   OS << "\"\n";
 }