diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Driver/Types.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 125 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendOptions.cpp | 2 | ||||
-rw-r--r-- | clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Serialization/ModuleManager.cpp | 14 |
9 files changed, 163 insertions, 8 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 706409d05d7..29ed5cffaa5 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -126,6 +126,7 @@ const { // -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler. } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || + (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) || (PhaseArg = DAL.getLastArg(options::OPT__migrate)) || @@ -1170,6 +1171,8 @@ Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase, return new MigrateJobAction(Input, types::TY_Remap); } else if (Args.hasArg(options::OPT_emit_ast)) { return new CompileJobAction(Input, types::TY_AST); + } else if (Args.hasArg(options::OPT_module_file_info)) { + return new CompileJobAction(Input, types::TY_ModuleFile); } else if (IsUsingLTO(Args)) { types::ID Output = Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC; @@ -1432,7 +1435,8 @@ const char *Driver::GetNamedOutputPath(Compilation &C, } // Default to writing to stdout? - if (AtTopLevel && isa<PreprocessJobAction>(JA) && !CCGenDiagnostics) + if (AtTopLevel && !CCGenDiagnostics && + (isa<PreprocessJobAction>(JA) || JA.getType() == types::TY_ModuleFile)) return "-"; // Output to a temporary file? diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index c7e47ad1110..fa3128bbd59 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1860,6 +1860,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-S"); } else if (JA.getType() == types::TY_AST) { CmdArgs.push_back("-emit-pch"); + } else if (JA.getType() == types::TY_ModuleFile) { + CmdArgs.push_back("-module-file-info"); } else if (JA.getType() == types::TY_RewrittenObjC) { CmdArgs.push_back("-rewrite-objc"); rewriteKind = RK_NonFragile; @@ -3696,6 +3698,9 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, else if (II.getType() == types::TY_AST) D.Diag(diag::err_drv_no_ast_support) << getToolChain().getTripleString(); + else if (II.getType() == types::TY_ModuleFile) + D.Diag(diag::err_drv_no_module_support) + << getToolChain().getTripleString(); if (types::canTypeBeUserSpecified(II.getType())) { CmdArgs.push_back("-x"); @@ -3826,6 +3831,9 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, else if (II.getType() == types::TY_AST) D.Diag(clang::diag::err_drv_no_ast_support) << getToolChain().getTripleString(); + else if (II.getType() == types::TY_ModuleFile) + D.Diag(diag::err_drv_no_module_support) + << getToolChain().getTripleString(); if (II.isFilename()) CmdArgs.push_back(II.getFilename()); diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp index 9665095b003..7d22596a17e 100644 --- a/clang/lib/Driver/Types.cpp +++ b/clang/lib/Driver/Types.cpp @@ -87,7 +87,7 @@ bool types::isAcceptedByClang(ID Id) { case TY_ObjCHeader: case TY_PP_ObjCHeader: case TY_CXXHeader: case TY_PP_CXXHeader: case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: - case TY_AST: + case TY_AST: case TY_ModuleFile: case TY_LLVM_IR: case TY_LLVM_BC: return true; } @@ -164,6 +164,7 @@ types::ID types::lookupTypeForExtension(const char *Ext) { .Case("F90", TY_Fortran) .Case("F95", TY_Fortran) .Case("mii", TY_PP_ObjCXX) + .Case("pcm", TY_ModuleFile) .Default(TY_INVALID); } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2d945b5b044..0fb8e58b3d5 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -644,6 +644,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::InitOnly; break; case OPT_fsyntax_only: Opts.ProgramAction = frontend::ParseSyntaxOnly; break; + case OPT_module_file_info: + Opts.ProgramAction = frontend::ModuleFileInfo; break; case OPT_print_decl_contexts: Opts.ProgramAction = frontend::PrintDeclContext; break; case OPT_print_preamble: @@ -779,7 +781,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, .Case("objective-c-header", IK_ObjC) .Case("c++-header", IK_CXX) .Case("objective-c++-header", IK_ObjCXX) - .Case("ast", IK_AST) + .Cases("ast", "pcm", IK_AST) .Case("ir", IK_LLVM_IR) .Default(IK_None); if (DashX == IK_None) @@ -1465,6 +1467,7 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, case frontend::GeneratePCH: case frontend::GeneratePTH: case frontend::ParseSyntaxOnly: + case frontend::ModuleFileInfo: case frontend::PluginAction: case frontend::PrintDeclContext: case frontend::RewriteObjC: @@ -1627,6 +1630,8 @@ llvm::APInt ModuleSignature::getAsInteger() const { } 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. using llvm::hash_code; using llvm::hash_value; using llvm::hash_combine; diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index f3466f02342..5c7567fa8c0 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -19,6 +19,7 @@ #include "clang/Lex/Pragma.h" #include "clang/Lex/Preprocessor.h" #include "clang/Parse/Parser.h" +#include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/FileSystem.h" @@ -316,6 +317,130 @@ ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, return new ASTConsumer(); } +ASTConsumer *DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { + return new ASTConsumer(); +} + +namespace { + /// \brief AST reader listener that dumps module information for a module + /// file. + class DumpModuleInfoListener : public ASTReaderListener { + llvm::raw_ostream &Out; + + public: + DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { } + +#define DUMP_BOOLEAN(Value, Text) \ + Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n" + + virtual bool ReadFullVersionInformation(StringRef FullVersion) { + Out.indent(2) + << "Generated by " + << (FullVersion == getClangFullRepositoryVersion()? "this" + : "a different") + << " Clang: " << FullVersion << "\n"; + return ASTReaderListener::ReadFullVersionInformation(FullVersion); + } + + virtual bool ReadLanguageOptions(const LangOptions &LangOpts, + bool Complain) { + Out.indent(2) << "Language options:\n"; +#define LANGOPT(Name, Bits, Default, Description) \ + DUMP_BOOLEAN(LangOpts.Name, Description); +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + Out.indent(4) << Description << ": " \ + << static_cast<unsigned>(LangOpts.get##Name()) << "\n"; +#define VALUE_LANGOPT(Name, Bits, Default, Description) \ + Out.indent(4) << Description << ": " << LangOpts.Name << "\n"; +#define BENIGN_LANGOPT(Name, Bits, Default, Description) +#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) +#include "clang/Basic/LangOptions.def" + return false; + } + + virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, + bool Complain) { + Out.indent(2) << "Target options:\n"; + Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n"; + Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n"; + Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n"; + Out.indent(4) << " C++ ABI: " << TargetOpts.CXXABI << "\n"; + Out.indent(4) << " Linker version: " << TargetOpts.LinkerVersion << "\n"; + + if (!TargetOpts.FeaturesAsWritten.empty()) { + Out.indent(4) << "Target features:\n"; + for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size(); + I != N; ++I) { + Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n"; + } + } + + return false; + } + + virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + bool Complain) { + Out.indent(2) << "Header search options:\n"; + Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n"; + DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes, + "Use builtin include directories [-nobuiltininc]"); + DUMP_BOOLEAN(HSOpts.UseStandardSystemIncludes, + "Use standard system include directories [-nostdinc]"); + DUMP_BOOLEAN(HSOpts.UseStandardCXXIncludes, + "Use standard C++ include directories [-nostdinc++]"); + DUMP_BOOLEAN(HSOpts.UseLibcxx, + "Use libc++ (rather than libstdc++) [-stdlib=]"); + return false; + } + + virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, + bool Complain, + std::string &SuggestedPredefines) { + Out.indent(2) << "Preprocessor options:\n"; + DUMP_BOOLEAN(PPOpts.UsePredefines, + "Uses compiler/target-specific predefines [-undef]"); + DUMP_BOOLEAN(PPOpts.DetailedRecord, + "Uses detailed preprocessing record (for indexing)"); + + if (!PPOpts.Macros.empty()) { + Out.indent(4) << "Predefined macros:\n"; + } + + for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator + I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end(); + I != IEnd; ++I) { + Out.indent(6); + if (I->second) + Out << "-U"; + else + Out << "-D"; + Out << I->first << "\n"; + } + return false; + } +#undef DUMP_BOOLEAN + }; +} + +void DumpModuleInfoAction::ExecuteAction() { + // Set up the output file. + llvm::OwningPtr<llvm::raw_fd_ostream> OutFile; + StringRef OutputFileName = getCompilerInstance().getFrontendOpts().OutputFile; + if (!OutputFileName.empty() && OutputFileName != "-") { + std::string ErrorInfo; + OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str().c_str(), + ErrorInfo)); + } + llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs(); + + Out << "Information for module file '" << getCurrentFile() << "':\n"; + DumpModuleInfoListener Listener(Out); + ASTReader::readASTFileControlBlock(getCurrentFile(), + getCompilerInstance().getFileManager(), + Listener); +} + //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// diff --git a/clang/lib/Frontend/FrontendOptions.cpp b/clang/lib/Frontend/FrontendOptions.cpp index ea4005f7c96..f1823c69e96 100644 --- a/clang/lib/Frontend/FrontendOptions.cpp +++ b/clang/lib/Frontend/FrontendOptions.cpp @@ -13,7 +13,7 @@ using namespace clang; InputKind FrontendOptions::getInputKindForExtension(StringRef Extension) { return llvm::StringSwitch<InputKind>(Extension) - .Case("ast", IK_AST) + .Cases("ast", "pcm", IK_AST) .Case("c", IK_C) .Cases("S", "s", IK_Asm) .Case("i", IK_PreprocessedC) diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index ad8eb04768b..b0d76da3342 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -62,6 +62,7 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { case GeneratePTH: return new GeneratePTHAction(); case InitOnly: return new InitOnlyAction(); case ParseSyntaxOnly: return new SyntaxOnlyAction(); + case ModuleFileInfo: return new DumpModuleInfoAction(); case PluginAction: { for (FrontendPluginRegistry::iterator it = diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 55e333a17b6..4c2d2197e49 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3487,10 +3487,9 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, if (Record[0] != VERSION_MAJOR) return true; - const std::string &CurBranch = getClangFullRepositoryVersion(); - if (StringRef(CurBranch) != Blob) + if (Listener.ReadFullVersionInformation(Blob)) return true; - + break; } case LANGUAGE_OPTIONS: diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index 193a38b9738..f3d53adafa5 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -29,7 +29,19 @@ using namespace serialization; ModuleFile *ModuleManager::lookup(StringRef Name) { const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false, /*cacheFailure=*/false); - return Modules[Entry]; + if (Entry) + return lookup(Entry); + + return 0; +} + +ModuleFile *ModuleManager::lookup(const FileEntry *File) { + llvm::DenseMap<const FileEntry *, ModuleFile *>::iterator Known + = Modules.find(File); + if (Known == Modules.end()) + return 0; + + return Known->second; } llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) { |