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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

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