From 4d00c92eb2954b45dd9417ed0b41928bb2145c41 Mon Sep 17 00:00:00 2001
From: Peter Matta <mattapet@fit.cvut.cz>
Date: Wed, 25 Apr 2018 23:25:04 +0200
Subject: [PATCH] Updated defaul interface for compiler

---
 include/CMakeLists.txt                        |  1 -
 include/dusk/AST/ASTContext.h                 | 84 ++++++++++++++++++
 include/dusk/AST/ASTVisitor.h                 |  2 -
 include/dusk/AST/CMakeLists.txt               |  1 +
 include/dusk/AST/Pattern.h                    |  5 +-
 include/dusk/Basic/LLVM.h                     |  4 +-
 include/dusk/Frontend/CMakeLists.txt          |  6 +-
 include/dusk/Frontend/Compiler.h              | 51 -----------
 include/dusk/Frontend/CompilerInstance.h      | 85 +++++++++++++++++++
 include/dusk/Frontend/CompilerInvocation.h    | 57 +++++++++++++
 .../Frontend/{InputFile.h => SourceFile.h}    | 10 ++-
 include/dusk/Parse/Parser.h                   | 51 +++++++----
 .../Formatter.h => lib/AST/ASTContext.cpp     | 18 +---
 lib/AST/ASTPrinter.cpp                        | 17 ++--
 lib/AST/CMakeLists.txt                        |  1 +
 lib/Frontend/CMakeLists.txt                   |  6 +-
 lib/Frontend/Compiler.cpp                     | 80 -----------------
 lib/Frontend/CompilerInstance.cpp             | 50 +++++++++++
 lib/Frontend/CompilerInvocation.cpp           | 42 +++++++++
 lib/Frontend/Formatter.cpp                    |  0
 lib/Frontend/InputFile.cpp                    | 20 -----
 lib/IRGen/CMakeLists.txt                      |  2 -
 lib/IRGen/TopLevelExpr.cpp                    |  0
 lib/IRGen/TopLevelExpr.h                      |  0
 lib/Parser/ParseDecl.cpp                      |  8 +-
 lib/Parser/ParseExpr.cpp                      | 20 ++---
 lib/Parser/ParsePattern.cpp                   |  4 +-
 lib/Parser/ParseStmt.cpp                      | 20 ++---
 lib/Parser/Parser.cpp                         | 21 +++--
 tools/dusk-format/main.cpp                    | 35 ++++++--
 30 files changed, 448 insertions(+), 253 deletions(-)
 create mode 100644 include/dusk/AST/ASTContext.h
 delete mode 100644 include/dusk/Frontend/Compiler.h
 create mode 100644 include/dusk/Frontend/CompilerInstance.h
 create mode 100644 include/dusk/Frontend/CompilerInvocation.h
 rename include/dusk/Frontend/{InputFile.h => SourceFile.h} (82%)
 rename include/dusk/Frontend/Formatter.h => lib/AST/ASTContext.cpp (50%)
 delete mode 100644 lib/Frontend/Compiler.cpp
 create mode 100644 lib/Frontend/CompilerInstance.cpp
 create mode 100644 lib/Frontend/CompilerInvocation.cpp
 delete mode 100644 lib/Frontend/Formatter.cpp
 delete mode 100644 lib/Frontend/InputFile.cpp
 delete mode 100644 lib/IRGen/TopLevelExpr.cpp
 delete mode 100644 lib/IRGen/TopLevelExpr.h

diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 0c39d4d..2cbe7c7 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -1,5 +1,4 @@
 add_subdirectory(dusk)
-link_directories(dusk)
 
 set(HEADERS
     ${HEADERS}
diff --git a/include/dusk/AST/ASTContext.h b/include/dusk/AST/ASTContext.h
new file mode 100644
index 0000000..caf17fd
--- /dev/null
+++ b/include/dusk/AST/ASTContext.h
@@ -0,0 +1,84 @@
+//===--- ASTContext.h - Object holding AST state ----------------*- C++ -*-===//
+//
+//                                 dusk-lang
+// This source file is part of a dusk-lang project, which is a semestral
+// assignement for BI-PJP course at Czech Technical University in Prague.
+// The software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DUSK_AST_CONTEXT_H
+#define DUSK_AST_CONTEXT_H
+
+#include "dusk/Basic/LLVM.h"
+#include "dusk/AST/ASTNode.h"
+#include "dusk/AST/Pattern.h"
+#include "dusk/AST/Type.h"
+#include "llvm/ADT/ArrayRef.h"
+#include <memory>
+#include <vector>
+
+namespace dusk {
+class Decl;
+class ModuleDecl;
+class Expr;
+class Stmt;
+class ASTNode;
+class Pattern;
+class Type;
+class VoidType;
+class IntType;
+  
+/// This class owns all of the nodes, which are part of the AST.
+class ASTContext {
+  std::vector<std::unique_ptr<ASTNode>> Nodes;
+  std::vector<std::unique_ptr<Pattern>> Patterns;
+  std::vector<std::unique_ptr<Type>> Types;
+  
+  bool IsError = false;
+  
+  ModuleDecl *RootModule;
+  
+public:
+  ASTContext() = default;
+  
+  /// Returns pointer to the root module of the AST.
+  ModuleDecl *getRootModule() const { return RootModule; }
+  
+  /// Sets the root module of the AST.
+  void setRootModule(ModuleDecl *RM) { RootModule = RM; }
+  
+  /// Returns \c true if \c setError has been called upon the context, \c false
+  /// otherwise.
+  bool isError() const { return IsError; }
+  
+  /// Sets AST error state to \c true.
+  ///
+  /// \node This action is ireversible.
+  void setError() { IsError = true; }
+  
+  ArrayRef<std::unique_ptr<ASTNode>> getNodes() const { return Nodes; }
+  
+  ArrayRef<std::unique_ptr<Pattern>> getPatterns() const { return Patterns; }
+  
+  ArrayRef<std::unique_ptr<Type>> getTypes() const { return Types; }
+  
+  template <typename T> T *pushNode(std::unique_ptr<T> &&Node) {
+    Nodes.push_back(std::move(Node));
+    return static_cast<T *>(Nodes.back().get());
+  }
+  
+  template <typename T> T *pushPattern(std::unique_ptr<T> &&Pattern) {
+    Patterns.push_back(std::move(Pattern));
+    return static_cast<T *>(Patterns.back().get());
+  }
+  
+  template <typename T> T *pushType(std::unique_ptr<T> &&Type) {
+    Types.push_back(std::move(Type));
+    return static_cast<T *>(Patterns.back().get());
+  }
+};
+  
+} // namespace dusk
+
+#endif /* DUSK_AST_CONTEXT_H */
diff --git a/include/dusk/AST/ASTVisitor.h b/include/dusk/AST/ASTVisitor.h
index af8db93..0bd1a5d 100644
--- a/include/dusk/AST/ASTVisitor.h
+++ b/include/dusk/AST/ASTVisitor.h
@@ -45,8 +45,6 @@ public:
       return visit(E);
     if (auto *S = dynamic_cast<Stmt *>(N))
       return visit(S);
-    if (auto *P = dynamic_cast<Pattern *>(N))
-      return visit(P);
 
     llvm_unreachable("Unexpected node");
   }
