static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl, llvm::SmallVectorImpl<ObjCProtocolDecl*> &ConformingProtocols, const NSAPI &NS, edit::Commit &commit) { const ObjCList<ObjCProtocolDecl> &Protocols = IDecl->getReferencedProtocols(); std::string ClassString; SourceLocation EndLoc = IDecl->getSuperClass() ? IDecl->getSuperClassLoc() : IDecl->getLocation(); if (Protocols.empty()) { ClassString = '<'; for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { ClassString += ConformingProtocols[i]->getNameAsString(); if (i != (e-1)) ClassString += ", "; } ClassString += "> "; } else { ClassString = ", "; for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { ClassString += ConformingProtocols[i]->getNameAsString(); if (i != (e-1)) ClassString += ", "; } ObjCInterfaceDecl::protocol_loc_iterator PL = IDecl->protocol_loc_end() - 1; EndLoc = *PL; } commit.insertAfterToken(EndLoc, ClassString); return true; }
static std::error_code openModuleFiles(StringRef DirName, StringRef ModuleFilename, StringRef ModuleDocFilename, std::unique_ptr<llvm::MemoryBuffer> &ModuleBuffer, std::unique_ptr<llvm::MemoryBuffer> &ModuleDocBuffer, llvm::SmallVectorImpl<char> &Scratch) { // Try to open the module file first. If we fail, don't even look for the // module documentation file. Scratch.clear(); llvm::sys::path::append(Scratch, DirName, ModuleFilename); llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ModuleOrErr = llvm::MemoryBuffer::getFile(StringRef(Scratch.data(), Scratch.size())); if (!ModuleOrErr) return ModuleOrErr.getError(); // Try to open the module documentation file. If it does not exist, ignore // the error. However, pass though all other errors. Scratch.clear(); llvm::sys::path::append(Scratch, DirName, ModuleDocFilename); llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ModuleDocOrErr = llvm::MemoryBuffer::getFile(StringRef(Scratch.data(), Scratch.size())); if (!ModuleDocOrErr && ModuleDocOrErr.getError() != std::errc::no_such_file_or_directory) { return ModuleDocOrErr.getError(); } ModuleBuffer = std::move(ModuleOrErr.get()); if (ModuleDocOrErr) ModuleDocBuffer = std::move(ModuleDocOrErr.get()); return std::error_code(); }
static void EraseUnwantedCUDAMatchesImpl(Sema &S, const FunctionDecl *Caller, llvm::SmallVectorImpl<T> &Matches, FetchDeclFn FetchDecl) { assert(S.getLangOpts().CUDATargetOverloads && "Should not be called w/o enabled target overloads."); if (Matches.size() <= 1) return; // Find the best call preference among the functions in Matches. Sema::CUDAFunctionPreference P, BestCFP = Sema::CFP_Never; for (auto const &Match : Matches) { P = S.IdentifyCUDAPreference(Caller, FetchDecl(Match)); if (P > BestCFP) BestCFP = P; } // Erase all functions with lower priority. for (unsigned I = 0, N = Matches.size(); I != N;) if (S.IdentifyCUDAPreference(Caller, FetchDecl(Matches[I])) < BestCFP) { Matches[I] = Matches[--N]; Matches.resize(N); } else { ++I; } }
// FIXME: Why don't we just put this list in the defs file, eh. void types::getCompilationPhases(ID Id, llvm::SmallVectorImpl<phases::ID> &P) { if (Id != TY_Object) { if (getPreprocessedType(Id) != TY_INVALID) { P.push_back(phases::Preprocess); } if (onlyPrecompileType(Id)) { P.push_back(phases::Precompile); } else { if (!onlyAssembleType(Id)) { P.push_back(phases::Compile); P.push_back(phases::Backend); } if (Id != TY_CUDA_DEVICE) P.push_back(phases::Assemble); } } if (!onlyPrecompileType(Id) && Id != TY_CUDA_DEVICE) { P.push_back(phases::Link); } assert(0 < P.size() && "Not enough phases in list"); assert(P.size() <= phases::MaxNumberOfPhases && "Too many phases in list"); return; }
/// \brief Find the end of the word starting at the given offset /// within a string. /// /// \returns the index pointing one character past the end of the /// word. static unsigned findEndOfWord(unsigned Start, const llvm::SmallVectorImpl<char> &Str, unsigned Length, unsigned Column, unsigned Columns) { assert(Start < Str.size() && "Invalid start position!"); unsigned End = Start + 1; // If we are already at the end of the string, take that as the word. if (End == Str.size()) return End; // Determine if the start of the string is actually opening // punctuation, e.g., a quote or parentheses. char EndPunct = findMatchingPunctuation(Str[Start]); if (!EndPunct) { // This is a normal word. Just find the first space character. while (End < Length && !isspace(Str[End])) ++End; return End; } // We have the start of a balanced punctuation sequence (quotes, // parentheses, etc.). Determine the full sequence is. llvm::SmallVector<char, 16> PunctuationEndStack; PunctuationEndStack.push_back(EndPunct); while (End < Length && !PunctuationEndStack.empty()) { if (Str[End] == PunctuationEndStack.back()) PunctuationEndStack.pop_back(); else if (char SubEndPunct = findMatchingPunctuation(Str[End])) PunctuationEndStack.push_back(SubEndPunct); ++End; } // Find the first space character after the punctuation ended. while (End < Length && !isspace(Str[End])) ++End; unsigned PunctWordLength = End - Start; if (// If the word fits on this line Column + PunctWordLength <= Columns || // ... or the word is "short enough" to take up the next line // without too much ugly white space PunctWordLength < Columns/3) return End; // Take the whole thing as a single "word". // The whole quoted/parenthesized string is too long to print as a // single "word". Instead, find the "word" that starts just after // the punctuation and use that end-point instead. This will recurse // until it finds something small enough to consider a word. return findEndOfWord(Start + 1, Str, Length, Column + 1, Columns); }
/// ParseTemplateParameterList - Parse a template parameter list. If /// the parsing fails badly (i.e., closing bracket was left out), this /// will try to put the token stream in a reasonable position (closing /// a statement, etc.) and return false. /// /// template-parameter-list: [C++ temp] /// template-parameter /// template-parameter-list ',' template-parameter bool Parser::ParseTemplateParameterList(unsigned Depth, llvm::SmallVectorImpl<Decl*> &TemplateParams) { while (1) { if (Decl *TmpParam = ParseTemplateParameter(Depth, TemplateParams.size())) { TemplateParams.push_back(TmpParam); } else { // If we failed to parse a template parameter, skip until we find // a comma or closing brace. SkipUntil(tok::comma, tok::greater, true, true); } // Did we find a comma or the end of the template parmeter list? if (Tok.is(tok::comma)) { ConsumeToken(); } else if (Tok.is(tok::greater)) { // Don't consume this... that's done by template parser. break; } else { // Somebody probably forgot to close the template. Skip ahead and // try to get out of the expression. This error is currently // subsumed by whatever goes on in ParseTemplateParameter. // TODO: This could match >>, and it would be nice to avoid those // silly errors with template <vec<T>>. Diag(Tok.getLocation(), diag::err_expected_comma_greater); SkipUntil(tok::greater, true, true); return false; } } return true; }
static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, llvm::SmallVectorImpl<llvm::Type*> &elementTypes) { ASTContext &C = CGM.getContext(); // The header is basically a 'struct { void *; int; int; void *; void *; }'. CharUnits ptrSize, ptrAlign, intSize, intAlign; llvm::tie(ptrSize, ptrAlign) = C.getTypeInfoInChars(C.UInt32Ty); llvm::tie(intSize, intAlign) = C.getTypeInfoInChars(C.Int32Ty); // Are there crazy embedded platforms where this isn't true? assert(intSize <= ptrSize && "layout assumptions horribly violated"); CharUnits headerSize = ptrSize; if (2 * intSize < ptrAlign) headerSize += ptrSize; else headerSize += 2 * intSize; headerSize += 2 * ptrSize; info.BlockAlign = ptrAlign; info.BlockSize = headerSize; assert(elementTypes.empty()); llvm::Type *i8p = CGM.getTypes().ConvertType(C.UInt32Ty); llvm::Type *intTy = CGM.getTypes().ConvertType(C.Int32Ty); elementTypes.push_back(i8p); elementTypes.push_back(intTy); elementTypes.push_back(intTy); elementTypes.push_back(i8p); elementTypes.push_back(CGM.getBlockDescriptorType()); assert(elementTypes.size() == BlockHeaderSize); }
static void freeCallersOfUnresolvedSymbols(llvm::SmallVectorImpl<llvm::Function*>& funcsToFree, llvm::ExecutionEngine* engine) { llvm::SmallPtrSet<llvm::Function*, 40> funcsToFreeUnique; for (size_t i = 0; i < funcsToFree.size(); ++i) { llvm::Function* func = funcsToFree[i]; assert(func && "Cannot free NULL function"); if (funcsToFreeUnique.insert(func)) { for (llvm::Value::use_iterator IU = func->use_begin(), EU = func->use_end(); IU != EU; ++IU) { llvm::Instruction* instUser = llvm::dyn_cast<llvm::Instruction>(*IU); if (!instUser) continue; if (!instUser->getParent()) continue; if (llvm::Function* userFunc = instUser->getParent()->getParent()) funcsToFree.push_back(userFunc); } } } for (llvm::SmallPtrSet<llvm::Function*, 40>::iterator I = funcsToFreeUnique.begin(), E = funcsToFreeUnique.end(); I != E; ++I) { // This should force the JIT to recompile the function. But the stubs stay, // and the JIT reuses the stubs now pointing nowhere, i.e. without updating // the machine code address. Fix the JIT, or hope that MCJIT helps. //engine->freeMachineCodeForFunction(*I); engine->updateGlobalMapping(*I, 0); } }
StringRef DeclName::getString(llvm::SmallVectorImpl<char> &scratch, bool skipEmptyArgumentNames) const { { llvm::raw_svector_ostream out(scratch); print(out, skipEmptyArgumentNames); } return StringRef(scratch.data(), scratch.size()); }
static void AddFID(FIDMap &FIDs, llvm::SmallVectorImpl<FileID> &V, const SourceManager* SM, SourceLocation L) { FileID FID = SM->getFileID(SM->getInstantiationLoc(L)); FIDMap::iterator I = FIDs.find(FID); if (I != FIDs.end()) return; FIDs[FID] = V.size(); V.push_back(FID); }
llvm::StringRef ParserImpl::MergeTokensUntil(const unsigned int* toks, unsigned int num_toks, SourceLocation* start, SourceLocation* end, llvm::SmallVectorImpl<char>& buffer, bool stop_at_eos, bool stop_at_ws) { buffer.clear(); *start = *end = m_token.getLocation(); for (;;) { // If we found one of the tokens, stop. for (unsigned i = 0; i < num_toks; ++i) { if (m_token.is(toks[i])) goto done; } // If we hit end of statement, stop. if (stop_at_eos && m_token.isEndOfStatement()) break; // Turn the token back into characters. // The first if's are optimizations for common cases. llvm::StringRef data; if (m_token.isLiteral()) { data = m_token.getLiteral(); } else if (m_token.is(Token::identifier) || m_token.is(Token::label)) { IdentifierInfo* ii = m_token.getIdentifierInfo(); data = ii->getName(); } else { // Get the raw data from the source manager. SourceManager& smgr = m_preproc.getSourceManager(); data = llvm::StringRef(smgr.getCharacterData(m_token.getLocation()), m_token.getLength()); } buffer.append(data.begin(), data.end()); *end = m_token.getEndLocation(); ConsumeAnyToken(); // If we hit a token with leading space, stop. // We do this down here in case the first token had preceding ws. if (stop_at_ws && m_token.hasLeadingSpace()) break; } done: return llvm::StringRef(buffer.data(), buffer.size()); }
void ExternalASTSource::SetExternalVisibleDecls(const DeclContext *DC, const llvm::SmallVectorImpl<VisibleDeclaration> &Decls) { // There is no longer any visible storage in this context. DC->ExternalVisibleStorage = false; assert(!DC->LookupPtr && "Have a lookup map before de-serialization?"); StoredDeclsMap *Map = DC->CreateStoredDeclsMap(DC->getParentASTContext()); for (unsigned I = 0, N = Decls.size(); I != N; ++I) { (*Map)[Decls[I].Name].setFromDeclIDs(Decls[I].Declarations); } }
void ExternalASTSource::SetExternalVisibleDecls(const DeclContext *DC, const llvm::SmallVectorImpl<NamedDecl*> &Decls) { // There is no longer any visible storage in this context. DC->ExternalVisibleStorage = false; assert(!DC->LookupPtr && "Have a lookup map before de-serialization?"); StoredDeclsMap &Map = *DC->CreateStoredDeclsMap(DC->getParentASTContext()); for (unsigned I = 0, N = Decls.size(); I != N; ++I) { StoredDeclsList &List = Map[Decls[I]->getDeclName()]; if (List.isNull()) List.setOnlyValue(Decls[I]); else List.AddSubsequentDecl(Decls[I]); } }
CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention, bool _NoReturn, unsigned _RegParm, CanQualType ResTy, const llvm::SmallVectorImpl<CanQualType> &ArgTys) : CallingConvention(_CallingConvention), EffectiveCallingConvention(_CallingConvention), NoReturn(_NoReturn), RegParm(_RegParm) { NumArgs = ArgTys.size(); Args = new ArgInfo[1 + NumArgs]; Args[0].type = ResTy; for (unsigned i = 0; i < NumArgs; ++i) Args[1 + i].type = ArgTys[i]; }
std::pair<Defn *, Defn *> DefnContext::BuildDefnChain(const llvm::SmallVectorImpl<Defn*> &Defns) { // Build up a chain of declarations via the Decl::NextDeclInContext field. Defn *FirstNewDefn = 0; Defn *PrevDefn = 0; for (unsigned I = 0, N = Defns.size(); I != N; ++I) { Defn *D = Defns[I]; if (PrevDefn) PrevDefn->NextDefnInContext = D; else FirstNewDefn = D; PrevDefn = D; } return std::make_pair(FirstNewDefn, PrevDefn); }
void ExternalASTSource::MaterializeVisibleDefnsForName(const DefnContext *DC, DefinitionName Name, llvm::SmallVectorImpl<NamedDefn*> &Defns) { assert(DC->LookupPtr); StoredDefnsMap &Map = *DC->LookupPtr; // If there's an entry in the table the visible decls for this name have // already been deserialized. if (Map.find(Name) == Map.end()) { StoredDefnsList &List = Map[Name]; for (unsigned I = 0, N = Defns.size(); I != N; ++I) { if (List.isNull()) List.setOnlyValue(Defns[I]); else List.AddSubsequentDefn(Defns[I]); } } }
bool Popen(const std::string& Cmd, llvm::SmallVectorImpl<char>& Buf, bool RdE) { if (FILE *PF = ::popen(RdE ? (Cmd + " 2>&1").c_str() : Cmd.c_str(), "r")) { Buf.resize(0); const size_t Chunk = Buf.capacity_in_bytes(); while (true) { const size_t Len = Buf.size(); Buf.resize(Len + Chunk); const size_t R = ::fread(&Buf[Len], sizeof(char), Chunk, PF); if (R < Chunk) { Buf.resize(Len + R); break; } } ::pclose(PF); return !Buf.empty(); } return false; }
DeclContext::lookup_result ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name, llvm::SmallVectorImpl<NamedDecl*> &Decls) { ASTContext &Context = DC->getParentASTContext();; StoredDeclsMap *Map; if (!(Map = DC->LookupPtr)) Map = DC->CreateStoredDeclsMap(Context); StoredDeclsList &List = (*Map)[Name]; for (unsigned I = 0, N = Decls.size(); I != N; ++I) { if (List.isNull()) List.setOnlyValue(Decls[I]); else List.AddSubsequentDecl(Decls[I]); } return List.getLookupResult(Context); }
/// Parse an identifier in an MS-style inline assembly block. /// /// \param CastInfo - a void* so that we don't have to teach Parser.h /// about the actual type. ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks, unsigned &NumLineToksConsumed, void *CastInfo, bool IsUnevaluatedContext) { llvm::InlineAsmIdentifierInfo &Info = *(llvm::InlineAsmIdentifierInfo *)CastInfo; // Push a fake token on the end so that we don't overrun the token // stream. We use ';' because it expression-parsing should never // overrun it. const tok::TokenKind EndOfStream = tok::semi; Token EndOfStreamTok; EndOfStreamTok.startToken(); EndOfStreamTok.setKind(EndOfStream); LineToks.push_back(EndOfStreamTok); // Also copy the current token over. LineToks.push_back(Tok); PP.EnterTokenStream(LineToks.begin(), LineToks.size(), /*disable macros*/ true, /*owns tokens*/ false); // Clear the current token and advance to the first token in LineToks. ConsumeAnyToken(); // Parse an optional scope-specifier if we're in C++. CXXScopeSpec SS; if (getLangOpts().CPlusPlus) { ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); } // Require an identifier here. SourceLocation TemplateKWLoc; UnqualifiedId Id; bool Invalid = true; ExprResult Result; if (Tok.is(tok::kw_this)) { Result = ParseCXXThis(); Invalid = false; } else { Invalid = ParseUnqualifiedId(SS, /*EnteringContext=*/false, /*AllowDestructorName=*/false, /*AllowConstructorName=*/false, /*ObjectType=*/ParsedType(), TemplateKWLoc, Id); // Perform the lookup. Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info, IsUnevaluatedContext); } // While the next two tokens are 'period' 'identifier', repeatedly parse it as // a field access. We have to avoid consuming assembler directives that look // like '.' 'else'. while (Result.isUsable() && Tok.is(tok::period)) { Token IdTok = PP.LookAhead(0); if (IdTok.isNot(tok::identifier)) break; ConsumeToken(); // Consume the period. IdentifierInfo *Id = Tok.getIdentifierInfo(); ConsumeToken(); // Consume the identifier. Result = Actions.LookupInlineAsmVarDeclField(Result.get(), Id->getName(), Info, Tok.getLocation()); } // Figure out how many tokens we are into LineToks. unsigned LineIndex = 0; if (Tok.is(EndOfStream)) { LineIndex = LineToks.size() - 2; } else { while (LineToks[LineIndex].getLocation() != Tok.getLocation()) { LineIndex++; assert(LineIndex < LineToks.size() - 2); // we added two extra tokens } } // If we've run into the poison token we inserted before, or there // was a parsing error, then claim the entire line. if (Invalid || Tok.is(EndOfStream)) { NumLineToksConsumed = LineToks.size() - 2; } else { // Otherwise, claim up to the start of the next token. NumLineToksConsumed = LineIndex; } // Finally, restore the old parsing state by consuming all the tokens we // staged before, implicitly killing off the token-lexer we pushed. for (unsigned i = 0, e = LineToks.size() - LineIndex - 2; i != e; ++i) { ConsumeAnyToken(); } assert(Tok.is(EndOfStream)); ConsumeToken(); // Leave LineToks in its original state. LineToks.pop_back(); LineToks.pop_back(); return Result; }
void DeclExtractor::EnforceInitOrder(llvm::SmallVectorImpl<Stmt*>& Stmts){ Scope* TUScope = m_Sema->TUScope; DeclContext* TUDC = static_cast<DeclContext*>(TUScope->getEntity()); // We can't PushDeclContext, because we don't have scope. Sema::ContextRAII pushedDC(*m_Sema, TUDC); std::string FunctionName = "__fd"; createUniqueName(FunctionName); IdentifierInfo& IIFD = m_Context->Idents.get(FunctionName); SourceLocation Loc; NamedDecl* ND = m_Sema->ImplicitlyDefineFunction(Loc, IIFD, TUScope); if (FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(ND)) { FD->setImplicit(false); // Better for debugging // Add a return statement if it doesn't exist if (!isa<ReturnStmt>(Stmts.back())) { Sema::ContextRAII pushedDC(*m_Sema, FD); // Generate the return statement: // First a literal 0, then the return taking that literal. // One bit is enough: llvm::APInt ZeroInt(m_Context->getIntWidth(m_Context->IntTy), 0, /*isSigned=*/true); IntegerLiteral* ZeroLit = IntegerLiteral::Create(*m_Context, ZeroInt, m_Context->IntTy, SourceLocation()); Stmts.push_back(m_Sema->ActOnReturnStmt(ZeroLit->getExprLoc(), ZeroLit).take()); } // Wrap Stmts into a function body. llvm::ArrayRef<Stmt*> StmtsRef(Stmts.data(), Stmts.size()); CompoundStmt* CS = new (*m_Context)CompoundStmt(*m_Context, StmtsRef, Loc, Loc); FD->setBody(CS); // We know the transaction is closed, but it is safe. getTransaction()->forceAppend(FD); // Create the VarDecl with the init std::string VarName = "__vd"; createUniqueName(VarName); IdentifierInfo& IIVD = m_Context->Idents.get(VarName); VarDecl* VD = VarDecl::Create(*m_Context, TUDC, Loc, Loc, &IIVD, FD->getReturnType(), (TypeSourceInfo*)0, SC_None); LookupResult R(*m_Sema, FD->getDeclName(), Loc, Sema::LookupMemberName); R.addDecl(FD); CXXScopeSpec CSS; Expr* UnresolvedLookup = m_Sema->BuildDeclarationNameExpr(CSS, R, /*ADL*/ false).take(); Expr* TheCall = m_Sema->ActOnCallExpr(TUScope, UnresolvedLookup, Loc, MultiExprArg(), Loc).take(); assert(VD && TheCall && "Missing VD or its init!"); VD->setInit(TheCall); // We know the transaction is closed, but it is safe. getTransaction()->forceAppend(VD); // Add it to the transaction for codegenning TUDC->addHiddenDecl(VD); Stmts.clear(); return; } llvm_unreachable("Must be able to enforce init order."); }
// ParseArguments - static void ParseArguments(llvm::SmallVectorImpl<const char*> &ArgVector, llvm::SmallVectorImpl<const char*> &Inputs, RSCCOptions &Opts, clang::DiagnosticsEngine &DiagEngine) { if (ArgVector.size() > 1) { const char **ArgBegin = ArgVector.data() + 1; const char **ArgEnd = ArgVector.data() + ArgVector.size(); unsigned MissingArgIndex, MissingArgCount; llvm::OwningPtr<OptTable> OptParser(createRSCCOptTable()); llvm::OwningPtr<InputArgList> Args( OptParser->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount)); // Check for missing argument error. if (MissingArgCount) DiagEngine.Report(clang::diag::err_drv_missing_argument) << Args->getArgString(MissingArgIndex) << MissingArgCount; clang::DiagnosticOptions DiagOpts; DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w); DiagOpts.Warnings = Args->getAllArgValues(OPT_W); clang::ProcessWarningOptions(DiagEngine, DiagOpts); // Issue errors on unknown arguments. for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN), ie = Args->filtered_end(); it != ie; ++it) DiagEngine.Report(clang::diag::err_drv_unknown_argument) << (*it)->getAsString(*Args); for (ArgList::const_iterator it = Args->begin(), ie = Args->end(); it != ie; ++it) { const Arg *A = *it; if (A->getOption().getKind() == Option::InputClass) Inputs.push_back(A->getValue(*Args)); } Opts.mIncludePaths = Args->getAllArgValues(OPT_I); Opts.mOutputDir = Args->getLastArgValue(OPT_o); if (const Arg *A = Args->getLastArg(OPT_M_Group)) { switch (A->getOption().getID()) { case OPT_M: { Opts.mOutputDep = 1; Opts.mOutputType = slang::Slang::OT_Dependency; break; } case OPT_MD: { Opts.mOutputDep = 1; Opts.mOutputType = slang::Slang::OT_Bitcode; break; } default: { slangAssert(false && "Invalid option in M group!"); } } } if (const Arg *A = Args->getLastArg(OPT_Output_Type_Group)) { switch (A->getOption().getID()) { case OPT_emit_asm: { Opts.mOutputType = slang::Slang::OT_Assembly; break; } case OPT_emit_llvm: { Opts.mOutputType = slang::Slang::OT_LLVMAssembly; break; } case OPT_emit_bc: { Opts.mOutputType = slang::Slang::OT_Bitcode; break; } case OPT_emit_nothing: { Opts.mOutputType = slang::Slang::OT_Nothing; break; } default: { slangAssert(false && "Invalid option in output type group!"); } } } if (Opts.mOutputDep && ((Opts.mOutputType != slang::Slang::OT_Bitcode) && (Opts.mOutputType != slang::Slang::OT_Dependency))) DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with) << Args->getLastArg(OPT_M_Group)->getAsString(*Args) << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args); Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix); Opts.mJavaReflectionPathBase = Args->getLastArgValue(OPT_java_reflection_path_base); Opts.mJavaReflectionPackageName = Args->getLastArgValue(OPT_java_reflection_package_name); Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name); llvm::StringRef BitcodeStorageValue = Args->getLastArgValue(OPT_bitcode_storage); if (BitcodeStorageValue == "ar") Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE; else if (BitcodeStorageValue == "jc") Opts.mBitcodeStorage = slang::BCST_JAVA_CODE; else if (!BitcodeStorageValue.empty()) DiagEngine.Report(clang::diag::err_drv_invalid_value) << OptParser->getOptionName(OPT_bitcode_storage) << BitcodeStorageValue; if (Args->hasArg(OPT_reflect_cpp)) { Opts.mBitcodeStorage = slang::BCST_CPP_CODE; } Opts.mOutputDepDir = Args->getLastArgValue(OPT_output_dep_dir, Opts.mOutputDir); Opts.mAdditionalDepTargets = Args->getAllArgValues(OPT_additional_dep_target); Opts.mShowHelp = Args->hasArg(OPT_help); Opts.mShowVersion = Args->hasArg(OPT_version); Opts.mDebugEmission = Args->hasArg(OPT_emit_g); size_t OptLevel = Args->getLastArgIntValue(OPT_optimization_level, 3, DiagEngine); Opts.mOptimizationLevel = OptLevel == 0 ? llvm::CodeGenOpt::None : llvm::CodeGenOpt::Aggressive; Opts.mTargetAPI = Args->getLastArgIntValue(OPT_target_api, RS_VERSION, DiagEngine); } return; }
void IrAggr::addFieldInitializers( llvm::SmallVectorImpl<llvm::Constant *> &constants, const VarInitMap &explicitInitializers, AggregateDeclaration *decl, unsigned &offset, bool populateInterfacesWithVtbls) { if (ClassDeclaration *cd = decl->isClassDeclaration()) { if (cd->baseClass) { addFieldInitializers(constants, explicitInitializers, cd->baseClass, offset, populateInterfacesWithVtbls); } // has interface vtbls? if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0) { // Align interface infos to pointer size. unsigned aligned = (offset + Target::ptrsize - 1) & ~(Target::ptrsize - 1); if (offset < aligned) { add_zeros(constants, offset, aligned); offset = aligned; } // false when it's not okay to use functions from super classes bool newinsts = (cd == aggrdecl->isClassDeclaration()); size_t inter_idx = interfacesWithVtbls.size(); for (auto bc : *cd->vtblInterfaces) { constants.push_back(getInterfaceVtbl(bc, newinsts, inter_idx)); offset += Target::ptrsize; inter_idx++; if (populateInterfacesWithVtbls) interfacesWithVtbls.push_back(bc); } } } AggrTypeBuilder b(false, offset); b.addAggregate(decl, &explicitInitializers, AggrTypeBuilder::Aliases::Skip); offset = b.currentOffset(); const size_t baseLLFieldIndex = constants.size(); const size_t numNewLLFields = b.defaultTypes().size(); constants.resize(constants.size() + numNewLLFields, nullptr); // add explicit and non-overlapping implicit initializers for (const auto &pair : b.varGEPIndices()) { const auto field = pair.first; const size_t fieldIndex = pair.second; const auto explicitIt = explicitInitializers.find(field); llvm::Constant *init = (explicitIt != explicitInitializers.end() ? explicitIt->second : getDefaultInitializer(field)); constants[baseLLFieldIndex + fieldIndex] = FillSArrayDims(field->type, init); } // zero out remaining padding fields for (size_t i = 0; i < numNewLLFields; i++) { auto &init = constants[baseLLFieldIndex + i]; if (!init) init = llvm::Constant::getNullValue(b.defaultTypes()[i]); } }
/// \brief Print the given string to a stream, word-wrapping it to /// some number of columns in the process. /// /// \brief OS the stream to which the word-wrapping string will be /// emitted. /// /// \brief Str the string to word-wrap and output. /// /// \brief Columns the number of columns to word-wrap to. /// /// \brief Column the column number at which the first character of \p /// Str will be printed. This will be non-zero when part of the first /// line has already been printed. /// /// \brief Indentation the number of spaces to indent any lines beyond /// the first line. /// /// \returns true if word-wrapping was required, or false if the /// string fit on the first line. static bool PrintWordWrapped(llvm::raw_ostream &OS, const llvm::SmallVectorImpl<char> &Str, unsigned Columns, unsigned Column = 0, unsigned Indentation = WordWrapIndentation) { unsigned Length = Str.size(); // If there is a newline in this message somewhere, find that // newline and split the message into the part before the newline // (which will be word-wrapped) and the part from the newline one // (which will be emitted unchanged). for (unsigned I = 0; I != Length; ++I) if (Str[I] == '\n') { Length = I; break; } // The string used to indent each line. llvm::SmallString<16> IndentStr; IndentStr.assign(Indentation, ' '); bool Wrapped = false; for (unsigned WordStart = 0, WordEnd; WordStart < Length; WordStart = WordEnd) { // Find the beginning of the next word. WordStart = skipWhitespace(WordStart, Str, Length); if (WordStart == Length) break; // Find the end of this word. WordEnd = findEndOfWord(WordStart, Str, Length, Column, Columns); // Does this word fit on the current line? unsigned WordLength = WordEnd - WordStart; if (Column + WordLength < Columns) { // This word fits on the current line; print it there. if (WordStart) { OS << ' '; Column += 1; } OS.write(&Str[WordStart], WordLength); Column += WordLength; continue; } // This word does not fit on the current line, so wrap to the next // line. OS << '\n'; OS.write(&IndentStr[0], Indentation); OS.write(&Str[WordStart], WordLength); Column = Indentation + WordLength; Wrapped = true; } if (Length == Str.size()) return Wrapped; // We're done. // There is a newline in the message, followed by something that // will not be word-wrapped. Print that. OS.write(&Str[Length], Str.size() - Length); 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(llvm::raw_ostream &OS, llvm::SmallVectorImpl<const char*> &Args, llvm::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('/') != llvm::StringRef::npos) { llvm::StringRef MatchPattern = Edit.substr(2).split('/').first; llvm::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"; } }