static bool doesNoDiscardMacroExist(ASTContext &Context, const llvm::StringRef &MacroId) { // Don't check for the Macro existence if we are using an attribute // either a C++17 standard attribute or pre C++17 syntax if (MacroId.startswith("[[") || MacroId.startswith("__attribute__")) return true; // Otherwise look up the macro name in the context to see if its defined. return Context.Idents.get(MacroId).hasMacroDefinition(); }
lldb::SymbolType ObjectFile::GetSymbolTypeFromName(llvm::StringRef name, lldb::SymbolType symbol_type_hint) { if (!name.empty()) { if (name.startswith("_T")) { // Swift if (name.startswith("_TM")) return lldb::eSymbolTypeMetadata; if (name.startswith("_TWvd")) return lldb::eSymbolTypeIVarOffset; } else if (name.startswith("_OBJC_")) { // ObjC if (name.startswith("_OBJC_CLASS_$_")) return lldb::eSymbolTypeObjCClass; if (name.startswith("_OBJC_METACLASS_$_")) return lldb::eSymbolTypeObjCMetaClass; if (name.startswith("_OBJC_IVAR_$_")) return lldb::eSymbolTypeObjCIVar; } else if (name.startswith(".objc_class_name_")) { // ObjC v1 return lldb::eSymbolTypeObjCClass; } } return symbol_type_hint; }
std::string Context::getThunkTarget(llvm::StringRef MangledName) { if (!isThunkSymbol(MangledName)) return std::string(); if (isMangledName(MangledName)) { // The targets of those thunks not derivable from the mangling. if (MangledName.endswith("TR") || MangledName.endswith("Tr") || MangledName.endswith("TW") ) return std::string(); if (MangledName.endswith("fC")) { std::string target = MangledName.str(); target[target.size() - 1] = 'c'; return target; } return MangledName.substr(0, MangledName.size() - 2).str(); } // Old mangling. assert(MangledName.startswith("_T")); StringRef Remaining = MangledName.substr(2); if (Remaining.startswith("PA_")) return Remaining.substr(3).str(); if (Remaining.startswith("PAo_")) return Remaining.substr(4).str(); assert(Remaining.startswith("To") || Remaining.startswith("TO")); return std::string("_T") + Remaining.substr(2).str(); }
// Parses the contents of version.txt in an CUDA installation. It should // contain one line of the from e.g. "CUDA Version 7.5.2". static CudaVersion ParseCudaVersionFile(llvm::StringRef V) { if (!V.startswith("CUDA Version ")) return CudaVersion::UNKNOWN; V = V.substr(strlen("CUDA Version ")); int Major = -1, Minor = -1; auto First = V.split('.'); auto Second = First.second.split('.'); if (First.first.getAsInteger(10, Major) || Second.first.getAsInteger(10, Minor)) return CudaVersion::UNKNOWN; if (Major == 7 && Minor == 0) { // This doesn't appear to ever happen -- version.txt doesn't exist in the // CUDA 7 installs I've seen. But no harm in checking. return CudaVersion::CUDA_70; } if (Major == 7 && Minor == 5) return CudaVersion::CUDA_75; if (Major == 8 && Minor == 0) return CudaVersion::CUDA_80; if (Major == 9 && Minor == 0) return CudaVersion::CUDA_90; if (Major == 9 && Minor == 1) return CudaVersion::CUDA_91; return CudaVersion::UNKNOWN; }
URI::URI(llvm::StringRef Scheme, llvm::StringRef Authority, llvm::StringRef Body) : Scheme(Scheme), Authority(Authority), Body(Body) { assert(!Scheme.empty()); assert((Authority.empty() || Body.startswith("/")) && "URI body must start with '/' when authority is present."); }
static void demangle(llvm::raw_ostream &os, llvm::StringRef name, const swift::Demangle::DemangleOptions &options) { bool hadLeadingUnderscore = false; if (name.startswith("__")) { hadLeadingUnderscore = true; name = name.substr(1); } swift::Demangle::NodePointer pointer = swift::demangle_wrappers::demangleSymbolAsNode(name); if (ExpandMode || TreeOnly) { llvm::outs() << "Demangling for " << name << '\n'; swift::demangle_wrappers::NodeDumper(pointer).print(llvm::outs()); } if (RemangleMode) { if (hadLeadingUnderscore) llvm::outs() << '_'; // Just reprint the original mangled name if it didn't demangle. // This makes it easier to share the same database between the // mangling and demangling tests. if (!pointer) { llvm::outs() << name; } else { llvm::outs() << swift::Demangle::mangleNode(pointer); } return; } if (!TreeOnly) { std::string string = swift::Demangle::nodeToString(pointer, options); if (!CompactMode) llvm::outs() << name << " ---> "; llvm::outs() << (string.empty() ? name : llvm::StringRef(string)); } }
llvm::Optional<TextEdit> IncludeInserter::insert(llvm::StringRef VerbatimHeader) const { llvm::Optional<TextEdit> Edit = None; if (auto Insertion = Inserter.insert(VerbatimHeader.trim("\"<>"), VerbatimHeader.startswith("<"))) Edit = replacementToEdit(Code, *Insertion); return Edit; }
void AutoloadCallback::report(clang::SourceLocation l, llvm::StringRef name, llvm::StringRef header) { Sema& sema= m_Interpreter->getSema(); unsigned id = sema.getDiagnostics().getCustomDiagID (DiagnosticsEngine::Level::Warning, "Note: '%0' can be found in %1"); /* unsigned idn //TODO: To be enabled after we have a way to get the full path = sema.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Level::Note, "Type : %0 , Full Path: %1")*/; if (header.startswith(llvm::StringRef(annoTag, lenAnnoTag))) sema.Diags.Report(l, id) << name << header.drop_front(lenAnnoTag); }
static bool IsValidBasename(const llvm::StringRef &basename) { // Check that the basename matches with the following regular expression or is // an operator name: // "^~?([A-Za-z_][A-Za-z_0-9]*)(<.*>)?$" // We are using a hand written implementation because it is significantly more // efficient then // using the general purpose regular expression library. size_t idx = 0; if (basename.size() > 0 && basename[0] == '~') idx = 1; if (basename.size() <= idx) return false; // Empty string or "~" if (!std::isalpha(basename[idx]) && basename[idx] != '_') return false; // First charater (after removing the possible '~'') isn't in // [A-Za-z_] // Read all characters matching [A-Za-z_0-9] ++idx; while (idx < basename.size()) { if (!std::isalnum(basename[idx]) && basename[idx] != '_') break; ++idx; } // We processed all characters. It is a vaild basename. if (idx == basename.size()) return true; // Check for basename with template arguments // TODO: Improve the quality of the validation with validating the template // arguments if (basename[idx] == '<' && basename.back() == '>') return true; // Check if the basename is a vaild C++ operator name if (!basename.startswith("operator")) return false; static RegularExpression g_operator_regex( llvm::StringRef("^(operator)( " "?)([A-Za-z_][A-Za-z_0-9]*|\\(\\)|" "\\[\\]|[\\^<>=!\\/" "*+-]+)(<.*>)?(\\[\\])?$")); std::string basename_str(basename.str()); return g_operator_regex.Execute(basename_str, nullptr); }
bool MocPPCallbacks::FileNotFound(llvm::StringRef FileName, llvm::SmallVectorImpl< char >& RecoveryPath) { if (FileName.endswith(".moc") || FileName.endswith("_moc.cpp") || FileName.startswith("moc_")) { if (!PP.GetSuppressIncludeNotFoundError()) { PP.SetSuppressIncludeNotFoundError(true); IncludeNotFoundSupressed = true; } } else { if (IncludeNotFoundSupressed) { PP.SetSuppressIncludeNotFoundError(false); IncludeNotFoundSupressed = false; } else { ShouldWarnHeaderNotFound = true; } } return false; }
bool Context::isThunkSymbol(llvm::StringRef MangledName) { if (isMangledName(MangledName)) { // First do a quick check if (MangledName.endswith("TA") || // partial application forwarder MangledName.endswith("Ta") || // ObjC partial application forwarder MangledName.endswith("To") || // swift-as-ObjC thunk MangledName.endswith("TO") || // ObjC-as-swift thunk MangledName.endswith("TR") || // reabstraction thunk helper function MangledName.endswith("Tr") || // reabstraction thunk MangledName.endswith("TW") || // protocol witness thunk MangledName.endswith("fC")) { // allocating constructor // To avoid false positives, we need to fully demangle the symbol. NodePointer Nd = D->demangleSymbol(MangledName); if (!Nd || Nd->getKind() != Node::Kind::Global || Nd->getNumChildren() == 0) return false; switch (Nd->getFirstChild()->getKind()) { case Node::Kind::ObjCAttribute: case Node::Kind::NonObjCAttribute: case Node::Kind::PartialApplyObjCForwarder: case Node::Kind::PartialApplyForwarder: case Node::Kind::ReabstractionThunkHelper: case Node::Kind::ReabstractionThunk: case Node::Kind::ProtocolWitness: case Node::Kind::Allocator: return true; default: break; } } return false; } if (MangledName.startswith("_T")) { // Old mangling. StringRef Remaining = MangledName.substr(2); if (Remaining.startswith("To") || // swift-as-ObjC thunk Remaining.startswith("TO") || // ObjC-as-swift thunk Remaining.startswith("PA_") || // partial application forwarder Remaining.startswith("PAo_")) { // ObjC partial application forwarder return true; } } return false; }
/// \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(llvm::StringRef define, unsigned &Major, unsigned &Minor, unsigned &Micro) { assert(define.startswith(SimulatorVersionDefineName())); llvm::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; }
bool cocoa::isRefType(QualType RetTy, llvm::StringRef Prefix, llvm::StringRef Name) { // Recursively walk the typedef stack, allowing typedefs of reference types. while (const TypedefType *TD = dyn_cast<TypedefType>(RetTy.getTypePtr())) { llvm::StringRef TDName = TD->getDecl()->getIdentifier()->getName(); if (TDName.startswith(Prefix) && TDName.endswith("Ref")) return true; RetTy = TD->getDecl()->getUnderlyingType(); } if (Name.empty()) return false; // Is the type void*? const PointerType* PT = RetTy->getAs<PointerType>(); if (!(PT->getPointeeType().getUnqualifiedType()->isVoidType())) return false; // Does the name start with the prefix? return Name.startswith(Prefix); }
std::string DynamicLibraryManager::lookupLibrary(llvm::StringRef libStem) const { llvm::SmallString<128> Absolute(libStem); llvm::sys::fs::make_absolute(Absolute); bool isAbsolute = libStem == Absolute; // If it is an absolute path, don't try iterate over the paths. if (isAbsolute) { if (isSharedLib(libStem)) return normalizePath(libStem); else return ""; } std::string foundName = lookupLibMaybeAddExt(libStem); if (foundName.empty() && !libStem.startswith("lib")) { // try with "lib" prefix: foundName = lookupLibMaybeAddExt("lib" + libStem.str()); } if (isSharedLib(foundName)) return normalizePath(foundName); return ""; }
void XCTMigrator::migrateInclude(llvm::StringRef Filename, CharSourceRange FilenameRange, SourceLocation HashLoc, bool isAngled) { StringRef Parent = "SenTestingKit/"; if (!Filename.startswith(Parent)) return; if (isFromSenTestInclude(HashLoc)) return; edit::Commit commit(Editor); StringRef HeaderName = Filename.substr(Parent.size()); llvm::StringMap<llvm::StringRef>::iterator I = IncludesMap.find(HeaderName); if (I == IncludesMap.end() || I->second.empty()) { commit.remove(CharSourceRange::getCharRange(HashLoc,FilenameRange.getEnd())); } else { SmallString<128> NewInclude; NewInclude.push_back(isAngled ? '<' : '"'); NewInclude += "XCTest/"; NewInclude += I->second; NewInclude.push_back(isAngled ? '>' : '"'); commit.replace(FilenameRange, NewInclude.str()); } Editor.commit(commit); }
std::vector<find_all_symbols::SymbolInfo> SymbolIndexManager::search(llvm::StringRef Identifier, bool IsNestedSearch) const { // The identifier may be fully qualified, so split it and get all the context // names. llvm::SmallVector<llvm::StringRef, 8> Names; Identifier.split(Names, "::"); bool IsFullyQualified = false; if (Identifier.startswith("::")) { Names.erase(Names.begin()); // Drop first (empty) element. IsFullyQualified = true; } // As long as we don't find a result keep stripping name parts from the end. // This is to support nested classes which aren't recorded in the database. // Eventually we will either hit a class (namespaces aren't in the database // either) and can report that result. bool TookPrefix = false; std::vector<clang::find_all_symbols::SymbolInfo> MatchedSymbols; do { std::vector<clang::find_all_symbols::SymbolInfo> Symbols; for (const auto &DB : SymbolIndices) { auto Res = DB->search(Names.back().str()); Symbols.insert(Symbols.end(), Res.begin(), Res.end()); } DEBUG(llvm::dbgs() << "Searching " << Names.back() << "... got " << Symbols.size() << " results...\n"); for (const auto &Symbol : Symbols) { // Match the identifier name without qualifier. if (Symbol.getName() == Names.back()) { bool IsMatched = true; auto SymbolContext = Symbol.getContexts().begin(); auto IdentiferContext = Names.rbegin() + 1; // Skip identifier name. // Match the remaining context names. while (IdentiferContext != Names.rend() && SymbolContext != Symbol.getContexts().end()) { if (SymbolContext->second == *IdentiferContext) { ++IdentiferContext; ++SymbolContext; } else if (SymbolContext->first == find_all_symbols::SymbolInfo::ContextType::EnumDecl) { // Skip non-scoped enum context. ++SymbolContext; } else { IsMatched = false; break; } } // If the name was qualified we only want to add results if we evaluated // all contexts. if (IsFullyQualified) IsMatched &= (SymbolContext == Symbol.getContexts().end()); // FIXME: Support full match. At this point, we only find symbols in // database which end with the same contexts with the identifier. if (IsMatched && IdentiferContext == Names.rend()) { // If we're in a situation where we took a prefix but the thing we // found couldn't possibly have a nested member ignore it. if (TookPrefix && (Symbol.getSymbolKind() == SymbolInfo::SymbolKind::Function || Symbol.getSymbolKind() == SymbolInfo::SymbolKind::Variable || Symbol.getSymbolKind() == SymbolInfo::SymbolKind::EnumConstantDecl || Symbol.getSymbolKind() == SymbolInfo::SymbolKind::Macro)) continue; MatchedSymbols.push_back(Symbol); } } } Names.pop_back(); TookPrefix = true; } while (MatchedSymbols.empty() && !Names.empty() && IsNestedSearch); rankByPopularity(MatchedSymbols); return MatchedSymbols; }
static bool IsPercentageProperty(llvm::StringRef name) { if (name.startswith("raw_")) name = name.substr(4); return name == "brightness" || name == "contrast" || name == "saturation" || name == "hue" || name == "sharpness" || name == "gain" || name == "exposure_absolute"; }
//===----------------------------------------------------------------------===// // parser<mcld::ZOption> //===----------------------------------------------------------------------===// bool parser<mcld::ZOption>::parse(llvm::cl::Option &O, llvm::StringRef ArgName, llvm::StringRef Arg, mcld::ZOption &Val) { if (0 == Arg.compare("combreloc")) Val.setKind(ZOption::CombReloc); else if (0 == Arg.compare("nocombreloc")) Val.setKind(ZOption::NoCombReloc); else if (0 == Arg.compare("defs")) Val.setKind(ZOption::Defs); else if (0 == Arg.compare("execstack")) Val.setKind(ZOption::ExecStack); else if (0 == Arg.compare("noexecstack")) Val.setKind(ZOption::NoExecStack); else if (0 == Arg.compare("initfirst")) Val.setKind(ZOption::InitFirst); else if (0 == Arg.compare("interpose")) Val.setKind(ZOption::InterPose); else if (0 == Arg.compare("loadfltr")) Val.setKind(ZOption::LoadFltr); else if (0 == Arg.compare("muldefs")) Val.setKind(ZOption::MulDefs); else if (0 == Arg.compare("nocopyreloc")) Val.setKind(ZOption::NoCopyReloc); else if (0 == Arg.compare("nodefaultlib")) Val.setKind(ZOption::NoDefaultLib); else if (0 == Arg.compare("nodelete")) Val.setKind(ZOption::NoDelete); else if (0 == Arg.compare("nodlopen")) Val.setKind(ZOption::NoDLOpen); else if (0 == Arg.compare("nodump")) Val.setKind(ZOption::NoDump); else if (0 == Arg.compare("relro")) Val.setKind(ZOption::Relro); else if (0 == Arg.compare("norelro")) Val.setKind(ZOption::NoRelro); else if (0 == Arg.compare("lazy")) Val.setKind(ZOption::Lazy); else if (0 == Arg.compare("now")) Val.setKind(ZOption::Now); else if (0 == Arg.compare("origin")) Val.setKind(ZOption::Origin); else if (Arg.startswith("common-page-size=")) { Val.setKind(ZOption::CommPageSize); long long unsigned size = 0; Arg.drop_front(17).getAsInteger(0, size); Val.setPageSize(static_cast<uint64_t>(size)); } else if (Arg.startswith("max-page-size=")) { Val.setKind(ZOption::MaxPageSize); long long unsigned size = 0; Arg.drop_front(14).getAsInteger(0, size); Val.setPageSize(static_cast<uint64_t>(size)); } if (ZOption::Unknown == Val.kind()) llvm::report_fatal_error(llvm::Twine("unknown -z option: `") + Arg + llvm::Twine("'\n")); return false; }
bool isLiteralInclude(llvm::StringRef Include) { return Include.startswith("<") || Include.startswith("\""); }
bool Interpreter::isUniqueWrapper(llvm::StringRef name) { return name.startswith(utils::Synthesize::UniquePrefix); }
static inline llvm::StringRef extractUSRSuffix(llvm::StringRef s) { return s.startswith("c:") ? s.substr(2) : ""; }
lldb::SectionType IRExecutionUnit::GetSectionTypeFromSectionName (const llvm::StringRef &name, IRExecutionUnit::AllocationKind alloc_kind) { lldb::SectionType sect_type = lldb::eSectionTypeCode; switch (alloc_kind) { case AllocationKind::Stub: sect_type = lldb::eSectionTypeCode; break; case AllocationKind::Code: sect_type = lldb::eSectionTypeCode; break; case AllocationKind::Data: sect_type = lldb::eSectionTypeData; break; case AllocationKind::Global:sect_type = lldb::eSectionTypeData; break; case AllocationKind::Bytes: sect_type = lldb::eSectionTypeOther; break; } if (!name.empty()) { if (name.equals("__text") || name.equals(".text")) sect_type = lldb::eSectionTypeCode; else if (name.equals("__data") || name.equals(".data")) sect_type = lldb::eSectionTypeCode; else if (name.startswith("__debug_") || name.startswith(".debug_")) { const uint32_t name_idx = name[0] == '_' ? 8 : 7; llvm::StringRef dwarf_name(name.substr(name_idx)); switch (dwarf_name[0]) { case 'a': if (dwarf_name.equals("abbrev")) sect_type = lldb::eSectionTypeDWARFDebugAbbrev; else if (dwarf_name.equals("aranges")) sect_type = lldb::eSectionTypeDWARFDebugAranges; break; case 'f': if (dwarf_name.equals("frame")) sect_type = lldb::eSectionTypeDWARFDebugFrame; break; case 'i': if (dwarf_name.equals("info")) sect_type = lldb::eSectionTypeDWARFDebugInfo; break; case 'l': if (dwarf_name.equals("line")) sect_type = lldb::eSectionTypeDWARFDebugLine; else if (dwarf_name.equals("loc")) sect_type = lldb::eSectionTypeDWARFDebugLoc; break; case 'm': if (dwarf_name.equals("macinfo")) sect_type = lldb::eSectionTypeDWARFDebugMacInfo; break; case 'p': if (dwarf_name.equals("pubnames")) sect_type = lldb::eSectionTypeDWARFDebugPubNames; else if (dwarf_name.equals("pubtypes")) sect_type = lldb::eSectionTypeDWARFDebugPubTypes; break; case 's': if (dwarf_name.equals("str")) sect_type = lldb::eSectionTypeDWARFDebugStr; break; case 'r': if (dwarf_name.equals("ranges")) sect_type = lldb::eSectionTypeDWARFDebugRanges; break; default: break; } } else if (name.startswith("__apple_") || name.startswith(".apple_")) { #if 0 const uint32_t name_idx = name[0] == '_' ? 8 : 7; llvm::StringRef apple_name(name.substr(name_idx)); switch (apple_name[0]) { case 'n': if (apple_name.equals("names")) sect_type = lldb::eSectionTypeDWARFAppleNames; else if (apple_name.equals("namespac") || apple_name.equals("namespaces")) sect_type = lldb::eSectionTypeDWARFAppleNamespaces; break; case 't': if (apple_name.equals("types")) sect_type = lldb::eSectionTypeDWARFAppleTypes; break; case 'o': if (apple_name.equals("objc")) sect_type = lldb::eSectionTypeDWARFAppleObjC; break; default: break; } #else sect_type = lldb::eSectionTypeInvalid; #endif } else if (name.equals("__objc_imageinfo")) sect_type = lldb::eSectionTypeOther; } return sect_type; }
InputValidator::ValidationResult InputValidator::validate(llvm::StringRef line) { ValidationResult Res = kComplete; Token Tok; const char* curPos = line.data(); bool multilineComment = inBlockComment(); int commentTok = multilineComment ? tok::asterik : tok::slash; if (!multilineComment && m_ParenStack.empty()) { // Only check for 'template' if we're not already indented MetaLexer Lex(curPos, true); Lex.Lex(Tok); curPos = Lex.getLocation(); if (Tok.is(tok::ident)) { if (Tok.getIdent()=="template") m_ParenStack.push_back(tok::greater); } else curPos -= Tok.getLength(); // Rewind buffer for LexPunctuatorAndAdvance } do { const char* prevStart = curPos; if (!MetaLexer::LexPunctuatorAndAdvance(curPos, Tok)) { // there were tokens between the previous and this Tok. commentTok = tok::slash; } const int kind = (int)Tok.getKind(); if (kind == commentTok) { if (kind == tok::slash) { if (multilineComment) { // exiting a comment, unwind the stack multilineComment = false; commentTok = tok::slash; unwindTokens(m_ParenStack, tok::slash); } // If we have a closing comment without a start it will be transformed // to */; and clang reports an error for both the */ and the ; // If we return kIncomplete, then just one error is printed, but too // late: after the user has another expression which will always fail. // So just deal with two errors for now // else if (prevKind == tok::asterik) { // Res = kIncomplete; // break; // } else // wait for an asterik commentTok = tok::asterik; } else { assert(commentTok == tok::asterik && "Comment token not / or *"); if (!multilineComment) { // entering a new comment multilineComment = true; m_ParenStack.push_back(tok::slash); } else // wait for closing / (must be next token) commentTok = tok::slash; } } else { // If we're in a multiline, and waiting for the closing slash // we gonna have to wait for another asterik first if (multilineComment) { if (kind == tok::eof) { switch (findNestedBlockComments(prevStart, curPos)) { case -1: unwindTokens(m_ParenStack, tok::slash); case 1: case 0: break; default: assert(0 && "Nested block comment count"); break; } // eof, were done anyway break; } else if (commentTok == tok::slash) { // Cancel the wait for a slash, but only if current token isn't // also an asterik. if (kind != tok::asterik) commentTok = tok::asterik; } } if (kind >= (int)tok::l_square && kind <= (int)tok::r_brace) { // The closing paren kind is open paren kind + 1 (i.e odd number) if (kind % 2) { int prev = m_ParenStack.empty() ? -1: m_ParenStack.back(); // closing the right one? if (prev != kind - 1) { if (multilineComment) continue; Res = kMismatch; break; } m_ParenStack.pop_back(); // Right brace will pop a template if their is one if (kind == tok::r_brace && m_ParenStack.size() == 1 ) { if (m_ParenStack.back() == tok::greater) m_ParenStack.pop_back(); } } else m_ParenStack.push_back(kind); } else if (kind == tok::hash) { MetaLexer Lex(curPos); Lex.SkipWhitespace(); Lex.LexAnyString(Tok); const llvm::StringRef PPtk = Tok.getIdent(); if (PPtk.startswith("endif") && (PPtk.size() > 5 ? PPtk[5]=='/' || isspace(PPtk[5]) : true)) { if (m_ParenStack.empty() || m_ParenStack.back() != tok::hash) { Res = kMismatch; break; } m_ParenStack.pop_back(); } else if (PPtk.startswith("if")) { m_ParenStack.push_back(tok::hash); } } else if (kind == tok::semicolon) { // Template forward declatation if (m_ParenStack.size() == 1 && m_ParenStack.back()==tok::greater) m_ParenStack.pop_back(); } else if (kind >= (int)tok::stringlit && kind <= (int)tok::charlit) { MetaLexer::LexQuotedStringAndAdvance(curPos, Tok); } } } while (Tok.isNot(tok::eof)); if (!m_ParenStack.empty() && Res != kMismatch) Res = kIncomplete; if (!m_Input.empty()) { if (!m_ParenStack.empty() && (m_ParenStack.back() == tok::stringlit || m_ParenStack.back() == tok::charlit)) m_Input.append("\\n"); else m_Input.append("\n"); } else m_Input = ""; m_Input.append(line); return Res; }
static void demangle(llvm::raw_ostream &os, llvm::StringRef name, swift::Demangle::Context &DCtx, const swift::Demangle::DemangleOptions &options) { bool hadLeadingUnderscore = false; if (name.startswith("__")) { hadLeadingUnderscore = true; name = name.substr(1); } swift::Demangle::NodePointer pointer = DCtx.demangleSymbolAsNode(name); if (ExpandMode || TreeOnly) { llvm::outs() << "Demangling for " << name << '\n'; llvm::outs() << getNodeTreeAsString(pointer); } if (RemangleMode) { std::string remangled; if (!pointer || !(name.startswith(MANGLING_PREFIX_STR) || name.startswith("_S"))) { // Just reprint the original mangled name if it didn't demangle or is in // the old mangling scheme. // This makes it easier to share the same database between the // mangling and demangling tests. remangled = name; } else { remangled = swift::Demangle::mangleNode(pointer); // Also accept the future mangling prefix. // TODO: remove the special "_S" handling as soon as MANGLING_PREFIX_STR // gets "_S". if (name.startswith("_S")) { assert(remangled.find(MANGLING_PREFIX_STR) == 0); remangled = "_S" + remangled.substr(3); } if (name != remangled) { llvm::errs() << "\nError: re-mangled name \n " << remangled << "\ndoes not match original name\n " << name << '\n'; exit(1); } } if (hadLeadingUnderscore) llvm::outs() << '_'; llvm::outs() << remangled; return; } if (!TreeOnly) { if (RemangleNew) { if (!pointer) { llvm::errs() << "Can't de-mangle " << name << '\n'; exit(1); } std::string remangled = swift::Demangle::mangleNode(pointer); llvm::outs() << remangled; return; } std::string string = swift::Demangle::nodeToString(pointer, options); if (!CompactMode) llvm::outs() << name << " ---> "; if (Classify) { std::string Classifications; std::string cName = name.str(); if (!swift::Demangle::isSwiftSymbol(cName.c_str())) Classifications += 'N'; if (DCtx.isThunkSymbol(name)) { if (!Classifications.empty()) Classifications += ','; Classifications += "T:"; Classifications += DCtx.getThunkTarget(name); } else { assert(DCtx.getThunkTarget(name).empty()); } if (pointer && !DCtx.hasSwiftCallingConvention(name)) { if (!Classifications.empty()) Classifications += ','; Classifications += 'C'; } if (!Classifications.empty()) llvm::outs() << '{' << Classifications << "} "; } llvm::outs() << (string.empty() ? name : llvm::StringRef(string)); } DCtx.clear(); }