diff options
Diffstat (limited to 'clang/lib/Frontend')
25 files changed, 1049 insertions, 566 deletions
diff --git a/clang/lib/Frontend/ASTConsumers.cpp b/clang/lib/Frontend/ASTConsumers.cpp index 043b2541b8f8..a73cc8876d5d 100644 --- a/clang/lib/Frontend/ASTConsumers.cpp +++ b/clang/lib/Frontend/ASTConsumers.cpp @@ -36,10 +36,10 @@ namespace { enum Kind { DumpFull, Dump, Print, None }; ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K, ASTDumpOutputFormat Format, StringRef FilterString, - bool DumpLookups = false) + bool DumpLookups = false, bool DumpDeclTypes = false) : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)), OutputKind(K), OutputFormat(Format), FilterString(FilterString), - DumpLookups(DumpLookups) {} + DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {} void HandleTranslationUnit(ASTContext &Context) override { TranslationUnitDecl *D = Context.getTranslationUnitDecl(); @@ -91,8 +91,22 @@ namespace { } else if (OutputKind == Print) { PrintingPolicy Policy(D->getASTContext().getLangOpts()); D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true); - } else if (OutputKind != None) + } else if (OutputKind != None) { D->dump(Out, OutputKind == DumpFull, OutputFormat); + } + + if (DumpDeclTypes) { + Decl *InnerD = D; + if (auto *TD = dyn_cast<TemplateDecl>(D)) + InnerD = TD->getTemplatedDecl(); + + // FIXME: Support OutputFormat in type dumping. + // FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups. + if (auto *VD = dyn_cast<ValueDecl>(InnerD)) + VD->getType().dump(Out, VD->getASTContext()); + if (auto *TD = dyn_cast<TypeDecl>(InnerD)) + TD->getTypeForDecl()->dump(Out, TD->getASTContext()); + } } raw_ostream &Out; @@ -111,6 +125,9 @@ namespace { /// results will be output with a format determined by OutputKind. This is /// incompatible with OutputKind == Print. bool DumpLookups; + + /// Whether to dump the type for each declaration dumped. + bool DumpDeclTypes; }; class ASTDeclNodeLister : public ASTConsumer, @@ -146,13 +163,13 @@ clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out, std::unique_ptr<ASTConsumer> clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups, - ASTDumpOutputFormat Format) { + bool DumpDeclTypes, ASTDumpOutputFormat Format) { assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump"); - return std::make_unique<ASTPrinter>(std::move(Out), - Deserialize ? ASTPrinter::DumpFull : - DumpDecls ? ASTPrinter::Dump : - ASTPrinter::None, Format, - FilterString, DumpLookups); + return std::make_unique<ASTPrinter>( + std::move(Out), + Deserialize ? ASTPrinter::DumpFull + : DumpDecls ? ASTPrinter::Dump : ASTPrinter::None, + Format, FilterString, DumpLookups, DumpDeclTypes); } std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() { diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index b3264952ff47..57d025b7c32e 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -224,7 +224,7 @@ struct ASTUnit::ASTWriterData { }; void ASTUnit::clearFileLevelDecls() { - llvm::DeleteContainerSeconds(FileDecls); + FileDecls.clear(); } /// After failing to build a precompiled preamble (due to @@ -784,7 +784,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( UserFilesAreVolatile); AST->ModuleCache = new InMemoryModuleCache; AST->HSOpts = std::make_shared<HeaderSearchOptions>(); - AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat(); + AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormat()); AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts, AST->getSourceManager(), AST->getDiagnostics(), @@ -847,7 +847,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( return nullptr; } - AST->OriginalSourceFile = AST->Reader->getOriginalSourceFile(); + AST->OriginalSourceFile = std::string(AST->Reader->getOriginalSourceFile()); PP.setCounterValue(Counter); @@ -1131,7 +1131,8 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, CICleanup(Clang.get()); Clang->setInvocation(CCInvocation); - OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile(); + OriginalSourceFile = + std::string(Clang->getFrontendOpts().Inputs[0].getFile()); // Set up diagnostics, capturing any diagnostics that would // otherwise be dropped. @@ -1260,13 +1261,13 @@ makeStandaloneDiagnostic(const LangOptions &LangOpts, ASTUnit::StandaloneDiagnostic OutDiag; OutDiag.ID = InDiag.getID(); OutDiag.Level = InDiag.getLevel(); - OutDiag.Message = InDiag.getMessage(); + OutDiag.Message = std::string(InDiag.getMessage()); OutDiag.LocOffset = 0; if (InDiag.getLocation().isInvalid()) return OutDiag; const SourceManager &SM = InDiag.getLocation().getManager(); SourceLocation FileLoc = SM.getFileLoc(InDiag.getLocation()); - OutDiag.Filename = SM.getFilename(FileLoc); + OutDiag.Filename = std::string(SM.getFilename(FileLoc)); if (OutDiag.Filename.empty()) return OutDiag; OutDiag.LocOffset = SM.getFileOffset(FileLoc); @@ -1532,7 +1533,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( if (!ResourceFilesPath.empty()) { // Override the resources path. - CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; + CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath); } AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; @@ -1564,7 +1565,8 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( CICleanup(Clang.get()); Clang->setInvocation(std::move(CI)); - AST->OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile(); + AST->OriginalSourceFile = + std::string(Clang->getFrontendOpts().Inputs[0].getFile()); // Set up diagnostics, capturing any diagnostics that would // otherwise be dropped. @@ -1767,13 +1769,14 @@ ASTUnit *ASTUnit::LoadFromCommandLine( PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks; // Override the resources path. - CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; + CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath); CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies == SkipFunctionBodiesScope::PreambleAndMainFile; if (ModuleFormat) - CI->getHeaderSearchOpts().ModuleFormat = ModuleFormat.getValue(); + CI->getHeaderSearchOpts().ModuleFormat = + std::string(ModuleFormat.getValue()); // Create the AST unit. std::unique_ptr<ASTUnit> AST; @@ -2165,7 +2168,7 @@ void ASTUnit::CodeComplete( assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion); - FrontendOpts.CodeCompletionAt.FileName = File; + FrontendOpts.CodeCompletionAt.FileName = std::string(File); FrontendOpts.CodeCompletionAt.Line = Line; FrontendOpts.CodeCompletionAt.Column = Column; @@ -2185,7 +2188,8 @@ void ASTUnit::CodeComplete( auto &Inv = *CCInvocation; Clang->setInvocation(std::move(CCInvocation)); - OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile(); + OriginalSourceFile = + std::string(Clang->getFrontendOpts().Inputs[0].getFile()); // Set up diagnostics, capturing any diagnostics produced. Clang->setDiagnostics(&Diag); @@ -2432,9 +2436,9 @@ void ASTUnit::addFileLevelDecl(Decl *D) { if (FID.isInvalid()) return; - LocDeclsTy *&Decls = FileDecls[FID]; + std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID]; if (!Decls) - Decls = new LocDeclsTy(); + Decls = std::make_unique<LocDeclsTy>(); std::pair<unsigned, Decl *> LocDecl(Offset, D); diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp index dec281529b9e..1486adf70c3f 100644 --- a/clang/lib/Frontend/ChainedIncludesSource.cpp +++ b/clang/lib/Frontend/ChainedIncludesSource.cpp @@ -189,7 +189,7 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( Clang->getASTConsumer().GetASTDeserializationListener()); if (!Reader) return nullptr; - Clang->setModuleManager(Reader); + Clang->setASTReader(Reader); Clang->getASTContext().setExternalSource(Reader); } diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 688f21dd0908..4613ed8d7f61 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -97,6 +97,10 @@ void CompilerInstance::setVerboseOutputStream(std::unique_ptr<raw_ostream> Value void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; } void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; } +llvm::vfs::FileSystem &CompilerInstance::getVirtualFileSystem() const { + return getFileManager().getVirtualFileSystem(); +} + void CompilerInstance::setFileManager(FileManager *Value) { FileMgr = Value; } @@ -138,7 +142,7 @@ std::unique_ptr<Sema> CompilerInstance::takeSema() { IntrusiveRefCntPtr<ASTReader> CompilerInstance::getASTReader() const { return TheASTReader; } -void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { +void CompilerInstance::setASTReader(IntrusiveRefCntPtr<ASTReader> Reader) { assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() && "Expected ASTReader to use the same PCM cache"); TheASTReader = std::move(Reader); @@ -379,7 +383,7 @@ static void InitializeFileRemapping(DiagnosticsEngine &Diags, void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { const PreprocessorOptions &PPOpts = getPreprocessorOpts(); - // The module manager holds a reference to the old preprocessor (if any). + // The AST reader holds a reference to the old preprocessor (if any). TheASTReader.reset(); // Create the Preprocessor. @@ -474,7 +478,7 @@ std::string CompilerInstance::getSpecificModuleCachePath() { if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash) llvm::sys::path::append(SpecificModuleCache, getInvocation().getModuleHash()); - return SpecificModuleCache.str(); + return std::string(SpecificModuleCache.str()); } // ASTContext @@ -713,13 +717,13 @@ std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile( std::string OutFile, TempFile; if (!OutputPath.empty()) { - OutFile = OutputPath; + OutFile = std::string(OutputPath); } else if (InFile == "-") { OutFile = "-"; } else if (!Extension.empty()) { SmallString<128> Path(InFile); llvm::sys::path::replace_extension(Path, Extension); - OutFile = Path.str(); + OutFile = std::string(Path.str()); } else { OutFile = "-"; } @@ -774,7 +778,7 @@ std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile( if (!EC) { OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); - OSFile = TempFile = TempPath.str(); + OSFile = TempFile = std::string(TempPath.str()); } // If we failed to create the temporary, fallback to writing to the file // directly. This handles the corner case where we cannot write to the @@ -811,17 +815,15 @@ std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile( // Initialization Utilities bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ - return InitializeSourceManager( - Input, getDiagnostics(), getFileManager(), getSourceManager(), - hasPreprocessor() ? &getPreprocessor().getHeaderSearchInfo() : nullptr, - getDependencyOutputOpts(), getFrontendOpts()); + return InitializeSourceManager(Input, getDiagnostics(), getFileManager(), + getSourceManager()); } // static -bool CompilerInstance::InitializeSourceManager( - const FrontendInputFile &Input, DiagnosticsEngine &Diags, - FileManager &FileMgr, SourceManager &SourceMgr, HeaderSearch *HS, - DependencyOutputOptions &DepOpts, const FrontendOptions &Opts) { +bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, + DiagnosticsEngine &Diags, + FileManager &FileMgr, + SourceManager &SourceMgr) { SrcMgr::CharacteristicKind Kind = Input.getKind().getFormat() == InputKind::ModuleMap ? Input.isSystem() ? SrcMgr::C_System_ModuleMap @@ -923,10 +925,27 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { !getFrontendOpts().AuxTriple.empty()) { auto TO = std::make_shared<TargetOptions>(); TO->Triple = llvm::Triple::normalize(getFrontendOpts().AuxTriple); + if (getFrontendOpts().AuxTargetCPU) + TO->CPU = getFrontendOpts().AuxTargetCPU.getValue(); + if (getFrontendOpts().AuxTargetFeatures) + TO->FeaturesAsWritten = getFrontendOpts().AuxTargetFeatures.getValue(); TO->HostTriple = getTarget().getTriple().str(); setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO)); } + if (!getTarget().hasStrictFP() && !getLangOpts().ExpStrictFP) { + if (getLangOpts().getFPRoundingMode() != + llvm::RoundingMode::NearestTiesToEven) { + getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_rounding); + getLangOpts().setFPRoundingMode(llvm::RoundingMode::NearestTiesToEven); + } + if (getLangOpts().getFPExceptionMode() != LangOptions::FPE_Ignore) { + getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_exceptions); + getLangOpts().setFPExceptionMode(LangOptions::FPE_Ignore); + } + // FIXME: can we disable FEnvAccess? + } + // Inform the target of the language options. // // FIXME: We shouldn't need to do this, the target should be immutable once @@ -1073,7 +1092,7 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, ImportingInstance.getInvocation().getLangOpts()->ModuleName; // Note the name of the module we're building. - Invocation->getLangOpts()->CurrentModule = ModuleName; + Invocation->getLangOpts()->CurrentModule = std::string(ModuleName); // Make sure that the failed-module structure has been allocated in // the importing instance, and propagate the pointer to the newly-created @@ -1093,7 +1112,7 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, FrontendOpts.DisableFree = false; FrontendOpts.GenerateGlobalModuleIndex = false; FrontendOpts.BuildingImplicitModule = true; - FrontendOpts.OriginalModuleMap = OriginalModuleMapFile; + FrontendOpts.OriginalModuleMap = std::string(OriginalModuleMapFile); // Force implicitly-built modules to hash the content of the module file. HSOpts.ModulesHashContent = true; FrontendOpts.Inputs = {Input}; @@ -1568,7 +1587,7 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { Stack.push_back(M); while (!Stack.empty()) { Module *Current = Stack.pop_back_val(); - if (Current->IsMissingRequirement) continue; + if (Current->IsUnimportable) continue; Current->IsAvailable = true; Stack.insert(Stack.end(), Current->submodule_begin(), Current->submodule_end()); @@ -1630,10 +1649,10 @@ enum ModuleSource { /// Select a source for loading the named module and compute the filename to /// load it from. -static ModuleSource -selectModuleSource(Module *M, StringRef ModuleName, std::string &ModuleFilename, - const std::map<std::string, std::string> &BuiltModules, - HeaderSearch &HS) { +static ModuleSource selectModuleSource( + Module *M, StringRef ModuleName, std::string &ModuleFilename, + const std::map<std::string, std::string, std::less<>> &BuiltModules, + HeaderSearch &HS) { assert(ModuleFilename.empty() && "Already has a module source?"); // Check to see if the module has been built as part of this compilation @@ -2077,7 +2096,7 @@ void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc, // Build the module, inheriting any modules that we've built locally. if (compileModuleImpl(*this, ImportLoc, ModuleName, Input, StringRef(), ModuleFileName, PreBuildStep, PostBuildStep)) { - BuiltModules[ModuleName] = ModuleFileName.str(); + BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName.str()); llvm::sys::RemoveFileOnSignal(ModuleFileName); } } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index e1e59565083b..75d7cf5d26d3 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -41,11 +41,13 @@ #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang/Sema/CodeCompleteOptions.h" +#include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ModuleFileExtension.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/CachedHashString.h" +#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" @@ -116,6 +118,62 @@ CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X) CompilerInvocationBase::~CompilerInvocationBase() = default; //===----------------------------------------------------------------------===// +// Normalizers +//===----------------------------------------------------------------------===// + +#define SIMPLE_ENUM_VALUE_TABLE +#include "clang/Driver/Options.inc" +#undef SIMPLE_ENUM_VALUE_TABLE + +static llvm::Optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt, + unsigned TableIndex, + const ArgList &Args, + DiagnosticsEngine &Diags) { + assert(TableIndex < SimpleEnumValueTablesSize); + const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; + + auto *Arg = Args.getLastArg(Opt); + if (!Arg) + return None; + + StringRef ArgValue = Arg->getValue(); + for (int I = 0, E = Table.Size; I != E; ++I) + if (ArgValue == Table.Table[I].Name) + return Table.Table[I].Value; + + Diags.Report(diag::err_drv_invalid_value) + << Arg->getAsString(Args) << ArgValue; + return None; +} + +static const char *denormalizeSimpleEnum(CompilerInvocation::StringAllocator SA, + unsigned TableIndex, unsigned Value) { + assert(TableIndex < SimpleEnumValueTablesSize); + const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; + for (int I = 0, E = Table.Size; I != E; ++I) + if (Value == Table.Table[I].Value) + return Table.Table[I].Name; + + llvm_unreachable("The simple enum value was not correctly defined in " + "the tablegen option description"); +} + +static const char *denormalizeString(CompilerInvocation::StringAllocator SA, + unsigned TableIndex, + const std::string &Value) { + return SA(Value); +} + +static Optional<std::string> normalizeTriple(OptSpecifier Opt, int TableIndex, + const ArgList &Args, + DiagnosticsEngine &Diags) { + auto *Arg = Args.getLastArg(Opt); + if (!Arg) + return None; + return llvm::Triple::normalize(Arg->getValue()); +} + +//===----------------------------------------------------------------------===// // Deserialization (from args) //===----------------------------------------------------------------------===// @@ -135,7 +193,7 @@ static unsigned getOptimizationLevel(ArgList &Args, InputKind IK, assert(A->getOption().matches(options::OPT_O)); StringRef S(A->getValue()); - if (S == "s" || S == "z" || S.empty()) + if (S == "s" || S == "z") return llvm::CodeGenOpt::Default; if (S == "g") @@ -170,10 +228,12 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, if (A->getOption().getKind() == Option::FlagClass) { // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add // its name (minus the "W" or "R" at the beginning) to the warning list. - Diagnostics.push_back(A->getOption().getName().drop_front(1)); + Diagnostics.push_back( + std::string(A->getOption().getName().drop_front(1))); } else if (A->getOption().matches(GroupWithValue)) { // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic group. - Diagnostics.push_back(A->getOption().getName().drop_front(1).rtrim("=-")); + Diagnostics.push_back( + std::string(A->getOption().getName().drop_front(1).rtrim("=-"))); } else { // Otherwise, add its value (for OPT_W_Joined and similar). for (const auto *Arg : A->getValues()) @@ -307,14 +367,16 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, Opts.visualizeExplodedGraphWithGraphViz = Args.hasArg(OPT_analyzer_viz_egraph_graphviz); - Opts.DumpExplodedGraphTo = Args.getLastArgValue(OPT_analyzer_dump_egraph); + Opts.DumpExplodedGraphTo = + std::string(Args.getLastArgValue(OPT_analyzer_dump_egraph)); Opts.NoRetryExhausted = Args.hasArg(OPT_analyzer_disable_retry_exhausted); Opts.AnalyzerWerror = Args.hasArg(OPT_analyzer_werror); Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers); Opts.AnalyzerDisplayProgress = Args.hasArg(OPT_analyzer_display_progress); Opts.AnalyzeNestedBlocks = Args.hasArg(OPT_analyzer_opt_analyze_nested_blocks); - Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function); + Opts.AnalyzeSpecificFunction = + std::string(Args.getLastArgValue(OPT_analyze_function)); Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG); Opts.TrimGraph = Args.hasArg(OPT_trim_egraph); Opts.maxBlockVisitOnPath = @@ -335,7 +397,8 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, SmallVector<StringRef, 16> CheckersAndPackages; CheckerAndPackageList.split(CheckersAndPackages, ","); for (const StringRef &CheckerOrPackage : CheckersAndPackages) - Opts.CheckersAndPackages.emplace_back(CheckerOrPackage, IsEnabled); + Opts.CheckersAndPackages.emplace_back(std::string(CheckerOrPackage), + IsEnabled); } // Go through the analyzer configuration options. @@ -372,7 +435,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, } A->claim(); - Opts.Config[key] = val; + Opts.Config[key] = std::string(val); } } @@ -394,7 +457,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config, StringRef OptionName, StringRef DefaultVal) { - return Config.insert({OptionName, DefaultVal}).first->second; + return Config.insert({OptionName, std::string(DefaultVal)}).first->second; } static void initOption(AnalyzerOptions::ConfigTable &Config, @@ -521,36 +584,6 @@ static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) { Opts.ParseAllComments = Args.hasArg(OPT_fparse_all_comments); } -static StringRef getCodeModel(ArgList &Args, DiagnosticsEngine &Diags) { - if (Arg *A = Args.getLastArg(OPT_mcode_model)) { - StringRef Value = A->getValue(); - if (Value == "small" || Value == "kernel" || Value == "medium" || - Value == "large" || Value == "tiny") - return Value; - Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value; - } - return "default"; -} - -static llvm::Reloc::Model getRelocModel(ArgList &Args, - DiagnosticsEngine &Diags) { - if (Arg *A = Args.getLastArg(OPT_mrelocation_model)) { - StringRef Value = A->getValue(); - auto RM = llvm::StringSwitch<llvm::Optional<llvm::Reloc::Model>>(Value) - .Case("static", llvm::Reloc::Static) - .Case("pic", llvm::Reloc::PIC_) - .Case("ropi", llvm::Reloc::ROPI) - .Case("rwpi", llvm::Reloc::RWPI) - .Case("ropi-rwpi", llvm::Reloc::ROPI_RWPI) - .Case("dynamic-no-pic", llvm::Reloc::DynamicNoPIC) - .Default(None); - if (RM.hasValue()) - return *RM; - Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value; - } - return llvm::Reloc::PIC_; -} - /// Create a new Regex instance out of the string value in \p RpassArg. /// It returns a pointer to the newly generated Regex instance. static std::shared_ptr<llvm::Regex> @@ -754,7 +787,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.setDebuggerTuning(static_cast<llvm::DebuggerKind>(Val)); } Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 0, Diags); - Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info); + Opts.DebugColumnInfo = !Args.hasArg(OPT_gno_column_info); Opts.EmitCodeView = Args.hasArg(OPT_gcodeview); Opts.CodeViewGHash = Args.hasArg(OPT_gcodeview_ghash); Opts.MacroDebugInfo = Args.hasArg(OPT_debug_info_macro); @@ -762,19 +795,21 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.VirtualFunctionElimination = Args.hasArg(OPT_fvirtual_function_elimination); Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std); - Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file); - Opts.SplitDwarfOutput = Args.getLastArgValue(OPT_split_dwarf_output); + Opts.SplitDwarfFile = std::string(Args.getLastArgValue(OPT_split_dwarf_file)); + Opts.SplitDwarfOutput = + std::string(Args.getLastArgValue(OPT_split_dwarf_output)); Opts.SplitDwarfInlining = !Args.hasArg(OPT_fno_split_dwarf_inlining); Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs); Opts.DebugExplicitImport = Args.hasArg(OPT_dwarf_explicit_import); Opts.DebugFwdTemplateParams = Args.hasArg(OPT_debug_forward_template_params); Opts.EmbedSource = Args.hasArg(OPT_gembed_source); + Opts.ForceDwarfFrameSection = Args.hasArg(OPT_fforce_dwarf_frame); - Opts.ForceDwarfFrameSection = - Args.hasFlag(OPT_fforce_dwarf_frame, OPT_fno_force_dwarf_frame, false); - - for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) - Opts.DebugPrefixMap.insert(StringRef(Arg).split('=')); + for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) { + auto Split = StringRef(Arg).split('='); + Opts.DebugPrefixMap.insert( + {std::string(Split.first), std::string(Split.second)}); + } if (const Arg *A = Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists)) @@ -785,12 +820,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, const llvm::Triple::ArchType DebugEntryValueArchs[] = { llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64, - llvm::Triple::arm, llvm::Triple::armeb}; + llvm::Triple::arm, llvm::Triple::armeb, llvm::Triple::mips, + llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el}; llvm::Triple T(TargetOpts.Triple); if (Opts.OptimizationLevel > 0 && Opts.hasReducedDebugInfo() && llvm::is_contained(DebugEntryValueArchs, T.getArch())) - Opts.EnableDebugEntryValues = Args.hasArg(OPT_femit_debug_entry_values); + Opts.EmitCallSiteInfo = true; Opts.DisableO0ImplyOptNone = Args.hasArg(OPT_disable_O0_optnone); Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone); @@ -805,10 +841,12 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.FineGrainedBitfieldAccesses = Args.hasFlag(OPT_ffine_grained_bitfield_accesses, OPT_fno_fine_grained_bitfield_accesses, false); - Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags); - Opts.RecordCommandLine = Args.getLastArgValue(OPT_record_command_line); + Opts.DwarfDebugFlags = + std::string(Args.getLastArgValue(OPT_dwarf_debug_flags)); + Opts.RecordCommandLine = + std::string(Args.getLastArgValue(OPT_record_command_line)); Opts.MergeAllConstants = Args.hasArg(OPT_fmerge_all_constants); - Opts.NoCommon = Args.hasArg(OPT_fno_common); + Opts.NoCommon = !Args.hasArg(OPT_fcommon); Opts.NoInlineLineTables = Args.hasArg(OPT_gno_inline_line_tables); Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float); Opts.OptimizeSize = getOptimizationLevelSize(Args); @@ -823,7 +861,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.DisableIntegratedAS = Args.hasArg(OPT_fno_integrated_as); Opts.Autolink = !Args.hasArg(OPT_fno_autolink); - Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ); + Opts.SampleProfileFile = + std::string(Args.getLastArgValue(OPT_fprofile_sample_use_EQ)); Opts.DebugInfoForProfiling = Args.hasFlag( OPT_fdebug_info_for_profiling, OPT_fno_debug_info_for_profiling, false); Opts.DebugNameTable = static_cast<unsigned>( @@ -836,13 +875,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, setPGOInstrumentor(Opts, Args, Diags); Opts.InstrProfileOutput = - Args.getLastArgValue(OPT_fprofile_instrument_path_EQ); + std::string(Args.getLastArgValue(OPT_fprofile_instrument_path_EQ)); Opts.ProfileInstrumentUsePath = - Args.getLastArgValue(OPT_fprofile_instrument_use_path_EQ); + std::string(Args.getLastArgValue(OPT_fprofile_instrument_use_path_EQ)); if (!Opts.ProfileInstrumentUsePath.empty()) setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath); Opts.ProfileRemappingFile = - Args.getLastArgValue(OPT_fprofile_remapping_file_EQ); + std::string(Args.getLastArgValue(OPT_fprofile_remapping_file_EQ)); if (!Opts.ProfileRemappingFile.empty() && !Opts.ExperimentalNewPassManager) { Diags.Report(diag::err_drv_argument_only_allowed_with) << Args.getLastArg(OPT_fprofile_remapping_file_EQ)->getAsString(Args) @@ -852,7 +891,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.CoverageMapping = Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false); Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping); - Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose); + Opts.AsmVerbose = !Args.hasArg(OPT_fno_verbose_asm); Opts.PreserveAsmComments = !Args.hasArg(OPT_fno_preserve_as_comments); Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions); @@ -861,7 +900,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_fregister_global_dtors_with_atexit); Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); Opts.CodeModel = TargetOpts.CodeModel; - Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); + Opts.DebugPass = std::string(Args.getLastArgValue(OPT_mdebug_pass)); // Handle -mframe-pointer option. if (Arg *A = Args.getLastArg(OPT_mframe_pointer_EQ)) { @@ -883,49 +922,30 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.setFramePointer(FP); } - // -pg may override -mframe-pointer - // TODO: This should be merged into getFramePointerKind in Clang.cpp. - if (Args.hasArg(OPT_pg)) - Opts.setFramePointer(CodeGenOptions::FramePointerKind::All); - Opts.DisableFree = Args.hasArg(OPT_disable_free); Opts.DiscardValueNames = Args.hasArg(OPT_discard_value_names); Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls); Opts.NoEscapingBlockTailCalls = Args.hasArg(OPT_fno_escaping_block_tail_calls); - Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi); + Opts.FloatABI = std::string(Args.getLastArgValue(OPT_mfloat_abi)); Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable) || Args.hasArg(OPT_cl_unsafe_math_optimizations) || Args.hasArg(OPT_cl_fast_relaxed_math); - Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision); - Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) || - Args.hasArg(OPT_cl_finite_math_only) || - Args.hasArg(OPT_cl_fast_relaxed_math)); - Opts.NoNaNsFPMath = (Args.hasArg(OPT_menable_no_nans) || - Args.hasArg(OPT_cl_unsafe_math_optimizations) || - Args.hasArg(OPT_cl_finite_math_only) || - Args.hasArg(OPT_cl_fast_relaxed_math)); - Opts.NoSignedZeros = (Args.hasArg(OPT_fno_signed_zeros) || - Args.hasArg(OPT_cl_no_signed_zeros) || - Args.hasArg(OPT_cl_unsafe_math_optimizations) || - Args.hasArg(OPT_cl_fast_relaxed_math)); - Opts.Reassociate = Args.hasArg(OPT_mreassociate); - Opts.FlushDenorm = Args.hasArg(OPT_cl_denorms_are_zero) || - (Args.hasArg(OPT_fcuda_is_device) && - Args.hasArg(OPT_fcuda_flush_denormals_to_zero)); + Opts.LimitFloatPrecision = + std::string(Args.getLastArgValue(OPT_mlimit_float_precision)); Opts.CorrectlyRoundedDivSqrt = Args.hasArg(OPT_cl_fp32_correctly_rounded_divide_sqrt); Opts.UniformWGSize = Args.hasArg(OPT_cl_uniform_work_group_size); Opts.Reciprocals = Args.getAllArgValues(OPT_mrecip_EQ); - Opts.ReciprocalMath = Args.hasArg(OPT_freciprocal_math); - Opts.NoTrappingMath = Args.hasArg(OPT_fno_trapping_math); Opts.StrictFloatCastOverflow = !Args.hasArg(OPT_fno_strict_float_cast_overflow); - Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss); + Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_fno_zero_initialized_in_bss); Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags); Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack); + Opts.SmallDataLimit = + getLastArgIntValue(Args, OPT_msmall_data_limit, 0, Diags); Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings); Opts.NoWarn = Args.hasArg(OPT_massembler_no_warn); Opts.EnableSegmentedStacks = Args.hasArg(OPT_split_stacks); @@ -942,27 +962,31 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.StrictReturn = !Args.hasArg(OPT_fno_strict_return); Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers); Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables); - Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) || - Args.hasArg(OPT_cl_unsafe_math_optimizations) || - Args.hasArg(OPT_cl_fast_relaxed_math); Opts.UnwindTables = Args.hasArg(OPT_munwind_tables); - Opts.RelocationModel = getRelocModel(Args, Diags); - Opts.ThreadModel = Args.getLastArgValue(OPT_mthread_model, "posix"); + Opts.ThreadModel = + std::string(Args.getLastArgValue(OPT_mthread_model, "posix")); if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single") Diags.Report(diag::err_drv_invalid_value) << Args.getLastArg(OPT_mthread_model)->getAsString(Args) << Opts.ThreadModel; - Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ); + Opts.TrapFuncName = std::string(Args.getLastArgValue(OPT_ftrap_function_EQ)); Opts.UseInitArray = !Args.hasArg(OPT_fno_use_init_array); - Opts.FunctionSections = Args.hasFlag(OPT_ffunction_sections, - OPT_fno_function_sections, false); - Opts.DataSections = Args.hasFlag(OPT_fdata_sections, - OPT_fno_data_sections, false); - Opts.StackSizeSection = - Args.hasFlag(OPT_fstack_size_section, OPT_fno_stack_size_section, false); - Opts.UniqueSectionNames = Args.hasFlag(OPT_funique_section_names, - OPT_fno_unique_section_names, true); + Opts.BBSections = + std::string(Args.getLastArgValue(OPT_fbasic_block_sections_EQ, "none")); + + // Basic Block Sections implies Function Sections. + Opts.FunctionSections = + Args.hasArg(OPT_ffunction_sections) || + (Opts.BBSections != "none" && Opts.BBSections != "labels"); + + Opts.DataSections = Args.hasArg(OPT_fdata_sections); + Opts.StackSizeSection = Args.hasArg(OPT_fstack_size_section); + Opts.UniqueSectionNames = !Args.hasArg(OPT_fno_unique_section_names); + Opts.UniqueBasicBlockSectionNames = + Args.hasArg(OPT_funique_basic_block_section_names); + Opts.UniqueInternalLinkageNames = + Args.hasArg(OPT_funique_internal_linkage_names); Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions); @@ -987,7 +1011,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, if (IK.getLanguage() != Language::LLVM_IR) Diags.Report(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args) << "-x ir"; - Opts.ThinLTOIndexFile = Args.getLastArgValue(OPT_fthinlto_index_EQ); + Opts.ThinLTOIndexFile = + std::string(Args.getLastArgValue(OPT_fthinlto_index_EQ)); } if (Arg *A = Args.getLastArg(OPT_save_temps_EQ)) Opts.SaveTempsFilePrefix = @@ -995,16 +1020,18 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, .Case("obj", FrontendOpts.OutputFile) .Default(llvm::sys::path::filename(FrontendOpts.OutputFile).str()); - Opts.ThinLinkBitcodeFile = Args.getLastArgValue(OPT_fthin_link_bitcode_EQ); + Opts.ThinLinkBitcodeFile = + std::string(Args.getLastArgValue(OPT_fthin_link_bitcode_EQ)); Opts.MSVolatile = Args.hasArg(OPT_fms_volatile); Opts.VectorizeLoop = Args.hasArg(OPT_vectorize_loops); Opts.VectorizeSLP = Args.hasArg(OPT_vectorize_slp); - Opts.PreferVectorWidth = Args.getLastArgValue(OPT_mprefer_vector_width_EQ); + Opts.PreferVectorWidth = + std::string(Args.getLastArgValue(OPT_mprefer_vector_width_EQ)); - Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name); + Opts.MainFileName = std::string(Args.getLastArgValue(OPT_main_file_name)); Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier); Opts.ControlFlowGuardNoChecks = Args.hasArg(OPT_cfguard_no_checks); @@ -1014,17 +1041,14 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data); Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes); if (Opts.EmitGcovArcs || Opts.EmitGcovNotes) { - Opts.CoverageDataFile = Args.getLastArgValue(OPT_coverage_data_file); - Opts.CoverageNotesFile = Args.getLastArgValue(OPT_coverage_notes_file); - Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum); - Opts.CoverageNoFunctionNamesInData = - Args.hasArg(OPT_coverage_no_function_names_in_data); + Opts.CoverageDataFile = + std::string(Args.getLastArgValue(OPT_coverage_data_file)); + Opts.CoverageNotesFile = + std::string(Args.getLastArgValue(OPT_coverage_notes_file)); Opts.ProfileFilterFiles = - Args.getLastArgValue(OPT_fprofile_filter_files_EQ); + std::string(Args.getLastArgValue(OPT_fprofile_filter_files_EQ)); Opts.ProfileExcludeFiles = - Args.getLastArgValue(OPT_fprofile_exclude_files_EQ); - Opts.CoverageExitBlockBeforeBody = - Args.hasArg(OPT_coverage_exit_block_before_body); + std::string(Args.getLastArgValue(OPT_fprofile_exclude_files_EQ)); if (Args.hasArg(OPT_coverage_version_EQ)) { StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ); if (CoverageVersion.size() != 4) { @@ -1062,8 +1086,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, A->getOption().getID() == options::OPT_INPUT || A->getOption().getID() == options::OPT_x || A->getOption().getID() == options::OPT_fembed_bitcode || - (A->getOption().getGroup().isValid() && - A->getOption().getGroup().getID() == options::OPT_W_Group)) + A->getOption().matches(options::OPT_W_Group)) continue; ArgStringList ASL; A->render(Args, ASL); @@ -1091,6 +1114,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_fxray_always_emit_typedevents); Opts.XRayInstructionThreshold = getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags); + Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops); + Opts.XRayOmitFunctionIndex = Args.hasArg(OPT_fno_xray_function_index); auto XRayInstrBundles = Args.getAllArgValues(OPT_fxray_instrumentation_bundle); @@ -1103,6 +1128,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.PatchableFunctionEntryCount = getLastArgIntValue(Args, OPT_fpatchable_function_entry_EQ, 0, Diags); + Opts.PatchableFunctionEntryOffset = getLastArgIntValue( + Args, OPT_fpatchable_function_entry_offset_EQ, 0, Diags); Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.CallFEntry = Args.hasArg(OPT_mfentry); Opts.MNopMCount = Args.hasArg(OPT_mnop_mcount); @@ -1141,7 +1168,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations); - Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir); + Opts.DebugCompilationDir = + std::string(Args.getLastArgValue(OPT_fdebug_compilation_dir)); for (auto *A : Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) { CodeGenOptions::BitcodeFileToLink F; @@ -1171,9 +1199,15 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.SanitizeCoverageNoPrune = Args.hasArg(OPT_fsanitize_coverage_no_prune); Opts.SanitizeCoverageInline8bitCounters = Args.hasArg(OPT_fsanitize_coverage_inline_8bit_counters); + Opts.SanitizeCoverageInlineBoolFlag = + Args.hasArg(OPT_fsanitize_coverage_inline_bool_flag); Opts.SanitizeCoveragePCTable = Args.hasArg(OPT_fsanitize_coverage_pc_table); Opts.SanitizeCoverageStackDepth = Args.hasArg(OPT_fsanitize_coverage_stack_depth); + Opts.SanitizeCoverageAllowlistFiles = + Args.getAllArgValues(OPT_fsanitize_coverage_allowlist); + Opts.SanitizeCoverageBlocklistFiles = + Args.getAllArgValues(OPT_fsanitize_coverage_blocklist); Opts.SanitizeMemoryTrackOrigins = getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags); Opts.SanitizeMemoryUseAfterDtor = @@ -1225,6 +1259,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.NoStackArgProbe = Args.hasArg(OPT_mno_stack_arg_probe); + Opts.StackClashProtector = Args.hasArg(OPT_fstack_clash_protection); + if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) { StringRef Name = A->getValue(); unsigned Method = llvm::StringSwitch<unsigned>(Name) @@ -1273,15 +1309,35 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) { StringRef Val = A->getValue(); Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val); - if (Opts.FPDenormalMode == llvm::DenormalMode::Invalid) + if (!Opts.FPDenormalMode.isValid()) + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; + } + + if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_f32_EQ)) { + StringRef Val = A->getValue(); + Opts.FP32DenormalMode = llvm::parseDenormalFPAttribute(Val); + if (!Opts.FP32DenormalMode.isValid()) Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } - if (Arg *A = Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return)) { - if (A->getOption().matches(OPT_fpcc_struct_return)) { + // X86_32 has -fppc-struct-return and -freg-struct-return. + // PPC32 has -maix-struct-return and -msvr4-struct-return. + if (Arg *A = + Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return, + OPT_maix_struct_return, OPT_msvr4_struct_return)) { + // TODO: We might want to consider enabling these options on AIX in the + // future. + if (T.isOSAIX()) + Diags.Report(diag::err_drv_unsupported_opt_for_target) + << A->getSpelling() << T.str(); + + const Option &O = A->getOption(); + if (O.matches(OPT_fpcc_struct_return) || + O.matches(OPT_maix_struct_return)) { Opts.setStructReturnConvention(CodeGenOptions::SRCK_OnStack); } else { - assert(A->getOption().matches(OPT_freg_struct_return)); + assert(O.matches(OPT_freg_struct_return) || + O.matches(OPT_msvr4_struct_return)); Opts.setStructReturnConvention(CodeGenOptions::SRCK_InRegs); } } @@ -1290,7 +1346,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.LinkerOptions = Args.getAllArgValues(OPT_linker_option); bool NeedLocTracking = false; - Opts.OptRecordFile = Args.getLastArgValue(OPT_opt_record_file); + Opts.OptRecordFile = std::string(Args.getLastArgValue(OPT_opt_record_file)); if (!Opts.OptRecordFile.empty()) NeedLocTracking = true; @@ -1363,7 +1419,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.SanitizeTrap); Opts.CudaGpuBinaryFileName = - Args.getLastArgValue(OPT_fcuda_include_gpubinary); + std::string(Args.getLastArgValue(OPT_fcuda_include_gpubinary)); Opts.Backchain = Args.hasArg(OPT_mbackchain); @@ -1374,38 +1430,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.Addrsig = Args.hasArg(OPT_faddrsig); - if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) { - StringRef SignScope = A->getValue(); - - if (SignScope.equals_lower("none")) - Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::None); - else if (SignScope.equals_lower("all")) - Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::All); - else if (SignScope.equals_lower("non-leaf")) - Opts.setSignReturnAddress( - CodeGenOptions::SignReturnAddressScope::NonLeaf); - else - Diags.Report(diag::err_drv_invalid_value) - << A->getAsString(Args) << SignScope; - - if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) { - StringRef SignKey = A->getValue(); - if (!SignScope.empty() && !SignKey.empty()) { - if (SignKey.equals_lower("a_key")) - Opts.setSignReturnAddressKey( - CodeGenOptions::SignReturnAddressKeyValue::AKey); - else if (SignKey.equals_lower("b_key")) - Opts.setSignReturnAddressKey( - CodeGenOptions::SignReturnAddressKeyValue::BKey); - else - Diags.Report(diag::err_drv_invalid_value) - << A->getAsString(Args) << SignKey; - } - } - } - - Opts.BranchTargetEnforcement = Args.hasArg(OPT_mbranch_target_enforce); - Opts.KeepStaticConsts = Args.hasArg(OPT_fkeep_static_consts); Opts.SpeculativeLoadHardening = Args.hasArg(OPT_mspeculative_load_hardening); @@ -1414,20 +1438,23 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.PassPlugins = Args.getAllArgValues(OPT_fpass_plugin_EQ); - Opts.SymbolPartition = Args.getLastArgValue(OPT_fsymbol_partition_EQ); + Opts.SymbolPartition = + std::string(Args.getLastArgValue(OPT_fsymbol_partition_EQ)); + Opts.ForceAAPCSBitfieldLoad = Args.hasArg(OPT_ForceAAPCSBitfieldLoad); return Success; } static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, ArgList &Args) { - Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file); + Opts.OutputFile = std::string(Args.getLastArgValue(OPT_dependency_file)); Opts.Targets = Args.getAllArgValues(OPT_MT); Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps); Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps); Opts.UsePhonyTargets = Args.hasArg(OPT_MP); Opts.ShowHeaderIncludes = Args.hasArg(OPT_H); - Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file); + Opts.HeaderIncludeOutputFile = + std::string(Args.getLastArgValue(OPT_header_include_file)); Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG); if (Args.hasArg(OPT_show_includes)) { // Writing both /showIncludes and preprocessor output to stdout @@ -1440,9 +1467,9 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, } else { Opts.ShowIncludesDest = ShowIncludesDestination::None; } - Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot); + Opts.DOTOutputFile = std::string(Args.getLastArgValue(OPT_dependency_dot)); Opts.ModuleDependencyOutputDir = - Args.getLastArgValue(OPT_module_dependency_dir); + std::string(Args.getLastArgValue(OPT_module_dependency_dir)); if (Args.hasArg(OPT_MV)) Opts.OutputFormat = DependencyOutputFormat::NMake; // Add sanitizer blacklists as extra dependencies. @@ -1452,13 +1479,13 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, for (const auto *A : Args.filtered(OPT_fsanitize_blacklist)) { StringRef Val = A->getValue(); if (Val.find('=') == StringRef::npos) - Opts.ExtraDeps.push_back(Val); + Opts.ExtraDeps.push_back(std::string(Val)); } if (Opts.IncludeSystemHeaders) { for (const auto *A : Args.filtered(OPT_fsanitize_system_blacklist)) { StringRef Val = A->getValue(); if (Val.find('=') == StringRef::npos) - Opts.ExtraDeps.push_back(Val); + Opts.ExtraDeps.push_back(std::string(Val)); } } } @@ -1472,7 +1499,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, for (const auto *A : Args.filtered(OPT_fmodule_file)) { StringRef Val = A->getValue(); if (Val.find('=') == StringRef::npos) - Opts.ExtraDeps.push_back(Val); + Opts.ExtraDeps.push_back(std::string(Val)); } } @@ -1531,10 +1558,11 @@ static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes, bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, DiagnosticsEngine *Diags, - bool DefaultDiagColor, bool DefaultShowOpt) { + bool DefaultDiagColor) { bool Success = true; - Opts.DiagnosticLogFile = Args.getLastArgValue(OPT_diagnostic_log_file); + Opts.DiagnosticLogFile = + std::string(Args.getLastArgValue(OPT_diagnostic_log_file)); if (Arg *A = Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags)) Opts.DiagnosticSerializationFile = A->getValue(); @@ -1544,17 +1572,11 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors); Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics); Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor); - Opts.ShowColumn = Args.hasFlag(OPT_fshow_column, - OPT_fno_show_column, - /*Default=*/true); + Opts.ShowColumn = !Args.hasArg(OPT_fno_show_column); Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info); Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location); Opts.AbsolutePath = Args.hasArg(OPT_fdiagnostics_absolute_paths); - Opts.ShowOptionNames = - Args.hasFlag(OPT_fdiagnostics_show_option, - OPT_fno_diagnostics_show_option, DefaultShowOpt); - - llvm::sys::Process::UseANSIEscapeCodes(Args.hasArg(OPT_fansi_escape_codes)); + Opts.ShowOptionNames = !Args.hasArg(OPT_fno_diagnostics_show_option); // Default behavior is to not to show note include stacks. Opts.ShowNoteIncludeStack = false; @@ -1660,7 +1682,11 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Diags->Report(diag::warn_ignoring_ftabstop_value) << Opts.TabStop << DiagnosticOptions::DefaultTabStop; } - Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags); + Opts.MessageLength = + getLastArgIntValue(Args, OPT_fmessage_length_EQ, 0, Diags); + + Opts.UndefPrefixes = Args.getAllArgValues(OPT_Wundef_prefix_EQ); + addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings); addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks); @@ -1668,7 +1694,7 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, } static void ParseFileSystemArgs(FileSystemOptions &Opts, ArgList &Args) { - Opts.WorkingDir = Args.getLastArgValue(OPT_working_directory); + Opts.WorkingDir = std::string(Args.getLastArgValue(OPT_working_directory)); } /// Parse the argument to the -ftest-module-file-extension @@ -1686,12 +1712,12 @@ static bool parseTestModuleFileExtensionArg(StringRef Arg, if (Args.size() < 5) return true; - BlockName = Args[0]; + BlockName = std::string(Args[0]); if (Args[1].getAsInteger(10, MajorVersion)) return true; if (Args[2].getAsInteger(10, MinorVersion)) return true; if (Args[3].getAsInteger(2, Hashed)) return true; if (Args.size() > 4) - UserInfo = Args[4]; + UserInfo = std::string(Args[4]); return false; } @@ -1724,6 +1750,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, case OPT_ast_dump: case OPT_ast_dump_all: case OPT_ast_dump_lookups: + case OPT_ast_dump_decl_types: Opts.ProgramAction = frontend::ASTDump; break; case OPT_ast_print: Opts.ProgramAction = frontend::ASTPrint; break; @@ -1766,25 +1793,26 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, StringRef ArgStr = Args.hasArg(OPT_interface_stub_version_EQ) ? Args.getLastArgValue(OPT_interface_stub_version_EQ) - : "experimental-ifs-v1"; + : "experimental-ifs-v2"; if (ArgStr == "experimental-yaml-elf-v1" || + ArgStr == "experimental-ifs-v1" || ArgStr == "experimental-tapi-elf-v1") { std::string ErrorMessage = "Invalid interface stub format: " + ArgStr.str() + " is deprecated."; Diags.Report(diag::err_drv_invalid_value) << "Must specify a valid interface stub format type, ie: " - "-interface-stub-version=experimental-ifs-v1" + "-interface-stub-version=experimental-ifs-v2" << ErrorMessage; - } else if (ArgStr != "experimental-ifs-v1") { + } else if (!ArgStr.startswith("experimental-ifs-")) { std::string ErrorMessage = "Invalid interface stub format: " + ArgStr.str() + "."; Diags.Report(diag::err_drv_invalid_value) << "Must specify a valid interface stub format type, ie: " - "-interface-stub-version=experimental-ifs-v1" + "-interface-stub-version=experimental-ifs-v2" << ErrorMessage; } else { - Opts.ProgramAction = frontend::GenerateInterfaceIfsExpV1; + Opts.ProgramAction = frontend::GenerateInterfaceStubs; } break; } @@ -1859,7 +1887,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, } Opts.DisableFree = Args.hasArg(OPT_disable_free); - Opts.OutputFile = Args.getLastArgValue(OPT_o); + Opts.OutputFile = std::string(Args.getLastArgValue(OPT_o)); Opts.Plugins = Args.getAllArgValues(OPT_load); Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch); Opts.ShowHelp = Args.hasArg(OPT_help); @@ -1878,8 +1906,9 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp); Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ); Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ); - Opts.ASTDumpFilter = Args.getLastArgValue(OPT_ast_dump_filter); + Opts.ASTDumpFilter = std::string(Args.getLastArgValue(OPT_ast_dump_filter)); Opts.ASTDumpLookups = Args.hasArg(OPT_ast_dump_lookups); + Opts.ASTDumpDeclTypes = Args.hasArg(OPT_ast_dump_decl_types); Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index); Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex; Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file); @@ -1887,12 +1916,17 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, for (const auto *A : Args.filtered(OPT_fmodule_file)) { StringRef Val = A->getValue(); if (Val.find('=') == StringRef::npos) - Opts.ModuleFiles.push_back(Val); + Opts.ModuleFiles.push_back(std::string(Val)); } Opts.ModulesEmbedFiles = Args.getAllArgValues(OPT_fmodules_embed_file_EQ); Opts.ModulesEmbedAllFiles = Args.hasArg(OPT_fmodules_embed_all_files); Opts.IncludeTimestamps = !Args.hasArg(OPT_fno_pch_timestamp); Opts.UseTemporary = !Args.hasArg(OPT_fno_temp_file); + Opts.IsSystemModule = Args.hasArg(OPT_fsystem_module); + + if (Opts.ProgramAction != frontend::GenerateModule && Opts.IsSystemModule) + Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module" + << "-emit-module"; Opts.CodeCompleteOpts.IncludeMacros = Args.hasArg(OPT_code_completion_macros); @@ -1907,10 +1941,14 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.CodeCompleteOpts.IncludeFixIts = Args.hasArg(OPT_code_completion_with_fixits); - Opts.OverrideRecordLayoutsFile - = Args.getLastArgValue(OPT_foverride_record_layout_EQ); - Opts.AuxTriple = Args.getLastArgValue(OPT_aux_triple); - Opts.StatsFile = Args.getLastArgValue(OPT_stats_file); + Opts.OverrideRecordLayoutsFile = + std::string(Args.getLastArgValue(OPT_foverride_record_layout_EQ)); + Opts.AuxTriple = std::string(Args.getLastArgValue(OPT_aux_triple)); + if (Args.hasArg(OPT_aux_target_cpu)) + Opts.AuxTargetCPU = std::string(Args.getLastArgValue(OPT_aux_target_cpu)); + if (Args.hasArg(OPT_aux_target_feature)) + Opts.AuxTargetFeatures = Args.getAllArgValues(OPT_aux_target_feature); + Opts.StatsFile = std::string(Args.getLastArgValue(OPT_stats_file)); if (const Arg *A = Args.getLastArg(OPT_arcmt_check, OPT_arcmt_modify, @@ -1929,9 +1967,10 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, break; } } - Opts.MTMigrateDir = Args.getLastArgValue(OPT_mt_migrate_directory); - Opts.ARCMTMigrateReportOut - = Args.getLastArgValue(OPT_arcmt_migrate_report_output); + Opts.MTMigrateDir = + std::string(Args.getLastArgValue(OPT_mt_migrate_directory)); + Opts.ARCMTMigrateReportOut = + std::string(Args.getLastArgValue(OPT_arcmt_migrate_report_output)); Opts.ARCMTMigrateEmitARCErrors = Args.hasArg(OPT_arcmt_migrate_emit_arc_errors); @@ -1966,7 +2005,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, if (Args.hasArg(OPT_objcmt_migrate_all)) Opts.ObjCMTAction |= FrontendOptions::ObjCMT_MigrateDecls; - Opts.ObjCMTWhiteListPath = Args.getLastArgValue(OPT_objcmt_whitelist_dir_path); + Opts.ObjCMTWhiteListPath = + std::string(Args.getLastArgValue(OPT_objcmt_whitelist_dir_path)); if (Opts.ARCMTAction != FrontendOptions::ARCMT_None && Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) { @@ -2043,12 +2083,16 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, DashX = IK; } + bool IsSystem = false; + // The -emit-module action implicitly takes a module map. if (Opts.ProgramAction == frontend::GenerateModule && - IK.getFormat() == InputKind::Source) + IK.getFormat() == InputKind::Source) { IK = IK.withFormat(InputKind::ModuleMap); + IsSystem = Opts.IsSystemModule; + } - Opts.Inputs.emplace_back(std::move(Inputs[i]), IK); + Opts.Inputs.emplace_back(std::move(Inputs[i]), IK, IsSystem); } return DashX; @@ -2063,14 +2107,14 @@ std::string CompilerInvocation::GetResourcesPath(const char *Argv0, static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, const std::string &WorkingDir) { - Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/"); + Opts.Sysroot = std::string(Args.getLastArgValue(OPT_isysroot, "/")); Opts.Verbose = Args.hasArg(OPT_v); Opts.UseBuiltinIncludes = !Args.hasArg(OPT_nobuiltininc); Opts.UseStandardSystemIncludes = !Args.hasArg(OPT_nostdsysteminc); Opts.UseStandardCXXIncludes = !Args.hasArg(OPT_nostdincxx); if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ)) Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0); - Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir); + Opts.ResourceDir = std::string(Args.getLastArgValue(OPT_resource_dir)); // Canonicalize -fmodules-cache-path before storing it. SmallString<128> P(Args.getLastArgValue(OPT_fmodules_cache_path)); @@ -2081,20 +2125,23 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, llvm::sys::fs::make_absolute(WorkingDir, P); } llvm::sys::path::remove_dots(P); - Opts.ModuleCachePath = P.str(); + Opts.ModuleCachePath = std::string(P.str()); - Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path); + Opts.ModuleUserBuildPath = + std::string(Args.getLastArgValue(OPT_fmodules_user_build_path)); // Only the -fmodule-file=<name>=<file> form. for (const auto *A : Args.filtered(OPT_fmodule_file)) { StringRef Val = A->getValue(); - if (Val.find('=') != StringRef::npos) - Opts.PrebuiltModuleFiles.insert(Val.split('=')); + if (Val.find('=') != StringRef::npos){ + auto Split = Val.split('='); + Opts.PrebuiltModuleFiles.insert( + {std::string(Split.first), std::string(Split.second)}); + } } for (const auto *A : Args.filtered(OPT_fprebuilt_module_path)) Opts.AddPrebuiltModulePath(A->getValue()); Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content); - Opts.ModulesStrictContextHash = Args.hasArg(OPT_fmodules_strict_context_hash); Opts.ModulesValidateDiagnosticOptions = !Args.hasArg(OPT_fmodules_disable_diagnostic_validation); Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps); @@ -2141,7 +2188,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, SmallString<32> Buffer; llvm::sys::path::append(Buffer, Opts.Sysroot, llvm::StringRef(A->getValue()).substr(1)); - Path = Buffer.str(); + Path = std::string(Buffer.str()); } Opts.AddPath(Path, Group, IsFramework, @@ -2241,7 +2288,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, if (T.isPS4()) LangStd = LangStandard::lang_gnu99; else - LangStd = LangStandard::lang_gnu11; + LangStd = LangStandard::lang_gnu17; #endif break; case Language::ObjC: @@ -2278,7 +2325,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.CPlusPlus11 = Std.isCPlusPlus11(); Opts.CPlusPlus14 = Std.isCPlusPlus14(); Opts.CPlusPlus17 = Std.isCPlusPlus17(); - Opts.CPlusPlus2a = Std.isCPlusPlus2a(); + Opts.CPlusPlus20 = Std.isCPlusPlus20(); Opts.Digraphs = Std.hasDigraphs(); Opts.GNUMode = Std.isGNUMode(); Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus; @@ -2304,7 +2351,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.AltiVec = 0; Opts.ZVector = 0; Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::None); - Opts.setDefaultFPContractMode(LangOptions::FPC_On); + Opts.setDefaultFPContractMode(LangOptions::FPM_On); Opts.NativeHalfType = 1; Opts.NativeHalfArgsAndReturns = 1; Opts.OpenCLCPlusPlus = Opts.CPlusPlus; @@ -2324,7 +2371,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.CUDA = IK.getLanguage() == Language::CUDA || Opts.HIP; if (Opts.CUDA) // Set default FP_CONTRACT to FAST. - Opts.setDefaultFPContractMode(LangOptions::FPC_Fast); + Opts.setDefaultFPContractMode(LangOptions::FPM_Fast); Opts.RenderScript = IK.getLanguage() == Language::RenderScript; if (Opts.RenderScript) { @@ -2513,6 +2560,24 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, LangStd = OpenCLLangStd; } + Opts.SYCL = Args.hasArg(options::OPT_fsycl); + Opts.SYCLIsDevice = Opts.SYCL && Args.hasArg(options::OPT_fsycl_is_device); + if (Opts.SYCL) { + // -sycl-std applies to any SYCL source, not only those containing kernels, + // but also those using the SYCL API + if (const Arg *A = Args.getLastArg(OPT_sycl_std_EQ)) { + Opts.SYCLVersion = llvm::StringSwitch<unsigned>(A->getValue()) + .Cases("2017", "1.2.1", "121", "sycl-1.2.1", 2017) + .Default(0U); + + if (Opts.SYCLVersion == 0U) { + // User has passed an invalid value to the flag, this is an error + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + } + } + } + Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header); Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins); @@ -2699,7 +2764,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping); // Set the handler, if one is specified. Opts.OverflowHandler = - Args.getLastArgValue(OPT_ftrapv_handler); + std::string(Args.getLastArgValue(OPT_ftrapv_handler)); } else if (Args.hasArg(OPT_fwrapv)) Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined); @@ -2750,6 +2815,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_fno_threadsafe_statics)) Opts.ThreadsafeStatics = 0; Opts.Exceptions = Args.hasArg(OPT_fexceptions); + Opts.IgnoreExceptions = Args.hasArg(OPT_fignore_exceptions); Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions); Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions); @@ -2788,7 +2854,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL && Opts.OpenCLVersion == 200); Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional); - Opts.Coroutines = Opts.CPlusPlus2a || Args.hasArg(OPT_fcoroutines_ts); + Opts.Coroutines = Opts.CPlusPlus20 || Args.hasArg(OPT_fcoroutines_ts); Opts.ConvergentFunctions = Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || Args.hasArg(OPT_fconvergent_functions); @@ -2798,7 +2864,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, OPT_fno_double_square_bracket_attributes, Opts.DoubleSquareBracketAttributes); - Opts.CPlusPlusModules = Opts.CPlusPlus2a; + Opts.CPlusPlusModules = Opts.CPlusPlus20; Opts.ModulesTS = Args.hasArg(OPT_fmodules_ts); Opts.Modules = Args.hasArg(OPT_fmodules) || Opts.ModulesTS || Opts.CPlusPlusModules; @@ -2819,7 +2885,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ImplicitModules = !Args.hasArg(OPT_fno_implicit_modules); Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char); Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar); - Opts.Char8 = Args.hasFlag(OPT_fchar8__t, OPT_fno_char8__t, Opts.CPlusPlus2a); + Opts.Char8 = Args.hasFlag(OPT_fchar8__t, OPT_fno_char8__t, Opts.CPlusPlus20); if (const Arg *A = Args.getLastArg(OPT_fwchar_type_EQ)) { Opts.WCharSize = llvm::StringSwitch<unsigned>(A->getValue()) .Case("char", 1) @@ -2852,7 +2918,15 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, << A->getValue(); Opts.NewAlignOverride = 0; } - Opts.ConceptsTS = Args.hasArg(OPT_fconcepts_ts); + Opts.ConceptSatisfactionCaching = + !Args.hasArg(OPT_fno_concept_satisfaction_caching); + if (Args.hasArg(OPT_fconcepts_ts)) + Diags.Report(diag::warn_fe_concepts_ts_flag); + // Recovery AST still heavily relies on dependent-type machinery. + Opts.RecoveryAST = + Args.hasFlag(OPT_frecovery_ast, OPT_fno_recovery_ast, Opts.CPlusPlus); + Opts.RecoveryASTType = + Args.hasFlag(OPT_frecovery_ast_type, OPT_fno_recovery_ast_type, false); Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions); Opts.AccessControl = !Args.hasArg(OPT_fno_access_control); Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors); @@ -2873,7 +2947,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, getLastArgIntValue(Args, OPT_Wlarge_by_value_copy_EQ, 0, Diags); Opts.MSBitfields = Args.hasArg(OPT_mms_bitfields); Opts.ObjCConstantStringClass = - Args.getLastArgValue(OPT_fconstant_string_class); + std::string(Args.getLastArgValue(OPT_fconstant_string_class)); Opts.ObjCDefaultSynthProperties = !Args.hasArg(OPT_disable_objc_default_synthesize_properties); Opts.EncodeExtendedBlockSig = @@ -2882,6 +2956,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.PackStruct = getLastArgIntValue(Args, OPT_fpack_struct_EQ, 0, Diags); Opts.MaxTypeAlign = getLastArgIntValue(Args, OPT_fmax_type_align_EQ, 0, Diags); Opts.AlignDouble = Args.hasArg(OPT_malign_double); + Opts.DoubleSize = getLastArgIntValue(Args, OPT_mdouble_EQ, 0, Diags); Opts.LongDoubleSize = Args.hasArg(OPT_mlong_double_128) ? 128 : Args.hasArg(OPT_mlong_double_64) ? 64 : 0; @@ -2899,6 +2974,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.NoBitFieldTypeAlign = Args.hasArg(OPT_fno_bitfield_type_align); Opts.SinglePrecisionConstants = Args.hasArg(OPT_cl_single_precision_constant); Opts.FastRelaxedMath = Args.hasArg(OPT_cl_fast_relaxed_math); + if (Opts.FastRelaxedMath) + Opts.setDefaultFPContractMode(LangOptions::FPM_Fast); Opts.HexagonQdsp6Compat = Args.hasArg(OPT_mqdsp6_compat); Opts.FakeAddressSpaceMap = Args.hasArg(OPT_ffake_address_space_map); Opts.ParseUnknownAnytype = Args.hasArg(OPT_funknown_anytype); @@ -2906,7 +2983,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.DebuggerCastResultToId = Args.hasArg(OPT_fdebugger_cast_result_to_id); Opts.DebuggerObjCLiteral = Args.hasArg(OPT_fdebugger_objc_literal); Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack); - Opts.ModuleName = Args.getLastArgValue(OPT_fmodule_name_EQ); + Opts.ModuleName = std::string(Args.getLastArgValue(OPT_fmodule_name_EQ)); Opts.CurrentModule = Opts.ModuleName; Opts.AppExt = Args.hasArg(OPT_fapplication_extension); Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature); @@ -3001,6 +3078,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.setDefaultCallingConv(DefaultCC); } + Opts.SemanticInterposition = Args.hasArg(OPT_fsemantic_interposition); + // An explicit -fno-semantic-interposition infers dso_local. + Opts.ExplicitNoSemanticInterposition = + Args.hasArg(OPT_fno_semantic_interposition); + // -mrtd option if (Arg *A = Args.getLastArg(OPT_mrtd)) { if (Opts.getDefaultCallingConv() != LangOptions::DCC_None) @@ -3016,8 +3098,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } } - // Check if -fopenmp is specified and set default version to 4.5. - Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 45 : 0; + // Check if -fopenmp is specified and set default version to 5.0. + Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 50 : 0; // Check if -fopenmp-simd is specified. bool IsSimdSpecified = Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd, @@ -3035,10 +3117,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Opts.OpenMP || Opts.OpenMPSimd) { if (int Version = getLastArgIntValue( Args, OPT_fopenmp_version_EQ, - (IsSimdSpecified || IsTargetSpecified) ? 45 : Opts.OpenMP, Diags)) + (IsSimdSpecified || IsTargetSpecified) ? 50 : Opts.OpenMP, Diags)) Opts.OpenMP = Version; - else if (IsSimdSpecified || IsTargetSpecified) - Opts.OpenMP = 45; // Provide diagnostic when a given target is not expected to be an OpenMP // device or host. if (!Opts.OpenMPIsDevice) { @@ -3057,7 +3137,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // Set the flag to prevent the implementation from emitting device exception // handling code for those requiring so. - if ((Opts.OpenMPIsDevice && T.isNVPTX()) || Opts.OpenCLCPlusPlus) { + if ((Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN())) || + Opts.OpenCLCPlusPlus) { Opts.Exceptions = 0; Opts.CXXExceptions = 0; } @@ -3091,6 +3172,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, TT.getArch() == llvm::Triple::ppc64le || TT.getArch() == llvm::Triple::nvptx || TT.getArch() == llvm::Triple::nvptx64 || + TT.getArch() == llvm::Triple::amdgcn || TT.getArch() == llvm::Triple::x86 || TT.getArch() == llvm::Triple::x86_64)) Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i); @@ -3108,15 +3190,19 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, << Opts.OMPHostIRFile; } - Opts.SYCLIsDevice = Args.hasArg(options::OPT_fsycl_is_device); - - // Set CUDA mode for OpenMP target NVPTX if specified in options - Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && T.isNVPTX() && + // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options + Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) && Args.hasArg(options::OPT_fopenmp_cuda_mode); - // Set CUDA mode for OpenMP target NVPTX if specified in options + // Set CUDA support for parallel execution of target regions for OpenMP target + // NVPTX/AMDGCN if specified in options. + Opts.OpenMPCUDATargetParallel = + Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) && + Args.hasArg(options::OPT_fopenmp_cuda_parallel_target_regions); + + // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options Opts.OpenMPCUDAForceFullRuntime = - Opts.OpenMPIsDevice && T.isNVPTX() && + Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) && Args.hasArg(options::OPT_fopenmp_cuda_force_full_runtime); // Record whether the __DEPRECATED define was requested. @@ -3140,30 +3226,65 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (InlineArg->getOption().matches(options::OPT_fno_inline)) Opts.NoInlineDefine = true; - Opts.FastMath = Args.hasArg(OPT_ffast_math) || - Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.FastMath = + Args.hasArg(OPT_ffast_math) || Args.hasArg(OPT_cl_fast_relaxed_math); Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only) || - Args.hasArg(OPT_cl_finite_math_only) || - Args.hasArg(OPT_cl_fast_relaxed_math); + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_finite_math_only) || + Args.hasArg(OPT_cl_fast_relaxed_math); Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.AllowFPReassoc = Args.hasArg(OPT_mreassociate) || + Args.hasArg(OPT_menable_unsafe_fp_math) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.NoHonorNaNs = + Args.hasArg(OPT_menable_no_nans) || Args.hasArg(OPT_ffinite_math_only) || + Args.hasArg(OPT_ffast_math) || Args.hasArg(OPT_cl_finite_math_only) || + Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.NoHonorInfs = Args.hasArg(OPT_menable_no_infinities) || + Args.hasArg(OPT_ffinite_math_only) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_finite_math_only) || + Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.NoSignedZero = Args.hasArg(OPT_fno_signed_zeros) || + Args.hasArg(OPT_menable_unsafe_fp_math) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_no_signed_zeros) || Args.hasArg(OPT_cl_unsafe_math_optimizations) || Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.AllowRecip = Args.hasArg(OPT_freciprocal_math) || + Args.hasArg(OPT_menable_unsafe_fp_math) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_fast_relaxed_math); + // Currently there's no clang option to enable this individually + Opts.ApproxFunc = Args.hasArg(OPT_menable_unsafe_fp_math) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_fast_relaxed_math); if (Arg *A = Args.getLastArg(OPT_ffp_contract)) { StringRef Val = A->getValue(); if (Val == "fast") - Opts.setDefaultFPContractMode(LangOptions::FPC_Fast); + Opts.setDefaultFPContractMode(LangOptions::FPM_Fast); else if (Val == "on") - Opts.setDefaultFPContractMode(LangOptions::FPC_On); + Opts.setDefaultFPContractMode(LangOptions::FPM_On); else if (Val == "off") - Opts.setDefaultFPContractMode(LangOptions::FPC_Off); + Opts.setDefaultFPContractMode(LangOptions::FPM_Off); else Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } - LangOptions::FPRoundingModeKind FPRM = LangOptions::FPR_ToNearest; + if (Args.hasArg(OPT_fexperimental_strict_floating_point)) + Opts.ExpStrictFP = true; + + auto FPRM = llvm::RoundingMode::NearestTiesToEven; if (Args.hasArg(OPT_frounding_math)) { - FPRM = LangOptions::FPR_Dynamic; + FPRM = llvm::RoundingMode::Dynamic; } Opts.setFPRoundingMode(FPRM); @@ -3217,6 +3338,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } + if (Arg *A = Args.getLastArg(OPT_ftrivial_auto_var_init_stop_after)) { + int Val = std::stoi(A->getValue()); + Opts.TrivialAutoVarInitStopAfter = Val; + } + // Parse -fsanitize= arguments. parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), Diags, Opts.Sanitize); @@ -3231,18 +3357,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, systemBlacklists.end()); // -fxray-instrument - Opts.XRayInstrument = - Args.hasFlag(OPT_fxray_instrument, OPT_fnoxray_instrument, false); - - // -fxray-always-emit-customevents + Opts.XRayInstrument = Args.hasArg(OPT_fxray_instrument); Opts.XRayAlwaysEmitCustomEvents = - Args.hasFlag(OPT_fxray_always_emit_customevents, - OPT_fnoxray_always_emit_customevents, false); - - // -fxray-always-emit-typedevents + Args.hasArg(OPT_fxray_always_emit_customevents); Opts.XRayAlwaysEmitTypedEvents = - Args.hasFlag(OPT_fxray_always_emit_typedevents, - OPT_fnoxray_always_emit_customevents, false); + Args.hasArg(OPT_fxray_always_emit_typedevents); // -fxray-{always,never}-instrument= filenames. Opts.XRayAlwaysInstrumentFiles = @@ -3294,6 +3413,54 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.CompleteMemberPointers = Args.hasArg(OPT_fcomplete_member_pointers); Opts.BuildingPCHWithObjectFile = Args.hasArg(OPT_building_pch_with_obj); + Opts.PCHInstantiateTemplates = Args.hasArg(OPT_fpch_instantiate_templates); + + Opts.MatrixTypes = Args.hasArg(OPT_fenable_matrix); + + Opts.MaxTokens = getLastArgIntValue(Args, OPT_fmax_tokens_EQ, 0, Diags); + + if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) { + StringRef SignScope = A->getValue(); + + if (SignScope.equals_lower("none")) + Opts.setSignReturnAddressScope( + LangOptions::SignReturnAddressScopeKind::None); + else if (SignScope.equals_lower("all")) + Opts.setSignReturnAddressScope( + LangOptions::SignReturnAddressScopeKind::All); + else if (SignScope.equals_lower("non-leaf")) + Opts.setSignReturnAddressScope( + LangOptions::SignReturnAddressScopeKind::NonLeaf); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << SignScope; + + if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) { + StringRef SignKey = A->getValue(); + if (!SignScope.empty() && !SignKey.empty()) { + if (SignKey.equals_lower("a_key")) + Opts.setSignReturnAddressKey( + LangOptions::SignReturnAddressKeyKind::AKey); + else if (SignKey.equals_lower("b_key")) + Opts.setSignReturnAddressKey( + LangOptions::SignReturnAddressKeyKind::BKey); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << SignKey; + } + } + } + + Opts.BranchTargetEnforcement = Args.hasArg(OPT_mbranch_target_enforce); + Opts.SpeculativeLoadHardening = Args.hasArg(OPT_mspeculative_load_hardening); + + Opts.CompatibilityQualifiedIdBlockParamTypeChecking = + Args.hasArg(OPT_fcompatibility_qualified_id_block_param_type_checking); + + Opts.RelativeCXXABIVTables = + Args.hasFlag(OPT_fexperimental_relative_cxx_abi_vtables, + OPT_fno_experimental_relative_cxx_abi_vtables, + /*default=*/false); } static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { @@ -3314,7 +3481,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::GenerateModuleInterface: case frontend::GenerateHeaderModule: case frontend::GeneratePCH: - case frontend::GenerateInterfaceIfsExpV1: + case frontend::GenerateInterfaceStubs: case frontend::ParseSyntaxOnly: case frontend::ModuleFileInfo: case frontend::VerifyPCH: @@ -3343,11 +3510,12 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action) { - Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch); + Opts.ImplicitPCHInclude = std::string(Args.getLastArgValue(OPT_include_pch)); Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) || Args.hasArg(OPT_pch_through_hdrstop_use); Opts.PCHWithHdrStopCreate = Args.hasArg(OPT_pch_through_hdrstop_create); - Opts.PCHThroughHeader = Args.getLastArgValue(OPT_pch_through_header_EQ); + Opts.PCHThroughHeader = + std::string(Args.getLastArgValue(OPT_pch_through_header_EQ)); Opts.UsePredefines = !Args.hasArg(OPT_undef); Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record); Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch); @@ -3357,8 +3525,11 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl)) Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue()); - for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) - Opts.MacroPrefixMap.insert(StringRef(A).split('=')); + for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) { + auto Split = StringRef(A).split('='); + Opts.MacroPrefixMap.insert( + {std::string(Split.first), std::string(Split.second)}); + } if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) { StringRef Value(A->getValue()); @@ -3435,6 +3606,7 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, Opts.LexEditorPlaceholders = false; Opts.SetUpStaticAnalyzer = Args.hasArg(OPT_setup_static_analyzer); + Opts.DisablePragmaDebugCrash = Args.hasArg(OPT_disable_pragma_debug_crash); } static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, @@ -3457,8 +3629,8 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags) { - Opts.CodeModel = getCodeModel(Args, Diags); - Opts.ABI = Args.getLastArgValue(OPT_target_abi); + Opts.CodeModel = std::string(Args.getLastArgValue(OPT_mcmodel_EQ, "default")); + Opts.ABI = std::string(Args.getLastArgValue(OPT_target_abi)); if (Arg *A = Args.getLastArg(OPT_meabi)) { StringRef Value = A->getValue(); llvm::EABI EABIVersion = llvm::StringSwitch<llvm::EABI>(Value) @@ -3473,15 +3645,11 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, else Opts.EABIVersion = EABIVersion; } - Opts.CPU = Args.getLastArgValue(OPT_target_cpu); - Opts.FPMath = Args.getLastArgValue(OPT_mfpmath); + Opts.CPU = std::string(Args.getLastArgValue(OPT_target_cpu)); + Opts.FPMath = std::string(Args.getLastArgValue(OPT_mfpmath)); Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature); - Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version); - Opts.Triple = Args.getLastArgValue(OPT_triple); - // Use the default target triple if unspecified. - if (Opts.Triple.empty()) - Opts.Triple = llvm::sys::getDefaultTargetTriple(); - Opts.Triple = llvm::Triple::normalize(Opts.Triple); + Opts.LinkerVersion = + std::string(Args.getLastArgValue(OPT_target_linker_version)); Opts.OpenCLExtensionsAsWritten = Args.getAllArgValues(OPT_cl_ext_EQ); Opts.ForceEnableInt128 = Args.hasArg(OPT_fforce_enable_int128); Opts.NVPTXUseShortPointers = Args.hasFlag( @@ -3496,9 +3664,35 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, } } +bool CompilerInvocation::parseSimpleArgs(const ArgList &Args, + DiagnosticsEngine &Diags) { +#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \ + ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \ + METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \ + KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \ + this->KEYPATH = Args.hasArg(OPT_##ID) && IS_POSITIVE; + +#define OPTION_WITH_MARSHALLING_STRING( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + TYPE, NORMALIZER, DENORMALIZER, TABLE_INDEX) \ + { \ + if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, Diags)) \ + this->KEYPATH = static_cast<TYPE>(*MaybeValue); \ + else \ + this->KEYPATH = DEFAULT_VALUE; \ + } + +#include "clang/Driver/Options.inc" +#undef OPTION_WITH_MARSHALLING_STRING +#undef OPTION_WITH_MARSHALLING_FLAG + return true; +} + bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs, - DiagnosticsEngine &Diags) { + DiagnosticsEngine &Diags, + const char *Argv0) { bool Success = true; // Parse the arguments. @@ -3528,6 +3722,11 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Success = false; } + Success &= Res.parseSimpleArgs(Args, Diags); + + llvm::sys::Process::UseANSIEscapeCodes( + Res.DiagnosticOpts->UseANSIEscapeCodes); + Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags); Success &= ParseMigratorArgs(Res.getMigratorOpts(), Args); ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args); @@ -3536,9 +3735,8 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Diags.Report(diag::err_fe_dependency_file_requires_MT); Success = false; } - Success &= - ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags, - false /*DefaultDiagColor*/, false /*DefaultShowOpt*/); + Success &= ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags, + /*DefaultDiagColor=*/false); ParseCommentArgs(LangOpts.CommentOpts, Args); ParseFileSystemArgs(Res.getFileSystemOpts(), Args); // FIXME: We shouldn't have to pass the DashX option around here @@ -3619,6 +3817,11 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false; Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored); } + + // Store the command-line for using in the CodeView backend. + Res.getCodeGenOpts().Argv0 = Argv0; + Res.getCodeGenOpts().CommandLineArgs = CommandLineArgs; + return Success; } @@ -3635,6 +3838,11 @@ std::string CompilerInvocation::getModuleHash() const { // CityHash, but this will do for now. hash_code code = hash_value(getClangFullRepositoryVersion()); + // Also include the serialization version, in case LLVM_APPEND_VC_REV is off + // and getClangFullRepositoryVersion() doesn't include git revision. + code = hash_combine(code, serialization::VERSION_MAJOR, + serialization::VERSION_MINOR); + // Extend the signature with the language options #define LANGOPT(Name, Bits, Default, Description) \ code = hash_combine(code, LangOpts->Name); @@ -3647,6 +3855,10 @@ std::string CompilerInvocation::getModuleHash() const { for (StringRef Feature : LangOpts->ModuleFeatures) code = hash_combine(code, Feature); + code = hash_combine(code, LangOpts->ObjCRuntime); + const auto &BCN = LangOpts->CommentOpts.BlockCommandNames; + code = hash_combine(code, hash_combine_range(BCN.begin(), BCN.end())); + // Extend the signature with the target options. code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU, TargetOpts->ABI); @@ -3726,6 +3938,33 @@ std::string CompilerInvocation::getModuleHash() const { return llvm::APInt(64, code).toString(36, /*Signed=*/false); } +void CompilerInvocation::generateCC1CommandLine( + SmallVectorImpl<const char *> &Args, StringAllocator SA) const { +#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \ + ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \ + METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \ + KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \ + if ((FLAGS) & options::CC1Option && \ + (ALWAYS_EMIT || this->KEYPATH != DEFAULT_VALUE)) \ + Args.push_back(SPELLING); + +#define OPTION_WITH_MARSHALLING_STRING( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + NORMALIZER_RET_TY, NORMALIZER, DENORMALIZER, TABLE_INDEX) \ + if (((FLAGS) & options::CC1Option) && \ + (ALWAYS_EMIT || this->KEYPATH != DEFAULT_VALUE)) { \ + if (Option::KIND##Class == Option::SeparateClass) { \ + Args.push_back(SPELLING); \ + Args.push_back(DENORMALIZER(SA, TABLE_INDEX, this->KEYPATH)); \ + } \ + } + +#include "clang/Driver/Options.inc" +#undef OPTION_WITH_MARSHALLING_STRING +#undef OPTION_WITH_MARSHALLING_FLAG +} + namespace clang { IntrusiveRefCntPtr<llvm::vfs::FileSystem> diff --git a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp index 18c4814bbd5c..1d5a6c06b34f 100644 --- a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -93,7 +93,7 @@ std::unique_ptr<CompilerInvocation> clang::createInvocationFromCommandLine( if (CC1Args) *CC1Args = {CCArgs.begin(), CCArgs.end()}; auto CI = std::make_unique<CompilerInvocation>(); - if (!CompilerInvocation::CreateFromArgs(*CI, CCArgs, *Diags) && + if (!CompilerInvocation::CreateFromArgs(*CI, CCArgs, *Diags, Args[0]) && !ShouldRecoverOnErorrs) return nullptr; return CI; diff --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp index 4bb0167bd597..c9240f4122a7 100644 --- a/clang/lib/Frontend/DependencyFile.cpp +++ b/clang/lib/Frontend/DependencyFile.cpp @@ -137,16 +137,17 @@ struct DepCollectorASTListener : public ASTReaderListener { }; } // end anonymous namespace -void DependencyCollector::maybeAddDependency(StringRef Filename, bool FromModule, - bool IsSystem, bool IsModuleFile, - bool IsMissing) { +void DependencyCollector::maybeAddDependency(StringRef Filename, + bool FromModule, bool IsSystem, + bool IsModuleFile, + bool IsMissing) { if (sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing)) addDependency(Filename); } bool DependencyCollector::addDependency(StringRef Filename) { if (Seen.insert(Filename).second) { - Dependencies.push_back(Filename); + Dependencies.push_back(std::string(Filename)); return true; } return false; @@ -160,8 +161,8 @@ static bool isSpecialFilename(StringRef Filename) { } bool DependencyCollector::sawDependency(StringRef Filename, bool FromModule, - bool IsSystem, bool IsModuleFile, - bool IsMissing) { + bool IsSystem, bool IsModuleFile, + bool IsMissing) { return !isSpecialFilename(Filename) && (needSystemDependencies() || !IsSystem); } diff --git a/clang/lib/Frontend/DependencyGraph.cpp b/clang/lib/Frontend/DependencyGraph.cpp index ccf7a2785510..8a6e491def45 100644 --- a/clang/lib/Frontend/DependencyGraph.cpp +++ b/clang/lib/Frontend/DependencyGraph.cpp @@ -119,8 +119,7 @@ void DependencyGraphCallback::OutputGraphFile() { if (FileName.startswith(SysRoot)) FileName = FileName.substr(SysRoot.size()); - OS << DOT::EscapeString(FileName) - << "\"];\n"; + OS << DOT::EscapeString(std::string(FileName)) << "\"];\n"; } // Write the edges diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 934d17b3c925..59a968b5c709 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -157,10 +157,9 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, bool FoundAllPlugins = true; for (const std::string &Arg : CI.getFrontendOpts().AddPluginActions) { bool Found = false; - for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), - ie = FrontendPluginRegistry::end(); - it != ie; ++it) { - if (it->getName() == Arg) + for (const FrontendPluginRegistry::entry &Plugin : + FrontendPluginRegistry::entries()) { + if (Plugin.getName() == Arg) Found = true; } if (!Found) { @@ -183,25 +182,24 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, // or after it (in AfterConsumers) std::vector<std::unique_ptr<ASTConsumer>> Consumers; std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers; - for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), - ie = FrontendPluginRegistry::end(); - it != ie; ++it) { - std::unique_ptr<PluginASTAction> P = it->instantiate(); + for (const FrontendPluginRegistry::entry &Plugin : + FrontendPluginRegistry::entries()) { + std::unique_ptr<PluginASTAction> P = Plugin.instantiate(); PluginASTAction::ActionType ActionType = P->getActionType(); if (ActionType == PluginASTAction::Cmdline) { // This is O(|plugins| * |add_plugins|), but since both numbers are // way below 50 in practice, that's ok. - for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); - i != e; ++i) { - if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) { - ActionType = PluginASTAction::AddAfterMainAction; - break; - } - } + if (llvm::any_of(CI.getFrontendOpts().AddPluginActions, + [&](const std::string &PluginAction) { + return PluginAction == Plugin.getName(); + })) + ActionType = PluginASTAction::AddAfterMainAction; } if ((ActionType == PluginASTAction::AddBeforeMainAction || ActionType == PluginASTAction::AddAfterMainAction) && - P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs[it->getName()])) { + P->ParseArgs( + CI, + CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())])) { std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile); if (ActionType == PluginASTAction::AddBeforeMainAction) { Consumers.push_back(std::move(PluginConsumer)); @@ -363,6 +361,7 @@ static std::error_code collectModuleHeaderIncludes( llvm::sys::path::native(UmbrellaDir.Entry->getName(), DirNative); llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); + SmallVector<std::pair<std::string, const FileEntry *>, 8> Headers; for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End; Dir != End && !EC; Dir.increment(EC)) { // Check whether this entry has an extension typically associated with @@ -393,13 +392,25 @@ static std::error_code collectModuleHeaderIncludes( ++It) llvm::sys::path::append(RelativeHeader, *It); - // Include this header as part of the umbrella directory. - Module->addTopHeader(*Header); - addHeaderInclude(RelativeHeader, Includes, LangOpts, Module->IsExternC); + std::string RelName = RelativeHeader.c_str(); + Headers.push_back(std::make_pair(RelName, *Header)); } if (EC) return EC; + + // Sort header paths and make the header inclusion order deterministic + // across different OSs and filesystems. + llvm::sort(Headers.begin(), Headers.end(), []( + const std::pair<std::string, const FileEntry *> &LHS, + const std::pair<std::string, const FileEntry *> &RHS) { + return LHS.first < RHS.first; + }); + for (auto &H : Headers) { + // Include this header as part of the umbrella directory. + Module->addTopHeader(H.second); + addHeaderInclude(H.first, Includes, LangOpts, Module->IsExternC); + } } // Recurse into submodules. @@ -564,8 +575,9 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, StringRef InputFile = Input.getFile(); std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( - InputFile, CI.getPCHContainerReader(), ASTUnit::LoadPreprocessorOnly, - ASTDiags, CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs); + std::string(InputFile), CI.getPCHContainerReader(), + ASTUnit::LoadPreprocessorOnly, ASTDiags, CI.getFileSystemOpts(), + CI.getCodeGenOpts().DebugTypeExtRefs); if (!AST) goto failure; @@ -592,10 +604,11 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, if (&MF != &PrimaryModule) CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName); - ASTReader->visitTopLevelModuleMaps(PrimaryModule, - [&](const FileEntry *FE) { - CI.getFrontendOpts().ModuleMapFiles.push_back(FE->getName()); - }); + ASTReader->visitTopLevelModuleMaps( + PrimaryModule, [&](const FileEntry *FE) { + CI.getFrontendOpts().ModuleMapFiles.push_back( + std::string(FE->getName())); + }); } // Set up the input file for replay purposes. @@ -630,8 +643,9 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, StringRef InputFile = Input.getFile(); std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( - InputFile, CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags, - CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs); + std::string(InputFile), CI.getPCHContainerReader(), + ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts(), + CI.getCodeGenOpts().DebugTypeExtRefs); if (!AST) goto failure; @@ -725,7 +739,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, Dir->path(), FileMgr, CI.getPCHContainerReader(), CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(), SpecificModuleCachePath)) { - PPOpts.ImplicitPCHInclude = Dir->path(); + PPOpts.ImplicitPCHInclude = std::string(Dir->path()); Found = true; break; } @@ -783,7 +797,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User; auto &SourceMgr = CI.getSourceManager(); auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind); - assert(BufferID.isValid() && "couldn't creaate module buffer ID"); + assert(BufferID.isValid() && "couldn't create module buffer ID"); SourceMgr.setMainFileID(BufferID); } } @@ -817,7 +831,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, // For preprocessed files, check if the first line specifies the original // source file name with a linemarker. - std::string PresumedInputFile = getCurrentFileOrBufferName(); + std::string PresumedInputFile = std::string(getCurrentFileOrBufferName()); if (Input.isPreprocessed()) ReadOriginalFileName(CI, PresumedInputFile); @@ -836,7 +850,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, source = createChainedIncludesSource(CI, FinalReader); if (!source) goto failure; - CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get())); + CI.setASTReader(static_cast<ASTReader *>(FinalReader.get())); CI.getASTContext().setExternalSource(source); } else if (CI.getLangOpts().Modules || !CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { @@ -866,7 +880,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, if (!CI.getASTContext().getExternalSource()) goto failure; } - // If modules are enabled, create the module manager before creating + // If modules are enabled, create the AST reader before creating // any builtins, so that all declarations know that they might be // extended by an external source. if (CI.getLangOpts().Modules || !CI.hasASTContext() || @@ -1077,6 +1091,9 @@ void WrapperFrontendAction::ExecuteAction() { void WrapperFrontendAction::EndSourceFileAction() { WrappedAction->EndSourceFileAction(); } +bool WrapperFrontendAction::shouldEraseOutputFiles() { + return WrappedAction->shouldEraseOutputFiles(); +} bool WrapperFrontendAction::usesPreprocessorOnly() const { return WrappedAction->usesPreprocessorOnly(); diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 8574d0a7e813..711e7336c820 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -9,6 +9,7 @@ #include "clang/Frontend/FrontendActions.h" #include "clang/AST/ASTConsumer.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Basic/LangStandard.h" #include "clang/Frontend/ASTConsumers.h" #include "clang/Frontend/CompilerInstance.h" @@ -78,7 +79,8 @@ ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { const FrontendOptions &Opts = CI.getFrontendOpts(); return CreateASTDumper(nullptr /*Dump to stdout.*/, Opts.ASTDumpFilter, Opts.ASTDumpDecls, Opts.ASTDumpAll, - Opts.ASTDumpLookups, Opts.ASTDumpFormat); + Opts.ASTDumpLookups, Opts.ASTDumpDeclTypes, + Opts.ASTDumpFormat); } std::unique_ptr<ASTConsumer> @@ -115,7 +117,7 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, FrontendOpts.IncludeTimestamps, +CI.getLangOpts().CacheGeneratedPCH)); Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( - CI, InFile, OutputFile, std::move(OS), Buffer)); + CI, std::string(InFile), OutputFile, std::move(OS), Buffer)); return std::make_unique<MultiplexConsumer>(std::move(Consumers)); } @@ -181,7 +183,7 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, /*ShouldCacheASTInMemory=*/ +CI.getFrontendOpts().BuildingImplicitModule)); Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( - CI, InFile, OutputFile, std::move(OS), Buffer)); + CI, std::string(InFile), OutputFile, std::move(OS), Buffer)); return std::make_unique<MultiplexConsumer>(std::move(Consumers)); } @@ -266,7 +268,7 @@ bool GenerateHeaderModuleAction::PrepareToExecuteAction( HeaderContents += "#include \""; HeaderContents += FIF.getFile(); HeaderContents += "\"\n"; - ModuleHeaders.push_back(FIF.getFile()); + ModuleHeaders.push_back(std::string(FIF.getFile())); } Buffer = llvm::MemoryBuffer::getMemBufferCopy( HeaderContents, Module::getModuleInputBufferName()); @@ -295,7 +297,7 @@ bool GenerateHeaderModuleAction::BeginSourceFileAction( << Name; continue; } - Headers.push_back({Name, &FE->getFileEntry()}); + Headers.push_back({std::string(Name), &FE->getFileEntry()}); } HS.getModuleMap().createHeaderModule(CI.getLangOpts().CurrentModule, Headers); @@ -429,6 +431,14 @@ private: return "ConstraintNormalization"; case CodeSynthesisContext::ParameterMappingSubstitution: return "ParameterMappingSubstitution"; + case CodeSynthesisContext::RequirementInstantiation: + return "RequirementInstantiation"; + case CodeSynthesisContext::NestedRequirementConstraintsCheck: + return "NestedRequirementConstraintsCheck"; + case CodeSynthesisContext::InitializingStructuredBinding: + return "InitializingStructuredBinding"; + case CodeSynthesisContext::MarkingClassDllexported: + return "MarkingClassDllexported"; } return ""; } diff --git a/clang/lib/Frontend/FrontendOptions.cpp b/clang/lib/Frontend/FrontendOptions.cpp index 5c1fbf889c23..9f080db733f1 100644 --- a/clang/lib/Frontend/FrontendOptions.cpp +++ b/clang/lib/Frontend/FrontendOptions.cpp @@ -25,11 +25,12 @@ InputKind FrontendOptions::getInputKindForExtension(StringRef Extension) { .Cases("mm", "M", Language::ObjCXX) .Case("mii", InputKind(Language::ObjCXX).getPreprocessed()) .Cases("C", "cc", "cp", Language::CXX) - .Cases("cpp", "CPP", "c++", "cxx", "hpp", Language::CXX) + .Cases("cpp", "CPP", "c++", "cxx", "hpp", "hxx", Language::CXX) .Case("cppm", Language::CXX) .Case("iim", InputKind(Language::CXX).getPreprocessed()) .Case("cl", Language::OpenCL) .Case("cu", Language::CUDA) + .Case("hip", Language::HIP) .Cases("ll", "bc", Language::LLVM_IR) .Default(Language::Unknown); } diff --git a/clang/lib/Frontend/HeaderIncludeGen.cpp b/clang/lib/Frontend/HeaderIncludeGen.cpp index 5f91157816b0..97fac8a26fae 100644 --- a/clang/lib/Frontend/HeaderIncludeGen.cpp +++ b/clang/lib/Frontend/HeaderIncludeGen.cpp @@ -127,8 +127,8 @@ void clang::AttachHeaderIncludeGen(Preprocessor &PP, void HeaderIncludesCallback::FileChanged(SourceLocation Loc, FileChangeReason Reason, - SrcMgr::CharacteristicKind NewFileType, - FileID PrevFID) { + SrcMgr::CharacteristicKind NewFileType, + FileID PrevFID) { // Unless we are exiting a #include, make sure to skip ahead to the line the // #include directive was at. PresumedLoc UserLoc = SM.getPresumedLoc(Loc); @@ -167,6 +167,9 @@ void HeaderIncludesCallback::FileChanged(SourceLocation Loc, else if (!DepOpts.ShowIncludesPretendHeader.empty()) ++IncludeDepth; // Pretend inclusion by ShowIncludesPretendHeader. + if (!DepOpts.IncludeSystemHeaders && isSystem(NewFileType)) + ShowHeader = false; + // Dump the header include information we are past the predefines buffer or // are showing all headers and this isn't the magic implicit <command line> // header. diff --git a/clang/lib/Frontend/InitHeaderSearch.cpp b/clang/lib/Frontend/InitHeaderSearch.cpp index 5d877ee9c0d7..16f1f1670e8d 100644 --- a/clang/lib/Frontend/InitHeaderSearch.cpp +++ b/clang/lib/Frontend/InitHeaderSearch.cpp @@ -47,11 +47,9 @@ class InitHeaderSearch { bool HasSysroot; public: - InitHeaderSearch(HeaderSearch &HS, bool verbose, StringRef sysroot) - : Headers(HS), Verbose(verbose), IncludeSysroot(sysroot), - HasSysroot(!(sysroot.empty() || sysroot == "/")) { - } + : Headers(HS), Verbose(verbose), IncludeSysroot(std::string(sysroot)), + HasSysroot(!(sysroot.empty() || sysroot == "/")) {} /// AddPath - Add the specified path to the specified group list, prefixing /// the sysroot if used. @@ -67,7 +65,7 @@ public: /// AddSystemHeaderPrefix - Add the specified prefix to the system header /// prefix list. void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) { - SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader); + SystemHeaderPrefixes.emplace_back(std::string(Prefix), IsSystemHeader); } /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu @@ -355,7 +353,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, // files is <SDK_DIR>/host_tools/lib/clang SmallString<128> P = StringRef(HSOpts.ResourceDir); llvm::sys::path::append(P, "../../.."); - BaseSDKPath = P.str(); + BaseSDKPath = std::string(P.str()); } } AddPath(BaseSDKPath + "/target/include", System, false); @@ -383,6 +381,7 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths( case llvm::Triple::Linux: case llvm::Triple::Hurd: case llvm::Triple::Solaris: + case llvm::Triple::AIX: llvm_unreachable("Include management is handled in the driver."); break; case llvm::Triple::Win32: @@ -426,6 +425,7 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang, case llvm::Triple::Hurd: case llvm::Triple::Solaris: case llvm::Triple::WASI: + case llvm::Triple::AIX: return; case llvm::Triple::Win32: @@ -435,8 +435,7 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang, break; case llvm::Triple::UnknownOS: - if (triple.getArch() == llvm::Triple::wasm32 || - triple.getArch() == llvm::Triple::wasm64) + if (triple.isWasm()) return; break; } diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 2c7e3a56c043..6eef1e2376f6 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -80,9 +80,9 @@ static void AddImplicitIncludeMacros(MacroBuilder &Builder, StringRef File) { static void AddImplicitIncludePCH(MacroBuilder &Builder, Preprocessor &PP, const PCHContainerReader &PCHContainerRdr, StringRef ImplicitIncludePCH) { - std::string OriginalFile = - ASTReader::getOriginalSourceFile(ImplicitIncludePCH, PP.getFileManager(), - PCHContainerRdr, PP.getDiagnostics()); + std::string OriginalFile = ASTReader::getOriginalSourceFile( + std::string(ImplicitIncludePCH), PP.getFileManager(), PCHContainerRdr, + PP.getDiagnostics()); if (OriginalFile.empty()) return; @@ -344,13 +344,27 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, const LangOptions &LangOpts, const FrontendOptions &FEOpts, MacroBuilder &Builder) { + // C++ [cpp.predefined]p1: + // The following macro names shall be defined by the implementation: + + // -- __STDC__ + // [C++] Whether __STDC__ is predefined and if so, what its value is, + // are implementation-defined. + // (Removed in C++20.) if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP) Builder.defineMacro("__STDC__"); + // -- __STDC_HOSTED__ + // The integer literal 1 if the implementation is a hosted + // implementation or the integer literal 0 if it is not. if (LangOpts.Freestanding) Builder.defineMacro("__STDC_HOSTED__", "0"); else Builder.defineMacro("__STDC_HOSTED__"); + // -- __STDC_VERSION__ + // [C++] Whether __STDC_VERSION__ is predefined and if so, what its + // value is, are implementation-defined. + // (Removed in C++20.) if (!LangOpts.CPlusPlus) { if (LangOpts.C17) Builder.defineMacro("__STDC_VERSION__", "201710L"); @@ -361,33 +375,29 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, else if (!LangOpts.GNUMode && LangOpts.Digraphs) Builder.defineMacro("__STDC_VERSION__", "199409L"); } else { - // FIXME: Use correct value for C++20. - if (LangOpts.CPlusPlus2a) - Builder.defineMacro("__cplusplus", "201707L"); - // C++17 [cpp.predefined]p1: - // The name __cplusplus is defined to the value 201703L when compiling a - // C++ translation unit. + // -- __cplusplus + // [C++20] The integer literal 202002L. + if (LangOpts.CPlusPlus20) + Builder.defineMacro("__cplusplus", "202002L"); + // [C++17] The integer literal 201703L. else if (LangOpts.CPlusPlus17) Builder.defineMacro("__cplusplus", "201703L"); - // C++1y [cpp.predefined]p1: - // The name __cplusplus is defined to the value 201402L when compiling a - // C++ translation unit. + // [C++14] The name __cplusplus is defined to the value 201402L when + // compiling a C++ translation unit. else if (LangOpts.CPlusPlus14) Builder.defineMacro("__cplusplus", "201402L"); - // C++11 [cpp.predefined]p1: - // The name __cplusplus is defined to the value 201103L when compiling a - // C++ translation unit. + // [C++11] The name __cplusplus is defined to the value 201103L when + // compiling a C++ translation unit. else if (LangOpts.CPlusPlus11) Builder.defineMacro("__cplusplus", "201103L"); - // C++03 [cpp.predefined]p1: - // The name __cplusplus is defined to the value 199711L when compiling a - // C++ translation unit. + // [C++03] The name __cplusplus is defined to the value 199711L when + // compiling a C++ translation unit. else Builder.defineMacro("__cplusplus", "199711L"); - // C++1z [cpp.predefined]p1: - // An integer literal of type std::size_t whose value is the alignment - // guaranteed by a call to operator new(std::size_t) + // -- __STDCPP_DEFAULT_NEW_ALIGNMENT__ + // [C++17] An integer literal of type std::size_t whose value is the + // alignment guaranteed by a call to operator new(std::size_t) // // We provide this in all language modes, since it seems generally useful. Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__", @@ -450,6 +460,13 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, if (LangOpts.FastRelaxedMath) Builder.defineMacro("__FAST_RELAXED_MATH__"); } + + if (LangOpts.SYCL) { + // SYCL Version is set to a value when building SYCL applications + if (LangOpts.SYCLVersion == 2017) + Builder.defineMacro("CL_SYCL_LANGUAGE_VERSION", "121"); + } + // Not "standard" per se, but available even with the -undef flag. if (LangOpts.AsmPreprocessor) Builder.defineMacro("__ASSEMBLER__"); @@ -481,7 +498,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_user_defined_literals", "200809L"); Builder.defineMacro("__cpp_lambdas", "200907L"); Builder.defineMacro("__cpp_constexpr", - LangOpts.CPlusPlus2a ? "201907L" : + LangOpts.CPlusPlus20 ? "201907L" : LangOpts.CPlusPlus17 ? "201603L" : LangOpts.CPlusPlus14 ? "201304L" : "200704"); Builder.defineMacro("__cpp_constexpr_in_decltype", "201711L"); @@ -508,9 +525,9 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_binary_literals", "201304L"); Builder.defineMacro("__cpp_digit_separators", "201309L"); Builder.defineMacro("__cpp_init_captures", - LangOpts.CPlusPlus2a ? "201803L" : "201304L"); + LangOpts.CPlusPlus20 ? "201803L" : "201304L"); Builder.defineMacro("__cpp_generic_lambdas", - LangOpts.CPlusPlus2a ? "201707L" : "201304L"); + LangOpts.CPlusPlus20 ? "201707L" : "201304L"); Builder.defineMacro("__cpp_decltype_auto", "201304L"); Builder.defineMacro("__cpp_return_type_deduction", "201304L"); Builder.defineMacro("__cpp_aggregate_nsdmi", "201304L"); @@ -546,9 +563,9 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_template_template_args", "201611L"); // C++20 features. - if (LangOpts.CPlusPlus2a) { + if (LangOpts.CPlusPlus20) { //Builder.defineMacro("__cpp_aggregate_paren_init", "201902L"); - //Builder.defineMacro("__cpp_concepts", "201907L"); + Builder.defineMacro("__cpp_concepts", "201907L"); Builder.defineMacro("__cpp_conditional_explicit", "201806L"); //Builder.defineMacro("__cpp_consteval", "201811L"); Builder.defineMacro("__cpp_constexpr_dynamic_alloc", "201907L"); @@ -564,8 +581,6 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_impl_destroying_delete", "201806L"); // TS features. - if (LangOpts.ConceptsTS) - Builder.defineMacro("__cpp_experimental_concepts", "1L"); if (LangOpts.Coroutines) Builder.defineMacro("__cpp_coroutines", "201703L"); } @@ -1061,12 +1076,12 @@ static void InitializePredefinedMacros(const TargetInfo &TI, case 40: Builder.defineMacro("_OPENMP", "201307"); break; - case 50: - Builder.defineMacro("_OPENMP", "201811"); + case 45: + Builder.defineMacro("_OPENMP", "201511"); break; default: - // Default version is OpenMP 4.5 - Builder.defineMacro("_OPENMP", "201511"); + // Default version is OpenMP 5.0 + Builder.defineMacro("_OPENMP", "201811"); break; } } diff --git a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp index 7241081d6cc0..b7c1e693413b 100644 --- a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp +++ b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp @@ -8,6 +8,7 @@ #include "clang/AST/Mangle.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Sema/TemplateInstCallback.h" @@ -289,7 +290,7 @@ public: const ASTContext &context, StringRef Format, raw_ostream &OS) -> void { OS << "--- !" << Format << "\n"; - OS << "IfsVersion: 1.0\n"; + OS << "IfsVersion: 2.0\n"; OS << "Triple: " << T.str() << "\n"; OS << "ObjectFileFormat: " << "ELF" @@ -298,11 +299,11 @@ public: for (const auto &E : Symbols) { const MangledSymbol &Symbol = E.second; for (auto Name : Symbol.Names) { - OS << " \"" + OS << " - { Name: \"" << (Symbol.ParentName.empty() || Instance.getLangOpts().CPlusPlus ? "" : (Symbol.ParentName + ".")) - << Name << "\" : { Type: "; + << Name << "\", Type: "; switch (Symbol.Type) { default: llvm_unreachable( @@ -329,15 +330,15 @@ public: OS.flush(); }; - assert(Format == "experimental-ifs-v1" && "Unexpected IFS Format."); + assert(Format == "experimental-ifs-v2" && "Unexpected IFS Format."); writeIfsV1(Instance.getTarget().getTriple(), Symbols, context, Format, *OS); } }; } // namespace std::unique_ptr<ASTConsumer> -GenerateInterfaceIfsExpV1Action::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +GenerateInterfaceStubsAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { return std::make_unique<InterfaceStubFunctionsConsumer>( - CI, InFile, "experimental-ifs-v1"); + CI, InFile, "experimental-ifs-v2"); } diff --git a/clang/lib/Frontend/LogDiagnosticPrinter.cpp b/clang/lib/Frontend/LogDiagnosticPrinter.cpp index 4bac17553999..df8b23691a7d 100644 --- a/clang/lib/Frontend/LogDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/LogDiagnosticPrinter.cpp @@ -120,7 +120,7 @@ void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level, if (FID.isValid()) { const FileEntry *FE = SM.getFileEntryForID(FID); if (FE && FE->isValid()) - MainFilename = FE->getName(); + MainFilename = std::string(FE->getName()); } } @@ -129,12 +129,13 @@ void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level, DE.DiagnosticID = Info.getID(); DE.DiagnosticLevel = Level; - DE.WarningOption = DiagnosticIDs::getWarningOptionForDiag(DE.DiagnosticID); + DE.WarningOption = + std::string(DiagnosticIDs::getWarningOptionForDiag(DE.DiagnosticID)); // Format the message. SmallString<100> MessageStr; Info.FormatDiagnostic(MessageStr); - DE.Message = MessageStr.str(); + DE.Message = std::string(MessageStr.str()); // Set the location information. DE.Filename = ""; @@ -149,7 +150,7 @@ void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level, if (FID.isValid()) { const FileEntry *FE = SM.getFileEntryForID(FID); if (FE && FE->isValid()) - DE.Filename = FE->getName(); + DE.Filename = std::string(FE->getName()); } } else { DE.Filename = PLoc.getFilename(); diff --git a/clang/lib/Frontend/ModuleDependencyCollector.cpp b/clang/lib/Frontend/ModuleDependencyCollector.cpp index fd22433d31bd..b54eb97d6c47 100644 --- a/clang/lib/Frontend/ModuleDependencyCollector.cpp +++ b/clang/lib/Frontend/ModuleDependencyCollector.cpp @@ -170,7 +170,7 @@ bool ModuleDependencyCollector::getRealPath(StringRef SrcPath, if (DirWithSymLink == SymLinkMap.end()) { if (llvm::sys::fs::real_path(Dir, RealPath)) return false; - SymLinkMap[Dir] = RealPath.str(); + SymLinkMap[Dir] = std::string(RealPath.str()); } else { RealPath = DirWithSymLink->second; } diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp index 0e5a8e504dc5..6cdfc595dcae 100644 --- a/clang/lib/Frontend/PrecompiledPreamble.cpp +++ b/clang/lib/Frontend/PrecompiledPreamble.cpp @@ -12,21 +12,26 @@ #include "clang/Frontend/PrecompiledPreamble.h" #include "clang/AST/DeclObjC.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/LangStandard.h" #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Frontend/FrontendOptions.h" +#include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang/Serialization/ASTWriter.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/VirtualFileSystem.h" #include <limits> @@ -73,6 +78,68 @@ public: bool needSystemDependencies() override { return true; } }; +// Collects files whose existence would invalidate the preamble. +// Collecting *all* of these would make validating it too slow though, so we +// just find all the candidates for 'file not found' diagnostics. +// +// A caveat that may be significant for generated files: we'll omit files under +// search path entries whose roots don't exist when the preamble is built. +// These are pruned by InitHeaderSearch and so we don't see the search path. +// It would be nice to include them but we don't want to duplicate all the rest +// of the InitHeaderSearch logic to reconstruct them. +class MissingFileCollector : public PPCallbacks { + llvm::StringSet<> &Out; + const HeaderSearch &Search; + const SourceManager &SM; + +public: + MissingFileCollector(llvm::StringSet<> &Out, const HeaderSearch &Search, + const SourceManager &SM) + : Out(Out), Search(Search), SM(SM) {} + + void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, + StringRef FileName, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, + StringRef SearchPath, StringRef RelativePath, + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override { + // File is null if it wasn't found. + // (We have some false negatives if PP recovered e.g. <foo> -> "foo") + if (File != nullptr) + return; + + // If it's a rare absolute include, we know the full path already. + if (llvm::sys::path::is_absolute(FileName)) { + Out.insert(FileName); + return; + } + + // Reconstruct the filenames that would satisfy this directive... + llvm::SmallString<256> Buf; + auto NotFoundRelativeTo = [&](const DirectoryEntry *DE) { + Buf = DE->getName(); + llvm::sys::path::append(Buf, FileName); + llvm::sys::path::remove_dots(Buf, /*remove_dot_dot=*/true); + Out.insert(Buf); + }; + // ...relative to the including file. + if (!IsAngled) { + if (const FileEntry *IncludingFile = + SM.getFileEntryForID(SM.getFileID(IncludeTok.getLocation()))) + if (IncludingFile->getDir()) + NotFoundRelativeTo(IncludingFile->getDir()); + } + // ...relative to the search paths. + for (const auto &Dir : llvm::make_range( + IsAngled ? Search.angled_dir_begin() : Search.search_dir_begin(), + Search.search_dir_end())) { + // No support for frameworks or header maps yet. + if (Dir.isNormalDir()) + NotFoundRelativeTo(Dir.getDir()); + } + } +}; + /// Keeps a track of files to be deleted in destructor. class TemporaryFiles { public: @@ -188,6 +255,10 @@ public: Action.setEmittedPreamblePCH(getWriter()); } + bool shouldSkipFunctionBody(Decl *D) override { + return Action.Callbacks.shouldSkipFunctionBody(D); + } + private: PrecompilePreambleAction &Action; std::unique_ptr<raw_ostream> Out; @@ -227,7 +298,7 @@ template <class T> bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) { } // namespace PreambleBounds clang::ComputePreambleBounds(const LangOptions &LangOpts, - llvm::MemoryBuffer *Buffer, + const llvm::MemoryBuffer *Buffer, unsigned MaxLines) { return Lexer::ComputePreamble(Buffer->getBuffer(), LangOpts, MaxLines); } @@ -269,8 +340,9 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build( // Tell the compiler invocation to generate a temporary precompiled header. FrontendOpts.ProgramAction = frontend::GeneratePCH; - FrontendOpts.OutputFile = StoreInMemory ? getInMemoryPreamblePath() - : Storage.asFile().getFilePath(); + FrontendOpts.OutputFile = + std::string(StoreInMemory ? getInMemoryPreamblePath() + : Storage.asFile().getFilePath()); PreprocessorOpts.PrecompiledPreambleBytes.first = 0; PreprocessorOpts.PrecompiledPreambleBytes.second = false; // Inform preprocessor to record conditional stack when building the preamble. @@ -351,6 +423,11 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build( Clang->getPreprocessor().addPPCallbacks(std::move(DelegatedPPCallbacks)); if (auto CommentHandler = Callbacks.getCommentHandler()) Clang->getPreprocessor().addCommentHandler(CommentHandler); + llvm::StringSet<> MissingFiles; + Clang->getPreprocessor().addPPCallbacks( + std::make_unique<MissingFileCollector>( + MissingFiles, Clang->getPreprocessor().getHeaderSearchInfo(), + Clang->getSourceManager())); if (llvm::Error Err = Act->Execute()) return errorToErrorCode(std::move(Err)); @@ -385,9 +462,9 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build( } } - return PrecompiledPreamble(std::move(Storage), std::move(PreambleBytes), - PreambleEndsAtStartOfLine, - std::move(FilesInPreamble)); + return PrecompiledPreamble( + std::move(Storage), std::move(PreambleBytes), PreambleEndsAtStartOfLine, + std::move(FilesInPreamble), std::move(MissingFiles)); } PreambleBounds PrecompiledPreamble::getBounds() const { @@ -444,6 +521,7 @@ bool PrecompiledPreamble::CanReuse(const CompilerInvocation &Invocation, // First, make a record of those files that have been overridden via // remapping or unsaved_files. std::map<llvm::sys::fs::UniqueID, PreambleFileHash> OverriddenFiles; + llvm::StringSet<> OverriddenAbsPaths; // Either by buffers or files. for (const auto &R : PreprocessorOpts.RemappedFiles) { llvm::vfs::Status Status; if (!moveOnNoError(VFS->status(R.second), Status)) { @@ -451,6 +529,10 @@ bool PrecompiledPreamble::CanReuse(const CompilerInvocation &Invocation, // horrible happened. return false; } + // If a mapped file was previously missing, then it has changed. + llvm::SmallString<128> MappedPath(R.first); + if (!VFS->makeAbsolute(MappedPath)) + OverriddenAbsPaths.insert(MappedPath); OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForFile( Status.getSize(), llvm::sys::toTimeT(Status.getLastModificationTime())); @@ -466,6 +548,10 @@ bool PrecompiledPreamble::CanReuse(const CompilerInvocation &Invocation, OverriddenFiles[Status.getUniqueID()] = PreambleHash; else OverridenFileBuffers[RB.first] = PreambleHash; + + llvm::SmallString<128> MappedPath(RB.first); + if (!VFS->makeAbsolute(MappedPath)) + OverriddenAbsPaths.insert(MappedPath); } // Check whether anything has changed. @@ -503,6 +589,17 @@ bool PrecompiledPreamble::CanReuse(const CompilerInvocation &Invocation, F.second.ModTime) return false; } + for (const auto &F : MissingFiles) { + // A missing file may be "provided" by an override buffer or file. + if (OverriddenAbsPaths.count(F.getKey())) + return false; + // If a file previously recorded as missing exists as a regular file, then + // consider the preamble out-of-date. + if (auto Status = VFS->status(F.getKey())) { + if (Status->isRegularFile()) + return false; + } + } return true; } @@ -523,8 +620,10 @@ void PrecompiledPreamble::OverridePreamble( PrecompiledPreamble::PrecompiledPreamble( PCHStorage Storage, std::vector<char> PreambleBytes, bool PreambleEndsAtStartOfLine, - llvm::StringMap<PreambleFileHash> FilesInPreamble) + llvm::StringMap<PreambleFileHash> FilesInPreamble, + llvm::StringSet<> MissingFiles) : Storage(std::move(Storage)), FilesInPreamble(std::move(FilesInPreamble)), + MissingFiles(std::move(MissingFiles)), PreambleBytes(std::move(PreambleBytes)), PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) { assert(this->Storage.getKind() != PCHStorage::Kind::Empty); @@ -548,7 +647,7 @@ PrecompiledPreamble::TempPCHFile::CreateNewPreamblePCHFile() { return EC; // We only needed to make sure the file exists, close the file right away. llvm::sys::Process::SafelyCloseFileDescriptor(FD); - return TempPCHFile(std::move(File).str()); + return TempPCHFile(std::string(std::move(File).str())); } PrecompiledPreamble::TempPCHFile::TempPCHFile(std::string FilePath) @@ -715,7 +814,7 @@ void PrecompiledPreamble::setupPreambleStorage( IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS) { if (Storage.getKind() == PCHStorage::Kind::TempFile) { const TempPCHFile &PCHFile = Storage.asFile(); - PreprocessorOpts.ImplicitPCHInclude = PCHFile.getFilePath(); + PreprocessorOpts.ImplicitPCHInclude = std::string(PCHFile.getFilePath()); // Make sure we can access the PCH file even if we're using a VFS IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS = @@ -739,7 +838,7 @@ void PrecompiledPreamble::setupPreambleStorage( // For in-memory preamble, we have to provide a VFS overlay that makes it // accessible. StringRef PCHPath = getInMemoryPreamblePath(); - PreprocessorOpts.ImplicitPCHInclude = PCHPath; + PreprocessorOpts.ImplicitPCHInclude = std::string(PCHPath); auto Buf = llvm::MemoryBuffer::getMemBuffer(Storage.asMemory().Data); VFS = createVFSOverlayForPreamblePCH(PCHPath, std::move(Buf), VFS); diff --git a/clang/lib/Frontend/Rewrite/FixItRewriter.cpp b/clang/lib/Frontend/Rewrite/FixItRewriter.cpp index 0217b3385a51..4fe64b96cb15 100644 --- a/clang/lib/Frontend/Rewrite/FixItRewriter.cpp +++ b/clang/lib/Frontend/Rewrite/FixItRewriter.cpp @@ -95,7 +95,8 @@ bool FixItRewriter::WriteFixedFiles( for (iterator I = buffer_begin(), E = buffer_end(); I != E; ++I) { const FileEntry *Entry = Rewrite.getSourceMgr().getFileEntryForID(I->first); int fd; - std::string Filename = FixItOpts->RewriteFilename(Entry->getName(), fd); + std::string Filename = + FixItOpts->RewriteFilename(std::string(Entry->getName()), fd); std::error_code EC; std::unique_ptr<llvm::raw_fd_ostream> OS; if (fd != -1) { @@ -113,7 +114,8 @@ bool FixItRewriter::WriteFixedFiles( OS->flush(); if (RewrittenFiles) - RewrittenFiles->push_back(std::make_pair(Entry->getName(), Filename)); + RewrittenFiles->push_back( + std::make_pair(std::string(Entry->getName()), Filename)); } return false; diff --git a/clang/lib/Frontend/Rewrite/FrontendActions.cpp b/clang/lib/Frontend/Rewrite/FrontendActions.cpp index aaffbde3309b..5351ff0593ed 100644 --- a/clang/lib/Frontend/Rewrite/FrontendActions.cpp +++ b/clang/lib/Frontend/Rewrite/FrontendActions.cpp @@ -77,7 +77,7 @@ public: SmallString<128> Path(Filename); llvm::sys::path::replace_extension(Path, NewSuffix + llvm::sys::path::extension(Path)); - return Path.str(); + return std::string(Path.str()); } }; @@ -88,7 +88,7 @@ public: llvm::sys::fs::createTemporaryFile(llvm::sys::path::filename(Filename), llvm::sys::path::extension(Filename).drop_front(), fd, Path); - return Path.str(); + return std::string(Path.str()); } }; } // end anonymous namespace @@ -166,11 +166,11 @@ RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { CI.createDefaultOutputFile(false, InFile, "cpp")) { if (CI.getLangOpts().ObjCRuntime.isNonFragile()) return CreateModernObjCRewriter( - InFile, std::move(OS), CI.getDiagnostics(), CI.getLangOpts(), - CI.getDiagnosticOpts().NoRewriteMacros, + std::string(InFile), std::move(OS), CI.getDiagnostics(), + CI.getLangOpts(), CI.getDiagnosticOpts().NoRewriteMacros, (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo)); - return CreateObjCRewriter(InFile, std::move(OS), CI.getDiagnostics(), - CI.getLangOpts(), + return CreateObjCRewriter(std::string(InFile), std::move(OS), + CI.getDiagnostics(), CI.getLangOpts(), CI.getDiagnosticOpts().NoRewriteMacros); } return nullptr; diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index 831f95e8c6be..e122b10e76d3 100644 --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -860,7 +860,7 @@ RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) { // ivar in class extensions requires special treatment. if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) CDecl = CatDecl->getClassInterface(); - std::string RecName = CDecl->getName(); + std::string RecName = std::string(CDecl->getName()); RecName += "_IMPL"; RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, SourceLocation(), @@ -941,9 +941,10 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, unsigned Attributes = PD->getPropertyAttributes(); if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) { - bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) && - (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | - ObjCPropertyDecl::OBJC_PR_copy)); + bool GenGetProperty = + !(Attributes & ObjCPropertyAttribute::kind_nonatomic) && + (Attributes & (ObjCPropertyAttribute::kind_retain | + ObjCPropertyAttribute::kind_copy)); std::string Getr; if (GenGetProperty && !objcGetPropertyDefined) { objcGetPropertyDefined = true; @@ -1002,8 +1003,8 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, // Generate the 'setter' function. std::string Setr; - bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | - ObjCPropertyDecl::OBJC_PR_copy); + bool GenSetProperty = Attributes & (ObjCPropertyAttribute::kind_retain | + ObjCPropertyAttribute::kind_copy); if (GenSetProperty && !objcSetPropertyDefined) { objcSetPropertyDefined = true; // FIXME. Is this attribute correct in all cases? @@ -1022,11 +1023,11 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, Setr += ", (id)"; Setr += PD->getName(); Setr += ", "; - if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) + if (Attributes & ObjCPropertyAttribute::kind_nonatomic) Setr += "0, "; else Setr += "1, "; - if (Attributes & ObjCPropertyDecl::OBJC_PR_copy) + if (Attributes & ObjCPropertyAttribute::kind_copy) Setr += "1)"; else Setr += "0)"; @@ -2586,9 +2587,10 @@ Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { strType, nullptr, SC_Static); DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, NewVD, false, strType, VK_LValue, SourceLocation()); - Expr *Unop = new (Context) - UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), - VK_RValue, OK_Ordinary, SourceLocation(), false); + Expr *Unop = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), DRE, UO_AddrOf, + Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); // cast to NSConstantString * CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), CK_CPointerToObjCPointerCast, Unop); @@ -2688,7 +2690,7 @@ Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) { // Don't forget the parens to enforce the proper binding. ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); - const FunctionType *FT = msgSendType->getAs<FunctionType>(); + auto *FT = msgSendType->castAs<FunctionType>(); CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc); ReplaceStmt(Exp, CE); @@ -3282,10 +3284,10 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // we need the cast below. For example: // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) // - SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), - VK_RValue, OK_Ordinary, - SourceLocation(), false); + SuperRep = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -3300,10 +3302,10 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, superType, VK_LValue, ILE, false); // struct __rw_objc_super * - SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), - VK_RValue, OK_Ordinary, - SourceLocation(), false); + SuperRep = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); } MsgExprs.push_back(SuperRep); break; @@ -3377,10 +3379,10 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // we need the cast below. For example: // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) // - SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), - VK_RValue, OK_Ordinary, - SourceLocation(), false); + SuperRep = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -4442,7 +4444,7 @@ void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { static void BuildUniqueMethodName(std::string &Name, ObjCMethodDecl *MD) { ObjCInterfaceDecl *IFace = MD->getClassInterface(); - Name = IFace->getName(); + Name = std::string(IFace->getName()); Name += "__" + MD->getSelector().getAsString(); // Convert colons to underscores. std::string::size_type loc = 0; @@ -4704,9 +4706,9 @@ Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { if (VarDecl *Var = dyn_cast<VarDecl>(VD)) if (!ImportedLocalExternalDecls.count(Var)) return DRE; - Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), - VK_LValue, OK_Ordinary, - DRE->getLocation(), false); + Expr *Exp = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), DRE, UO_Deref, DRE->getType(), + VK_LValue, OK_Ordinary, DRE->getLocation(), false, FPOptionsOverride()); // Need parens to enforce precedence. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), Exp); @@ -5292,11 +5294,12 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, VarDecl *NewVD = VarDecl::Create( *Context, TUDecl, SourceLocation(), SourceLocation(), &Context->Idents.get(DescData), Context->VoidPtrTy, nullptr, SC_Static); - UnaryOperator *DescRefExpr = new (Context) UnaryOperator( + UnaryOperator *DescRefExpr = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy, VK_LValue, SourceLocation()), UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue, - OK_Ordinary, SourceLocation(), false); + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); InitExprs.push_back(DescRefExpr); // Add initializers for any closure decl refs. @@ -5313,9 +5316,9 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, - OK_Ordinary, SourceLocation(), - false); + Exp = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); } } else if (isTopLevelBlockPointerType((*I)->getType())) { FD = SynthBlockInitFunctionDecl((*I)->getName()); @@ -5330,9 +5333,9 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, - OK_Ordinary, SourceLocation(), - false); + Exp = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); } } @@ -5370,10 +5373,10 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, // captured nested byref variable has its address passed. Do not take // its address again. if (!isNestedCapturedVar) - Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, - Context->getPointerType(Exp->getType()), - VK_RValue, OK_Ordinary, SourceLocation(), - false); + Exp = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), Exp, UO_AddrOf, + Context->getPointerType(Exp->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); InitExprs.push_back(Exp); } @@ -5397,9 +5400,10 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, NewRep = DRE; } - NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, - Context->getPointerType(NewRep->getType()), - VK_RValue, OK_Ordinary, SourceLocation(), false); + NewRep = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), NewRep, UO_AddrOf, + Context->getPointerType(NewRep->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); // Put Paren around the call. @@ -7484,10 +7488,10 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, NewVD, false, Context->UnsignedLongTy, VK_LValue, SourceLocation()); - BinaryOperator *addExpr = - new (Context) BinaryOperator(castExpr, DRE, BO_Add, - Context->getPointerType(Context->CharTy), - VK_RValue, OK_Ordinary, SourceLocation(), FPOptions()); + BinaryOperator *addExpr = BinaryOperator::Create( + *Context, castExpr, DRE, BO_Add, + Context->getPointerType(Context->CharTy), VK_RValue, OK_Ordinary, + SourceLocation(), FPOptionsOverride()); // Don't forget the parens to enforce the proper binding. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), @@ -7501,12 +7505,11 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { RD = RD->getDefinition(); if (RD && !RD->getDeclName().getAsIdentifierInfo()) { // decltype(((Foo_IMPL*)0)->bar) * - ObjCContainerDecl *CDecl = - dyn_cast<ObjCContainerDecl>(D->getDeclContext()); + auto *CDecl = cast<ObjCContainerDecl>(D->getDeclContext()); // ivar in class extensions requires special treatment. if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) CDecl = CatDecl->getClassInterface(); - std::string RecName = CDecl->getName(); + std::string RecName = std::string(CDecl->getName()); RecName += "_IMPL"; RecordDecl *RD = RecordDecl::Create( *Context, TTK_Struct, TUDecl, SourceLocation(), SourceLocation(), @@ -7539,10 +7542,9 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { CK_BitCast, PE); - - Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT, - VK_LValue, OK_Ordinary, - SourceLocation(), false); + Expr *Exp = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), castExpr, UO_Deref, IvarT, + VK_LValue, OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); PE = new (Context) ParenExpr(OldRange.getBegin(), OldRange.getEnd(), Exp); diff --git a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp index 0cb7592b9982..3f320dc57aa6 100644 --- a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp @@ -789,9 +789,10 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, unsigned Attributes = PD->getPropertyAttributes(); if (PID->getGetterMethodDecl() && !PID->getGetterMethodDecl()->isDefined()) { - bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) && - (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | - ObjCPropertyDecl::OBJC_PR_copy)); + bool GenGetProperty = + !(Attributes & ObjCPropertyAttribute::kind_nonatomic) && + (Attributes & (ObjCPropertyAttribute::kind_retain | + ObjCPropertyAttribute::kind_copy)); std::string Getr; if (GenGetProperty && !objcGetPropertyDefined) { objcGetPropertyDefined = true; @@ -850,8 +851,8 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, // Generate the 'setter' function. std::string Setr; - bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | - ObjCPropertyDecl::OBJC_PR_copy); + bool GenSetProperty = Attributes & (ObjCPropertyAttribute::kind_retain | + ObjCPropertyAttribute::kind_copy); if (GenSetProperty && !objcSetPropertyDefined) { objcSetPropertyDefined = true; // FIXME. Is this attribute correct in all cases? @@ -870,11 +871,11 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, Setr += ", (id)"; Setr += PD->getName(); Setr += ", "; - if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) + if (Attributes & ObjCPropertyAttribute::kind_nonatomic) Setr += "0, "; else Setr += "1, "; - if (Attributes & ObjCPropertyDecl::OBJC_PR_copy) + if (Attributes & ObjCPropertyAttribute::kind_copy) Setr += "1)"; else Setr += "0)"; @@ -2513,9 +2514,10 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { strType, nullptr, SC_Static); DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, NewVD, false, strType, VK_LValue, SourceLocation()); - Expr *Unop = new (Context) - UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), - VK_RValue, OK_Ordinary, SourceLocation(), false); + Expr *Unop = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), DRE, UO_AddrOf, + Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); // cast to NSConstantString * CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), CK_CPointerToObjCPointerCast, Unop); @@ -2713,10 +2715,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // we need the cast below. For example: // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) // - SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), - VK_RValue, OK_Ordinary, - SourceLocation(), false); + SuperRep = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -2731,10 +2733,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, superType, VK_LValue, ILE, false); // struct objc_super * - SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), - VK_RValue, OK_Ordinary, - SourceLocation(), false); + SuperRep = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); } MsgExprs.push_back(SuperRep); break; @@ -2808,10 +2810,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // we need the cast below. For example: // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) // - SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), - VK_RValue, OK_Ordinary, - SourceLocation(), false); + SuperRep = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -2995,10 +2997,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, llvm::APInt(IntSize, 8), Context->IntTy, SourceLocation()); - BinaryOperator *lessThanExpr = - new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy, - VK_RValue, OK_Ordinary, SourceLocation(), - FPOptions()); + BinaryOperator *lessThanExpr = BinaryOperator::Create( + *Context, sizeofExpr, limit, BO_LE, Context->IntTy, VK_RValue, + OK_Ordinary, SourceLocation(), FPOptionsOverride()); // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) ConditionalOperator *CondExpr = new (Context) ConditionalOperator(lessThanExpr, @@ -3048,9 +3049,10 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { nullptr, SC_Extern); DeclRefExpr *DRE = new (Context) DeclRefExpr( *Context, VD, false, getProtocolType(), VK_LValue, SourceLocation()); - Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, - Context->getPointerType(DRE->getType()), - VK_RValue, OK_Ordinary, SourceLocation(), false); + Expr *DerefExpr = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), DRE, UO_AddrOf, + Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), CK_BitCast, DerefExpr); @@ -3631,7 +3633,7 @@ void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { static void BuildUniqueMethodName(std::string &Name, ObjCMethodDecl *MD) { ObjCInterfaceDecl *IFace = MD->getClassInterface(); - Name = IFace->getName(); + Name = std::string(IFace->getName()); Name += "__" + MD->getSelector().getAsString(); // Convert colons to underscores. std::string::size_type loc = 0; @@ -3875,9 +3877,9 @@ Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { if (VarDecl *Var = dyn_cast<VarDecl>(VD)) if (!ImportedLocalExternalDecls.count(Var)) return DRE; - Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), - VK_LValue, OK_Ordinary, - DRE->getLocation(), false); + Expr *Exp = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), DRE, UO_Deref, DRE->getType(), + VK_LValue, OK_Ordinary, DRE->getLocation(), false, FPOptionsOverride()); // Need parens to enforce precedence. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), Exp); @@ -4432,11 +4434,12 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, VarDecl *NewVD = VarDecl::Create( *Context, TUDecl, SourceLocation(), SourceLocation(), &Context->Idents.get(DescData), Context->VoidPtrTy, nullptr, SC_Static); - UnaryOperator *DescRefExpr = new (Context) UnaryOperator( + UnaryOperator *DescRefExpr = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy, VK_LValue, SourceLocation()), UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue, - OK_Ordinary, SourceLocation(), false); + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); InitExprs.push_back(DescRefExpr); // Add initializers for any closure decl refs. @@ -4453,9 +4456,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, - OK_Ordinary, SourceLocation(), - false); + Exp = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); } } else if (isTopLevelBlockPointerType((*I)->getType())) { FD = SynthBlockInitFunctionDecl((*I)->getName()); @@ -4470,9 +4473,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, - OK_Ordinary, SourceLocation(), - false); + Exp = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); } } InitExprs.push_back(Exp); @@ -4509,9 +4512,10 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, // captured nested byref variable has its address passed. Do not take // its address again. if (!isNestedCapturedVar) - Exp = new (Context) UnaryOperator( - Exp, UO_AddrOf, Context->getPointerType(Exp->getType()), VK_RValue, - OK_Ordinary, SourceLocation(), false); + Exp = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), Exp, UO_AddrOf, + Context->getPointerType(Exp->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); InitExprs.push_back(Exp); } @@ -4527,9 +4531,10 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, } NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue, SourceLocation()); - NewRep = new (Context) UnaryOperator( - NewRep, UO_AddrOf, Context->getPointerType(NewRep->getType()), VK_RValue, - OK_Ordinary, SourceLocation(), false); + NewRep = UnaryOperator::Create( + const_cast<ASTContext &>(*Context), NewRep, UO_AddrOf, + Context->getPointerType(NewRep->getType()), VK_RValue, OK_Ordinary, + SourceLocation(), false, FPOptionsOverride()); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); BlockDeclRefs.clear(); @@ -5819,7 +5824,8 @@ Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); // Synthesize an explicit cast to gain access to the ivar. - std::string RecName = clsDeclared->getIdentifier()->getName(); + std::string RecName = + std::string(clsDeclared->getIdentifier()->getName()); RecName += "_IMPL"; IdentifierInfo *II = &Context->Idents.get(RecName); RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, @@ -5859,7 +5865,8 @@ Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); // Synthesize an explicit cast to gain access to the ivar. - std::string RecName = clsDeclared->getIdentifier()->getName(); + std::string RecName = + std::string(clsDeclared->getIdentifier()->getName()); RecName += "_IMPL"; IdentifierInfo *II = &Context->Idents.get(RecName); RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, diff --git a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp index 8042b52ddc03..462aeda6e027 100644 --- a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -22,6 +22,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Bitstream/BitCodes.h" #include "llvm/Bitstream/BitstreamReader.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" #include <utility> @@ -238,6 +239,9 @@ private: /// generated from child processes. bool MergeChildRecords; + /// Whether we've started finishing and tearing down this instance. + bool IsFinishing = false; + /// State that is shared among the various clones of this diagnostic /// consumer. struct SharedState { @@ -567,6 +571,17 @@ unsigned SDiagsWriter::getEmitDiagnosticFlag(StringRef FlagName) { void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) { + assert(!IsFinishing && + "Received a diagnostic after we've already started teardown."); + if (IsFinishing) { + SmallString<256> diagnostic; + Info.FormatDiagnostic(diagnostic); + getMetaDiags()->Report( + diag::warn_fe_serialized_diag_failure_during_finalisation) + << diagnostic; + return; + } + // Enter the block for a non-note diagnostic immediately, rather than waiting // for beginDiagnostic, in case associated notes are emitted before we get // there. @@ -760,6 +775,9 @@ void SDiagsWriter::RemoveOldDiagnostics() { } void SDiagsWriter::finish() { + assert(!IsFinishing); + IsFinishing = true; + // The original instance is responsible for writing the file. if (!OriginalInstance) return; @@ -785,12 +803,20 @@ void SDiagsWriter::finish() { if (EC) { getMetaDiags()->Report(diag::warn_fe_serialized_diag_failure) << State->OutputFile << EC.message(); + OS->clear_error(); return; } // Write the generated bitstream to "Out". OS->write((char *)&State->Buffer.front(), State->Buffer.size()); OS->flush(); + + assert(!OS->has_error()); + if (OS->has_error()) { + getMetaDiags()->Report(diag::warn_fe_serialized_diag_failure) + << State->OutputFile << OS->error().message(); + OS->clear_error(); + } } std::error_code SDiagsMerger::visitStartOfDiagnostic() { diff --git a/clang/lib/Frontend/TextDiagnosticBuffer.cpp b/clang/lib/Frontend/TextDiagnosticBuffer.cpp index b2497f56cbcd..90f273e65f88 100644 --- a/clang/lib/Frontend/TextDiagnosticBuffer.cpp +++ b/clang/lib/Frontend/TextDiagnosticBuffer.cpp @@ -32,20 +32,20 @@ void TextDiagnosticBuffer::HandleDiagnostic(DiagnosticsEngine::Level Level, "Diagnostic not handled during diagnostic buffering!"); case DiagnosticsEngine::Note: All.emplace_back(Level, Notes.size()); - Notes.emplace_back(Info.getLocation(), Buf.str()); + Notes.emplace_back(Info.getLocation(), std::string(Buf.str())); break; case DiagnosticsEngine::Warning: All.emplace_back(Level, Warnings.size()); - Warnings.emplace_back(Info.getLocation(), Buf.str()); + Warnings.emplace_back(Info.getLocation(), std::string(Buf.str())); break; case DiagnosticsEngine::Remark: All.emplace_back(Level, Remarks.size()); - Remarks.emplace_back(Info.getLocation(), Buf.str()); + Remarks.emplace_back(Info.getLocation(), std::string(Buf.str())); break; case DiagnosticsEngine::Error: case DiagnosticsEngine::Fatal: All.emplace_back(Level, Errors.size()); - Errors.emplace_back(Info.getLocation(), Buf.str()); + Errors.emplace_back(Info.getLocation(), std::string(Buf.str())); break; } } diff --git a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp index 82c2af87706e..56e05242f7c9 100644 --- a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -89,9 +89,10 @@ namespace { class StandardDirective : public Directive { public: StandardDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc, - bool MatchAnyLine, StringRef Text, unsigned Min, - unsigned Max) - : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max) {} + bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text, + unsigned Min, unsigned Max) + : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFileAndLine, + MatchAnyLine, Text, Min, Max) {} bool isValid(std::string &Error) override { // all strings are considered valid; even empty ones @@ -107,9 +108,10 @@ public: class RegexDirective : public Directive { public: RegexDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc, - bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max, - StringRef RegexStr) - : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max), + bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text, + unsigned Min, unsigned Max, StringRef RegexStr) + : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFileAndLine, + MatchAnyLine, Text, Min, Max), Regex(RegexStr) {} bool isValid(std::string &Error) override { @@ -294,11 +296,13 @@ struct UnattachedDirective { // Attach the specified directive to the line of code indicated by // \p ExpectedLoc. void attachDirective(DiagnosticsEngine &Diags, const UnattachedDirective &UD, - SourceLocation ExpectedLoc, bool MatchAnyLine = false) { + SourceLocation ExpectedLoc, + bool MatchAnyFileAndLine = false, + bool MatchAnyLine = false) { // Construct new directive. - std::unique_ptr<Directive> D = - Directive::create(UD.RegexKind, UD.DirectivePos, ExpectedLoc, - MatchAnyLine, UD.Text, UD.Min, UD.Max); + std::unique_ptr<Directive> D = Directive::create( + UD.RegexKind, UD.DirectivePos, ExpectedLoc, MatchAnyFileAndLine, + MatchAnyLine, UD.Text, UD.Min, UD.Max); std::string Error; if (!D->isValid(Error)) { @@ -498,6 +502,7 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, // Next optional token: @ SourceLocation ExpectedLoc; StringRef Marker; + bool MatchAnyFileAndLine = false; bool MatchAnyLine = false; if (!PH.Next("@")) { ExpectedLoc = Pos; @@ -526,26 +531,39 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, StringRef Filename(PH.C, PH.P-PH.C); PH.Advance(); - // Lookup file via Preprocessor, like a #include. - const DirectoryLookup *CurDir; - Optional<FileEntryRef> File = - PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir, - nullptr, nullptr, nullptr, nullptr, nullptr); - if (!File) { - Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin), - diag::err_verify_missing_file) << Filename << KindStr; - continue; - } - - const FileEntry *FE = &File->getFileEntry(); - if (SM.translateFile(FE).isInvalid()) - SM.createFileID(FE, Pos, SrcMgr::C_User); - - if (PH.Next(Line) && Line > 0) - ExpectedLoc = SM.translateFileLineCol(FE, Line, 1); - else if (PH.Next("*")) { + if (Filename == "*") { + MatchAnyFileAndLine = true; + if (!PH.Next("*")) { + Diags.Report(Pos.getLocWithOffset(PH.C - PH.Begin), + diag::err_verify_missing_line) + << "'*'"; + continue; + } MatchAnyLine = true; - ExpectedLoc = SM.translateFileLineCol(FE, 1, 1); + ExpectedLoc = SourceLocation(); + } else { + // Lookup file via Preprocessor, like a #include. + const DirectoryLookup *CurDir; + Optional<FileEntryRef> File = + PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir, + nullptr, nullptr, nullptr, nullptr, nullptr); + if (!File) { + Diags.Report(Pos.getLocWithOffset(PH.C - PH.Begin), + diag::err_verify_missing_file) + << Filename << KindStr; + continue; + } + + const FileEntry *FE = &File->getFileEntry(); + if (SM.translateFile(FE).isInvalid()) + SM.createFileID(FE, Pos, SrcMgr::C_User); + + if (PH.Next(Line) && Line > 0) + ExpectedLoc = SM.translateFileLineCol(FE, Line, 1); + else if (PH.Next("*")) { + MatchAnyLine = true; + ExpectedLoc = SM.translateFileLineCol(FE, 1, 1); + } } } else if (PH.Next("*")) { MatchAnyLine = true; @@ -631,7 +649,7 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, } if (Marker.empty()) - attachDirective(Diags, D, ExpectedLoc, MatchAnyLine); + attachDirective(Diags, D, ExpectedLoc, MatchAnyFileAndLine, MatchAnyLine); else Markers.addDirective(Marker, D); FoundDirective = true; @@ -877,7 +895,7 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags, SmallString<256> Fmt; llvm::raw_svector_ostream OS(Fmt); for (const auto *D : DL) { - if (D->DiagnosticLoc.isInvalid()) + if (D->DiagnosticLoc.isInvalid() || D->MatchAnyFileAndLine) OS << "\n File *"; else OS << "\n File " << SourceMgr.getFilename(D->DiagnosticLoc); @@ -937,7 +955,7 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr, continue; } - if (!D.DiagnosticLoc.isInvalid() && + if (!D.DiagnosticLoc.isInvalid() && !D.MatchAnyFileAndLine && !IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first)) continue; @@ -1114,11 +1132,13 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() { std::unique_ptr<Directive> Directive::create(bool RegexKind, SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc, + bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max) { if (!RegexKind) return std::make_unique<StandardDirective>(DirectiveLoc, DiagnosticLoc, - MatchAnyLine, Text, Min, Max); + MatchAnyFileAndLine, + MatchAnyLine, Text, Min, Max); // Parse the directive into a regular expression. std::string RegexStr; @@ -1143,6 +1163,7 @@ std::unique_ptr<Directive> Directive::create(bool RegexKind, } } - return std::make_unique<RegexDirective>( - DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max, RegexStr); + return std::make_unique<RegexDirective>(DirectiveLoc, DiagnosticLoc, + MatchAnyFileAndLine, MatchAnyLine, + Text, Min, Max, RegexStr); } |