diff --git a/include/dusk/AST/CMakeLists.txt b/include/dusk/AST/CMakeLists.txt
index 98d812f..7321e37 100644
--- a/include/dusk/AST/CMakeLists.txt
+++ b/include/dusk/AST/CMakeLists.txt
@@ -1,4 +1,5 @@
 set(HEADERS
+    ${CMAKE_CURRENT_SOURCE_DIR}/ASTContext.h
     ${CMAKE_CURRENT_SOURCE_DIR}/ASTNode.h
     ${CMAKE_CURRENT_SOURCE_DIR}/ASTPrinter.h
     ${CMAKE_CURRENT_SOURCE_DIR}/ASTVisitor.h
diff --git a/include/dusk/AST/Pattern.h b/include/dusk/AST/Pattern.h
index 4ab8409..4499d99 100644
--- a/include/dusk/AST/Pattern.h
+++ b/include/dusk/AST/Pattern.h
@@ -25,7 +25,7 @@ class ParamDecl;
 /// Pattern description.
 enum struct PatternKind { Expr, Variable };
 
-class Pattern : public ASTNode {
+class Pattern {
   /// Pattern type.
   PatternKind Kind;
 
@@ -34,6 +34,9 @@ public:
   PatternKind getKind() const { return Kind; }
   
   virtual size_t count() const = 0;
+  virtual SMRange getSourceRange() const = 0;
+  SMLoc getLocStart() { return getSourceRange().Start; }
+  SMLoc getLocEnd() { return getSourceRange().End; }
 };
 
 /// Expression pattern
diff --git a/include/dusk/Basic/LLVM.h b/include/dusk/Basic/LLVM.h
index 1d0d2a9..a2122f5 100644
--- a/include/dusk/Basic/LLVM.h
+++ b/include/dusk/Basic/LLVM.h
@@ -25,7 +25,7 @@ template <typename T> class Optional;
 // Support
 class SMLoc;
 class SMRange;
-class SourceMrg;
+class SourceMgr;
 class SMDiagnostic;
 class SMFixIt;
 
@@ -48,7 +48,7 @@ using llvm::Optional;
 // Support
 using llvm::SMLoc;
 using llvm::SMRange;
-using llvm::SourceMrg;
+using llvm::SourceMgr;
 using llvm::SMDiagnostic;
 using llvm::SMFixIt;
 
diff --git a/include/dusk/Frontend/CMakeLists.txt b/include/dusk/Frontend/CMakeLists.txt
index 63b3453..154c1fd 100644
--- a/include/dusk/Frontend/CMakeLists.txt
+++ b/include/dusk/Frontend/CMakeLists.txt
@@ -1,7 +1,7 @@
 set(HEADERS
-    ${CMAKE_CURRENT_SOURCE_DIR}/Compiler.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/Formatter.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/InputFile.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/CompilerInstance.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/CompilerInvocation.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/SourceFile.h
     ${HEADERS}
     PARENT_SCOPE
 )
diff --git a/include/dusk/Frontend/Compiler.h b/include/dusk/Frontend/Compiler.h
deleted file mode 100644
index 57d4cad..0000000
--- a/include/dusk/Frontend/Compiler.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===--- Compiler.h - Dusk compiler class -----------------------*- C++ -*-===//
-//
-//                                 dusk-lang
-// This source file is part of a dusk-lang project, which is a semestral
-// assignement for BI-PJP course at Czech Technical University in Prague.
-// The software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DUSK_COMPILER_H
-#define DUSK_COMPILER_H
-
-#include "dusk/Basic/LLVM.h"
-#include "dusk/AST/Diagnostics.h"
-#include "dusk/AST/Diagnostics.h"
-#include "dusk/Frontend/InputFile.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/raw_os_ostream.h"
-#include <vector>
-#include <memory>
-
-namespace llvm {
-class Module;
-}
-
-namespace dusk {
-class ParserResult;
-
-class Compiler : public DiagnosticConsumer {
-  llvm::SourceMgr SourceManager;
-
-  DiagnosticEngine Engine;
-
-  std::vector<std::unique_ptr<InputFile>> InputFiles;
-
-  /// Diagnostic output stream
-  llvm::raw_os_ostream OS;
-
-public:
-  Compiler(std::vector<StringRef> Filenames);
-
-  void Compile();
-  void Lex();
-
-  void consume(SMDiagnostic &Diag);
-};
-
-} // namesapce dusk
-
-#endif /* DUSK_COMPILER_H */
diff --git a/include/dusk/Frontend/CompilerInstance.h b/include/dusk/Frontend/CompilerInstance.h
new file mode 100644
index 0000000..41af881
--- /dev/null
+++ b/include/dusk/Frontend/CompilerInstance.h
@@ -0,0 +1,85 @@
+//===--- CompilerInstance.h - Dusk compiler configuration -----*- C++ -*-===//
+//
+//                                 dusk-lang
+// This source file is part of a dusk-lang project, which is a semestral
+// assignement for BI-PJP course at Czech Technical University in Prague.
+// The software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND.
+//
+//===----------------------------------------------------------------------===//
+
+#include "dusk/Basic/LLVM.h"
+#include "dusk/AST/ASTContext.h"
+#include "dusk/AST/Diagnostics.h"
+#include "dusk/Frontend/CompilerInvocation.h"
+#include "dusk/Frontend/SourceFile.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/SourceMgr.h"
+#include <memory>
+
+#ifndef DUSK_COMPILER_INSTANCE_H
+#define DUSK_COMPILER_INSTANCE_H
+
+namespace dusk {
+class ModuleDecl;
+
+/// Encapsulation of compiler state and execution.
+class CompilerInstance {
+  CompilerInvocation Invocation;
+  SourceMgr SourceManager;
+  DiagnosticEngine Diag{SourceManager};
+  
+  /// Compilation context.
+  std::unique_ptr<ASTContext> Context;
+
+  /// Main compilation module
+  ModuleDecl *MainModule = nullptr;
+
+public:
+  /// Constructs a default compiler instance.
+  CompilerInstance() = default;
+
+  /// Retuns compilers source manager.
+  SourceMgr &getSourceManager() { return SourceManager; }
+
+  /// Returns compilers diagnostics.
+  DiagnosticEngine &getDiags() { return Diag; }
+
+  /// Returns AST context of current compilation
+  ASTContext &getContext() { return *Context; }
+
+  /// Returns \c true, if copmiler instance has an AST context, \c false
+  /// otherwise.
+  bool hasASTContext() const { return Context != nullptr; }
+
+  /// Retuns parsed file as a module.
+  ModuleDecl *getModule();
+
+  /// Returns the input file.
+  SourceFile *getInputFile();
+
+  /// Compiles a source file.
+  void performCompilation();
+  
+  /// Parses file and performs a semantic analysis.
+  void performSema();
+
+  /// Parses input file without performing any semantic analysis.
+  void performParseOnly();
+  
+  /// Free AST context to enable reuse of current compiler instance.
+  void freeContext();
+  
+  /// Reset compiler instance with new configuration.
+  void reset(CompilerInvocation &&I);
+  
+private:
+  // Explicitly forbid copying of any kind.
+  CompilerInstance(const CompilerInstance &other) = delete;
+  CompilerInstance &operator=(const CompilerInstance &other) = delete;
+  CompilerInstance(CompilerInstance &&other) = delete;
+  CompilerInstance &operator=(CompilerInstance &&other) = delete;
+};
+
+} // namespace dusk
+
+#endif /* DUSK_COMPILER_INSTANCE_H */
diff --git a/include/dusk/Frontend/CompilerInvocation.h b/include/dusk/Frontend/CompilerInvocation.h
new file mode 100644
index 0000000..777081d
--- /dev/null
+++ b/include/dusk/Frontend/CompilerInvocation.h
@@ -0,0 +1,57 @@
+//===--- CompilerInvocation.h - Dusk compiler configuration -----*- C++ -*-===//
+//
+//                                 dusk-lang
+// This source file is part of a dusk-lang project, which is a semestral
+// assignement for BI-PJP course at Czech Technical University in Prague.
+// The software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DUSK_COMPILER_INVOCATION_H
+#define DUSK_COMPILER_INVOCATION_H
+
+#include "dusk/Basic/LLVM.h"
+#include "dusk/AST/Diagnostics.h"
+#include "dusk/Frontend/SourceFile.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/SourceMgr.h"
+#include <vector>
+#include <memory>
+
+namespace dusk {
+  
+/// Compiler configuration.
+class CompilerInvocation {
+  
+  /// Minimum build target
+  llvm::Triple Target;
+  
+  std::unique_ptr<SourceFile> InputFile;
+  
+  StringRef ModuleName;
+  StringRef OutputName;
+  
+  bool IsQuiet;
+  
+public:
+  CompilerInvocation();
+
+  void setArgs(SourceMgr &SM, DiagnosticEngine &Diag, StringRef InFile,
+               StringRef OutFile, bool IsQuiet);
+
+  StringRef getTargetTriple() const { return Target.str(); }
+  
+  SourceFile *getInputFile() const { return InputFile.get(); }
+  
+  void setModuleName(StringRef Name) { ModuleName = Name; }
+  
+  StringRef getModuleName() const { return ModuleName; }
+  
+  StringRef getOutputFilename() const { return OutputName; }
+};
+  
+} // namespace dusk
+
+#endif /* DUSK_COMPILER_INVOCATION_H */
diff --git a/include/dusk/Frontend/InputFile.h b/include/dusk/Frontend/SourceFile.h
similarity index 82%
rename from include/dusk/Frontend/InputFile.h
rename to include/dusk/Frontend/SourceFile.h
index d84b670..20c474f 100644
--- a/include/dusk/Frontend/InputFile.h
+++ b/include/dusk/Frontend/SourceFile.h
@@ -1,4 +1,4 @@
-//===--- InputFile.h --------------------------------------------*- C++ -*-===//
+//===--- SourceFile.h -------------------------------------------*- C++ -*-===//
 //
 //                                 dusk-lang
 // This source file is part of a dusk-lang project, which is a semestral
@@ -23,15 +23,17 @@ namespace dusk {
 /// Upon construction of a new \c InputFile class, the object tries to load
 /// the provided file and pass it to provided \c SourceMgr instance,
 /// to register the as a new source buffer.
-class InputFile {
+class SourceFile {
   unsigned BufferID;
   std::string Filename;
   llvm::MemoryBuffer *Buffer;
-  llvm::SourceMgr &SourceManager;
 
 public:
   /// \brief Opens and reads a file with provided name.
-  InputFile(llvm::SourceMgr &SM, const StringRef F);
+  SourceFile(unsigned ID, llvm::MemoryBuffer *B, StringRef F)
+      : BufferID(ID), Filename(F), Buffer(B) {
+    assert(!Filename.empty() && "Filename must not be an empty string.");
+  }
 
   /// \bried Returns an ID of the opened buffer.
   unsigned bufferID() const { return BufferID; }
diff --git a/include/dusk/Parse/Parser.h b/include/dusk/Parse/Parser.h
index 8428099..8e1399e 100644
--- a/include/dusk/Parse/Parser.h
+++ b/include/dusk/Parse/Parser.h
@@ -15,6 +15,7 @@
 #define DUSK_PARSER_H
 
 #include "dusk/AST/ASTNode.h"
+#include "dusk/AST/ASTContext.h"
 #include "dusk/AST/Decl.h"
 #include "dusk/AST/Expr.h"
 #include "dusk/AST/Stmt.h"
@@ -24,7 +25,7 @@
 #include "dusk/Parse/Token.h"
 #include "dusk/Parse/Lexer.h"
 #include "dusk/Parse/ParserResult.h"
-#include "dusk/Frontend/InputFile.h"
+#include "dusk/Frontend/SourceFile.h"
 #include "llvm/Support/SMLoc.h"
 #include "llvm/Support/SourceMgr.h"
 
@@ -32,9 +33,14 @@ namespace dusk {
 
 /// The main class used for parsing a dusk-lang (.dusk) source file.
 class Parser {
+  ASTContext &Context;
+  
   llvm::SourceMgr &SourceManager;
-  InputFile &SourceFile;
-  DiagnosticEngine &Engine;
+  
+  SourceFile &SF;
+  
+  DiagnosticEngine &Diag;
+  
   Lexer *L;
 
   /// Parsing result.
@@ -47,7 +53,10 @@ class Parser {
   SMLoc PreviousLoc;
 
 public:
-  Parser(llvm::SourceMgr &SM, InputFile &SF, DiagnosticEngine &Engine,
+  Parser(ASTContext &C,
+         SourceMgr &SM,
+         SourceFile &SF,
+         DiagnosticEngine &Diag,
          unsigned BufferID);
 
   ~Parser();
@@ -79,17 +88,14 @@ public:
                          diag::DiagID ID = diag::DiagID::unexpected_token);
 
   /// Main parsing method.
-  ///
-  /// \return A pointer to the root of the AST representing parsed
-  ///  source file.
-  ParserResult &&parse();
+  ModuleDecl *parseModule();
 
 private:
-  //===------------------------------------------------------------------------===
-  //
-  //                     Recursive descent parsing methods
-  //
-  //===------------------------------------------------------------------------===
+//===------------------------------------------------------------------------===
+//
+//                     Recursive descent parsing methods
+//
+//===------------------------------------------------------------------------===
 
   ASTNode *parseGlobal();
 
@@ -170,9 +176,24 @@ private:
 
   /// Creates and adds a new instance of \c ASTNode to the parser result
   /// and returns a pointer to it.
-  template <typename Node, typename... Args> Node *make(Args &&... args) {
+  template <typename Node, typename... Args> Node *makeNode(Args &&... args) {
     auto N = std::unique_ptr<Node>(new Node(std::forward<Args>(args)...));
-    return R.push(std::move(N));
+    return Context.pushNode(std::move(N));
+  }
+
+  /// Creates and adds a new instance of \c ASTNode to the parser result
+  /// and returns a pointer to it.
+  template <typename Pattern, typename... Args>
+  Pattern *makePattern(Args &&... args) {
+    auto P = std::unique_ptr<Pattern>(new Pattern(std::forward<Args>(args)...));
+    return Context.pushPattern(std::move(P));
+  }
+
+  /// Creates and adds a new instance of \c ASTNode to the parser result
+  /// and returns a pointer to it.
+  template <typename Type, typename... Args> Type *makeType(Args &&... args) {
+    auto T = std::unique_ptr<Type>(new Type(std::forward<Args>(args)...));
+    return Context.pushType(std::move(T));
   }
 };
 
diff --git a/include/dusk/Frontend/Formatter.h b/lib/AST/ASTContext.cpp
similarity index 50%
rename from include/dusk/Frontend/Formatter.h
rename to lib/AST/ASTContext.cpp
index 22ea10b..42023b4 100644
--- a/include/dusk/Frontend/Formatter.h
+++ b/lib/AST/ASTContext.cpp
@@ -1,4 +1,4 @@
-//===--- Formatter.h - Dusk language formatter ------------------*- C++ -*-===//
+//===--- ASTContext.cpp ---------------------------------------------------===//
 //
 //                                 dusk-lang
 // This source file is part of a dusk-lang project, which is a semestral
@@ -7,19 +7,5 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef DUSK_FORMATTER_H
-#define DUSK_FORMATTER_H
 
-#include "dusk/AST/ASTNode.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace dusk {
-
-class Formatter {
-public:
-  void format(ASTNode *N, raw_ostream &OS);
-};
-
-} // namespace dusk
-
-#endif /* DUSK_FORMATTER_H */
+#include "dusk/AST/ASTContext.h"
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 2bf6346..201dd44 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -15,7 +15,6 @@
 #include "dusk/AST/Type.h"
 #include "dusk/AST/ASTVisitor.h"
 #include "dusk/Basic/TokenDefinition.h"
-#include "dusk/Frontend/Formatter.h"
 
 using namespace dusk;
 
@@ -499,11 +498,11 @@ StreamPrinter::StreamPrinter(raw_ostream &OS) : OS(OS) {}
 
 void StreamPrinter::printText(StringRef Text) { OS << Text; }
 
-// MARK: - Formatter
-
-void Formatter::format(ASTNode *N, raw_ostream &OS) {
-  PrettyPrinter pp(OS);
-  PrintAST p(pp);
-  p.ASTVisitor::visit(N);
-}
-
+//// MARK: - Formatter
+//
+//void Formatter::format(ASTNode *N, raw_ostream &OS) {
+//  PrettyPrinter pp(OS);
+//  PrintAST p(pp);
+//  p.ASTVisitor::visit(N);
+//}
+//
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 450cd4d..d7cf88a 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -1,4 +1,5 @@
 set(SOURCE
+    ${CMAKE_CURRENT_SOURCE_DIR}/ASTContext.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/ASTNode.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/ASTPrinter.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/ASTWalker.cpp
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index 04705cb..9164a59 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -1,7 +1,7 @@
 set(SOURCE
-    ${CMAKE_CURRENT_SOURCE_DIR}/Compiler.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/Formatter.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/InputFile.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/CompilerInstance.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/CompilerInvocation.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/SourceFile.cpp
     ${SOURCE}
     PARENT_SCOPE
 )
diff --git a/lib/Frontend/Compiler.cpp b/lib/Frontend/Compiler.cpp
deleted file mode 100644
index 18b7851..0000000
--- a/lib/Frontend/Compiler.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "dusk/Frontend/Compiler.h"
-#include "dusk/Frontend/Formatter.h"
-#include "dusk/Parse/Lexer.h"
-#include "dusk/Basic/TokenDefinition.h"
-#include "dusk/Parse/Parser.h"
-#include "dusk/IRGen/IRGenerator.h"
-#include "llvm/Support/raw_os_ostream.h"
-
-#include "llvm/Analysis/Passes.h"
-#include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
-#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <iostream>
-#include <vector>
-
-using namespace dusk;
-
-Compiler::Compiler(std::vector<StringRef> Filenames)
-  : Engine(SourceManager), OS(raw_os_ostream(std::cerr)) {
-  Engine.addConsumer(this);
-  for (auto &F : Filenames) {
-    auto File = std::make_unique<InputFile>(SourceManager, F);
-    InputFiles.push_back(std::move(File));
-  }
-}
-
-void Compiler::Compile() {
-  Formatter F;
-  raw_os_ostream OS(std::cout);
-  std::vector<ParserResult> Results;
-
-  for (auto &&File : InputFiles) {
-    Parser P(SourceManager, *File, Engine, File->bufferID());
-    auto R = P.parse();
-    // Stop compilation after error encounterment
-    if (R.isError())
-      return;
-    Results.push_back(std::move(R));
-  }
-
-//  for (auto &&R : Results)
-//    F.format(R.getRoot(), OS);
-  irgen::IRGenerator IRGen(Engine);
-  auto Module = IRGen.gen(Results.front().getRoot());
-  if (!Module)
-    return;
-  
-  Module->print(llvm::errs(), nullptr);
-  llvm::verifyModule(*Module);
-  std::cout << std::endl;
-}
-
-void Compiler::Lex() {
-  for (auto &&File : InputFiles) {
-    Lexer L(SourceManager, File->bufferID(), &Engine, true);
-    Token T;
-    do {
-      L.lex(T);
-      if (T.is(tok::unknown)) {
-        return;
-      }
-    } while (T.isNot(tok::eof));
-  }
-}
-
-void Compiler::consume(llvm::SMDiagnostic &Diag) {
-  Diag.print("duskc", OS);
-}
-
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
new file mode 100644
index 0000000..8cdd130
--- /dev/null
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -0,0 +1,50 @@
+//===--- CompilerInstance.cpp -------------------------------------------===//
+//
+//                                 dusk-lang
+// This source file is part of a dusk-lang project, which is a semestral
+// assignement for BI-PJP course at Czech Technical University in Prague.
+// The software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND.
+//
+//===----------------------------------------------------------------------===//
+
+#include "dusk/Frontend/CompilerInstance.h"
+
+#include "dusk/Parse/Parser.h"
+
+using namespace dusk;
+
+ModuleDecl *CompilerInstance::getModule() {
+  if (hasASTContext() && !Context->isError())
+    return MainModule;
+  else
+    return nullptr;
+}
+
+SourceFile *CompilerInstance::getInputFile() {
+  return Invocation.getInputFile();
+}
+
+void CompilerInstance::performCompilation() {
+  
+}
+
+void CompilerInstance::performSema() {
+  
+}
+
+void CompilerInstance::performParseOnly() {
+  Context = std::make_unique<ASTContext>();
+  auto InputFile = Invocation.getInputFile();
+  Parser P(*Context, SourceManager, *InputFile, Diag, InputFile->bufferID());
+  MainModule = P.parseModule();
+}
+
+void CompilerInstance::freeContext() {
+  Context.reset();
+}
+
+void CompilerInstance::reset(CompilerInvocation &&I) {
+  Invocation = std::move(I);
+  MainModule = nullptr;
+  freeContext();
+}
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
new file mode 100644
index 0000000..3f2eebf
--- /dev/null
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -0,0 +1,42 @@
+//===--- CompilerInvocation.cpp -------------------------------------------===//
+//
+//                                 dusk-lang
+// This source file is part of a dusk-lang project, which is a semestral
+// assignement for BI-PJP course at Czech Technical University in Prague.
+// The software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND.
+//
+//===----------------------------------------------------------------------===//
+
+#include "dusk/Frontend/CompilerInvocation.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/SMLoc.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/Path.h"
+
+using namespace dusk;
+
+CompilerInvocation::CompilerInvocation()
+    : Target(llvm::sys::getDefaultTargetTriple()), OutputName("a.out") {}
+
+void CompilerInvocation::setArgs(SourceMgr &SM, DiagnosticEngine &Diag,
+                                 StringRef InFile, StringRef OutFile,
+                                 bool IsQ) {
+  OutputName = OutFile;
+  IsQuiet = IsQ;
+
+  if (auto Err = llvm::MemoryBuffer::getFile(InFile)) {
+    auto Buff = std::move(*Err);
+    auto L = SMLoc::getFromPointer(Buff->getBufferStart());
+    auto BuffPtr = Buff.get();
+    auto BuffID = SM.AddNewSourceBuffer(std::move(Buff), L);
+    InputFile = std::make_unique<SourceFile>(BuffID, BuffPtr, InFile);
+  } else {
+    llvm_unreachable("Error opening or reading file");
+  }
+}
diff --git a/lib/Frontend/Formatter.cpp b/lib/Frontend/Formatter.cpp
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/Frontend/InputFile.cpp b/lib/Frontend/InputFile.cpp
deleted file mode 100644
index f5567c0..0000000
--- a/lib/Frontend/InputFile.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "dusk/Frontend/InputFile.h"
-
-using namespace dusk;
-
-InputFile::InputFile(llvm::SourceMgr &SM, const StringRef F)
-    : Filename(F), SourceManager(SM) {
-  assert(!Filename.empty() && "Filename must not be an empty string.");
-
-  if (auto Res = llvm::MemoryBuffer::getFile(Filename)) {
-    auto B = std::move(*Res);
-    auto L = SMLoc::getFromPointer(B->getBufferStart());
-    Buffer = B.get();
-    BufferID = SourceManager.AddNewSourceBuffer(std::move(B), L);
-
-  } else {
-    assert("Error opening and/or reading file" && false);
-  }
-}
-
-
diff --git a/lib/IRGen/CMakeLists.txt b/lib/IRGen/CMakeLists.txt
index ed0c3df..7b5e659 100644
--- a/lib/IRGen/CMakeLists.txt
+++ b/lib/IRGen/CMakeLists.txt
@@ -8,8 +8,6 @@ set(SOURCE
     ${CMAKE_CURRENT_SOURCE_DIR}/GenStmt.h
     ${CMAKE_CURRENT_SOURCE_DIR}/IRGenerator.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/Scope.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TopLevelExpr.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/TopLevelExpr.h
     ${SOURCE}
     PARENT_SCOPE
 )
diff --git a/lib/IRGen/TopLevelExpr.cpp b/lib/IRGen/TopLevelExpr.cpp
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/IRGen/TopLevelExpr.h b/lib/IRGen/TopLevelExpr.h
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/Parser/ParseDecl.cpp b/lib/Parser/ParseDecl.cpp
index 807d814..38b1e81 100644
--- a/lib/Parser/ParseDecl.cpp
+++ b/lib/Parser/ParseDecl.cpp
@@ -26,7 +26,7 @@ Decl *Parser::parseConstDecl() {
     return nullptr;
   }
 
-  return make<LetDecl>(ID.getText(), ID.getLoc(), L, parseDeclValue());
+  return makeNode<LetDecl>(ID.getText(), ID.getLoc(), L, parseDeclValue());
 }
 
 /// Var declaration
@@ -44,7 +44,7 @@ Decl *Parser::parseVarDecl() {
     return nullptr;
   }
 
-  return make<VarDecl>(ID.getText(), ID.getLoc(), L, parseDeclValue());
+  return makeNode<VarDecl>(ID.getText(), ID.getLoc(), L, parseDeclValue());
 }
 
 /// DeclVal ::=
@@ -82,7 +82,7 @@ Decl *Parser::parseFuncDecl() {
 
   auto Args = static_cast<VarPattern *>(parseVarPattern());
   auto RetTy = parseFuncDeclType();
-  return make<FuncDecl>(ID.getText(), ID.getLoc(), FL, Args, RetTy);
+  return makeNode<FuncDecl>(ID.getText(), ID.getLoc(), FL, Args, RetTy);
 }
 
 /// Function return type
@@ -121,6 +121,6 @@ Decl *Parser::parseParamDecl() {
 
   auto ID = Tok;
   consumeToken();
-  return make<ParamDecl>(ID.getText(), ID.getLoc());
+  return makeNode<ParamDecl>(ID.getText(), ID.getLoc());
 }
 
diff --git a/lib/Parser/ParseExpr.cpp b/lib/Parser/ParseExpr.cpp
index 8cfed77..e4bc62c 100644
--- a/lib/Parser/ParseExpr.cpp
+++ b/lib/Parser/ParseExpr.cpp
@@ -52,7 +52,7 @@ Expr *Parser::parseAssignExprRHS(Expr *LHS) {
 
   case tok::assign:
     consumeToken();
-    return make<AssignExpr>((IdentifierExpr *)LHS, parseExpr());
+    return makeNode<AssignExpr>((IdentifierExpr *)LHS, parseExpr());
 
   default:
       diagnose(Tok.getLoc());
@@ -94,7 +94,7 @@ Expr *Parser::parseLogicalExprRHS(Expr *LHS) {
   case tok::greater:
   case tok::greater_eq:
     consumeToken();
-    return make<InfixExpr>(LHS, parseArithExpr(), T);
+    return makeNode<InfixExpr>(LHS, parseArithExpr(), T);
 
   default:
       diagnose(Tok.getLoc());
@@ -138,7 +138,7 @@ Expr *Parser::parseArithExprRHS(Expr *LHS) {
   case tok::plus:
   case tok::minus:
     consumeToken();
-    return make<InfixExpr>(LHS, parseExpr(), T);
+    return makeNode<InfixExpr>(LHS, parseExpr(), T);
 
   default:
       diagnose(Tok.getLoc());
@@ -185,7 +185,7 @@ Expr *Parser::parseMulExprRHS(Expr *LHS) {
   case tok::multipy:
   case tok::divide:
     consumeToken();
-    return make<InfixExpr>(LHS, parseExpr(), T);
+    return makeNode<InfixExpr>(LHS, parseExpr(), T);
 
   default:
       diagnose(Tok.getLoc());
@@ -246,21 +246,21 @@ Expr *Parser::parseIdentifierExpr() {
 
   auto Name = Tok.getText();
   auto Loc = consumeToken();
-  return make<IdentifierExpr>(Name, Loc);
+  return makeNode<IdentifierExpr>(Name, Loc);
 }
 
 /// CallExpr ::= idenifier '(' Args ')'
 Expr *Parser::parseCallExpr(Expr *Dest) {
   // Validate `(`
   assert(Tok.is(tok::l_paren) && "Invalid parse method.");
-  return make<CallExpr>(Dest, parseExprPattern());
+  return makeNode<CallExpr>(Dest, parseExprPattern());
 }
 
 /// SubscriptExpr ::= idenifier '[' Args ']'
 Expr *Parser::parseSubscriptExpr(Expr *Dest) {
   // Validate `[`
   assert(Tok.is(tok::l_bracket) && "Invalid parse method.");
-  return make<SubscriptExpr>(Dest, parseSubscriptStmt());
+  return makeNode<SubscriptExpr>(Dest, parseSubscriptStmt());
 }
 
 /// PrimaryExpr ::= '(' Expr ')'
@@ -274,7 +274,7 @@ Expr *Parser::parseParenExpr() {
       .fixItAfter(")", Tok.getLoc());
     return nullptr;
   }
-  return make<ParenExpr>(E, L, PreviousLoc);
+  return makeNode<ParenExpr>(E, L, PreviousLoc);
 }
 
 Expr *Parser::parseUnaryExpr() {
@@ -283,7 +283,7 @@ Expr *Parser::parseUnaryExpr() {
 
   auto Op = Tok;
   consumeToken();
-  return make<PrefixExpr>(parsePrimaryExpr(), Op);
+  return makeNode<PrefixExpr>(parsePrimaryExpr(), Op);
 }
 
 /// Properly parse number literal
@@ -317,5 +317,5 @@ Expr *Parser::parseNumberLiteralExpr() {
   }
 
   consumeToken();
-  return make<NumberLiteralExpr>(Value, R);
+  return makeNode<NumberLiteralExpr>(Value, R);
 }
diff --git a/lib/Parser/ParsePattern.cpp b/lib/Parser/ParsePattern.cpp
index 376f944..d42e443 100644
--- a/lib/Parser/ParsePattern.cpp
+++ b/lib/Parser/ParsePattern.cpp
@@ -28,7 +28,7 @@ Pattern *Parser::parseExprPattern() {
     .fixItBefore(")", Tok.getLoc());
     return nullptr;
   }
-  return make<ExprPattern>(std::move(C), LP, PreviousLoc);
+  return makePattern<ExprPattern>(std::move(C), LP, PreviousLoc);
 }
 
 /// ExprPatternBody ::=
@@ -96,7 +96,7 @@ Pattern *Parser::parseVarPattern() {
       .fixItBefore(")", Tok.getLoc());
     return nullptr;
   }
-  return make<VarPattern>(std::move(C), LP, PreviousLoc);
+  return makePattern<VarPattern>(std::move(C), LP, PreviousLoc);
 }
 
 /// VarPatternBody ::=
diff --git a/lib/Parser/ParseStmt.cpp b/lib/Parser/ParseStmt.cpp
index b134951..c631e32 100644
--- a/lib/Parser/ParseStmt.cpp
+++ b/lib/Parser/ParseStmt.cpp
@@ -51,7 +51,7 @@ Stmt *Parser::parseBreakStmt() {
       .fixItAfter(";", PreviousLoc);
     return nullptr;
   }
-  return make<BreakStmt>(llvm::SMRange{S, E});
+  return makeNode<BreakStmt>(llvm::SMRange{S, E});
 }
 
 /// ReturnStmt ::=
@@ -78,7 +78,7 @@ Stmt *Parser::parseReturnStmt() {
     .fixItAfter(";", PreviousLoc);
     return nullptr;
   }
-  return make<ReturnStmt>(RL, E);
+  return makeNode<ReturnStmt>(RL, E);
 }
 
 /// SubscriptionPattern ::=
@@ -95,7 +95,7 @@ Stmt *Parser::parseSubscriptStmt() {
     return nullptr;
   }
   
-  return make<SubscriptStmt>(V, L, PreviousLoc);
+  return makeNode<SubscriptStmt>(V, L, PreviousLoc);
 }
 
 /// Block ::=
@@ -115,7 +115,7 @@ Stmt *Parser::parseBlock() {
       .fixItBefore("}", Tok.getLoc());
     return nullptr;
   }
-  return make<BlockStmt>(L, PreviousLoc, std::move(Nodes));
+  return makeNode<BlockStmt>(L, PreviousLoc, std::move(Nodes));
 }
 
 ASTNode *Parser::parseBlockBody() {
@@ -171,7 +171,7 @@ Stmt *Parser::parseExterStmt() {
     return nullptr;
   }
   
-  auto D = make<ExternStmt>(EL, parseFuncDecl());
+  auto D = makeNode<ExternStmt>(EL, parseFuncDecl());
   if (consumeIf(tok::semicolon))
     return D;
 
@@ -187,7 +187,7 @@ Stmt *Parser::parseFuncStmt() {
   assert(Tok.is(tok::kwFunc) && "Invalid parse method");
   auto D = parseFuncDecl();
   if (Tok.is(tok::l_brace))
-    return make<FuncStmt>(D, parseBlock());
+    return makeNode<FuncStmt>(D, parseBlock());
   
   diagnose(Tok.getLoc(), diag::DiagID::expected_l_brace)
     .fixIt("{", Tok.getLoc());
@@ -216,7 +216,7 @@ Stmt *Parser::parseForStmt() {
     return nullptr;
   }
   auto Body = parseBlock();
-  return make<ForStmt>(FLoc, Var, Rng, Body);
+  return makeNode<ForStmt>(FLoc, Var, Rng, Body);
 }
 
 Stmt *Parser::parseRangeStmt() {
@@ -230,7 +230,7 @@ Stmt *Parser::parseRangeStmt() {
   }
   consumeToken();
   auto E = parseExpr();
-  return make<RangeStmt>(S, E, Op);
+  return makeNode<RangeStmt>(S, E, Op);
 }
 
 Stmt *Parser::parseWhileStmt() {
@@ -239,7 +239,7 @@ Stmt *Parser::parseWhileStmt() {
 
   auto Cond = parseExpr();
   auto Body = parseBlock();
-  return make<WhileStmt>(L, Cond, Body);
+  return makeNode<WhileStmt>(L, Cond, Body);
 }
 
 Stmt *Parser::parseIfStmt() {
@@ -248,7 +248,7 @@ Stmt *Parser::parseIfStmt() {
   auto Cond = parseExpr();
   auto Then = parseBlock();
   auto Else = parseElseStmt();
-  return make<IfStmt>(L, Cond, Then, Else);
+  return makeNode<IfStmt>(L, Cond, Then, Else);
 }
 
 Stmt *Parser::parseElseStmt() {
diff --git a/lib/Parser/Parser.cpp b/lib/Parser/Parser.cpp
index 42e6bd0..f6a1afa 100644
--- a/lib/Parser/Parser.cpp
+++ b/lib/Parser/Parser.cpp
@@ -17,10 +17,10 @@ using namespace dusk;
 
 // MARK: - Parser
 
-Parser::Parser(llvm::SourceMgr &SM, InputFile &SF, DiagnosticEngine &Engine,
-               unsigned BufferID)
-    : SourceManager(SM), SourceFile(SF), Engine(Engine),
-      L(new Lexer(SM, BufferID, &Engine)) {}
+Parser::Parser(ASTContext &C, llvm::SourceMgr &SM, SourceFile &SF,
+               DiagnosticEngine &Diag, unsigned BufferID)
+    : Context(C), SourceManager(SM), SF(SF), Diag(Diag),
+      L(new Lexer(SM, BufferID, &Diag)) {}
 
 Parser::~Parser() { delete L; }
 
@@ -43,26 +43,25 @@ DiagnosticRef Parser::diagnose(SMLoc Loc, diag::DiagID ID) {
   if (diag::DiagID::unexpected_token == ID && R.isError())
     // No better diagnostics than already given.
     return DiagnosticRef();
-  R.setError();
+  Context.setError();
   if (Tok.is(tok::unknown))
     // Handeled by lexer.
     return DiagnosticRef();
-  return Engine.diagnose(Loc, ID);
+  return Diag.diagnose(Loc, ID);
 }
 
 // MARK: - Main parsing loop
 
-ParserResult &&Parser::parse() {
+ModuleDecl *Parser::parseModule() {
   std::vector<ASTNode *> Nodes;
   consumeToken();
   while (Tok.isNot(tok::eof) && !R.isError())
     Nodes.push_back(parseGlobal());
-
-  if (Nodes.size() != 0)
-    R.setRoot(make<ModuleDecl>(SourceFile.file(), std::move(Nodes)));
-  return std::move(R);
+  
+  return makeNode<ModuleDecl>(SF.file(), std::move(Nodes));
 }
 
+
 ASTNode *Parser::parseGlobal() {
   switch (Tok.getKind()) {
   case tok::kwVar:
diff --git a/tools/dusk-format/main.cpp b/tools/dusk-format/main.cpp
index 2e31454..cfcbbbc 100644
--- a/tools/dusk-format/main.cpp
+++ b/tools/dusk-format/main.cpp
@@ -1,14 +1,35 @@
-#include "dusk/Frontend/Compiler.h"
+#include "dusk/Basic/LLVM.h"
+#include "dusk/Frontend/CompilerInvocation.h"
+#include "dusk/Frontend/CompilerInstance.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CommandLine.h"
 #include <iostream>
+#include <string>
 
 using namespace dusk;
+using namespace llvm;
+
+cl::opt<std::string> InFile(cl::Positional, cl::Required,
+                            cl::desc("<input file>"), cl::init("-"));
+
+cl::opt<std::string> OutFile("o", cl::desc("Specify output filename"),
+                             cl::value_desc("<filename>"));
+cl::opt<bool> IsQuiet("quiet", cl::desc("Suppress diagnostics"));
+cl::alias IsQuiet2("q", cl::desc("Suppress diagnostics"),
+                   cl::aliasopt(IsQuiet));
+
+void initCompilerInstance(CompilerInstance &C) {
+  CompilerInvocation Inv;
+  Inv.setArgs(C.getSourceManager(), C.getDiags(), InFile, OutFile, IsQuiet);
+  C.reset(std::move(Inv));
+}
 
 int main(int argc, const char *argv[]) {
-  std::vector<llvm::StringRef> Filenames;
-  for (size_t i = 1; i < argc; i++) {
-    Filenames.push_back(argv[i]);
-  }
-  Compiler C(Filenames);
-  C.Compile();
+  cl::ParseCommandLineOptions(argc, argv);
+  CompilerInstance Compiler;
+  initCompilerInstance(Compiler);
+
+  Compiler.performParseOnly();
+
   return 0;
 }
-- 
GitLab