Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/LinkOnce.cc

    rc6b4432 r3cbe320  
    2222#include "AST/Expr.hpp"
    2323#include "AST/Pass.hpp"
     24#include "Common/PassVisitor.h"       // for PassVisitor, WithShortCircuiting
    2425
    2526namespace CodeGen {
    2627
    2728namespace {
     29
     30bool is_cfa_linkonce_old( Attribute const * attr ) {
     31        return std::string("cfa_linkonce") == attr->name;
     32}
     33
     34bool is_section_attribute_old( Attribute const * attr ) {
     35        return std::string("section") == attr->name;
     36}
     37
     38class LinkOnceVisitorCore : public WithShortCircuiting {
     39public:
     40        void previsit( Declaration * ) {
     41                visit_children = false;
     42        }
     43
     44        void previsit( DeclarationWithType * decl ) {
     45                std::list< Attribute * > & attributes = decl->attributes;
     46                // See if we can find the element:
     47                auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce_old );
     48                if ( attributes.end() != found ) {
     49                        // Remove any other sections:
     50                        attributes.remove_if( is_section_attribute_old );
     51                        // Iterator to the cfa_linkonce attribute should still be valid.
     52                        Attribute * attribute = *found;
     53                        assert( attribute->parameters.empty() );
     54                        assert( !decl->mangleName.empty() );
     55                        // Overwrite the attribute in place.
     56                        const std::string section_name = ".gnu.linkonce." + decl->mangleName;
     57                        attribute->name = "section";
     58                        attribute->parameters.push_back(
     59                                new ConstantExpr( Constant::from_string( section_name ) )
     60                        );
     61
     62                        // Unconditionnaly add "visibility(default)" to anything with gnu.linkonce
     63                        // visibility is a mess otherwise
     64                        attributes.push_back(new Attribute("visibility", {new ConstantExpr( Constant::from_string( "default" ) )}));
     65
     66                }
     67                visit_children = false;
     68        }
     69};
    2870
    2971bool is_cfa_linkonce( ast::Attribute const * attr ) {
     
    80122} // namespace
    81123
     124void translateLinkOnce( std::list< Declaration *> & translationUnit ) {
     125        PassVisitor<LinkOnceVisitorCore> translator;
     126        acceptAll( translationUnit, translator );
     127}
     128
    82129void translateLinkOnce( ast::TranslationUnit & translationUnit ) {
    83130        ast::Pass<LinkOnceCore>::run( translationUnit );
Note: See TracChangeset for help on using the changeset viewer.