/// BSS - Zero initialized writeable data.
BSS,
+
+ /// Common - Data with common linkage. These represent tentative
+ /// definitions, which always have a zero initializer and are never
+ /// marked 'constant'.
+ Common,
/// DataRel - This is the most general form of data that is written
/// to by the program, it can have random relocations to arbitrary
bool isThreadData() const { return K == ThreadData; }
bool isGlobalWriteableData() const {
- return isBSS() || isDataRel() || isReadOnlyWithRel();
+ return isBSS() || isCommon() || isDataRel() || isReadOnlyWithRel();
}
bool isBSS() const { return K == BSS; }
+ bool isCommon() const { return K == Common; }
bool isDataRel() const {
return K == DataRel || K == DataRelLocal || K == DataNoRel;
static SectionKind getThreadBSS() { return get(ThreadBSS); }
static SectionKind getThreadData() { return get(ThreadData); }
static SectionKind getBSS() { return get(BSS); }
+ static SectionKind getCommon() { return get(Common); }
static SectionKind getDataRel() { return get(DataRel); }
static SectionKind getDataRelLocal() { return get(DataRelLocal); }
static SectionKind getDataNoRel() { return get(DataNoRel); }
O << "\t.type " << *GVarSym << ",%object\n";
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
+
+ // Handle normal common symbols.
+ if (GVKind.isCommon()) {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ O << ".comm " << *GVarSym << ',' << Size;
+ if (MAI->getCOMMDirectiveTakesAlignment())
+ O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+
+ if (VerboseAsm) {
+ O << "\t\t" << MAI->getCommentString() << " '";
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+ O << '\'';
+ }
+ O << '\n';
+ return;
+ }
+
const MCSection *TheSection =
getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
-
+
// Handle the zerofill directive on darwin, which is a special form of BSS
// emission.
if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
}
}
+ OutStreamer.SwitchSection(TheSection);
+
// FIXME: get this stuff from section kind flags.
if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
// Don't put things that should go in the cstring section into "comm".
unsigned Size = TD->getTypeAllocSize(Type);
unsigned Align = TD->getPreferredAlignmentLog(GVar);
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
+ SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
+
+ // Handle normal common symbols.
+ if (GVKind.isCommon()) {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ O << ".comm " << *GVarSym << ',' << Size;
+ if (MAI->getCOMMDirectiveTakesAlignment())
+ O << ',' << Align;
+
+ if (VerboseAsm) {
+ O << "\t\t" << MAI->getCommentString() << " '";
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+ O << '\'';
+ }
+ O << '\n';
+ return;
+ }
+
+ OutStreamer.SwitchSection(getObjFileLowering().
+ SectionForGlobal(GVar, GVKind, Mang, TM));
if (C->isNullValue() && /* FIXME: Verify correct */
!GVar->hasSection() &&
unsigned Align = TD->getPreferredAlignmentLog(GVar);
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
+
+ // Handle normal common symbols.
+ if (GVKind.isCommon()) {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ O << ".comm " << *GVarSym << ',' << Size;
+ if (MAI->getCOMMDirectiveTakesAlignment())
+ O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+
+ if (VerboseAsm) {
+ O << "\t\t" << MAI->getCommentString() << " '";
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+ O << '\'';
+ }
+ O << '\n';
+ return;
+ }
+
const MCSection *TheSection =
getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
-
+
// Handle the zerofill directive on darwin, which is a special form of BSS
// emission.
if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
}
}
+ OutStreamer.SwitchSection(TheSection);
+
/// FIXME: Drive this off the section!
if (C->isNullValue() && /* FIXME: Verify correct */
!GVar->hasSection() &&
if (GVar->hasLocalLinkage()) {
O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size << ',' << Align;
- } else if (!GVar->hasCommonLinkage()) {
+
+ if (VerboseAsm) {
+ O << "\t\t" << MAI->getCommentString() << " '";
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+ O << "'";
+ }
+ O << '\n';
+ } else {
O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective();
O << *GVarSym << '\n';
EmitAlignment(Align, GVar);
}
O << '\n';
EmitGlobalConstant(C);
- return;
- } else {
- O << ".comm " << *GVarSym << ',' << Size;
- // Darwin 9 and above support aligned common data.
- if (Subtarget.isDarwin9())
- O << ',' << Align;
}
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
return;
}
if (C->isNullValue() && !GVar->hasSection() &&
!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
+ (GVar->hasLocalLinkage() || GVar->hasCommonLinkage())) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
return SectionKind::getThreadData();
}
+ // Variables with common linkage always get classified as common.
+ if (GVar->hasCommonLinkage())
+ return SectionKind::getCommon();
+
// Variable can be easily put to BSS section.
if (isSuitableForBSS(GVar))
return SectionKind::getBSS();
// If this global is linkonce/weak and the target handles this by emitting it
// into a 'uniqued' section name, create and return the section now.
- if (GV->isWeakForLinker()) {
+ if (GV->isWeakForLinker() && !Kind.isCommon()) {
const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
SmallString<128> Name;
Name.append(Prefix, Prefix+strlen(Prefix));
if (Kind.isThreadData()) return TLSDataSection;
if (Kind.isThreadBSS()) return TLSBSSSection;
- if (Kind.isBSS()) return BSSSection;
+ if (Kind.isBSS() || Kind.isCommon()) return BSSSection;
if (Kind.isDataNoRel()) return DataSection;
if (Kind.isDataRelLocal()) return DataRelLocalSection;
O << "\t.type\t" << *GVarSym << ",@object\n";
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
+
+ // Handle normal common symbols.
+ if (GVKind.isCommon()) {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ O << ".comm " << *GVarSym << ',' << Size;
+ if (MAI->getCOMMDirectiveTakesAlignment())
+ O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+
+ if (VerboseAsm) {
+ O << "\t\t" << MAI->getCommentString() << " '";
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+ O << '\'';
+ }
+ O << '\n';
+ return;
+ }
+
const MCSection *TheSection =
getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
// Handle the zerofill directive on darwin, which is a special form of BSS
// emission.
return;
}
}
+
+ OutStreamer.SwitchSection(TheSection);
// FIXME: get this stuff from section kind flags.
if (C->isNullValue() && !GVar->hasSection() &&
O << LComm << *GVarSym << ',' << Size;
if (Subtarget->isTargetDarwin())
O << ',' << Align;
- } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) {
+ } else if (Subtarget->isTargetDarwin()) {
OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
O << MAI->getWeakDefDirective() << *GVarSym << '\n';
EmitAlignment(Align, GVar);