Przeglądaj źródła

Frontend: Add FrontendAction support for handling LLVM IR inputs.
- These inputs follow an abbreviated execution path, but are still worth handling by FrontendAction so they reuse all the other clang -cc1 features.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105582 91177308-0d34-0410-b5e6-96231b3b80d8

Daniel Dunbar 15 lat temu
rodzic
commit
faddc3e53a

+ 5 - 1
include/clang/Frontend/FrontendAction.h

@@ -32,7 +32,8 @@ enum InputKind {
   IK_PreprocessedObjC,
   IK_PreprocessedObjC,
   IK_PreprocessedObjCXX,
   IK_PreprocessedObjCXX,
   IK_OpenCL,
   IK_OpenCL,
-  IK_AST
+  IK_AST,
+  IK_LLVM_IR
 };
 };
 
 
 
 
@@ -153,6 +154,9 @@ public:
   /// hasASTFileSupport - Does this action support use with AST files?
   /// hasASTFileSupport - Does this action support use with AST files?
   virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
   virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
 
 
+  /// hasIRSupport - Does this action support use with IR files?
+  virtual bool hasIRSupport() const { return false; }
+
   /// hasCodeCompletionSupport - Does this action support use with code
   /// hasCodeCompletionSupport - Does this action support use with code
   /// completion?
   /// completion?
   virtual bool hasCodeCompletionSupport() const { return false; }
   virtual bool hasCodeCompletionSupport() const { return false; }

+ 2 - 0
lib/Frontend/ASTUnit.cpp

@@ -334,6 +334,8 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
          "Invocation must have exactly one source file!");
          "Invocation must have exactly one source file!");
   assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST &&
   assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST &&
          "FIXME: AST inputs not yet supported here!");
          "FIXME: AST inputs not yet supported here!");
+  assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR &&
+         "IR inputs not support here!");
 
 
   // Create the AST unit.
   // Create the AST unit.
   AST.reset(new ASTUnit(false));
   AST.reset(new ASTUnit(false));

+ 4 - 1
lib/Frontend/CompilerInvocation.cpp

@@ -287,6 +287,7 @@ static const char *getInputKindName(InputKind Kind) {
   case IK_Asm:               return "assembler-with-cpp";
   case IK_Asm:               return "assembler-with-cpp";
   case IK_C:                 return "c";
   case IK_C:                 return "c";
   case IK_CXX:               return "c++";
   case IK_CXX:               return "c++";
+  case IK_LLVM_IR:           return "ir";
   case IK_ObjC:              return "objective-c";
   case IK_ObjC:              return "objective-c";
   case IK_ObjCXX:            return "objective-c++";
   case IK_ObjCXX:            return "objective-c++";
   case IK_OpenCL:            return "cl";
   case IK_OpenCL:            return "cl";
@@ -1022,6 +1023,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
       .Case("c++-header", IK_CXX)
       .Case("c++-header", IK_CXX)
       .Case("objective-c++-header", IK_ObjCXX)
       .Case("objective-c++-header", IK_ObjCXX)
       .Case("ast", IK_AST)
       .Case("ast", IK_AST)
+      .Case("ir", IK_LLVM_IR)
       .Default(IK_None);
       .Default(IK_None);
     if (DashX == IK_None)
     if (DashX == IK_None)
       Diags.Report(diag::err_drv_invalid_value)
       Diags.Report(diag::err_drv_invalid_value)
@@ -1141,6 +1143,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
     switch (IK) {
     switch (IK) {
     case IK_None:
     case IK_None:
     case IK_AST:
     case IK_AST:
+    case IK_LLVM_IR:
       assert(0 && "Invalid input kind!");
       assert(0 && "Invalid input kind!");
     case IK_OpenCL:
     case IK_OpenCL:
       LangStd = LangStandard::lang_opencl;
       LangStd = LangStandard::lang_opencl;
@@ -1401,7 +1404,7 @@ void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
   ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, Diags);
   ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, Diags);
   InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
   InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
   ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);
   ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);
-  if (DashX != IK_AST)
+  if (DashX != IK_AST && DashX != IK_LLVM_IR)
     ParseLangArgs(Res.getLangOpts(), *Args, DashX, Diags);
     ParseLangArgs(Res.getLangOpts(), *Args, DashX, Diags);
   ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, Diags);
   ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, Diags);
   ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args);
   ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args);

+ 18 - 1
lib/Frontend/FrontendAction.cpp

@@ -75,11 +75,28 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
     return true;
     return true;
   }
   }
 
 
-  // Setup the file and source managers, if needed, and the preprocessor.
+  // Set up the file and source managers, if needed.
   if (!CI.hasFileManager())
   if (!CI.hasFileManager())
     CI.createFileManager();
     CI.createFileManager();
   if (!CI.hasSourceManager())
   if (!CI.hasSourceManager())
     CI.createSourceManager();
     CI.createSourceManager();
+
+  // IR files bypass the rest of initialization.
+  if (InputKind == IK_LLVM_IR) {
+    assert(hasIRSupport() &&
+           "This action does not have IR file support!");
+
+    // Inform the diagnostic client we are processing a source file.
+    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
+
+    // Initialize the action.
+    if (!BeginSourceFileAction(CI, Filename))
+      goto failure;
+
+    return true;
+  }
+
+  // Set up the preprocessor.
   CI.createPreprocessor();
   CI.createPreprocessor();
 
 
   // Inform the diagnostic client we are processing a source file.
   // Inform the diagnostic client we are processing a source file.

+ 1 - 0
lib/Frontend/FrontendOptions.cpp

@@ -26,5 +26,6 @@ InputKind FrontendOptions::getInputKindForExtension(llvm::StringRef Extension) {
     .Cases("C", "cc", "cp", IK_CXX)
     .Cases("C", "cc", "cp", IK_CXX)
     .Cases("cpp", "CPP", "c++", "cxx", "hpp", IK_CXX)
     .Cases("cpp", "CPP", "c++", "cxx", "hpp", IK_CXX)
     .Case("cl", IK_OpenCL)
     .Case("cl", IK_OpenCL)
+    .Cases("ll", "bc", IK_LLVM_IR)
     .Default(IK_C);
     .Default(IK_C);
 }
 }