source: src/CodeGen/LinkOnce.cc@ fe293bf

Last change on this file since fe293bf was 3cbe320, checked in by Andrew Beach <ajbeach@…>, 2 years ago

Translated the Link-Once pass to the new ast.

  • Property mode set to 100644
File size: 3.9 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// LinkOnce.cc -- Translate the cfa_linkonce attribute.
8//
9// Author : Andrew Beach
10// Created On : Thur May 13 10:10:00 2021
11// Last Modified By : Andrew Beach
12// Last Modified On : Wed Oct 4 10:52:00 2023
13// Update Count : 1
14//
15
16#include "LinkOnce.h"
17
18#include <algorithm>
19
20#include "AST/Attribute.hpp"
21#include "AST/Decl.hpp"
22#include "AST/Expr.hpp"
23#include "AST/Pass.hpp"
24#include "Common/PassVisitor.h" // for PassVisitor, WithShortCircuiting
25
26namespace CodeGen {
27
28namespace {
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};
70
71bool is_cfa_linkonce( ast::Attribute const * attr ) {
72 return "cfa_linkonce" == attr->name;
73}
74
75bool is_section_attribute( ast::Attribute const * attr ) {
76 return "section" == attr->name;
77}
78
79struct LinkOnceCore : public ast::WithShortCircuiting {
80 void previsit( ast::Decl const * ) {
81 visit_children = false;
82 }
83
84 ast::DeclWithType const * postvisit( ast::DeclWithType const * decl ) {
85 // Check to see if we have to mutate, because should be uncommon.
86 {
87 auto & attributes = decl->attributes;
88 auto found = std::find_if( attributes.begin(), attributes.end(),
89 is_cfa_linkonce );
90 if ( attributes.end() == found ) return decl;
91 }
92 auto mutDecl = mutate( decl );
93 auto & attributes = mutDecl->attributes;
94
95 // Remove all conflicting section attributes.
96 erase_if( attributes, is_section_attribute );
97
98 // Get the attribute, and overwrite it as a section attribute.
99 auto found = std::find_if( attributes.begin(), attributes.end(),
100 is_cfa_linkonce );
101 assert( attributes.end() != found );
102 ast::Attribute * attribute = found->get_and_mutate();
103 assert( attribute->params.empty() );
104 assert( !decl->mangleName.empty() );
105
106 attribute->name = "section";
107 attribute->params.push_back(
108 ast::ConstantExpr::from_string( mutDecl->location,
109 ".gnu.linkonce." + decl->mangleName
110 )
111 );
112
113 // Unconditionnaly add "visibility(default)" to anything with
114 // .gnu.linkonce visibility is a mess otherwise.
115 attributes.push_back( new ast::Attribute( "visibility", {
116 ast::ConstantExpr::from_string( mutDecl->location, "default" )
117 } ) );
118 return mutDecl;
119 }
120};
121
122} // namespace
123
124void translateLinkOnce( std::list< Declaration *> & translationUnit ) {
125 PassVisitor<LinkOnceVisitorCore> translator;
126 acceptAll( translationUnit, translator );
127}
128
129void translateLinkOnce( ast::TranslationUnit & translationUnit ) {
130 ast::Pass<LinkOnceCore>::run( translationUnit );
131}
132
133} // namespace CodeGen
Note: See TracBrowser for help on using the repository browser.