1//===--- AVR.cpp - AVR ToolChain Implementations ----------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "AVR.h"
10#include "CommonArgs.h"
11#include "clang/Driver/Compilation.h"
12#include "clang/Driver/DriverDiagnostic.h"
13#include "clang/Driver/InputInfo.h"
14#include "clang/Driver/Options.h"
15#include "llvm/ADT/StringExtras.h"
16#include "llvm/MC/MCSubtargetInfo.h"
17#include "llvm/Option/ArgList.h"
18#include "llvm/Support/FileSystem.h"
19#include "llvm/Support/Path.h"
20#include "llvm/TargetParser/SubtargetFeature.h"
21
22using namespace clang::driver;
23using namespace clang::driver::toolchains;
24using namespace clang::driver::tools;
25using namespace clang;
26using namespace llvm::opt;
27
28namespace {
29
30// NOTE: This list has been synchronized with gcc-avr 7.3.0 and avr-libc 2.0.0.
31constexpr struct {
32 StringRef Name;
33 StringRef SubPath;
34 StringRef Family;
35 unsigned DataAddr;
36} MCUInfo[] = {
37 {.Name: "at90s1200", .SubPath: "", .Family: "avr1", .DataAddr: 0},
38 {.Name: "attiny11", .SubPath: "", .Family: "avr1", .DataAddr: 0},
39 {.Name: "attiny12", .SubPath: "", .Family: "avr1", .DataAddr: 0},
40 {.Name: "attiny15", .SubPath: "", .Family: "avr1", .DataAddr: 0},
41 {.Name: "attiny28", .SubPath: "", .Family: "avr1", .DataAddr: 0},
42 {.Name: "at90s2313", .SubPath: "tiny-stack", .Family: "avr2", .DataAddr: 0x800060},
43 {.Name: "at90s2323", .SubPath: "tiny-stack", .Family: "avr2", .DataAddr: 0x800060},
44 {.Name: "at90s2333", .SubPath: "tiny-stack", .Family: "avr2", .DataAddr: 0x800060},
45 {.Name: "at90s2343", .SubPath: "tiny-stack", .Family: "avr2", .DataAddr: 0x800060},
46 {.Name: "at90s4433", .SubPath: "tiny-stack", .Family: "avr2", .DataAddr: 0x800060},
47 {.Name: "attiny22", .SubPath: "tiny-stack", .Family: "avr2", .DataAddr: 0x800060},
48 {.Name: "attiny26", .SubPath: "tiny-stack", .Family: "avr2", .DataAddr: 0x800060},
49 {.Name: "at90s4414", .SubPath: "", .Family: "avr2", .DataAddr: 0x800060},
50 {.Name: "at90s4434", .SubPath: "", .Family: "avr2", .DataAddr: 0x800060},
51 {.Name: "at90s8515", .SubPath: "", .Family: "avr2", .DataAddr: 0x800060},
52 {.Name: "at90c8534", .SubPath: "", .Family: "avr2", .DataAddr: 0x800060},
53 {.Name: "at90s8535", .SubPath: "", .Family: "avr2", .DataAddr: 0x800060},
54 {.Name: "attiny13", .SubPath: "avr25/tiny-stack", .Family: "avr25", .DataAddr: 0x800060},
55 {.Name: "attiny13a", .SubPath: "avr25/tiny-stack", .Family: "avr25", .DataAddr: 0x800060},
56 {.Name: "attiny2313", .SubPath: "avr25/tiny-stack", .Family: "avr25", .DataAddr: 0x800060},
57 {.Name: "attiny2313a", .SubPath: "avr25/tiny-stack", .Family: "avr25", .DataAddr: 0x800060},
58 {.Name: "attiny24", .SubPath: "avr25/tiny-stack", .Family: "avr25", .DataAddr: 0x800060},
59 {.Name: "attiny24a", .SubPath: "avr25/tiny-stack", .Family: "avr25", .DataAddr: 0x800060},
60 {.Name: "attiny25", .SubPath: "avr25/tiny-stack", .Family: "avr25", .DataAddr: 0x800060},
61 {.Name: "attiny261", .SubPath: "avr25/tiny-stack", .Family: "avr25", .DataAddr: 0x800060},
62 {.Name: "attiny261a", .SubPath: "avr25/tiny-stack", .Family: "avr25", .DataAddr: 0x800060},
63 {.Name: "at86rf401", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
64 {.Name: "ata5272", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800100},
65 {.Name: "ata6616c", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800100},
66 {.Name: "attiny4313", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
67 {.Name: "attiny44", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
68 {.Name: "attiny44a", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
69 {.Name: "attiny84", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
70 {.Name: "attiny84a", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
71 {.Name: "attiny45", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
72 {.Name: "attiny85", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
73 {.Name: "attiny441", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800100},
74 {.Name: "attiny461", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
75 {.Name: "attiny461a", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
76 {.Name: "attiny841", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800100},
77 {.Name: "attiny861", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
78 {.Name: "attiny861a", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
79 {.Name: "attiny87", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800100},
80 {.Name: "attiny43u", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800060},
81 {.Name: "attiny48", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800100},
82 {.Name: "attiny88", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800100},
83 {.Name: "attiny828", .SubPath: "avr25", .Family: "avr25", .DataAddr: 0x800100},
84 {.Name: "at43usb355", .SubPath: "avr3", .Family: "avr3", .DataAddr: 0x800100},
85 {.Name: "at76c711", .SubPath: "avr3", .Family: "avr3", .DataAddr: 0x800060},
86 {.Name: "atmega103", .SubPath: "avr31", .Family: "avr31", .DataAddr: 0x800060},
87 {.Name: "at43usb320", .SubPath: "avr31", .Family: "avr31", .DataAddr: 0x800060},
88 {.Name: "attiny167", .SubPath: "avr35", .Family: "avr35", .DataAddr: 0x800100},
89 {.Name: "at90usb82", .SubPath: "avr35", .Family: "avr35", .DataAddr: 0x800100},
90 {.Name: "at90usb162", .SubPath: "avr35", .Family: "avr35", .DataAddr: 0x800100},
91 {.Name: "ata5505", .SubPath: "avr35", .Family: "avr35", .DataAddr: 0x800100},
92 {.Name: "ata6617c", .SubPath: "avr35", .Family: "avr35", .DataAddr: 0x800100},
93 {.Name: "ata664251", .SubPath: "avr35", .Family: "avr35", .DataAddr: 0x800100},
94 {.Name: "atmega8u2", .SubPath: "avr35", .Family: "avr35", .DataAddr: 0x800100},
95 {.Name: "atmega16u2", .SubPath: "avr35", .Family: "avr35", .DataAddr: 0x800100},
96 {.Name: "atmega32u2", .SubPath: "avr35", .Family: "avr35", .DataAddr: 0x800100},
97 {.Name: "attiny1634", .SubPath: "avr35", .Family: "avr35", .DataAddr: 0x800100},
98 {.Name: "atmega8", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800060},
99 {.Name: "ata6289", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
100 {.Name: "atmega8a", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800060},
101 {.Name: "ata6285", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
102 {.Name: "ata6286", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
103 {.Name: "ata6612c", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
104 {.Name: "atmega48", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
105 {.Name: "atmega48a", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
106 {.Name: "atmega48pa", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
107 {.Name: "atmega48pb", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
108 {.Name: "atmega48p", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
109 {.Name: "atmega88", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
110 {.Name: "atmega88a", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
111 {.Name: "atmega88p", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
112 {.Name: "atmega88pa", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
113 {.Name: "atmega88pb", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
114 {.Name: "atmega8515", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800060},
115 {.Name: "atmega8535", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800060},
116 {.Name: "atmega8hva", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
117 {.Name: "at90pwm1", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
118 {.Name: "at90pwm2", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
119 {.Name: "at90pwm2b", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
120 {.Name: "at90pwm3", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
121 {.Name: "at90pwm3b", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
122 {.Name: "at90pwm81", .SubPath: "avr4", .Family: "avr4", .DataAddr: 0x800100},
123 {.Name: "ata5702m322", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800200},
124 {.Name: "ata5782", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800200},
125 {.Name: "ata5790", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
126 {.Name: "ata5790n", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
127 {.Name: "ata5791", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
128 {.Name: "ata5795", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
129 {.Name: "ata5831", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800200},
130 {.Name: "ata6613c", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
131 {.Name: "ata6614q", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
132 {.Name: "ata8210", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800200},
133 {.Name: "ata8510", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800200},
134 {.Name: "atmega16", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800060},
135 {.Name: "atmega16a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800060},
136 {.Name: "atmega161", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800060},
137 {.Name: "atmega162", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
138 {.Name: "atmega163", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800060},
139 {.Name: "atmega164a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
140 {.Name: "atmega164p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
141 {.Name: "atmega164pa", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
142 {.Name: "atmega165", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
143 {.Name: "atmega165a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
144 {.Name: "atmega165p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
145 {.Name: "atmega165pa", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
146 {.Name: "atmega168", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
147 {.Name: "atmega168a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
148 {.Name: "atmega168p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
149 {.Name: "atmega168pa", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
150 {.Name: "atmega168pb", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
151 {.Name: "atmega169", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
152 {.Name: "atmega169a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
153 {.Name: "atmega169p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
154 {.Name: "atmega169pa", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
155 {.Name: "atmega32", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800060},
156 {.Name: "atmega32a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800060},
157 {.Name: "atmega323", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800060},
158 {.Name: "atmega324a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
159 {.Name: "atmega324p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
160 {.Name: "atmega324pa", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
161 {.Name: "atmega324pb", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
162 {.Name: "atmega325", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
163 {.Name: "atmega325a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
164 {.Name: "atmega325p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
165 {.Name: "atmega325pa", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
166 {.Name: "atmega3250", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
167 {.Name: "atmega3250a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
168 {.Name: "atmega3250p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
169 {.Name: "atmega3250pa", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
170 {.Name: "atmega328", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
171 {.Name: "atmega328p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
172 {.Name: "atmega328pb", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
173 {.Name: "atmega329", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
174 {.Name: "atmega329a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
175 {.Name: "atmega329p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
176 {.Name: "atmega329pa", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
177 {.Name: "atmega3290", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
178 {.Name: "atmega3290a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
179 {.Name: "atmega3290p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
180 {.Name: "atmega3290pa", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
181 {.Name: "atmega406", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
182 {.Name: "atmega64", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
183 {.Name: "atmega64a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
184 {.Name: "atmega640", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800200},
185 {.Name: "atmega644", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
186 {.Name: "atmega644a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
187 {.Name: "atmega644p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
188 {.Name: "atmega644pa", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
189 {.Name: "atmega645", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
190 {.Name: "atmega645a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
191 {.Name: "atmega645p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
192 {.Name: "atmega649", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
193 {.Name: "atmega649a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
194 {.Name: "atmega649p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
195 {.Name: "atmega6450", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
196 {.Name: "atmega6450a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
197 {.Name: "atmega6450p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
198 {.Name: "atmega6490", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
199 {.Name: "atmega6490a", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
200 {.Name: "atmega6490p", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
201 {.Name: "atmega64rfr2", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800200},
202 {.Name: "atmega644rfr2", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800200},
203 {.Name: "atmega16hva", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
204 {.Name: "atmega16hva2", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
205 {.Name: "atmega16hvb", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
206 {.Name: "atmega16hvbrevb", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
207 {.Name: "atmega32hvb", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
208 {.Name: "atmega32hvbrevb", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
209 {.Name: "atmega64hve", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
210 {.Name: "atmega64hve2", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
211 {.Name: "at90can32", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
212 {.Name: "at90can64", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
213 {.Name: "at90pwm161", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
214 {.Name: "at90pwm216", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
215 {.Name: "at90pwm316", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
216 {.Name: "atmega32c1", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
217 {.Name: "atmega64c1", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
218 {.Name: "atmega16m1", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
219 {.Name: "atmega32m1", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
220 {.Name: "atmega64m1", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
221 {.Name: "atmega16u4", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
222 {.Name: "atmega32u4", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
223 {.Name: "atmega32u6", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
224 {.Name: "at90usb646", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
225 {.Name: "at90usb647", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
226 {.Name: "at90scr100", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800100},
227 {.Name: "at94k", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800060},
228 {.Name: "m3000", .SubPath: "avr5", .Family: "avr5", .DataAddr: 0x800060},
229 {.Name: "atmega128", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800100},
230 {.Name: "atmega128a", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800100},
231 {.Name: "atmega1280", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800200},
232 {.Name: "atmega1281", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800200},
233 {.Name: "atmega1284", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800100},
234 {.Name: "atmega1284p", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800100},
235 {.Name: "atmega128rfa1", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800200},
236 {.Name: "atmega128rfr2", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800200},
237 {.Name: "atmega1284rfr2", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800200},
238 {.Name: "at90can128", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800200},
239 {.Name: "at90usb1286", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800200},
240 {.Name: "at90usb1287", .SubPath: "avr51", .Family: "avr51", .DataAddr: 0x800200},
241 {.Name: "atmega2560", .SubPath: "avr6", .Family: "avr6", .DataAddr: 0x800200},
242 {.Name: "atmega2561", .SubPath: "avr6", .Family: "avr6", .DataAddr: 0x800200},
243 {.Name: "atmega256rfr2", .SubPath: "avr6", .Family: "avr6", .DataAddr: 0x800200},
244 {.Name: "atmega2564rfr2", .SubPath: "avr6", .Family: "avr6", .DataAddr: 0x800200},
245 {.Name: "attiny4", .SubPath: "avrtiny", .Family: "avrtiny", .DataAddr: 0x800040},
246 {.Name: "attiny5", .SubPath: "avrtiny", .Family: "avrtiny", .DataAddr: 0x800040},
247 {.Name: "attiny9", .SubPath: "avrtiny", .Family: "avrtiny", .DataAddr: 0x800040},
248 {.Name: "attiny10", .SubPath: "avrtiny", .Family: "avrtiny", .DataAddr: 0x800040},
249 {.Name: "attiny20", .SubPath: "avrtiny", .Family: "avrtiny", .DataAddr: 0x800040},
250 {.Name: "attiny40", .SubPath: "avrtiny", .Family: "avrtiny", .DataAddr: 0x800040},
251 {.Name: "attiny102", .SubPath: "avrtiny", .Family: "avrtiny", .DataAddr: 0x800040},
252 {.Name: "attiny104", .SubPath: "avrtiny", .Family: "avrtiny", .DataAddr: 0x800040},
253 {.Name: "atxmega16a4", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
254 {.Name: "atxmega16a4u", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
255 {.Name: "atxmega16c4", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
256 {.Name: "atxmega16d4", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
257 {.Name: "atxmega32a4", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
258 {.Name: "atxmega32a4u", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
259 {.Name: "atxmega32c3", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
260 {.Name: "atxmega32c4", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
261 {.Name: "atxmega32d3", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
262 {.Name: "atxmega32d4", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
263 {.Name: "atxmega32e5", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
264 {.Name: "atxmega16e5", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
265 {.Name: "atxmega8e5", .SubPath: "avrxmega2", .Family: "avrxmega2", .DataAddr: 0x802000},
266 {.Name: "atxmega64a3", .SubPath: "avrxmega4", .Family: "avrxmega4", .DataAddr: 0x802000},
267 {.Name: "atxmega64a3u", .SubPath: "avrxmega4", .Family: "avrxmega4", .DataAddr: 0x802000},
268 {.Name: "atxmega64a4u", .SubPath: "avrxmega4", .Family: "avrxmega4", .DataAddr: 0x802000},
269 {.Name: "atxmega64b1", .SubPath: "avrxmega4", .Family: "avrxmega4", .DataAddr: 0x802000},
270 {.Name: "atxmega64b3", .SubPath: "avrxmega4", .Family: "avrxmega4", .DataAddr: 0x802000},
271 {.Name: "atxmega64c3", .SubPath: "avrxmega4", .Family: "avrxmega4", .DataAddr: 0x802000},
272 {.Name: "atxmega64d3", .SubPath: "avrxmega4", .Family: "avrxmega4", .DataAddr: 0x802000},
273 {.Name: "atxmega64d4", .SubPath: "avrxmega4", .Family: "avrxmega4", .DataAddr: 0x802000},
274 {.Name: "atxmega64a1", .SubPath: "avrxmega5", .Family: "avrxmega5", .DataAddr: 0x802000},
275 {.Name: "atxmega64a1u", .SubPath: "avrxmega5", .Family: "avrxmega5", .DataAddr: 0x802000},
276 {.Name: "atxmega128a3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
277 {.Name: "atxmega128a3u", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
278 {.Name: "atxmega128b1", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
279 {.Name: "atxmega128b3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
280 {.Name: "atxmega128c3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
281 {.Name: "atxmega128d3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
282 {.Name: "atxmega128d4", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
283 {.Name: "atxmega192a3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
284 {.Name: "atxmega192a3u", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
285 {.Name: "atxmega192c3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
286 {.Name: "atxmega192d3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
287 {.Name: "atxmega256a3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
288 {.Name: "atxmega256a3u", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
289 {.Name: "atxmega256a3b", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
290 {.Name: "atxmega256a3bu", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
291 {.Name: "atxmega256c3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
292 {.Name: "atxmega256d3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
293 {.Name: "atxmega384c3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
294 {.Name: "atxmega384d3", .SubPath: "avrxmega6", .Family: "avrxmega6", .DataAddr: 0x802000},
295 {.Name: "atxmega128a1", .SubPath: "avrxmega7", .Family: "avrxmega7", .DataAddr: 0x802000},
296 {.Name: "atxmega128a1u", .SubPath: "avrxmega7", .Family: "avrxmega7", .DataAddr: 0x802000},
297 {.Name: "atxmega128a4u", .SubPath: "avrxmega7", .Family: "avrxmega7", .DataAddr: 0x802000},
298 {.Name: "attiny202", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F80},
299 {.Name: "attiny204", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F80},
300 {.Name: "attiny212", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F80},
301 {.Name: "attiny214", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F80},
302 {.Name: "attiny402", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F00},
303 {.Name: "attiny404", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F00},
304 {.Name: "attiny406", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F00},
305 {.Name: "attiny412", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F00},
306 {.Name: "attiny414", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F00},
307 {.Name: "attiny416", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F00},
308 {.Name: "attiny417", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803F00},
309 {.Name: "attiny804", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803E00},
310 {.Name: "attiny806", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803E00},
311 {.Name: "attiny807", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803E00},
312 {.Name: "attiny814", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803E00},
313 {.Name: "attiny816", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803E00},
314 {.Name: "attiny817", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803E00},
315 {.Name: "atmega808", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803C00},
316 {.Name: "atmega809", .SubPath: "avrxmega3/short-calls", .Family: "avrxmega3", .DataAddr: 0x803C00},
317 {.Name: "atmega1608", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803800},
318 {.Name: "atmega1609", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803800},
319 {.Name: "atmega3208", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803000},
320 {.Name: "atmega3209", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803000},
321 {.Name: "atmega4808", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x802800},
322 {.Name: "atmega4809", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x802800},
323 {.Name: "attiny1604", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803C00},
324 {.Name: "attiny1606", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803C00},
325 {.Name: "attiny1607", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803C00},
326 {.Name: "attiny1614", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803800},
327 {.Name: "attiny1616", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803800},
328 {.Name: "attiny1617", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803800},
329 {.Name: "attiny1624", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803800},
330 {.Name: "attiny1626", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803800},
331 {.Name: "attiny1627", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803800},
332 {.Name: "attiny3216", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803800},
333 {.Name: "attiny3217", .SubPath: "avrxmega3", .Family: "avrxmega3", .DataAddr: 0x803800},
334};
335
336std::string GetMCUSubPath(StringRef MCUName) {
337 for (const auto &MCU : MCUInfo)
338 if (MCU.Name == MCUName)
339 return std::string(MCU.SubPath);
340 return "";
341}
342
343std::optional<StringRef> GetMCUFamilyName(StringRef MCUName) {
344 for (const auto &MCU : MCUInfo)
345 if (MCU.Name == MCUName)
346 return std::optional<StringRef>(MCU.Family);
347 return std::nullopt;
348}
349
350std::optional<unsigned> GetMCUSectionAddressData(StringRef MCUName) {
351 for (const auto &MCU : MCUInfo)
352 if (MCU.Name == MCUName && MCU.DataAddr > 0)
353 return std::optional<unsigned>(MCU.DataAddr);
354 return std::nullopt;
355}
356
357const StringRef PossibleAVRLibcLocations[] = {
358 "/avr",
359 "/usr/avr",
360 "/usr/lib/avr",
361};
362
363} // end anonymous namespace
364
365/// AVR Toolchain
366AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple,
367 const ArgList &Args)
368 : Generic_ELF(D, Triple, Args) {
369 GCCInstallation.init(TargetTriple: Triple, Args);
370
371 if (getCPUName(D, Args, T: Triple).empty())
372 D.Diag(diag::DiagID: warn_drv_avr_mcu_not_specified);
373
374 // Only add default libraries if the user hasn't explicitly opted out.
375 if (!Args.hasArg(options::OPT_nostdlib) &&
376 !Args.hasArg(options::OPT_nodefaultlibs) && GCCInstallation.isValid()) {
377 GCCInstallPath = GCCInstallation.getInstallPath();
378 std::string GCCParentPath(GCCInstallation.getParentLibPath());
379 getProgramPaths().push_back(Elt: GCCParentPath + "/../bin");
380 }
381}
382
383void AVRToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
384 ArgStringList &CC1Args) const {
385 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
386 DriverArgs.hasArg(options::OPT_nostdlibinc))
387 return;
388
389 // Omit if there is no avr-libc installed.
390 std::optional<std::string> AVRLibcRoot = findAVRLibcInstallation();
391 if (!AVRLibcRoot)
392 return;
393
394 // Add 'avr-libc/include' to clang system include paths if applicable.
395 std::string AVRInc = *AVRLibcRoot + "/include";
396 if (llvm::sys::fs::is_directory(Path: AVRInc))
397 addSystemInclude(DriverArgs, CC1Args, Path: AVRInc);
398}
399
400void AVRToolChain::addClangTargetOptions(
401 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
402 Action::OffloadKind DeviceOffloadKind) const {
403 // By default, use `.ctors` (not `.init_array`), as required by libgcc, which
404 // runs constructors/destructors on AVR.
405 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
406 options::OPT_fno_use_init_array, false))
407 CC1Args.push_back(Elt: "-fno-use-init-array");
408 // Use `-fno-use-cxa-atexit` as default, since avr-libc does not support
409 // `__cxa_atexit()`.
410 if (!DriverArgs.hasFlag(options::OPT_fuse_cxa_atexit,
411 options::OPT_fno_use_cxa_atexit, false))
412 CC1Args.push_back(Elt: "-fno-use-cxa-atexit");
413}
414
415Tool *AVRToolChain::buildLinker() const {
416 return new tools::AVR::Linker(getTriple(), *this);
417}
418
419std::string
420AVRToolChain::getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
421 FileType Type = ToolChain::FT_Static) const {
422 assert(Type == ToolChain::FT_Static && "AVR only supports static libraries");
423 // Since AVR can never be a host environment, its compiler-rt library files
424 // should always have ".a" suffix, even on windows.
425 SmallString<32> File("/libclang_rt.");
426 File += Component.str();
427 File += ".a";
428 // Return the default compiler-rt path appended with
429 // "avr/libclang_rt.$COMPONENT.a".
430 SmallString<256> Path(ToolChain::getCompilerRTPath());
431 llvm::sys::path::append(path&: Path, a: "avr");
432 llvm::sys::path::append(path&: Path, a: File.str());
433 return std::string(Path);
434}
435
436void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
437 const InputInfo &Output,
438 const InputInfoList &Inputs, const ArgList &Args,
439 const char *LinkingOutput) const {
440 const auto &TC = static_cast<const AVRToolChain &>(getToolChain());
441 const Driver &D = getToolChain().getDriver();
442
443 // Compute information about the target AVR.
444 std::string CPU = getCPUName(D, Args, T: getToolChain().getTriple());
445 std::optional<StringRef> FamilyName = GetMCUFamilyName(MCUName: CPU);
446 std::optional<std::string> AVRLibcRoot = TC.findAVRLibcInstallation();
447 std::optional<unsigned> SectionAddressData = GetMCUSectionAddressData(MCUName: CPU);
448
449 // Compute the linker program path, and use GNU "avr-ld" as default.
450 const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ);
451 std::string Linker = A ? getToolChain().GetLinkerPath(LinkerIsLLD: nullptr)
452 : getToolChain().GetProgramPath(Name: getShortName());
453
454 ArgStringList CmdArgs;
455
456 CmdArgs.push_back(Elt: "-o");
457 CmdArgs.push_back(Elt: Output.getFilename());
458
459 // Enable garbage collection of unused sections.
460 if (!Args.hasArg(options::OPT_r))
461 CmdArgs.push_back(Elt: "--gc-sections");
462
463 // Add library search paths before we specify libraries.
464 Args.AddAllArgs(Output&: CmdArgs, options::Id0: OPT_L);
465 getToolChain().AddFilePathLibArgs(Args, CmdArgs);
466
467 // Currently we only support libgcc and compiler-rt.
468 auto RtLib = TC.GetRuntimeLibType(Args);
469 assert(
470 (RtLib == ToolChain::RLT_Libgcc || RtLib == ToolChain::RLT_CompilerRT) &&
471 "unknown runtime library");
472
473 // Only add default libraries if the user hasn't explicitly opted out.
474 bool LinkStdlib = false;
475 if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_r) &&
476 !Args.hasArg(options::OPT_nodefaultlibs)) {
477 if (!CPU.empty()) {
478 if (!FamilyName) {
479 // We do not have an entry for this CPU in the family
480 // mapping table yet.
481 D.Diag(diag::DiagID: warn_drv_avr_family_linking_stdlibs_not_implemented)
482 << CPU;
483 } else if (!AVRLibcRoot) {
484 // No avr-libc found and so no runtime linked.
485 D.Diag(diag::DiagID: warn_drv_avr_libc_not_found);
486 } else {
487 std::string SubPath = GetMCUSubPath(MCUName: CPU);
488 // Add path of avr-libc.
489 CmdArgs.push_back(
490 Elt: Args.MakeArgString(Str: Twine("-L") + *AVRLibcRoot + "/lib/" + SubPath));
491 if (RtLib == ToolChain::RLT_Libgcc)
492 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-L" + TC.getGCCInstallPath() +
493 "/" + SubPath));
494 LinkStdlib = true;
495 }
496 }
497 if (!LinkStdlib)
498 D.Diag(diag::DiagID: warn_drv_avr_stdlib_not_linked);
499 }
500
501 if (!Args.hasArg(options::OPT_r)) {
502 if (SectionAddressData) {
503 CmdArgs.push_back(
504 Elt: Args.MakeArgString(Str: "--defsym=__DATA_REGION_ORIGIN__=0x" +
505 Twine::utohexstr(Val: *SectionAddressData)));
506 } else {
507 // We do not have an entry for this CPU in the address mapping table
508 // yet.
509 D.Diag(diag::DiagID: warn_drv_avr_linker_section_addresses_not_implemented)
510 << CPU;
511 }
512 }
513
514 if (D.isUsingLTO()) {
515 assert(!Inputs.empty() && "Must have at least one input.");
516 // Find the first filename InputInfo object.
517 auto Input = llvm::find_if(
518 Range: Inputs, P: [](const InputInfo &II) -> bool { return II.isFilename(); });
519 if (Input == Inputs.end())
520 // For a very rare case, all of the inputs to the linker are
521 // InputArg. If that happens, just use the first InputInfo.
522 Input = Inputs.begin();
523
524 addLTOOptions(ToolChain: TC, Args, CmdArgs, Output, Input: *Input,
525 IsThinLTO: D.getLTOMode() == LTOK_Thin);
526 }
527
528 // If the family name is known, we can link with the device-specific libgcc.
529 // Without it, libgcc will simply not be linked. This matches avr-gcc
530 // behavior.
531 if (LinkStdlib) {
532 assert(!CPU.empty() && "CPU name must be known in order to link stdlibs");
533
534 CmdArgs.push_back(Elt: "--start-group");
535
536 // Add the object file for the CRT.
537 std::string CrtFileName = std::string("-l:crt") + CPU + std::string(".o");
538 CmdArgs.push_back(Elt: Args.MakeArgString(Str: CrtFileName));
539
540 // Link to libgcc.
541 if (RtLib == ToolChain::RLT_Libgcc)
542 CmdArgs.push_back(Elt: "-lgcc");
543
544 // Link to generic libraries of avr-libc.
545 CmdArgs.push_back(Elt: "-lm");
546 CmdArgs.push_back(Elt: "-lc");
547
548 // Add the link library specific to the MCU.
549 CmdArgs.push_back(Elt: Args.MakeArgString(Str: std::string("-l") + CPU));
550
551 // Add the relocatable inputs.
552 AddLinkerInputs(TC: getToolChain(), Inputs, Args, CmdArgs, JA);
553
554 // We directly use libclang_rt.builtins.a as input file, instead of using
555 // '-lclang_rt.builtins'.
556 if (RtLib == ToolChain::RLT_CompilerRT) {
557 std::string RtLib =
558 getToolChain().getCompilerRT(Args, Component: "builtins", Type: ToolChain::FT_Static);
559 if (llvm::sys::fs::exists(Path: RtLib))
560 CmdArgs.push_back(Elt: Args.MakeArgString(Str: RtLib));
561 }
562
563 CmdArgs.push_back(Elt: "--end-group");
564
565 // Add avr-libc's linker script to lld by default, if it exists.
566 if (!Args.hasArg(options::OPT_T) &&
567 Linker.find(s: "avr-ld") == std::string::npos) {
568 std::string Path(*AVRLibcRoot + "/lib/ldscripts/");
569 Path += *FamilyName;
570 Path += ".x";
571 if (llvm::sys::fs::exists(Path))
572 CmdArgs.push_back(Elt: Args.MakeArgString(Str: "-T" + Path));
573 }
574 // Otherwise add user specified linker script to either avr-ld or lld.
575 else
576 Args.AddAllArgs(Output&: CmdArgs, options::Id0: OPT_T);
577
578 if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))
579 CmdArgs.push_back(Elt: "--relax");
580 } else {
581 AddLinkerInputs(TC: getToolChain(), Inputs, Args, CmdArgs, JA);
582 }
583
584 // Specify the family name as the emulation mode to use.
585 // This is almost always required because otherwise avr-ld
586 // will assume 'avr2' and warn about the program being larger
587 // than the bare minimum supports.
588 if (Linker.find(s: "avr-ld") != std::string::npos && FamilyName)
589 CmdArgs.push_back(Elt: Args.MakeArgString(Str: std::string("-m") + *FamilyName));
590
591 C.addCommand(C: std::make_unique<Command>(
592 args: JA, args: *this, args: ResponseFileSupport::AtFileCurCP(), args: Args.MakeArgString(Str: Linker),
593 args&: CmdArgs, args: Inputs, args: Output));
594}
595
596std::optional<std::string> AVRToolChain::findAVRLibcInstallation() const {
597 // Search avr-libc installation according to avr-gcc installation.
598 std::string GCCParent(GCCInstallation.getParentLibPath());
599 std::string Path(GCCParent + "/avr");
600 if (llvm::sys::fs::is_directory(Path))
601 return Path;
602 Path = GCCParent + "/../avr";
603 if (llvm::sys::fs::is_directory(Path))
604 return Path;
605
606 // Search avr-libc installation from possible locations, and return the first
607 // one that exists, if there is no avr-gcc installed.
608 for (StringRef PossiblePath : PossibleAVRLibcLocations) {
609 std::string Path = getDriver().SysRoot + PossiblePath.str();
610 if (llvm::sys::fs::is_directory(Path))
611 return Path;
612 }
613
614 return std::nullopt;
615}
616

source code of clang/lib/Driver/ToolChains/AVR.cpp