diff options
Diffstat (limited to 'clang/lib/Frontend')
-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 |
3 files changed, 132 insertions, 2 deletions
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) |