diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 |
commit | 2b6b257f4e5503a7a2675bdb8735693db769f75c (patch) | |
tree | e85e046ae7003fe3bcc8b5454cd0fa3f7407b470 /lib/Frontend | |
parent | b4348ed0b7e90c0831b925fbee00b5f179a99796 (diff) |
Notes
Diffstat (limited to 'lib/Frontend')
31 files changed, 1226 insertions, 959 deletions
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp index 52776b6a84837..de72ea57e35b7 100644 --- a/lib/Frontend/ASTConsumers.cpp +++ b/lib/Frontend/ASTConsumers.cpp @@ -35,9 +35,9 @@ namespace { typedef RecursiveASTVisitor<ASTPrinter> base; public: - ASTPrinter(raw_ostream *Out = nullptr, bool Dump = false, + ASTPrinter(std::unique_ptr<raw_ostream> Out = nullptr, bool Dump = false, StringRef FilterString = "", bool DumpLookups = false) - : Out(Out ? *Out : llvm::outs()), Dump(Dump), + : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)), Dump(Dump), FilterString(FilterString), DumpLookups(DumpLookups) {} void HandleTranslationUnit(ASTContext &Context) override { @@ -94,6 +94,7 @@ namespace { } raw_ostream &Out; + std::unique_ptr<raw_ostream> OwnedOut; bool Dump; std::string FilterString; bool DumpLookups; @@ -122,9 +123,11 @@ namespace { }; } // end anonymous namespace -std::unique_ptr<ASTConsumer> clang::CreateASTPrinter(raw_ostream *Out, - StringRef FilterString) { - return llvm::make_unique<ASTPrinter>(Out, /*Dump=*/false, FilterString); +std::unique_ptr<ASTConsumer> +clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out, + StringRef FilterString) { + return llvm::make_unique<ASTPrinter>(std::move(Out), /*Dump=*/false, + FilterString); } std::unique_ptr<ASTConsumer> clang::CreateASTDumper(StringRef FilterString, @@ -268,7 +271,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC, // Print the parameters. Out << "("; bool PrintComma = false; - for (auto I : FD->params()) { + for (auto I : FD->parameters()) { if (PrintComma) Out << ", "; else @@ -290,13 +293,12 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC, // Print the parameters. Out << "("; bool PrintComma = false; - for (FunctionDecl::param_const_iterator I = D->param_begin(), - E = D->param_end(); I != E; ++I) { + for (ParmVarDecl *Parameter : D->parameters()) { if (PrintComma) Out << ", "; else PrintComma = true; - Out << **I; + Out << *Parameter; } Out << ")"; @@ -320,13 +322,12 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC, // Print the parameters. Out << "("; bool PrintComma = false; - for (FunctionDecl::param_const_iterator I = D->param_begin(), - E = D->param_end(); I != E; ++I) { + for (ParmVarDecl *Parameter : D->parameters()) { if (PrintComma) Out << ", "; else PrintComma = true; - Out << **I; + Out << *Parameter; } Out << ")"; diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp index b499fa2b0e68b..51064da270cc9 100644 --- a/lib/Frontend/ASTMerge.cpp +++ b/lib/Frontend/ASTMerge.cpp @@ -83,14 +83,13 @@ void ASTMergeAction::EndSourceFileAction() { return AdaptedAction->EndSourceFileAction(); } -ASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction, +ASTMergeAction::ASTMergeAction(std::unique_ptr<FrontendAction> adaptedAction, ArrayRef<std::string> ASTFiles) - : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles.begin(), ASTFiles.end()) { +: AdaptedAction(std::move(adaptedAction)), ASTFiles(ASTFiles.begin(), ASTFiles.end()) { assert(AdaptedAction && "ASTMergeAction needs an action to adapt"); } ASTMergeAction::~ASTMergeAction() { - delete AdaptedAction; } bool ASTMergeAction::usesPreprocessorOnly() const { diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index e6ba29201f857..76fd00a132b47 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -920,17 +920,17 @@ class PrecompilePreambleConsumer : public PCHGenerator { unsigned &Hash; std::vector<Decl *> TopLevelDecls; PrecompilePreambleAction *Action; - raw_ostream *Out; + std::unique_ptr<raw_ostream> Out; public: PrecompilePreambleConsumer(ASTUnit &Unit, PrecompilePreambleAction *Action, const Preprocessor &PP, StringRef isysroot, - raw_ostream *Out) + std::unique_ptr<raw_ostream> Out) : PCHGenerator(PP, "", nullptr, isysroot, std::make_shared<PCHBuffer>(), ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>>(), /*AllowASTWithErrors=*/true), Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action), - Out(Out) { + Out(std::move(Out)) { Hash = 0; } @@ -982,8 +982,9 @@ PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::string Sysroot; std::string OutputFile; - raw_ostream *OS = GeneratePCHAction::ComputeASTConsumerArguments( - CI, InFile, Sysroot, OutputFile); + std::unique_ptr<raw_ostream> OS = + GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot, + OutputFile); if (!OS) return nullptr; @@ -994,7 +995,7 @@ PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI, llvm::make_unique<MacroDefinitionTrackerPPCallbacks>( Unit.getCurrentTopLevelHashValue())); return llvm::make_unique<PrecompilePreambleConsumer>( - Unit, this, CI.getPreprocessor(), Sysroot, OS); + Unit, this, CI.getPreprocessor(), Sysroot, std::move(OS)); } static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) { @@ -1040,7 +1041,7 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, // Create the compiler instance to use for building the AST. std::unique_ptr<CompilerInstance> Clang( - new CompilerInstance(PCHContainerOps)); + new CompilerInstance(std::move(PCHContainerOps))); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -1138,11 +1139,9 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) goto error; - if (SavedMainFileBuffer) { - std::string ModName = getPreambleFile(this); + if (SavedMainFileBuffer) TranslateStoredDiagnostics(getFileManager(), getSourceManager(), PreambleDiagnostics, StoredDiagnostics); - } if (!Act->Execute()) goto error; @@ -1380,7 +1379,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble( // First, make a record of those files that have been overridden via // remapping or unsaved_files. - llvm::StringMap<PreambleFileHash> OverriddenFiles; + std::map<llvm::sys::fs::UniqueID, PreambleFileHash> OverriddenFiles; for (const auto &R : PreprocessorOpts.RemappedFiles) { if (AnyFileChanged) break; @@ -1393,24 +1392,38 @@ ASTUnit::getMainBufferWithPrecompiledPreamble( break; } - OverriddenFiles[R.first] = PreambleFileHash::createForFile( + OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForFile( Status.getSize(), Status.getLastModificationTime().toEpochTime()); } for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) { if (AnyFileChanged) break; - OverriddenFiles[RB.first] = + + vfs::Status Status; + if (FileMgr->getNoncachedStatValue(RB.first, Status)) { + AnyFileChanged = true; + break; + } + + OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForMemoryBuffer(RB.second); } // Check whether anything has changed. - for (llvm::StringMap<PreambleFileHash>::iterator + for (llvm::StringMap<PreambleFileHash>::iterator F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end(); !AnyFileChanged && F != FEnd; ++F) { - llvm::StringMap<PreambleFileHash>::iterator Overridden - = OverriddenFiles.find(F->first()); + vfs::Status Status; + if (FileMgr->getNoncachedStatValue(F->first(), Status)) { + // If we can't stat the file, assume that something horrible happened. + AnyFileChanged = true; + break; + } + + std::map<llvm::sys::fs::UniqueID, PreambleFileHash>::iterator Overridden + = OverriddenFiles.find(Status.getUniqueID()); if (Overridden != OverriddenFiles.end()) { // This file was remapped; check whether the newly-mapped file // matches up with the previous mapping. @@ -1420,13 +1433,9 @@ ASTUnit::getMainBufferWithPrecompiledPreamble( } // The file was not remapped; check whether it has changed on disk. - vfs::Status Status; - if (FileMgr->getNoncachedStatValue(F->first(), Status)) { - // If we can't stat the file, assume that something horrible happened. - AnyFileChanged = true; - } else if (Status.getSize() != uint64_t(F->second.Size) || - Status.getLastModificationTime().toEpochTime() != - uint64_t(F->second.ModTime)) + if (Status.getSize() != uint64_t(F->second.Size) || + Status.getLastModificationTime().toEpochTime() != + uint64_t(F->second.ModTime)) AnyFileChanged = true; } @@ -1506,7 +1515,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble( // Create the compiler instance to use for building the precompiled preamble. std::unique_ptr<CompilerInstance> Clang( - new CompilerInstance(PCHContainerOps)); + new CompilerInstance(std::move(PCHContainerOps))); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -1723,7 +1732,7 @@ ASTUnit *ASTUnit::create(CompilerInvocation *CI, ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( CompilerInvocation *CI, std::shared_ptr<PCHContainerOperations> PCHContainerOps, - IntrusiveRefCntPtr<DiagnosticsEngine> Diags, ASTFrontendAction *Action, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FrontendAction *Action, ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath, bool OnlyLocalDecls, bool CaptureDiagnostics, unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults, @@ -1768,7 +1777,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( // Create the compiler instance to use for building the AST. std::unique_ptr<CompilerInstance> Clang( - new CompilerInstance(PCHContainerOps)); + new CompilerInstance(std::move(PCHContainerOps))); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -1812,7 +1821,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( // Create the source manager. Clang->setSourceManager(&AST->getSourceManager()); - ASTFrontendAction *Act = Action; + FrontendAction *Act = Action; std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct; if (!Act) { @@ -1888,7 +1897,7 @@ bool ASTUnit::LoadFromCompilerInvocation( llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer> MemBufferCleanup(OverrideMainBuffer.get()); - return Parse(PCHContainerOps, std::move(OverrideMainBuffer)); + return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer)); } std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation( @@ -1921,7 +1930,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation( llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > DiagCleanup(Diags.get()); - if (AST->LoadFromCompilerInvocation(PCHContainerOps, + if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps), PrecompilePreambleAfterNParses)) return nullptr; return AST; @@ -2004,7 +2013,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine( llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> ASTUnitCleanup(AST.get()); - if (AST->LoadFromCompilerInvocation(PCHContainerOps, + if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps), PrecompilePreambleAfterNParses)) { // Some error occurred, if caller wants to examine diagnostics, pass it the // ASTUnit. @@ -2054,7 +2063,8 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, getDiagnostics().setNumWarnings(NumWarningsInPreamble); // Parse the sources - bool Result = Parse(PCHContainerOps, std::move(OverrideMainBuffer)); + bool Result = + Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer)); // If we're caching global code-completion results, and the top-level // declarations have changed, clear out the code-completion cache. @@ -2500,7 +2510,8 @@ static bool serializeUnit(ASTWriter &Writer, } bool ASTUnit::serialize(raw_ostream &OS) { - bool hasErrors = getDiagnostics().hasErrorOccurred(); + // For serialization we are lenient if the errors were only warn-as-error kind. + bool hasErrors = getDiagnostics().hasUncompilableErrorOccurred(); if (WriterData) return serializeUnit(WriterData->Writer, WriterData->Buffer, @@ -2814,7 +2825,7 @@ const FileEntry *ASTUnit::getPCHFile() { } bool ASTUnit::isModuleFile() { - return isMainFileAST() && !ASTFileLangOpts.CurrentModule.empty(); + return isMainFileAST() && ASTFileLangOpts.CompilingModule; } void ASTUnit::PreambleData::countLines() const { diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt index 476812046241c..18abecd2071cc 100644 --- a/lib/Frontend/CMakeLists.txt +++ b/lib/Frontend/CMakeLists.txt @@ -3,9 +3,15 @@ add_subdirectory(Rewrite) set(LLVM_LINK_COMPONENTS BitReader Option + ProfileData Support ) +set(optional_deps intrinsics_gen) +if (CLANG_BUILT_STANDALONE) + set(optional_deps) +endif() + add_clang_library(clangFrontend ASTConsumers.cpp ASTMerge.cpp @@ -43,7 +49,7 @@ add_clang_library(clangFrontend DEPENDS ClangDriverOptions - intrinsics_gen + ${optional_deps} LINK_LIBS clangAST diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp index 87f3d17258140..15b0adab7c5ee 100644 --- a/lib/Frontend/CacheTokens.cpp +++ b/lib/Frontend/CacheTokens.cpp @@ -241,7 +241,7 @@ public: : Out(out), PP(pp), idcount(0), CurStrOffset(0) {} PTHMap &getPM() { return PM; } - void GeneratePTH(const std::string &MainFile); + void GeneratePTH(StringRef MainFile); }; } // end anonymous namespace @@ -479,7 +479,7 @@ static void pwrite32le(raw_pwrite_stream &OS, uint32_t Val, uint64_t &Off) { Off += 4; } -void PTHWriter::GeneratePTH(const std::string &MainFile) { +void PTHWriter::GeneratePTH(StringRef MainFile) { // Generate the prologue. Out << "cfe-pth" << '\0'; Emit32(PTHManager::Version); diff --git a/lib/Frontend/ChainedIncludesSource.cpp b/lib/Frontend/ChainedIncludesSource.cpp index 1c1081fbe08e7..3f126615b1eb6 100644 --- a/lib/Frontend/ChainedIncludesSource.cpp +++ b/lib/Frontend/ChainedIncludesSource.cpp @@ -18,6 +18,7 @@ #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Lex/Preprocessor.h" #include "clang/Parse/ParseAST.h" +#include "clang/Sema/MultiplexExternalSemaSource.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" #include "llvm/Support/MemoryBuffer.h" @@ -25,51 +26,52 @@ using namespace clang; namespace { -class ChainedIncludesSource : public ExternalSemaSource { +class ChainedIncludesSourceImpl : public ExternalSemaSource { public: - ~ChainedIncludesSource() override; - - ExternalSemaSource &getFinalReader() const { return *FinalReader; } - - std::vector<CompilerInstance *> CIs; - IntrusiveRefCntPtr<ExternalSemaSource> FinalReader; + ChainedIncludesSourceImpl(std::vector<std::unique_ptr<CompilerInstance>> CIs) + : CIs(std::move(CIs)) {} protected: //===----------------------------------------------------------------------===// // ExternalASTSource interface. //===----------------------------------------------------------------------===// - Decl *GetExternalDecl(uint32_t ID) override; - Selector GetExternalSelector(uint32_t ID) override; - uint32_t GetNumExternalSelectors() override; - Stmt *GetExternalDeclStmt(uint64_t Offset) override; - CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override; - CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override; - bool FindExternalVisibleDeclsByName(const DeclContext *DC, - DeclarationName Name) override; - void - FindExternalLexicalDecls(const DeclContext *DC, - llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, - SmallVectorImpl<Decl *> &Result) override; - void CompleteType(TagDecl *Tag) override; - void CompleteType(ObjCInterfaceDecl *Class) override; - void StartedDeserializing() override; - void FinishedDeserializing() override; - void StartTranslationUnit(ASTConsumer *Consumer) override; - void PrintStats() override; - /// Return the amount of memory used by memory buffers, breaking down /// by heap-backed versus mmap'ed memory. - void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override; + void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override { + for (unsigned i = 0, e = CIs.size(); i != e; ++i) { + if (const ExternalASTSource *eSrc = + CIs[i]->getASTContext().getExternalSource()) { + eSrc->getMemoryBufferSizes(sizes); + } + } + } - //===----------------------------------------------------------------------===// - // ExternalSemaSource interface. - //===----------------------------------------------------------------------===// +private: + std::vector<std::unique_ptr<CompilerInstance>> CIs; +}; + +/// Members of ChainedIncludesSource, factored out so we can initialize +/// them before we initialize the ExternalSemaSource base class. +struct ChainedIncludesSourceMembers { + ChainedIncludesSourceMembers( + std::vector<std::unique_ptr<CompilerInstance>> CIs, + IntrusiveRefCntPtr<ExternalSemaSource> FinalReader) + : Impl(std::move(CIs)), FinalReader(std::move(FinalReader)) {} + ChainedIncludesSourceImpl Impl; + IntrusiveRefCntPtr<ExternalSemaSource> FinalReader; +}; - void InitializeSema(Sema &S) override; - void ForgetSema() override; - void ReadMethodPool(Selector Sel) override; - bool LookupUnqualified(LookupResult &R, Scope *S) override; +/// Use MultiplexExternalSemaSource to dispatch all ExternalSemaSource +/// calls to the final reader. +class ChainedIncludesSource + : private ChainedIncludesSourceMembers, + public MultiplexExternalSemaSource { +public: + ChainedIncludesSource(std::vector<std::unique_ptr<CompilerInstance>> CIs, + IntrusiveRefCntPtr<ExternalSemaSource> FinalReader) + : ChainedIncludesSourceMembers(std::move(CIs), std::move(FinalReader)), + MultiplexExternalSemaSource(Impl, *this->FinalReader) {} }; } @@ -107,18 +109,13 @@ createASTReader(CompilerInstance &CI, StringRef pchFile, return nullptr; } -ChainedIncludesSource::~ChainedIncludesSource() { - for (unsigned i = 0, e = CIs.size(); i != e; ++i) - delete CIs[i]; -} - IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( CompilerInstance &CI, IntrusiveRefCntPtr<ExternalSemaSource> &Reader) { std::vector<std::string> &includes = CI.getPreprocessorOpts().ChainedIncludes; assert(!includes.empty() && "No '-chain-include' in options!"); - IntrusiveRefCntPtr<ChainedIncludesSource> source(new ChainedIncludesSource()); + std::vector<std::unique_ptr<CompilerInstance>> CIs; InputKind IK = CI.getFrontendOpts().Inputs[0].getKind(); SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> SerialBufs; @@ -164,7 +161,7 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions; auto consumer = llvm::make_unique<PCHGenerator>( Clang->getPreprocessor(), "-", nullptr, /*isysroot=*/"", Buffer, - Extensions); + Extensions, /*AllowASTWithErrors=*/true); Clang->getASTContext().setASTMutationListener( consumer->GetASTMutationListener()); Clang->setASTConsumer(std::move(consumer)); @@ -206,7 +203,7 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy( StringRef(serialAST.data(), serialAST.size()))); serialAST.clear(); - source->CIs.push_back(Clang.release()); + CIs.push_back(std::move(Clang)); } assert(!SerialBufs.empty()); @@ -216,83 +213,6 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( if (!Reader) return nullptr; - source->FinalReader = Reader; - return source; -} - -//===----------------------------------------------------------------------===// -// ExternalASTSource interface. -//===----------------------------------------------------------------------===// - -Decl *ChainedIncludesSource::GetExternalDecl(uint32_t ID) { - return getFinalReader().GetExternalDecl(ID); -} -Selector ChainedIncludesSource::GetExternalSelector(uint32_t ID) { - return getFinalReader().GetExternalSelector(ID); -} -uint32_t ChainedIncludesSource::GetNumExternalSelectors() { - return getFinalReader().GetNumExternalSelectors(); + return IntrusiveRefCntPtr<ChainedIncludesSource>( + new ChainedIncludesSource(std::move(CIs), Reader)); } -Stmt *ChainedIncludesSource::GetExternalDeclStmt(uint64_t Offset) { - return getFinalReader().GetExternalDeclStmt(Offset); -} -CXXBaseSpecifier * -ChainedIncludesSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) { - return getFinalReader().GetExternalCXXBaseSpecifiers(Offset); -} -CXXCtorInitializer ** -ChainedIncludesSource::GetExternalCXXCtorInitializers(uint64_t Offset) { - return getFinalReader().GetExternalCXXCtorInitializers(Offset); -} -bool -ChainedIncludesSource::FindExternalVisibleDeclsByName(const DeclContext *DC, - DeclarationName Name) { - return getFinalReader().FindExternalVisibleDeclsByName(DC, Name); -} -void ChainedIncludesSource::FindExternalLexicalDecls( - const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, - SmallVectorImpl<Decl *> &Result) { - return getFinalReader().FindExternalLexicalDecls(DC, IsKindWeWant, Result); -} -void ChainedIncludesSource::CompleteType(TagDecl *Tag) { - return getFinalReader().CompleteType(Tag); -} -void ChainedIncludesSource::CompleteType(ObjCInterfaceDecl *Class) { - return getFinalReader().CompleteType(Class); -} -void ChainedIncludesSource::StartedDeserializing() { - return getFinalReader().StartedDeserializing(); -} -void ChainedIncludesSource::FinishedDeserializing() { - return getFinalReader().FinishedDeserializing(); -} -void ChainedIncludesSource::StartTranslationUnit(ASTConsumer *Consumer) { - return getFinalReader().StartTranslationUnit(Consumer); -} -void ChainedIncludesSource::PrintStats() { - return getFinalReader().PrintStats(); -} -void ChainedIncludesSource::getMemoryBufferSizes(MemoryBufferSizes &sizes)const{ - for (unsigned i = 0, e = CIs.size(); i != e; ++i) { - if (const ExternalASTSource *eSrc = - CIs[i]->getASTContext().getExternalSource()) { - eSrc->getMemoryBufferSizes(sizes); - } - } - - getFinalReader().getMemoryBufferSizes(sizes); -} - -void ChainedIncludesSource::InitializeSema(Sema &S) { - return getFinalReader().InitializeSema(S); -} -void ChainedIncludesSource::ForgetSema() { - return getFinalReader().ForgetSema(); -} -void ChainedIncludesSource::ReadMethodPool(Selector Sel) { - getFinalReader().ReadMethodPool(Sel); -} -bool ChainedIncludesSource::LookupUnqualified(LookupResult &R, Scope *S) { - return getFinalReader().LookupUnqualified(R, S); -} - diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 3edcf5d654b9d..8b00a3d00879d 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -48,6 +48,7 @@ #include <sys/stat.h> #include <system_error> #include <time.h> +#include <utility> using namespace clang; @@ -55,7 +56,8 @@ CompilerInstance::CompilerInstance( std::shared_ptr<PCHContainerOperations> PCHContainerOps, bool BuildingModule) : ModuleLoader(BuildingModule), Invocation(new CompilerInvocation()), - ModuleManager(nullptr), ThePCHContainerOperations(PCHContainerOps), + ModuleManager(nullptr), + ThePCHContainerOperations(std::move(PCHContainerOps)), BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false), ModuleBuildFailed(false) {} @@ -125,7 +127,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { return ModuleManager; } void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { - ModuleManager = Reader; + ModuleManager = std::move(Reader); } std::shared_ptr<ModuleDependencyCollector> @@ -135,7 +137,7 @@ CompilerInstance::getModuleDepCollector() const { void CompilerInstance::setModuleDepCollector( std::shared_ptr<ModuleDependencyCollector> Collector) { - ModuleDepCollector = Collector; + ModuleDepCollector = std::move(Collector); } // Diagnostics @@ -349,30 +351,34 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, getHeaderSearchOpts().Sysroot); - for (auto &Listener : DependencyCollectors) - Listener->attachToPreprocessor(*PP); - // If we don't have a collector, but we are collecting module dependencies, // then we're the top level compiler instance and need to create one. - if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) + if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) { ModuleDepCollector = std::make_shared<ModuleDependencyCollector>( DepOpts.ModuleDependencyOutputDir); + } + + if (ModuleDepCollector) + addDependencyCollector(ModuleDepCollector); + + for (auto &Listener : DependencyCollectors) + Listener->attachToPreprocessor(*PP); // Handle generating header include information, if requested. if (DepOpts.ShowHeaderIncludes) - AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps); + AttachHeaderIncludeGen(*PP, DepOpts); if (!DepOpts.HeaderIncludeOutputFile.empty()) { StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; if (OutputPath == "-") OutputPath = ""; - AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps, + AttachHeaderIncludeGen(*PP, DepOpts, /*ShowAllHeaders=*/true, OutputPath, /*ShowDepth=*/false); } if (DepOpts.PrintShowIncludes) { - AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps, - /*ShowAllHeaders=*/false, /*OutputPath=*/"", + AttachHeaderIncludeGen(*PP, DepOpts, + /*ShowAllHeaders=*/true, /*OutputPath=*/"", /*ShowDepth=*/true, /*MSStyle=*/true); } } @@ -467,7 +473,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( // Code Completion static bool EnableCodeCompletion(Preprocessor &PP, - const std::string &Filename, + StringRef Filename, unsigned Line, unsigned Column) { // Tell the source manager to chop off the given file at a specific @@ -536,15 +542,11 @@ void CompilerInstance::createSema(TranslationUnitKind TUKind, // Output Files void CompilerInstance::addOutputFile(OutputFile &&OutFile) { - assert(OutFile.OS && "Attempt to add empty stream to output list!"); OutputFiles.push_back(std::move(OutFile)); } void CompilerInstance::clearOutputFiles(bool EraseFiles) { for (OutputFile &OF : OutputFiles) { - // Manually close the stream before we rename it. - OF.OS.reset(); - if (!OF.TempFilename.empty()) { if (EraseFiles) { llvm::sys::fs::remove(OF.TempFilename); @@ -564,13 +566,12 @@ void CompilerInstance::clearOutputFiles(bool EraseFiles) { } } else if (!OF.Filename.empty() && EraseFiles) llvm::sys::fs::remove(OF.Filename); - } OutputFiles.clear(); NonSeekStream.reset(); } -raw_pwrite_stream * +std::unique_ptr<raw_pwrite_stream> CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile, StringRef Extension) { return createOutputFile(getFrontendOpts().OutputFile, Binary, @@ -578,14 +579,11 @@ CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile, /*UseTemporary=*/true); } -llvm::raw_null_ostream *CompilerInstance::createNullOutputFile() { - auto OS = llvm::make_unique<llvm::raw_null_ostream>(); - llvm::raw_null_ostream *Ret = OS.get(); - addOutputFile(OutputFile("", "", std::move(OS))); - return Ret; +std::unique_ptr<raw_pwrite_stream> CompilerInstance::createNullOutputFile() { + return llvm::make_unique<llvm::raw_null_ostream>(); } -raw_pwrite_stream * +std::unique_ptr<raw_pwrite_stream> CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal, StringRef InFile, StringRef Extension, bool UseTemporary, @@ -601,13 +599,12 @@ CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary, return nullptr; } - raw_pwrite_stream *Ret = OS.get(); // Add the output file -- but don't try to remove "-", since this means we are // using stdin. - addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "", - TempPathName, std::move(OS))); + addOutputFile( + OutputFile((OutputPathName != "-") ? OutputPathName : "", TempPathName)); - return Ret; + return OS; } std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile( @@ -712,16 +709,17 @@ std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile( // Initialization Utilities bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ - return InitializeSourceManager(Input, getDiagnostics(), - getFileManager(), getSourceManager(), - getFrontendOpts()); + return InitializeSourceManager( + Input, getDiagnostics(), getFileManager(), getSourceManager(), + hasPreprocessor() ? &getPreprocessor().getHeaderSearchInfo() : nullptr, + getDependencyOutputOpts(), getFrontendOpts()); } -bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, - DiagnosticsEngine &Diags, - FileManager &FileMgr, - SourceManager &SourceMgr, - const FrontendOptions &Opts) { +// static +bool CompilerInstance::InitializeSourceManager( + const FrontendInputFile &Input, DiagnosticsEngine &Diags, + FileManager &FileMgr, SourceManager &SourceMgr, HeaderSearch *HS, + DependencyOutputOptions &DepOpts, const FrontendOptions &Opts) { SrcMgr::CharacteristicKind Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; @@ -737,7 +735,35 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, // Figure out where to get and map in the main file. if (InputFile != "-") { - const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true); + const FileEntry *File; + if (Opts.FindPchSource.empty()) { + File = FileMgr.getFile(InputFile, /*OpenFile=*/true); + } else { + // When building a pch file in clang-cl mode, the .h file is built as if + // it was included by a cc file. Since the driver doesn't know about + // all include search directories, the frontend must search the input + // file through HeaderSearch here, as if it had been included by the + // cc file at Opts.FindPchSource. + const FileEntry *FindFile = FileMgr.getFile(Opts.FindPchSource); + if (!FindFile) { + Diags.Report(diag::err_fe_error_reading) << Opts.FindPchSource; + return false; + } + const DirectoryLookup *UnusedCurDir; + SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 16> + Includers; + Includers.push_back(std::make_pair(FindFile, FindFile->getDir())); + File = HS->LookupFile(InputFile, SourceLocation(), /*isAngled=*/false, + /*FromDir=*/nullptr, + /*CurDir=*/UnusedCurDir, Includers, + /*SearchPath=*/nullptr, + /*RelativePath=*/nullptr, + /*RequestingModule=*/nullptr, + /*SuggestedModule=*/nullptr, /*SkipCache=*/true); + // Also add the header to /showIncludes output. + if (File) + DepOpts.ShowIncludesPretendHeader = File->getName(); + } if (!File) { Diags.Report(diag::err_fe_error_reading) << InputFile; return false; @@ -803,8 +829,9 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { // Create TargetInfo for the other side of CUDA compilation. if (getLangOpts().CUDA && !getFrontendOpts().AuxTriple.empty()) { - std::shared_ptr<TargetOptions> TO(new TargetOptions); + auto TO = std::make_shared<TargetOptions>(); TO->Triple = getFrontendOpts().AuxTriple; + TO->HostTriple = getTarget().getTriple().str(); setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO)); } @@ -1050,7 +1077,7 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance, switch (Locked) { case llvm::LockFileManager::LFS_Error: Diags.Report(ModuleNameLoc, diag::err_module_lock_failure) - << Module->Name; + << Module->Name << Locked.getErrorMessage(); return false; case llvm::LockFileManager::LFS_Owned: @@ -1290,8 +1317,6 @@ void CompilerInstance::createModuleManager() { if (TheDependencyFileGenerator) TheDependencyFileGenerator->AttachToASTReader(*ModuleManager); - if (ModuleDepCollector) - ModuleDepCollector->attachToASTReader(*ModuleManager); for (auto &Listener : DependencyCollectors) Listener->attachToASTReader(*ModuleManager); } @@ -1386,8 +1411,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // when both the preprocessor and parser see the same import declaration. if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) { // Make the named module visible. - if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule && - ModuleName != getLangOpts().ImplementationOfModule) + if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, ImportLoc); return LastModuleImportResult; @@ -1401,8 +1425,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, if (Known != KnownModules.end()) { // Retrieve the cached top-level module. Module = Known->second; - } else if (ModuleName == getLangOpts().CurrentModule || - ModuleName == getLangOpts().ImplementationOfModule) { + } else if (ModuleName == getLangOpts().CurrentModule) { // This is the module we're building. Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; @@ -1580,10 +1603,6 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, } } - // Don't make the module visible if we are in the implementation. - if (ModuleName == getLangOpts().ImplementationOfModule) - return ModuleLoadResult(Module, false); - // Make the named module visible, if it's not already part of the module // we are parsing. if (ModuleName != getLangOpts().CurrentModule) { diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 237a447040968..c6948ebfc4b4e 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -33,6 +33,7 @@ #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" +#include "llvm/ProfileData/InstrProfReader.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" @@ -40,6 +41,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/Support/ScopedPrinter.h" #include <atomic> #include <memory> #include <sys/stat.h> @@ -375,6 +377,46 @@ static void parseSanitizerKinds(StringRef FlagName, } } +// Set the profile kind for fprofile-instrument. +static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args, + DiagnosticsEngine &Diags) { + Arg *A = Args.getLastArg(OPT_fprofile_instrument_EQ); + if (A == nullptr) + return; + StringRef S = A->getValue(); + unsigned I = llvm::StringSwitch<unsigned>(S) + .Case("none", CodeGenOptions::ProfileNone) + .Case("clang", CodeGenOptions::ProfileClangInstr) + .Case("llvm", CodeGenOptions::ProfileIRInstr) + .Default(~0U); + if (I == ~0U) { + Diags.Report(diag::err_drv_invalid_pgo_instrumentor) << A->getAsString(Args) + << S; + return; + } + CodeGenOptions::ProfileInstrKind Instrumentor = + static_cast<CodeGenOptions::ProfileInstrKind>(I); + Opts.setProfileInstr(Instrumentor); +} + +// Set the profile kind using fprofile-instrument-use-path. +static void setPGOUseInstrumentor(CodeGenOptions &Opts, + const Twine &ProfileName) { + auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName); + // In error, return silently and let Clang PGOUse report the error message. + if (auto E = ReaderOrErr.takeError()) { + llvm::consumeError(std::move(E)); + Opts.setProfileUse(CodeGenOptions::ProfileClangInstr); + return; + } + std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader = + std::move(ReaderOrErr.get()); + if (PGOReader->isIRLevelProfile()) + Opts.setProfileUse(CodeGenOptions::ProfileIRInstr); + else + Opts.setProfileUse(CodeGenOptions::ProfileClangInstr); +} + static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, DiagnosticsEngine &Diags, const TargetOptions &TargetOpts) { @@ -400,8 +442,17 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, : CodeGenOptions::OnlyAlwaysInlining); // -fno-inline-functions overrides OptimizationLevel > 1. Opts.NoInline = Args.hasArg(OPT_fno_inline); - Opts.setInlining(Args.hasArg(OPT_fno_inline_functions) ? - CodeGenOptions::OnlyAlwaysInlining : Opts.getInlining()); + if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions, + options::OPT_finline_hint_functions, + options::OPT_fno_inline_functions)) { + const Option& InlineOpt = InlineArg->getOption(); + if (InlineOpt.matches(options::OPT_finline_functions)) + Opts.setInlining(CodeGenOptions::NormalInlining); + else if (InlineOpt.matches(options::OPT_finline_hint_functions)) + Opts.setInlining(CodeGenOptions::OnlyHintInlining); + else + Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining); + } if (Arg *A = Args.getLastArg(OPT_fveclib)) { StringRef Name = A->getValue(); @@ -416,34 +467,36 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) { unsigned Val = llvm::StringSwitch<unsigned>(A->getValue()) - .Case("line-tables-only", CodeGenOptions::DebugLineTablesOnly) - .Case("limited", CodeGenOptions::LimitedDebugInfo) - .Case("standalone", CodeGenOptions::FullDebugInfo) + .Case("line-tables-only", codegenoptions::DebugLineTablesOnly) + .Case("limited", codegenoptions::LimitedDebugInfo) + .Case("standalone", codegenoptions::FullDebugInfo) .Default(~0U); if (Val == ~0U) Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); else - Opts.setDebugInfo(static_cast<CodeGenOptions::DebugInfoKind>(Val)); + Opts.setDebugInfo(static_cast<codegenoptions::DebugInfoKind>(Val)); } if (Arg *A = Args.getLastArg(OPT_debugger_tuning_EQ)) { unsigned Val = llvm::StringSwitch<unsigned>(A->getValue()) - .Case("gdb", CodeGenOptions::DebuggerKindGDB) - .Case("lldb", CodeGenOptions::DebuggerKindLLDB) - .Case("sce", CodeGenOptions::DebuggerKindSCE) + .Case("gdb", unsigned(llvm::DebuggerKind::GDB)) + .Case("lldb", unsigned(llvm::DebuggerKind::LLDB)) + .Case("sce", unsigned(llvm::DebuggerKind::SCE)) .Default(~0U); if (Val == ~0U) Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); else - Opts.setDebuggerTuning(static_cast<CodeGenOptions::DebuggerKind>(Val)); + 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.EmitCodeView = Args.hasArg(OPT_gcodeview); + Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables); + Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std); Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file); Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs); - Opts.DebugExplicitImport = Triple.isPS4CPU(); + Opts.DebugExplicitImport = Triple.isPS4CPU(); for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) Opts.DebugPrefixMap.insert(StringRef(Arg).split('=')); @@ -471,20 +524,26 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs); Opts.UnrollLoops = Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops, - (Opts.OptimizationLevel > 1 && !Opts.OptimizeSize)); + (Opts.OptimizationLevel > 1)); Opts.RerollLoops = Args.hasArg(OPT_freroll_loops); 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.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate) || - Args.hasArg(OPT_fprofile_instr_generate_EQ); - Opts.InstrProfileOutput = Args.getLastArgValue(OPT_fprofile_instr_generate_EQ); - Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ); + + setPGOInstrumentor(Opts, Args, Diags); + Opts.InstrProfileOutput = + Args.getLastArgValue(OPT_fprofile_instrument_path_EQ); + Opts.ProfileInstrumentUsePath = + Args.getLastArgValue(OPT_fprofile_instrument_use_path_EQ); + if (!Opts.ProfileInstrumentUsePath.empty()) + setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath); + 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.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions); Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit); Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); @@ -493,22 +552,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.DisableFPElim = (Args.hasArg(OPT_mdisable_fp_elim) || Args.hasArg(OPT_pg)); Opts.DisableFree = Args.hasArg(OPT_disable_free); + Opts.DiscardValueNames = Args.hasArg(OPT_discard_value_names); Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls); Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi); - if (Arg *A = Args.getLastArg(OPT_meabi)) { - StringRef Value = A->getValue(); - llvm::EABI EABIVersion = llvm::StringSwitch<llvm::EABI>(Value) - .Case("default", llvm::EABI::Default) - .Case("4", llvm::EABI::EABI4) - .Case("5", llvm::EABI::EABI5) - .Case("gnu", llvm::EABI::GNU) - .Default(llvm::EABI::Unknown); - if (EABIVersion == llvm::EABI::Unknown) - Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) - << Value; - else - Opts.EABIVersion = Value; - } Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable); Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision); Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) || @@ -518,7 +564,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, 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); + Opts.NoSignedZeros = (Args.hasArg(OPT_fno_signed_zeros) || + Args.hasArg(OPT_cl_no_signed_zeros)); Opts.ReciprocalMath = Args.hasArg(OPT_freciprocal_math); Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss); Opts.BackendOptions = Args.getAllArgValues(OPT_backend_option); @@ -557,9 +604,11 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions); + Opts.NoUseJumpTables = Args.hasArg(OPT_fno_jump_tables); + Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ); const Arg *A = Args.getLastArg(OPT_flto, OPT_flto_EQ); - Opts.EmitFunctionSummary = A && A->containsValue("thin"); + Opts.EmitSummaryIndex = A && A->containsValue("thin"); if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) { if (IK != IK_LLVM_IR) Diags.Report(diag::err_drv_argument_only_allowed_with) @@ -597,11 +646,54 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } } } + // Handle -fembed-bitcode option. + if (Arg *A = Args.getLastArg(OPT_fembed_bitcode_EQ)) { + StringRef Name = A->getValue(); + unsigned Model = llvm::StringSwitch<unsigned>(Name) + .Case("off", CodeGenOptions::Embed_Off) + .Case("all", CodeGenOptions::Embed_All) + .Case("bitcode", CodeGenOptions::Embed_Bitcode) + .Case("marker", CodeGenOptions::Embed_Marker) + .Default(~0U); + if (Model == ~0U) { + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name; + Success = false; + } else + Opts.setEmbedBitcode( + static_cast<CodeGenOptions::EmbedBitcodeKind>(Model)); + } + // FIXME: For backend options that are not yet recorded as function + // attributes in the IR, keep track of them so we can embed them in a + // separate data section and use them when building the bitcode. + if (Opts.getEmbedBitcode() == CodeGenOptions::Embed_All) { + for (const auto &A : Args) { + // Do not encode output and input. + if (A->getOption().getID() == options::OPT_o || + 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)) + continue; + ArgStringList ASL; + A->render(Args, ASL); + for (const auto &arg : ASL) { + StringRef ArgStr(arg); + Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end()); + // using \00 to seperate each commandline options. + Opts.CmdArgs.push_back('\0'); + } + } + } Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions); + Opts.XRayInstrumentFunctions = Args.hasArg(OPT_fxray_instrument); + Opts.XRayInstructionThreshold = + getLastArgIntValue(Args, OPT_fxray_instruction_threshold_, 200, Diags); Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info); Opts.CompressDebugSections = Args.hasArg(OPT_compress_debug_sections); + Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations); Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir); for (auto A : Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_cuda_bitcode)) { unsigned LinkFlags = llvm::Linker::Flags::None; @@ -618,11 +710,15 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.SanitizeCoverageTraceCmp = Args.hasArg(OPT_fsanitize_coverage_trace_cmp); Opts.SanitizeCoverage8bitCounters = Args.hasArg(OPT_fsanitize_coverage_8bit_counters); + Opts.SanitizeCoverageTracePC = Args.hasArg(OPT_fsanitize_coverage_trace_pc); Opts.SanitizeMemoryTrackOrigins = getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags); Opts.SanitizeMemoryUseAfterDtor = Args.hasArg(OPT_fsanitize_memory_use_after_dtor); Opts.SanitizeCfiCrossDso = Args.hasArg(OPT_fsanitize_cfi_cross_dso); + Opts.SanitizeStats = Args.hasArg(OPT_fsanitize_stats); + Opts.SanitizeAddressUseAfterScope = + Args.hasArg(OPT_fsanitize_address_use_after_scope); Opts.SSPBufferSize = getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags); Opts.StackRealignment = Args.hasArg(OPT_mstackrealign); @@ -697,6 +793,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib); + Opts.LinkerOptions = Args.getAllArgValues(OPT_linker_option); bool NeedLocTracking = false; if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) { @@ -725,8 +822,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, // If the user requested a flag that requires source locations available in // the backend, make sure that the backend tracks source location information. - if (NeedLocTracking && Opts.getDebugInfo() == CodeGenOptions::NoDebugInfo) - Opts.setDebugInfo(CodeGenOptions::LocTrackingOnly); + if (NeedLocTracking && Opts.getDebugInfo() == codegenoptions::NoDebugInfo) + Opts.setDebugInfo(codegenoptions::LocTrackingOnly); Opts.RewriteMapFiles = Args.getAllArgValues(OPT_frewrite_map_file); @@ -742,6 +839,11 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.CudaGpuBinaryFileNames = Args.getAllArgValues(OPT_fcuda_include_gpubinary); + Opts.Backchain = Args.hasArg(OPT_mbackchain); + + Opts.EmitCheckPathComponentsToStrip = getLastArgIntValue( + Args, OPT_fsanitize_undefined_strip_path_components_EQ, 0, Diags); + return Success; } @@ -771,8 +873,51 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, ModuleFiles.end()); } +static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) { + // Color diagnostics default to auto ("on" if terminal supports) in the driver + // but default to off in cc1, needing an explicit OPT_fdiagnostics_color. + // Support both clang's -f[no-]color-diagnostics and gcc's + // -f[no-]diagnostics-colors[=never|always|auto]. + enum { + Colors_On, + Colors_Off, + Colors_Auto + } ShowColors = DefaultColor ? Colors_Auto : Colors_Off; + for (Arg *A : Args) { + const Option &O = A->getOption(); + if (!O.matches(options::OPT_fcolor_diagnostics) && + !O.matches(options::OPT_fdiagnostics_color) && + !O.matches(options::OPT_fno_color_diagnostics) && + !O.matches(options::OPT_fno_diagnostics_color) && + !O.matches(options::OPT_fdiagnostics_color_EQ)) + continue; + + if (O.matches(options::OPT_fcolor_diagnostics) || + O.matches(options::OPT_fdiagnostics_color)) { + ShowColors = Colors_On; + } else if (O.matches(options::OPT_fno_color_diagnostics) || + O.matches(options::OPT_fno_diagnostics_color)) { + ShowColors = Colors_Off; + } else { + assert(O.matches(options::OPT_fdiagnostics_color_EQ)); + StringRef Value(A->getValue()); + if (Value == "always") + ShowColors = Colors_On; + else if (Value == "never") + ShowColors = Colors_Off; + else if (Value == "auto") + ShowColors = Colors_Auto; + } + } + if (ShowColors == Colors_On || + (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors())) + return true; + return false; +} + bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, - DiagnosticsEngine *Diags) { + DiagnosticsEngine *Diags, + bool DefaultDiagColor) { using namespace options; bool Success = true; @@ -785,7 +930,7 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.Pedantic = Args.hasArg(OPT_pedantic); Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors); Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics); - Opts.ShowColors = Args.hasArg(OPT_fcolor_diagnostics); + Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor); Opts.ShowColumn = Args.hasFlag(OPT_fshow_column, OPT_fno_show_column, /*Default=*/true); @@ -999,18 +1144,10 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.Plugins.emplace_back(A->getValue(0)); Opts.ProgramAction = frontend::PluginAction; Opts.ActionName = A->getValue(); - - for (const Arg *AA : Args.filtered(OPT_plugin_arg)) - if (AA->getValue(0) == Opts.ActionName) - Opts.PluginArgs.emplace_back(AA->getValue(1)); } - Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin); - Opts.AddPluginArgs.resize(Opts.AddPluginActions.size()); - for (int i = 0, e = Opts.AddPluginActions.size(); i != e; ++i) - for (const Arg *A : Args.filtered(OPT_plugin_arg)) - if (A->getValue(0) == Opts.AddPluginActions[i]) - Opts.AddPluginArgs[i].emplace_back(A->getValue(1)); + for (const Arg *AA : Args.filtered(OPT_plugin_arg)) + Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1)); for (const std::string &Arg : Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) { @@ -1063,6 +1200,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ModuleFiles = Args.getAllArgValues(OPT_fmodule_file); 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.CodeCompleteOpts.IncludeMacros = Args.hasArg(OPT_code_completion_macros); @@ -1077,6 +1215,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, = Args.getLastArgValue(OPT_foverride_record_layout_EQ); Opts.AuxTriple = llvm::Triple::normalize(Args.getLastArgValue(OPT_aux_triple)); + Opts.FindPchSource = Args.getLastArgValue(OPT_find_pch_source_EQ); if (const Arg *A = Args.getLastArg(OPT_arcmt_check, OPT_arcmt_modify, @@ -1164,6 +1303,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, .Case("objective-c++-header", IK_ObjCXX) .Cases("ast", "pcm", IK_AST) .Case("ir", IK_LLVM_IR) + .Case("renderscript", IK_RenderScript) .Default(IK_None); if (DashX == IK_None) Diags.Report(diag::err_drv_invalid_value) @@ -1243,6 +1383,8 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { // Add -I..., -F..., and -index-header-map options in order. bool IsIndexHeaderMap = false; + bool IsSysrootSpecified = + Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot); for (const Arg *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) { if (A->getOption().matches(OPT_index_header_map)) { // -index-header-map applies to the next -I or -F. @@ -1253,8 +1395,18 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { frontend::IncludeDirGroup Group = IsIndexHeaderMap ? frontend::IndexHeaderMap : frontend::Angled; - Opts.AddPath(A->getValue(), Group, - /*IsFramework=*/A->getOption().matches(OPT_F), true); + bool IsFramework = A->getOption().matches(OPT_F); + std::string Path = A->getValue(); + + if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') { + SmallString<32> Buffer; + llvm::sys::path::append(Buffer, Opts.Sysroot, + llvm::StringRef(A->getValue()).substr(1)); + Path = Buffer.str(); + } + + Opts.AddPath(Path.c_str(), Group, IsFramework, + /*IgnoreSysroot*/ true); IsIndexHeaderMap = false; } @@ -1309,7 +1461,16 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { Opts.AddVFSOverlayFile(A->getValue()); } +bool isOpenCL(LangStandard::Kind LangStd) { + return LangStd == LangStandard::lang_opencl || + LangStd == LangStandard::lang_opencl11 || + LangStd == LangStandard::lang_opencl12 || + LangStd == LangStandard::lang_opencl20; +} + void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, + const llvm::Triple &T, + PreprocessorOptions &PPOpts, LangStandard::Kind LangStd) { // Set some properties which depend solely on the input kind; it would be nice // to move these to the language standard, and have the driver resolve the @@ -1342,7 +1503,11 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, case IK_PreprocessedC: case IK_ObjC: case IK_PreprocessedObjC: - LangStd = LangStandard::lang_gnu11; + // The PS4 uses C99 as the default C standard. + if (T.isPS4()) + LangStd = LangStandard::lang_gnu99; + else + LangStd = LangStandard::lang_gnu11; break; case IK_CXX: case IK_PreprocessedCXX: @@ -1350,6 +1515,9 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, case IK_PreprocessedObjCXX: LangStd = LangStandard::lang_gnucxx98; break; + case IK_RenderScript: + LangStd = LangStandard::lang_c99; + break; } } @@ -1368,7 +1536,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.ImplicitInt = Std.hasImplicitInt(); // Set OpenCL Version. - Opts.OpenCL = LangStd == LangStandard::lang_opencl || IK == IK_OpenCL; + Opts.OpenCL = isOpenCL(LangStd) || IK == IK_OpenCL; if (LangStd == LangStandard::lang_opencl) Opts.OpenCLVersion = 100; else if (LangStd == LangStandard::lang_opencl11) @@ -1386,11 +1554,22 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.LaxVectorConversions = 0; Opts.DefaultFPContract = 1; Opts.NativeHalfType = 1; + Opts.NativeHalfArgsAndReturns = 1; + // Include default header file for OpenCL. + if (Opts.IncludeDefaultHeader) { + PPOpts.Includes.push_back("opencl-c.h"); + } } Opts.CUDA = IK == IK_CUDA || IK == IK_PreprocessedCuda || LangStd == LangStandard::lang_cuda; + Opts.RenderScript = IK == IK_RenderScript; + if (Opts.RenderScript) { + Opts.NativeHalfType = 1; + Opts.NativeHalfArgsAndReturns = 1; + } + // OpenCL and C++ both have bool, true, false keywords. Opts.Bool = Opts.OpenCL || Opts.CPlusPlus; @@ -1425,6 +1604,8 @@ static Visibility parseVisibility(Arg *arg, ArgList &args, } static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, + const TargetOptions &TargetOpts, + PreprocessorOptions &PPOpts, DiagnosticsEngine &Diags) { // FIXME: Cleanup per-file based stuff. LangStandard::Kind LangStd = LangStandard::lang_unspecified; @@ -1432,6 +1613,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, LangStd = llvm::StringSwitch<LangStandard::Kind>(A->getValue()) #define LANGSTANDARD(id, name, desc, features) \ .Case(name, LangStandard::lang_##id) +#define LANGSTANDARD_ALIAS(id, alias) \ + .Case(alias, LangStandard::lang_##id) #include "clang/Frontend/LangStandards.def" .Default(LangStandard::lang_unspecified); if (LangStd == LangStandard::lang_unspecified) @@ -1459,7 +1642,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, << A->getAsString(Args) << "C++/ObjC++"; break; case IK_OpenCL: - if (!Std.isC99()) + if (!isOpenCL(LangStd)) Diags.Report(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args) << "OpenCL"; break; @@ -1480,10 +1663,10 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) { LangStandard::Kind OpenCLLangStd = llvm::StringSwitch<LangStandard::Kind>(A->getValue()) - .Case("CL", LangStandard::lang_opencl) - .Case("CL1.1", LangStandard::lang_opencl11) - .Case("CL1.2", LangStandard::lang_opencl12) - .Case("CL2.0", LangStandard::lang_opencl20) + .Cases("cl", "CL", LangStandard::lang_opencl) + .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11) + .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12) + .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20) .Default(LangStandard::lang_unspecified); if (OpenCLLangStd == LangStandard::lang_unspecified) { @@ -1494,7 +1677,22 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, LangStd = OpenCLLangStd; } - CompilerInvocation::setLangDefaults(Opts, IK, LangStd); + Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header); + + llvm::Triple T(TargetOpts.Triple); + CompilerInvocation::setLangDefaults(Opts, IK, T, PPOpts, LangStd); + + // -cl-strict-aliasing needs to emit diagnostic in the case where CL > 1.0. + // This option should be deprecated for CL > 1.0 because + // this option was added for compatibility with OpenCL 1.0. + if (Args.getLastArg(OPT_cl_strict_aliasing) + && Opts.OpenCLVersion > 100) { + std::string VerSpec = llvm::to_string(Opts.OpenCLVersion / 100) + + std::string(".") + + llvm::to_string((Opts.OpenCLVersion % 100) / 10); + Diags.Report(diag::warn_option_invalid_ocl_version) + << VerSpec << Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args); + } // We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension // keywords. This behavior is provided by GCC's poorly named '-fasm' flag, @@ -1510,14 +1708,17 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_fcuda_is_device)) Opts.CUDAIsDevice = 1; - if (Args.hasArg(OPT_fcuda_allow_host_calls_from_host_device)) - Opts.CUDAAllowHostCallsFromHostDevice = 1; + if (Args.hasArg(OPT_fcuda_allow_variadic_functions)) + Opts.CUDAAllowVariadicFunctions = 1; + + if (Args.hasArg(OPT_fno_cuda_host_device_constexpr)) + Opts.CUDAHostDeviceConstexpr = 0; - if (Args.hasArg(OPT_fcuda_disable_target_call_checks)) - Opts.CUDADisableTargetCallChecks = 1; + if (Opts.CUDAIsDevice && Args.hasArg(OPT_fcuda_flush_denormals_to_zero)) + Opts.CUDADeviceFlushDenormalsToZero = 1; - if (Args.hasArg(OPT_fcuda_target_overloads)) - Opts.CUDATargetOverloads = 1; + if (Opts.CUDAIsDevice && Args.hasArg(OPT_fcuda_approx_transcendentals)) + Opts.CUDADeviceApproxTranscendentals = 1; if (Opts.ObjC1) { if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) { @@ -1662,11 +1863,13 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions); Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions); Opts.SjLjExceptions = Args.hasArg(OPT_fsjlj_exceptions); + Opts.ExternCNoUnwind = Args.hasArg(OPT_fexternc_nounwind); Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp); - Opts.RTTI = !Args.hasArg(OPT_fno_rtti); + Opts.RTTI = Opts.CPlusPlus && !Args.hasArg(OPT_fno_rtti); Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data); - Opts.Blocks = Args.hasArg(OPT_fblocks); + Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL + && Opts.OpenCLVersion >= 200); Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional); Opts.Coroutines = Args.hasArg(OPT_fcoroutines); Opts.Modules = Args.hasArg(OPT_fmodules); @@ -1689,7 +1892,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (!Opts.NoBuiltin) getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs); Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin); - Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); Opts.SizedDeallocation = Args.hasArg(OPT_fsized_deallocation); Opts.ConceptsTS = Args.hasArg(OPT_fconcepts_ts); Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions); @@ -1718,8 +1920,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls); 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.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags); - Opts.PIELevel = getLastArgIntValue(Args, OPT_pie_level, 0, Diags); + Opts.PIE = Args.hasArg(OPT_pic_is_pie); Opts.Static = Args.hasArg(OPT_static_define); Opts.DumpRecordLayoutsSimple = Args.hasArg(OPT_fdump_record_layouts_simple); Opts.DumpRecordLayouts = Opts.DumpRecordLayoutsSimple @@ -1729,7 +1932,6 @@ 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); - Opts.MRTD = Args.hasArg(OPT_mrtd); Opts.HexagonQdsp6Compat = Args.hasArg(OPT_mqdsp6_compat); Opts.FakeAddressSpaceMap = Args.hasArg(OPT_ffake_address_space_map); Opts.ParseUnknownAnytype = Args.hasArg(OPT_funknown_anytype); @@ -1737,14 +1939,16 @@ 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.CurrentModule = Args.getLastArgValue(OPT_fmodule_name); + Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name_EQ); Opts.AppExt = Args.hasArg(OPT_fapplication_extension); - Opts.ImplementationOfModule = - Args.getLastArgValue(OPT_fmodule_implementation_of); Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature); std::sort(Opts.ModuleFeatures.begin(), Opts.ModuleFeatures.end()); Opts.NativeHalfType |= Args.hasArg(OPT_fnative_half_type); - Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns); + Opts.NativeHalfArgsAndReturns |= Args.hasArg(OPT_fnative_half_arguments_and_returns); + // Enable HalfArgsAndReturns if present in Args or if NativeHalfArgsAndReturns + // is enabled. + Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns) + | Opts.NativeHalfArgsAndReturns; Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm); // __declspec is enabled by default for the PS4 by the driver, and also @@ -1758,12 +1962,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Args.hasFlag(OPT_fdeclspec, OPT_fno_declspec, (Opts.MicrosoftExt || Opts.Borland || Opts.CUDA)); - if (!Opts.CurrentModule.empty() && !Opts.ImplementationOfModule.empty() && - Opts.CurrentModule != Opts.ImplementationOfModule) { - Diags.Report(diag::err_conflicting_module_names) - << Opts.CurrentModule << Opts.ImplementationOfModule; - } - // For now, we only support local submodule visibility in C++ (because we // heavily depend on the ODR for merging redefinitions). if (Opts.ModulesLocalVisibility && !Opts.CPlusPlus) @@ -1810,15 +2008,79 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.setMSPointerToMemberRepresentationMethod(InheritanceModel); } + // Check for MS default calling conventions being specified. + if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) { + LangOptions::DefaultCallingConvention DefaultCC = + llvm::StringSwitch<LangOptions::DefaultCallingConvention>( + A->getValue()) + .Case("cdecl", LangOptions::DCC_CDecl) + .Case("fastcall", LangOptions::DCC_FastCall) + .Case("stdcall", LangOptions::DCC_StdCall) + .Case("vectorcall", LangOptions::DCC_VectorCall) + .Default(LangOptions::DCC_None); + if (DefaultCC == LangOptions::DCC_None) + Diags.Report(diag::err_drv_invalid_value) + << "-fdefault-calling-conv=" << A->getValue(); + + llvm::Triple T(TargetOpts.Triple); + llvm::Triple::ArchType Arch = T.getArch(); + bool emitError = (DefaultCC == LangOptions::DCC_FastCall || + DefaultCC == LangOptions::DCC_StdCall) && + Arch != llvm::Triple::x86; + emitError |= DefaultCC == LangOptions::DCC_VectorCall && + !(Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64); + if (emitError) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getSpelling() << T.getTriple(); + else + Opts.setDefaultCallingConv(DefaultCC); + } + + // -mrtd option + if (Arg *A = Args.getLastArg(OPT_mrtd)) { + if (Opts.getDefaultCallingConv() != LangOptions::DCC_None) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getSpelling() << "-fdefault-calling-conv"; + else { + llvm::Triple T(TargetOpts.Triple); + if (T.getArch() != llvm::Triple::x86) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getSpelling() << T.getTriple(); + else + Opts.setDefaultCallingConv(LangOptions::DCC_StdCall); + } + } + // Check if -fopenmp is specified. - Opts.OpenMP = Args.hasArg(options::OPT_fopenmp); + Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 1 : 0; Opts.OpenMPUseTLS = Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls); Opts.OpenMPIsDevice = Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_device); + if (Opts.OpenMP) { + int Version = + getLastArgIntValue(Args, OPT_fopenmp_version_EQ, Opts.OpenMP, Diags); + if (Version != 0) + Opts.OpenMP = Version; + // Provide diagnostic when a given target is not expected to be an OpenMP + // device or host. + if (!Opts.OpenMPIsDevice) { + switch (T.getArch()) { + default: + break; + // Add unsupported host targets here: + case llvm::Triple::nvptx: + case llvm::Triple::nvptx64: + Diags.Report(clang::diag::err_drv_omp_host_target_not_supported) + << TargetOpts.Triple; + break; + } + } + } + // Get the OpenMP target triples if any. - if (Arg *A = Args.getLastArg(options::OPT_omptargets_EQ)) { + if (Arg *A = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) { for (unsigned i = 0; i < A->getNumValues(); ++i) { llvm::Triple TT(A->getValue(i)); @@ -1832,7 +2094,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // Get OpenMP host file path if any and report if a non existent file is // found - if (Arg *A = Args.getLastArg(options::OPT_omp_host_ir_file_path)) { + if (Arg *A = Args.getLastArg(options::OPT_fopenmp_host_ir_file_path)) { Opts.OMPHostIRFile = A->getValue(); if (!llvm::sys::fs::exists(Opts.OMPHostIRFile)) Diags.Report(clang::diag::err_drv_omp_host_ir_file_not_found) @@ -1939,10 +2201,6 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, for (const Arg *A : Args.filtered(OPT_chain_include)) Opts.ChainedIncludes.emplace_back(A->getValue()); - // Include 'altivec.h' if -faltivec option present - if (Args.hasArg(OPT_faltivec)) - Opts.Includes.emplace_back("altivec.h"); - for (const Arg *A : Args.filtered(OPT_remap_file)) { std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';'); @@ -2020,9 +2278,24 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, Opts.UseLineDirectives = Args.hasArg(OPT_fuse_line_directives); } -static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) { +static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, + DiagnosticsEngine &Diags) { using namespace options; Opts.ABI = Args.getLastArgValue(OPT_target_abi); + if (Arg *A = Args.getLastArg(OPT_meabi)) { + StringRef Value = A->getValue(); + llvm::EABI EABIVersion = llvm::StringSwitch<llvm::EABI>(Value) + .Case("default", llvm::EABI::Default) + .Case("4", llvm::EABI::EABI4) + .Case("5", llvm::EABI::EABI5) + .Case("gnu", llvm::EABI::GNU) + .Default(llvm::EABI::Unknown); + if (EABIVersion == llvm::EABI::Unknown) + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) + << Value; + else + Opts.EABIVersion = Value; + } Opts.CPU = Args.getLastArgValue(OPT_target_cpu); Opts.FPMath = Args.getLastArgValue(OPT_mfpmath); Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature); @@ -2047,6 +2320,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, InputArgList Args = Opts->ParseArgs(llvm::makeArrayRef(ArgBegin, ArgEnd), MissingArgIndex, MissingArgCount, IncludedFlagsBitmask); + LangOptions &LangOpts = *Res.getLangOpts(); // Check for missing argument error. if (MissingArgCount) { @@ -2064,12 +2338,13 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags); Success &= ParseMigratorArgs(Res.getMigratorOpts(), Args); ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args); - Success &= ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags); - ParseCommentArgs(Res.getLangOpts()->CommentOpts, Args); + Success &= ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags, + false /*DefaultDiagColor*/); + ParseCommentArgs(LangOpts.CommentOpts, Args); ParseFileSystemArgs(Res.getFileSystemOpts(), Args); // FIXME: We shouldn't have to pass the DashX option around here InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), Args, Diags); - ParseTargetArgs(Res.getTargetOpts(), Args); + ParseTargetArgs(Res.getTargetOpts(), Args, Diags); Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, Res.getTargetOpts()); ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args); @@ -2078,15 +2353,39 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, // PassManager in BackendUtil.cpp. They need to be initializd no matter // what the input type is. if (Args.hasArg(OPT_fobjc_arc)) - Res.getLangOpts()->ObjCAutoRefCount = 1; + LangOpts.ObjCAutoRefCount = 1; + // PIClevel and PIELevel are needed during code generation and this should be + // set regardless of the input type. + LangOpts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags); + LangOpts.PIE = Args.hasArg(OPT_pic_is_pie); parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), - Diags, Res.getLangOpts()->Sanitize); + Diags, LangOpts.Sanitize); } else { // Other LangOpts are only initialzed when the input is not AST or LLVM IR. - ParseLangArgs(*Res.getLangOpts(), Args, DashX, Diags); + ParseLangArgs(LangOpts, Args, DashX, Res.getTargetOpts(), + Res.getPreprocessorOpts(), Diags); if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC) - Res.getLangOpts()->ObjCExceptions = 1; + LangOpts.ObjCExceptions = 1; + } + + if (LangOpts.CUDA) { + // During CUDA device-side compilation, the aux triple is the + // triple used for host compilation. + if (LangOpts.CUDAIsDevice) + Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple; + + // Set default FP_CONTRACT to FAST. + if (!Args.hasArg(OPT_ffp_contract)) + Res.getCodeGenOpts().setFPContractMode(CodeGenOptions::FPC_Fast); } + + // FIXME: Override value name discarding when asan or msan is used because the + // backend passes depend on the name of the alloca in order to print out + // names. + Res.getCodeGenOpts().DiscardValueNames &= + !LangOpts.Sanitize.has(SanitizerKind::Address) && + !LangOpts.Sanitize.has(SanitizerKind::Memory); + // FIXME: ParsePreprocessorArgs uses the FileManager to read the contents of // PCH file and find the original header name. Remove the need to do that in // ParsePreprocessorArgs and remove the FileManager @@ -2098,59 +2397,6 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, return Success; } -namespace { - - class ModuleSignature { - SmallVector<uint64_t, 16> Data; - unsigned CurBit; - uint64_t CurValue; - - public: - ModuleSignature() : CurBit(0), CurValue(0) { } - - void add(uint64_t Value, unsigned Bits); - void add(StringRef Value); - void flush(); - - llvm::APInt getAsInteger() const; - }; -} - -void ModuleSignature::add(uint64_t Value, unsigned int NumBits) { - CurValue |= Value << CurBit; - if (CurBit + NumBits < 64) { - CurBit += NumBits; - return; - } - - // Add the current word. - Data.push_back(CurValue); - - if (CurBit) - CurValue = Value >> (64-CurBit); - else - CurValue = 0; - CurBit = (CurBit+NumBits) & 63; -} - -void ModuleSignature::flush() { - if (CurBit == 0) - return; - - Data.push_back(CurValue); - CurBit = 0; - CurValue = 0; -} - -void ModuleSignature::add(StringRef Value) { - for (auto &c : Value) - add(c, 8); -} - -llvm::APInt ModuleSignature::getAsInteger() const { - return llvm::APInt(Data.size() * 64, Data); -} - std::string CompilerInvocation::getModuleHash() const { // Note: For QoI reasons, the things we use as a hash here should all be // dumped via the -module-info flag. @@ -2217,7 +2463,7 @@ std::string CompilerInvocation::getModuleHash() const { // Extend the signature with the module file extensions. const FrontendOptions &frontendOpts = getFrontendOpts(); - for (auto ext : frontendOpts.ModuleFileExtensions) { + for (const auto &ext : frontendOpts.ModuleFileExtensions) { code = ext->hashExtension(code); } @@ -2309,8 +2555,8 @@ createVFSFromCompilerInvocation(const CompilerInvocation &CI, return IntrusiveRefCntPtr<vfs::FileSystem>(); } - IntrusiveRefCntPtr<vfs::FileSystem> FS = - vfs::getVFSFromYAML(std::move(Buffer.get()), /*DiagHandler*/ nullptr); + IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getVFSFromYAML( + std::move(Buffer.get()), /*DiagHandler*/ nullptr, File); if (!FS.get()) { Diags.Report(diag::err_invalid_vfs_overlay) << File; return IntrusiveRefCntPtr<vfs::FileSystem>(); diff --git a/lib/Frontend/CreateInvocationFromCommandLine.cpp b/lib/Frontend/CreateInvocationFromCommandLine.cpp index 301916422564f..1e9e57afb6bdf 100644 --- a/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ b/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -60,25 +60,25 @@ clang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList, } // We expect to get back exactly one command job, if we didn't something - // failed. CUDA compilation is an exception as it creates multiple jobs. If - // that's the case, we proceed with the first job. If caller needs particular - // CUDA job, it should be controlled via --cuda-{host|device}-only option - // passed to the driver. + // failed. Offload compilation is an exception as it creates multiple jobs. If + // that's the case, we proceed with the first job. If caller needs a + // particular job, it should be controlled via options (e.g. + // --cuda-{host|device}-only for CUDA) passed to the driver. const driver::JobList &Jobs = C->getJobs(); - bool CudaCompilation = false; + bool OffloadCompilation = false; if (Jobs.size() > 1) { for (auto &A : C->getActions()){ // On MacOSX real actions may end up being wrapped in BindArchAction if (isa<driver::BindArchAction>(A)) - A = *A->begin(); - if (isa<driver::CudaDeviceAction>(A)) { - CudaCompilation = true; + A = *A->input_begin(); + if (isa<driver::OffloadAction>(A)) { + OffloadCompilation = true; break; } } } if (Jobs.size() == 0 || !isa<driver::Command>(*Jobs.begin()) || - (Jobs.size() > 1 && !CudaCompilation)) { + (Jobs.size() > 1 && !OffloadCompilation)) { SmallString<256> Msg; llvm::raw_svector_ostream OS(Msg); Jobs.Print(OS, "; ", true); diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp index 93d4a80346965..a9b61282378dd 100644 --- a/lib/Frontend/DependencyFile.cpp +++ b/lib/Frontend/DependencyFile.cpp @@ -177,7 +177,7 @@ public: SeenMissingHeader(false), IncludeModuleFiles(Opts.IncludeModuleFiles), OutputFormat(Opts.OutputFormat) { - for (auto ExtraDep : Opts.ExtraDeps) { + for (const auto &ExtraDep : Opts.ExtraDeps) { AddFilename(ExtraDep); } } diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp index caf1f0dce99ff..586d2e6167b3b 100644 --- a/lib/Frontend/DiagnosticRenderer.cpp +++ b/lib/Frontend/DiagnosticRenderer.cpp @@ -23,48 +23,6 @@ #include <algorithm> using namespace clang; -/// \brief Retrieve the name of the immediate macro expansion. -/// -/// This routine starts from a source location, and finds the name of the macro -/// responsible for its immediate expansion. It looks through any intervening -/// macro argument expansions to compute this. It returns a StringRef which -/// refers to the SourceManager-owned buffer of the source where that macro -/// name is spelled. Thus, the result shouldn't out-live that SourceManager. -/// -/// This differs from Lexer::getImmediateMacroName in that any macro argument -/// location will result in the topmost function macro that accepted it. -/// e.g. -/// \code -/// MAC1( MAC2(foo) ) -/// \endcode -/// for location of 'foo' token, this function will return "MAC1" while -/// Lexer::getImmediateMacroName will return "MAC2". -static StringRef getImmediateMacroName(SourceLocation Loc, - const SourceManager &SM, - const LangOptions &LangOpts) { - assert(Loc.isMacroID() && "Only reasonble to call this on macros"); - // Walk past macro argument expanions. - while (SM.isMacroArgExpansion(Loc)) - Loc = SM.getImmediateExpansionRange(Loc).first; - - // If the macro's spelling has no FileID, then it's actually a token paste - // or stringization (or similar) and not a macro at all. - if (!SM.getFileEntryForID(SM.getFileID(SM.getSpellingLoc(Loc)))) - return StringRef(); - - // Find the spelling location of the start of the non-argument expansion - // range. This is where the macro name was spelled in order to begin - // expanding this macro. - Loc = SM.getSpellingLoc(SM.getImmediateExpansionRange(Loc).first); - - // Dig out the buffer where the macro name was spelled and the extents of the - // name so that we can render it into the expansion note. - std::pair<FileID, unsigned> ExpansionInfo = SM.getDecomposedLoc(Loc); - unsigned MacroTokenLength = Lexer::MeasureTokenLength(Loc, SM, LangOpts); - StringRef ExpansionBuffer = SM.getBufferData(ExpansionInfo.first); - return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength); -} - DiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts, DiagnosticOptions *DiagOpts) : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {} @@ -209,7 +167,8 @@ void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level, const SourceManager &SM) { - SourceLocation IncludeLoc = PLoc.getIncludeLoc(); + SourceLocation IncludeLoc = + PLoc.isInvalid() ? SourceLocation() : PLoc.getIncludeLoc(); // Skip redundant include stacks altogether. if (LastIncludeLoc == IncludeLoc) @@ -474,7 +433,8 @@ void DiagnosticRenderer::emitSingleMacroExpansion( SmallString<100> MessageStorage; llvm::raw_svector_ostream Message(MessageStorage); - StringRef MacroName = getImmediateMacroName(Loc, SM, LangOpts); + StringRef MacroName = + Lexer::getImmediateMacroNameForDiagnostics(Loc, SM, LangOpts); if (MacroName.empty()) Message << "expanded from here"; else @@ -658,7 +618,7 @@ DiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc, // Generate a note indicating the include location. SmallString<200> MessageStorage; llvm::raw_svector_ostream Message(MessageStorage); - if (PLoc.getFilename()) + if (PLoc.isValid()) Message << "while building module '" << ModuleName << "' imported from " << PLoc.getFilename() << ':' << PLoc.getLine() << ":"; else diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp index ecef92e0a7dde..d514d406d8b61 100644 --- a/lib/Frontend/FrontendAction.cpp +++ b/lib/Frontend/FrontendAction.cpp @@ -141,28 +141,46 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, if (!Consumer) return nullptr; - if (CI.getFrontendOpts().AddPluginActions.size() == 0) + // If there are no registered plugins we don't need to wrap the consumer + if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end()) return Consumer; - // Make sure the non-plugin consumer is first, so that plugins can't - // modifiy the AST. + // Collect the list of plugins that go before the main action (in Consumers) + // or after it (in AfterConsumers) std::vector<std::unique_ptr<ASTConsumer>> Consumers; - Consumers.push_back(std::move(Consumer)); - - for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); - i != e; ++i) { - // This is O(|plugins| * |add_plugins|), but since both numbers are - // way below 50 in practice, that's ok. - for (FrontendPluginRegistry::iterator - it = FrontendPluginRegistry::begin(), - ie = FrontendPluginRegistry::end(); - it != ie; ++it) { - if (it->getName() != CI.getFrontendOpts().AddPluginActions[i]) - continue; - std::unique_ptr<PluginASTAction> P = it->instantiate(); - if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i])) - Consumers.push_back(P->CreateASTConsumer(CI, InFile)); + 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(); + 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 ((ActionType == PluginASTAction::AddBeforeMainAction || + ActionType == PluginASTAction::AddAfterMainAction) && + P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs[it->getName()])) { + std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile); + if (ActionType == PluginASTAction::AddBeforeMainAction) { + Consumers.push_back(std::move(PluginConsumer)); + } else { + AfterConsumers.push_back(std::move(PluginConsumer)); + } + } + } + + // Add to Consumers the main consumer, then all the plugins that go after it + Consumers.push_back(std::move(Consumer)); + for (auto &C : AfterConsumers) { + Consumers.push_back(std::move(C)); } return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); @@ -559,7 +577,10 @@ bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) { WrappedAction->setCurrentInput(getCurrentInput()); WrappedAction->setCompilerInstance(&CI); - return WrappedAction->BeginSourceFileAction(CI, Filename); + auto Ret = WrappedAction->BeginSourceFileAction(CI, Filename); + // BeginSourceFileAction may change CurrentInput, e.g. during module builds. + setCurrentInput(WrappedAction->getCurrentInput()); + return Ret; } void WrapperFrontendAction::ExecuteAction() { WrappedAction->ExecuteAction(); @@ -587,6 +608,7 @@ bool WrapperFrontendAction::hasCodeCompletionSupport() const { return WrappedAction->hasCodeCompletionSupport(); } -WrapperFrontendAction::WrapperFrontendAction(FrontendAction *WrappedAction) - : WrappedAction(WrappedAction) {} +WrapperFrontendAction::WrapperFrontendAction( + std::unique_ptr<FrontendAction> WrappedAction) + : WrappedAction(std::move(WrappedAction)) {} diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index 407ccea2e7d16..b1e806add8cc2 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -48,8 +48,9 @@ void InitOnlyAction::ExecuteAction() { std::unique_ptr<ASTConsumer> ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) - return CreateASTPrinter(OS, CI.getFrontendOpts().ASTDumpFilter); + if (std::unique_ptr<raw_ostream> OS = + CI.createDefaultOutputFile(false, InFile)) + return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter); return nullptr; } @@ -80,7 +81,7 @@ std::unique_ptr<ASTConsumer> GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::string Sysroot; std::string OutputFile; - raw_pwrite_stream *OS = + std::unique_ptr<raw_pwrite_stream> OS = ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile); if (!OS) return nullptr; @@ -92,16 +93,21 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::vector<std::unique_ptr<ASTConsumer>> Consumers; Consumers.push_back(llvm::make_unique<PCHGenerator>( CI.getPreprocessor(), OutputFile, nullptr, Sysroot, - Buffer, CI.getFrontendOpts().ModuleFileExtensions)); + Buffer, CI.getFrontendOpts().ModuleFileExtensions, + /*AllowASTWithErrors*/false, + /*IncludeTimestamps*/ + +CI.getFrontendOpts().IncludeTimestamps)); Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( - CI, InFile, OutputFile, OS, Buffer)); + CI, InFile, OutputFile, std::move(OS), Buffer)); return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); } -raw_pwrite_stream *GeneratePCHAction::ComputeASTConsumerArguments( - CompilerInstance &CI, StringRef InFile, std::string &Sysroot, - std::string &OutputFile) { +std::unique_ptr<raw_pwrite_stream> +GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI, + StringRef InFile, + std::string &Sysroot, + std::string &OutputFile) { Sysroot = CI.getHeaderSearchOpts().Sysroot; if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) { CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot); @@ -111,7 +117,7 @@ raw_pwrite_stream *GeneratePCHAction::ComputeASTConsumerArguments( // We use createOutputFile here because this is exposed via libclang, and we // must disable the RemoveFileOnSignal behavior. // We use a temporary to avoid race conditions. - raw_pwrite_stream *OS = + std::unique_ptr<raw_pwrite_stream> OS = CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true, /*RemoveFileOnSignal=*/false, InFile, /*Extension=*/"", /*useTemporary=*/true); @@ -127,7 +133,7 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::string Sysroot; std::string OutputFile; - raw_pwrite_stream *OS = + std::unique_ptr<raw_pwrite_stream> OS = ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile); if (!OS) return nullptr; @@ -142,7 +148,7 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, /*IncludeTimestamps=*/ +CI.getFrontendOpts().BuildingImplicitModule)); Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( - CI, InFile, OutputFile, OS, Buffer)); + CI, InFile, OutputFile, std::move(OS), Buffer)); return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); } @@ -152,10 +158,10 @@ operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) { return Includes; } -static std::error_code addHeaderInclude(StringRef HeaderName, - SmallVectorImpl<char> &Includes, - const LangOptions &LangOpts, - bool IsExternC) { +static void addHeaderInclude(StringRef HeaderName, + SmallVectorImpl<char> &Includes, + const LangOptions &LangOpts, + bool IsExternC) { if (IsExternC && LangOpts.CPlusPlus) Includes += "extern \"C\" {\n"; if (LangOpts.ObjC1) @@ -168,7 +174,6 @@ static std::error_code addHeaderInclude(StringRef HeaderName, Includes += "\"\n"; if (IsExternC && LangOpts.CPlusPlus) Includes += "}\n"; - return std::error_code(); } /// \brief Collect the set of header includes needed to construct the given @@ -194,38 +199,34 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, // file relative to the module build directory (the directory containing // the module map file) so this will find the same file that we found // while parsing the module map. - if (std::error_code Err = addHeaderInclude(H.NameAsWritten, Includes, - LangOpts, Module->IsExternC)) - return Err; + addHeaderInclude(H.NameAsWritten, Includes, LangOpts, Module->IsExternC); } } // Note that Module->PrivateHeaders will not be a TopHeader. if (Module::Header UmbrellaHeader = Module->getUmbrellaHeader()) { Module->addTopHeader(UmbrellaHeader.Entry); - if (Module->Parent) { + if (Module->Parent) // Include the umbrella header for submodules. - if (std::error_code Err = addHeaderInclude(UmbrellaHeader.NameAsWritten, - Includes, LangOpts, - Module->IsExternC)) - return Err; - } + addHeaderInclude(UmbrellaHeader.NameAsWritten, Includes, LangOpts, + Module->IsExternC); } else if (Module::DirectoryName UmbrellaDir = Module->getUmbrellaDir()) { // Add all of the headers we find in this subdirectory. std::error_code EC; SmallString<128> DirNative; llvm::sys::path::native(UmbrellaDir.Entry->getName(), DirNative); - for (llvm::sys::fs::recursive_directory_iterator Dir(DirNative, EC), - DirEnd; - Dir != DirEnd && !EC; Dir.increment(EC)) { + + vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); + for (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 // headers. - if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path())) + if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->getName())) .Cases(".h", ".H", ".hh", ".hpp", true) .Default(false)) continue; - const FileEntry *Header = FileMgr.getFile(Dir->path()); + const FileEntry *Header = FileMgr.getFile(Dir->getName()); // FIXME: This shouldn't happen unless there is a file system race. Is // that worth diagnosing? if (!Header) @@ -238,7 +239,7 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, // Compute the relative path from the directory to this file. SmallVector<StringRef, 16> Components; - auto PathIt = llvm::sys::path::rbegin(Dir->path()); + auto PathIt = llvm::sys::path::rbegin(Dir->getName()); for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt) Components.push_back(*PathIt); SmallString<128> RelativeHeader(UmbrellaDir.NameAsWritten); @@ -248,9 +249,7 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, // Include this header as part of the umbrella directory. Module->addTopHeader(Header); - if (std::error_code Err = addHeaderInclude(RelativeHeader, Includes, - LangOpts, Module->IsExternC)) - return Err; + addHeaderInclude(RelativeHeader, Includes, LangOpts, Module->IsExternC); } if (EC) @@ -270,6 +269,8 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) { + CI.getLangOpts().CompilingModule = true; + // Find the module map file. const FileEntry *ModuleMap = CI.getFileManager().getFile(Filename, /*openFile*/true); @@ -354,10 +355,9 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, SmallString<256> HeaderContents; std::error_code Err = std::error_code(); if (Module::Header UmbrellaHeader = Module->getUmbrellaHeader()) - Err = addHeaderInclude(UmbrellaHeader.NameAsWritten, HeaderContents, - CI.getLangOpts(), Module->IsExternC); - if (!Err) - Err = collectModuleHeaderIncludes( + addHeaderInclude(UmbrellaHeader.NameAsWritten, HeaderContents, + CI.getLangOpts(), Module->IsExternC); + Err = collectModuleHeaderIncludes( CI.getLangOpts(), FileMgr, CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), Module, HeaderContents); @@ -381,9 +381,11 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, return true; } -raw_pwrite_stream *GenerateModuleAction::ComputeASTConsumerArguments( - CompilerInstance &CI, StringRef InFile, std::string &Sysroot, - std::string &OutputFile) { +std::unique_ptr<raw_pwrite_stream> +GenerateModuleAction::ComputeASTConsumerArguments(CompilerInstance &CI, + StringRef InFile, + std::string &Sysroot, + std::string &OutputFile) { // If no output file was provided, figure out where this module would go // in the module cache. if (CI.getFrontendOpts().OutputFile.empty()) { @@ -396,7 +398,7 @@ raw_pwrite_stream *GenerateModuleAction::ComputeASTConsumerArguments( // We use createOutputFile here because this is exposed via libclang, and we // must disable the RemoveFileOnSignal behavior. // We use a temporary to avoid race conditions. - raw_pwrite_stream *OS = + std::unique_ptr<raw_pwrite_stream> OS = CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true, /*RemoveFileOnSignal=*/false, InFile, /*Extension=*/"", /*useTemporary=*/true, @@ -408,6 +410,9 @@ raw_pwrite_stream *GenerateModuleAction::ComputeASTConsumerArguments( return OS; } +SyntaxOnlyAction::~SyntaxOnlyAction() { +} + std::unique_ptr<ASTConsumer> SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { return llvm::make_unique<ASTConsumer>(); @@ -647,11 +652,12 @@ void DumpTokensAction::ExecuteAction() { void GeneratePTHAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); - raw_pwrite_stream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); + std::unique_ptr<raw_pwrite_stream> OS = + CI.createDefaultOutputFile(true, getCurrentFile()); if (!OS) return; - CacheTokens(CI.getPreprocessor(), OS); + CacheTokens(CI.getPreprocessor(), OS.get()); } void PreprocessOnlyAction::ExecuteAction() { @@ -707,14 +713,16 @@ void PrintPreprocessedAction::ExecuteAction() { } else if (*cur == 0x0A) // LF break; - ++cur, ++next; + ++cur; + ++next; } } - raw_ostream *OS = CI.createDefaultOutputFile(BinaryMode, getCurrentFile()); + std::unique_ptr<raw_ostream> OS = + CI.createDefaultOutputFile(BinaryMode, getCurrentFile()); if (!OS) return; - DoPrintPreprocessedInput(CI.getPreprocessor(), OS, + DoPrintPreprocessedInput(CI.getPreprocessor(), OS.get(), CI.getPreprocessorOutputOpts()); } @@ -737,6 +745,7 @@ void PrintPreambleAction::ExecuteAction() { case IK_PreprocessedObjCXX: case IK_AST: case IK_LLVM_IR: + case IK_RenderScript: // We can't do anything with these. return; } diff --git a/lib/Frontend/HeaderIncludeGen.cpp b/lib/Frontend/HeaderIncludeGen.cpp index 0bc1169ba0a97..5bff4ecd0b46c 100644 --- a/lib/Frontend/HeaderIncludeGen.cpp +++ b/lib/Frontend/HeaderIncludeGen.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/Frontend/DependencyOutputOptions.h" #include "clang/Frontend/Utils.h" #include "clang/Basic/SourceManager.h" #include "clang/Frontend/FrontendDiagnostic.h" @@ -19,6 +20,7 @@ namespace { class HeaderIncludesCallback : public PPCallbacks { SourceManager &SM; raw_ostream *OutputFile; + const DependencyOutputOptions &DepOpts; unsigned CurrentIncludeDepth; bool HasProcessedPredefines; bool OwnsOutputFile; @@ -28,12 +30,13 @@ class HeaderIncludesCallback : public PPCallbacks { public: HeaderIncludesCallback(const Preprocessor *PP, bool ShowAllHeaders_, - raw_ostream *OutputFile_, bool OwnsOutputFile_, - bool ShowDepth_, bool MSStyle_) - : SM(PP->getSourceManager()), OutputFile(OutputFile_), - CurrentIncludeDepth(0), HasProcessedPredefines(false), - OwnsOutputFile(OwnsOutputFile_), ShowAllHeaders(ShowAllHeaders_), - ShowDepth(ShowDepth_), MSStyle(MSStyle_) {} + raw_ostream *OutputFile_, + const DependencyOutputOptions &DepOpts, + bool OwnsOutputFile_, bool ShowDepth_, bool MSStyle_) + : SM(PP->getSourceManager()), OutputFile(OutputFile_), DepOpts(DepOpts), + CurrentIncludeDepth(0), HasProcessedPredefines(false), + OwnsOutputFile(OwnsOutputFile_), ShowAllHeaders(ShowAllHeaders_), + ShowDepth(ShowDepth_), MSStyle(MSStyle_) {} ~HeaderIncludesCallback() override { if (OwnsOutputFile) @@ -46,38 +49,37 @@ public: }; } -static void PrintHeaderInfo(raw_ostream *OutputFile, const char* Filename, +static void PrintHeaderInfo(raw_ostream *OutputFile, StringRef Filename, bool ShowDepth, unsigned CurrentIncludeDepth, bool MSStyle) { - // Write to a temporary string to avoid unnecessary flushing on errs(). - SmallString<512> Pathname(Filename); - if (!MSStyle) - Lexer::Stringify(Pathname); + // Write to a temporary string to avoid unnecessary flushing on errs(). + SmallString<512> Pathname(Filename); + if (!MSStyle) + Lexer::Stringify(Pathname); - SmallString<256> Msg; - if (MSStyle) - Msg += "Note: including file:"; + SmallString<256> Msg; + if (MSStyle) + Msg += "Note: including file:"; - if (ShowDepth) { - // The main source file is at depth 1, so skip one dot. - for (unsigned i = 1; i != CurrentIncludeDepth; ++i) - Msg += MSStyle ? ' ' : '.'; + if (ShowDepth) { + // The main source file is at depth 1, so skip one dot. + for (unsigned i = 1; i != CurrentIncludeDepth; ++i) + Msg += MSStyle ? ' ' : '.'; - if (!MSStyle) - Msg += ' '; - } - Msg += Pathname; - Msg += '\n'; + if (!MSStyle) + Msg += ' '; + } + Msg += Pathname; + Msg += '\n'; - OutputFile->write(Msg.data(), Msg.size()); - OutputFile->flush(); + *OutputFile << Msg; + OutputFile->flush(); } void clang::AttachHeaderIncludeGen(Preprocessor &PP, - const std::vector<std::string> &ExtraHeaders, - bool ShowAllHeaders, - StringRef OutputPath, bool ShowDepth, - bool MSStyle) { + const DependencyOutputOptions &DepOpts, + bool ShowAllHeaders, StringRef OutputPath, + bool ShowDepth, bool MSStyle) { raw_ostream *OutputFile = MSStyle ? &llvm::outs() : &llvm::errs(); bool OwnsOutputFile = false; @@ -97,20 +99,16 @@ void clang::AttachHeaderIncludeGen(Preprocessor &PP, } } - // Print header info for extra headers, pretending they were discovered - // by the regular preprocessor. The primary use case is to support - // proper generation of Make / Ninja file dependencies for implicit includes, - // such as sanitizer blacklists. It's only important for cl.exe - // compatibility, the GNU way to generate rules is -M / -MM / -MD / -MMD. - for (auto Header : ExtraHeaders) { - PrintHeaderInfo(OutputFile, Header.c_str(), ShowDepth, 2, MSStyle); - } - PP.addPPCallbacks(llvm::make_unique<HeaderIncludesCallback>(&PP, - ShowAllHeaders, - OutputFile, - OwnsOutputFile, - ShowDepth, - MSStyle)); + // Print header info for extra headers, pretending they were discovered by + // the regular preprocessor. The primary use case is to support proper + // generation of Make / Ninja file dependencies for implicit includes, such + // as sanitizer blacklists. It's only important for cl.exe compatibility, + // the GNU way to generate rules is -M / -MM / -MD / -MMD. + for (const auto &Header : DepOpts.ExtraDeps) + PrintHeaderInfo(OutputFile, Header, ShowDepth, 2, MSStyle); + PP.addPPCallbacks(llvm::make_unique<HeaderIncludesCallback>( + &PP, ShowAllHeaders, OutputFile, DepOpts, OwnsOutputFile, ShowDepth, + MSStyle)); } void HeaderIncludesCallback::FileChanged(SourceLocation Loc, @@ -132,8 +130,13 @@ void HeaderIncludesCallback::FileChanged(SourceLocation Loc, // We track when we are done with the predefines by watching for the first // place where we drop back to a nesting depth of 1. - if (CurrentIncludeDepth == 1 && !HasProcessedPredefines) + if (CurrentIncludeDepth == 1 && !HasProcessedPredefines) { + if (!DepOpts.ShowIncludesPretendHeader.empty()) { + PrintHeaderInfo(OutputFile, DepOpts.ShowIncludesPretendHeader, + ShowDepth, 2, MSStyle); + } HasProcessedPredefines = true; + } return; } else @@ -144,11 +147,20 @@ void HeaderIncludesCallback::FileChanged(SourceLocation Loc, // line buffers. bool ShowHeader = (HasProcessedPredefines || (ShowAllHeaders && CurrentIncludeDepth > 2)); + unsigned IncludeDepth = CurrentIncludeDepth; + if (!HasProcessedPredefines) + --IncludeDepth; // Ignore indent from <built-in>. + else if (!DepOpts.ShowIncludesPretendHeader.empty()) + ++IncludeDepth; // Pretend inclusion by ShowIncludesPretendHeader. // Dump the header include information we are past the predefines buffer or - // are showing all headers. - if (ShowHeader && Reason == PPCallbacks::EnterFile) { - PrintHeaderInfo(OutputFile, UserLoc.getFilename(), - ShowDepth, CurrentIncludeDepth, MSStyle); + // are showing all headers and this isn't the magic implicit <command line> + // header. + // FIXME: Identify headers in a more robust way than comparing their name to + // "<command line>" and "<built-in>" in a bunch of places. + if (ShowHeader && Reason == PPCallbacks::EnterFile && + UserLoc.getFilename() != StringRef("<command line>")) { + PrintHeaderInfo(OutputFile, UserLoc.getFilename(), ShowDepth, IncludeDepth, + MSStyle); } } diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index 26bab0db53479..1b5c760f01b5b 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -267,38 +267,39 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, } case llvm::Triple::Haiku: - AddPath("/boot/common/include", System, false); - AddPath("/boot/develop/headers/os", System, false); - AddPath("/boot/develop/headers/os/app", System, false); - AddPath("/boot/develop/headers/os/arch", System, false); - AddPath("/boot/develop/headers/os/device", System, false); - AddPath("/boot/develop/headers/os/drivers", System, false); - AddPath("/boot/develop/headers/os/game", System, false); - AddPath("/boot/develop/headers/os/interface", System, false); - AddPath("/boot/develop/headers/os/kernel", System, false); - AddPath("/boot/develop/headers/os/locale", System, false); - AddPath("/boot/develop/headers/os/mail", System, false); - AddPath("/boot/develop/headers/os/media", System, false); - AddPath("/boot/develop/headers/os/midi", System, false); - AddPath("/boot/develop/headers/os/midi2", System, false); - AddPath("/boot/develop/headers/os/net", System, false); - AddPath("/boot/develop/headers/os/storage", System, false); - AddPath("/boot/develop/headers/os/support", System, false); - AddPath("/boot/develop/headers/os/translation", System, false); - AddPath("/boot/develop/headers/os/add-ons/graphics", System, false); - AddPath("/boot/develop/headers/os/add-ons/input_server", System, false); - AddPath("/boot/develop/headers/os/add-ons/screen_saver", System, false); - AddPath("/boot/develop/headers/os/add-ons/tracker", System, false); - AddPath("/boot/develop/headers/os/be_apps/Deskbar", System, false); - AddPath("/boot/develop/headers/os/be_apps/NetPositive", System, false); - AddPath("/boot/develop/headers/os/be_apps/Tracker", System, false); - AddPath("/boot/develop/headers/cpp", System, false); - AddPath("/boot/develop/headers/cpp/i586-pc-haiku", System, false); - AddPath("/boot/develop/headers/3rdparty", System, false); - AddPath("/boot/develop/headers/bsd", System, false); - AddPath("/boot/develop/headers/glibc", System, false); - AddPath("/boot/develop/headers/posix", System, false); - AddPath("/boot/develop/headers", System, false); + AddPath("/boot/system/non-packaged/develop/headers", System, false); + AddPath("/boot/system/develop/headers/os", System, false); + AddPath("/boot/system/develop/headers/os/app", System, false); + AddPath("/boot/system/develop/headers/os/arch", System, false); + AddPath("/boot/system/develop/headers/os/device", System, false); + AddPath("/boot/system/develop/headers/os/drivers", System, false); + AddPath("/boot/system/develop/headers/os/game", System, false); + AddPath("/boot/system/develop/headers/os/interface", System, false); + AddPath("/boot/system/develop/headers/os/kernel", System, false); + AddPath("/boot/system/develop/headers/os/locale", System, false); + AddPath("/boot/system/develop/headers/os/mail", System, false); + AddPath("/boot/system/develop/headers/os/media", System, false); + AddPath("/boot/system/develop/headers/os/midi", System, false); + AddPath("/boot/system/develop/headers/os/midi2", System, false); + AddPath("/boot/system/develop/headers/os/net", System, false); + AddPath("/boot/system/develop/headers/os/opengl", System, false); + AddPath("/boot/system/develop/headers/os/storage", System, false); + AddPath("/boot/system/develop/headers/os/support", System, false); + AddPath("/boot/system/develop/headers/os/translation", System, false); + AddPath("/boot/system/develop/headers/os/add-ons/graphics", System, false); + AddPath("/boot/system/develop/headers/os/add-ons/input_server", System, false); + AddPath("/boot/system/develop/headers/os/add-ons/mail_daemon", System, false); + AddPath("/boot/system/develop/headers/os/add-ons/registrar", System, false); + AddPath("/boot/system/develop/headers/os/add-ons/screen_saver", System, false); + AddPath("/boot/system/develop/headers/os/add-ons/tracker", System, false); + AddPath("/boot/system/develop/headers/os/be_apps/Deskbar", System, false); + AddPath("/boot/system/develop/headers/os/be_apps/NetPositive", System, false); + AddPath("/boot/system/develop/headers/os/be_apps/Tracker", System, false); + AddPath("/boot/system/develop/headers/3rdparty", System, false); + AddPath("/boot/system/develop/headers/bsd", System, false); + AddPath("/boot/system/develop/headers/glibc", System, false); + AddPath("/boot/system/develop/headers/posix", System, false); + AddPath("/boot/system/develop/headers", System, false); break; case llvm::Triple::RTEMS: break; @@ -326,7 +327,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, // <isysroot> gets prepended later in AddPath(). std::string BaseSDKPath = ""; if (!HasSysroot) { - const char *envValue = getenv("SCE_PS4_SDK_DIR"); + const char *envValue = getenv("SCE_ORBIS_SDK_DIR"); if (envValue) BaseSDKPath = envValue; else { diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 15aa54607cedf..6b93c697d9b1e 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -408,6 +408,39 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, if (LangOpts.ObjC1) Builder.defineMacro("__OBJC__"); + // OpenCL v1.0/1.1 s6.9, v1.2/2.0 s6.10: Preprocessor Directives and Macros. + if (LangOpts.OpenCL) { + // OpenCL v1.0 and v1.1 do not have a predefined macro to indicate the + // language standard with which the program is compiled. __OPENCL_VERSION__ + // is for the OpenCL version supported by the OpenCL device, which is not + // necessarily the language standard with which the program is compiled. + // A shared OpenCL header file requires a macro to indicate the language + // standard. As a workaround, __OPENCL_C_VERSION__ is defined for + // OpenCL v1.0 and v1.1. + switch (LangOpts.OpenCLVersion) { + case 100: + Builder.defineMacro("__OPENCL_C_VERSION__", "100"); + break; + case 110: + Builder.defineMacro("__OPENCL_C_VERSION__", "110"); + break; + case 120: + Builder.defineMacro("__OPENCL_C_VERSION__", "120"); + break; + case 200: + Builder.defineMacro("__OPENCL_C_VERSION__", "200"); + break; + default: + llvm_unreachable("Unsupported OpenCL version"); + } + Builder.defineMacro("CL_VERSION_1_0", "100"); + Builder.defineMacro("CL_VERSION_1_1", "110"); + Builder.defineMacro("CL_VERSION_1_2", "120"); + Builder.defineMacro("CL_VERSION_2_0", "200"); + + if (LangOpts.FastRelaxedMath) + Builder.defineMacro("__FAST_RELAXED_MATH__"); + } // Not "standard" per se, but available even with the -undef flag. if (LangOpts.AsmPreprocessor) Builder.defineMacro("__ASSEMBLER__"); @@ -793,8 +826,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI, DefineFastIntType(64, true, TI, Builder); DefineFastIntType(64, false, TI, Builder); - if (const char *Prefix = TI.getUserLabelPrefix()) - Builder.defineMacro("__USER_LABEL_PREFIX__", Prefix); + char UserLabelPrefix[2] = {TI.getDataLayout().getGlobalPrefix(), 0}; + Builder.defineMacro("__USER_LABEL_PREFIX__", UserLabelPrefix); if (LangOpts.FastMath || LangOpts.FiniteMathOnly) Builder.defineMacro("__FINITE_MATH_ONLY__", "1"); @@ -811,7 +844,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, // FIXME: This is target-dependent. Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1"); - // Used by libstdc++ to implement ATOMIC_<foo>_LOCK_FREE. + // Used by libc++ and libstdc++ to implement ATOMIC_<foo>_LOCK_FREE. unsigned InlineWidthBits = TI.getMaxAtomicInlineWidth(); #define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \ Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \ @@ -840,10 +873,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (unsigned PICLevel = LangOpts.PICLevel) { Builder.defineMacro("__PIC__", Twine(PICLevel)); Builder.defineMacro("__pic__", Twine(PICLevel)); - } - if (unsigned PIELevel = LangOpts.PIELevel) { - Builder.defineMacro("__PIE__", Twine(PIELevel)); - Builder.defineMacro("__pie__", Twine(PIELevel)); + if (LangOpts.PIE) { + Builder.defineMacro("__PIE__", Twine(PICLevel)); + Builder.defineMacro("__pie__", Twine(PICLevel)); + } } // Macros to control C99 numerics and <float.h> @@ -889,13 +922,24 @@ static void InitializePredefinedMacros(const TargetInfo &TI, } // OpenMP definition - if (LangOpts.OpenMP) { - // OpenMP 2.2: - // In implementations that support a preprocessor, the _OPENMP - // macro name is defined to have the decimal value yyyymm where - // yyyy and mm are the year and the month designations of the - // version of the OpenMP API that the implementation support. + // OpenMP 2.2: + // In implementations that support a preprocessor, the _OPENMP + // macro name is defined to have the decimal value yyyymm where + // yyyy and mm are the year and the month designations of the + // version of the OpenMP API that the implementation support. + switch (LangOpts.OpenMP) { + case 0: + break; + case 40: Builder.defineMacro("_OPENMP", "201307"); + break; + case 45: + Builder.defineMacro("_OPENMP", "201511"); + break; + default: + // Default version is OpenMP 3.1 + Builder.defineMacro("_OPENMP", "201107"); + break; } // CUDA device path compilaton @@ -905,6 +949,21 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__CUDA_ARCH__"); } + // We need to communicate this to our CUDA header wrapper, which in turn + // informs the proper CUDA headers of this choice. + if (LangOpts.CUDADeviceApproxTranscendentals || LangOpts.FastMath) { + Builder.defineMacro("__CLANG_CUDA_APPROX_TRANSCENDENTALS__"); + } + + // OpenCL definitions. + if (LangOpts.OpenCL) { +#define OPENCLEXT(Ext) \ + if (TI.getSupportedOpenCLOpts().is_##Ext##_supported( \ + LangOpts.OpenCLVersion)) \ + Builder.defineMacro(#Ext); +#include "clang/Basic/OpenCLExtensions.def" + } + // Get other target #defines. TI.getTargetDefines(LangOpts, Builder); } @@ -972,6 +1031,10 @@ void clang::InitializePreprocessor( PP.getDiagnostics()); } + // Exit the command line and go back to <built-in> (2 is LC_LEAVE). + if (!PP.getLangOpts().AsmPreprocessor) + Builder.append("# 1 \"<built-in>\" 2"); + // If -imacros are specified, include them now. These are processed before // any -include directives. for (unsigned i = 0, e = InitOpts.MacroIncludes.size(); i != e; ++i) @@ -990,10 +1053,6 @@ void clang::InitializePreprocessor( AddImplicitInclude(Builder, Path); } - // Exit the command line and go back to <built-in> (2 is LC_LEAVE). - if (!PP.getLangOpts().AsmPreprocessor) - Builder.append("# 1 \"<built-in>\" 2"); - // Instruct the preprocessor to skip the preamble. PP.setSkipMainFilePreamble(InitOpts.PrecompiledPreambleBytes.first, InitOpts.PrecompiledPreambleBytes.second); diff --git a/lib/Frontend/LayoutOverrideSource.cpp b/lib/Frontend/LayoutOverrideSource.cpp index 924a64068fe4e..06e9a7dc50b46 100644 --- a/lib/Frontend/LayoutOverrideSource.cpp +++ b/lib/Frontend/LayoutOverrideSource.cpp @@ -188,7 +188,7 @@ LayoutOverrideSource::layoutRecordType(const RecordDecl *Record, return true; } -void LayoutOverrideSource::dump() { +LLVM_DUMP_METHOD void LayoutOverrideSource::dump() { raw_ostream &OS = llvm::errs(); for (llvm::StringMap<Layout>::iterator L = Layouts.begin(), LEnd = Layouts.end(); diff --git a/lib/Frontend/Makefile b/lib/Frontend/Makefile deleted file mode 100644 index 8554b7649fa2f..0000000000000 --- a/lib/Frontend/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- clang/lib/Frontend/Makefile -------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -DIRS := Rewrite -LIBRARYNAME := clangFrontend - -include $(CLANG_LEVEL)/Makefile diff --git a/lib/Frontend/ModuleDependencyCollector.cpp b/lib/Frontend/ModuleDependencyCollector.cpp index 9768a164acbc4..ca11f9b863bb9 100644 --- a/lib/Frontend/ModuleDependencyCollector.cpp +++ b/lib/Frontend/ModuleDependencyCollector.cpp @@ -11,9 +11,11 @@ // //===----------------------------------------------------------------------===// +#include "clang/Basic/CharInfo.h" #include "clang/Frontend/Utils.h" +#include "clang/Lex/Preprocessor.h" #include "clang/Serialization/ASTReader.h" -#include "llvm/ADT/StringSet.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" @@ -22,73 +24,202 @@ using namespace clang; namespace { -/// Private implementation for ModuleDependencyCollector +/// Private implementations for ModuleDependencyCollector class ModuleDependencyListener : public ASTReaderListener { ModuleDependencyCollector &Collector; - - std::error_code copyToRoot(StringRef Src); public: ModuleDependencyListener(ModuleDependencyCollector &Collector) : Collector(Collector) {} bool needsInputFileVisitation() override { return true; } bool needsSystemInputFileVisitation() override { return true; } bool visitInputFile(StringRef Filename, bool IsSystem, bool IsOverridden, - bool IsExplicitModule) override; + bool IsExplicitModule) override { + Collector.addFile(Filename); + return true; + } +}; + +struct ModuleDependencyMMCallbacks : public ModuleMapCallbacks { + ModuleDependencyCollector &Collector; + ModuleDependencyMMCallbacks(ModuleDependencyCollector &Collector) + : Collector(Collector) {} + + void moduleMapAddHeader(StringRef HeaderPath) override { + if (llvm::sys::path::is_absolute(HeaderPath)) + Collector.addFile(HeaderPath); + } + void moduleMapAddUmbrellaHeader(FileManager *FileMgr, + const FileEntry *Header) override { + StringRef HeaderFilename = Header->getName(); + moduleMapAddHeader(HeaderFilename); + // The FileManager can find and cache the symbolic link for a framework + // header before its real path, this means a module can have some of its + // headers to use other paths. Although this is usually not a problem, it's + // inconsistent, and not collecting the original path header leads to + // umbrella clashes while rebuilding modules in the crash reproducer. For + // example: + // ApplicationServices.framework/Frameworks/ImageIO.framework/ImageIO.h + // instead of: + // ImageIO.framework/ImageIO.h + // + // FIXME: this shouldn't be necessary once we have FileName instances + // around instead of FileEntry ones. For now, make sure we collect all + // that we need for the reproducer to work correctly. + StringRef UmbreallDirFromHeader = + llvm::sys::path::parent_path(HeaderFilename); + StringRef UmbrellaDir = Header->getDir()->getName(); + if (!UmbrellaDir.equals(UmbreallDirFromHeader)) { + SmallString<128> AltHeaderFilename; + llvm::sys::path::append(AltHeaderFilename, UmbrellaDir, + llvm::sys::path::filename(HeaderFilename)); + if (FileMgr->getFile(AltHeaderFilename)) + moduleMapAddHeader(AltHeaderFilename); + } + } }; + +} + +// TODO: move this to Support/Path.h and check for HAVE_REALPATH? +static bool real_path(StringRef SrcPath, SmallVectorImpl<char> &RealPath) { +#ifdef LLVM_ON_UNIX + char CanonicalPath[PATH_MAX]; + + // TODO: emit a warning in case this fails...? + if (!realpath(SrcPath.str().c_str(), CanonicalPath)) + return false; + + SmallString<256> RPath(CanonicalPath); + RealPath.swap(RPath); + return true; +#else + // FIXME: Add support for systems without realpath. + return false; +#endif } void ModuleDependencyCollector::attachToASTReader(ASTReader &R) { R.addListener(llvm::make_unique<ModuleDependencyListener>(*this)); } +void ModuleDependencyCollector::attachToPreprocessor(Preprocessor &PP) { + PP.getHeaderSearchInfo().getModuleMap().addModuleMapCallbacks( + llvm::make_unique<ModuleDependencyMMCallbacks>(*this)); +} + +static bool isCaseSensitivePath(StringRef Path) { + SmallString<256> TmpDest = Path, UpperDest, RealDest; + // Remove component traversals, links, etc. + if (!real_path(Path, TmpDest)) + return true; // Current default value in vfs.yaml + Path = TmpDest; + + // Change path to all upper case and ask for its real path, if the latter + // exists and is equal to Path, it's not case sensitive. Default to case + // sensitive in the absense of realpath, since this is what the VFSWriter + // already expects when sensitivity isn't setup. + for (auto &C : Path) + UpperDest.push_back(toUppercase(C)); + if (real_path(UpperDest, RealDest) && Path.equals(RealDest)) + return false; + return true; +} + void ModuleDependencyCollector::writeFileMap() { if (Seen.empty()) return; - SmallString<256> Dest = getDest(); - llvm::sys::path::append(Dest, "vfs.yaml"); + StringRef VFSDir = getDest(); + + // Default to use relative overlay directories in the VFS yaml file. This + // allows crash reproducer scripts to work across machines. + VFSWriter.setOverlayDir(VFSDir); + + // Explicitly set case sensitivity for the YAML writer. For that, find out + // the sensitivity at the path where the headers all collected to. + VFSWriter.setCaseSensitivity(isCaseSensitivePath(VFSDir)); + + // Do not rely on real path names when executing the crash reproducer scripts + // since we only want to actually use the files we have on the VFS cache. + VFSWriter.setUseExternalNames(false); std::error_code EC; - llvm::raw_fd_ostream OS(Dest, EC, llvm::sys::fs::F_Text); + SmallString<256> YAMLPath = VFSDir; + llvm::sys::path::append(YAMLPath, "vfs.yaml"); + llvm::raw_fd_ostream OS(YAMLPath, EC, llvm::sys::fs::F_Text); if (EC) { - setHasErrors(); + HasErrors = true; return; } VFSWriter.write(OS); } -std::error_code ModuleDependencyListener::copyToRoot(StringRef Src) { +bool ModuleDependencyCollector::getRealPath(StringRef SrcPath, + SmallVectorImpl<char> &Result) { + using namespace llvm::sys; + SmallString<256> RealPath; + StringRef FileName = path::filename(SrcPath); + std::string Dir = path::parent_path(SrcPath).str(); + auto DirWithSymLink = SymLinkMap.find(Dir); + + // Use real_path to fix any symbolic link component present in a path. + // Computing the real path is expensive, cache the search through the + // parent path directory. + if (DirWithSymLink == SymLinkMap.end()) { + if (!real_path(Dir, RealPath)) + return false; + SymLinkMap[Dir] = RealPath.str(); + } else { + RealPath = DirWithSymLink->second; + } + + path::append(RealPath, FileName); + Result.swap(RealPath); + return true; +} + +std::error_code ModuleDependencyCollector::copyToRoot(StringRef Src) { using namespace llvm::sys; - // We need an absolute path to append to the root. + // We need an absolute src path to append to the root. SmallString<256> AbsoluteSrc = Src; fs::make_absolute(AbsoluteSrc); - // Canonicalize to a native path to avoid mixed separator styles. + // Canonicalize src to a native path to avoid mixed separator styles. path::native(AbsoluteSrc); - // TODO: We probably need to handle .. as well as . in order to have valid - // input to the YAMLVFSWriter. - path::remove_dots(AbsoluteSrc); + // Remove redundant leading "./" pieces and consecutive separators. + AbsoluteSrc = path::remove_leading_dotslash(AbsoluteSrc); - // Build the destination path. - SmallString<256> Dest = Collector.getDest(); - path::append(Dest, path::relative_path(AbsoluteSrc)); + // Canonicalize the source path by removing "..", "." components. + SmallString<256> CanonicalPath = AbsoluteSrc; + path::remove_dots(CanonicalPath, /*remove_dot_dot=*/true); + + // If a ".." component is present after a symlink component, remove_dots may + // lead to the wrong real destination path. Let the source be canonicalized + // like that but make sure we always use the real path for the destination. + SmallString<256> RealPath; + if (!getRealPath(AbsoluteSrc, RealPath)) + RealPath = CanonicalPath; + SmallString<256> Dest = getDest(); + path::append(Dest, path::relative_path(RealPath)); // Copy the file into place. if (std::error_code EC = fs::create_directories(path::parent_path(Dest), /*IgnoreExisting=*/true)) return EC; - if (std::error_code EC = fs::copy_file(AbsoluteSrc, Dest)) + if (std::error_code EC = fs::copy_file(RealPath, Dest)) return EC; - // Use the absolute path under the root for the file mapping. - Collector.addFileMapping(AbsoluteSrc, Dest); + + // Always map a canonical src path to its real path into the YAML, by doing + // this we map different virtual src paths to the same entry in the VFS + // overlay, which is a way to emulate symlink inside the VFS; this is also + // needed for correctness, not doing that can lead to module redifinition + // errors. + addFileMapping(CanonicalPath, Dest); return std::error_code(); } -bool ModuleDependencyListener::visitInputFile(StringRef Filename, bool IsSystem, - bool IsOverridden, - bool IsExplicitModule) { - if (Collector.insertSeen(Filename)) +void ModuleDependencyCollector::addFile(StringRef Filename) { + if (insertSeen(Filename)) if (copyToRoot(Filename)) - Collector.setHasErrors(); - return true; + HasErrors = true; } diff --git a/lib/Frontend/MultiplexConsumer.cpp b/lib/Frontend/MultiplexConsumer.cpp index f8b73e9034b3e..17cdaee4be05c 100644 --- a/lib/Frontend/MultiplexConsumer.cpp +++ b/lib/Frontend/MultiplexConsumer.cpp @@ -125,6 +125,8 @@ public: void FunctionDefinitionInstantiated(const FunctionDecl *D) override; void DeclarationMarkedUsed(const Decl *D) override; void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; + void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, + const Attr *Attr) override; void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; void AddedAttributeToRecord(const Attr *Attr, const RecordDecl *Record) override; @@ -219,6 +221,11 @@ void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate( for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D); } +void MultiplexASTMutationListener::DeclarationMarkedOpenMPDeclareTarget( + const Decl *D, const Attr *Attr) { + for (auto *L : Listeners) + L->DeclarationMarkedOpenMPDeclareTarget(D, Attr); +} void MultiplexASTMutationListener::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) { for (auto *L : Listeners) @@ -272,9 +279,9 @@ bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { return Continue; } -void MultiplexConsumer::HandleInlineMethodDefinition(CXXMethodDecl *D) { +void MultiplexConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) { for (auto &Consumer : Consumers) - Consumer->HandleInlineMethodDefinition(D); + Consumer->HandleInlineFunctionDefinition(D); } void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { @@ -317,24 +324,14 @@ void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) { Consumer->HandleImplicitImportDecl(D); } -void MultiplexConsumer::HandleLinkerOptionPragma(llvm::StringRef Opts) { - for (auto &Consumer : Consumers) - Consumer->HandleLinkerOptionPragma(Opts); -} - -void MultiplexConsumer::HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) { - for (auto &Consumer : Consumers) - Consumer->HandleDetectMismatch(Name, Value); -} - -void MultiplexConsumer::HandleDependentLibrary(llvm::StringRef Lib) { +void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { for (auto &Consumer : Consumers) - Consumer->HandleDependentLibrary(Lib); + Consumer->CompleteTentativeDefinition(D); } -void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { +void MultiplexConsumer::AssignInheritanceModel(CXXRecordDecl *RD) { for (auto &Consumer : Consumers) - Consumer->CompleteTentativeDefinition(D); + Consumer->AssignInheritanceModel(RD); } void MultiplexConsumer::HandleVTable(CXXRecordDecl *RD) { @@ -355,6 +352,13 @@ void MultiplexConsumer::PrintStats() { Consumer->PrintStats(); } +bool MultiplexConsumer::shouldSkipFunctionBody(Decl *D) { + bool Skip = true; + for (auto &Consumer : Consumers) + Skip = Skip && Consumer->shouldSkipFunctionBody(D); + return Skip; +} + void MultiplexConsumer::InitializeSema(Sema &S) { for (auto &Consumer : Consumers) if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) diff --git a/lib/Frontend/PCHContainerOperations.cpp b/lib/Frontend/PCHContainerOperations.cpp index 5e1d772050987..2d4edde43280a 100644 --- a/lib/Frontend/PCHContainerOperations.cpp +++ b/lib/Frontend/PCHContainerOperations.cpp @@ -13,23 +13,27 @@ #include "clang/Frontend/PCHContainerOperations.h" #include "clang/AST/ASTConsumer.h" +#include "clang/Lex/ModuleLoader.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/raw_ostream.h" -#include "clang/Lex/ModuleLoader.h" +#include <utility> using namespace clang; +PCHContainerWriter::~PCHContainerWriter() {} +PCHContainerReader::~PCHContainerReader() {} + namespace { /// \brief A PCHContainerGenerator that writes out the PCH to a flat file. class RawPCHContainerGenerator : public ASTConsumer { std::shared_ptr<PCHBuffer> Buffer; - raw_pwrite_stream *OS; + std::unique_ptr<raw_pwrite_stream> OS; public: - RawPCHContainerGenerator(llvm::raw_pwrite_stream *OS, + RawPCHContainerGenerator(std::unique_ptr<llvm::raw_pwrite_stream> OS, std::shared_ptr<PCHBuffer> Buffer) - : Buffer(Buffer), OS(OS) {} + : Buffer(std::move(Buffer)), OS(std::move(OS)) {} ~RawPCHContainerGenerator() override = default; @@ -49,9 +53,9 @@ public: std::unique_ptr<ASTConsumer> RawPCHContainerWriter::CreatePCHContainerGenerator( CompilerInstance &CI, const std::string &MainFileName, - const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, + const std::string &OutputFileName, std::unique_ptr<llvm::raw_pwrite_stream> OS, std::shared_ptr<PCHBuffer> Buffer) const { - return llvm::make_unique<RawPCHContainerGenerator>(OS, Buffer); + return llvm::make_unique<RawPCHContainerGenerator>(std::move(OS), Buffer); } void RawPCHContainerReader::ExtractPCH( diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp index a58c935620a2f..77b80e612fbf2 100644 --- a/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/lib/Frontend/PrintPreprocessedOutput.cpp @@ -326,8 +326,20 @@ void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc, if (Imported) { startNewLineIfNeeded(); MoveToLine(HashLoc); - OS << "@import " << Imported->getFullModuleName() << ";" - << " /* clang -E: implicit import for \"" << File->getName() << "\" */"; + if (PP.getLangOpts().ObjC2) { + OS << "@import " << Imported->getFullModuleName() << ";" + << " /* clang -E: implicit import for \"" << File->getName() + << "\" */"; + } else { + // FIXME: Preseve whether this was a + // #include/#include_next/#include_macros/#import. + OS << "#include " + << (IsAngled ? '<' : '"') + << FileName + << (IsAngled ? '>' : '"') + << " /* clang -E: implicit import for module " + << Imported->getFullModuleName() << " */"; + } // Since we want a newline after the @import, but not a #<line>, start a new // line immediately. EmittedTokensOnThisLine = true; @@ -369,18 +381,16 @@ void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok, setEmittedDirectiveOnThisLine(); } -static void outputPrintable(llvm::raw_ostream& OS, - const std::string &Str) { - for (unsigned i = 0, e = Str.size(); i != e; ++i) { - unsigned char Char = Str[i]; - if (isPrintable(Char) && Char != '\\' && Char != '"') - OS << (char)Char; - else // Output anything hard as an octal escape. - OS << '\\' - << (char)('0'+ ((Char >> 6) & 7)) - << (char)('0'+ ((Char >> 3) & 7)) - << (char)('0'+ ((Char >> 0) & 7)); - } +static void outputPrintable(raw_ostream &OS, StringRef Str) { + for (unsigned char Char : Str) { + if (isPrintable(Char) && Char != '\\' && Char != '"') + OS << (char)Char; + else // Output anything hard as an octal escape. + OS << '\\' + << (char)('0' + ((Char >> 6) & 7)) + << (char)('0' + ((Char >> 3) & 7)) + << (char)('0' + ((Char >> 0) & 7)); + } } void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc, @@ -547,8 +557,10 @@ void PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr, // If we have \n\r or \r\n, skip both and count as one line. if (Len != 1 && (TokStr[1] == '\n' || TokStr[1] == '\r') && - TokStr[0] != TokStr[1]) - ++TokStr, --Len; + TokStr[0] != TokStr[1]) { + ++TokStr; + --Len; + } } if (NumNewlines == 0) return; @@ -577,6 +589,15 @@ struct UnknownPragmaHandler : public PragmaHandler { Callbacks->MoveToLine(PragmaTok.getLocation()); Callbacks->OS.write(Prefix, strlen(Prefix)); + if (ShouldExpandTokens) { + // The first token does not have expanded macros. Expand them, if + // required. + auto Toks = llvm::make_unique<Token[]>(1); + Toks[0] = PragmaTok; + PP.EnterTokenStream(std::move(Toks), /*NumToks=*/1, + /*DisableMacroExpansion=*/false); + PP.Lex(PragmaTok); + } Token PrevToken; Token PrevPrevToken; PrevToken.startToken(); diff --git a/lib/Frontend/Rewrite/FrontendActions.cpp b/lib/Frontend/Rewrite/FrontendActions.cpp index 8cf8adf37ed66..13d410e213819 100644 --- a/lib/Frontend/Rewrite/FrontendActions.cpp +++ b/lib/Frontend/Rewrite/FrontendActions.cpp @@ -23,6 +23,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include <memory> +#include <utility> using namespace clang; @@ -32,8 +33,9 @@ using namespace clang; std::unique_ptr<ASTConsumer> HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) - return CreateHTMLPrinter(OS, CI.getPreprocessor()); + if (std::unique_ptr<raw_ostream> OS = + CI.createDefaultOutputFile(false, InFile)) + return CreateHTMLPrinter(std::move(OS), CI.getPreprocessor()); return nullptr; } @@ -60,8 +62,8 @@ class FixItActionSuffixInserter : public FixItOptions { public: FixItActionSuffixInserter(std::string NewSuffix, bool FixWhatYouCan) - : NewSuffix(NewSuffix) { - this->FixWhatYouCan = FixWhatYouCan; + : NewSuffix(std::move(NewSuffix)) { + this->FixWhatYouCan = FixWhatYouCan; } std::string RewriteFilename(const std::string &Filename, int &fd) override { @@ -151,15 +153,15 @@ bool FixItRecompile::BeginInvocation(CompilerInstance &CI) { std::unique_ptr<ASTConsumer> RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp")) { + if (std::unique_ptr<raw_ostream> OS = + CI.createDefaultOutputFile(false, InFile, "cpp")) { if (CI.getLangOpts().ObjCRuntime.isNonFragile()) - return CreateModernObjCRewriter(InFile, OS, - CI.getDiagnostics(), CI.getLangOpts(), - CI.getDiagnosticOpts().NoRewriteMacros, - (CI.getCodeGenOpts().getDebugInfo() != - CodeGenOptions::NoDebugInfo)); - return CreateObjCRewriter(InFile, OS, - CI.getDiagnostics(), CI.getLangOpts(), + return CreateModernObjCRewriter( + 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(), CI.getDiagnosticOpts().NoRewriteMacros); } return nullptr; @@ -173,25 +175,28 @@ RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { void RewriteMacrosAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); - raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); + std::unique_ptr<raw_ostream> OS = + CI.createDefaultOutputFile(true, getCurrentFile()); if (!OS) return; - RewriteMacrosInInput(CI.getPreprocessor(), OS); + RewriteMacrosInInput(CI.getPreprocessor(), OS.get()); } void RewriteTestAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); - raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile()); + std::unique_ptr<raw_ostream> OS = + CI.createDefaultOutputFile(false, getCurrentFile()); if (!OS) return; - DoRewriteTest(CI.getPreprocessor(), OS); + DoRewriteTest(CI.getPreprocessor(), OS.get()); } void RewriteIncludesAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); - raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); + std::unique_ptr<raw_ostream> OS = + CI.createDefaultOutputFile(true, getCurrentFile()); if (!OS) return; - RewriteIncludesInInput(CI.getPreprocessor(), OS, + RewriteIncludesInInput(CI.getPreprocessor(), OS.get(), CI.getPreprocessorOutputOpts()); } diff --git a/lib/Frontend/Rewrite/HTMLPrint.cpp b/lib/Frontend/Rewrite/HTMLPrint.cpp index 22ccfe6936b7a..f5fad346124a8 100644 --- a/lib/Frontend/Rewrite/HTMLPrint.cpp +++ b/lib/Frontend/Rewrite/HTMLPrint.cpp @@ -32,14 +32,14 @@ using namespace clang; namespace { class HTMLPrinter : public ASTConsumer { Rewriter R; - raw_ostream *Out; + std::unique_ptr<raw_ostream> Out; Preprocessor &PP; bool SyntaxHighlight, HighlightMacros; public: - HTMLPrinter(raw_ostream *OS, Preprocessor &pp, + HTMLPrinter(std::unique_ptr<raw_ostream> OS, Preprocessor &pp, bool _SyntaxHighlight, bool _HighlightMacros) - : Out(OS), PP(pp), SyntaxHighlight(_SyntaxHighlight), + : Out(std::move(OS)), PP(pp), SyntaxHighlight(_SyntaxHighlight), HighlightMacros(_HighlightMacros) {} void Initialize(ASTContext &context) override; @@ -47,11 +47,10 @@ namespace { }; } -std::unique_ptr<ASTConsumer> clang::CreateHTMLPrinter(raw_ostream *OS, - Preprocessor &PP, - bool SyntaxHighlight, - bool HighlightMacros) { - return llvm::make_unique<HTMLPrinter>(OS, PP, SyntaxHighlight, +std::unique_ptr<ASTConsumer> +clang::CreateHTMLPrinter(std::unique_ptr<raw_ostream> OS, Preprocessor &PP, + bool SyntaxHighlight, bool HighlightMacros) { + return llvm::make_unique<HTMLPrinter>(std::move(OS), PP, SyntaxHighlight, HighlightMacros); } diff --git a/lib/Frontend/Rewrite/InclusionRewriter.cpp b/lib/Frontend/Rewrite/InclusionRewriter.cpp index ca8226251fd9c..b761c34fcbdeb 100644 --- a/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ b/lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -450,7 +450,9 @@ bool InclusionRewriter::Process(FileID FileId, WriteLineInfo(FileName, Line - 1, FileType, ""); StringRef LineInfoExtra; SourceLocation Loc = HashToken.getLocation(); - if (const Module *Mod = FindModuleAtLocation(Loc)) + if (const Module *Mod = PP.getLangOpts().ObjC2 + ? FindModuleAtLocation(Loc) + : nullptr) WriteImplicitModuleImport(Mod); else if (const IncludedFile *Inc = FindIncludeAtLocation(Loc)) { // include and recursively process the file diff --git a/lib/Frontend/Rewrite/Makefile b/lib/Frontend/Rewrite/Makefile deleted file mode 100644 index 1d565477053c0..0000000000000 --- a/lib/Frontend/Rewrite/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -##===- clang/lib/Rewrite/Makefile --------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements code transformation / rewriting facilities. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../../.. -LIBRARYNAME := clangRewriteFrontend - -include $(CLANG_LEVEL)/Makefile - -ifeq ($(ENABLE_CLANG_ARCMT),1) - CXX.Flags += -DCLANG_ENABLE_OBJC_REWRITER -endif - diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp index be68d42affa15..ad217517d7d72 100644 --- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -72,7 +72,7 @@ namespace { Stmt *CurrentBody; ParentMap *PropParentMap; // created lazily. std::string InFileName; - raw_ostream* OutFile; + std::unique_ptr<raw_ostream> OutFile; std::string Preamble; TypeDecl *ProtocolTypeDecl; @@ -135,7 +135,6 @@ namespace { SmallVector<DeclRefExpr *, 32> BlockDeclRefs; - // Block related declarations. SmallVector<ValueDecl *, 8> BlockByCopyDecls; llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet; @@ -186,6 +185,7 @@ namespace { public: llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames; + // Top Level Driver code. bool HandleTopLevelDecl(DeclGroupRef D) override { for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { @@ -235,14 +235,13 @@ namespace { RewriteObjCQualifiedInterfaceTypes(TD); } } - return; } void HandleTopLevelSingleDecl(Decl *D); void HandleDeclInMainFile(Decl *D); - RewriteModernObjC(std::string inFile, raw_ostream *OS, - DiagnosticsEngine &D, const LangOptions &LOpts, - bool silenceMacroWarn, bool LineInfo); + RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS, + DiagnosticsEngine &D, const LangOptions &LOpts, + bool silenceMacroWarn, bool LineInfo); ~RewriteModernObjC() override {} @@ -367,7 +366,6 @@ namespace { Stmt *RewriteContinueStmt(ContinueStmt *S); void RewriteCastExpr(CStyleCastExpr *CE); void RewriteImplicitCastObjCExpr(CastExpr *IE); - void RewriteLinkageSpec(LinkageSpecDecl *LSD); // Computes ivar bitfield group no. unsigned ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV); @@ -448,9 +446,6 @@ namespace { std::string &Result); void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, std::string &Result); - void RewriteObjCProtocolListMetaData( - const ObjCList<ObjCProtocolDecl> &Prots, - StringRef prefix, StringRef ClassName, std::string &Result); void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, std::string &Result); void RewriteClassSetupInitHook(std::string &Result); @@ -523,7 +518,6 @@ namespace { QualType getSuperStructType(); QualType getConstantStringStructType(); QualType convertFunctionTypeOfBlocks(const FunctionType *FT); - bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf); void convertToUnqualifiedObjCType(QualType &T) { if (T->isObjCQualifiedIdType()) { @@ -562,6 +556,7 @@ namespace { } return false; } + bool PointerTypeTakesAnyBlockArguments(QualType QT); bool PointerTypeTakesAnyObjCQualifiedType(QualType QT); void GetExtentOfArgList(const char *Name, const char *&LParen, @@ -608,8 +603,7 @@ namespace { /*Pascal=*/false, StrType, SourceLocation()); } }; - -} +} // end anonymous namespace void RewriteModernObjC::RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D) { @@ -644,12 +638,13 @@ static bool IsHeaderFile(const std::string &Filename) { return Ext == "h" || Ext == "hh" || Ext == "H"; } -RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS, - DiagnosticsEngine &D, const LangOptions &LOpts, - bool silenceMacroWarn, - bool LineInfo) - : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS), - SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) { +RewriteModernObjC::RewriteModernObjC(std::string inFile, + std::unique_ptr<raw_ostream> OS, + DiagnosticsEngine &D, + const LangOptions &LOpts, + bool silenceMacroWarn, bool LineInfo) + : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)), + SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) { IsHeader = IsHeaderFile(inFile); RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, "rewriting sub-expression within a macro (may not be correct)"); @@ -665,10 +660,12 @@ RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS, } std::unique_ptr<ASTConsumer> clang::CreateModernObjCRewriter( - const std::string &InFile, raw_ostream *OS, DiagnosticsEngine &Diags, - const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo) { - return llvm::make_unique<RewriteModernObjC>( - InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning, LineInfo); + const std::string &InFile, std::unique_ptr<raw_ostream> OS, + DiagnosticsEngine &Diags, const LangOptions &LOpts, + bool SilenceRewriteMacroWarning, bool LineInfo) { + return llvm::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags, + LOpts, SilenceRewriteMacroWarning, + LineInfo); } void RewriteModernObjC::InitializeCommon(ASTContext &context) { @@ -743,10 +740,6 @@ void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) { if (PD->isThisDeclarationADefinition()) RewriteProtocolDecl(PD); } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) { - // FIXME. This will not work in all situations and leaving it out - // is harmless. - // RewriteLinkageSpec(LSD); - // Recurse into linkage specifications for (DeclContext::decl_iterator DI = LSD->decls_begin(), DIEnd = LSD->decls_end(); @@ -853,7 +846,6 @@ RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) { else WriteInternalIvarName(ClassDecl, D, IvarOffsetName); - std::string S = "(*("; QualType IvarT = D->getType(); if (D->isBitField()) @@ -1068,11 +1060,11 @@ static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, const std::string &typedefString) { - SourceLocation startLoc = ClassDecl->getLocStart(); - const char *startBuf = SM->getCharacterData(startLoc); - const char *semiPtr = strchr(startBuf, ';'); - // Replace the @class with typedefs corresponding to the classes. - ReplaceText(startLoc, semiPtr-startBuf+1, typedefString); + SourceLocation startLoc = ClassDecl->getLocStart(); + const char *startBuf = SM->getCharacterData(startLoc); + const char *semiPtr = strchr(startBuf, ';'); + // Replace the @class with typedefs corresponding to the classes. + ReplaceText(startLoc, semiPtr-startBuf+1, typedefString); } void RewriteModernObjC::RewriteForwardClassDecl(DeclGroupRef D) { @@ -1147,7 +1139,7 @@ void RewriteModernObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) { ReplaceText(LocStart, 0, "// "); } - for (auto *I : CatDecl->properties()) + for (auto *I : CatDecl->instance_properties()) RewriteProperty(I); for (auto *I : CatDecl->instance_methods()) @@ -1171,7 +1163,7 @@ void RewriteModernObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) { RewriteMethodDeclaration(I); for (auto *I : PDecl->class_methods()) RewriteMethodDeclaration(I); - for (auto *I : PDecl->properties()) + for (auto *I : PDecl->instance_properties()) RewriteProperty(I); // Lastly, comment out the @end. @@ -1212,22 +1204,6 @@ RewriteModernObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) ReplaceText(LocStart, 0, "// "); } -void -RewriteModernObjC::RewriteLinkageSpec(LinkageSpecDecl *LSD) { - SourceLocation LocStart = LSD->getExternLoc(); - if (LocStart.isInvalid()) - llvm_unreachable("Invalid extern SourceLocation"); - - ReplaceText(LocStart, 0, "// "); - if (!LSD->hasBraces()) - return; - // FIXME. We don't rewrite well if '{' is not on same line as 'extern'. - SourceLocation LocRBrace = LSD->getRBraceLoc(); - if (LocRBrace.isInvalid()) - llvm_unreachable("Invalid rbrace SourceLocation"); - ReplaceText(LocRBrace, 0, "// "); -} - void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr, const FunctionType *&FPRetType) { if (T->isObjCQualifiedIdType()) @@ -1313,7 +1289,7 @@ void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, ResultStr += " _cmd"; // Method arguments. - for (const auto *PDecl : OMD->params()) { + for (const auto *PDecl : OMD->parameters()) { ResultStr += ", "; if (PDecl->getType()->isObjCQualifiedIdType()) { ResultStr += "id "; @@ -1354,6 +1330,7 @@ void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, } } } + void RewriteModernObjC::RewriteImplementationDecl(Decl *OID) { ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID); ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID); @@ -1417,7 +1394,7 @@ void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { // Mark this typedef as having been written into its c++ equivalent. ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl()); - for (auto *I : ClassDecl->properties()) + for (auto *I : ClassDecl->instance_properties()) RewriteProperty(I); for (auto *I : ClassDecl->instance_methods()) RewriteMethodDeclaration(I); @@ -1940,7 +1917,6 @@ void RewriteModernObjC::WarnAboutReturnGotoStmts(Stmt *S) Diags.Report(Context->getFullLoc(S->getLocStart()), TryFinallyContainsReturnDiag); } - return; } Stmt *RewriteModernObjC::RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { @@ -2809,11 +2785,10 @@ Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) { Context->UnsignedIntTy, SourceLocation()); MsgExprs.push_back(cnt); - SmallVector<QualType, 4> ArgTypes; ArgTypes.push_back(Context->getObjCClassType()); ArgTypes.push_back(Context->getObjCSelType()); - for (const auto *PI : ArrayMethod->params()) + for (const auto *PI : ArrayMethod->parameters()) ArgTypes.push_back(PI->getType()); QualType returnType = Exp->getType(); @@ -2921,8 +2896,6 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral CK_BitCast, DictLiteralKeyME); - - // Synthesize a call to objc_msgSend(). SmallVector<Expr*, 32> MsgExprs; SmallVector<Expr*, 4> ClsExprs; @@ -2959,11 +2932,10 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral Context->UnsignedIntTy, SourceLocation()); MsgExprs.push_back(cnt); - SmallVector<QualType, 8> ArgTypes; ArgTypes.push_back(Context->getObjCClassType()); ArgTypes.push_back(Context->getObjCSelType()); - for (const auto *PI : DictMethod->params()) { + for (const auto *PI : DictMethod->parameters()) { QualType T = PI->getType(); if (const PointerType* PT = T->getAs<PointerType>()) { QualType PointeeTy = PT->getPointeeType(); @@ -3176,7 +3148,6 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla str += "\t memset((void*)&s, 0, sizeof(s));\n"; str += "\t else\n"; - str += "\t s = (("; str += castType.getAsString(Context->getPrintingPolicy()); str += ")(void *)objc_msgSend_stret)(receiver, sel"; for (unsigned i = 2; i < ArgTypes.size(); i++) { @@ -3188,7 +3159,6 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla } str += ");\n"; - str += "\t}\n"; str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy()); str += " s;\n"; @@ -3530,7 +3500,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, ArgTypes.push_back(Context->getObjCSelType()); if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) { // Push any user argument types. - for (const auto *PI : OMD->params()) { + for (const auto *PI : OMD->parameters()) { QualType t = PI->getType()->isObjCQualifiedIdType() ? Context->getObjCIdType() : PI->getType(); @@ -3635,33 +3605,6 @@ Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl()); // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. return castExpr; - -} - -bool RewriteModernObjC::BufferContainsPPDirectives(const char *startBuf, - const char *endBuf) { - while (startBuf < endBuf) { - if (*startBuf == '#') { - // Skip whitespace. - for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf) - ; - if (!strncmp(startBuf, "if", strlen("if")) || - !strncmp(startBuf, "ifdef", strlen("ifdef")) || - !strncmp(startBuf, "ifndef", strlen("ifndef")) || - !strncmp(startBuf, "define", strlen("define")) || - !strncmp(startBuf, "undef", strlen("undef")) || - !strncmp(startBuf, "else", strlen("else")) || - !strncmp(startBuf, "elif", strlen("elif")) || - !strncmp(startBuf, "endif", strlen("endif")) || - !strncmp(startBuf, "pragma", strlen("pragma")) || - !strncmp(startBuf, "include", strlen("include")) || - !strncmp(startBuf, "import", strlen("import")) || - !strncmp(startBuf, "include_next", strlen("include_next"))) - return true; - } - startBuf++; - } - return false; } /// IsTagDefinedInsideClass - This routine checks that a named tagged type @@ -3688,7 +3631,6 @@ bool RewriteModernObjC::IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, TagLocation = ED->getLocation(); return Context->getSourceManager().isBeforeInTranslationUnit( IDecl->getLocation(), TagLocation); - } return false; } @@ -3820,7 +3762,6 @@ void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDec if (IsNamedDefinition) GlobalDefinedTags.insert(TD); } - } unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV) { @@ -3911,7 +3852,6 @@ void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, Result += "__GRBF_"; unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); Result += utostr(GroupNo); - return; } /// ObjCIvarBitfieldGroupType - Names struct type for ivar bitfield group. @@ -3924,7 +3864,6 @@ void RewriteModernObjC::ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, Result += "__T_"; unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); Result += utostr(GroupNo); - return; } /// ObjCIvarBitfieldGroupOffset - Names symbol for ivar bitfield group field offset. @@ -4063,7 +4002,6 @@ void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl, // Meta Data Emission //===----------------------------------------------------------------------===// - /// RewriteImplementations - This routine rewrites all method implementations /// and emits meta-data. @@ -4543,8 +4481,6 @@ void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) { HasLocalVariableExternalStorage(DRE->getDecl())) // FIXME: Handle enums. BlockDeclRefs.push_back(DRE); - - return; } void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S, @@ -4572,8 +4508,6 @@ void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S, ImportedLocalExternalDecls.insert(Var); } } - - return; } /// convertObjCTypeToCStyleType - This routine converts such objc types @@ -4658,7 +4592,7 @@ Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp = dyn_cast<PseudoObjectExpr>(BlockExp)) { CPT = POE->getType()->castAs<BlockPointerType>(); } else { - assert(1 && "RewriteBlockClass: Bad type"); + assert(false && "RewriteBlockClass: Bad type"); } assert(CPT && "RewriteBlockClass: Bad type"); const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>(); @@ -4828,7 +4762,6 @@ void RewriteModernObjC::RewriteCastExpr(CStyleCastExpr *CE) { break; } } - return; } void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) { @@ -4844,8 +4777,6 @@ void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) { Str += TypeString; Str += ")"; InsertText(IC->getSubExpr()->getLocStart(), Str); - - return; } void RewriteModernObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { @@ -4880,7 +4811,6 @@ void RewriteModernObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { break; } } - return; } bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { @@ -5017,11 +4947,8 @@ void RewriteModernObjC::RewriteBlockPointerDecl(NamedDecl *ND) { OrigLength++; } ReplaceText(Start, OrigLength, buf); - - return; } - /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, /// struct Block_byref_id_object *src) { @@ -5242,7 +5169,6 @@ void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl, InsertText(separatorLoc, lastDecl ? "}" : "};\n"); } - return; } void RewriteModernObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { @@ -5284,7 +5210,6 @@ FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) { Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) { - const BlockDecl *block = Exp->getBlockDecl(); Blocks.push_back(Exp); @@ -5292,7 +5217,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, CollectBlockDeclRefInfo(Exp); // Add inner imported variables now used in current block. - int countOfInnerDecls = 0; + int countOfInnerDecls = 0; if (!InnerBlockDeclRefs.empty()) { for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { DeclRefExpr *Exp = InnerBlockDeclRefs[i]; @@ -6995,7 +6920,8 @@ void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, PDecl->getNameAsString(), false); // Protocol's property metadata. - SmallVector<ObjCPropertyDecl *, 8> ProtocolProperties(PDecl->properties()); + SmallVector<ObjCPropertyDecl *, 8> ProtocolProperties( + PDecl->instance_properties()); Write_prop_list_t_initializer(*this, Context, Result, ProtocolProperties, /* Container */nullptr, "_OBJC_PROTOCOL_PROPERTIES_", @@ -7007,7 +6933,7 @@ void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, Result += "static "; Result += "struct _protocol_t _OBJC_PROTOCOL_"; Result += PDecl->getNameAsString(); - Result += " __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n"; + Result += " __attribute__ ((used)) = {\n"; Result += "\t0,\n"; // id is; is null Result += "\t\""; Result += PDecl->getNameAsString(); Result += "\",\n"; if (SuperProtocols.size() > 0) { @@ -7072,52 +6998,6 @@ void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, // Mark this protocol as having been generated. if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()).second) llvm_unreachable("protocol already synthesized"); - -} - -void RewriteModernObjC::RewriteObjCProtocolListMetaData( - const ObjCList<ObjCProtocolDecl> &Protocols, - StringRef prefix, StringRef ClassName, - std::string &Result) { - if (Protocols.empty()) return; - - for (unsigned i = 0; i != Protocols.size(); i++) - RewriteObjCProtocolMetaData(Protocols[i], Result); - - // Output the top lovel protocol meta-data for the class. - /* struct _objc_protocol_list { - struct _objc_protocol_list *next; - int protocol_count; - struct _objc_protocol *class_protocols[]; - } - */ - Result += "\n"; - if (LangOpts.MicrosoftExt) - Result += "__declspec(allocate(\".cat_cls_meth$B\")) "; - Result += "static struct {\n"; - Result += "\tstruct _objc_protocol_list *next;\n"; - Result += "\tint protocol_count;\n"; - Result += "\tstruct _objc_protocol *class_protocols["; - Result += utostr(Protocols.size()); - Result += "];\n} _OBJC_"; - Result += prefix; - Result += "_PROTOCOLS_"; - Result += ClassName; - Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " - "{\n\t0, "; - Result += utostr(Protocols.size()); - Result += "\n"; - - Result += "\t,{&_OBJC_PROTOCOL_"; - Result += Protocols[0]->getNameAsString(); - Result += " \n"; - - for (unsigned i = 1; i != Protocols.size(); i++) { - Result += "\t ,&_OBJC_PROTOCOL_"; - Result += Protocols[i]->getNameAsString(); - Result += "\n"; - } - Result += "\t }\n};\n"; } /// hasObjCExceptionAttribute - Return true if this class or any super @@ -7208,19 +7088,18 @@ void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, IDecl->getNameAsString()); // Protocol's property metadata. - SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->properties()); + SmallVector<ObjCPropertyDecl *, 8> ClassProperties( + CDecl->instance_properties()); Write_prop_list_t_initializer(*this, Context, Result, ClassProperties, /* Container */IDecl, "_OBJC_$_PROP_LIST_", CDecl->getNameAsString()); - // Data for initializing _class_ro_t metaclass meta-data uint32_t flags = CLS_META; std::string InstanceSize; std::string InstanceStart; - bool classIsHidden = CDecl->getVisibility() == HiddenVisibility; if (classIsHidden) flags |= OBJC2_CLS_HIDDEN; @@ -7288,7 +7167,6 @@ void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, if (ImplementationIsNonLazy(IDecl)) DefinedNonLazyClasses.push_back(CDecl); - } void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) { @@ -7453,7 +7331,8 @@ void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, FullCategoryName); // Protocol's property metadata. - SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->properties()); + SmallVector<ObjCPropertyDecl *, 8> ClassProperties( + CDecl->instance_properties()); Write_prop_list_t_initializer(*this, Context, Result, ClassProperties, /* Container */IDecl, "_OBJC_$_PROP_LIST_", @@ -7470,7 +7349,6 @@ void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, // Determine if this category is also "non-lazy". if (ImplementationIsNonLazy(IDecl)) DefinedNonLazyCategories.push_back(CDecl); - } void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) { @@ -7705,4 +7583,4 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { return Replacement; } -#endif +#endif // CLANG_ENABLE_OBJC_REWRITER diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp index e0ddadb123063..5967e40bfed96 100644 --- a/lib/Frontend/Rewrite/RewriteObjC.cpp +++ b/lib/Frontend/Rewrite/RewriteObjC.cpp @@ -37,7 +37,6 @@ using llvm::utostr; namespace { class RewriteObjC : public ASTConsumer { protected: - enum { BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */ @@ -72,7 +71,7 @@ namespace { Stmt *CurrentBody; ParentMap *PropParentMap; // created lazily. std::string InFileName; - raw_ostream* OutFile; + std::unique_ptr<raw_ostream> OutFile; std::string Preamble; TypeDecl *ProtocolTypeDecl; @@ -158,14 +157,15 @@ namespace { : R(R), SavedValue(R.DisableReplaceStmt) { R.DisableReplaceStmt = true; } + ~DisableReplaceStmtScope() { R.DisableReplaceStmt = SavedValue; } }; + void InitializeCommon(ASTContext &context); public: - // Top Level Driver code. bool HandleTopLevelDecl(DeclGroupRef D) override { for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { @@ -187,9 +187,10 @@ namespace { } return true; } + void HandleTopLevelSingleDecl(Decl *D); void HandleDeclInMainFile(Decl *D); - RewriteObjC(std::string inFile, raw_ostream *OS, + RewriteObjC(std::string inFile, std::unique_ptr<raw_ostream> OS, DiagnosticsEngine &D, const LangOptions &LOpts, bool silenceMacroWarn); @@ -505,12 +506,10 @@ namespace { class RewriteObjCFragileABI : public RewriteObjC { public: - - RewriteObjCFragileABI(std::string inFile, raw_ostream *OS, - DiagnosticsEngine &D, const LangOptions &LOpts, - bool silenceMacroWarn) : RewriteObjC(inFile, OS, - D, LOpts, - silenceMacroWarn) {} + RewriteObjCFragileABI(std::string inFile, std::unique_ptr<raw_ostream> OS, + DiagnosticsEngine &D, const LangOptions &LOpts, + bool silenceMacroWarn) + : RewriteObjC(inFile, std::move(OS), D, LOpts, silenceMacroWarn) {} ~RewriteObjCFragileABI() override {} void Initialize(ASTContext &context) override; @@ -540,7 +539,7 @@ namespace { std::string &Result) override; Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) override; }; -} +} // end anonymous namespace void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D) { @@ -575,11 +574,11 @@ static bool IsHeaderFile(const std::string &Filename) { return Ext == "h" || Ext == "hh" || Ext == "H"; } -RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS, +RewriteObjC::RewriteObjC(std::string inFile, std::unique_ptr<raw_ostream> OS, DiagnosticsEngine &D, const LangOptions &LOpts, bool silenceMacroWarn) - : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS), - SilenceRewriteMacroWarning(silenceMacroWarn) { + : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)), + SilenceRewriteMacroWarning(silenceMacroWarn) { IsHeader = IsHeaderFile(inFile); RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, "rewriting sub-expression within a macro (may not be correct)"); @@ -590,11 +589,12 @@ RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS, } std::unique_ptr<ASTConsumer> -clang::CreateObjCRewriter(const std::string &InFile, raw_ostream *OS, +clang::CreateObjCRewriter(const std::string &InFile, + std::unique_ptr<raw_ostream> OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning) { - return llvm::make_unique<RewriteObjCFragileABI>(InFile, OS, Diags, LOpts, - SilenceRewriteMacroWarning); + return llvm::make_unique<RewriteObjCFragileABI>( + InFile, std::move(OS), Diags, LOpts, SilenceRewriteMacroWarning); } void RewriteObjC::InitializeCommon(ASTContext &context) { @@ -969,7 +969,7 @@ void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) { // FIXME: handle category headers that are declared across multiple lines. ReplaceText(LocStart, 0, "// "); - for (auto *I : CatDecl->properties()) + for (auto *I : CatDecl->instance_properties()) RewriteProperty(I); for (auto *I : CatDecl->instance_methods()) RewriteMethodDeclaration(I); @@ -992,7 +992,7 @@ void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) { RewriteMethodDeclaration(I); for (auto *I : PDecl->class_methods()) RewriteMethodDeclaration(I); - for (auto *I : PDecl->properties()) + for (auto *I : PDecl->instance_properties()) RewriteProperty(I); // Lastly, comment out the @end. @@ -1118,7 +1118,7 @@ void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, ResultStr += " _cmd"; // Method arguments. - for (const auto *PDecl : OMD->params()) { + for (const auto *PDecl : OMD->parameters()) { ResultStr += ", "; if (PDecl->getType()->isObjCQualifiedIdType()) { ResultStr += "id "; @@ -1159,6 +1159,7 @@ void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, } } } + void RewriteObjC::RewriteImplementationDecl(Decl *OID) { ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID); ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID); @@ -1210,7 +1211,7 @@ void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { } RewriteObjCInternalStruct(ClassDecl, ResultStr); - for (auto *I : ClassDecl->properties()) + for (auto *I : ClassDecl->instance_properties()) RewriteProperty(I); for (auto *I : ClassDecl->instance_methods()) RewriteMethodDeclaration(I); @@ -1720,7 +1721,6 @@ void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S) Diags.Report(Context->getFullLoc(S->getLocStart()), TryFinallyContainsReturnDiag); } - return; } void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) @@ -1730,32 +1730,29 @@ void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) if (SubStmt) HasReturnStmts(SubStmt, hasReturns); - if (isa<ReturnStmt>(S)) - hasReturns = true; - return; + if (isa<ReturnStmt>(S)) + hasReturns = true; } void RewriteObjC::RewriteTryReturnStmts(Stmt *S) { - // Perform a bottom up traversal of all children. - for (Stmt *SubStmt : S->children()) - if (SubStmt) { - RewriteTryReturnStmts(SubStmt); - } - if (isa<ReturnStmt>(S)) { - SourceLocation startLoc = S->getLocStart(); - const char *startBuf = SM->getCharacterData(startLoc); - - const char *semiBuf = strchr(startBuf, ';'); - assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'"); - SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); + // Perform a bottom up traversal of all children. + for (Stmt *SubStmt : S->children()) + if (SubStmt) { + RewriteTryReturnStmts(SubStmt); + } + if (isa<ReturnStmt>(S)) { + SourceLocation startLoc = S->getLocStart(); + const char *startBuf = SM->getCharacterData(startLoc); + const char *semiBuf = strchr(startBuf, ';'); + assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'"); + SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); - std::string buf; - buf = "{ objc_exception_try_exit(&_stack); return"; + std::string buf; + buf = "{ objc_exception_try_exit(&_stack); return"; - ReplaceText(startLoc, 6, buf); - InsertText(onePastSemiLoc, "}"); - } - return; + ReplaceText(startLoc, 6, buf); + InsertText(onePastSemiLoc, "}"); + } } void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) { @@ -1780,7 +1777,6 @@ void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) { ReplaceText(startLoc, 6, buf); InsertText(onePastSemiLoc, "}"); } - return; } Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { @@ -2287,7 +2283,6 @@ void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str, } } - void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); @@ -2615,10 +2610,8 @@ CallExpr *RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavo CallExpr *STCE = new (Context) CallExpr( *Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, SourceLocation()); return STCE; - } - Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SourceLocation StartLoc, SourceLocation EndLoc) { @@ -2924,7 +2917,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, ArgTypes.push_back(Context->getObjCSelType()); if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) { // Push any user argument types. - for (const auto *PI : OMD->params()) { + for (const auto *PI : OMD->parameters()) { QualType t = PI->getType()->isObjCQualifiedIdType() ? Context->getObjCIdType() : PI->getType(); @@ -3059,7 +3052,6 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl()); // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. return castExpr; - } bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf, @@ -3224,7 +3216,6 @@ void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, // Meta Data Emission //===----------------------------------------------------------------------===// - /// RewriteImplementations - This routine rewrites all method implementations /// and emits meta-data. @@ -3665,8 +3656,6 @@ void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { HasLocalVariableExternalStorage(DRE->getDecl())) // FIXME: Handle enums. BlockDeclRefs.push_back(DRE); - - return; } void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, @@ -3694,8 +3683,6 @@ void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, ImportedLocalExternalDecls.insert(Var); } } - - return; } /// convertFunctionTypeOfBlocks - This routine converts a function type @@ -3761,7 +3748,7 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { = dyn_cast<PseudoObjectExpr>(BlockExp)) { CPT = POE->getType()->castAs<BlockPointerType>(); } else { - assert(1 && "RewriteBlockClass: Bad type"); + assert(false && "RewriteBlockClass: Bad type"); } assert(CPT && "RewriteBlockClass: Bad type"); const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>(); @@ -3931,7 +3918,6 @@ void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) { break; } } - return; } void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { @@ -3966,7 +3952,6 @@ void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { break; } } - return; } bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { @@ -4103,11 +4088,8 @@ void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) { OrigLength++; } ReplaceText(Start, OrigLength, buf); - - return; } - /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, /// struct Block_byref_id_object *src) { @@ -4328,7 +4310,6 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) { InsertText(semiLoc, "}"); } - return; } void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { @@ -4494,7 +4475,6 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, OK_Ordinary, SourceLocation()); } - } InitExprs.push_back(Exp); } @@ -5241,7 +5221,6 @@ void RewriteObjCFragileABI::RewriteObjCProtocolMetaData( // Mark this protocol as having been generated. if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()).second) llvm_unreachable("protocol already synthesized"); - } void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData( @@ -5910,4 +5889,4 @@ Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { return Replacement; } -#endif +#endif // CLANG_ENABLE_OBJC_REWRITER diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp index 1bf10d2769456..5c42406876b69 100644 --- a/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" +#include <utility> #include <vector> using namespace clang; @@ -147,7 +148,7 @@ class SDiagsWriter : public DiagnosticConsumer { explicit SDiagsWriter(IntrusiveRefCntPtr<SharedState> State) : LangOpts(nullptr), OriginalInstance(false), MergeChildRecords(false), - State(State) {} + State(std::move(State)) {} public: SDiagsWriter(StringRef File, DiagnosticOptions *Diags, bool MergeChildRecords) diff --git a/lib/Frontend/TestModuleFileExtension.cpp b/lib/Frontend/TestModuleFileExtension.cpp index d1b20c4a80b34..b43d45f7ae467 100644 --- a/lib/Frontend/TestModuleFileExtension.cpp +++ b/lib/Frontend/TestModuleFileExtension.cpp @@ -38,9 +38,7 @@ void TestModuleFileExtension::Writer::writeExtensionContents( OS << "Hello from " << Ext->BlockName << " v" << Ext->MajorVersion << "." << Ext->MinorVersion; } - SmallVector<uint64_t, 4> Record; - Record.push_back(FIRST_EXTENSION_RECORD_ID); - Record.push_back(Message.size()); + uint64_t Record[] = {FIRST_EXTENSION_RECORD_ID, Message.size()}; Stream.EmitRecordWithBlob(Abbrev, Record, Message); } diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp index d4e156d44582f..977af079a77aa 100644 --- a/lib/Frontend/TextDiagnostic.cpp +++ b/lib/Frontend/TextDiagnostic.cpp @@ -819,7 +819,15 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc, switch (DiagOpts->getFormat()) { case DiagnosticOptions::Clang: case DiagnosticOptions::Vi: OS << ':'; break; - case DiagnosticOptions::MSVC: OS << ") : "; break; + case DiagnosticOptions::MSVC: + // MSVC2013 and before print 'file(4) : error'. MSVC2015 gets rid of the + // space and prints 'file(4): error'. + OS << ')'; + if (LangOpts.MSCompatibilityVersion && + !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015)) + OS << ' '; + OS << ": "; + break; } if (DiagOpts->ShowSourceRanges && !Ranges.empty()) { @@ -875,7 +883,7 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc, void TextDiagnostic::emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc, const SourceManager &SM) { - if (DiagOpts->ShowLocation && PLoc.getFilename()) + if (DiagOpts->ShowLocation && PLoc.isValid()) OS << "In file included from " << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n"; else @@ -885,7 +893,7 @@ void TextDiagnostic::emitIncludeLocation(SourceLocation Loc, void TextDiagnostic::emitImportLocation(SourceLocation Loc, PresumedLoc PLoc, StringRef ModuleName, const SourceManager &SM) { - if (DiagOpts->ShowLocation && PLoc.getFilename()) + if (DiagOpts->ShowLocation && PLoc.isValid()) OS << "In module '" << ModuleName << "' imported from " << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n"; else @@ -896,7 +904,7 @@ void TextDiagnostic::emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc, StringRef ModuleName, const SourceManager &SM) { - if (DiagOpts->ShowLocation && PLoc.getFilename()) + if (DiagOpts->ShowLocation && PLoc.isValid()) OS << "While building module '" << ModuleName << "' imported from " << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n"; else @@ -1082,10 +1090,13 @@ void TextDiagnostic::emitSnippetAndCaret( // Get information about the buffer it points into. bool Invalid = false; - const char *BufStart = SM.getBufferData(FID, &Invalid).data(); + StringRef BufData = SM.getBufferData(FID, &Invalid); if (Invalid) return; + const char *BufStart = BufData.data(); + const char *BufEnd = BufStart + BufData.size(); + unsigned LineNo = SM.getLineNumber(FID, FileOffset); unsigned ColNo = SM.getColumnNumber(FID, FileOffset); @@ -1101,15 +1112,20 @@ void TextDiagnostic::emitSnippetAndCaret( // Compute the line end. Scan forward from the error position to the end of // the line. const char *LineEnd = TokPtr; - while (*LineEnd != '\n' && *LineEnd != '\r' && *LineEnd != '\0') + while (*LineEnd != '\n' && *LineEnd != '\r' && LineEnd != BufEnd) ++LineEnd; // Arbitrarily stop showing snippets when the line is too long. if (size_t(LineEnd - LineStart) > MaxLineLengthToPrint) return; + // Trim trailing null-bytes. + StringRef Line(LineStart, LineEnd - LineStart); + while (Line.size() > ColNo && Line.back() == '\0') + Line = Line.drop_back(); + // Copy the line of code into an std::string for ease of manipulation. - std::string SourceLine(LineStart, LineEnd); + std::string SourceLine(Line.begin(), Line.end()); // Build the byte to column map. const SourceColumnMap sourceColMap(SourceLine, DiagOpts->TabStop); |