[cfe-commits] r82107 - in /cfe/trunk: include/clang/Basic/DiagnosticFrontendKinds.td test/Frontend/ast-codegen.c tools/clang-cc/clang-cc.cpp
Daniel Dunbar
daniel at zuster.org
Wed Sep 16 17:48:13 PDT 2009
Author: ddunbar
Date: Wed Sep 16 19:48:13 2009
New Revision: 82107
URL: http://llvm.org/viewvc/llvm-project?rev=82107&view=rev
Log:
Initial support for code generation from .ast files.
- Doesn't actually work yet because only module level asm's get correctly marked as externally visible in the PCH.
- Other things like 'clang-cc foo.ast -ast-dump' now work, as well.
Added:
cfe/trunk/test/Frontend/ast-codegen.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
cfe/trunk/tools/clang-cc/clang-cc.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td?rev=82107&r1=82106&r2=82107&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td Wed Sep 16 19:48:13 2009
@@ -15,6 +15,8 @@
def err_fe_error_reading : Error<"error reading '%0'">;
def err_fe_error_reading_stdin : Error<"error reading stdin">;
def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
+def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal;
+def err_fe_invalid_ast_action : Error<"invalid action for AST input">, DefaultFatal;
def note_fixit_applied : Note<"FIX-IT applied suggested code changes">;
def note_fixit_in_macro : Note<
Added: cfe/trunk/test/Frontend/ast-codegen.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/ast-codegen.c?rev=82107&view=auto
==============================================================================
--- cfe/trunk/test/Frontend/ast-codegen.c (added)
+++ cfe/trunk/test/Frontend/ast-codegen.c Wed Sep 16 19:48:13 2009
@@ -0,0 +1,5 @@
+// RUN: clang -emit-ast -o %t.ast %s &&
+// RUN: clang -emit-llvm -S -o - %t.ast | FileCheck %s
+
+// CHECK: module asm "foo"
+__asm__("foo");
Modified: cfe/trunk/tools/clang-cc/clang-cc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-cc/clang-cc.cpp?rev=82107&r1=82106&r2=82107&view=diff
==============================================================================
--- cfe/trunk/tools/clang-cc/clang-cc.cpp (original)
+++ cfe/trunk/tools/clang-cc/clang-cc.cpp Wed Sep 16 19:48:13 2009
@@ -24,6 +24,7 @@
#include "clang/Frontend/AnalysisConsumer.h"
#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompileOptions.h"
#include "clang/Frontend/FixItRewriter.h"
#include "clang/Frontend/FrontendDiagnostic.h"
@@ -318,7 +319,8 @@
langkind_objc_cpp,
langkind_objcxx,
langkind_objcxx_cpp,
- langkind_ocl
+ langkind_ocl,
+ langkind_ast
};
static llvm::cl::opt<LangKind>
@@ -347,6 +349,8 @@
"C++ header"),
clEnumValN(langkind_objcxx, "objective-c++-header",
"Objective-C++ header"),
+ clEnumValN(langkind_ast, "ast",
+ "Clang AST"),
clEnumValEnd));
static llvm::cl::opt<bool>
@@ -402,7 +406,9 @@
return BaseLang;
llvm::StringRef Ext = Filename.rsplit('.').second;
- if (Ext == "c")
+ if (Ext == "ast")
+ return langkind_ast;
+ else if (Ext == "c")
return langkind_c;
else if (Ext == "S" || Ext == "s")
return langkind_asm_cpp;
@@ -687,6 +693,7 @@
if (LangStd == lang_unspecified) {
// Based on the base language, pick one.
switch (LK) {
+ case langkind_ast: assert(0 && "Invalid call for AST inputs");
case lang_unspecified: assert(0 && "Unknown base language");
case langkind_ocl:
LangStd = lang_c99;
@@ -2116,6 +2123,65 @@
}
}
+/// ProcessInputFile - Process a single AST input file with the specified state.
+///
+static void ProcessASTInputFile(const std::string &InFile, ProgActions PA,
+ const llvm::StringMap<bool> &Features,
+ Diagnostic &Diags, FileManager &FileMgr,
+ llvm::LLVMContext& Context) {
+ // FIXME: This is manufactoring its own diags and source manager, we should
+ // reuse ours.
+ std::string Error;
+ llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromPCHFile(InFile, FileMgr,
+ &Error));
+ if (!AST) {
+ Diags.Report(FullSourceLoc(), diag::err_fe_invalid_ast_file) << Error;
+ return;
+ }
+
+ Preprocessor &PP = AST->getPreprocessor();
+
+ llvm::OwningPtr<llvm::raw_ostream> OS;
+ llvm::sys::Path OutPath;
+ llvm::OwningPtr<ASTConsumer> Consumer(CreateConsumerAction(PP, InFile, PA, OS,
+ OutPath, Features,
+ Context));
+
+ if (!Consumer.get()) {
+ Diags.Report(FullSourceLoc(), diag::err_fe_invalid_ast_action);
+ return;
+ }
+
+ // Stream the input AST to the consumer.
+ Consumer->Initialize(AST->getASTContext());
+ AST->getASTContext()
+ .getExternalSource()->StartTranslationUnit(Consumer.get());
+ Consumer->HandleTranslationUnit(AST->getASTContext());
+
+ // FIXME: Tentative decls and #pragma weak aren't going to get handled
+ // correctly here.
+
+ // Release the consumer and the AST, in that order since the consumer may
+ // perform actions in its destructor which require the context.
+ if (DisableFree) {
+ Consumer.take();
+ AST.take();
+ } else {
+ Consumer.reset();
+ AST.reset();
+ }
+
+ // Always delete the output stream because we don't want to leak file
+ // handles. Also, we don't want to try to erase an open file.
+ OS.reset();
+
+ if ((HadErrors || (PP.getDiagnostics().getNumErrors() != 0)) &&
+ !OutPath.isEmpty()) {
+ // If we had errors, try to erase the output file.
+ OutPath.eraseFromDisk();
+ }
+}
+
static llvm::cl::list<std::string>
InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input files>"));
@@ -2258,6 +2324,14 @@
for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
const std::string &InFile = InputFilenames[i];
+ LangKind LK = GetLanguage(InFile);
+ // AST inputs are handled specially.
+ if (LK == langkind_ast) {
+ ProcessASTInputFile(InFile, ProgAction, Features,
+ Diags, FileMgr, Context);
+ continue;
+ }
+
/// Create a SourceManager object. This tracks and owns all the file
/// buffers allocated to a translation unit.
if (!SourceMgr)
@@ -2269,7 +2343,6 @@
LangOptions LangInfo;
DiagClient->setLangOptions(&LangInfo);
- LangKind LK = GetLanguage(InFile);
InitializeLangOptions(LangInfo, LK);
InitializeLanguageStandard(LangInfo, LK, Target.get(), Features);
More information about the cfe-commits
mailing list