/// getDarwinNumber - Parse the 'darwin number' out of the specific target /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is /// not defined, return 0's. This requires that the triple have an OSType of /// darwin before it is called. void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min, unsigned &Revision) const { assert(getOS() == Darwin && "Not a darwin target triple!"); StringRef OSName = getOSName(); assert(OSName.startswith("darwin") && "Unknown darwin target triple!"); // Strip off "darwin". OSName = OSName.substr(6); Maj = Min = Revision = 0; if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') return; // The major version is the first digit. Maj = EatNumber(OSName); if (OSName.empty()) return; // Handle minor version: 10.4.9 -> darwin8.9. if (OSName[0] != '.') return; // Eat the '.'. OSName = OSName.substr(1); if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') return; Min = EatNumber(OSName); if (OSName.empty()) return; // Handle revision darwin8.9.1 if (OSName[0] != '.') return; // Eat the '.'. OSName = OSName.substr(1); if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') return; Revision = EatNumber(OSName); }
static const ProtocolDescriptor * _searchProtocolRecords(ProtocolMetadataPrivateState &C, const llvm::StringRef protocolName){ for (auto §ion : C.SectionsToScan.snapshot()) { for (const auto &record : section) { if (auto protocol = record.Protocol.getPointer()) { // Drop the "S$" prefix from the protocol record. It's not used in // the type itself. StringRef foundProtocolName = protocol->Name; assert(foundProtocolName.startswith("$S")); foundProtocolName = foundProtocolName.drop_front(2); if (foundProtocolName == protocolName) return protocol; } } } return nullptr; }
static void parseVersionFromName(StringRef Name, unsigned &Major, unsigned &Minor, unsigned &Micro) { // Any unset version defaults to 0. Major = Minor = Micro = 0; // Parse up to three components. unsigned *Components[3] = {&Major, &Minor, &Micro}; for (unsigned i = 0; i != 3; ++i) { if (Name.empty() || Name[0] < '0' || Name[0] > '9') break; // Consume the leading number. *Components[i] = EatNumber(Name); // Consume the separator, if present. if (Name.startswith(".")) Name = Name.substr(1); } }
int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts) { StringRef Name = Attr->getName(); // Normalize the attribute name, __foo__ becomes foo. if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__")) Name = Name.substr(2, Name.size() - 4); // Normalize the scope name, but only for gnu and clang attributes. StringRef ScopeName = Scope ? Scope->getName() : ""; if (ScopeName == "__gnu__") ScopeName = "gnu"; else if (ScopeName == "_Clang") ScopeName = "clang"; #include "clang/Basic/AttrHasAttributeImpl.inc" return 0; }
/// \brief Parse the simulator version define: /// __IPHONE_OS_VERSION_MIN_REQUIRED=([0-9])([0-9][0-9])([0-9][0-9]) // and return the grouped values as integers, e.g: // __IPHONE_OS_VERSION_MIN_REQUIRED=40201 // will return Major=4, Minor=2, Micro=1. static bool GetVersionFromSimulatorDefine(StringRef define, unsigned &Major, unsigned &Minor, unsigned &Micro) { assert(define.startswith(SimulatorVersionDefineName())); StringRef name, version; llvm::tie(name, version) = define.split('='); if (version.empty()) return false; std::string verstr = version.str(); char *end; unsigned num = (unsigned) strtol(verstr.c_str(), &end, 10); if (*end != '\0') return false; Major = num / 10000; num = num % 10000; Minor = num / 100; Micro = num % 100; return true; }
/// LexSingleQuote: Integer: 'b' AsmToken AsmLexer::LexSingleQuote() { int CurChar = getNextChar(); if (CurChar == '\\') CurChar = getNextChar(); if (CurChar == EOF) return ReturnError(TokStart, "unterminated single quote"); CurChar = getNextChar(); if (CurChar != '\'') return ReturnError(TokStart, "single quote way too long"); // The idea here being that 'c' is basically just an integral // constant. StringRef Res = StringRef(TokStart,CurPtr - TokStart); long long Value; if (Res.startswith("\'\\")) { char theChar = Res[2]; switch (theChar) { default: Value = theChar; break; case '\'': Value = '\''; break; case 't': Value = '\t'; break; case 'n': Value = '\n'; break; case 'b': Value = '\b'; break; } } else Value = TokStart[1]; return AsmToken(AsmToken::Integer, Res, Value); }
error_code Archive::Child::getName(StringRef &Result) const { StringRef name = ToHeader(Data.data())->getName(); // Check if it's a special name. if (name[0] == '/') { if (name.size() == 1) { // Linker member. Result = name; return object_error::success; } if (name.size() == 2 && name[1] == '/') { // String table. Result = name; return object_error::success; } // It's a long name. // Get the offset. APInt offset; name.substr(1).getAsInteger(10, offset); const char *addr = Parent->StringTable->Data.begin() + sizeof(ArchiveMemberHeader) + offset.getZExtValue(); // Verify it. if (Parent->StringTable == Parent->end_children() || addr < (Parent->StringTable->Data.begin() + sizeof(ArchiveMemberHeader)) || addr > (Parent->StringTable->Data.begin() + sizeof(ArchiveMemberHeader) + Parent->StringTable->getSize())) return object_error::parse_failed; Result = addr; return object_error::success; } else if (name.startswith("#1/")) { APInt name_size; name.substr(3).getAsInteger(10, name_size); Result = Data.substr(0, name_size.getZExtValue()); return object_error::success; } // It's a simple name. if (name[name.size() - 1] == '/') Result = name.substr(0, name.size() - 1); else Result = name; return object_error::success; }
void WalkAST::VisitCallExpr(CallExpr *CE) { // Get the callee. const FunctionDecl *FD = CE->getDirectCallee(); if (!FD) return; // Get the name of the callee. If it's a builtin, strip off the prefix. IdentifierInfo *II = FD->getIdentifier(); if (!II) // if no identifier, not a simple C function return; StringRef Name = II->getName(); if (Name.startswith("__builtin_")) Name = Name.substr(10); // Set the evaluation function by switching on the callee name. FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name) .Case("gets", &WalkAST::checkCall_gets) .Case("getpw", &WalkAST::checkCall_getpw) .Case("mktemp", &WalkAST::checkCall_mktemp) .Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy) .Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat) .Case("drand48", &WalkAST::checkCall_rand) .Case("erand48", &WalkAST::checkCall_rand) .Case("jrand48", &WalkAST::checkCall_rand) .Case("lrand48", &WalkAST::checkCall_rand) .Case("mrand48", &WalkAST::checkCall_rand) .Case("nrand48", &WalkAST::checkCall_rand) .Case("lcong48", &WalkAST::checkCall_rand) .Case("rand", &WalkAST::checkCall_rand) .Case("rand_r", &WalkAST::checkCall_rand) .Case("random", &WalkAST::checkCall_random) .Default(NULL); // If the callee isn't defined, it is not of security concern. // Check and evaluate the call. if (evalFunction) (this->*evalFunction)(CE, FD); // Recurse and check children. VisitChildren(CE); }
void StatsComputer::handleIns(FunInfo &funInfo, const Instruction &ins) { if (const CallInst *CI = dyn_cast<const CallInst>(&ins)) { if (CI->isInlineAsm()) { #ifdef DEBUG_ASM errs() << "ASM: in " << ins.getParent()->getParent()->getName() << " "; CI->print(errs()); CI->getParent()->print(errs()); errs() << "\n"; #endif funInfo.setHasAsm(); } else { Function *called = CI->getCalledFunction(); if (called) { StringRef calledName = called->getName(); if (calledName.startswith("llvm.") || calledName.equals("__assert_fail") || calledName.equals("__kmalloc") || calledName.equals("kfree") || isLockingFun(calledName)) return; if (called->isDeclaration()) { #ifdef DEBUG_EXT errs() << "EXT1 " << ins.getParent()->getParent()->getName() << " to " << called->getName() << "\n"; #endif funInfo.setHasExternalCall(); } } else { #ifdef DEBUG_EXT errs() << "EXT2 " << ins.getParent()->getParent()->getName() << " to "; ins.print(errs()); errs() << '\n'; #endif funInfo.setHasExternalCall(); } funInfo.setHasCall(); } } else if (const StoreInst *SI = dyn_cast<const StoreInst>(&ins)) { const Value *LHS = SI->getPointerOperand(); if (LHS->hasName() && LHS->getName().startswith("__ai_state")) funInfo.setHasLock(); } }
Type ASTBuilder::createBuiltinType(StringRef builtinName, StringRef mangledName) { if (builtinName.startswith(BUILTIN_TYPE_NAME_PREFIX)) { SmallVector<ValueDecl *, 1> decls; ModuleDecl::AccessPathTy accessPath; StringRef strippedName = builtinName.drop_front(strlen(BUILTIN_TYPE_NAME_PREFIX)); Ctx.TheBuiltinModule->lookupValue(accessPath, Ctx.getIdentifier(strippedName), NLKind::QualifiedLookup, decls); if (decls.size() == 1 && isa<TypeDecl>(decls[0])) return cast<TypeDecl>(decls[0])->getDeclaredInterfaceType(); } return Type(); }
Archive::Child::Child(const Archive *Parent, const char *Start) : Parent(Parent) { if (!Start) return; const ArchiveMemberHeader *Header = reinterpret_cast<const ArchiveMemberHeader *>(Start); Data = StringRef(Start, sizeof(ArchiveMemberHeader) + Header->getSize()); // Setup StartOfFile and PaddingBytes. StartOfFile = sizeof(ArchiveMemberHeader); // Don't include attached name. StringRef Name = Header->getName(); if (Name.startswith("#1/")) { uint64_t NameSize; if (Name.substr(3).rtrim(" ").getAsInteger(10, NameSize)) llvm_unreachable("Long name length is not an integer"); StartOfFile += NameSize; } }
static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { assert(F && "Illegal to upgrade a non-existent Function."); // Quickly eliminate it, if it's not a candidate. StringRef Name = F->getName(); if (Name.size() <= 8 || !Name.startswith("llvm.")) return false; Name = Name.substr(5); // Strip off "llvm." switch (Name[0]) { default: break; // SOMEDAY: Add some. } // This may not belong here. This function is effectively being overloaded // to both detect an intrinsic which needs upgrading, and to provide the // upgraded form of the intrinsic. We should perhaps have two separate // functions for this. return false; }
static void sanitizeCompilerArgs(ArrayRef<const char *> Args, SmallVectorImpl<const char *> &NewArgs) { for (const char *CArg : Args) { StringRef Arg = CArg; if (Arg.startswith("-j")) continue; if (Arg == "-c") continue; if (Arg == "-v") continue; if (Arg == "-Xfrontend") continue; if (Arg == "-embed-bitcode") continue; if (Arg == "-enable-bridging-pch" || Arg == "-disable-bridging-pch") continue; NewArgs.push_back(CArg); } }
static void parseInputFilenamesFile(MemoryBuffer *Buffer, WeightedFileVector &WFV) { if (!Buffer) return; SmallVector<StringRef, 8> Entries; StringRef Data = Buffer->getBuffer(); Data.split(Entries, '\n', /*MaxSplit=*/-1, /*KeepEmpty=*/false); for (const StringRef &FileWeightEntry : Entries) { StringRef SanitizedEntry = FileWeightEntry.trim(" \t\v\f\r"); // Skip comments. if (SanitizedEntry.startswith("#")) continue; // If there's no comma, it's an unweighted profile. else if (SanitizedEntry.find(',') == StringRef::npos) addWeightedInput(WFV, {SanitizedEntry, 1}); else addWeightedInput(WFV, parseWeightedFile(SanitizedEntry)); } }
ErrorOr<StringRef> Archive::Child::getName() const { StringRef name = getRawName(); // Check if it's a special name. if (name[0] == '/') { if (name.size() == 1) // Linker member. return name; if (name.size() == 2 && name[1] == '/') // String table. return name; // It's a long name. // Get the offset. std::size_t offset; if (name.substr(1).rtrim(' ').getAsInteger(10, offset)) llvm_unreachable("Long name offset is not an integer"); // Verify it. if (offset >= Parent->StringTable.size()) return object_error::parse_failed; const char *addr = Parent->StringTable.begin() + offset; // GNU long file names end with a "/\n". if (Parent->kind() == K_GNU || Parent->kind() == K_MIPS64) { StringRef::size_type End = StringRef(addr).find('\n'); return StringRef(addr, End - 1); } return StringRef(addr); } else if (name.startswith("#1/")) { uint64_t name_size; if (name.substr(3).rtrim(' ').getAsInteger(10, name_size)) llvm_unreachable("Long name length is not an ingeter"); return Data.substr(Header.getSizeOf(), name_size).rtrim('\0'); } else { // It is not a long name so trim the blanks at the end of the name. if (name[name.size() - 1] != '/') { return name.rtrim(' '); } } // It's a simple name. if (name[name.size() - 1] == '/') return name.substr(0, name.size() - 1); return name; }
/// InlineAsmDiagHandler2 - This function is invoked when the backend hits an /// error parsing inline asm. The SMDiagnostic indicates the error relative to /// the temporary memory buffer that the inline asm parser has set up. void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D, SourceLocation LocCookie) { // There are a couple of different kinds of errors we could get here. First, // we re-format the SMDiagnostic in terms of a clang diagnostic. // Strip "error: " off the start of the message string. StringRef Message = D.getMessage(); if (Message.startswith("error: ")) Message = Message.substr(7); // If the SMDiagnostic has an inline asm source location, translate it. FullSourceLoc Loc; if (D.getLoc() != SMLoc()) Loc = ConvertBackendLocation(D, Context->getSourceManager()); // If this problem has clang-level source location information, report the // issue as being an error in the source with a note showing the instantiated // code. if (LocCookie.isValid()) { Diags.Report(LocCookie, diag::err_fe_inline_asm).AddString(Message); if (D.getLoc().isValid()) { DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here); // Convert the SMDiagnostic ranges into SourceRange and attach them // to the diagnostic. for (unsigned i = 0, e = D.getRanges().size(); i != e; ++i) { std::pair<unsigned, unsigned> Range = D.getRanges()[i]; unsigned Column = D.getColumnNo(); B << SourceRange(Loc.getLocWithOffset(Range.first - Column), Loc.getLocWithOffset(Range.second - Column)); } } return; } // Otherwise, report the backend error as occurring in the generated .s file. // If Loc is invalid, we still need to report the error, it just gets no // location info. Diags.Report(Loc, diag::err_fe_inline_asm).AddString(Message); }
AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name, const IdentifierInfo *ScopeName, Syntax SyntaxUsed) { StringRef AttrName = Name->getName(); // Normalize the attribute name, __foo__ becomes foo. if (AttrName.startswith("__") && AttrName.endswith("__") && AttrName.size() >= 4) AttrName = AttrName.substr(2, AttrName.size() - 4); SmallString<64> Buf; if (ScopeName) Buf += ScopeName->getName(); // Ensure that in the case of C++11 attributes, we look for '::foo' if it is // unscoped. if (ScopeName || SyntaxUsed == AS_CXX11) Buf += "::"; Buf += AttrName; return ::getAttrKind(Buf); }
static bool mayReflowContent(StringRef Content) { Content = Content.trim(Blanks); // Lines starting with '@' commonly have special meaning. static const SmallVector<StringRef, 4> kSpecialMeaningPrefixes = { "@", "TODO", "FIXME", "XXX"}; bool hasSpecialMeaningPrefix = false; for (StringRef Prefix : kSpecialMeaningPrefixes) { if (Content.startswith(Prefix)) { hasSpecialMeaningPrefix = true; break; } } // Simple heuristic for what to reflow: content should contain at least two // characters and either the first or second character must be // non-punctuation. return Content.size() >= 2 && !hasSpecialMeaningPrefix && !Content.endswith("\\") && // Note that this is UTF-8 safe, since if isPunctuation(Content[0]) is // true, then the first code point must be 1 byte long. (!isPunctuation(Content[0]) || !isPunctuation(Content[1])); }
static unsigned getELFSectionType(StringRef Name, SectionKind K) { // Use SHT_NOTE for section whose name starts with ".note" to allow // emitting ELF notes from C variable declaration. // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609 if (Name.startswith(".note")) return ELF::SHT_NOTE; if (Name == ".init_array") return ELF::SHT_INIT_ARRAY; if (Name == ".fini_array") return ELF::SHT_FINI_ARRAY; if (Name == ".preinit_array") return ELF::SHT_PREINIT_ARRAY; if (K.isBSS() || K.isThreadBSS()) return ELF::SHT_NOBITS; return ELF::SHT_PROGBITS; }
void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec, const MCAsmLayout &Layout) { MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); StringRef SectionName = Section.getSectionName(); // Compressing debug_frame requires handling alignment fragments which is // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow // for writing to arbitrary buffers) for little benefit. if (!Asm.getContext().getAsmInfo()->compressDebugSections() || !SectionName.startswith(".debug_") || SectionName == ".debug_frame") { Asm.writeSectionData(&Section, Layout); return; } SmallVector<char, 128> UncompressedData; raw_svector_ostream VecOS(UncompressedData); raw_pwrite_stream &OldStream = getStream(); setStream(VecOS); Asm.writeSectionData(&Section, Layout); setStream(OldStream); #if 0 SmallVector<char, 128> CompressedContents; zlib::Status Success = zlib::compress( StringRef(UncompressedData.data(), UncompressedData.size()), CompressedContents); if (Success != zlib::StatusOK) { getStream() << UncompressedData; return; } if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) { getStream() << UncompressedData; return; } Asm.getContext().renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str()); getStream() << CompressedContents; #endif }
Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) { if (EnvironmentName.startswith("eabi")) return EABI; else if (EnvironmentName.startswith("gnueabihf")) return GNUEABIHF; else if (EnvironmentName.startswith("gnueabi")) return GNUEABI; else if (EnvironmentName.startswith("gnu")) return GNU; else if (EnvironmentName.startswith("macho")) return MachO; else if (EnvironmentName.startswith("androideabi")) return ANDROIDEABI; else return UnknownEnvironment; }
void NVPTXReplaceImageHandles:: replaceImageHandle(MachineOperand &Op, MachineFunction &MF) { const MachineRegisterInfo &MRI = MF.getRegInfo(); NVPTXMachineFunctionInfo *MFI = MF.getInfo<NVPTXMachineFunctionInfo>(); // Which instruction defines the handle? MachineInstr *MI = MRI.getVRegDef(Op.getReg()); assert(MI && "No def for image handle vreg?"); MachineInstr &TexHandleDef = *MI; switch (TexHandleDef.getOpcode()) { case NVPTX::LD_i64_avar: { // The handle is a parameter value being loaded, replace with the // parameter symbol assert(TexHandleDef.getOperand(6).isSymbol() && "Load is not a symbol!"); StringRef Sym = TexHandleDef.getOperand(6).getSymbolName(); std::string ParamBaseName = MF.getName(); ParamBaseName += "_param_"; assert(Sym.startswith(ParamBaseName) && "Invalid symbol reference"); unsigned Param = atoi(Sym.data()+ParamBaseName.size()); std::string NewSym; raw_string_ostream NewSymStr(NewSym); NewSymStr << MF.getFunction()->getName() << "_param_" << Param; Op.ChangeToImmediate( MFI->getImageHandleSymbolIndex(NewSymStr.str().c_str())); InstrsToRemove.insert(&TexHandleDef); break; } case NVPTX::texsurf_handles: { // The handle is a global variable, replace with the global variable name assert(TexHandleDef.getOperand(1).isGlobal() && "Load is not a global!"); const GlobalValue *GV = TexHandleDef.getOperand(1).getGlobal(); assert(GV->hasName() && "Global sampler must be named!"); Op.ChangeToImmediate(MFI->getImageHandleSymbolIndex(GV->getName().data())); InstrsToRemove.insert(&TexHandleDef); break; } default: llvm_unreachable("Unknown instruction operating on handle"); } }
SVMProgramSection SVMMemoryLayout::getSectionKind(const MCSectionData *SD) const { /* * Categorize a MCSection as one of the several predefined * SVMProgramSection types. This determines which program section * we'll lump it in with, or whether it'll be included as debug-only. * * This value can be specifically overridden with setSectionKind(). * If we have no override, we calculate the proper section kind * using the section's name, size, type, and other data. */ SectionKindOverrides_t::const_iterator it = SectionKindOverrides.find(SD); if (it != SectionKindOverrides.end()) return it->second; const MCSection *S = &SD->getSection(); SectionKind k = S->getKind(); const MCSectionELF *SE = dyn_cast<MCSectionELF>(S); assert(SE); StringRef Name = SE->getSectionName(); if (Name == ".metadata") return SPS_META; if (Name.startswith(".debug_")) return SPS_DEBUG; if (k.isBSS()) return SPS_BSS; if (SE->getType() == ELF::SHT_PROGBITS) { if (k.isReadOnly() || k.isText()) return SPS_RO; if (k.isGlobalWriteableData()) return SPS_RW_PLAIN; } return SPS_DEBUG; }
void DependencyGraphCallback::OutputGraphFile() { std::string Err; llvm::raw_fd_ostream OS(OutputFile.c_str(), Err, llvm::sys::fs::F_Text); if (!Err.empty()) { PP->getDiagnostics().Report(diag::err_fe_error_opening) << OutputFile << Err; return; } OS << "digraph \"dependencies\" {\n"; // Write the nodes for (unsigned I = 0, N = AllFiles.size(); I != N; ++I) { // Write the node itself. OS.indent(2); writeNodeReference(OS, AllFiles[I]); OS << " [ shape=\"box\", label=\""; StringRef FileName = AllFiles[I]->getName(); if (FileName.startswith(SysRoot)) FileName = FileName.substr(SysRoot.size()); OS << DOT::EscapeString(FileName) << "\"];\n"; } // Write the edges for (DependencyMap::iterator F = Dependencies.begin(), FEnd = Dependencies.end(); F != FEnd; ++F) { for (unsigned I = 0, N = F->second.size(); I != N; ++I) { OS.indent(2); writeNodeReference(OS, F->first); OS << " -> "; writeNodeReference(OS, F->second[I]); OS << ";\n"; } } OS << "}\n"; }
static const ProtocolDescriptor * _searchProtocolRecords(const ProtocolMetadataState &C, const llvm::StringRef protocolName){ unsigned sectionIdx = 0; unsigned endSectionIdx = C.SectionsToScan.size(); for (; sectionIdx < endSectionIdx; ++sectionIdx) { auto §ion = C.SectionsToScan[sectionIdx]; for (const auto &record : section) { if (auto protocol = record.Protocol.getPointer()) { // Drop the "S$" prefix from the protocol record. It's not used in // the type itself. StringRef foundProtocolName = protocol->Name; assert(foundProtocolName.startswith("$S")); foundProtocolName = foundProtocolName.drop_front(2); if (foundProtocolName == protocolName) return protocol; } } } return nullptr; }
/// HasExtension - Return true if we recognize and implement the feature /// specified by the identifier, either as an extension or a standard language /// feature. static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) { if (HasFeature(PP, II)) return true; // If the use of an extension results in an error diagnostic, extensions are // effectively unavailable, so just return false here. if (PP.getDiagnostics().getExtensionHandlingBehavior() == DiagnosticsEngine::Ext_Error) return false; const LangOptions &LangOpts = PP.getLangOpts(); StringRef Extension = II->getName(); // Normalize the extension name, __foo__ becomes foo. if (Extension.startswith("__") && Extension.endswith("__") && Extension.size() >= 4) Extension = Extension.substr(2, Extension.size() - 4); // Because we inherit the feature list from HasFeature, this string switch // must be less restrictive than HasFeature's. return llvm::StringSwitch<bool>(Extension) // C11 features supported by other languages as extensions. .Case("c_alignas", true) .Case("c_atomic", true) .Case("c_generic_selections", true) .Case("c_static_assert", true) // C++0x features supported by other languages as extensions. .Case("cxx_atomic", LangOpts.CPlusPlus) .Case("cxx_deleted_functions", LangOpts.CPlusPlus) .Case("cxx_explicit_conversions", LangOpts.CPlusPlus) .Case("cxx_inline_namespaces", LangOpts.CPlusPlus) .Case("cxx_local_type_template_args", LangOpts.CPlusPlus) .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus) .Case("cxx_override_control", LangOpts.CPlusPlus) .Case("cxx_range_for", LangOpts.CPlusPlus) .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus) .Case("cxx_rvalue_references", LangOpts.CPlusPlus) .Default(false); }
bool AssertionSiteInstrumenter::runOnModule(Module &M) { InstrCtx.reset(InstrContext::Create(M, SuppressDebugInstr)); // Replace all structure automaton "anchors" with automata definitions. for (auto &Fn : M) { StringRef Name = Fn.getName(); if (not Name.startswith(STRUCT_AUTOMATON)) continue; Name = Name.substr(STRUCT_AUTOMATON.length()); Identifier ID; ID.set_name(Name.str()); const Automaton *A = this->M.FindAutomaton(ID); if (not A) { llvm::errs() << "TESLA manifest does not contain " << Name << "\n"; panic("missing automaton definition", false); } assert(A->Name() == Name); if (Function *AutomatonDefinition = M.getFunction(Name)) AutomatonDefinition->eraseFromParent(); InstrCtx->BuildAutomatonDescription(A); } // If this module doesn't declare any assertions, just carry on. AssertFn = M.getFunction(INLINE_ASSERTION); if (!AssertFn) return false; // Find all calls to TESLA assertion pseudo-function (before we modify IR). set<CallInst*> AssertCalls; for (auto I = AssertFn->use_begin(); I != AssertFn->use_end(); ++I) AssertCalls.insert(cast<CallInst>(*I)); return ConvertAssertions(AssertCalls, M); }
// Little/Big endian ARM::EndianKind ARM::parseArchEndian(StringRef Arch) { if (Arch.startswith("armeb") || Arch.startswith("thumbeb") || Arch.startswith("aarch64_be")) return EndianKind::BIG; if (Arch.startswith("arm") || Arch.startswith("thumb")) { if (Arch.endswith("eb")) return EndianKind::BIG; else return EndianKind::LITTLE; } if (Arch.startswith("aarch64")) return EndianKind::LITTLE; return EndianKind::INVALID; }
// Little/Big endian unsigned llvm::ARM::parseArchEndian(StringRef Arch) { if (Arch.startswith("armeb") || Arch.startswith("thumbeb") || Arch.startswith("aarch64_be")) return ARM::EK_BIG; if (Arch.startswith("arm") || Arch.startswith("thumb")) { if (Arch.endswith("eb")) return ARM::EK_BIG; else return ARM::EK_LITTLE; } if (Arch.startswith("aarch64")) return ARM::EK_LITTLE; return ARM::EK_INVALID; }
bool PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM, StringRef &PipelineText, bool VerifyEachPass, bool DebugLogging) { for (;;) { // Parse nested pass managers by recursing. if (PipelineText.startswith("loop(")) { LoopPassManager NestedLPM(DebugLogging); // Parse the inner pipeline inte the nested manager. PipelineText = PipelineText.substr(strlen("loop(")); if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass, DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. LPM.addPass(std::move(NestedLPM)); } else { // Otherwise try to parse a pass name. size_t End = PipelineText.find_first_of(",)"); if (!parseLoopPassName(LPM, PipelineText.substr(0, End))) return false; // TODO: Ideally, we would run a LoopVerifierPass() here in the // VerifyEachPass case, but we don't have such a verifier yet. PipelineText = PipelineText.substr(End); } if (PipelineText.empty() || PipelineText[0] == ')') return true; assert(PipelineText[0] == ','); PipelineText = PipelineText.substr(1); } }