void DeclContext::localUncachedLookup(DeclarationName Name, SmallVectorImpl<NamedDecl *> &Results) { Results.clear(); // If there's no external storage, just perform a normal lookup and copy // the results. if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) { lookup_result LookupResults = lookup(Name); Results.insert(Results.end(), LookupResults.begin(), LookupResults.end()); return; } // If we have a lookup table, check there first. Maybe we'll get lucky. if (Name && !LookupPtr.getInt()) { if (StoredDeclsMap *Map = LookupPtr.getPointer()) { StoredDeclsMap::iterator Pos = Map->find(Name); if (Pos != Map->end()) { Results.insert(Results.end(), Pos->second.getLookupResult().begin(), Pos->second.getLookupResult().end()); return; } } } // Slow case: grovel through the declarations in our chain looking for // matches. for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) { if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) if (ND->getDeclName() == Name) Results.push_back(ND); } }
static void insertArgsFromProgramName(StringRef ProgName, const DriverSuffix *DS, SmallVectorImpl<const char *> &ArgVector, std::set<std::string> &SavedStrings) { if (!DS) return; if (const char *Flag = DS->ModeFlag) { // Add Flag to the arguments. auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; ArgVector.insert(it, Flag); } StringRef::size_type LastComponent = ProgName.rfind( '-', ProgName.size() - strlen(DS->Suffix)); if (LastComponent == StringRef::npos) return; // Infer target from the prefix. StringRef Prefix = ProgName.slice(0, LastComponent); std::string IgnoredError; if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; const char *arr[] = { "-target", GetStableCStr(SavedStrings, Prefix) }; ArgVector.insert(it, std::begin(arr), std::end(arr)); } }
static void ParseProgName(SmallVectorImpl<const char *> &ArgVector, std::set<std::string> &SavedStrings) { // Try to infer frontend type and default target from the program name by // comparing it against DriverSuffixes in order. // If there is a match, the function tries to identify a target as prefix. // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target // prefix "x86_64-linux". If such a target prefix is found, is gets added via // -target as implicit first argument. std::string ProgName =llvm::sys::path::stem(ArgVector[0]); #ifdef LLVM_ON_WIN32 // Transform to lowercase for case insensitive file systems. ProgName = StringRef(ProgName).lower(); #endif StringRef ProgNameRef = ProgName; const DriverSuffix *DS = FindDriverSuffix(ProgNameRef); if (!DS) { // Try again after stripping any trailing version number: // clang++3.5 -> clang++ ProgNameRef = ProgNameRef.rtrim("0123456789."); DS = FindDriverSuffix(ProgNameRef); } if (!DS) { // Try again after stripping trailing -component. // clang++-tot -> clang++ ProgNameRef = ProgNameRef.slice(0, ProgNameRef.rfind('-')); DS = FindDriverSuffix(ProgNameRef); } if (DS) { if (const char *Flag = DS->ModeFlag) { // Add Flag to the arguments. auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; ArgVector.insert(it, Flag); } StringRef::size_type LastComponent = ProgNameRef.rfind( '-', ProgNameRef.size() - strlen(DS->Suffix)); if (LastComponent == StringRef::npos) return; // Infer target from the prefix. StringRef Prefix = ProgNameRef.slice(0, LastComponent); std::string IgnoredError; if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; const char *arr[] = { "-target", GetStableCStr(SavedStrings, Prefix) }; ArgVector.insert(it, std::begin(arr), std::end(arr)); } } }
static void insertTargetAndModeArgs(StringRef Target, StringRef Mode, SmallVectorImpl<const char *> &ArgVector, std::set<std::string> &SavedStrings) { if (!Mode.empty()) { // Add the mode flag to the arguments. auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; ArgVector.insert(it, GetStableCStr(SavedStrings, Mode)); } if (!Target.empty()) { auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; const char *arr[] = {"-target", GetStableCStr(SavedStrings, Target)}; ArgVector.insert(it, std::begin(arr), std::end(arr)); } }
// Construct a DIE for this scope. void DwarfCompileUnit::constructScopeDIE( LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) { if (!Scope || !Scope->getScopeNode()) return; auto *DS = Scope->getScopeNode(); assert((Scope->getInlinedAt() || !isa<DISubprogram>(DS)) && "Only handle inlined subprograms here, use " "constructSubprogramScopeDIE for non-inlined " "subprograms"); SmallVector<DIE *, 8> Children; // We try to create the scope DIE first, then the children DIEs. This will // avoid creating un-used children then removing them later when we find out // the scope DIE is null. DIE *ScopeDIE; if (Scope->getParent() && isa<DISubprogram>(DS)) { ScopeDIE = constructInlinedScopeDIE(Scope); if (!ScopeDIE) return; // We create children when the scope DIE is not null. createScopeChildrenDIE(Scope, Children); } else { // Early exit when we know the scope DIE is going to be null. if (DD->isLexicalScopeDIENull(Scope)) return; bool HasNonScopeChildren = false; // We create children here when we know the scope DIE is not going to be // null and the children will be added to the scope DIE. createScopeChildrenDIE(Scope, Children, &HasNonScopeChildren); // If there are only other scopes as children, put them directly in the // parent instead, as this scope would serve no purpose. if (!HasNonScopeChildren) { FinalChildren.insert(FinalChildren.end(), std::make_move_iterator(Children.begin()), std::make_move_iterator(Children.end())); return; } ScopeDIE = constructLexicalScopeDIE(Scope); assert(ScopeDIE && "Scope DIE should not be null."); } // Add children for (auto &I : Children) ScopeDIE->addChild(std::move(I)); FinalChildren.push_back(std::move(ScopeDIE)); }
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix /// and the specified global variable's name. If the global variable doesn't /// have a name, this fills in a unique name for the global. void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV) { ManglerPrefixTy PrefixTy = Mangler::Default; if (GV->hasPrivateLinkage()) PrefixTy = Mangler::Private; else if (GV->hasLinkerPrivateLinkage() || GV->hasLinkerPrivateWeakLinkage()) PrefixTy = Mangler::LinkerPrivate; // If this global has a name, handle it simply. if (GV->hasName()) { StringRef Name = GV->getName(); getNameWithPrefix(OutName, Name, PrefixTy); // No need to do anything else if the global has the special "do not mangle" // flag in the name. if (Name[0] == 1) return; } else { // Get the ID for the global, assigning a new one if we haven't got one // already. unsigned &ID = AnonGlobalIDs[GV]; if (ID == 0) ID = NextAnonGlobalID++; // Must mangle the global into a unique ID. getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy); } // If we are supposed to add a microsoft-style suffix for stdcall/fastcall, // add it. if (DL->hasMicrosoftFastStdCallMangling()) { if (const Function *F = dyn_cast<Function>(GV)) { CallingConv::ID CC = F->getCallingConv(); // fastcall functions need to start with @. // FIXME: This logic seems unlikely to be right. if (CC == CallingConv::X86_FastCall) { if (OutName[0] == '_') OutName[0] = '@'; else OutName.insert(OutName.begin(), '@'); } // fastcall and stdcall functions usually need @42 at the end to specify // the argument info. FunctionType *FT = F->getFunctionType(); if ((CC == CallingConv::X86_FastCall || CC == CallingConv::X86_StdCall) && // "Pure" variadic functions do not receive @0 suffix. (!FT->isVarArg() || FT->getNumParams() == 0 || (FT->getNumParams() == 1 && F->hasStructRetAttr()))) AddFastCallStdCallSuffix(OutName, F, *DL); } } }
static void insertTargetAndModeArgs(const ParsedClangName &NameParts, SmallVectorImpl<const char *> &ArgVector, std::set<std::string> &SavedStrings) { // Put target and mode arguments at the start of argument list so that // arguments specified in command line could override them. Avoid putting // them at index 0, as an option like '-cc1' must remain the first. int InsertionPoint = 0; if (ArgVector.size() > 0) ++InsertionPoint; if (NameParts.DriverMode) { // Add the mode flag to the arguments. ArgVector.insert(ArgVector.begin() + InsertionPoint, GetStableCStr(SavedStrings, NameParts.DriverMode)); } if (NameParts.TargetIsValid) { const char *arr[] = {"-target", GetStableCStr(SavedStrings, NameParts.TargetPrefix)}; ArgVector.insert(ArgVector.begin() + InsertionPoint, std::begin(arr), std::end(arr)); } }
// Include the debug info compression header: // "ZLIB" followed by 8 bytes representing the uncompressed size of the section, // useful for consumers to preallocate a buffer to decompress into. static bool prependCompressionHeader(uint64_t Size, SmallVectorImpl<char> &CompressedContents) { const StringRef Magic = "ZLIB"; if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) return false; if (sys::IsLittleEndianHost) sys::swapByteOrder(Size); CompressedContents.insert(CompressedContents.begin(), Magic.size() + sizeof(Size), 0); std::copy(Magic.begin(), Magic.end(), CompressedContents.begin()); std::copy(reinterpret_cast<char *>(&Size), reinterpret_cast<char *>(&Size + 1), CompressedContents.begin() + Magic.size()); return true; }
/// ApplyQAOverride - Apply a list of edits to the input argument lists. /// /// The input string is a space separate list of edits to perform, /// they are applied in order to the input argument lists. Edits /// should be one of the following forms: /// /// '#': Silence information about the changes to the command line arguments. /// /// '^': Add FOO as a new argument at the beginning of the command line. /// /// '+': Add FOO as a new argument at the end of the command line. /// /// 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command /// line. /// /// 'xOPTION': Removes all instances of the literal argument OPTION. /// /// 'XOPTION': Removes all instances of the literal argument OPTION, /// and the following argument. /// /// 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox' /// at the end of the command line. /// /// \param OS - The stream to write edit information to. /// \param Args - The vector of command line arguments. /// \param Edit - The override command to perform. /// \param SavedStrings - Set to use for storing string representations. static void ApplyOneQAOverride(raw_ostream &OS, SmallVectorImpl<const char*> &Args, StringRef Edit, std::set<std::string> &SavedStrings) { // This does not need to be efficient. if (Edit[0] == '^') { const char *Str = SaveStringInSet(SavedStrings, Edit.substr(1)); OS << "### Adding argument " << Str << " at beginning\n"; Args.insert(Args.begin() + 1, Str); } else if (Edit[0] == '+') { const char *Str = SaveStringInSet(SavedStrings, Edit.substr(1)); OS << "### Adding argument " << Str << " at end\n"; Args.push_back(Str); } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") && Edit.slice(2, Edit.size()-1).find('/') != StringRef::npos) { StringRef MatchPattern = Edit.substr(2).split('/').first; StringRef ReplPattern = Edit.substr(2).split('/').second; ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1); for (unsigned i = 1, e = Args.size(); i != e; ++i) { std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]); if (Repl != Args[i]) { OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n"; Args[i] = SaveStringInSet(SavedStrings, Repl); } } } else if (Edit[0] == 'x' || Edit[0] == 'X') { std::string Option = Edit.substr(1, std::string::npos); for (unsigned i = 1; i < Args.size();) { if (Option == Args[i]) { OS << "### Deleting argument " << Args[i] << '\n'; Args.erase(Args.begin() + i); if (Edit[0] == 'X') { if (i < Args.size()) { OS << "### Deleting argument " << Args[i] << '\n'; Args.erase(Args.begin() + i); } else OS << "### Invalid X edit, end of command line!\n"; } } else ++i; } } else if (Edit[0] == 'O') { for (unsigned i = 1; i < Args.size();) { const char *A = Args[i]; if (A[0] == '-' && A[1] == 'O' && (A[2] == '\0' || (A[3] == '\0' && (A[2] == 's' || A[2] == 'z' || ('0' <= A[2] && A[2] <= '9'))))) { OS << "### Deleting argument " << Args[i] << '\n'; Args.erase(Args.begin() + i); } else ++i; } OS << "### Adding argument " << Edit << " at end\n"; Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit.str())); } else { OS << "### Unrecognized edit: " << Edit << "\n"; } }
static void ParseProgName(SmallVectorImpl<const char *> &ArgVector, std::set<std::string> &SavedStrings, Driver &TheDriver) { // Try to infer frontend type and default target from the program name. // suffixes[] contains the list of known driver suffixes. // Suffixes are compared against the program name in order. // If there is a match, the frontend type is updated as necessary (CPP/C++). // If there is no match, a second round is done after stripping the last // hyphen and everything following it. This allows using something like // "clang++-2.9". // If there is a match in either the first or second round, // the function tries to identify a target as prefix. E.g. // "x86_64-linux-clang" as interpreted as suffix "clang" with // target prefix "x86_64-linux". If such a target prefix is found, // is gets added via -target as implicit first argument. static const struct { const char *Suffix; bool IsCXX; bool IsCPP; } suffixes [] = { { "clang", false, false }, { "clang++", true, false }, { "clang-c++", true, false }, { "clang-cc", false, false }, { "clang-cpp", false, true }, { "clang-g++", true, false }, { "clang-gcc", false, false }, { "cc", false, false }, { "cpp", false, true }, { "++", true, false }, }; std::string ProgName(llvm::sys::path::stem(ArgVector[0])); StringRef ProgNameRef(ProgName); StringRef Prefix; for (int Components = 2; Components; --Components) { bool FoundMatch = false; size_t i; for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) { if (ProgNameRef.endswith(suffixes[i].Suffix)) { FoundMatch = true; if (suffixes[i].IsCXX) TheDriver.CCCIsCXX = true; if (suffixes[i].IsCPP) TheDriver.CCCIsCPP = true; break; } } if (FoundMatch) { StringRef::size_type LastComponent = ProgNameRef.rfind('-', ProgNameRef.size() - strlen(suffixes[i].Suffix)); if (LastComponent != StringRef::npos) Prefix = ProgNameRef.slice(0, LastComponent); break; } StringRef::size_type LastComponent = ProgNameRef.rfind('-'); if (LastComponent == StringRef::npos) break; ProgNameRef = ProgNameRef.slice(0, LastComponent); } if (Prefix.empty()) return; std::string IgnoredError; if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { SmallVectorImpl<const char *>::iterator it = ArgVector.begin(); if (it != ArgVector.end()) ++it; ArgVector.insert(it, SaveStringInSet(SavedStrings, Prefix)); ArgVector.insert(it, SaveStringInSet(SavedStrings, std::string("-target"))); } }
bool GuardWideningImpl::combineRangeChecks( SmallVectorImpl<GuardWideningImpl::RangeCheck> &Checks, SmallVectorImpl<GuardWideningImpl::RangeCheck> &RangeChecksOut) { unsigned OldCount = Checks.size(); while (!Checks.empty()) { // Pick all of the range checks with a specific base and length, and try to // merge them. Value *CurrentBase = Checks.front().getBase(); Value *CurrentLength = Checks.front().getLength(); SmallVector<GuardWideningImpl::RangeCheck, 3> CurrentChecks; auto IsCurrentCheck = [&](GuardWideningImpl::RangeCheck &RC) { return RC.getBase() == CurrentBase && RC.getLength() == CurrentLength; }; copy_if(Checks, std::back_inserter(CurrentChecks), IsCurrentCheck); Checks.erase(remove_if(Checks, IsCurrentCheck), Checks.end()); assert(CurrentChecks.size() != 0 && "We know we have at least one!"); if (CurrentChecks.size() < 3) { RangeChecksOut.insert(RangeChecksOut.end(), CurrentChecks.begin(), CurrentChecks.end()); continue; } // CurrentChecks.size() will typically be 3 here, but so far there has been // no need to hard-code that fact. std::sort(CurrentChecks.begin(), CurrentChecks.end(), [&](const GuardWideningImpl::RangeCheck &LHS, const GuardWideningImpl::RangeCheck &RHS) { return LHS.getOffsetValue().slt(RHS.getOffsetValue()); }); // Note: std::sort should not invalidate the ChecksStart iterator. ConstantInt *MinOffset = CurrentChecks.front().getOffset(), *MaxOffset = CurrentChecks.back().getOffset(); unsigned BitWidth = MaxOffset->getValue().getBitWidth(); if ((MaxOffset->getValue() - MinOffset->getValue()) .ugt(APInt::getSignedMinValue(BitWidth))) return false; APInt MaxDiff = MaxOffset->getValue() - MinOffset->getValue(); const APInt &HighOffset = MaxOffset->getValue(); auto OffsetOK = [&](const GuardWideningImpl::RangeCheck &RC) { return (HighOffset - RC.getOffsetValue()).ult(MaxDiff); }; if (MaxDiff.isMinValue() || !std::all_of(std::next(CurrentChecks.begin()), CurrentChecks.end(), OffsetOK)) return false; // We have a series of f+1 checks as: // // I+k_0 u< L ... Chk_0 // I_k_1 u< L ... Chk_1 // ... // I_k_f u< L ... Chk_(f+1) // // with forall i in [0,f): k_f-k_i u< k_f-k_0 ... Precond_0 // k_f-k_0 u< INT_MIN+k_f ... Precond_1 // k_f != k_0 ... Precond_2 // // Claim: // Chk_0 AND Chk_(f+1) implies all the other checks // // Informal proof sketch: // // We will show that the integer range [I+k_0,I+k_f] does not unsigned-wrap // (i.e. going from I+k_0 to I+k_f does not cross the -1,0 boundary) and // thus I+k_f is the greatest unsigned value in that range. // // This combined with Ckh_(f+1) shows that everything in that range is u< L. // Via Precond_0 we know that all of the indices in Chk_0 through Chk_(f+1) // lie in [I+k_0,I+k_f], this proving our claim. // // To see that [I+k_0,I+k_f] is not a wrapping range, note that there are // two possibilities: I+k_0 u< I+k_f or I+k_0 >u I+k_f (they can't be equal // since k_0 != k_f). In the former case, [I+k_0,I+k_f] is not a wrapping // range by definition, and the latter case is impossible: // // 0-----I+k_f---I+k_0----L---INT_MAX,INT_MIN------------------(-1) // xxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // // For Chk_0 to succeed, we'd have to have k_f-k_0 (the range highlighted // with 'x' above) to be at least >u INT_MIN. RangeChecksOut.emplace_back(CurrentChecks.front()); RangeChecksOut.emplace_back(CurrentChecks.back()); } assert(RangeChecksOut.size() <= OldCount && "We pessimized!"); return RangeChecksOut.size() != OldCount; }
MipsInstrInfo::BranchType MipsInstrInfo::AnalyzeBranch( MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, bool AllowModify, SmallVectorImpl<MachineInstr *> &BranchInstrs) const { MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); // Skip all the debug instructions. while (I != REnd && I->isDebugValue()) ++I; if (I == REnd || !isUnpredicatedTerminator(*I)) { // This block ends with no branches (it just falls through to its succ). // Leave TBB/FBB null. TBB = FBB = nullptr; return BT_NoBranch; } MachineInstr *LastInst = &*I; unsigned LastOpc = LastInst->getOpcode(); BranchInstrs.push_back(LastInst); // Not an analyzable branch (e.g., indirect jump). if (!getAnalyzableBrOpc(LastOpc)) return LastInst->isIndirectBranch() ? BT_Indirect : BT_None; // Get the second to last instruction in the block. unsigned SecondLastOpc = 0; MachineInstr *SecondLastInst = nullptr; if (++I != REnd) { SecondLastInst = &*I; SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode()); // Not an analyzable branch (must be an indirect jump). if (isUnpredicatedTerminator(*SecondLastInst) && !SecondLastOpc) return BT_None; } // If there is only one terminator instruction, process it. if (!SecondLastOpc) { // Unconditional branch. if (LastInst->isUnconditionalBranch()) { TBB = LastInst->getOperand(0).getMBB(); return BT_Uncond; } // Conditional branch AnalyzeCondBr(LastInst, LastOpc, TBB, Cond); return BT_Cond; } // If we reached here, there are two branches. // If there are three terminators, we don't know what sort of block this is. if (++I != REnd && isUnpredicatedTerminator(*I)) return BT_None; BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst); // If second to last instruction is an unconditional branch, // analyze it and remove the last instruction. if (SecondLastInst->isUnconditionalBranch()) { // Return if the last instruction cannot be removed. if (!AllowModify) return BT_None; TBB = SecondLastInst->getOperand(0).getMBB(); LastInst->eraseFromParent(); BranchInstrs.pop_back(); return BT_Uncond; } // Conditional branch followed by an unconditional branch. // The last one must be unconditional. if (!LastInst->isUnconditionalBranch()) return BT_None; AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond); FBB = LastInst->getOperand(0).getMBB(); return BT_CondUncond; }
static void ParseProgName(SmallVectorImpl<const char *> &ArgVector, std::set<std::string> &SavedStrings, Driver &TheDriver) { // Try to infer frontend type and default target from the program name. // suffixes[] contains the list of known driver suffixes. // Suffixes are compared against the program name in order. // If there is a match, the frontend type is updated as necessary (CPP/C++). // If there is no match, a second round is done after stripping the last // hyphen and everything following it. This allows using something like // "clang++-2.9". // If there is a match in either the first or second round, // the function tries to identify a target as prefix. E.g. // "x86_64-linux-clang" as interpreted as suffix "clang" with // target prefix "x86_64-linux". If such a target prefix is found, // is gets added via -target as implicit first argument. static const struct { const char *Suffix; const char *ModeFlag; } suffixes [] = { { "templight", nullptr }, { "templight++", "--driver-mode=g++" }, { "templight-c++", "--driver-mode=g++" }, { "templight-cc", nullptr }, { "templight-cpp", "--driver-mode=cpp" }, { "templight-g++", "--driver-mode=g++" }, { "templight-gcc", nullptr }, { "templight-cl", "--driver-mode=cl" }, { "cc", nullptr }, { "cpp", "--driver-mode=cpp" }, { "cl" , "--driver-mode=cl" }, { "++", "--driver-mode=g++" }, }; std::string ProgName(llvm::sys::path::stem(ArgVector[0])); #ifdef LLVM_ON_WIN32 // Transform to lowercase for case insensitive file systems. std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), toLowercase); #endif StringRef ProgNameRef(ProgName); StringRef Prefix; for (int Components = 2; Components; --Components) { bool FoundMatch = false; size_t i; for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) { if (ProgNameRef.endswith(suffixes[i].Suffix)) { FoundMatch = true; SmallVectorImpl<const char *>::iterator it = ArgVector.begin(); if (it != ArgVector.end()) ++it; if (suffixes[i].ModeFlag) ArgVector.insert(it, suffixes[i].ModeFlag); break; } } if (FoundMatch) { StringRef::size_type LastComponent = ProgNameRef.rfind('-', ProgNameRef.size() - strlen(suffixes[i].Suffix)); if (LastComponent != StringRef::npos) Prefix = ProgNameRef.slice(0, LastComponent); break; } StringRef::size_type LastComponent = ProgNameRef.rfind('-'); if (LastComponent == StringRef::npos) break; ProgNameRef = ProgNameRef.slice(0, LastComponent); } if (Prefix.empty()) return; std::string IgnoredError; if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { SmallVectorImpl<const char *>::iterator it = ArgVector.begin(); if (it != ArgVector.end()) ++it; const char* Strings[] = { GetStableCStr(SavedStrings, std::string("-target")), GetStableCStr(SavedStrings, Prefix) }; ArgVector.insert(it, Strings, Strings + llvm::array_lengthof(Strings)); } }
/// GenerateNewArgTokens - Returns true if OldTokens can be converted to a new /// vector of tokens in NewTokens. The new number of arguments will be placed /// in NumArgs and the ranges which need to surrounded in parentheses will be /// in ParenHints. /// Returns false if the token stream cannot be changed. If this is because /// of an initializer list starting a macro argument, the range of those /// initializer lists will be place in InitLists. static bool GenerateNewArgTokens(Preprocessor &PP, SmallVectorImpl<Token> &OldTokens, SmallVectorImpl<Token> &NewTokens, unsigned &NumArgs, SmallVectorImpl<SourceRange> &ParenHints, SmallVectorImpl<SourceRange> &InitLists) { if (!CheckMatchedBrackets(OldTokens)) return false; // Once it is known that the brackets are matched, only a simple count of the // braces is needed. unsigned Braces = 0; // First token of a new macro argument. SmallVectorImpl<Token>::iterator ArgStartIterator = OldTokens.begin(); // First closing brace in a new macro argument. Used to generate // SourceRanges for InitLists. SmallVectorImpl<Token>::iterator ClosingBrace = OldTokens.end(); NumArgs = 0; Token TempToken; // Set to true when a macro separator token is found inside a braced list. // If true, the fixed argument spans multiple old arguments and ParenHints // will be updated. bool FoundSeparatorToken = false; for (SmallVectorImpl<Token>::iterator I = OldTokens.begin(), E = OldTokens.end(); I != E; ++I) { if (I->is(tok::l_brace)) { ++Braces; } else if (I->is(tok::r_brace)) { --Braces; if (Braces == 0 && ClosingBrace == E && FoundSeparatorToken) ClosingBrace = I; } else if (I->is(tok::eof)) { // EOF token is used to separate macro arguments if (Braces != 0) { // Assume comma separator is actually braced list separator and change // it back to a comma. FoundSeparatorToken = true; I->setKind(tok::comma); I->setLength(1); } else { // Braces == 0 // Separator token still separates arguments. ++NumArgs; // If the argument starts with a brace, it can't be fixed with // parentheses. A different diagnostic will be given. if (FoundSeparatorToken && ArgStartIterator->is(tok::l_brace)) { InitLists.push_back( SourceRange(ArgStartIterator->getLocation(), PP.getLocForEndOfToken(ClosingBrace->getLocation()))); ClosingBrace = E; } // Add left paren if (FoundSeparatorToken) { TempToken.startToken(); TempToken.setKind(tok::l_paren); TempToken.setLocation(ArgStartIterator->getLocation()); TempToken.setLength(0); NewTokens.push_back(TempToken); } // Copy over argument tokens NewTokens.insert(NewTokens.end(), ArgStartIterator, I); // Add right paren and store the paren locations in ParenHints if (FoundSeparatorToken) { SourceLocation Loc = PP.getLocForEndOfToken((I - 1)->getLocation()); TempToken.startToken(); TempToken.setKind(tok::r_paren); TempToken.setLocation(Loc); TempToken.setLength(0); NewTokens.push_back(TempToken); ParenHints.push_back(SourceRange(ArgStartIterator->getLocation(), Loc)); } // Copy separator token NewTokens.push_back(*I); // Reset values ArgStartIterator = I + 1; FoundSeparatorToken = false; } } } return !ParenHints.empty() && InitLists.empty(); }
static void ParseProgName(SmallVectorImpl<const char *> &ArgVector, std::set<std::string> &SavedStrings, Driver &TheDriver) { // Try to infer frontend type and default target from the program name. // suffixes[] contains the list of known driver suffixes. // Suffixes are compared against the program name in order. // If there is a match, the frontend type is updated as necessary (CPP/C++). // If there is no match, a second round is done after stripping the last // hyphen and everything following it. This allows using something like // "clang++-2.9". // If there is a match in either the first or second round, // the function tries to identify a target as prefix. E.g. // "x86_64-linux-clang" as interpreted as suffix "clang" with // target prefix "x86_64-linux". If such a target prefix is found, // is gets added via -target as implicit first argument. static const struct { const char *Suffix; const char *ModeFlag; bool IsELLCC; } suffixes [] = { { "clang", 0 }, { "clang++", "--driver-mode=g++" }, { "clang-c++", "--driver-mode=g++" }, { "clang-cc", 0 }, { "clang-cpp", "--driver-mode=cpp" }, { "clang-g++", "--driver-mode=g++" }, { "clang-gcc", 0 }, { "ecc", 0, true }, { "ecc++", "--driver-mode=g++", true }, { "clang-cl", "--driver-mode=cl" }, { "cc", 0 }, { "cpp", "--driver-mode=cpp" }, { "cl" , "--driver-mode=cl" }, { "++", "--driver-mode=g++" }, }; std::string ProgName(llvm::sys::path::stem(ArgVector[0])); std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), toLowercase); StringRef ProgNameRef(ProgName); StringRef Prefix; for (int Components = 2; Components; --Components) { bool FoundMatch = false; size_t i; for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) { if (ProgNameRef.endswith(suffixes[i].Suffix)) { FoundMatch = true; SmallVectorImpl<const char *>::iterator it = ArgVector.begin(); if (it != ArgVector.end()) ++it; if (suffixes[i].ModeFlag) ArgVector.insert(it, suffixes[i].ModeFlag); if (suffixes[i].IsELLCC) TheDriver.CCCIsELLCC = true; break; } } if (FoundMatch) { StringRef::size_type LastComponent = ProgNameRef.rfind('-', ProgNameRef.size() - strlen(suffixes[i].Suffix)); if (LastComponent != StringRef::npos) Prefix = ProgNameRef.slice(0, LastComponent); break; } StringRef::size_type LastComponent = ProgNameRef.rfind('-'); if (LastComponent == StringRef::npos) break; ProgNameRef = ProgNameRef.slice(0, LastComponent); } if (Prefix.empty()) return; if (TheDriver.CCCIsELLCC) { llvm::Triple triple(ProgName); if (triple.getArch() != llvm::Triple::UnknownArch) { llvm::StringRef OS = triple.getVendorName(); triple.setOSName(OS); if (OS == "elf" || triple.getOS() != llvm::Triple::UnknownOS) { // We have a valid arch and OS. // "elf" is used for OS neutural builds. // Use this to create the ELLCC triple. // The name looks like <arch>-<os>-* if (OS == "elf") { triple.setOSName("unknown"); } } } std::vector<const char*> ExtraArgs; ExtraArgs.push_back("-ccc-clang-archs"); ExtraArgs.push_back(""); ExtraArgs.push_back("-ccc-host-triple"); std::string et(triple.getArchName().str() + "-ellcc-" + triple.getOSName().str()); ExtraArgs.push_back(SaveStringInSet(SavedStrings, et.c_str())); ArgVector.insert(&ArgVector[1], ExtraArgs.begin(), ExtraArgs.end()); } else { std::string IgnoredError; if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { SmallVectorImpl<const char *>::iterator it = ArgVector.begin(); if (it != ArgVector.end()) ++it; const char* Strings[] = { SaveStringInSet(SavedStrings, std::string("-target")), SaveStringInSet(SavedStrings, Prefix) }; ArgVector.insert(it, Strings, Strings + llvm::array_lengthof(Strings)); } } }