You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
4.3 KiB
162 lines
4.3 KiB
//===- MCLDAttribute.cpp --------------------------------------------------===//
|
|
//
|
|
// The MCLinker Project
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "mcld/MC/Attribute.h"
|
|
|
|
#include "mcld/MC/AttributeSet.h"
|
|
#include "mcld/Support/MsgHandling.h"
|
|
|
|
namespace mcld {
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// AttrConstraint
|
|
//===----------------------------------------------------------------------===//
|
|
bool AttrConstraint::isLegal(const Attribute& pAttr) const {
|
|
if (!isWholeArchive() && pAttr.isWholeArchive()) {
|
|
error(diag::err_unsupported_whole_archive);
|
|
return false;
|
|
}
|
|
if (!isAsNeeded() && pAttr.isAsNeeded()) {
|
|
error(diag::err_unsupported_as_needed);
|
|
return false;
|
|
}
|
|
if (!isAddNeeded() && pAttr.isAddNeeded()) {
|
|
error(diag::err_unsupported_add_needed);
|
|
return false;
|
|
}
|
|
if (isStaticSystem() && pAttr.isDynamic()) {
|
|
error(diag::err_unsupported_Bdynamic);
|
|
return false;
|
|
}
|
|
if (isStaticSystem() && pAttr.isAsNeeded()) {
|
|
warning(diag::err_enable_as_needed_on_static_system);
|
|
return true;
|
|
}
|
|
// FIXME: may be it's legal, but ignored by GNU ld.
|
|
if (pAttr.isAsNeeded() && pAttr.isStatic()) {
|
|
warning(diag::err_mix_static_as_needed);
|
|
return true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// AttributeProxy
|
|
//===----------------------------------------------------------------------===//
|
|
AttributeProxy::AttributeProxy(AttributeSet& pParent,
|
|
const Attribute& pBase,
|
|
const AttrConstraint& pConstraint)
|
|
: m_AttrPool(pParent), m_pBase(&pBase), m_Constraint(pConstraint) {
|
|
}
|
|
|
|
AttributeProxy::~AttributeProxy() {
|
|
}
|
|
|
|
bool AttributeProxy::isWholeArchive() const {
|
|
if (m_Constraint.isWholeArchive())
|
|
return m_pBase->isWholeArchive();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool AttributeProxy::isAsNeeded() const {
|
|
if (m_Constraint.isAsNeeded())
|
|
return m_pBase->isAsNeeded();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool AttributeProxy::isAddNeeded() const {
|
|
if (m_Constraint.isAddNeeded())
|
|
return m_pBase->isAddNeeded();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool AttributeProxy::isStatic() const {
|
|
if (m_Constraint.isSharedSystem())
|
|
return m_pBase->isStatic();
|
|
else
|
|
return true;
|
|
}
|
|
|
|
bool AttributeProxy::isDynamic() const {
|
|
if (m_Constraint.isSharedSystem())
|
|
return m_pBase->isDynamic();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
static inline void ReplaceOrRecord(AttributeSet& pParent,
|
|
const Attribute*& pBase,
|
|
Attribute*& pCopy) {
|
|
Attribute* result = pParent.exists(*pCopy);
|
|
if (result == NULL) { // can not find
|
|
pParent.record(*pCopy);
|
|
pBase = pCopy;
|
|
} else { // find
|
|
delete pCopy;
|
|
pBase = result;
|
|
}
|
|
}
|
|
|
|
void AttributeProxy::setWholeArchive() {
|
|
Attribute* copy = new Attribute(*m_pBase);
|
|
copy->setWholeArchive();
|
|
ReplaceOrRecord(m_AttrPool, m_pBase, copy);
|
|
}
|
|
|
|
void AttributeProxy::unsetWholeArchive() {
|
|
Attribute* copy = new Attribute(*m_pBase);
|
|
copy->unsetWholeArchive();
|
|
ReplaceOrRecord(m_AttrPool, m_pBase, copy);
|
|
}
|
|
|
|
void AttributeProxy::setAsNeeded() {
|
|
Attribute* copy = new Attribute(*m_pBase);
|
|
copy->setAsNeeded();
|
|
ReplaceOrRecord(m_AttrPool, m_pBase, copy);
|
|
}
|
|
|
|
void AttributeProxy::unsetAsNeeded() {
|
|
Attribute* copy = new Attribute(*m_pBase);
|
|
copy->unsetAsNeeded();
|
|
ReplaceOrRecord(m_AttrPool, m_pBase, copy);
|
|
}
|
|
|
|
void AttributeProxy::setAddNeeded() {
|
|
Attribute* copy = new Attribute(*m_pBase);
|
|
copy->setAddNeeded();
|
|
ReplaceOrRecord(m_AttrPool, m_pBase, copy);
|
|
}
|
|
|
|
void AttributeProxy::unsetAddNeeded() {
|
|
Attribute* copy = new Attribute(*m_pBase);
|
|
copy->unsetAddNeeded();
|
|
ReplaceOrRecord(m_AttrPool, m_pBase, copy);
|
|
}
|
|
|
|
void AttributeProxy::setStatic() {
|
|
Attribute* copy = new Attribute(*m_pBase);
|
|
copy->setStatic();
|
|
ReplaceOrRecord(m_AttrPool, m_pBase, copy);
|
|
}
|
|
|
|
void AttributeProxy::setDynamic() {
|
|
Attribute* copy = new Attribute(*m_pBase);
|
|
copy->setDynamic();
|
|
ReplaceOrRecord(m_AttrPool, m_pBase, copy);
|
|
}
|
|
|
|
AttributeProxy& AttributeProxy::assign(Attribute* pBase) {
|
|
m_pBase = pBase;
|
|
return *this;
|
|
}
|
|
|
|
} // namespace mcld
|