source: src/CodeGen/LinkOnce.cc @ 116d7e2

Last change on this file since 116d7e2 was c6b4432, checked in by Andrew Beach <ajbeach@…>, 7 months ago

Remove BaseSyntaxNode? and clean-up.

  • Property mode set to 100644
File size: 2.3 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
25namespace CodeGen {
26
27namespace {
28
29bool is_cfa_linkonce( ast::Attribute const * attr ) {
30        return "cfa_linkonce" == attr->name;
31}
32
33bool is_section_attribute( ast::Attribute const * attr ) {
34        return "section" == attr->name;
35}
36
37struct LinkOnceCore : public ast::WithShortCircuiting {
38        void previsit( ast::Decl const * ) {
39                visit_children = false;
40        }
41
42        ast::DeclWithType const * postvisit( ast::DeclWithType const * decl ) {
43                // Check to see if we have to mutate, because should be uncommon.
44                {
45                        auto & attributes = decl->attributes;
46                        auto found = std::find_if( attributes.begin(), attributes.end(),
47                                        is_cfa_linkonce );
48                        if ( attributes.end() == found ) return decl;
49                }
50                auto mutDecl = mutate( decl );
51                auto & attributes = mutDecl->attributes;
52
53                // Remove all conflicting section attributes.
54                erase_if( attributes, is_section_attribute );
55
56                // Get the attribute, and overwrite it as a section attribute.
57                auto found = std::find_if( attributes.begin(), attributes.end(),
58                                is_cfa_linkonce );
59                assert( attributes.end() != found );
60                ast::Attribute * attribute = found->get_and_mutate();
61                assert( attribute->params.empty() );
62                assert( !decl->mangleName.empty() );
63
64                attribute->name = "section";
65                attribute->params.push_back(
66                        ast::ConstantExpr::from_string( mutDecl->location,
67                                ".gnu.linkonce." + decl->mangleName
68                        )
69                );
70
71                // Unconditionnaly add "visibility(default)" to anything with
72                // .gnu.linkonce visibility is a mess otherwise.
73                attributes.push_back( new ast::Attribute( "visibility", {
74                        ast::ConstantExpr::from_string( mutDecl->location, "default" )
75                } ) );
76                return mutDecl;
77        }
78};
79
80} // namespace
81
82void translateLinkOnce( ast::TranslationUnit & translationUnit ) {
83        ast::Pass<LinkOnceCore>::run( translationUnit );
84}
85
86} // namespace CodeGen
Note: See TracBrowser for help on using the repository browser.