// Checks if there is a conflict between the input and output lists with the // clobbers list. If there's a conflict, returns the location of the // conflicted clobber, else returns nullptr static SourceLocation getClobberConflictLocation(MultiExprArg Exprs, StringLiteral **Constraints, StringLiteral **Clobbers, int NumClobbers, const TargetInfo &Target, ASTContext &Cont) { llvm::StringSet<> InOutVars; // Collect all the input and output registers from the extended asm // statement in order to check for conflicts with the clobber list for (unsigned int i = 0; i < Exprs.size(); ++i) { StringRef Constraint = Constraints[i]->getString(); StringRef InOutReg = Target.getConstraintRegister( Constraint, extractRegisterName(Exprs[i], Target)); if (InOutReg != "") InOutVars.insert(InOutReg); } // Check for each item in the clobber list if it conflicts with the input // or output for (int i = 0; i < NumClobbers; ++i) { StringRef Clobber = Clobbers[i]->getString(); // We only check registers, therefore we don't check cc and memory // clobbers if (Clobber == "cc" || Clobber == "memory") continue; Clobber = Target.getNormalizedGCCRegisterName(Clobber, true); // Go over the output's registers we collected if (InOutVars.count(Clobber)) return Clobbers[i]->getLocStart(); } return SourceLocation(); }
static void DefineFmt(const Twine &Prefix, TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { bool IsSigned = TI.isTypeSigned(Ty); StringRef FmtModifier = TI.getTypeFormatModifier(Ty); for (const char *Fmt = IsSigned ? "di" : "ouxX"; *Fmt; ++Fmt) { Builder.defineMacro(Prefix + "_FMT" + Twine(*Fmt) + "__", Twine("\"") + FmtModifier + Twine(*Fmt) + "\""); } }
void DumpSTG( const TargetInfo& ti, SymbolManager *symbol, target_ptr_t sp, uint32_t starting_depth) { // TODO: See GHC's 'Printer.c' on how we could print more information about what's on // the stack // Traverse and print the passed STG stack for (unsigned int depth=starting_depth; depth<128; depth++) { // Top closure const target_ptr_t info = ti.ReadMemoryPtr(sp); const uint32_t sym_id = symbol->AddressToSymbolID(info); Indent(depth); // Let our wrapper collect the required information uint32_t closure_type, closure_size; target_ptr_t fun_ref; if (GetClosureTypeAndSize(ti.m_task_port, sp, &closure_type, &closure_size, &fun_ref) != 0) { std::printf("0x%x (Can't read stack frame)\n", sp); break; } // Referenced closure char ref_buf[256] = { 0 }; if (fun_ref != 0) { std::snprintf( ref_buf, sizeof(ref_buf), ", <%s>", symbol->SymbolIDToName(symbol->AddressToSymbolID(ti.ReadMemoryPtr(fun_ref)))); } std::printf("0x%x <%s> (%s, %ib%s)\n", sp, symbol->SymbolIDToName(sym_id), ClosureTypeToString(closure_type), closure_size, ref_buf); if (closure_type == wrapper_STOP_FRAME) break; // TODO: Handle underflow frames if (closure_type == wrapper_UNDERFLOW_FRAME) break; sp += closure_size; } }
/// \brief Determine whether a translation unit built using the current /// language options has the given feature. static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target) { return llvm::StringSwitch<bool>(Feature) .Case("altivec", LangOpts.AltiVec) .Case("blocks", LangOpts.Blocks) .Case("cplusplus", LangOpts.CPlusPlus) .Case("cplusplus11", LangOpts.CPlusPlus11) .Case("objc", LangOpts.ObjC1) .Case("objc_arc", LangOpts.ObjCAutoRefCount) .Case("opencl", LangOpts.OpenCL) .Case("tls", Target.isTLSSupported()) .Default(Target.hasFeature(Feature)); }
// Extracting the register name from the Expression value, // if there is no register name to extract, returns "" static StringRef extractRegisterName(const Expr *Expression, const TargetInfo &Target) { Expression = Expression->IgnoreImpCasts(); if (const DeclRefExpr *AsmDeclRef = dyn_cast<DeclRefExpr>(Expression)) { // Handle cases where the expression is a variable const VarDecl *Variable = dyn_cast<VarDecl>(AsmDeclRef->getDecl()); if (Variable && Variable->getStorageClass() == SC_Register) { if (AsmLabelAttr *Attr = Variable->getAttr<AsmLabelAttr>()) if (Target.isValidGCCRegisterName(Attr->getLabel())) return Target.getNormalizedGCCRegisterName(Attr->getLabel(), true); } } return ""; }
static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { int TypeWidth = TI.getTypeWidth(Ty); bool IsSigned = TI.isTypeSigned(Ty); // Use the target specified int64 type, when appropriate, so that [u]int64_t // ends up being defined in terms of the correct type. if (TypeWidth == 64) Ty = IsSigned ? TI.getInt64Type() : TI.getUInt64Type(); const char *Prefix = IsSigned ? "__INT" : "__UINT"; DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); }
void Builtin::Context::InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget) { assert(TSRecords.empty() && "Already initialized target?"); TSRecords = Target.getTargetBuiltins(); if (AuxTarget) AuxTSRecords = AuxTarget->getTargetBuiltins(); }
static void DefineExactWidthIntType(TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { int TypeWidth = TI.getTypeWidth(Ty); // Use the target specified int64 type, when appropriate, so that [u]int64_t // ends up being defined in terms of the correct type. if (TypeWidth == 64) Ty = TI.getInt64Type(); DefineType("__INT" + Twine(TypeWidth) + "_TYPE__", Ty, Builder); StringRef ConstSuffix(TargetInfo::getTypeConstantSuffix(Ty)); if (!ConstSuffix.empty()) Builder.defineMacro("__INT" + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix); }
bool CallingConvention_x86_64_systemv::matches(TargetInfo &target, Executable &executable) const { const char arch[] = "x86"; const char exe[] = "ELF 64"; return strncmp(target.targetName().c_str(), arch, sizeof arch - 1) == 0 && strncmp(executable.getExecutableType().c_str(), exe, sizeof exe - 1) == 0; }
void c2ffi::init_ci(config &c, clang::CompilerInstance &ci) { using clang::DiagnosticOptions; using clang::TextDiagnosticPrinter; using clang::TargetOptions; using clang::TargetInfo; DiagnosticOptions *dopt = new DiagnosticOptions; TextDiagnosticPrinter *tpd = new TextDiagnosticPrinter(llvm::errs(), dopt, false); ci.createDiagnostics(tpd); std::shared_ptr<TargetOptions> pto = std::shared_ptr<TargetOptions>(new TargetOptions()); if(c.arch == "") pto->Triple = llvm::sys::getDefaultTargetTriple(); else pto->Triple = c.arch; TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto); clang::LangOptions &lo = ci.getLangOpts(); switch(pti->getTriple().getEnvironment()) { case llvm::Triple::EnvironmentType::GNU: lo.GNUMode = 1; break; case llvm::Triple::EnvironmentType::MSVC: lo.MSVCCompat = 1; lo.MicrosoftExt = 1; break; default: std::cerr << "c2ffi warning: Unhandled environment: '" << pti->getTriple().getEnvironmentName().str() << "' for triple '" << c.arch << "'" << std::endl; } ci.getInvocation().setLangDefaults(lo, c.kind, c.std); ci.setTarget(pti); ci.createFileManager(); ci.createSourceManager(ci.getFileManager()); ci.createPreprocessor(clang::TU_Complete); ci.getPreprocessorOpts().UsePredefines = false; ci.getPreprocessorOutputOpts().ShowCPP = c.preprocess_only; ci.getPreprocessor().setPreprocessedOutput(c.preprocess_only); }
void DumpCCS(const TargetInfo& ti, target_ptr_t ccs, uint32_t starting_depth) { // Traverse and print the passed Cost Center Stack for (unsigned int depth=starting_depth; depth<64; depth++) { Indent(depth); // Get CC pointer from CCS const target_ptr_t cc = ti.ReadMemoryPtr(ccs + OFFSET_ConstCentreStack_cc); if (cc == 0) { std::printf("(Can't read CC pointer)\n"); break; } // Retrieve symbol information from CC const target_ptr_t label_ptr = ti.ReadMemoryPtr(cc + OFFSET_ConstCentre_label); const target_ptr_t module_ptr = ti.ReadMemoryPtr(cc + OFFSET_ConstCentre_module); const target_ptr_t srcloc_ptr = ti.ReadMemoryPtr(cc + OFFSET_ConstCentre_srcloc); char label[256], module[256], srcloc[256]; if (ti.ReadMemoryString(label_ptr, label, sizeof(label)) == false) std::strcpy(label, "(can't read label)"); if (ti.ReadMemoryString(module_ptr, module, sizeof(module)) == false) std::strcpy(module, "(can't read module)"); if (ti.ReadMemoryString(srcloc_ptr, srcloc, sizeof(srcloc)) == false) std::strcpy(srcloc, "(can't read srcloc)"); std::printf("CCS:0x%x <%s> from %s (%s)\n", ccs, label, module, srcloc); // Walk the CC stack ccs = ti.ReadMemoryPtr(ccs + OFFSET_ConstCentreStack_prevStack); if (ccs == 0) break; } }
// Determine if this is a simple MSAsm instruction. static bool isSimpleMSAsm(std::vector<StringRef> &Pieces, const TargetInfo &TI) { if (isMSAsmKeyword(Pieces[0])) return false; for (unsigned i = 1, e = Pieces.size(); i != e; ++i) if (!TI.isValidGCCRegisterName(Pieces[i])) return false; return true; }
static void DefineExactWidthIntType(TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { int TypeWidth = TI.getTypeWidth(Ty); bool IsSigned = TI.isTypeSigned(Ty); // Use the target specified int64 type, when appropriate, so that [u]int64_t // ends up being defined in terms of the correct type. if (TypeWidth == 64) Ty = IsSigned ? TI.getInt64Type() : TI.getIntTypeByWidth(64, false); const char *Prefix = IsSigned ? "__INT" : "__UINT"; DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder); StringRef ConstSuffix(TargetInfo::getTypeConstantSuffix(Ty)); if (!ConstSuffix.empty()) Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix); }
void CIFactory::SetClingTargetLangOpts(LangOptions& Opts, const TargetInfo& Target) { if (Target.getTriple().getOS() == llvm::Triple::Win32) { Opts.MicrosoftExt = 1; Opts.MSCVersion = 1300; // Should fix http://llvm.org/bugs/show_bug.cgi?id=10528 Opts.DelayedTemplateParsing = 1; } else { Opts.MicrosoftExt = 0; } }
/// \brief Determine whether a translation unit built using the current /// language options has the given feature. static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target) { bool HasFeature = llvm::StringSwitch<bool>(Feature) .Case("altivec", LangOpts.AltiVec) .Case("blocks", LangOpts.Blocks) .Case("cplusplus", LangOpts.CPlusPlus) .Case("cplusplus11", LangOpts.CPlusPlus11) .Case("objc", LangOpts.ObjC1) .Case("objc_arc", LangOpts.ObjCAutoRefCount) .Case("opencl", LangOpts.OpenCL) .Case("tls", Target.isTLSSupported()) .Case("zvector", LangOpts.ZVector) .Case("cplusplusamp", LangOpts.CPlusPlusAMP) .Default(Target.hasFeature(Feature)); if (!HasFeature) HasFeature = std::find(LangOpts.ModuleFeatures.begin(), LangOpts.ModuleFeatures.end(), Feature) != LangOpts.ModuleFeatures.end(); return HasFeature; }
static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned, const TargetInfo &TI, MacroBuilder &Builder) { TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned); if (Ty == TargetInfo::NoInt) return; const char *Prefix = IsSigned ? "__INT_LEAST" : "__UINT_LEAST"; DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder); DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); }
static void DefineFastIntType(unsigned TypeWidth, bool IsSigned, const TargetInfo &TI, MacroBuilder &Builder) { // stdint.h currently defines the fast int types as equivalent to the least // types. TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned); if (Ty == TargetInfo::NoInt) return; const char *Prefix = IsSigned ? "__INT_FAST" : "__UINT_FAST"; DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder); DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); }
static void DefineExactWidthIntType(TargetInfo::IntType Ty, const TargetInfo &TI, std::vector<char> &Buf) { char MacroBuf[60]; int TypeWidth = TI.getTypeWidth(Ty); sprintf(MacroBuf, "__INT%d_TYPE__", TypeWidth); DefineType(MacroBuf, Ty, Buf); const char *ConstSuffix = TargetInfo::getTypeConstantSuffix(Ty); if (strlen(ConstSuffix) > 0) { sprintf(MacroBuf, "__INT%d_C_SUFFIX__=%s", TypeWidth, ConstSuffix); DefineBuiltinMacro(Buf, MacroBuf); } }
static std::string SimplifyConstraint(const char *Constraint, TargetInfo &Target, llvm::SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=0) { std::string Result; while (*Constraint) { switch (*Constraint) { default: Result += Target.convertConstraint(*Constraint); break; // Ignore these case '*': case '?': case '!': break; case 'g': Result += "imr"; break; case '[': { assert(OutCons && "Must pass output names to constraints with a symbolic name"); unsigned Index; bool result = Target.resolveSymbolicName(Constraint, &(*OutCons)[0], OutCons->size(), Index); assert(result && "Could not resolve symbolic name"); result=result; Result += llvm::utostr(Index); break; } } Constraint++; } return Result; }
static void InitializeStandardPredefinedMacros(const TargetInfo &TI, const LangOptions &LangOpts, const FrontendOptions &FEOpts, MacroBuilder &Builder) { if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP) Builder.defineMacro("__STDC__"); if (LangOpts.Freestanding) Builder.defineMacro("__STDC_HOSTED__", "0"); else Builder.defineMacro("__STDC_HOSTED__"); if (!LangOpts.CPlusPlus) { if (LangOpts.C11) Builder.defineMacro("__STDC_VERSION__", "201112L"); else if (LangOpts.C99) Builder.defineMacro("__STDC_VERSION__", "199901L"); else if (!LangOpts.GNUMode && LangOpts.Digraphs) Builder.defineMacro("__STDC_VERSION__", "199409L"); } else { // FIXME: Use correct value for C++17. if (LangOpts.CPlusPlus1z) Builder.defineMacro("__cplusplus", "201406L"); // C++1y [cpp.predefined]p1: // The name __cplusplus is defined to the value 201402L when compiling a // C++ translation unit. else if (LangOpts.CPlusPlus14) Builder.defineMacro("__cplusplus", "201402L"); // C++11 [cpp.predefined]p1: // The name __cplusplus is defined to the value 201103L when compiling a // C++ translation unit. else if (LangOpts.CPlusPlus11) Builder.defineMacro("__cplusplus", "201103L"); // C++03 [cpp.predefined]p1: // The name __cplusplus is defined to the value 199711L when compiling a // C++ translation unit. else Builder.defineMacro("__cplusplus", "199711L"); // C++1z [cpp.predefined]p1: // An integer literal of type std::size_t whose value is the alignment // guaranteed by a call to operator new(std::size_t) // // We provide this in all language modes, since it seems generally useful. Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__", Twine(TI.getNewAlign() / TI.getCharWidth()) + TI.getTypeConstantSuffix(TI.getSizeType())); } // In C11 these are environment macros. In C++11 they are only defined // as part of <cuchar>. To prevent breakage when mixing C and C++ // code, define these macros unconditionally. We can define them // unconditionally, as Clang always uses UTF-16 and UTF-32 for 16-bit // and 32-bit character literals. Builder.defineMacro("__STDC_UTF_16__", "1"); Builder.defineMacro("__STDC_UTF_32__", "1"); if (LangOpts.ObjC1) Builder.defineMacro("__OBJC__"); // OpenCL v1.0/1.1 s6.9, v1.2/2.0 s6.10: Preprocessor Directives and Macros. if (LangOpts.OpenCL) { // OpenCL v1.0 and v1.1 do not have a predefined macro to indicate the // language standard with which the program is compiled. __OPENCL_VERSION__ // is for the OpenCL version supported by the OpenCL device, which is not // necessarily the language standard with which the program is compiled. // A shared OpenCL header file requires a macro to indicate the language // standard. As a workaround, __OPENCL_C_VERSION__ is defined for // OpenCL v1.0 and v1.1. switch (LangOpts.OpenCLVersion) { case 100: Builder.defineMacro("__OPENCL_C_VERSION__", "100"); break; case 110: Builder.defineMacro("__OPENCL_C_VERSION__", "110"); break; case 120: Builder.defineMacro("__OPENCL_C_VERSION__", "120"); break; case 200: Builder.defineMacro("__OPENCL_C_VERSION__", "200"); break; default: llvm_unreachable("Unsupported OpenCL version"); } Builder.defineMacro("CL_VERSION_1_0", "100"); Builder.defineMacro("CL_VERSION_1_1", "110"); Builder.defineMacro("CL_VERSION_1_2", "120"); Builder.defineMacro("CL_VERSION_2_0", "200"); if (TI.isLittleEndian()) Builder.defineMacro("__ENDIAN_LITTLE__"); if (LangOpts.FastRelaxedMath) Builder.defineMacro("__FAST_RELAXED_MATH__"); } // Not "standard" per se, but available even with the -undef flag. if (LangOpts.AsmPreprocessor) Builder.defineMacro("__ASSEMBLER__"); if (LangOpts.CUDA) Builder.defineMacro("__CUDA__"); }
static void InitializePredefinedMacros(const TargetInfo &TI, const LangOptions &LangOpts, const FrontendOptions &FEOpts, MacroBuilder &Builder) { // Compiler version introspection macros. Builder.defineMacro("__llvm__"); // LLVM Backend Builder.defineMacro("__clang__"); // Clang Frontend #define TOSTR2(X) #X #define TOSTR(X) TOSTR2(X) Builder.defineMacro("__clang_major__", TOSTR(CLANG_VERSION_MAJOR)); Builder.defineMacro("__clang_minor__", TOSTR(CLANG_VERSION_MINOR)); #ifdef CLANG_VERSION_PATCHLEVEL Builder.defineMacro("__clang_patchlevel__", TOSTR(CLANG_VERSION_PATCHLEVEL)); #else Builder.defineMacro("__clang_patchlevel__", "0"); #endif Builder.defineMacro("__clang_version__", "\"" CLANG_VERSION_STRING " " + getClangFullRepositoryVersion() + "\""); #undef TOSTR #undef TOSTR2 if (!LangOpts.MSVCCompat) { // Currently claim to be compatible with GCC 4.2.1-5621, but only if we're // not compiling for MSVC compatibility Builder.defineMacro("__GNUC_MINOR__", "2"); Builder.defineMacro("__GNUC_PATCHLEVEL__", "1"); Builder.defineMacro("__GNUC__", "4"); Builder.defineMacro("__GXX_ABI_VERSION", "1002"); } // Define macros for the C11 / C++11 memory orderings Builder.defineMacro("__ATOMIC_RELAXED", "0"); Builder.defineMacro("__ATOMIC_CONSUME", "1"); Builder.defineMacro("__ATOMIC_ACQUIRE", "2"); Builder.defineMacro("__ATOMIC_RELEASE", "3"); Builder.defineMacro("__ATOMIC_ACQ_REL", "4"); Builder.defineMacro("__ATOMIC_SEQ_CST", "5"); // Support for #pragma redefine_extname (Sun compatibility) Builder.defineMacro("__PRAGMA_REDEFINE_EXTNAME", "1"); // As sad as it is, enough software depends on the __VERSION__ for version // checks that it is necessary to report 4.2.1 (the base GCC version we claim // compatibility with) first. Builder.defineMacro("__VERSION__", "\"4.2.1 Compatible " + Twine(getClangFullCPPVersion()) + "\""); // Initialize language-specific preprocessor defines. // Standard conforming mode? if (!LangOpts.GNUMode && !LangOpts.MSVCCompat) Builder.defineMacro("__STRICT_ANSI__"); if (!LangOpts.MSVCCompat && LangOpts.CPlusPlus11) Builder.defineMacro("__GXX_EXPERIMENTAL_CXX0X__"); if (LangOpts.ObjC1) { if (LangOpts.ObjCRuntime.isNonFragile()) { Builder.defineMacro("__OBJC2__"); if (LangOpts.ObjCExceptions) Builder.defineMacro("OBJC_ZEROCOST_EXCEPTIONS"); } if (LangOpts.getGC() != LangOptions::NonGC) Builder.defineMacro("__OBJC_GC__"); if (LangOpts.ObjCRuntime.isNeXTFamily()) Builder.defineMacro("__NEXT_RUNTIME__"); if (LangOpts.ObjCRuntime.getKind() == ObjCRuntime::ObjFW) { VersionTuple tuple = LangOpts.ObjCRuntime.getVersion(); unsigned minor = 0; if (tuple.getMinor().hasValue()) minor = tuple.getMinor().getValue(); unsigned subminor = 0; if (tuple.getSubminor().hasValue()) subminor = tuple.getSubminor().getValue(); Builder.defineMacro("__OBJFW_RUNTIME_ABI__", Twine(tuple.getMajor() * 10000 + minor * 100 + subminor)); } Builder.defineMacro("IBOutlet", "__attribute__((iboutlet))"); Builder.defineMacro("IBOutletCollection(ClassName)", "__attribute__((iboutletcollection(ClassName)))"); Builder.defineMacro("IBAction", "void)__attribute__((ibaction)"); Builder.defineMacro("IBInspectable", ""); Builder.defineMacro("IB_DESIGNABLE", ""); } if (LangOpts.CPlusPlus) InitializeCPlusPlusFeatureTestMacros(LangOpts, Builder); // darwin_constant_cfstrings controls this. This is also dependent // on other things like the runtime I believe. This is set even for C code. if (!LangOpts.NoConstantCFStrings) Builder.defineMacro("__CONSTANT_CFSTRINGS__"); if (LangOpts.ObjC2) Builder.defineMacro("OBJC_NEW_PROPERTIES"); if (LangOpts.PascalStrings) Builder.defineMacro("__PASCAL_STRINGS__"); if (LangOpts.Blocks) { Builder.defineMacro("__block", "__attribute__((__blocks__(byref)))"); Builder.defineMacro("__BLOCKS__"); } if (!LangOpts.MSVCCompat && LangOpts.Exceptions) Builder.defineMacro("__EXCEPTIONS"); if (!LangOpts.MSVCCompat && LangOpts.RTTI) Builder.defineMacro("__GXX_RTTI"); if (LangOpts.SjLjExceptions) Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__"); if (LangOpts.Deprecated) Builder.defineMacro("__DEPRECATED"); if (!LangOpts.MSVCCompat && LangOpts.CPlusPlus) { Builder.defineMacro("__GNUG__", "4"); Builder.defineMacro("__GXX_WEAK__"); Builder.defineMacro("__private_extern__", "extern"); } if (LangOpts.MicrosoftExt) { if (LangOpts.WChar) { // wchar_t supported as a keyword. Builder.defineMacro("_WCHAR_T_DEFINED"); Builder.defineMacro("_NATIVE_WCHAR_T_DEFINED"); } } if (LangOpts.Optimize) Builder.defineMacro("__OPTIMIZE__"); if (LangOpts.OptimizeSize) Builder.defineMacro("__OPTIMIZE_SIZE__"); if (LangOpts.FastMath) Builder.defineMacro("__FAST_MATH__"); // Initialize target-specific preprocessor defines. // __BYTE_ORDER__ was added in GCC 4.6. It's analogous // to the macro __BYTE_ORDER (no trailing underscores) // from glibc's <endian.h> header. // We don't support the PDP-11 as a target, but include // the define so it can still be compared against. Builder.defineMacro("__ORDER_LITTLE_ENDIAN__", "1234"); Builder.defineMacro("__ORDER_BIG_ENDIAN__", "4321"); Builder.defineMacro("__ORDER_PDP_ENDIAN__", "3412"); if (TI.isBigEndian()) { Builder.defineMacro("__BYTE_ORDER__", "__ORDER_BIG_ENDIAN__"); Builder.defineMacro("__BIG_ENDIAN__"); } else { Builder.defineMacro("__BYTE_ORDER__", "__ORDER_LITTLE_ENDIAN__"); Builder.defineMacro("__LITTLE_ENDIAN__"); } if (TI.getPointerWidth(0) == 64 && TI.getLongWidth() == 64 && TI.getIntWidth() == 32) { Builder.defineMacro("_LP64"); Builder.defineMacro("__LP64__"); } if (TI.getPointerWidth(0) == 32 && TI.getLongWidth() == 32 && TI.getIntWidth() == 32) { Builder.defineMacro("_ILP32"); Builder.defineMacro("__ILP32__"); } // Define type sizing macros based on the target properties. assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far"); Builder.defineMacro("__CHAR_BIT__", "8"); DefineTypeSize("__SCHAR_MAX__", TargetInfo::SignedChar, TI, Builder); DefineTypeSize("__SHRT_MAX__", TargetInfo::SignedShort, TI, Builder); DefineTypeSize("__INT_MAX__", TargetInfo::SignedInt, TI, Builder); DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, TI, Builder); DefineTypeSize("__LONG_LONG_MAX__", TargetInfo::SignedLongLong, TI, Builder); DefineTypeSize("__WCHAR_MAX__", TI.getWCharType(), TI, Builder); DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Builder); DefineTypeSize("__SIZE_MAX__", TI.getSizeType(), TI, Builder); DefineTypeSize("__UINTMAX_MAX__", TI.getUIntMaxType(), TI, Builder); DefineTypeSize("__PTRDIFF_MAX__", TI.getPtrDiffType(0), TI, Builder); DefineTypeSize("__INTPTR_MAX__", TI.getIntPtrType(), TI, Builder); DefineTypeSize("__UINTPTR_MAX__", TI.getUIntPtrType(), TI, Builder); DefineTypeSizeof("__SIZEOF_DOUBLE__", TI.getDoubleWidth(), TI, Builder); DefineTypeSizeof("__SIZEOF_FLOAT__", TI.getFloatWidth(), TI, Builder); DefineTypeSizeof("__SIZEOF_INT__", TI.getIntWidth(), TI, Builder); DefineTypeSizeof("__SIZEOF_LONG__", TI.getLongWidth(), TI, Builder); DefineTypeSizeof("__SIZEOF_LONG_DOUBLE__",TI.getLongDoubleWidth(),TI,Builder); DefineTypeSizeof("__SIZEOF_LONG_LONG__", TI.getLongLongWidth(), TI, Builder); DefineTypeSizeof("__SIZEOF_POINTER__", TI.getPointerWidth(0), TI, Builder); DefineTypeSizeof("__SIZEOF_SHORT__", TI.getShortWidth(), TI, Builder); DefineTypeSizeof("__SIZEOF_PTRDIFF_T__", TI.getTypeWidth(TI.getPtrDiffType(0)), TI, Builder); DefineTypeSizeof("__SIZEOF_SIZE_T__", TI.getTypeWidth(TI.getSizeType()), TI, Builder); DefineTypeSizeof("__SIZEOF_WCHAR_T__", TI.getTypeWidth(TI.getWCharType()), TI, Builder); DefineTypeSizeof("__SIZEOF_WINT_T__", TI.getTypeWidth(TI.getWIntType()), TI, Builder); if (TI.hasInt128Type()) DefineTypeSizeof("__SIZEOF_INT128__", 128, TI, Builder); DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder); DefineFmt("__INTMAX", TI.getIntMaxType(), TI, Builder); Builder.defineMacro("__INTMAX_C_SUFFIX__", TI.getTypeConstantSuffix(TI.getIntMaxType())); DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder); DefineFmt("__UINTMAX", TI.getUIntMaxType(), TI, Builder); Builder.defineMacro("__UINTMAX_C_SUFFIX__", TI.getTypeConstantSuffix(TI.getUIntMaxType())); DefineTypeWidth("__INTMAX_WIDTH__", TI.getIntMaxType(), TI, Builder); DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(0), Builder); DefineFmt("__PTRDIFF", TI.getPtrDiffType(0), TI, Builder); DefineTypeWidth("__PTRDIFF_WIDTH__", TI.getPtrDiffType(0), TI, Builder); DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder); DefineFmt("__INTPTR", TI.getIntPtrType(), TI, Builder); DefineTypeWidth("__INTPTR_WIDTH__", TI.getIntPtrType(), TI, Builder); DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder); DefineFmt("__SIZE", TI.getSizeType(), TI, Builder); DefineTypeWidth("__SIZE_WIDTH__", TI.getSizeType(), TI, Builder); DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder); DefineTypeWidth("__WCHAR_WIDTH__", TI.getWCharType(), TI, Builder); DefineType("__WINT_TYPE__", TI.getWIntType(), Builder); DefineTypeWidth("__WINT_WIDTH__", TI.getWIntType(), TI, Builder); DefineTypeWidth("__SIG_ATOMIC_WIDTH__", TI.getSigAtomicType(), TI, Builder); DefineTypeSize("__SIG_ATOMIC_MAX__", TI.getSigAtomicType(), TI, Builder); DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder); DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder); DefineTypeWidth("__UINTMAX_WIDTH__", TI.getUIntMaxType(), TI, Builder); DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder); DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder); DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder); DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F"); DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat(), ""); DefineFloatMacros(Builder, "LDBL", &TI.getLongDoubleFormat(), "L"); // Define a __POINTER_WIDTH__ macro for stdint.h. Builder.defineMacro("__POINTER_WIDTH__", Twine((int)TI.getPointerWidth(0))); // Define __BIGGEST_ALIGNMENT__ to be compatible with gcc. Builder.defineMacro("__BIGGEST_ALIGNMENT__", Twine(TI.getSuitableAlign() / TI.getCharWidth()) ); if (!LangOpts.CharIsSigned) Builder.defineMacro("__CHAR_UNSIGNED__"); if (!TargetInfo::isTypeSigned(TI.getWCharType())) Builder.defineMacro("__WCHAR_UNSIGNED__"); if (!TargetInfo::isTypeSigned(TI.getWIntType())) Builder.defineMacro("__WINT_UNSIGNED__"); // Define exact-width integer types for stdint.h DefineExactWidthIntType(TargetInfo::SignedChar, TI, Builder); if (TI.getShortWidth() > TI.getCharWidth()) DefineExactWidthIntType(TargetInfo::SignedShort, TI, Builder); if (TI.getIntWidth() > TI.getShortWidth()) DefineExactWidthIntType(TargetInfo::SignedInt, TI, Builder); if (TI.getLongWidth() > TI.getIntWidth()) DefineExactWidthIntType(TargetInfo::SignedLong, TI, Builder); if (TI.getLongLongWidth() > TI.getLongWidth()) DefineExactWidthIntType(TargetInfo::SignedLongLong, TI, Builder); DefineExactWidthIntType(TargetInfo::UnsignedChar, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder); if (TI.getShortWidth() > TI.getCharWidth()) { DefineExactWidthIntType(TargetInfo::UnsignedShort, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder); } if (TI.getIntWidth() > TI.getShortWidth()) { DefineExactWidthIntType(TargetInfo::UnsignedInt, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder); } if (TI.getLongWidth() > TI.getIntWidth()) { DefineExactWidthIntType(TargetInfo::UnsignedLong, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder); } if (TI.getLongLongWidth() > TI.getLongWidth()) { DefineExactWidthIntType(TargetInfo::UnsignedLongLong, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder); DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder); } DefineLeastWidthIntType(8, true, TI, Builder); DefineLeastWidthIntType(8, false, TI, Builder); DefineLeastWidthIntType(16, true, TI, Builder); DefineLeastWidthIntType(16, false, TI, Builder); DefineLeastWidthIntType(32, true, TI, Builder); DefineLeastWidthIntType(32, false, TI, Builder); DefineLeastWidthIntType(64, true, TI, Builder); DefineLeastWidthIntType(64, false, TI, Builder); DefineFastIntType(8, true, TI, Builder); DefineFastIntType(8, false, TI, Builder); DefineFastIntType(16, true, TI, Builder); DefineFastIntType(16, false, TI, Builder); DefineFastIntType(32, true, TI, Builder); DefineFastIntType(32, false, TI, Builder); DefineFastIntType(64, true, TI, Builder); DefineFastIntType(64, false, TI, Builder); char UserLabelPrefix[2] = {TI.getDataLayout().getGlobalPrefix(), 0}; Builder.defineMacro("__USER_LABEL_PREFIX__", UserLabelPrefix); if (LangOpts.FastMath || LangOpts.FiniteMathOnly) Builder.defineMacro("__FINITE_MATH_ONLY__", "1"); else Builder.defineMacro("__FINITE_MATH_ONLY__", "0"); if (!LangOpts.MSVCCompat) { if (LangOpts.GNUInline || LangOpts.CPlusPlus) Builder.defineMacro("__GNUC_GNU_INLINE__"); else Builder.defineMacro("__GNUC_STDC_INLINE__"); // The value written by __atomic_test_and_set. // FIXME: This is target-dependent. Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1"); // Used by libc++ and libstdc++ to implement ATOMIC_<foo>_LOCK_FREE. unsigned InlineWidthBits = TI.getMaxAtomicInlineWidth(); #define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \ Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \ getLockFreeValue(TI.get##Type##Width(), \ TI.get##Type##Align(), \ InlineWidthBits)); DEFINE_LOCK_FREE_MACRO(BOOL, Bool); DEFINE_LOCK_FREE_MACRO(CHAR, Char); DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16); DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32); DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar); DEFINE_LOCK_FREE_MACRO(SHORT, Short); DEFINE_LOCK_FREE_MACRO(INT, Int); DEFINE_LOCK_FREE_MACRO(LONG, Long); DEFINE_LOCK_FREE_MACRO(LLONG, LongLong); Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE", getLockFreeValue(TI.getPointerWidth(0), TI.getPointerAlign(0), InlineWidthBits)); #undef DEFINE_LOCK_FREE_MACRO } if (LangOpts.NoInlineDefine) Builder.defineMacro("__NO_INLINE__"); if (unsigned PICLevel = LangOpts.PICLevel) { Builder.defineMacro("__PIC__", Twine(PICLevel)); Builder.defineMacro("__pic__", Twine(PICLevel)); } if (unsigned PIELevel = LangOpts.PIELevel) { Builder.defineMacro("__PIE__", Twine(PIELevel)); Builder.defineMacro("__pie__", Twine(PIELevel)); } // Macros to control C99 numerics and <float.h> Builder.defineMacro("__FLT_EVAL_METHOD__", Twine(TI.getFloatEvalMethod())); Builder.defineMacro("__FLT_RADIX__", "2"); Builder.defineMacro("__DECIMAL_DIG__", "__LDBL_DECIMAL_DIG__"); if (LangOpts.getStackProtector() == LangOptions::SSPOn) Builder.defineMacro("__SSP__"); else if (LangOpts.getStackProtector() == LangOptions::SSPStrong) Builder.defineMacro("__SSP_STRONG__", "2"); else if (LangOpts.getStackProtector() == LangOptions::SSPReq) Builder.defineMacro("__SSP_ALL__", "3"); // Define a macro that exists only when using the static analyzer. if (FEOpts.ProgramAction == frontend::RunAnalysis) Builder.defineMacro("__clang_analyzer__"); if (LangOpts.FastRelaxedMath) Builder.defineMacro("__FAST_RELAXED_MATH__"); if (FEOpts.ProgramAction == frontend::RewriteObjC || LangOpts.getGC() != LangOptions::NonGC) { Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))"); Builder.defineMacro("__autoreleasing", ""); Builder.defineMacro("__unsafe_unretained", ""); } else if (LangOpts.ObjC1) { Builder.defineMacro("__weak", "__attribute__((objc_ownership(weak)))"); Builder.defineMacro("__strong", "__attribute__((objc_ownership(strong)))"); Builder.defineMacro("__autoreleasing", "__attribute__((objc_ownership(autoreleasing)))"); Builder.defineMacro("__unsafe_unretained", "__attribute__((objc_ownership(none)))"); } // On Darwin, there are __double_underscored variants of the type // nullability qualifiers. if (TI.getTriple().isOSDarwin()) { Builder.defineMacro("__nonnull", "_Nonnull"); Builder.defineMacro("__null_unspecified", "_Null_unspecified"); Builder.defineMacro("__nullable", "_Nullable"); } // OpenMP definition // OpenMP 2.2: // In implementations that support a preprocessor, the _OPENMP // macro name is defined to have the decimal value yyyymm where // yyyy and mm are the year and the month designations of the // version of the OpenMP API that the implementation support. switch (LangOpts.OpenMP) { case 0: break; case 40: Builder.defineMacro("_OPENMP", "201307"); break; case 45: Builder.defineMacro("_OPENMP", "201511"); break; default: // Default version is OpenMP 3.1 Builder.defineMacro("_OPENMP", "201107"); break; } // CUDA device path compilaton if (LangOpts.CUDAIsDevice) { // The CUDA_ARCH value is set for the GPU target specified in the NVPTX // backend's target defines. Builder.defineMacro("__CUDA_ARCH__"); } // We need to communicate this to our CUDA header wrapper, which in turn // informs the proper CUDA headers of this choice. if (LangOpts.CUDADeviceApproxTranscendentals || LangOpts.FastMath) { Builder.defineMacro("__CLANG_CUDA_APPROX_TRANSCENDENTALS__"); } // OpenCL definitions. if (LangOpts.OpenCL) { #define OPENCLEXT(Ext) \ if (TI.getSupportedOpenCLOpts().is_##Ext##_supported( \ LangOpts.OpenCLVersion)) \ Builder.defineMacro(#Ext); #include "clang/Basic/OpenCLExtensions.def" } // Get other target #defines. TI.getTargetDefines(LangOpts, Builder); }
static void DefineTypeWidth(StringRef MacroName, TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { Builder.defineMacro(MacroName, Twine(TI.getTypeWidth(Ty))); }
static void DefineTypeSizeof(StringRef MacroName, unsigned BitWidth, const TargetInfo &TI, MacroBuilder &Builder) { Builder.defineMacro(MacroName, Twine(BitWidth / TI.getCharWidth())); }
/// DefineTypeSize - An overloaded helper that uses TargetInfo to determine /// the width, suffix, and signedness of the given type static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty), TI.isTypeSigned(Ty), Builder); }
static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, const char *&Beg, const char *E, unsigned &argIndex, const LangOptions &LO, const TargetInfo &Target) { using namespace clang::analyze_format_string; using namespace clang::analyze_printf; const char *I = Beg; const char *Start = 0; UpdateOnReturn <const char*> UpdateBeg(Beg, I); // Look for a '%' character that indicates the start of a format specifier. for ( ; I != E ; ++I) { char c = *I; if (c == '\0') { // Detect spurious null characters, which are likely errors. H.HandleNullChar(I); return true; } if (c == '%') { Start = I++; // Record the start of the format specifier. break; } } // No format specifier found? if (!Start) return false; if (I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } PrintfSpecifier FS; if (ParseArgPosition(H, FS, Start, I, E)) return true; if (I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } // Look for flags (if any). bool hasMore = true; for ( ; I != E; ++I) { switch (*I) { default: hasMore = false; break; case '\'': // FIXME: POSIX specific. Always accept? FS.setHasThousandsGrouping(I); break; case '-': FS.setIsLeftJustified(I); break; case '+': FS.setHasPlusPrefix(I); break; case ' ': FS.setHasSpacePrefix(I); break; case '#': FS.setHasAlternativeForm(I); break; case '0': FS.setHasLeadingZeros(I); break; } if (!hasMore) break; } if (I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } // Look for the field width (if any). if (ParseFieldWidth(H, FS, Start, I, E, FS.usesPositionalArg() ? 0 : &argIndex)) return true; if (I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } // Look for the precision (if any). if (*I == '.') { ++I; if (I == E) { H.HandleIncompleteSpecifier(Start, E - Start); return true; } if (ParsePrecision(H, FS, Start, I, E, FS.usesPositionalArg() ? 0 : &argIndex)) return true; if (I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } } // Look for the length modifier. if (ParseLengthModifier(FS, I, E, LO) && I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } if (*I == '\0') { // Detect spurious null characters, which are likely errors. H.HandleNullChar(I); return true; } // Finally, look for the conversion specifier. const char *conversionPosition = I++; ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; switch (*conversionPosition) { default: break; // C99: 7.19.6.1 (section 8). case '%': k = ConversionSpecifier::PercentArg; break; case 'A': k = ConversionSpecifier::AArg; break; case 'E': k = ConversionSpecifier::EArg; break; case 'F': k = ConversionSpecifier::FArg; break; case 'G': k = ConversionSpecifier::GArg; break; case 'X': k = ConversionSpecifier::XArg; break; case 'a': k = ConversionSpecifier::aArg; break; case 'c': k = ConversionSpecifier::cArg; break; case 'd': k = ConversionSpecifier::dArg; break; case 'e': k = ConversionSpecifier::eArg; break; case 'f': k = ConversionSpecifier::fArg; break; case 'g': k = ConversionSpecifier::gArg; break; case 'i': k = ConversionSpecifier::iArg; break; case 'n': k = ConversionSpecifier::nArg; break; case 'o': k = ConversionSpecifier::oArg; break; case 'p': k = ConversionSpecifier::pArg; break; case 's': k = ConversionSpecifier::sArg; break; case 'u': k = ConversionSpecifier::uArg; break; case 'x': k = ConversionSpecifier::xArg; break; // POSIX specific. case 'C': k = ConversionSpecifier::CArg; break; case 'S': k = ConversionSpecifier::SArg; break; // Objective-C. case '@': k = ConversionSpecifier::ObjCObjArg; break; // Glibc specific. case 'm': k = ConversionSpecifier::PrintErrno; break; // Apple-specific case 'D': if (Target.getTriple().isOSDarwin()) k = ConversionSpecifier::DArg; break; case 'O': if (Target.getTriple().isOSDarwin()) k = ConversionSpecifier::OArg; break; case 'U': if (Target.getTriple().isOSDarwin()) k = ConversionSpecifier::UArg; break; } PrintfConversionSpecifier CS(conversionPosition, k); FS.setConversionSpecifier(CS); if (CS.consumesDataArgument() && !FS.usesPositionalArg()) FS.setArgIndex(argIndex++); if (k == ConversionSpecifier::InvalidSpecifier) { // Assume the conversion takes one argument. return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start); } return PrintfSpecifierResult(Start, FS); }
bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { switch (LM.getKind()) { case LengthModifier::None: return true; // Handle most integer flags case LengthModifier::AsShort: if (Target.getTriple().isOSMSVCRT()) { switch (CS.getKind()) { case ConversionSpecifier::cArg: case ConversionSpecifier::CArg: case ConversionSpecifier::sArg: case ConversionSpecifier::SArg: case ConversionSpecifier::ZArg: return true; default: break; } } // Fall through. case LengthModifier::AsChar: case LengthModifier::AsLongLong: case LengthModifier::AsQuad: case LengthModifier::AsIntMax: case LengthModifier::AsSizeT: case LengthModifier::AsPtrDiff: switch (CS.getKind()) { case ConversionSpecifier::dArg: case ConversionSpecifier::DArg: case ConversionSpecifier::iArg: case ConversionSpecifier::oArg: case ConversionSpecifier::OArg: case ConversionSpecifier::uArg: case ConversionSpecifier::UArg: case ConversionSpecifier::xArg: case ConversionSpecifier::XArg: case ConversionSpecifier::nArg: return true; case ConversionSpecifier::FreeBSDrArg: case ConversionSpecifier::FreeBSDyArg: return Target.getTriple().isOSFreeBSD(); default: return false; } // Handle 'l' flag case LengthModifier::AsLong: // or AsWideChar switch (CS.getKind()) { case ConversionSpecifier::dArg: case ConversionSpecifier::DArg: case ConversionSpecifier::iArg: case ConversionSpecifier::oArg: case ConversionSpecifier::OArg: case ConversionSpecifier::uArg: case ConversionSpecifier::UArg: case ConversionSpecifier::xArg: case ConversionSpecifier::XArg: case ConversionSpecifier::aArg: case ConversionSpecifier::AArg: case ConversionSpecifier::fArg: case ConversionSpecifier::FArg: case ConversionSpecifier::eArg: case ConversionSpecifier::EArg: case ConversionSpecifier::gArg: case ConversionSpecifier::GArg: case ConversionSpecifier::nArg: case ConversionSpecifier::cArg: case ConversionSpecifier::sArg: case ConversionSpecifier::ScanListArg: case ConversionSpecifier::ZArg: return true; case ConversionSpecifier::FreeBSDrArg: case ConversionSpecifier::FreeBSDyArg: return Target.getTriple().isOSFreeBSD(); default: return false; } case LengthModifier::AsLongDouble: switch (CS.getKind()) { case ConversionSpecifier::aArg: case ConversionSpecifier::AArg: case ConversionSpecifier::fArg: case ConversionSpecifier::FArg: case ConversionSpecifier::eArg: case ConversionSpecifier::EArg: case ConversionSpecifier::gArg: case ConversionSpecifier::GArg: return true; // GNU libc extension. case ConversionSpecifier::dArg: case ConversionSpecifier::iArg: case ConversionSpecifier::oArg: case ConversionSpecifier::uArg: case ConversionSpecifier::xArg: case ConversionSpecifier::XArg: return !Target.getTriple().isOSDarwin() && !Target.getTriple().isOSWindows(); default: return false; } case LengthModifier::AsAllocate: switch (CS.getKind()) { case ConversionSpecifier::sArg: case ConversionSpecifier::SArg: case ConversionSpecifier::ScanListArg: return true; default: return false; } case LengthModifier::AsMAllocate: switch (CS.getKind()) { case ConversionSpecifier::cArg: case ConversionSpecifier::CArg: case ConversionSpecifier::sArg: case ConversionSpecifier::SArg: case ConversionSpecifier::ScanListArg: return true; default: return false; } case LengthModifier::AsInt32: case LengthModifier::AsInt3264: case LengthModifier::AsInt64: switch (CS.getKind()) { case ConversionSpecifier::dArg: case ConversionSpecifier::iArg: case ConversionSpecifier::oArg: case ConversionSpecifier::uArg: case ConversionSpecifier::xArg: case ConversionSpecifier::XArg: return Target.getTriple().isOSMSVCRT(); default: return false; } case LengthModifier::AsWide: switch (CS.getKind()) { case ConversionSpecifier::cArg: case ConversionSpecifier::CArg: case ConversionSpecifier::sArg: case ConversionSpecifier::SArg: case ConversionSpecifier::ZArg: return Target.getTriple().isOSMSVCRT(); default: return false; } } llvm_unreachable("Invalid LengthModifier Kind!"); }
/// This is where the link is actually performed. bool Driver::link(const TargetInfo &targetInfo) { // Honor -mllvm if (!targetInfo.llvmOptions().empty()) { unsigned numArgs = targetInfo.llvmOptions().size(); const char **args = new const char*[numArgs + 2]; args[0] = "lld (LLVM option parsing)"; for (unsigned i = 0; i != numArgs; ++i) args[i + 1] = targetInfo.llvmOptions()[i]; args[numArgs + 1] = 0; llvm::cl::ParseCommandLineOptions(numArgs + 1, args); } // Read inputs ScopedTask readTask(getDefaultDomain(), "Read Args"); std::vector<std::vector<std::unique_ptr<File>>> files( targetInfo.inputFiles().size()); size_t index = 0; std::atomic<bool> fail(false); TaskGroup tg; for (const auto &input : targetInfo.inputFiles()) { if (targetInfo.logInputFiles()) llvm::outs() << input.getPath() << "\n"; tg.spawn([ &, index]{ if (error_code ec = targetInfo.readFile(input.getPath(), files[index])) { llvm::errs() << "Failed to read file: " << input.getPath() << ": " << ec.message() << "\n"; fail = true; return; } }); ++index; } tg.sync(); readTask.end(); if (fail) return true; InputFiles inputs; for (auto &f : files) inputs.appendFiles(f); // Give target a chance to add files. targetInfo.addImplicitFiles(inputs); // assign an ordinal to each file so sort() can preserve command line order inputs.assignFileOrdinals(); // Do core linking. ScopedTask resolveTask(getDefaultDomain(), "Resolve"); Resolver resolver(targetInfo, inputs); if (resolver.resolve()) { if (!targetInfo.allowRemainingUndefines()) return true; } MutableFile &merged = resolver.resultFile(); resolveTask.end(); // Run passes on linked atoms. ScopedTask passTask(getDefaultDomain(), "Passes"); PassManager pm; targetInfo.addPasses(pm); pm.runOnFile(merged); passTask.end(); // Give linked atoms to Writer to generate output file. ScopedTask writeTask(getDefaultDomain(), "Write"); if (error_code ec = targetInfo.writeFile(merged)) { llvm::errs() << "Failed to write file '" << targetInfo.outputPath() << "': " << ec.message() << "\n"; return true; } return false; }
void Builtin::Context::InitializeTarget(const TargetInfo &Target) { assert(NumTSRecords == 0 && "Already initialized target?"); Target.getTargetBuiltins(TSRecords, NumTSRecords); }
// FIXME: Much of this is copy-paste from ParsePrintfSpecifier. // We can possibly refactor. static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, const char *&Beg, const char *E, unsigned &argIndex, const LangOptions &LO, const TargetInfo &Target) { using namespace lfort::analyze_scanf; const char *I = Beg; const char *Start = 0; UpdateOnReturn <const char*> UpdateBeg(Beg, I); // Look for a '%' character that indicates the start of a format specifier. for ( ; I != E ; ++I) { char c = *I; if (c == '\0') { // Detect spurious null characters, which are likely errors. H.HandleNullChar(I); return true; } if (c == '%') { Start = I++; // Record the start of the format specifier. break; } } // No format specifier found? if (!Start) return false; if (I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } ScanfSpecifier FS; if (ParseArgPosition(H, FS, Start, I, E)) return true; if (I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } // Look for '*' flag if it is present. if (*I == '*') { FS.setSuppressAssignment(I); if (++I == E) { H.HandleIncompleteSpecifier(Start, E - Start); return true; } } // Look for the field width (if any). Unlike printf, this is either // a fixed integer or isn't present. const OptionalAmount &Amt = lfort::analyze_format_string::ParseAmount(I, E); if (Amt.getHowSpecified() != OptionalAmount::NotSpecified) { assert(Amt.getHowSpecified() == OptionalAmount::Constant); FS.setFieldWidth(Amt); if (I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } } // Look for the length modifier. if (ParseLengthModifier(FS, I, E, LO, /*scanf=*/true) && I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; } // Detect spurious null characters, which are likely errors. if (*I == '\0') { H.HandleNullChar(I); return true; } // Finally, look for the conversion specifier. const char *conversionPosition = I++; ScanfConversionSpecifier::Kind k = ScanfConversionSpecifier::InvalidSpecifier; switch (*conversionPosition) { default: break; case '%': k = ConversionSpecifier::PercentArg; break; case 'A': k = ConversionSpecifier::AArg; break; case 'E': k = ConversionSpecifier::EArg; break; case 'F': k = ConversionSpecifier::FArg; break; case 'G': k = ConversionSpecifier::GArg; break; case 'X': k = ConversionSpecifier::XArg; break; case 'a': k = ConversionSpecifier::aArg; break; case 'd': k = ConversionSpecifier::dArg; break; case 'e': k = ConversionSpecifier::eArg; break; case 'f': k = ConversionSpecifier::fArg; break; case 'g': k = ConversionSpecifier::gArg; break; case 'i': k = ConversionSpecifier::iArg; break; case 'n': k = ConversionSpecifier::nArg; break; case 'c': k = ConversionSpecifier::cArg; break; case 'C': k = ConversionSpecifier::CArg; break; case 'S': k = ConversionSpecifier::SArg; break; case '[': k = ConversionSpecifier::ScanListArg; break; case 'u': k = ConversionSpecifier::uArg; break; case 'x': k = ConversionSpecifier::xArg; break; case 'o': k = ConversionSpecifier::oArg; break; case 's': k = ConversionSpecifier::sArg; break; case 'p': k = ConversionSpecifier::pArg; break; // Apple extensions // Apple-specific case 'D': if (Target.getTriple().isOSDarwin()) k = ConversionSpecifier::DArg; break; case 'O': if (Target.getTriple().isOSDarwin()) k = ConversionSpecifier::OArg; break; case 'U': if (Target.getTriple().isOSDarwin()) k = ConversionSpecifier::UArg; break; } ScanfConversionSpecifier CS(conversionPosition, k); if (k == ScanfConversionSpecifier::ScanListArg) { if (ParseScanList(H, CS, I, E)) return true; } FS.setConversionSpecifier(CS); if (CS.consumesDataArgument() && !FS.getSuppressAssignment() && !FS.usesPositionalArg()) FS.setArgIndex(argIndex++); // FIXME: '%' and '*' doesn't make sense. Issue a warning. // FIXME: 'ConsumedSoFar' and '*' doesn't make sense. if (k == ScanfConversionSpecifier::InvalidSpecifier) { // Assume the conversion takes one argument. return !H.HandleInvalidScanfConversionSpecifier(FS, Beg, I - Beg); } return ScanfSpecifierResult(Start, FS); }
static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, const char *&Beg, const char *E, unsigned &argIndex, const LangOptions &LO, const TargetInfo &Target, bool Warn, bool isFreeBSDKPrintf) { using namespace clang::analyze_format_string; using namespace clang::analyze_printf; const char *I = Beg; const char *Start = nullptr; UpdateOnReturn <const char*> UpdateBeg(Beg, I); // Look for a '%' character that indicates the start of a format specifier. for ( ; I != E ; ++I) { char c = *I; if (c == '\0') { // Detect spurious null characters, which are likely errors. H.HandleNullChar(I); return true; } if (c == '%') { Start = I++; // Record the start of the format specifier. break; } } // No format specifier found? if (!Start) return false; if (I == E) { // No more characters left? if (Warn) H.HandleIncompleteSpecifier(Start, E - Start); return true; } PrintfSpecifier FS; if (ParseArgPosition(H, FS, Start, I, E)) return true; if (I == E) { // No more characters left? if (Warn) H.HandleIncompleteSpecifier(Start, E - Start); return true; } const char *OSLogVisibilityFlagsStart = nullptr, *OSLogVisibilityFlagsEnd = nullptr; if (*I == '{') { OSLogVisibilityFlagsStart = I++; // Find the end of the modifier. while (I != E && *I != '}') { I++; } if (I == E) { if (Warn) H.HandleIncompleteSpecifier(Start, E - Start); return true; } assert(*I == '}'); OSLogVisibilityFlagsEnd = I++; // Just see if 'private' or 'public' is the first word. os_log itself will // do any further parsing. const char *P = OSLogVisibilityFlagsStart + 1; while (P < OSLogVisibilityFlagsEnd && isspace(*P)) P++; const char *WordStart = P; while (P < OSLogVisibilityFlagsEnd && (isalnum(*P) || *P == '_')) P++; const char *WordEnd = P; StringRef Word(WordStart, WordEnd - WordStart); if (Word == "private") { FS.setIsPrivate(WordStart); } else if (Word == "public") { FS.setIsPublic(WordStart); } } // Look for flags (if any). bool hasMore = true; for ( ; I != E; ++I) { switch (*I) { default: hasMore = false; break; case '\'': // FIXME: POSIX specific. Always accept? FS.setHasThousandsGrouping(I); break; case '-': FS.setIsLeftJustified(I); break; case '+': FS.setHasPlusPrefix(I); break; case ' ': FS.setHasSpacePrefix(I); break; case '#': FS.setHasAlternativeForm(I); break; case '0': FS.setHasLeadingZeros(I); break; } if (!hasMore) break; } if (I == E) { // No more characters left? if (Warn) H.HandleIncompleteSpecifier(Start, E - Start); return true; } // Look for the field width (if any). if (ParseFieldWidth(H, FS, Start, I, E, FS.usesPositionalArg() ? nullptr : &argIndex)) return true; if (I == E) { // No more characters left? if (Warn) H.HandleIncompleteSpecifier(Start, E - Start); return true; } // Look for the precision (if any). if (*I == '.') { ++I; if (I == E) { if (Warn) H.HandleIncompleteSpecifier(Start, E - Start); return true; } if (ParsePrecision(H, FS, Start, I, E, FS.usesPositionalArg() ? nullptr : &argIndex)) return true; if (I == E) { // No more characters left? if (Warn) H.HandleIncompleteSpecifier(Start, E - Start); return true; } } // Look for the length modifier. if (ParseLengthModifier(FS, I, E, LO) && I == E) { // No more characters left? if (Warn) H.HandleIncompleteSpecifier(Start, E - Start); return true; } // Look for the Objective-C modifier flags, if any. // We parse these here, even if they don't apply to // the conversion specifier, and then emit an error // later if the conversion specifier isn't '@'. This // enables better recovery, and we don't know if // these flags are applicable until later. const char *ObjCModifierFlagsStart = nullptr, *ObjCModifierFlagsEnd = nullptr; if (*I == '[') { ObjCModifierFlagsStart = I; ++I; auto flagStart = I; for (;; ++I) { ObjCModifierFlagsEnd = I; if (I == E) { if (Warn) H.HandleIncompleteSpecifier(Start, E - Start); return true; } // Did we find the closing ']'? if (*I == ']') { if (ParseObjCFlags(H, FS, flagStart, I, Warn)) return true; ++I; break; } // There are no separators defined yet for multiple // Objective-C modifier flags. When those are // defined, this is the place to check. } } if (*I == '\0') { // Detect spurious null characters, which are likely errors. H.HandleNullChar(I); return true; } // Finally, look for the conversion specifier. const char *conversionPosition = I++; ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; switch (*conversionPosition) { default: break; // C99: 7.19.6.1 (section 8). case '%': k = ConversionSpecifier::PercentArg; break; case 'A': k = ConversionSpecifier::AArg; break; case 'E': k = ConversionSpecifier::EArg; break; case 'F': k = ConversionSpecifier::FArg; break; case 'G': k = ConversionSpecifier::GArg; break; case 'X': k = ConversionSpecifier::XArg; break; case 'a': k = ConversionSpecifier::aArg; break; case 'c': k = ConversionSpecifier::cArg; break; case 'd': k = ConversionSpecifier::dArg; break; case 'e': k = ConversionSpecifier::eArg; break; case 'f': k = ConversionSpecifier::fArg; break; case 'g': k = ConversionSpecifier::gArg; break; case 'i': k = ConversionSpecifier::iArg; break; case 'n': k = ConversionSpecifier::nArg; break; case 'o': k = ConversionSpecifier::oArg; break; case 'p': k = ConversionSpecifier::pArg; break; case 's': k = ConversionSpecifier::sArg; break; case 'u': k = ConversionSpecifier::uArg; break; case 'x': k = ConversionSpecifier::xArg; break; // POSIX specific. case 'C': k = ConversionSpecifier::CArg; break; case 'S': k = ConversionSpecifier::SArg; break; // Apple extension for os_log case 'P': k = ConversionSpecifier::PArg; break; // Objective-C. case '@': k = ConversionSpecifier::ObjCObjArg; break; // Glibc specific. case 'm': k = ConversionSpecifier::PrintErrno; break; // FreeBSD kernel specific. case 'b': if (isFreeBSDKPrintf) k = ConversionSpecifier::FreeBSDbArg; // int followed by char * break; case 'r': if (isFreeBSDKPrintf) k = ConversionSpecifier::FreeBSDrArg; // int break; case 'y': if (isFreeBSDKPrintf) k = ConversionSpecifier::FreeBSDyArg; // int break; // Apple-specific. case 'D': if (isFreeBSDKPrintf) k = ConversionSpecifier::FreeBSDDArg; // void * followed by char * else if (Target.getTriple().isOSDarwin()) k = ConversionSpecifier::DArg; break; case 'O': if (Target.getTriple().isOSDarwin()) k = ConversionSpecifier::OArg; break; case 'U': if (Target.getTriple().isOSDarwin()) k = ConversionSpecifier::UArg; break; // MS specific. case 'Z': if (Target.getTriple().isOSMSVCRT()) k = ConversionSpecifier::ZArg; } // Check to see if we used the Objective-C modifier flags with // a conversion specifier other than '@'. if (k != ConversionSpecifier::ObjCObjArg && k != ConversionSpecifier::InvalidSpecifier && ObjCModifierFlagsStart) { H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart, ObjCModifierFlagsEnd + 1, conversionPosition); return true; } PrintfConversionSpecifier CS(conversionPosition, k); FS.setConversionSpecifier(CS); if (CS.consumesDataArgument() && !FS.usesPositionalArg()) FS.setArgIndex(argIndex++); // FreeBSD kernel specific. if (k == ConversionSpecifier::FreeBSDbArg || k == ConversionSpecifier::FreeBSDDArg) argIndex++; if (k == ConversionSpecifier::InvalidSpecifier) { unsigned Len = I - Start; if (ParseUTF8InvalidSpecifier(Start, E, Len)) { CS.setEndScanList(Start + Len); FS.setConversionSpecifier(CS); } // Assume the conversion takes one argument. return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len); } return PrintfSpecifierResult(Start, FS); }