summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2014-10-16 20:52:46 +0000
committerHans Wennborg <hans@hanshq.net>2014-10-16 20:52:46 +0000
commit899ded9cdf53b3d84c8d0e771851cc256296bfd2 (patch)
tree05e0f0f099bab9d80d79172a08299e85c89d306f /clang/lib
parent933bead97d1cd46e29d347329442a3c6f7259ce7 (diff)
downloadbcm5719-llvm-899ded9cdf53b3d84c8d0e771851cc256296bfd2.tar.gz
bcm5719-llvm-899ded9cdf53b3d84c8d0e771851cc256296bfd2.zip
MS Compat: mark globals emitted in read-only sections const
They cannot be written to, so marking them const makes sense and may improve optimisation. As a side-effect, SectionInfos has to be moved from Sema to ASTContext. It also fixes this problem, that occurs when compiling ATL: warning LNK4254: section 'ATL' (C0000040) merged into '.rdata' (40000040) with different attributes The ATL headers are putting variables in a special section that's marked read-only. However, Clang currently can't model that read-onlyness in the IR. But, by making the variables const, the section does become read-only, and the linker warning is avoided. Differential Revision: http://reviews.llvm.org/D5812 llvm-svn: 219960
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp7
-rw-r--r--clang/lib/Parse/ParsePragma.cpp27
-rw-r--r--clang/lib/Sema/SemaAttr.cpp20
-rw-r--r--clang/lib/Sema/SemaDecl.cpp10
4 files changed, 37 insertions, 27 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 7d8c34d1996..78a2631a366 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1931,6 +1931,13 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor &&
isTypeConstant(D->getType(), true));
+ // If it is in a read-only section, mark it 'constant'.
+ if (const SectionAttr *SA = D->getAttr<SectionAttr>()) {
+ const ASTContext::SectionInfo &SI = Context.SectionInfos[SA->getName()];
+ if ((SI.SectionFlags & ASTContext::PSF_Write) == 0)
+ GV->setConstant(true);
+ }
+
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
// Set the llvm linkage type as appropriate.
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 7f19abf89e1..8c3fb7a5695 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "RAIIObjectsForParser.h"
+#include "clang/AST/ASTContext.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseDiagnostic.h"
@@ -539,20 +540,20 @@ bool Parser::HandlePragmaMSSection(StringRef PragmaName,
<< PragmaName;
return false;
}
- Sema::PragmaSectionFlag Flag =
- llvm::StringSwitch<Sema::PragmaSectionFlag>(
+ ASTContext::PragmaSectionFlag Flag =
+ llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
Tok.getIdentifierInfo()->getName())
- .Case("read", Sema::PSF_Read)
- .Case("write", Sema::PSF_Write)
- .Case("execute", Sema::PSF_Execute)
- .Case("shared", Sema::PSF_Invalid)
- .Case("nopage", Sema::PSF_Invalid)
- .Case("nocache", Sema::PSF_Invalid)
- .Case("discard", Sema::PSF_Invalid)
- .Case("remove", Sema::PSF_Invalid)
- .Default(Sema::PSF_None);
- if (Flag == Sema::PSF_None || Flag == Sema::PSF_Invalid) {
- PP.Diag(PragmaLocation, Flag == Sema::PSF_None
+ .Case("read", ASTContext::PSF_Read)
+ .Case("write", ASTContext::PSF_Write)
+ .Case("execute", ASTContext::PSF_Execute)
+ .Case("shared", ASTContext::PSF_Invalid)
+ .Case("nopage", ASTContext::PSF_Invalid)
+ .Case("nocache", ASTContext::PSF_Invalid)
+ .Case("discard", ASTContext::PSF_Invalid)
+ .Case("remove", ASTContext::PSF_Invalid)
+ .Default(ASTContext::PSF_None);
+ if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) {
+ PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
? diag::warn_pragma_invalid_specific_action
: diag::warn_pragma_unsupported_action)
<< PragmaName << Tok.getIdentifierInfo()->getName();
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index f92bb68d209..76297977ea0 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -363,15 +363,15 @@ void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,
bool Sema::UnifySection(StringRef SectionName,
int SectionFlags,
DeclaratorDecl *Decl) {
- auto Section = SectionInfos.find(SectionName);
- if (Section == SectionInfos.end()) {
- SectionInfos[SectionName] =
- SectionInfo(Decl, SourceLocation(), SectionFlags);
+ auto Section = Context.SectionInfos.find(SectionName);
+ if (Section == Context.SectionInfos.end()) {
+ Context.SectionInfos[SectionName] =
+ ASTContext::SectionInfo(Decl, SourceLocation(), SectionFlags);
return false;
}
// A pre-declared section takes precedence w/o diagnostic.
if (Section->second.SectionFlags == SectionFlags ||
- !(Section->second.SectionFlags & PSF_Implicit))
+ !(Section->second.SectionFlags & ASTContext::PSF_Implicit))
return false;
auto OtherDecl = Section->second.Decl;
Diag(Decl->getLocation(), diag::err_section_conflict)
@@ -390,11 +390,11 @@ bool Sema::UnifySection(StringRef SectionName,
bool Sema::UnifySection(StringRef SectionName,
int SectionFlags,
SourceLocation PragmaSectionLocation) {
- auto Section = SectionInfos.find(SectionName);
- if (Section != SectionInfos.end()) {
+ auto Section = Context.SectionInfos.find(SectionName);
+ if (Section != Context.SectionInfos.end()) {
if (Section->second.SectionFlags == SectionFlags)
return false;
- if (!(Section->second.SectionFlags & PSF_Implicit)) {
+ if (!(Section->second.SectionFlags & ASTContext::PSF_Implicit)) {
Diag(PragmaSectionLocation, diag::err_section_conflict)
<< "this" << "a prior #pragma section";
Diag(Section->second.PragmaSectionLocation,
@@ -402,8 +402,8 @@ bool Sema::UnifySection(StringRef SectionName,
return true;
}
}
- SectionInfos[SectionName] =
- SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
+ Context.SectionInfos[SectionName] =
+ ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
return false;
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 65eafd5a3c2..6f20c6a9f78 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7334,7 +7334,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
CodeSegStack.CurrentValue->getString(),
CodeSegStack.CurrentPragmaLocation));
if (UnifySection(CodeSegStack.CurrentValue->getString(),
- PSF_Implicit | PSF_Execute | PSF_Read, NewFD))
+ ASTContext::PSF_Implicit | ASTContext::PSF_Execute |
+ ASTContext::PSF_Read,
+ NewFD))
NewFD->dropAttr<SectionAttr>();
}
@@ -9403,15 +9405,15 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
if (var->isThisDeclarationADefinition() &&
ActiveTemplateInstantiations.empty()) {
PragmaStack<StringLiteral *> *Stack = nullptr;
- int SectionFlags = PSF_Implicit | PSF_Read;
+ int SectionFlags = ASTContext::PSF_Implicit | ASTContext::PSF_Read;
if (var->getType().isConstQualified())
Stack = &ConstSegStack;
else if (!var->getInit()) {
Stack = &BSSSegStack;
- SectionFlags |= PSF_Write;
+ SectionFlags |= ASTContext::PSF_Write;
} else {
Stack = &DataSegStack;
- SectionFlags |= PSF_Write;
+ SectionFlags |= ASTContext::PSF_Write;
}
if (!var->hasAttr<SectionAttr>() && Stack->CurrentValue)
var->addAttr(
OpenPOWER on IntegriCloud