static bool isEmscriptenJSArgsFunc(Module *M, StringRef Name) { // TODO(jfb) Make these intrinsics in clang and remove the assert: these // intrinsics should only exist for Emscripten. bool isEmscriptenSpecial = Name.equals("emscripten_asm_const_int") || Name.equals("emscripten_asm_const_double") || Name.equals("emscripten_landingpad") || Name.equals("emscripten_resume"); assert(isEmscriptenSpecial ? Triple(M->getTargetTriple()).isOSEmscripten() : true); return isEmscriptenSpecial; }
// Returns true if the section name is such that the symbol will be put // in a small data section. // For instance, global variables with section attributes such as ".sdata" // ".sdata.*", ".sbss", and ".sbss.*" will go into small data. static bool isSmallDataSection(StringRef Sec) { // sectionName is either ".sdata" or ".sbss". Looking for an exact match // obviates the need for checks for section names such as ".sdatafoo". if (Sec.equals(".sdata") || Sec.equals(".sbss") || Sec.equals(".scommon")) return true; // If either ".sdata." or ".sbss." is a substring of the section name // then put the symbol in small data. return Sec.find(".sdata.") != StringRef::npos || Sec.find(".sbss.") != StringRef::npos || Sec.find(".scommon.") != StringRef::npos; }
static Triple::ArchType parseBPFArch(StringRef ArchName) { if (ArchName.equals("bpf")) { if (sys::IsLittleEndianHost) return Triple::bpfel; else return Triple::bpfeb; } else if (ArchName.equals("bpf_be") || ArchName.equals("bpfeb")) { return Triple::bpfeb; } else if (ArchName.equals("bpf_le") || ArchName.equals("bpfel")) { return Triple::bpfel; } else { return Triple::UnknownArch; } }
// If argument 0(protocol domain) is network, the return value should get taint. ProgramStateRef GenericTaintChecker::postSocket(const CallExpr *CE, CheckerContext &C) const { ProgramStateRef State = C.getState(); if (CE->getNumArgs() < 3) return State; SourceLocation DomLoc = CE->getArg(0)->getExprLoc(); StringRef DomName = C.getMacroNameOrSpelling(DomLoc); // White list the internal communication protocols. if (DomName.equals("AF_SYSTEM") || DomName.equals("AF_LOCAL") || DomName.equals("AF_UNIX") || DomName.equals("AF_RESERVED_36")) return State; State = State->addTaint(CE, C.getLocationContext()); return State; }
AMDGPUAsmParser::OperandMatchResultTy AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, int64_t &Int, int64_t Default) { // We are at the end of the statement, and this is a default argument, so // use a default value. if (getLexer().is(AsmToken::EndOfStatement)) { Int = Default; return MatchOperand_Success; } switch(getLexer().getKind()) { default: return MatchOperand_NoMatch; case AsmToken::Identifier: { StringRef OffsetName = Parser.getTok().getString(); if (!OffsetName.equals(Prefix)) return MatchOperand_NoMatch; Parser.Lex(); if (getLexer().isNot(AsmToken::Colon)) return MatchOperand_ParseFail; Parser.Lex(); if (getLexer().isNot(AsmToken::Integer)) return MatchOperand_ParseFail; if (getParser().parseAbsoluteExpression(Int)) return MatchOperand_ParseFail; break; } } return MatchOperand_Success; }
bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD, StringRef Name, ASTContext &Context) { // To avoid false positives (Ex: finding user defined functions with // similar names), only perform fuzzy name matching when it's a builtin. // Using a string compare is slow, we might want to switch on BuiltinID here. unsigned BId = FD->getBuiltinID(); if (BId != 0) { StringRef BName = Context.BuiltinInfo.GetName(BId); if (BName.find(Name) != StringRef::npos) return true; } const IdentifierInfo *II = FD->getIdentifier(); // If this is a special C++ name without IdentifierInfo, it can't be a // C library function. if (!II) return false; StringRef FName = II->getName(); if (FName.equals(Name)) return true; if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos)) return true; if (FName.startswith("__") && FName.endswith("_chk") && FName.find(Name) != StringRef::npos) return true; return false; }
bool CodeGenCoverage::parse(MemoryBuffer &Buffer, StringRef BackendName) { const char *CurPtr = Buffer.getBufferStart(); while (CurPtr != Buffer.getBufferEnd()) { // Read the backend name from the input. const char *LexedBackendName = CurPtr; while (*CurPtr++ != 0) ; if (CurPtr == Buffer.getBufferEnd()) return false; // Data is invalid, expected rule id's to follow. bool IsForThisBackend = BackendName.equals(LexedBackendName); while (CurPtr != Buffer.getBufferEnd()) { if (std::distance(CurPtr, Buffer.getBufferEnd()) < 8) return false; // Data is invalid. Not enough bytes for another rule id. uint64_t RuleID = support::endian::read64(CurPtr, support::native); CurPtr += 8; // ~0ull terminates the rule id list. if (RuleID == ~0ull) break; // Anything else, is recorded or ignored depending on whether it's // intended for the backend we're interested in. if (IsForThisBackend) setCovered(RuleID); } } return true; }
/// \brief Find string metadata for loop /// /// If it has a value (e.g. {"llvm.distribute", 1} return the value as an /// operand or null otherwise. If the string metadata is not found return /// Optional's not-a-value. Optional<const MDOperand *> llvm::findStringMetadataForLoop(Loop *TheLoop, StringRef Name) { MDNode *LoopID = TheLoop->getLoopID(); // Return none if LoopID is false. if (!LoopID) return None; // First operand should refer to the loop id itself. assert(LoopID->getNumOperands() > 0 && "requires at least one operand"); assert(LoopID->getOperand(0) == LoopID && "invalid loop id"); // Iterate over LoopID operands and look for MDString Metadata for (unsigned i = 1, e = LoopID->getNumOperands(); i < e; ++i) { MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(i)); if (!MD) continue; MDString *S = dyn_cast<MDString>(MD->getOperand(0)); if (!S) continue; // Return true if MDString holds expected MetaData. if (Name.equals(S->getString())) switch (MD->getNumOperands()) { case 1: return nullptr; case 2: return &MD->getOperand(1); default: llvm_unreachable("loop metadata has 0 or 1 operand"); } } return None; }
bool Input::MapHNode::isValidKey(StringRef Key) { for (const char *K : ValidKeys) { if (Key.equals(K)) return true; } return false; }
bool Input::MapHNode::isValidKey(StringRef Key) { for (SmallVectorImpl<const char *>::iterator i = ValidKeys.begin(), End = ValidKeys.end(); i != End; ++i) { if (Key.equals(*i)) return true; } return false; }
IOCode cdfg::get_io_code(CallInst &C) { llvm::Function *f = C.getCalledFunction(); assert(f && "function pointers are not currently supported"); if (!f->isDeclaration()) return NOT_IO; StringRef name = f->getName(); IOCode ioc = (name.equals("read_uint32") ? READ_UINT32 : (name.equals("write_uint32") ? WRITE_UINT32 : (name.equals("read_float32") ? READ_FLOAT32 : (name.equals("write_float32") ? WRITE_FLOAT32 : NOT_IO)))); return ioc; }
bool Aa::get_loop_pipelining_info(llvm::BasicBlock& BB,int& pipelining_depth, int& buffering, bool& full_rate_flag) { bool opt_fn_found = false; for(llvm::BasicBlock::iterator iiter = BB.begin(),fiter = BB.end(); iiter != fiter; ++iiter) { if(isa<CallInst>(*iiter)) { llvm::CallInst& C = static_cast<CallInst&>(*iiter); llvm::Function* f = C.getCalledFunction(); if(f == NULL) return(false); if(f->isDeclaration()) { StringRef name = f->getName(); if(name.equals("__loop_pipelining_on__")) { opt_fn_found = true; if(C.getNumArgOperands() > 0) { llvm::Value* v = C.getArgOperand(0); if(isa<Constant>(v)) { int pd = get_uint32(dyn_cast<Constant>(v)); if(pd > 0) pipelining_depth = pd; } if(C.getNumArgOperands() > 1) { v = C.getArgOperand(1); if(isa<Constant>(v)) { int bd = get_uint32(dyn_cast<Constant>(v)); if(bd > 0) buffering = bd; } } if(C.getNumArgOperands() > 2) { v = C.getArgOperand(2); if(isa<Constant>(v)) { int bd = get_uint32(dyn_cast<Constant>(v)); if(bd > 0) full_rate_flag = true; } } } break; } } } } return(opt_fn_found); }
bool Input::mapTag(StringRef Tag, bool Default) { std::string foundTag = CurrentNode->_node->getVerbatimTag(); if (foundTag.empty()) { // If no tag found and 'Tag' is the default, say it was found. return Default; } // Return true iff found tag matches supplied tag. return Tag.equals(foundTag); }
void ExecutionContext::setProperty(const StringRef name, const ValueRef value) { Scope scope(this); for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) { if (ctx->type == Type_WithContext) { ScopedObject w(scope, static_cast<WithContext *>(ctx)->withObject); if (w->__hasProperty__(name)) { w->put(name, value); return; } } else if (ctx->type == Type_CatchContext && static_cast<CatchContext *>(ctx)->exceptionVarName->isEqualTo(name)) { static_cast<CatchContext *>(ctx)->exceptionValue = *value; return; } else { ScopedObject activation(scope, (Object *)0); if (ctx->type >= Type_CallContext) { CallContext *c = static_cast<CallContext *>(ctx); if (c->function->function) { uint index = c->function->function->internalClass->find(name); if (index < UINT_MAX) { if (index < c->function->formalParameterCount) { c->callData->args[c->function->formalParameterCount - index - 1] = *value; } else { index -= c->function->formalParameterCount; c->locals[index] = *value; } return; } } activation = c->activation; } else if (ctx->type == Type_GlobalContext) { activation = static_cast<GlobalContext *>(ctx)->global; } if (activation) { if (ctx->type == Type_QmlContext) { activation->put(name, value); return; } else { PropertyAttributes attrs; Property *p = activation->__getOwnProperty__(name, &attrs); if (p) { activation->putValue(p, attrs, value); return; } } } } } if (strictMode || name->equals(engine->id_this)) { ScopedValue n(scope, name.asReturnedValue()); throwReferenceError(n); return; } engine->globalObject->put(name, value); }
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(); } }
bool RemoveRedundantCheckPass::runOnBasicBlock(BasicBlock* BB) { std::vector<Instruction*> redundantList; for (BasicBlock::iterator i = BB->begin(), e = BB->end(); i != e; ++i) { Instruction *inst = &*i; if (CallInst *CI = dyn_cast<CallInst>(inst)) { if (CI->getCalledFunction() == NULL) continue; StringRef funcName = CI->getCalledFunction()->getName(); if (funcName.equals("checkLessThan")) { RangeCheckSet* current = (*availableMap)[inst]; //errs() << "Call: " << *CI << "\n"; //errs() << "Available Expressions: "; current->println(); RangeCheckExpression* expr1 = new RangeCheckExpression(CI, M); for (std::vector<RangeCheckExpression>::iterator it = current->checkSet->begin(); it != current->checkSet->end(); ++it) { RangeCheckExpression* expr2 = &(*it); if (*expr1 == *expr2) { //errs() << "*** REMOVED ***\n"; redundantList.push_back(CI); } else if (expr2->subsumes(expr1)) { //errs() << "*** REMOVED ***\n"; redundantList.push_back(CI); } } } } } std::vector<Instruction*>::iterator it; for (it = redundantList.begin(); it != redundantList.end(); it++) { removedNum++; errs() << "Removing: " << **it << "\n"; (*it)->eraseFromParent(); } return true; }
static SectionRef getSectionRef(const ObjectFile *objectFile, ArrayRef<StringRef> anySectionNames) { for (auto section : objectFile->sections()) { StringRef sectionName; section.getName(sectionName); for (auto desiredName : anySectionNames) { if (sectionName.equals(desiredName)) { return section; } } } return SectionRef(); }
void ObjCContainersChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { StringRef Name = C.getCalleeName(CE); if (Name.empty() || CE->getNumArgs() < 1) return; // Add array size information to the state. if (Name.equals("CFArrayCreate")) { if (CE->getNumArgs() < 3) return; // Note, we can visit the Create method in the post-visit because // the CFIndex parameter is passed in by value and will not be invalidated // by the call. addSizeInfo(CE, CE->getArg(2), C); return; } if (Name.equals("CFArrayGetCount")) { addSizeInfo(CE->getArg(0), CE, C); return; } }
bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD, StringRef Name) { // To avoid false positives (Ex: finding user defined functions with // similar names), only perform fuzzy name matching when it's a builtin. // Using a string compare is slow, we might want to switch on BuiltinID here. unsigned BId = FD->getBuiltinID(); if (BId != 0) { if (Name.empty()) return true; StringRef BName = FD->getASTContext().BuiltinInfo.GetName(BId); if (BName.find(Name) != StringRef::npos) return true; } const IdentifierInfo *II = FD->getIdentifier(); // If this is a special C++ name without IdentifierInfo, it can't be a // C library function. if (!II) return false; // Look through 'extern "C"' and anything similar invented in the future. const DeclContext *DC = FD->getDeclContext(); while (DC->isTransparentContext()) DC = DC->getParent(); // If this function is in a namespace, it is not a C library function. if (!DC->isTranslationUnit()) return false; // If this function is not externally visible, it is not a C library function. // Note that we make an exception for inline functions, which may be // declared in header files without external linkage. if (!FD->isInlined() && FD->getLinkage() != ExternalLinkage) return false; if (Name.empty()) return true; StringRef FName = II->getName(); if (FName.equals(Name)) return true; if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos)) return true; if (FName.startswith("__") && FName.endswith("_chk") && FName.find(Name) != StringRef::npos) return true; return false; }
static Triple::ArchType parseARMArch(StringRef ArchName) { size_t offset = StringRef::npos; Triple::ArchType arch = Triple::UnknownArch; bool isThumb = ArchName.startswith("thumb"); if (ArchName.equals("arm")) return Triple::arm; if (ArchName.equals("armeb")) return Triple::armeb; if (ArchName.equals("thumb")) return Triple::thumb; if (ArchName.equals("thumbeb")) return Triple::thumbeb; if (ArchName.equals("arm64") || ArchName.equals("aarch64")) return Triple::aarch64; if (ArchName.equals("aarch64_be")) return Triple::aarch64_be; if (ArchName.startswith("armv")) { offset = 3; if (ArchName.endswith("eb")) { arch = Triple::armeb; ArchName = ArchName.substr(0, ArchName.size() - 2); } else arch = Triple::arm; } else if (ArchName.startswith("armebv")) { offset = 5; arch = Triple::armeb; } else if (ArchName.startswith("thumbv")) { offset = 5; if (ArchName.endswith("eb")) { arch = Triple::thumbeb; ArchName = ArchName.substr(0, ArchName.size() - 2); } else arch = Triple::thumb; } else if (ArchName.startswith("thumbebv")) { offset = 7; arch = Triple::thumbeb; } return StringSwitch<Triple::ArchType>(ArchName.substr(offset)) .Cases("v2", "v2a", isThumb ? Triple::UnknownArch : arch) .Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch) .Cases("v4", "v4t", arch) .Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch) .Cases("v6", "v6j", "v6k", "v6m", "v6sm", arch) .Cases("v6t2", "v6z", "v6zk", arch) .Cases("v7", "v7a", "v7em", "v7l", arch) .Cases("v7m", "v7r", "v7s", arch) .Cases("v8", "v8a", arch) .Cases("v8.1", "v8.1a", arch) .Default(Triple::UnknownArch); }
void replaceWithLoweredDeclaration(Module& M, Function* F) { LLVMContext& context = M.getContext(); StringRef name = F->getName(); if (!(name.equals("getindex") || name.equals("setindex"))) { return; } std::vector<Type*> ArgTypes = lowerJuliaArrayArgumentsDecl(F); FunctionType *functionType = buildLoweredFunctionType(F, ArgTypes); Function* NewFunc = Function::Create( functionType, F->getLinkage(), F->getName(), &M ); replaceAllCallsWith(F, NewFunc); F->eraseFromParent(); NewFunc->setName(mangle(context, name, functionType)); }
/// getFunctionName - Get function name for the given FnDecl. If the /// name is constructred on demand (e.g. C++ destructor) then the name /// is stored on the side. StringRef DebugInfo::getFunctionName(tree FnDecl) { StringRef FnNodeName = GetNodeName(FnDecl); // Use dwarf_name to construct function names. In C++ this is used to // create human readable destructor names. StringRef FnName = lang_hooks.dwarf_name(FnDecl, 0); if (FnNodeName.equals(FnName)) return FnNodeName; // Use name returned by dwarf_name. It is in a temp. storage so make a // copy first. char *StrPtr = FunctionNames.Allocate<char>(FnName.size() + 1); strncpy(StrPtr, FnName.data(), FnName.size()); StrPtr[FnName.size()] = 0; return StringRef(StrPtr); }
std::string FileInfo::getCoveragePath(StringRef Filename, StringRef MainFilename) { if (Options.NoOutput) // This is probably a bug in gcov, but when -n is specified, paths aren't // mangled at all, and the -l and -p options are ignored. Here, we do the // same. return Filename; std::string CoveragePath; if (Options.LongFileNames && !Filename.equals(MainFilename)) CoveragePath = mangleCoveragePath(MainFilename, Options.PreservePaths) + "##"; CoveragePath += mangleCoveragePath(Filename, Options.PreservePaths) + ".gcov"; return CoveragePath; }
bool Registry::referenceKindFromString(StringRef inputStr, Reference::KindNamespace &ns, Reference::KindArch &arch, Reference::KindValue &value) const { for (const KindEntry &entry : _kindEntries) { for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) { if (!inputStr.equals(pair->name)) continue; ns = entry.ns; arch = entry.arch; value = pair->value; return true; } } return false; }
bool llvm::slicing::handleCall(Function &F, FunctionStaticSlicer &ss, const CallInst *CI) { const char *ass_file = getenv("SLICE_ASSERT_FILE"); const char *ass_line = getenv("SLICE_ASSERT_LINE"); const ConstantExpr *fileArg = dyn_cast<ConstantExpr>(CI->getArgOperand(1)); //const ConstantInt *lineArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)); const ConstantInt *lineArg = dyn_cast<ConstantInt>(CI->getArgOperand(1)); if (ass_file && ass_line) { if (fileArg && fileArg->getOpcode() == Instruction::GetElementPtr && lineArg) { const GlobalVariable *strVar = dyn_cast<GlobalVariable>(fileArg->getOperand(0)); assert(strVar && strVar->hasInitializer()); const ConstantDataArray *str = dyn_cast<ConstantDataArray>(strVar->getInitializer()); assert(str && str->isCString()); /* trim the NUL terminator */ StringRef fileArgStr = str->getAsString().drop_back(1); const int ass_line_int = atoi(ass_line); errs() << "ASSERT at " << fileArgStr << ":" << lineArg->getValue() << "\n"; if (fileArgStr.equals(ass_file) && lineArg->equalsInt(ass_line_int)) { errs() << "\tMATCH\n"; goto count; } } ss.addSkipAssert(CI); return false; } count: #ifdef DEBUG_INITCRIT errs() << " adding\n"; #endif ss.addInitialCriterion(CI, Pointee(F.getParent()->getGlobalVariable("__ai_init_functions", true), -1)); // Add all the arguments of the call instruction for( int i = 0; i< CI->getNumArgOperands(); i++){ ss.addInitialCriterion(CI, Pointee(CI->getArgOperand(i), -1)); } return true; }
void ObjCContainersChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { StringRef Name = C.getCalleeName(CE); if (Name.empty() || CE->getNumArgs() < 2) return; // Check the array access. if (Name.equals("CFArrayGetValueAtIndex")) { ProgramStateRef State = C.getState(); // Retrieve the size. // Find out if we saw this array symbol before and have information about // it. const Expr *ArrayExpr = CE->getArg(0); SymbolRef ArraySym = getArraySym(ArrayExpr, C); if (!ArraySym) return; const DefinedSVal *Size = State->get<ArraySizeMap>(ArraySym); if (!Size) return; // Get the index. const Expr *IdxExpr = CE->getArg(1); SVal IdxVal = State->getSVal(IdxExpr, C.getLocationContext()); if (IdxVal.isUnknownOrUndef()) return; DefinedSVal Idx = IdxVal.castAs<DefinedSVal>(); // Now, check if 'Idx in [0, Size-1]'. const QualType T = IdxExpr->getType(); ProgramStateRef StInBound = State->assumeInBound(Idx, *Size, true, T); ProgramStateRef StOutBound = State->assumeInBound(Idx, *Size, false, T); if (StOutBound && !StInBound) { ExplodedNode *N = C.generateSink(StOutBound); if (!N) return; initBugType(); auto R = llvm::make_unique<BugReport>(*BT, "Index is out of bounds", N); R->addRange(IdxExpr->getSourceRange()); C.emitReport(std::move(R)); return; } } }
void InsInfo::handleVariousFuns(const ptr::PointsToSets &PS, const CallInst *C, const Function *F) { if (!F->hasName()) return; StringRef fName = F->getName(); if (fName.equals("klee_make_symbolic")) { const Value *l = elimConstExpr(C->getArgOperand(0)); const Value *len = elimConstExpr(C->getArgOperand(1)); uint64_t lenConst = getSizeOfMem(len); addREF(Pointee(l, -1)); addDEFArray(PS, l, lenConst); if (!isConstantValue(len)) addREF(Pointee(len, -1)); } }
size_t CaseInsensitiveHashTable<T>::get_indices(StringRef name, IndexVec* result) const { result->clear(); bool is_case_sensitive = false; if (name.size() > 0 && name.front() == '"' && name.back() == '"') { is_case_sensitive = true; name = name.substr(1, name.size() - 2); } size_t h = fnv1a_hash_lower(name) & index_mask_; size_t start = h; while (index_[h] != NULL && !iequals(name, index_[h]->name)) { h = (h + 1) & index_mask_; if (h == start) { return 0; } } const T* entry = index_[h]; if (entry == NULL) { return 0; } if (!is_case_sensitive) { while (entry != NULL) { result->push_back(entry->index); entry = entry->next; } } else { while (entry != NULL) { if (name.equals(entry->name)) { result->push_back(entry->index); } entry = entry->next; } } return result->size(); }
static bool handleAssert(Function &F, FunctionStaticSlicer &ss, const CallInst *CI) { const char *ass_file = getenv("SLICE_ASSERT_FILE"); const char *ass_line = getenv("SLICE_ASSERT_LINE"); const ConstantExpr *fileArg = dyn_cast<ConstantExpr>(CI->getArgOperand(1)); const ConstantInt *lineArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)); if (ass_file && ass_line) { if (fileArg && fileArg->getOpcode() == Instruction::GetElementPtr && lineArg) { const GlobalVariable *strVar = dyn_cast<GlobalVariable>(fileArg->getOperand(0)); assert(strVar && strVar->hasInitializer()); const ConstantArray *str = dyn_cast<ConstantArray>(strVar->getInitializer()); assert(str && str->isCString()); /* trim the NUL terminator */ StringRef tmpStr(str->getAsString()); StringRef fileArgStr = tmpStr.substr(0,tmpStr.size() - 1); const int ass_line_int = atoi(ass_line); errs() << "ASSERT at " << fileArgStr << ":" << lineArg->getValue() << "\n"; if (fileArgStr.equals(ass_file) && lineArg->equalsInt(ass_line_int)) { errs() << "\tMATCH\n"; goto count; } } ss.addSkipAssert(CI); return false; } count: #ifdef DEBUG_INITCRIT errs() << " adding\n"; #endif ss.addInitialCriterion(CI, F.getParent()->getGlobalVariable("__ai_init_functions", true)); return true; }
/// \brief Find string metadata for loop, if it exists return true, else return /// false. bool llvm::findStringMetadataForLoop(Loop *TheLoop, StringRef Name) { MDNode *LoopID = TheLoop->getLoopID(); // Return false if LoopID is false. if (!LoopID) return false; // First operand should refer to the loop id itself. assert(LoopID->getNumOperands() > 0 && "requires at least one operand"); assert(LoopID->getOperand(0) == LoopID && "invalid loop id"); // Iterate over LoopID operands and look for MDString Metadata for (unsigned i = 1, e = LoopID->getNumOperands(); i < e; ++i) { MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(i)); if (!MD) continue; MDString *S = dyn_cast<MDString>(MD->getOperand(0)); if (!S) continue; // Return true if MDString holds expected MetaData. if (Name.equals(S->getString())) return true; } return false; }