1218885Sdim//===-- TargetLibraryInfo.cpp - Runtime library information ----------------==//
2218885Sdim//
3218885Sdim//                     The LLVM Compiler Infrastructure
4218885Sdim//
5218885Sdim// This file is distributed under the University of Illinois Open Source
6218885Sdim// License. See LICENSE.TXT for details.
7218885Sdim//
8218885Sdim//===----------------------------------------------------------------------===//
9218885Sdim//
10218885Sdim// This file implements the TargetLibraryInfo class.
11218885Sdim//
12218885Sdim//===----------------------------------------------------------------------===//
13218885Sdim
14218885Sdim#include "llvm/Target/TargetLibraryInfo.h"
15218885Sdim#include "llvm/ADT/Triple.h"
16218885Sdimusing namespace llvm;
17218885Sdim
18218885Sdim// Register the default implementation.
19218885SdimINITIALIZE_PASS(TargetLibraryInfo, "targetlibinfo",
20218885Sdim                "Target Library Information", false, true)
21218885Sdimchar TargetLibraryInfo::ID = 0;
22218885Sdim
23235633Sdimvoid TargetLibraryInfo::anchor() { }
24235633Sdim
25235633Sdimconst char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
26235633Sdim  {
27252723Sdim    "_IO_getc",
28252723Sdim    "_IO_putc",
29245431Sdim    "_ZdaPv",
30263509Sdim    "_ZdaPvRKSt9nothrow_t",
31245431Sdim    "_ZdlPv",
32263509Sdim    "_ZdlPvRKSt9nothrow_t",
33245431Sdim    "_Znaj",
34245431Sdim    "_ZnajRKSt9nothrow_t",
35245431Sdim    "_Znam",
36245431Sdim    "_ZnamRKSt9nothrow_t",
37245431Sdim    "_Znwj",
38245431Sdim    "_ZnwjRKSt9nothrow_t",
39245431Sdim    "_Znwm",
40245431Sdim    "_ZnwmRKSt9nothrow_t",
41263509Sdim    "__cospi",
42263509Sdim    "__cospif",
43245431Sdim    "__cxa_atexit",
44245431Sdim    "__cxa_guard_abort",
45245431Sdim    "__cxa_guard_acquire",
46245431Sdim    "__cxa_guard_release",
47252723Sdim    "__isoc99_scanf",
48252723Sdim    "__isoc99_sscanf",
49245431Sdim    "__memcpy_chk",
50263509Sdim    "__sincospi_stret",
51263509Sdim    "__sincospi_stretf",
52263509Sdim    "__sinpi",
53263509Sdim    "__sinpif",
54263509Sdim    "__sqrt_finite",
55263509Sdim    "__sqrtf_finite",
56263509Sdim    "__sqrtl_finite",
57252723Sdim    "__strdup",
58252723Sdim    "__strndup",
59252723Sdim    "__strtok_r",
60252723Sdim    "abs",
61252723Sdim    "access",
62235633Sdim    "acos",
63245431Sdim    "acosf",
64245431Sdim    "acosh",
65245431Sdim    "acoshf",
66245431Sdim    "acoshl",
67235633Sdim    "acosl",
68235633Sdim    "asin",
69245431Sdim    "asinf",
70245431Sdim    "asinh",
71245431Sdim    "asinhf",
72245431Sdim    "asinhl",
73235633Sdim    "asinl",
74235633Sdim    "atan",
75235633Sdim    "atan2",
76245431Sdim    "atan2f",
77235633Sdim    "atan2l",
78245431Sdim    "atanf",
79245431Sdim    "atanh",
80245431Sdim    "atanhf",
81245431Sdim    "atanhl",
82245431Sdim    "atanl",
83252723Sdim    "atof",
84252723Sdim    "atoi",
85252723Sdim    "atol",
86252723Sdim    "atoll",
87252723Sdim    "bcmp",
88252723Sdim    "bcopy",
89252723Sdim    "bzero",
90245431Sdim    "calloc",
91245431Sdim    "cbrt",
92245431Sdim    "cbrtf",
93245431Sdim    "cbrtl",
94235633Sdim    "ceil",
95245431Sdim    "ceilf",
96235633Sdim    "ceill",
97252723Sdim    "chmod",
98252723Sdim    "chown",
99252723Sdim    "clearerr",
100252723Sdim    "closedir",
101235633Sdim    "copysign",
102235633Sdim    "copysignf",
103235633Sdim    "copysignl",
104235633Sdim    "cos",
105235633Sdim    "cosf",
106235633Sdim    "cosh",
107245431Sdim    "coshf",
108235633Sdim    "coshl",
109245431Sdim    "cosl",
110252723Sdim    "ctermid",
111235633Sdim    "exp",
112245431Sdim    "exp10",
113245431Sdim    "exp10f",
114245431Sdim    "exp10l",
115235633Sdim    "exp2",
116245431Sdim    "exp2f",
117235633Sdim    "exp2l",
118245431Sdim    "expf",
119245431Sdim    "expl",
120235633Sdim    "expm1",
121245431Sdim    "expm1f",
122235633Sdim    "expm1l",
123235633Sdim    "fabs",
124245431Sdim    "fabsf",
125235633Sdim    "fabsl",
126252723Sdim    "fclose",
127252723Sdim    "fdopen",
128252723Sdim    "feof",
129252723Sdim    "ferror",
130252723Sdim    "fflush",
131252723Sdim    "ffs",
132252723Sdim    "ffsl",
133252723Sdim    "ffsll",
134252723Sdim    "fgetc",
135252723Sdim    "fgetpos",
136252723Sdim    "fgets",
137252723Sdim    "fileno",
138245431Sdim    "fiprintf",
139252723Sdim    "flockfile",
140235633Sdim    "floor",
141245431Sdim    "floorf",
142235633Sdim    "floorl",
143235633Sdim    "fmod",
144245431Sdim    "fmodf",
145235633Sdim    "fmodl",
146252723Sdim    "fopen",
147252723Sdim    "fopen64",
148252723Sdim    "fprintf",
149245431Sdim    "fputc",
150235633Sdim    "fputs",
151252723Sdim    "fread",
152245431Sdim    "free",
153252723Sdim    "frexp",
154252723Sdim    "frexpf",
155252723Sdim    "frexpl",
156252723Sdim    "fscanf",
157252723Sdim    "fseek",
158252723Sdim    "fseeko",
159252723Sdim    "fseeko64",
160252723Sdim    "fsetpos",
161252723Sdim    "fstat",
162252723Sdim    "fstat64",
163252723Sdim    "fstatvfs",
164252723Sdim    "fstatvfs64",
165252723Sdim    "ftell",
166252723Sdim    "ftello",
167252723Sdim    "ftello64",
168252723Sdim    "ftrylockfile",
169252723Sdim    "funlockfile",
170235633Sdim    "fwrite",
171252723Sdim    "getc",
172252723Sdim    "getc_unlocked",
173252723Sdim    "getchar",
174252723Sdim    "getenv",
175252723Sdim    "getitimer",
176252723Sdim    "getlogin_r",
177252723Sdim    "getpwnam",
178252723Sdim    "gets",
179263509Sdim    "gettimeofday",
180252723Sdim    "htonl",
181252723Sdim    "htons",
182235633Sdim    "iprintf",
183252723Sdim    "isascii",
184252723Sdim    "isdigit",
185252723Sdim    "labs",
186252723Sdim    "lchown",
187252723Sdim    "llabs",
188235633Sdim    "log",
189235633Sdim    "log10",
190245431Sdim    "log10f",
191235633Sdim    "log10l",
192235633Sdim    "log1p",
193245431Sdim    "log1pf",
194235633Sdim    "log1pl",
195245431Sdim    "log2",
196245431Sdim    "log2f",
197245431Sdim    "log2l",
198245431Sdim    "logb",
199245431Sdim    "logbf",
200245431Sdim    "logbl",
201245431Sdim    "logf",
202245431Sdim    "logl",
203252723Sdim    "lstat",
204252723Sdim    "lstat64",
205245431Sdim    "malloc",
206252723Sdim    "memalign",
207252723Sdim    "memccpy",
208245431Sdim    "memchr",
209245431Sdim    "memcmp",
210235633Sdim    "memcpy",
211235633Sdim    "memmove",
212252723Sdim    "memrchr",
213235633Sdim    "memset",
214235633Sdim    "memset_pattern16",
215252723Sdim    "mkdir",
216252723Sdim    "mktime",
217252723Sdim    "modf",
218252723Sdim    "modff",
219252723Sdim    "modfl",
220235633Sdim    "nearbyint",
221235633Sdim    "nearbyintf",
222235633Sdim    "nearbyintl",
223252723Sdim    "ntohl",
224252723Sdim    "ntohs",
225252723Sdim    "open",
226252723Sdim    "open64",
227252723Sdim    "opendir",
228252723Sdim    "pclose",
229252723Sdim    "perror",
230252723Sdim    "popen",
231245431Sdim    "posix_memalign",
232235633Sdim    "pow",
233235633Sdim    "powf",
234235633Sdim    "powl",
235252723Sdim    "pread",
236252723Sdim    "printf",
237252723Sdim    "putc",
238245431Sdim    "putchar",
239245431Sdim    "puts",
240252723Sdim    "pwrite",
241252723Sdim    "qsort",
242252723Sdim    "read",
243252723Sdim    "readlink",
244245431Sdim    "realloc",
245245431Sdim    "reallocf",
246252723Sdim    "realpath",
247252723Sdim    "remove",
248252723Sdim    "rename",
249252723Sdim    "rewind",
250235633Sdim    "rint",
251235633Sdim    "rintf",
252235633Sdim    "rintl",
253252723Sdim    "rmdir",
254235633Sdim    "round",
255235633Sdim    "roundf",
256235633Sdim    "roundl",
257252723Sdim    "scanf",
258252723Sdim    "setbuf",
259252723Sdim    "setitimer",
260252723Sdim    "setvbuf",
261235633Sdim    "sin",
262235633Sdim    "sinf",
263235633Sdim    "sinh",
264245431Sdim    "sinhf",
265235633Sdim    "sinhl",
266245431Sdim    "sinl",
267235633Sdim    "siprintf",
268252723Sdim    "snprintf",
269252723Sdim    "sprintf",
270235633Sdim    "sqrt",
271245431Sdim    "sqrtf",
272235633Sdim    "sqrtl",
273252723Sdim    "sscanf",
274252723Sdim    "stat",
275252723Sdim    "stat64",
276252723Sdim    "statvfs",
277252723Sdim    "statvfs64",
278245431Sdim    "stpcpy",
279252723Sdim    "stpncpy",
280252723Sdim    "strcasecmp",
281245431Sdim    "strcat",
282245431Sdim    "strchr",
283245431Sdim    "strcmp",
284252723Sdim    "strcoll",
285245431Sdim    "strcpy",
286245431Sdim    "strcspn",
287245431Sdim    "strdup",
288245431Sdim    "strlen",
289252723Sdim    "strncasecmp",
290245431Sdim    "strncat",
291245431Sdim    "strncmp",
292245431Sdim    "strncpy",
293245431Sdim    "strndup",
294245431Sdim    "strnlen",
295245431Sdim    "strpbrk",
296245431Sdim    "strrchr",
297245431Sdim    "strspn",
298245431Sdim    "strstr",
299245431Sdim    "strtod",
300245431Sdim    "strtof",
301252723Sdim    "strtok",
302252723Sdim    "strtok_r",
303245431Sdim    "strtol",
304245431Sdim    "strtold",
305245431Sdim    "strtoll",
306245431Sdim    "strtoul",
307245431Sdim    "strtoull",
308252723Sdim    "strxfrm",
309252723Sdim    "system",
310235633Sdim    "tan",
311235633Sdim    "tanf",
312235633Sdim    "tanh",
313245431Sdim    "tanhf",
314235633Sdim    "tanhl",
315245431Sdim    "tanl",
316252723Sdim    "times",
317252723Sdim    "tmpfile",
318252723Sdim    "tmpfile64",
319252723Sdim    "toascii",
320235633Sdim    "trunc",
321235633Sdim    "truncf",
322235633Sdim    "truncl",
323252723Sdim    "uname",
324252723Sdim    "ungetc",
325252723Sdim    "unlink",
326252723Sdim    "unsetenv",
327252723Sdim    "utime",
328252723Sdim    "utimes",
329252723Sdim    "valloc",
330252723Sdim    "vfprintf",
331252723Sdim    "vfscanf",
332252723Sdim    "vprintf",
333252723Sdim    "vscanf",
334252723Sdim    "vsnprintf",
335252723Sdim    "vsprintf",
336252723Sdim    "vsscanf",
337252723Sdim    "write"
338235633Sdim  };
339235633Sdim
340263509Sdimstatic bool hasSinCosPiStret(const Triple &T) {
341263509Sdim  // Only Darwin variants have _stret versions of combined trig functions.
342263509Sdim  if (!T.isMacOSX() && T.getOS() != Triple::IOS)
343263509Sdim    return false;
344263509Sdim
345263509Sdim  // The ABI is rather complicated on x86, so don't do anything special there.
346263509Sdim  if (T.getArch() == Triple::x86)
347263509Sdim    return false;
348263509Sdim
349263509Sdim  if (T.isMacOSX() && T.isMacOSXVersionLT(10, 9))
350263509Sdim    return false;
351263509Sdim
352263509Sdim  if (T.getOS() == Triple::IOS && T.isOSVersionLT(7, 0))
353263509Sdim    return false;
354263509Sdim
355263509Sdim  return true;
356263509Sdim}
357263509Sdim
358218885Sdim/// initialize - Initialize the set of available library functions based on the
359218885Sdim/// specified target triple.  This should be carefully written so that a missing
360218885Sdim/// target triple gets a sane set of defaults.
361245431Sdimstatic void initialize(TargetLibraryInfo &TLI, const Triple &T,
362245431Sdim                       const char **StandardNames) {
363218885Sdim  initializeTargetLibraryInfoPass(*PassRegistry::getPassRegistry());
364218885Sdim
365245431Sdim#ifndef NDEBUG
366245431Sdim  // Verify that the StandardNames array is in alphabetical order.
367245431Sdim  for (unsigned F = 1; F < LibFunc::NumLibFuncs; ++F) {
368245431Sdim    if (strcmp(StandardNames[F-1], StandardNames[F]) >= 0)
369245431Sdim      llvm_unreachable("TargetLibraryInfo function names must be sorted");
370245431Sdim  }
371245431Sdim#endif // !NDEBUG
372218885Sdim
373218885Sdim  // memset_pattern16 is only available on iOS 3.0 and Mac OS/X 10.5 and later.
374221345Sdim  if (T.isMacOSX()) {
375221345Sdim    if (T.isMacOSXVersionLT(10, 5))
376221345Sdim      TLI.setUnavailable(LibFunc::memset_pattern16);
377263509Sdim  } else if (T.isiOS()) {
378221345Sdim    if (T.isOSVersionLT(3, 0))
379221345Sdim      TLI.setUnavailable(LibFunc::memset_pattern16);
380221345Sdim  } else {
381218885Sdim    TLI.setUnavailable(LibFunc::memset_pattern16);
382221345Sdim  }
383221345Sdim
384263509Sdim  if (!hasSinCosPiStret(T)) {
385263509Sdim    TLI.setUnavailable(LibFunc::sinpi);
386263509Sdim    TLI.setUnavailable(LibFunc::sinpif);
387263509Sdim    TLI.setUnavailable(LibFunc::cospi);
388263509Sdim    TLI.setUnavailable(LibFunc::cospif);
389263509Sdim    TLI.setUnavailable(LibFunc::sincospi_stret);
390263509Sdim    TLI.setUnavailable(LibFunc::sincospi_stretf);
391263509Sdim  }
392263509Sdim
393235633Sdim  if (T.isMacOSX() && T.getArch() == Triple::x86 &&
394235633Sdim      !T.isMacOSXVersionLT(10, 7)) {
395235633Sdim    // x86-32 OSX has a scheme where fwrite and fputs (and some other functions
396235633Sdim    // we don't care about) have two versions; on recent OSX, the one we want
397235633Sdim    // has a $UNIX2003 suffix. The two implementations are identical except
398235633Sdim    // for the return value in some edge cases.  However, we don't want to
399235633Sdim    // generate code that depends on the old symbols.
400235633Sdim    TLI.setAvailableWithName(LibFunc::fwrite, "fwrite$UNIX2003");
401235633Sdim    TLI.setAvailableWithName(LibFunc::fputs, "fputs$UNIX2003");
402235633Sdim  }
403235633Sdim
404223017Sdim  // iprintf and friends are only available on XCore and TCE.
405223017Sdim  if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce) {
406221345Sdim    TLI.setUnavailable(LibFunc::iprintf);
407221345Sdim    TLI.setUnavailable(LibFunc::siprintf);
408221345Sdim    TLI.setUnavailable(LibFunc::fiprintf);
409221345Sdim  }
410235633Sdim
411235633Sdim  if (T.getOS() == Triple::Win32) {
412235633Sdim    // Win32 does not support long double
413235633Sdim    TLI.setUnavailable(LibFunc::acosl);
414235633Sdim    TLI.setUnavailable(LibFunc::asinl);
415235633Sdim    TLI.setUnavailable(LibFunc::atanl);
416235633Sdim    TLI.setUnavailable(LibFunc::atan2l);
417235633Sdim    TLI.setUnavailable(LibFunc::ceill);
418235633Sdim    TLI.setUnavailable(LibFunc::copysignl);
419235633Sdim    TLI.setUnavailable(LibFunc::cosl);
420235633Sdim    TLI.setUnavailable(LibFunc::coshl);
421235633Sdim    TLI.setUnavailable(LibFunc::expl);
422235633Sdim    TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf
423235633Sdim    TLI.setUnavailable(LibFunc::fabsl);
424235633Sdim    TLI.setUnavailable(LibFunc::floorl);
425235633Sdim    TLI.setUnavailable(LibFunc::fmodl);
426252723Sdim    TLI.setUnavailable(LibFunc::frexpl);
427235633Sdim    TLI.setUnavailable(LibFunc::logl);
428252723Sdim    TLI.setUnavailable(LibFunc::modfl);
429235633Sdim    TLI.setUnavailable(LibFunc::powl);
430235633Sdim    TLI.setUnavailable(LibFunc::sinl);
431235633Sdim    TLI.setUnavailable(LibFunc::sinhl);
432235633Sdim    TLI.setUnavailable(LibFunc::sqrtl);
433235633Sdim    TLI.setUnavailable(LibFunc::tanl);
434235633Sdim    TLI.setUnavailable(LibFunc::tanhl);
435235633Sdim
436235633Sdim    // Win32 only has C89 math
437245431Sdim    TLI.setUnavailable(LibFunc::acosh);
438245431Sdim    TLI.setUnavailable(LibFunc::acoshf);
439245431Sdim    TLI.setUnavailable(LibFunc::acoshl);
440245431Sdim    TLI.setUnavailable(LibFunc::asinh);
441245431Sdim    TLI.setUnavailable(LibFunc::asinhf);
442245431Sdim    TLI.setUnavailable(LibFunc::asinhl);
443245431Sdim    TLI.setUnavailable(LibFunc::atanh);
444245431Sdim    TLI.setUnavailable(LibFunc::atanhf);
445245431Sdim    TLI.setUnavailable(LibFunc::atanhl);
446245431Sdim    TLI.setUnavailable(LibFunc::cbrt);
447245431Sdim    TLI.setUnavailable(LibFunc::cbrtf);
448245431Sdim    TLI.setUnavailable(LibFunc::cbrtl);
449245431Sdim    TLI.setUnavailable(LibFunc::exp10);
450245431Sdim    TLI.setUnavailable(LibFunc::exp10f);
451245431Sdim    TLI.setUnavailable(LibFunc::exp10l);
452235633Sdim    TLI.setUnavailable(LibFunc::exp2);
453235633Sdim    TLI.setUnavailable(LibFunc::exp2f);
454235633Sdim    TLI.setUnavailable(LibFunc::exp2l);
455235633Sdim    TLI.setUnavailable(LibFunc::expm1);
456235633Sdim    TLI.setUnavailable(LibFunc::expm1f);
457235633Sdim    TLI.setUnavailable(LibFunc::expm1l);
458235633Sdim    TLI.setUnavailable(LibFunc::log2);
459235633Sdim    TLI.setUnavailable(LibFunc::log2f);
460235633Sdim    TLI.setUnavailable(LibFunc::log2l);
461235633Sdim    TLI.setUnavailable(LibFunc::log1p);
462235633Sdim    TLI.setUnavailable(LibFunc::log1pf);
463235633Sdim    TLI.setUnavailable(LibFunc::log1pl);
464245431Sdim    TLI.setUnavailable(LibFunc::logb);
465245431Sdim    TLI.setUnavailable(LibFunc::logbf);
466245431Sdim    TLI.setUnavailable(LibFunc::logbl);
467235633Sdim    TLI.setUnavailable(LibFunc::nearbyint);
468235633Sdim    TLI.setUnavailable(LibFunc::nearbyintf);
469235633Sdim    TLI.setUnavailable(LibFunc::nearbyintl);
470235633Sdim    TLI.setUnavailable(LibFunc::rint);
471235633Sdim    TLI.setUnavailable(LibFunc::rintf);
472235633Sdim    TLI.setUnavailable(LibFunc::rintl);
473235633Sdim    TLI.setUnavailable(LibFunc::round);
474235633Sdim    TLI.setUnavailable(LibFunc::roundf);
475235633Sdim    TLI.setUnavailable(LibFunc::roundl);
476235633Sdim    TLI.setUnavailable(LibFunc::trunc);
477235633Sdim    TLI.setUnavailable(LibFunc::truncf);
478235633Sdim    TLI.setUnavailable(LibFunc::truncl);
479235633Sdim
480235633Sdim    // Win32 provides some C99 math with mangled names
481235633Sdim    TLI.setAvailableWithName(LibFunc::copysign, "_copysign");
482235633Sdim
483235633Sdim    if (T.getArch() == Triple::x86) {
484235633Sdim      // Win32 on x86 implements single-precision math functions as macros
485235633Sdim      TLI.setUnavailable(LibFunc::acosf);
486235633Sdim      TLI.setUnavailable(LibFunc::asinf);
487235633Sdim      TLI.setUnavailable(LibFunc::atanf);
488235633Sdim      TLI.setUnavailable(LibFunc::atan2f);
489235633Sdim      TLI.setUnavailable(LibFunc::ceilf);
490235633Sdim      TLI.setUnavailable(LibFunc::copysignf);
491235633Sdim      TLI.setUnavailable(LibFunc::cosf);
492235633Sdim      TLI.setUnavailable(LibFunc::coshf);
493235633Sdim      TLI.setUnavailable(LibFunc::expf);
494235633Sdim      TLI.setUnavailable(LibFunc::floorf);
495235633Sdim      TLI.setUnavailable(LibFunc::fmodf);
496235633Sdim      TLI.setUnavailable(LibFunc::logf);
497235633Sdim      TLI.setUnavailable(LibFunc::powf);
498235633Sdim      TLI.setUnavailable(LibFunc::sinf);
499235633Sdim      TLI.setUnavailable(LibFunc::sinhf);
500235633Sdim      TLI.setUnavailable(LibFunc::sqrtf);
501235633Sdim      TLI.setUnavailable(LibFunc::tanf);
502235633Sdim      TLI.setUnavailable(LibFunc::tanhf);
503235633Sdim    }
504245431Sdim
505252723Sdim    // Win32 does *not* provide provide these functions, but they are
506252723Sdim    // generally available on POSIX-compliant systems:
507252723Sdim    TLI.setUnavailable(LibFunc::access);
508252723Sdim    TLI.setUnavailable(LibFunc::bcmp);
509252723Sdim    TLI.setUnavailable(LibFunc::bcopy);
510252723Sdim    TLI.setUnavailable(LibFunc::bzero);
511252723Sdim    TLI.setUnavailable(LibFunc::chmod);
512252723Sdim    TLI.setUnavailable(LibFunc::chown);
513252723Sdim    TLI.setUnavailable(LibFunc::closedir);
514252723Sdim    TLI.setUnavailable(LibFunc::ctermid);
515252723Sdim    TLI.setUnavailable(LibFunc::fdopen);
516252723Sdim    TLI.setUnavailable(LibFunc::ffs);
517252723Sdim    TLI.setUnavailable(LibFunc::fileno);
518252723Sdim    TLI.setUnavailable(LibFunc::flockfile);
519252723Sdim    TLI.setUnavailable(LibFunc::fseeko);
520252723Sdim    TLI.setUnavailable(LibFunc::fstat);
521252723Sdim    TLI.setUnavailable(LibFunc::fstatvfs);
522252723Sdim    TLI.setUnavailable(LibFunc::ftello);
523252723Sdim    TLI.setUnavailable(LibFunc::ftrylockfile);
524252723Sdim    TLI.setUnavailable(LibFunc::funlockfile);
525252723Sdim    TLI.setUnavailable(LibFunc::getc_unlocked);
526252723Sdim    TLI.setUnavailable(LibFunc::getitimer);
527252723Sdim    TLI.setUnavailable(LibFunc::getlogin_r);
528252723Sdim    TLI.setUnavailable(LibFunc::getpwnam);
529263509Sdim    TLI.setUnavailable(LibFunc::gettimeofday);
530252723Sdim    TLI.setUnavailable(LibFunc::htonl);
531252723Sdim    TLI.setUnavailable(LibFunc::htons);
532252723Sdim    TLI.setUnavailable(LibFunc::lchown);
533252723Sdim    TLI.setUnavailable(LibFunc::lstat);
534252723Sdim    TLI.setUnavailable(LibFunc::memccpy);
535252723Sdim    TLI.setUnavailable(LibFunc::mkdir);
536252723Sdim    TLI.setUnavailable(LibFunc::ntohl);
537252723Sdim    TLI.setUnavailable(LibFunc::ntohs);
538252723Sdim    TLI.setUnavailable(LibFunc::open);
539252723Sdim    TLI.setUnavailable(LibFunc::opendir);
540252723Sdim    TLI.setUnavailable(LibFunc::pclose);
541252723Sdim    TLI.setUnavailable(LibFunc::popen);
542252723Sdim    TLI.setUnavailable(LibFunc::pread);
543252723Sdim    TLI.setUnavailable(LibFunc::pwrite);
544252723Sdim    TLI.setUnavailable(LibFunc::read);
545252723Sdim    TLI.setUnavailable(LibFunc::readlink);
546252723Sdim    TLI.setUnavailable(LibFunc::realpath);
547252723Sdim    TLI.setUnavailable(LibFunc::rmdir);
548252723Sdim    TLI.setUnavailable(LibFunc::setitimer);
549252723Sdim    TLI.setUnavailable(LibFunc::stat);
550252723Sdim    TLI.setUnavailable(LibFunc::statvfs);
551245431Sdim    TLI.setUnavailable(LibFunc::stpcpy);
552252723Sdim    TLI.setUnavailable(LibFunc::stpncpy);
553252723Sdim    TLI.setUnavailable(LibFunc::strcasecmp);
554252723Sdim    TLI.setUnavailable(LibFunc::strncasecmp);
555252723Sdim    TLI.setUnavailable(LibFunc::times);
556252723Sdim    TLI.setUnavailable(LibFunc::uname);
557252723Sdim    TLI.setUnavailable(LibFunc::unlink);
558252723Sdim    TLI.setUnavailable(LibFunc::unsetenv);
559252723Sdim    TLI.setUnavailable(LibFunc::utime);
560252723Sdim    TLI.setUnavailable(LibFunc::utimes);
561252723Sdim    TLI.setUnavailable(LibFunc::write);
562252723Sdim
563252723Sdim    // Win32 does *not* provide provide these functions, but they are
564252723Sdim    // specified by C99:
565252723Sdim    TLI.setUnavailable(LibFunc::atoll);
566252723Sdim    TLI.setUnavailable(LibFunc::frexpf);
567252723Sdim    TLI.setUnavailable(LibFunc::llabs);
568235633Sdim  }
569252723Sdim
570252723Sdim  // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and
571252723Sdim  // Linux (GLIBC):
572252723Sdim  // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/ffsl.3.html
573252723Sdim  // http://svn.freebsd.org/base/user/eri/pf45/head/lib/libc/string/ffsl.c
574252723Sdim  // http://www.gnu.org/software/gnulib/manual/html_node/ffsl.html
575252723Sdim  switch (T.getOS()) {
576252723Sdim  case Triple::Darwin:
577252723Sdim  case Triple::MacOSX:
578252723Sdim  case Triple::IOS:
579252723Sdim  case Triple::FreeBSD:
580252723Sdim  case Triple::Linux:
581252723Sdim    break;
582252723Sdim  default:
583252723Sdim    TLI.setUnavailable(LibFunc::ffsl);
584252723Sdim  }
585252723Sdim
586252723Sdim  // ffsll is available on at least FreeBSD and Linux (GLIBC):
587252723Sdim  // http://svn.freebsd.org/base/user/eri/pf45/head/lib/libc/string/ffsll.c
588252723Sdim  // http://www.gnu.org/software/gnulib/manual/html_node/ffsll.html
589252723Sdim  switch (T.getOS()) {
590252723Sdim  case Triple::FreeBSD:
591252723Sdim  case Triple::Linux:
592252723Sdim    break;
593252723Sdim  default:
594252723Sdim    TLI.setUnavailable(LibFunc::ffsll);
595252723Sdim  }
596252723Sdim
597252723Sdim  // The following functions are available on at least Linux:
598263509Sdim  if (!T.isOSLinux()) {
599252723Sdim    TLI.setUnavailable(LibFunc::dunder_strdup);
600252723Sdim    TLI.setUnavailable(LibFunc::dunder_strtok_r);
601252723Sdim    TLI.setUnavailable(LibFunc::dunder_isoc99_scanf);
602252723Sdim    TLI.setUnavailable(LibFunc::dunder_isoc99_sscanf);
603252723Sdim    TLI.setUnavailable(LibFunc::under_IO_getc);
604252723Sdim    TLI.setUnavailable(LibFunc::under_IO_putc);
605252723Sdim    TLI.setUnavailable(LibFunc::memalign);
606252723Sdim    TLI.setUnavailable(LibFunc::fopen64);
607252723Sdim    TLI.setUnavailable(LibFunc::fseeko64);
608252723Sdim    TLI.setUnavailable(LibFunc::fstat64);
609252723Sdim    TLI.setUnavailable(LibFunc::fstatvfs64);
610252723Sdim    TLI.setUnavailable(LibFunc::ftello64);
611252723Sdim    TLI.setUnavailable(LibFunc::lstat64);
612252723Sdim    TLI.setUnavailable(LibFunc::open64);
613252723Sdim    TLI.setUnavailable(LibFunc::stat64);
614252723Sdim    TLI.setUnavailable(LibFunc::statvfs64);
615252723Sdim    TLI.setUnavailable(LibFunc::tmpfile64);
616252723Sdim  }
617218885Sdim}
618218885Sdim
619218885Sdim
620218885SdimTargetLibraryInfo::TargetLibraryInfo() : ImmutablePass(ID) {
621218885Sdim  // Default to everything being available.
622218885Sdim  memset(AvailableArray, -1, sizeof(AvailableArray));
623218885Sdim
624245431Sdim  initialize(*this, Triple(), StandardNames);
625218885Sdim}
626218885Sdim
627218885SdimTargetLibraryInfo::TargetLibraryInfo(const Triple &T) : ImmutablePass(ID) {
628218885Sdim  // Default to everything being available.
629218885Sdim  memset(AvailableArray, -1, sizeof(AvailableArray));
630218885Sdim
631245431Sdim  initialize(*this, T, StandardNames);
632218885Sdim}
633218885Sdim
634223017SdimTargetLibraryInfo::TargetLibraryInfo(const TargetLibraryInfo &TLI)
635223017Sdim  : ImmutablePass(ID) {
636223017Sdim  memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
637235633Sdim  CustomNames = TLI.CustomNames;
638223017Sdim}
639223017Sdim
640252723Sdimnamespace {
641252723Sdimstruct StringComparator {
642252723Sdim  /// Compare two strings and return true if LHS is lexicographically less than
643252723Sdim  /// RHS. Requires that RHS doesn't contain any zero bytes.
644252723Sdim  bool operator()(const char *LHS, StringRef RHS) const {
645252723Sdim    // Compare prefixes with strncmp. If prefixes match we know that LHS is
646252723Sdim    // greater or equal to RHS as RHS can't contain any '\0'.
647252723Sdim    return std::strncmp(LHS, RHS.data(), RHS.size()) < 0;
648252723Sdim  }
649252723Sdim
650252723Sdim  // Provided for compatibility with MSVC's debug mode.
651252723Sdim  bool operator()(StringRef LHS, const char *RHS) const { return LHS < RHS; }
652252723Sdim  bool operator()(StringRef LHS, StringRef RHS) const { return LHS < RHS; }
653252723Sdim  bool operator()(const char *LHS, const char *RHS) const {
654252723Sdim    return std::strcmp(LHS, RHS) < 0;
655252723Sdim  }
656252723Sdim};
657252723Sdim}
658252723Sdim
659245431Sdimbool TargetLibraryInfo::getLibFunc(StringRef funcName,
660245431Sdim                                   LibFunc::Func &F) const {
661245431Sdim  const char **Start = &StandardNames[0];
662245431Sdim  const char **End = &StandardNames[LibFunc::NumLibFuncs];
663252723Sdim
664252723Sdim  // Filter out empty names and names containing null bytes, those can't be in
665252723Sdim  // our table.
666252723Sdim  if (funcName.empty() || funcName.find('\0') != StringRef::npos)
667252723Sdim    return false;
668252723Sdim
669252723Sdim  // Check for \01 prefix that is used to mangle __asm declarations and
670252723Sdim  // strip it if present.
671252723Sdim  if (funcName.front() == '\01')
672252723Sdim    funcName = funcName.substr(1);
673252723Sdim  const char **I = std::lower_bound(Start, End, funcName, StringComparator());
674245431Sdim  if (I != End && *I == funcName) {
675245431Sdim    F = (LibFunc::Func)(I - Start);
676245431Sdim    return true;
677245431Sdim  }
678245431Sdim  return false;
679245431Sdim}
680223017Sdim
681218885Sdim/// disableAllFunctions - This disables all builtins, which is used for options
682218885Sdim/// like -fno-builtin.
683218885Sdimvoid TargetLibraryInfo::disableAllFunctions() {
684218885Sdim  memset(AvailableArray, 0, sizeof(AvailableArray));
685218885Sdim}
686