summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Doffman <mark.doffman@codethink.co.uk>2014-10-29 15:48:44 +0000
committerMark Doffman <mark.doffman@codethink.co.uk>2014-11-03 21:02:29 +0000
commit5e1f661d0a5cc9d86ecccdd2224254571aaede21 (patch)
tree5a51cfa56376bc61e0f02b3dd4abcf639352c410
parent1646423aa7d657da1e95126c5b1bf2a9e72d8160 (diff)
downloadflang-5e1f661d0a5cc9d86ecccdd2224254571aaede21.tar.gz
Update code to llvm 3.6.
Updating API's to build with llvm 3.6.
-rw-r--r--include/flang/AST/ASTContext.h12
-rw-r--r--include/flang/AST/Decl.h2
-rw-r--r--include/flang/Basic/TargetOptions.h55
-rw-r--r--include/flang/CodeGen/BackendUtil.h40
-rw-r--r--include/flang/CodeGen/CodeGenAction.h102
-rw-r--r--include/flang/CodeGen/ModuleBuilder.h48
-rw-r--r--include/flang/Frontend/ASTUnit.h198
-rw-r--r--include/flang/Frontend/CodeGenOptions.def157
-rw-r--r--include/flang/Frontend/CodeGenOptions.h153
-rw-r--r--include/flang/Frontend/CommandLineSourceLoc.h87
-rw-r--r--include/flang/Frontend/CompilerInstance.h528
-rw-r--r--include/flang/Frontend/CompilerInvocation.h131
-rw-r--r--include/flang/Frontend/FrontendAction.h191
-rw-r--r--include/flang/Frontend/FrontendOptions.h234
-rw-r--r--include/flang/Frontend/VerifyDiagnosticConsumer.h3
-rw-r--r--lib/AST/Expr.cpp2
-rw-r--r--lib/Basic/Token.cpp4
-rw-r--r--lib/CodeGen/BackendUtil.cpp488
-rw-r--r--lib/CodeGen/CGCall.cpp2
-rw-r--r--lib/CodeGen/CGExprScalar.cpp2
-rw-r--r--lib/CodeGen/CGIntrinsic.cpp2
-rw-r--r--lib/CodeGen/CGStmt.cpp2
-rw-r--r--lib/CodeGen/CodeGenAction.cpp245
-rw-r--r--lib/CodeGen/CodeGenFunction.h2
-rw-r--r--lib/CodeGen/CodeGenModule.cpp4
-rw-r--r--lib/CodeGen/CodeGenModule.h4
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp11
-rw-r--r--lib/Sema/Sema.cpp6
-rw-r--r--tools/driver/CMakeLists.txt1
-rw-r--r--tools/driver/Main.cpp39
30 files changed, 2705 insertions, 50 deletions
diff --git a/include/flang/AST/ASTContext.h b/include/flang/AST/ASTContext.h
index 5191122dcd..7e9c00405a 100644
--- a/include/flang/AST/ASTContext.h
+++ b/include/flang/AST/ASTContext.h
@@ -79,8 +79,8 @@ public:
void *Allocate(unsigned Size, unsigned Align = 8) const {
return BumpAlloc.Allocate(Size, Align);
}
- void Deallocate(void *Ptr) const {
- BumpAlloc.Deallocate(Ptr);
+ void Deallocate(void *Ptr, size_t size) const {
+ BumpAlloc.Deallocate((const void*) Ptr, size);
}
LangOptions getLangOpts() const {
@@ -259,9 +259,9 @@ inline void *operator new(size_t Bytes, const flang::ASTContext &C,
/// invoking it directly; see the new operator for more details. This operator
/// is called implicitly by the compiler if a placement new expression using the
/// ASTContext throws in the object constructor.
-inline void operator delete(void *Ptr, const flang::ASTContext &C, size_t)
+inline void operator delete(void *Ptr, const flang::ASTContext &C, size_t size)
throw () {
- C.Deallocate(Ptr);
+ C.Deallocate(Ptr, size);
}
/// This placement form of operator new[] uses the ASTContext's allocator for
@@ -297,9 +297,9 @@ inline void *operator new[](size_t Bytes, const flang::ASTContext& C,
/// invoking it directly; see the new[] operator for more details. This operator
/// is called implicitly by the compiler if a placement new[] expression using
/// the ASTContext throws in the object constructor.
-inline void operator delete[](void *Ptr, const flang::ASTContext &C, size_t)
+inline void operator delete[](void *Ptr, const flang::ASTContext &C, size_t size)
throw () {
- C.Deallocate(Ptr);
+ C.Deallocate(Ptr, size);
}
#endif
diff --git a/include/flang/AST/Decl.h b/include/flang/AST/Decl.h
index a3248e3dc4..230968542a 100644
--- a/include/flang/AST/Decl.h
+++ b/include/flang/AST/Decl.h
@@ -1035,7 +1035,7 @@ static inline llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
// Specialization selected when ToTy is not a known subclass of DeclContext.
template <class ToTy,
- bool IsKnownSubtype = ::llvm::is_base_of< DeclContext, ToTy>::value>
+ bool IsKnownSubtype = ::std::is_base_of< DeclContext, ToTy>::value>
struct cast_convert_decl_context {
static const ToTy *doit(const DeclContext *Val) {
return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
diff --git a/include/flang/Basic/TargetOptions.h b/include/flang/Basic/TargetOptions.h
new file mode 100644
index 0000000000..6b06e9b5b5
--- /dev/null
+++ b/include/flang/Basic/TargetOptions.h
@@ -0,0 +1,55 @@
+//===--- TargetOptions.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the flang::TargetOptions class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_FRONTEND_TARGETOPTIONS_H
+#define LLVM_FLANG_FRONTEND_TARGETOPTIONS_H
+
+#include "flang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include <string>
+#include <vector>
+
+namespace flang {
+
+/// \brief Options for controlling the target.
+class TargetOptions : public llvm::RefCountedBase<TargetOptions> {
+public:
+ /// If given, the name of the target triple to compile for. If not given the
+ /// target will be selected to match the host.
+ std::string Triple;
+
+ /// If given, the name of the target CPU to generate code for.
+ std::string CPU;
+
+ /// If given, the name of the target ABI to use.
+ std::string ABI;
+
+ /// If given, the name of the target C++ ABI to use. If not given, defaults
+ /// to "itanium".
+ std::string CXXABI;
+
+ /// If given, the version string of the linker in use.
+ std::string LinkerVersion;
+
+ /// \brief The list of target specific features to enable or disable, as written on the command line.
+ std::vector<std::string> FeaturesAsWritten;
+
+ /// The list of target specific features to enable or disable -- this should
+ /// be a list of strings starting with by '+' or '-'.
+ std::vector<std::string> Features;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/flang/CodeGen/BackendUtil.h b/include/flang/CodeGen/BackendUtil.h
new file mode 100644
index 0000000000..3daac9f40c
--- /dev/null
+++ b/include/flang/CodeGen/BackendUtil.h
@@ -0,0 +1,40 @@
+//===--- BackendUtil.h - LLVM Backend Utilities -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_CODEGEN_BACKEND_UTIL_H
+#define LLVM_FLANG_CODEGEN_BACKEND_UTIL_H
+
+#include "flang/Basic/LLVM.h"
+
+namespace llvm {
+ class Module;
+}
+
+namespace flang {
+ class DiagnosticsEngine;
+ class CodeGenOptions;
+ class TargetOptions;
+ class LangOptions;
+
+ enum BackendAction {
+ Backend_EmitAssembly, ///< Emit native assembly files
+ Backend_EmitBC, ///< Emit LLVM bitcode files
+ Backend_EmitLL, ///< Emit human-readable LLVM assembly
+ Backend_EmitNothing, ///< Don't emit anything (benchmarking mode)
+ Backend_EmitMCNull, ///< Run CodeGen, but don't emit anything
+ Backend_EmitObj ///< Emit native object files
+ };
+
+ void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts,
+ const TargetOptions &TOpts, const LangOptions &LOpts,
+ llvm::Module *M,
+ BackendAction Action, raw_ostream *OS);
+}
+
+#endif
diff --git a/include/flang/CodeGen/CodeGenAction.h b/include/flang/CodeGen/CodeGenAction.h
new file mode 100644
index 0000000000..2951ac8429
--- /dev/null
+++ b/include/flang/CodeGen/CodeGenAction.h
@@ -0,0 +1,102 @@
+//===--- CodeGenAction.h - LLVM Code Generation Frontend Action -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_CODEGEN_CODE_GEN_ACTION_H
+#define LLVM_FLANG_CODEGEN_CODE_GEN_ACTION_H
+
+#include "flang/Frontend/FrontendAction.h"
+
+namespace llvm {
+ class LLVMContext;
+ class Module;
+}
+
+namespace flang {
+class BackendConsumer;
+
+class CodeGenAction : public ASTFrontendAction {
+private:
+ unsigned Act;
+ std::unique_ptr<llvm::Module> TheModule;
+ llvm::Module *LinkModule;
+ llvm::LLVMContext *VMContext;
+ bool OwnsVMContext;
+
+protected:
+ /// Create a new code generation action. If the optional \p _VMContext
+ /// parameter is supplied, the action uses it without taking ownership,
+ /// otherwise it creates a fresh LLVM context and takes ownership.
+ CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = 0);
+
+ virtual bool hasIRSupport() const;
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile);
+
+ virtual void ExecuteAction();
+
+ virtual void EndSourceFileAction();
+
+public:
+ ~CodeGenAction();
+
+ /// setLinkModule - Set the link module to be used by this action. If a link
+ /// module is not provided, and CodeGenOptions::LinkBitcodeFile is non-empty,
+ /// the action will load it from the specified file.
+ void setLinkModule(llvm::Module *Mod) { LinkModule = Mod; }
+
+ /// takeModule - Take the generated LLVM module, for use after the action has
+ /// been run. The result may be null on failure.
+ llvm::Module *takeModule();
+
+ /// Take the LLVM context used by this action.
+ llvm::LLVMContext *takeLLVMContext();
+
+ BackendConsumer *BEConsumer;
+};
+
+class EmitAssemblyAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitAssemblyAction(llvm::LLVMContext *_VMContext = 0);
+};
+
+class EmitBCAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitBCAction(llvm::LLVMContext *_VMContext = 0);
+};
+
+class EmitLLVMAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitLLVMAction(llvm::LLVMContext *_VMContext = 0);
+};
+
+class EmitLLVMOnlyAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext = 0);
+};
+
+class EmitCodeGenOnlyAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext = 0);
+};
+
+class EmitObjAction : public CodeGenAction {
+ virtual void anchor();
+public:
+ EmitObjAction(llvm::LLVMContext *_VMContext = 0);
+};
+
+}
+
+#endif
diff --git a/include/flang/CodeGen/ModuleBuilder.h b/include/flang/CodeGen/ModuleBuilder.h
new file mode 100644
index 0000000000..b3de50e442
--- /dev/null
+++ b/include/flang/CodeGen/ModuleBuilder.h
@@ -0,0 +1,48 @@
+//===--- CodeGen/ModuleBuilder.h - Build LLVM from ASTs ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ModuleBuilder interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_CODEGEN_MODULEBUILDER_H
+#define LLVM_FLANG_CODEGEN_MODULEBUILDER_H
+
+#include "flang/AST/ASTConsumer.h"
+#include "flang/Basic/TargetOptions.h"
+#include "flang/Frontend/CodeGenOptions.h"
+#include <string>
+
+namespace llvm {
+ class LLVMContext;
+ class Module;
+}
+
+namespace flang {
+ class DiagnosticsEngine;
+ class LangOptions;
+
+ class CodeGenerator : public ASTConsumer {
+ virtual void anchor();
+ public:
+ virtual llvm::Module* GetModule() = 0;
+ virtual llvm::Module* ReleaseModule() = 0;
+ };
+
+ /// CreateLLVMCodeGen - Create a CodeGenerator instance.
+ /// It is the responsibility of the caller to call delete on
+ /// the allocated CodeGenerator instance.
+ CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags,
+ const std::string &ModuleName,
+ const CodeGenOptions &CGO,
+ const TargetOptions &TO,
+ llvm::LLVMContext& C);
+}
+
+#endif
diff --git a/include/flang/Frontend/ASTUnit.h b/include/flang/Frontend/ASTUnit.h
new file mode 100644
index 0000000000..31ab83d522
--- /dev/null
+++ b/include/flang/Frontend/ASTUnit.h
@@ -0,0 +1,198 @@
+//===--- ASTUnit.h - ASTUnit utility ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// ASTUnit utility class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_FRONTEND_ASTUNIT_H
+#define LLVM_FLANG_FRONTEND_ASTUNIT_H
+
+#include "flang/AST/ASTContext.h"
+#include "flang/AST/ASTConsumer.h"
+#include "flang/Basic/LangOptions.h"
+#include "flang/Basic/TargetOptions.h"
+#include "flang/Sema/Sema.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Path.h"
+#include <cassert>
+#include <map>
+#include <string>
+#include <sys/types.h>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+ class MemoryBuffer;
+}
+
+namespace flang {
+class ASTContext;
+class ASTReader;
+class CodeCompleteConsumer;
+class CompilerInvocation;
+class CompilerInstance;
+class Decl;
+class DiagnosticsEngine;
+class FileEntry;
+class FileManager;
+class HeaderSearch;
+class Preprocessor;
+class SourceManager;
+class TargetInfo;
+class ASTFrontendAction;
+class ASTDeserializationListener;
+
+/// \brief Utility class for loading a ASTContext from an AST file.
+///
+class ASTUnit {
+private:
+ llvm::IntrusiveRefCntPtr<LangOptions> LangOpts;
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
+ llvm::IntrusiveRefCntPtr<TargetInfo> Target;
+ llvm::IntrusiveRefCntPtr<ASTContext> Ctx;
+ llvm::IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+
+ /// \brief The AST consumer that received information about the translation
+ /// unit as it was parsed or loaded.
+ std::unique_ptr<ASTConsumer> Consumer;
+
+ /// \brief The semantic analysis object used to type-check the translation
+ /// unit.
+ std::unique_ptr<Sema> TheSema;
+
+ /// Optional owned invocation, just used to make the invocation used in
+ /// LoadFromCommandLine available.
+ llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation;
+
+ /// The name of the original source file used to generate this ASTUnit.
+ std::string OriginalSourceFile;
+
+
+ /// \brief The language options used when we load an AST file.
+ LangOptions ASTFileLangOpts;
+
+ ASTUnit(const ASTUnit &) LLVM_DELETED_FUNCTION;
+ void operator=(const ASTUnit &) LLVM_DELETED_FUNCTION;
+
+ explicit ASTUnit(bool MainFileIsAST);
+
+ void CleanTemporaryFiles();
+ bool Parse(llvm::MemoryBuffer *OverrideMainBuffer);
+
+ /// \brief Transfers ownership of the objects (like SourceManager) from
+ /// \param CI to this ASTUnit.
+ void transferASTDataFromCompilerInstance(CompilerInstance &CI);
+
+public:
+
+ ~ASTUnit();
+
+ const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; }
+ DiagnosticsEngine &getDiagnostics() { return *Diagnostics; }
+
+
+ const ASTContext &getASTContext() const { return *Ctx; }
+ ASTContext &getASTContext() { return *Ctx; }
+
+ void setASTContext(ASTContext *ctx) { Ctx = ctx; }
+
+ bool hasSema() const { return TheSema.get() != nullptr; }
+ Sema &getSema() const {
+ assert(TheSema && "ASTUnit does not have a Sema object!");
+ return *TheSema;
+ }
+
+ StringRef getOriginalSourceFileName() {
+ return OriginalSourceFile;
+ }
+
+
+ /// \brief Get the source location for the given file:line:col triplet.
+ ///
+ /// The difference with SourceManager::getLocation is that this method checks
+ /// whether the requested location points inside the precompiled preamble
+ /// in which case the returned source location will be a "loaded" one.
+ SourceLocation getLocation(const FileEntry *File,
+ unsigned Line, unsigned Col) const;
+
+ /// \brief Get the source location for the given file:offset pair.
+ SourceLocation getLocation(const FileEntry *File, unsigned Offset) const;
+
+
+ llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
+ std::string *ErrorStr = 0);
+
+ /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
+ static ASTUnit *create(CompilerInvocation *CI,
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags);
+
+public:
+
+ /// \brief Create an ASTUnit from a source file, via a CompilerInvocation
+ /// object, by invoking the optionally provided ASTFrontendAction.
+ ///
+ /// \param CI - The compiler invocation to use; it must have exactly one input
+ /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
+ ///
+ /// \param Diags - The diagnostics engine to use for reporting errors; its
+ /// lifetime is expected to extend past that of the returned ASTUnit.
+ ///
+ /// \param Action - The ASTFrontendAction to invoke. Its ownership is not
+ /// transfered.
+ ///
+ /// \param Unit - optionally an already created ASTUnit. Its ownership is not
+ /// transfered.
+ ///
+ /// \param Persistent - if true the returned ASTUnit will be complete.
+ /// false means the caller is only interested in getting info through the
+ /// provided \see Action.
+ ///
+ /// \param ErrAST - If non-null and parsing failed without any AST to return
+ /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
+ /// mainly to allow the caller to see the diagnostics.
+ /// This will only receive an ASTUnit if a new one was created. If an already
+ /// created ASTUnit was passed in \p Unit then the caller can check that.
+ ///
+ static ASTUnit *LoadFromCompilerInvocationAction(CompilerInvocation *CI,
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+ ASTFrontendAction *Action = 0,
+ ASTUnit *Unit = 0,
+ bool Persistent = true,
+ StringRef ResourceFilesPath = StringRef(),
+ bool OnlyLocalDecls = false,
+ bool CaptureDiagnostics = false,
+ bool PrecompilePreamble = false,
+ bool CacheCodeCompletionResults = false,
+ bool IncludeBriefCommentsInCodeCompletion = false,
+ bool UserFilesAreVolatile = false,
+ std::unique_ptr<ASTUnit> *ErrAST = 0);
+
+ /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
+ /// CompilerInvocation object.
+ ///
+ /// \param CI - The compiler invocation to use; it must have exactly one input
+ /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
+ ///
+ /// \param Diags - The diagnostics engine to use for reporting errors; its
+ /// lifetime is expected to extend past that of the returned ASTUnit.
+ //
+ // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
+ // shouldn't need to specify them at construction time.
+ static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI,
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags);
+
+
+};
+
+} // namespace clang
+
+#endif
diff --git a/include/flang/Frontend/CodeGenOptions.def b/include/flang/Frontend/CodeGenOptions.def
new file mode 100644
index 0000000000..80046620f6
--- /dev/null
+++ b/include/flang/Frontend/CodeGenOptions.def
@@ -0,0 +1,157 @@
+//===--- CodeGenOptions.def - Code generation option database ------ C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the code generation options. Users of this file
+// must define the CODEGENOPT macro to make use of this information.
+// Optionally, the user may also define ENUM_CODEGENOPT (for options
+// that have enumeration type and VALUE_CODEGENOPT is a code
+// generation option that describes a value rather than a flag.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CODEGENOPT
+# error Define the CODEGENOPT macro to handle language options
+#endif
+
+#ifndef VALUE_CODEGENOPT
+# define VALUE_CODEGENOPT(Name, Bits, Default) \
+CODEGENOPT(Name, Bits, Default)
+#endif
+
+#ifndef ENUM_CODEGENOPT
+# define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
+CODEGENOPT(Name, Bits, Default)
+#endif
+
+CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink
+CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
+CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
+CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files.
+CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files.
+CODEGENOPT(CUDAIsDevice , 1, 0) ///< Set when compiling for CUDA device.
+CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors.
+CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker
+ ///< aliases to base ctors when possible.
+CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled.
+CODEGENOPT(DisableFPElim , 1, 0) ///< Set when -fomit-frame-pointer is enabled.
+CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory.
+CODEGENOPT(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing.
+CODEGENOPT(DisableLLVMOpts , 1, 0) ///< Don't run any optimizations, for use in
+ ///< getting .bc files that correspond to the
+ ///< internal state before optimizations are
+ ///< done.
+CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
+CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls.
+CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what
+ ///< Decl* various IR entities came from.
+ ///< Only useful when running CodeGen as a
+ ///< subroutine.
+CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA.
+CODEGENOPT(EmitGcovNotes , 1, 0) ///< Emit coverage "notes" files, aka GCNO.
+CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata.
+/// \brief FP_CONTRACT mode (on/off/fast).
+ENUM_CODEGENOPT(FPContractMode, FPContractModeKind, 2, FPC_On)
+CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
+ ///< are required.
+CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled.
+CODEGENOPT(HiddenWeakVTables , 1, 0) ///< Emit weak vtables, RTTI, and thunks with
+ ///< hidden visibility.
+CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
+ ///< enabled.
+CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
+CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to
+ ///< be generated.
+CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
+CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled.
+CODEGENOPT(NoDwarf2CFIAsm , 1, 0) ///< Set when -fno-dwarf2-cfi-asm is enabled.
+CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is
+ ///< enabled.
+CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled.
+CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
+CODEGENOPT(NoGlobalMerge , 1, 0) ///< Set when -mno-global-merge is enabled.
+CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled.
+CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf.
+CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled.
+ ///< Disables use of the inline keyword.
+CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN.
+CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
+/// \brief Method of Objective-C dispatch to use.
+ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
+CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is
+ ///< enabled.
+VALUE_CODEGENOPT(OptimizationLevel, 3, 0) ///< The -O[0-4] option specified.
+VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
+
+ /// If -fpcc-struct-return or -freg-struct-return is specified.
+ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default)
+
+CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions.
+CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled.
+CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA.
+CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
+CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
+ ///< offset in AddressSanitizer.
+CODEGENOPT(SanitizeMemoryTrackOrigins, 1, 0) ///< Enable tracking origins in
+ ///< MemorySanitizer
+CODEGENOPT(SanitizeUndefinedTrapOnError, 1, 0) ///< Set on
+ /// -fsanitize-undefined-trap-on-error
+CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
+CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float.
+CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition.
+CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled.
+CODEGENOPT(UnitAtATime , 1, 1) ///< Unused. For mirroring GCC optimization
+ ///< selection.
+CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled.
+CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns.
+CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables.
+CODEGENOPT(VectorizeBB , 1, 0) ///< Run basic block vectorizer.
+CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer.
+CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer.
+
+ /// Attempt to use register sized accesses to bit-fields in structures, when
+ /// possible.
+CODEGENOPT(UseRegisterSizedBitfieldAccess , 1, 0)
+
+CODEGENOPT(VerifyModule , 1, 1) ///< Control whether the module should be run
+ ///< through the LLVM Verifier.
+
+CODEGENOPT(StackRealignment , 1, 0) ///< Control whether to permit stack
+ ///< realignment.
+CODEGENOPT(UseInitArray , 1, 0) ///< Control whether to use .init_array or
+ ///< .ctors.
+VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack
+ ///< alignment, if not 0.
+CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information
+ ///< in debug info.
+
+/// The user specified number of registers to be used for integral arguments,
+/// or 0 if unspecified.
+VALUE_CODEGENOPT(NumRegisterParameters, 32, 0)
+
+/// The lower bound for a buffer to be considered for stack protection.
+VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
+
+/// The kind of generated debug info.
+ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 2, NoDebugInfo)
+
+/// Dwarf version.
+VALUE_CODEGENOPT(DwarfVersion, 3, 0)
+
+/// The kind of inlining to perform.
+ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining)
+
+/// The default TLS model to use.
+ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
+
+CODEGENOPT(SanitizeRecover, 1, 1) ///< Attempt to recover from sanitizer checks
+ ///< by continuing execution when possible
+
+#undef CODEGENOPT
+#undef ENUM_CODEGENOPT
+#undef VALUE_CODEGENOPT
+
diff --git a/include/flang/Frontend/CodeGenOptions.h b/include/flang/Frontend/CodeGenOptions.h
new file mode 100644
index 0000000000..6aae15b4c8
--- /dev/null
+++ b/include/flang/Frontend/CodeGenOptions.h
@@ -0,0 +1,153 @@
+//===--- CodeGenOptions.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the CodeGenOptions interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_FRONTEND_CODEGENOPTIONS_H
+#define LLVM_FLANG_FRONTEND_CODEGENOPTIONS_H
+
+#include <string>
+#include <vector>
+#include <string.h>
+
+namespace flang {
+
+/// \brief Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure
+/// that this large collection of bitfields is a trivial class type.
+class CodeGenOptionsBase {
+public:
+#define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits;
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default)
+#include "flang/Frontend/CodeGenOptions.def"
+
+protected:
+#define CODEGENOPT(Name, Bits, Default)
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default) unsigned Name : Bits;
+#include "flang/Frontend/CodeGenOptions.def"
+};
+
+/// CodeGenOptions - Track various options which control how the code
+/// is optimized and passed to the backend.
+class CodeGenOptions : public CodeGenOptionsBase {
+public:
+ enum InliningMethod {
+ NoInlining, // Perform no inlining whatsoever.
+ NormalInlining, // Use the standard function inlining pass.
+ OnlyAlwaysInlining // Only run the always inlining pass.
+ };
+
+ enum ObjCDispatchMethodKind {
+ Legacy = 0,
+ NonLegacy = 1,
+ Mixed = 2
+ };
+
+ enum DebugInfoKind {
+ NoDebugInfo, // Don't generate debug info.
+ DebugLineTablesOnly, // Emit only debug info necessary for generating
+ // line number tables (-gline-tables-only).
+ LimitedDebugInfo, // Limit generated debug info to reduce size
+ // (-flimit-debug-info).
+ FullDebugInfo // Generate complete debug info.
+ };
+
+ enum TLSModel {
+ GeneralDynamicTLSModel,
+ LocalDynamicTLSModel,
+ InitialExecTLSModel,
+ LocalExecTLSModel
+ };
+
+ enum FPContractModeKind {
+ FPC_Off, // Form fused FP ops only where result will not be affected.
+ FPC_On, // Form fused FP ops according to FP_CONTRACT rules.
+ FPC_Fast // Aggressively fuse FP ops (E.g. FMA).
+ };
+
+ enum StructReturnConventionKind {
+ SRCK_Default, // No special option was passed.
+ SRCK_OnStack, // Small structs on the stack (-fpcc-struct-return).
+ SRCK_InRegs // Small structs in registers (-freg-struct-return).
+ };
+
+ /// The code model to use (-mcmodel).
+ std::string CodeModel;
+
+ /// The filename with path we use for coverage files. The extension will be
+ /// replaced.
+ std::string CoverageFile;
+
+ /// The version string to put into coverage files.
+ char CoverageVersion[4];
+
+ /// Enable additional debugging information.
+ std::string DebugPass;
+
+ /// The string to embed in debug information as the current working directory.
+ std::string DebugCompilationDir;
+
+ /// The string to embed in the debug information for the compile unit, if
+ /// non-empty.
+ std::string DwarfDebugFlags;
+
+ /// The ABI to use for passing floating point arguments.
+ std::string FloatABI;
+
+ /// The float precision limit to use, if non-empty.
+ std::string LimitFloatPrecision;
+
+ /// The name of the bitcode file to link before optzns.
+ std::string LinkBitcodeFile;
+
+ /// The user provided name for the "main file", if non-empty. This is useful
+ /// in situations where the input file name does not match the original input
+ /// file, for example with -save-temps.
+ std::string MainFileName;
+
+ /// The name for the split debug info file that we'll break out. This is used
+ /// in the backend for setting the name in the skeleton cu.
+ std::string SplitDwarfFile;
+
+ /// The name of the relocation model to use.
+ std::string RelocationModel;
+
+ /// Path to blacklist file for sanitizers.
+ std::string SanitizerBlacklistFile;
+
+ /// If not an empty string, trap intrinsics are lowered to calls to this
+ /// function instead of to trap instructions.
+ std::string TrapFuncName;
+
+ /// A list of command-line options to forward to the LLVM backend.
+ std::vector<std::string> BackendOptions;
+
+public:
+ // Define accessors/mutators for code generation options of enumeration type.
+#define CODEGENOPT(Name, Bits, Default)
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
+ Type get##Name() const { return static_cast<Type>(Name); } \
+ void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
+#include "flang/Frontend/CodeGenOptions.def"
+
+ CodeGenOptions() {
+#define CODEGENOPT(Name, Bits, Default) Name = Default;
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
+ set##Name(Default);
+#include "flang/Frontend/CodeGenOptions.def"
+
+ RelocationModel = "pic";
+ memcpy(CoverageVersion, "402*", 4);
+ }
+};
+
+} // end namespace flang
+
+#endif
diff --git a/include/flang/Frontend/CommandLineSourceLoc.h b/include/flang/Frontend/CommandLineSourceLoc.h
new file mode 100644
index 0000000000..8dfc50b8b7
--- /dev/null
+++ b/include/flang/Frontend/CommandLineSourceLoc.h
@@ -0,0 +1,87 @@
+
+//===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Command line parsing for source locations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_FRONTEND_COMMANDLINESOURCELOC_H
+#define LLVM_FLANG_FRONTEND_COMMANDLINESOURCELOC_H
+
+#include "flang/Basic/LLVM.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace flang {
+
+/// \brief A source location that has been parsed on the command line.
+struct ParsedSourceLocation {
+ std::string FileName;
+ unsigned Line;
+ unsigned Column;
+
+public:
+ /// Construct a parsed source location from a string; the Filename is empty on
+ /// error.
+ static ParsedSourceLocation FromString(StringRef Str) {
+ ParsedSourceLocation PSL;
+ std::pair<StringRef, StringRef> ColSplit = Str.rsplit(':');
+ std::pair<StringRef, StringRef> LineSplit =
+ ColSplit.first.rsplit(':');
+
+ // If both tail splits were valid integers, return success.
+ if (!ColSplit.second.getAsInteger(10, PSL.Column) &&
+ !LineSplit.second.getAsInteger(10, PSL.Line)) {
+ PSL.FileName = LineSplit.first;
+
+ // On the command-line, stdin may be specified via "-". Inside the
+ // compiler, stdin is called "<stdin>".
+ if (PSL.FileName == "-")
+ PSL.FileName = "<stdin>";
+ }
+
+ return PSL;
+ }
+};
+
+}
+
+namespace llvm {
+ namespace cl {
+ /// \brief Command-line option parser that parses source locations.
+ ///
+ /// Source locations are of the form filename:line:column.
+ template<>
+ class parser<flang::ParsedSourceLocation>
+ : public basic_parser<flang::ParsedSourceLocation> {
+ public:
+ inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
+ flang::ParsedSourceLocation &Val);
+ };
+
+ bool
+ parser<flang::ParsedSourceLocation>::
+ parse(Option &O, StringRef ArgName, StringRef ArgValue,
+ flang::ParsedSourceLocation &Val) {
+ using namespace flang;
+
+ Val = ParsedSourceLocation::FromString(ArgValue);
+ if (Val.FileName.empty()) {
+ errs() << "error: "
+ << "source location must be of the form filename:line:column\n";
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
+
+#endif
diff --git a/include/flang/Frontend/CompilerInstance.h b/include/flang/Frontend/CompilerInstance.h
new file mode 100644
index 0000000000..948e8b336e
--- /dev/null
+++ b/include/flang/Frontend/CompilerInstance.h
@@ -0,0 +1,528 @@
+//===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_FRONTEND_COMPILERINSTANCE_H_
+#define LLVM_FLANG_FRONTEND_COMPILERINSTANCE_H_
+
+#include "flang/Basic/Diagnostic.h"
+#include "flang/Frontend/CompilerInvocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SourceMgr.h"
+#include <cassert>
+#include <list>
+#include <string>
+#include <utility>
+
+namespace llvm {
+class raw_fd_ostream;
+class Timer;
+}
+
+namespace flang {
+class ASTContext;
+class ASTConsumer;
+class ASTReader;
+class CodeCompleteConsumer;
+class DiagnosticsEngine;
+class DiagnosticClient;
+class ExternalASTSource;
+class FileEntry;
+class FrontendAction;
+class Module;
+class Preprocessor;
+class Sema;
+class TargetInfo;
+
+/// CompilerInstance - Helper class for managing a single instance of the Clang
+/// compiler.
+///
+/// The CompilerInstance serves two purposes:
+/// (1) It manages the various objects which are necessary to run the compiler,
+/// for example the preprocessor, the target information, and the AST
+/// context.
+/// (2) It provides utility routines for constructing and manipulating the
+/// common Clang objects.
+///
+/// The compiler instance generally owns the instance of all the objects that it
+/// manages. However, clients can still share objects by manually setting the
+/// object and retaking ownership prior to destroying the CompilerInstance.
+///
+/// The compiler instance is intended to simplify clients, but not to lock them
+/// in to the compiler instance for everything. When possible, utility functions
+/// come in two forms; a short form that reuses the CompilerInstance objects,
+/// and a long form that takes explicit instances of any required objects.
+class CompilerInstance {
+ /// The options used in this compiler instance.
+ llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation;
+
+ /// The diagnostics engine instance.
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
+
+ /// The target being compiled for.
+ llvm::IntrusiveRefCntPtr<TargetInfo> Target;
+
+ /// The source manager.
+ llvm::IntrusiveRefCntPtr<llvm::SourceMgr> SourceMgr;
+
+ /// The preprocessor.
+ llvm::IntrusiveRefCntPtr<Preprocessor> PP;
+
+ /// The AST context.
+ llvm::IntrusiveRefCntPtr<ASTContext> Context;
+
+ /// The AST consumer.
+ std::unique_ptr<ASTConsumer> Consumer;
+
+ /// The code completion consumer.
+ std::unique_ptr<CodeCompleteConsumer> CompletionConsumer;
+
+ /// \brief The semantic analysis object.
+ std::unique_ptr<Sema> TheSema;
+
+ /// \brief The frontend timer
+ std::unique_ptr<llvm::Timer> FrontendTimer;
+
+ /// \brief Non-owning reference to the ASTReader, if one exists.
+ ASTReader *ModuleManager;
+
+ /// \brief The set of top-level modules that has already been loaded,
+ /// along with the module map
+ llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
+
+ /// \brief The location of the module-import keyword for the last module
+ /// import.
+ SourceLocation LastModuleImportLoc;
+
+ /// \brief Whether we should (re)build the global module index once we
+ /// have finished with this translation unit.
+ bool BuildGlobalModuleIndex;
+
+ /// \brief One or more modules failed to build.
+ bool ModuleBuildFailed;
+
+ /// \brief Holds information about the output file.
+ ///
+ /// If TempFilename is not empty we must rename it to Filename at the end.
+ /// TempFilename may be empty and Filename non empty if creating the temporary
+ /// failed.
+ struct OutputFile {
+ std::string Filename;
+ std::string TempFilename;
+ raw_ostream *OS;
+
+ OutputFile(const std::string &filename, const std::string &tempFilename,
+ raw_ostream *os)
+ : Filename(filename), TempFilename(tempFilename), OS(os) { }
+ };
+
+ /// The list of active output files.
+ std::list<OutputFile> OutputFiles;
+
+ CompilerInstance(const CompilerInstance &) LLVM_DELETED_FUNCTION;
+ void operator=(const CompilerInstance &) LLVM_DELETED_FUNCTION;
+public:
+ CompilerInstance();
+ ~CompilerInstance();
+
+ /// @name High-Level Operations
+ /// {
+
+ /// ExecuteAction - Execute the provided action against the compiler's
+ /// CompilerInvocation object.
+ ///
+ /// This function makes the following assumptions:
+ ///
+ /// - The invocation options should be initialized. This function does not
+ /// handle the '-help' or '-version' options, clients should handle those
+ /// directly.
+ ///
+ /// - The diagnostics engine should have already been created by the client.
+ ///
+ /// - No other CompilerInstance state should have been initialized (this is
+ /// an unchecked error).
+ ///
+ /// - Clients should have initialized any LLVM target features that may be
+ /// required.
+ ///
+ /// - Clients should eventually call llvm_shutdown() upon the completion of
+ /// this routine to ensure that any managed objects are properly destroyed.
+ ///
+ /// Note that this routine may write output to 'stderr'.
+ ///
+ /// \param Act - The action to execute.
+ /// \return - True on success.
+ //
+ // FIXME: This function should take the stream to write any debugging /
+ // verbose output to as an argument.
+ //
+ // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
+ // of the context or else not CompilerInstance specific.
+ bool ExecuteAction(FrontendAction &Act);
+
+ /// }
+ /// @name Compiler Invocation and Options
+ /// {
+
+ bool hasInvocation() const { return Invocation != 0; }
+
+ CompilerInvocation &getInvocation() {
+ assert(Invocation && "Compiler instance has no invocation!");
+ return *Invocation;
+ }
+
+ /// setInvocation - Replace the current invocation.
+ void setInvocation(CompilerInvocation *Value);
+
+ /// \brief Indicates whether we should (re)build the global module index.
+ bool shouldBuildGlobalModuleIndex() const;
+
+ /// \brief Set the flag indicating whether we should (re)build the global
+ /// module index.
+ void setBuildGlobalModuleIndex(bool Build) {
+ BuildGlobalModuleIndex = Build;
+ }
+
+ /// }
+ /// @name Forwarding Methods
+ /// {
+
+ CodeGenOptions &getCodeGenOpts() {
+ return Invocation->getCodeGenOpts();
+ }
+ const CodeGenOptions &getCodeGenOpts() const {
+ return Invocation->getCodeGenOpts();
+ }
+
+ FrontendOptions &getFrontendOpts() {
+ return Invocation->getFrontendOpts();
+ }
+ const FrontendOptions &getFrontendOpts() const {
+ return Invocation->getFrontendOpts();
+ }
+
+ LangOptions &getLangOpts() {
+ return *Invocation->getLangOpts();
+ }
+ const LangOptions &getLangOpts() const {
+ return *Invocation->getLangOpts();
+ }
+
+ TargetOptions &getTargetOpts() {
+ return Invocation->getTargetOpts();
+ }
+ const TargetOptions &getTargetOpts() const {
+ return Invocation->getTargetOpts();
+ }
+
+ /// }
+ /// @name Diagnostics Engine
+ /// {
+
+ bool hasDiagnostics() const { return Diagnostics != 0; }
+
+ /// Get the current diagnostics engine.
+ DiagnosticsEngine &getDiagnostics() const {
+ assert(Diagnostics && "Compiler instance has no diagnostics!");
+ return *Diagnostics;
+ }
+
+ /// setDiagnostics - Replace the current diagnostics engine.
+ void setDiagnostics(DiagnosticsEngine *Value);
+
+ DiagnosticClient &getDiagnosticConsumer() const {
+ assert(Diagnostics && Diagnostics->getClient() &&
+ "Compiler instance has no diagnostic client!");
+ return *Diagnostics->getClient();
+ }
+
+ /// }
+ /// @name Target Info
+ /// {
+
+ bool hasTarget() const { return Target != 0; }
+
+ TargetInfo &getTarget() const {
+ assert(Target && "Compiler instance has no target!");
+ return *Target;
+ }
+
+ /// Replace the current diagnostics engine.
+ void setTarget(TargetInfo *Value);
+
+ /// }
+ /// @name Source Manager
+ /// {
+
+ bool hasSourceManager() const { return SourceMgr != 0; }
+
+ /// Return the current source manager.
+ llvm::SourceMgr &getSourceManager() const {
+ assert(SourceMgr && "Compiler instance has no source manager!");
+ return *SourceMgr;
+ }
+
+ void resetAndLeakSourceManager() {
+ SourceMgr.resetWithoutRelease();
+ }
+
+ /// setSourceManager - Replace the current source manager.
+ void setSourceManager(llvm::SourceMgr *Value);
+
+ /// }
+ /// @name Preprocessor
+ /// {
+
+ bool hasPreprocessor() const { return PP != 0; }
+
+ /// Return the current preprocessor.
+ Preprocessor &getPreprocessor() const {
+ assert(PP && "Compiler instance has no preprocessor!");
+ return *PP;
+ }
+
+ void resetAndLeakPreprocessor() {
+ PP.resetWithoutRelease();
+ }
+
+ /// Replace the current preprocessor.
+ void setPreprocessor(Preprocessor *Value);
+
+ /// }
+ /// @name ASTContext
+ /// {
+
+ bool hasASTContext() const { return Context != 0; }
+
+ ASTContext &getASTContext() const {
+ assert(Context && "Compiler instance has no AST context!");
+ return *Context;
+ }
+
+ void resetAndLeakASTContext() {
+ Context.resetWithoutRelease();
+ }
+
+ /// setASTContext - Replace the current AST context.
+ void setASTContext(ASTContext *Value);
+
+ /// \brief Replace the current Sema; the compiler instance takes ownership
+ /// of S.
+ void setSema(Sema *S);
+
+ /// }
+ /// @name ASTConsumer
+ /// {
+
+ bool hasASTConsumer() const { return Consumer.get() != nullptr; }
+
+ ASTConsumer &getASTConsumer() const {
+ assert(Consumer && "Compiler instance has no AST consumer!");
+ return *Consumer;
+ }
+
+ /// takeASTConsumer - Remove the current AST consumer and give ownership to
+ /// the caller.
+ ASTConsumer *takeASTConsumer() { return Consumer.release(); }
+
+ /// setASTConsumer - Replace the current AST consumer; the compiler instance
+ /// takes ownership of \p Value.
+ void setASTConsumer(ASTConsumer *Value);
+
+ /// }
+ /// @name Semantic analysis
+ /// {
+ bool hasSema() const { return TheSema.get() != nullptr; }
+
+ Sema &getSema() const {
+ assert(TheSema && "Compiler instance has no Sema object!");
+ return *TheSema;
+ }
+
+ Sema *takeSema() { return TheSema.release(); }
+
+ /// }
+ /// @name Module Management
+ /// {
+
+ ASTReader *getModuleManager() const { return ModuleManager; }
+ void setModuleManager(ASTReader *Reader) { ModuleManager = Reader; }
+
+ /// }
+ /// @name Frontend timer
+ /// {
+
+ bool hasFrontendTimer() const { return FrontendTimer.get() != nullptr; }
+
+ llvm::Timer &getFrontendTimer() const {
+ assert(FrontendTimer && "Compiler instance has no frontend timer!");
+ return *FrontendTimer;
+ }
+
+ /// }
+ /// @name Output Files
+ /// {
+
+ /// addOutputFile - Add an output file onto the list of tracked output files.
+ ///
+ /// \param OutFile - The output file info.
+ void addOutputFile(const OutputFile &OutFile);
+
+ /// clearOutputFiles - Clear the output file list, destroying the contained
+ /// output streams.
+ ///
+ /// \param EraseFiles - If true, attempt to erase the files from disk.
+ void clearOutputFiles(bool EraseFiles);
+
+ /// }
+ /// @name Construction Utility Methods
+ /// {
+
+ /// Create the diagnostics engine using the invocation's diagnostic options
+ /// and replace any existing one with it.
+ ///
+ /// Note that this routine also replaces the diagnostic client,
+ /// allocating one if one is not provided.
+ ///
+ /// \param Client If non-NULL, a diagnostic client that will be
+ /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST
+ /// unit.
+ ///
+ /// \param ShouldOwnClient If Client is non-NULL, specifies whether
+ /// the diagnostic object should take ownership of the client.
+ void createDiagnostics(DiagnosticClient *Client = 0,
+ bool ShouldOwnClient = true);
+
+ /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
+ ///
+ /// If no diagnostic client is provided, this creates a
+ /// DiagnosticConsumer that is owned by the returned diagnostic
+ /// object, if using directly the caller is responsible for
+ /// releasing the returned DiagnosticsEngine's client eventually.
+ ///
+ /// \param Opts - The diagnostic options; note that the created text
+ /// diagnostic object contains a reference to these options.
+ ///
+ /// \param Client If non-NULL, a diagnostic client that will be
+ /// attached to (and, then, owned by) the returned DiagnosticsEngine
+ /// object.
+ ///
+ /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be
+ /// used by some diagnostics printers (for logging purposes only).
+ ///
+ /// \return The new object on success, or null on failure.
+ static llvm::IntrusiveRefCntPtr<DiagnosticsEngine>
+ createDiagnostics(DiagnosticOptions *Opts,
+ DiagnosticClient *Client = 0,
+ bool ShouldOwnClient = true,
+ const CodeGenOptions *CodeGenOpts = 0);
+
+ /// Create the source manager and replace any existing one with it.
+ void createSourceManager();
+
+ /// Create the preprocessor, using the invocation, file, and source managers,
+ /// and replace any existing one with it.
+ void createPreprocessor();
+
+ /// Create the AST context.
+ void createASTContext();
+
+ /// \brief Create the Sema object to be used for parsing.
+ void createSema();
+
+ /// Create the frontend timer and replace any existing one with it.
+ void createFrontendTimer();
+
+ /// Create the default output file (from the invocation's options) and add it
+ /// to the list of tracked output files.
+ ///
+ /// The files created by this function always use temporary files to write to
+ /// their result (that is, the data is written to a temporary file which will
+ /// atomically replace the target output on success).
+ ///
+ /// \return - Null on error.
+ llvm::raw_fd_ostream *
+ createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "",
+ StringRef Extension = "");
+
+ /// Create a new output file and add it to the list of tracked output files,
+ /// optionally deriving the output path name.
+ ///
+ /// \return - Null on error.
+ llvm::raw_fd_ostream *
+ createOutputFile(StringRef OutputPath,
+ bool Binary, bool RemoveFileOnSignal,
+ StringRef BaseInput,
+ StringRef Extension,
+ bool UseTemporary,
+ bool CreateMissingDirectories = false);
+
+ /// Create a new output file, optionally deriving the output path name.
+ ///
+ /// If \p OutputPath is empty, then createOutputFile will derive an output
+ /// path location as \p BaseInput, with any suffix removed, and \p Extension
+ /// appended. If \p OutputPath is not stdout and \p UseTemporary
+ /// is true, createOutputFile will create a new temporary file that must be
+ /// renamed to \p OutputPath in the end.
+ ///
+ /// \param OutputPath - If given, the path to the output file.
+ /// \param Error [out] - On failure, the error message.
+ /// \param BaseInput - If \p OutputPath is empty, the input path name to use
+ /// for deriving the output path.
+ /// \param Extension - The extension to use for derived output names.
+ /// \param Binary - The mode to open the file in.
+ /// \param RemoveFileOnSignal - Whether the file should be registered with
+ /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
+ /// multithreaded use, as the underlying signal mechanism is not reentrant
+ /// \param UseTemporary - Create a new temporary file that must be renamed to
+ /// OutputPath in the end.
+ /// \param CreateMissingDirectories - When \p UseTemporary is true, create
+ /// missing directories in the output path.
+ /// \param ResultPathName [out] - If given, the result path name will be
+ /// stored here on success.
+ /// \param TempPathName [out] - If given, the temporary file path name
+ /// will be stored here on success.
+ static llvm::raw_fd_ostream *
+ createOutputFile(StringRef OutputPath, std::string &Error,
+ bool Binary, bool RemoveFileOnSignal,
+ StringRef BaseInput,
+ StringRef Extension,
+ bool UseTemporary,
+ bool CreateMissingDirectories,
+ std::string *ResultPathName,
+ std::string *TempPathName);
+
+ /// }
+ /// @name Initialization Utility Methods
+ /// {
+
+ /// InitializeSourceManager - Initialize the source manager to set InputFile
+ /// as the main file.
+ ///
+ /// \return True on success.
+ bool InitializeSourceManager(const FrontendInputFile &Input);
+
+ /// InitializeSourceManager - Initialize the source manager to set InputFile
+ /// as the main file.
+ ///
+ /// \return True on success.
+ static bool InitializeSourceManager(const FrontendInputFile &Input,
+ DiagnosticsEngine &Diags,
+ llvm::SourceMgr &SrcMgr,
+ const FrontendOptions &Opts);
+
+ /// }
+
+};
+
+} // end namespace flang
+
+#endif
diff --git a/include/flang/Frontend/CompilerInvocation.h b/include/flang/Frontend/CompilerInvocation.h
new file mode 100644
index 0000000000..56a028da36
--- /dev/null
+++ b/include/flang/Frontend/CompilerInvocation.h
@@ -0,0 +1,131 @@
+//===-- CompilerInvocation.h - Compiler Invocation Helper Data --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H_
+#define LLVM_FLANG_FRONTEND_COMPILERINVOCATION_H_
+
+#include "flang/Basic/LangOptions.h"
+#include "flang/Basic/TargetOptions.h"
+#include "flang/Frontend/CodeGenOptions.h"
+#include "flang/Frontend/FrontendOptions.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace opt {
+class ArgList;
+}
+}
+
+namespace flang {
+class CompilerInvocation;
+class DiagnosticsEngine;
+struct DiagnosticOptions {};
+
+/// \brief Fill out Opts based on the options given in Args.
+///
+/// Args must have been created from the OptTable returned by
+/// createCC1OptTable().
+///
+/// When errors are encountered, return false and, if Diags is non-null,
+/// report the error(s).
+bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
+ DiagnosticsEngine *Diags = 0);
+
+class CompilerInvocationBase : public llvm::RefCountedBase<CompilerInvocation> {
+protected:
+ /// Options controlling the language variant.
+ llvm::IntrusiveRefCntPtr<LangOptions> LangOpts;
+
+ /// Options controlling the target.
+ llvm::IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+
+public:
+ CompilerInvocationBase();
+
+ CompilerInvocationBase(const CompilerInvocationBase &X);
+
+ LangOptions *getLangOpts() { return LangOpts.get(); }
+ const LangOptions *getLangOpts() const { return LangOpts.get(); }
+
+ TargetOptions &getTargetOpts() { return *TargetOpts.get(); }
+ const TargetOptions &getTargetOpts() const {
+ return *TargetOpts.get();
+ }
+
+};
+
+/// \brief Helper class for holding the data necessary to invoke the compiler.
+///
+/// This class is designed to represent an abstract "invocation" of the
+/// compiler, including data such as the include paths, the code generation
+/// options, the warning flags, and so on.
+class CompilerInvocation : public CompilerInvocationBase {
+
+ /// Options controlling IRgen and the backend.
+ CodeGenOptions CodeGenOpts;
+
+ /// Options controlling the frontend itself.
+ FrontendOptions FrontendOpts;
+
+public:
+ CompilerInvocation() {}
+
+ /// @name Utility Methods
+ /// @{
+
+ /// \brief Create a compiler invocation from a list of input options.
+ /// \returns true on success.
+ ///
+ /// \param [out] Res - The resulting invocation.
+ /// \param ArgBegin - The first element in the argument vector.
+ /// \param ArgEnd - The last element in the argument vector.
+ /// \param Diags - The diagnostic engine to use for errors.
+ static bool CreateFromArgs(CompilerInvocation &Res,
+ const char* const *ArgBegin,
+ const char* const *ArgEnd,
+ DiagnosticsEngine &Diags);
+
+ /// \brief Get the directory where the compiler headers
+ /// reside, relative to the compiler binary (found by the passed in
+ /// arguments).
+ ///
+ /// \param Argv0 - The program path (from argv[0]), for finding the builtin
+ /// compiler path.
+ /// \param MainAddr - The address of main (or some other function in the main
+ /// executable), for finding the builtin compiler path.
+ static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
+
+ /// \brief Retrieve a module hash string that is suitable for uniquely
+ /// identifying the conditions under which the module was built.
+ std::string getModuleHash() const;
+
+ /// @}
+ /// @name Option Subgroups
+ /// @{
+
+ CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
+ const CodeGenOptions &getCodeGenOpts() const {
+ return CodeGenOpts;
+ }
+
+ FrontendOptions &getFrontendOpts() { return FrontendOpts; }
+ const FrontendOptions &getFrontendOpts() const {
+ return FrontendOpts;
+ }
+
+ /// @}
+};
+
+} // end namespace flang
+
+#endif
diff --git a/include/flang/Frontend/FrontendAction.h b/include/flang/Frontend/FrontendAction.h
new file mode 100644
index 0000000000..da23e6ddcf
--- /dev/null
+++ b/include/flang/Frontend/FrontendAction.h
@@ -0,0 +1,191 @@
+//===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the flang::FrontendAction interface and various convenience
+/// abstract classes (flang::ASTFrontendAction, flang::PluginASTAction,
+/// flang::PreprocessorFrontendAction, and flang::WrapperFrontendAction)
+/// derived from it.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_FRONTEND_FRONTENDACTION_H
+#define LLVM_FLANG_FRONTEND_FRONTENDACTION_H
+
+#include "flang/Basic/LLVM.h"
+#include "flang/Basic/LangOptions.h"
+#include "flang/Frontend/ASTUnit.h"
+#include "flang/Frontend/FrontendOptions.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace flang {
+class ASTConsumer;
+class CompilerInstance;
+
+/// Abstract base class for actions which can be performed by the frontend.
+class FrontendAction {
+ std::unique_ptr<ASTUnit> CurrentASTUnit;
+ CompilerInstance *Instance;
+
+private:
+ ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
+ StringRef InFile);
+
+protected:
+ /// @name Implementation Action Interface
+ /// @{
+
+ /// \brief Create the AST consumer object for this action, if supported.
+ ///
+ /// This routine is called as part of BeginSourceFile(), which will
+ /// fail if the AST consumer cannot be created. This will not be called if the
+ /// action has indicated that it only uses the preprocessor.
+ ///
+ /// \param CI - The current compiler instance, provided as a convenience, see
+ /// getCompilerInstance().
+ ///
+ /// \param InFile - The current input file, provided as a convenience, see
+ /// getCurrentFile().
+ ///
+ /// \return The new AST consumer, or null on failure.
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) = 0;
+
+ /// \brief Callback before starting processing a single input, giving the
+ /// opportunity to modify the CompilerInvocation or do some other action
+ /// before BeginSourceFileAction is called.
+ ///
+ /// \return True on success; on failure BeginSourceFileAction(),
+ /// ExecuteAction() and EndSourceFileAction() will not be called.
+ virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
+
+ /// \brief Callback at the start of processing a single input.
+ ///
+ /// \return True on success; on failure ExecutionAction() and
+ /// EndSourceFileAction() will not be called.
+ virtual bool BeginSourceFileAction(CompilerInstance &CI,
+ StringRef Filename) {
+ return true;
+ }
+
+ /// \brief Callback to run the program action, using the initialized
+ /// compiler instance.
+ ///
+ /// This is guaranteed to only be called between BeginSourceFileAction()
+ /// and EndSourceFileAction().
+ virtual void ExecuteAction() = 0;
+
+ /// \brief Callback at the end of processing a single input.
+ ///
+ /// This is guaranteed to only be called following a successful call to
+ /// BeginSourceFileAction (and BeginSourceFile).
+ virtual void EndSourceFileAction() {}
+
+ /// \brief Callback at the end of processing a single input, to determine
+ /// if the output files should be erased or not.
+ ///
+ /// By default it returns true if a compiler error occurred.
+ /// This is guaranteed to only be called following a successful call to
+ /// BeginSourceFileAction (and BeginSourceFile).
+ virtual bool shouldEraseOutputFiles();
+
+ /// @}
+
+public:
+ FrontendAction();
+ virtual ~FrontendAction();
+
+ /// @name Compiler Instance Access
+ /// @{
+
+ CompilerInstance &getCompilerInstance() const {
+ assert(Instance && "Compiler instance not registered!");
+ return *Instance;
+ }
+
+ void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
+
+ /// @}
+ /// @name Current File Information
+ /// @{
+
+ bool isCurrentFileAST() const {
+ assert(CurrentASTUnit && "No current AST unit!");
+ return CurrentASTUnit.get() != nullptr;
+ }
+
+ const StringRef getCurrentFile() const {
+ CurrentASTUnit.get()->getOriginalSourceFileName();
+ }
+
+ InputKind getCurrentFileKind() const {
+ return IK_None;
+ }
+
+ ASTUnit &getCurrentASTUnit() const {
+ assert(CurrentASTUnit && "No current AST unit!");
+ return *CurrentASTUnit;
+ }
+
+ ASTUnit *takeCurrentASTUnit() {
+ return CurrentASTUnit.release();
+ }
+
+ /// @}
+ /// @name Public Action Interface
+ /// @{
+
+ /// \brief Prepare the action for processing the input file \p Input.
+ ///
+ /// This is run after the options and frontend have been initialized,
+ /// but prior to executing any per-file processing.
+ ///
+ /// \param CI - The compiler instance this action is being run from. The
+ /// action may store and use this object up until the matching EndSourceFile
+ /// action.
+ ///
+ /// \param Input - The input filename and kind. Some input kinds are handled
+ /// specially, for example AST inputs, since the AST file itself contains
+ /// several objects which would normally be owned by the
+ /// CompilerInstance. When processing AST input files, these objects should
+ /// generally not be initialized in the CompilerInstance -- they will
+ /// automatically be shared with the AST file in between
+ /// BeginSourceFile() and EndSourceFile().
+ ///
+ /// \return True on success; on failure the compilation of this file should
+ /// be aborted and neither Execute() nor EndSourceFile() should be called.
+ bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
+
+ /// \brief Set the source manager's main input file, and run the action.
+ bool Execute();
+
+ /// \brief Perform any per-file post processing, deallocate per-file
+ /// objects, and run statistics and output file cleanup code.
+ void EndSourceFile();
+
+ /// @}
+};
+
+/// \brief Abstract base class to use for AST consumer-based frontend actions.
+class ASTFrontendAction : public FrontendAction {
+protected:
+ /// \brief Implement the ExecuteAction interface by running Sema on
+ /// the already-initialized AST consumer.
+ ///
+ /// This will also take care of instantiating a code completion consumer if
+ /// the user requested it and the action supports it.
+ virtual void ExecuteAction();
+
+};
+
+} // end namespace flang
+
+#endif
diff --git a/include/flang/Frontend/FrontendOptions.h b/include/flang/Frontend/FrontendOptions.h
new file mode 100644
index 0000000000..81e3d69b62
--- /dev/null
+++ b/include/flang/Frontend/FrontendOptions.h
@@ -0,0 +1,234 @@
+//===--- FrontendOptions.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H
+#define LLVM_FLANG_FRONTEND_FRONTENDOPTIONS_H
+
+#include "flang/Frontend/CommandLineSourceLoc.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+class MemoryBuffer;
+}
+
+namespace flang {
+
+namespace frontend {
+ enum ActionKind {
+ ASTDeclList, ///< Parse ASTs and list Decl nodes.
+ ASTDump, ///< Parse ASTs and dump them.
+ ASTDumpXML, ///< Parse ASTs and dump them in XML.
+ ASTPrint, ///< Parse ASTs and print them.
+ ASTView, ///< Parse ASTs and view them in Graphviz.
+ DumpRawTokens, ///< Dump out raw tokens.
+ DumpTokens, ///< Dump out preprocessed tokens.
+ EmitAssembly, ///< Emit a .s file.
+ EmitBC, ///< Emit a .bc file.
+ EmitHTML, ///< Translate input source into HTML.
+ EmitLLVM, ///< Emit a .ll file.
+ EmitLLVMOnly, ///< Generate LLVM IR, but do not emit anything.
+ EmitCodeGenOnly, ///< Generate machine code, but don't emit anything.
+ EmitObj, ///< Emit a .o file.
+ FixIt, ///< Parse and apply any fixits to the source.
+ GenerateModule, ///< Generate pre-compiled module.
+ GeneratePCH, ///< Generate pre-compiled header.
+ GeneratePTH, ///< Generate pre-tokenized header.
+ InitOnly, ///< Only execute frontend initialization.
+ ModuleFileInfo, ///< Dump information about a module file.
+ ParseSyntaxOnly, ///< Parse and perform semantic analysis.
+ PluginAction, ///< Run a plugin action, \see ActionName.
+ PrintDeclContext, ///< Print DeclContext and their Decls.
+ PrintPreamble, ///< Print the "preamble" of the input file
+ PrintPreprocessedInput, ///< -E mode.
+ RewriteMacros, ///< Expand macros but not \#includes.
+ RewriteObjC, ///< ObjC->C Rewriter.
+ RewriteTest, ///< Rewriter playground
+ RunAnalysis, ///< Run one or more source code analyses.
+ MigrateSource, ///< Run migrator.
+ RunPreprocessorOnly ///< Just lex, no output.
+ };
+}
+
+enum InputKind {
+ IK_None,
+ IK_Asm,
+ IK_C,
+ IK_CXX,
+ IK_ObjC,
+ IK_ObjCXX,
+ IK_PreprocessedC,
+ IK_PreprocessedCXX,
+ IK_PreprocessedObjC,
+ IK_PreprocessedObjCXX,
+ IK_OpenCL,
+ IK_CUDA,
+ IK_AST,
+ IK_LLVM_IR
+};
+
+
+/// \brief An input file for the front end.
+class FrontendInputFile {
+ /// \brief The file name, or "-" to read from standard input.
+ std::string File;
+
+ llvm::MemoryBuffer *Buffer;
+
+ /// \brief The kind of input, e.g., C source, AST file, LLVM IR.
+ InputKind Kind;
+
+ /// \brief Whether we're dealing with a 'system' input (vs. a 'user' input).
+ bool IsSystem;
+
+public:
+ FrontendInputFile() : Buffer(0), Kind(IK_None) { }
+ FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
+ : File(File.str()), Buffer(0), Kind(Kind), IsSystem(IsSystem) { }
+ FrontendInputFile(llvm::MemoryBuffer *buffer, InputKind Kind,
+ bool IsSystem = false)
+ : Buffer(buffer), Kind(Kind), IsSystem(IsSystem) { }
+
+ InputKind getKind() const { return Kind; }
+ bool isSystem() const { return IsSystem; }
+
+ bool isEmpty() const { return File.empty() && Buffer == 0; }
+ bool isFile() const { return !isBuffer(); }
+ bool isBuffer() const { return Buffer != 0; }
+
+ StringRef getFile() const {
+ assert(isFile());
+ return File;
+ }
+ llvm::MemoryBuffer *getBuffer() const {
+ assert(isBuffer());
+ return Buffer;
+ }
+};
+
+/// FrontendOptions - Options for controlling the behavior of the frontend.
+class FrontendOptions {
+public:
+ unsigned DisableFree : 1; ///< Disable memory freeing on exit.
+ unsigned RelocatablePCH : 1; ///< When generating PCH files,
+ /// instruct the AST writer to create
+ /// relocatable PCH files.
+ unsigned ShowHelp : 1; ///< Show the -help text.
+ unsigned ShowStats : 1; ///< Show frontend performance
+ /// metrics and statistics.
+ unsigned ShowTimers : 1; ///< Show timers for individual
+ /// actions.
+ unsigned ShowVersion : 1; ///< Show the -version text.
+ unsigned FixWhatYouCan : 1; ///< Apply fixes even if there are
+ /// unfixable errors.
+ unsigned FixOnlyWarnings : 1; ///< Apply fixes only for warnings.
+ unsigned FixAndRecompile : 1; ///< Apply fixes and recompile.
+ unsigned FixToTemporaries : 1; ///< Apply fixes to temporary files.
+ unsigned ARCMTMigrateEmitARCErrors : 1; /// Emit ARC errors even if the
+ /// migrator can fix them
+ unsigned SkipFunctionBodies : 1; ///< Skip over function bodies to
+ /// speed up parsing in cases you do
+ /// not need them (e.g. with code
+ /// completion).
+ unsigned UseGlobalModuleIndex : 1; ///< Whether we can use the
+ ///< global module index if available.
+ unsigned GenerateGlobalModuleIndex : 1; ///< Whether we can generate the
+ ///< global module index if needed.
+ unsigned ASTDumpLookups : 1; ///< Whether we include lookup table
+ ///< dumps in AST dumps.
+
+ enum {
+ ARCMT_None,
+ ARCMT_Check,
+ ARCMT_Modify,
+ ARCMT_Migrate
+ } ARCMTAction;
+
+ enum {
+ ObjCMT_None = 0,
+ /// \brief Enable migration to modern ObjC literals.
+ ObjCMT_Literals = 0x1,
+ /// \brief Enable migration to modern ObjC subscripting.
+ ObjCMT_Subscripting = 0x2,
+ /// \brief Enable migration to modern ObjC property.
+ ObjCMT_Property = 0x4
+ };
+ unsigned ObjCMTAction;
+
+ std::string MTMigrateDir;
+ std::string ARCMTMigrateReportOut;
+
+ /// The input files and their types.
+ std::vector<FrontendInputFile> Inputs;
+
+ /// The output file, if any.
+ std::string OutputFile;
+
+ /// If given, the new suffix for fix-it rewritten files.
+ std::string FixItSuffix;
+
+ /// If given, filter dumped AST Decl nodes by this substring.
+ std::string ASTDumpFilter;
+
+ /// If given, enable code completion at the provided location.
+ ParsedSourceLocation CodeCompletionAt;
+
+ /// The frontend action to perform.
+ frontend::ActionKind ProgramAction;
+
+ /// The name of the action to run when using a plugin action.
+ std::string ActionName;
+
+ /// Args to pass to the plugin
+ std::vector<std::string> PluginArgs;
+
+ /// The list of plugin actions to run in addition to the normal action.
+ std::vector<std::string> AddPluginActions;
+
+ /// Args to pass to the additional plugins
+ std::vector<std::vector<std::string> > AddPluginArgs;
+
+ /// The list of plugins to load.
+ std::vector<std::string> Plugins;
+
+ /// \brief The list of AST files to merge.
+ std::vector<std::string> ASTMergeFiles;
+
+ /// \brief A list of arguments to forward to LLVM's option processing; this
+ /// should only be used for debugging and experimental features.
+ std::vector<std::string> LLVMArgs;
+
+ /// \brief File name of the file that will provide record layouts
+ /// (in the format produced by -fdump-record-layouts).
+ std::string OverrideRecordLayoutsFile;
+
+public:
+ FrontendOptions() :
+ DisableFree(false), RelocatablePCH(false), ShowHelp(false),
+ ShowStats(false), ShowTimers(false), ShowVersion(false),
+ FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
+ FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
+ SkipFunctionBodies(false), UseGlobalModuleIndex(true),
+ GenerateGlobalModuleIndex(true), ASTDumpLookups(false),
+ ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None),
+ ProgramAction(frontend::ParseSyntaxOnly)
+ {}
+
+ /// getInputKindForExtension - Return the appropriate input kind for a file
+ /// extension. For example, "c" would return IK_C.
+ ///
+ /// \return The input kind for the extension, or IK_None if the extension is
+ /// not recognized.
+ static InputKind getInputKindForExtension(StringRef Extension);
+};
+
+} // end namespace flang
+
+#endif
diff --git a/include/flang/Frontend/VerifyDiagnosticConsumer.h b/include/flang/Frontend/VerifyDiagnosticConsumer.h
index e669198c8b..ec062870d2 100644
--- a/include/flang/Frontend/VerifyDiagnosticConsumer.h
+++ b/include/flang/Frontend/VerifyDiagnosticConsumer.h
@@ -13,7 +13,6 @@
#include "flang/Basic/Diagnostic.h"
#include "flang/Parse/Lexer.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include <climits>
@@ -203,7 +202,7 @@ private:
DiagnosticsEngine &Diags;
DiagnosticClient *PrimaryClient;
bool OwnsPrimaryClient;
- llvm::OwningPtr<TextDiagnosticBuffer> Buffer;
+ std::unique_ptr<TextDiagnosticBuffer> Buffer;
const Lexer *CurrentPreprocessor;
const LangOptions *LangOpts;
const llvm::SourceMgr *SrcManager;
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 19c79ccd56..c21da7c4d0 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -19,7 +19,7 @@ namespace flang {
void APNumericStorage::setIntValue(ASTContext &C, const APInt &Val) {
if (hasAllocation())
- C.Deallocate(pVal);
+ C.Deallocate(pVal, sizeof(uint64_t[llvm::APInt::getNumWords(BitWidth)]));
BitWidth = Val.getBitWidth();
unsigned NumWords = Val.getNumWords();
diff --git a/lib/Basic/Token.cpp b/lib/Basic/Token.cpp
index 1ed0d0012c..104be84f0a 100644
--- a/lib/Basic/Token.cpp
+++ b/lib/Basic/Token.cpp
@@ -66,8 +66,8 @@ llvm::Twine Token::CleanCharContext() {
if (*CurPtr != '\n' && *CurPtr != '\r')
continue;
- CharContext = CharContext +
- llvm::Twine(llvm::StringRef(Start, Amp - Start));
+ CharContext.concat(
+ llvm::Twine(llvm::StringRef(Start, Amp - Start)));
while (true) {
while (isHorizontalWhitespace(*CurPtr) ||
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
new file mode 100644
index 0000000000..37569cf43e
--- /dev/null
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -0,0 +1,488 @@
+//===--- BackendUtil.cpp - LLVM Backend Utilities -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/CodeGen/BackendUtil.h"
+#include "flang/Basic/Diagnostic.h"
+#include "flang/Basic/LangOptions.h"
+#include "flang/Basic/TargetOptions.h"
+#include "flang/Frontend/CodeGenOptions.h"
+#include "flang/Frontend/FrontendDiagnostic.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/CodeGen/RegAllocRegistry.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/PassManager.h"
+#include "llvm/Bitcode/BitcodeWriterPass.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetLibraryInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/ObjCARC.h"
+#include "llvm/Transforms/Scalar.h"
+using namespace flang;
+using namespace llvm;
+
+namespace {
+
+class EmitAssemblyHelper {
+ DiagnosticsEngine &Diags;
+ const CodeGenOptions &CodeGenOpts;
+ const flang::TargetOptions &TargetOpts;
+ const LangOptions &LangOpts;
+ Module *TheModule;
+
+ Timer CodeGenerationTime;
+
+ mutable PassManager *CodeGenPasses;
+ mutable PassManager *PerModulePasses;
+ mutable FunctionPassManager *PerFunctionPasses;
+
+private:
+ PassManager *getCodeGenPasses() const {
+ if (!CodeGenPasses) {
+ CodeGenPasses = new PassManager();
+ CodeGenPasses->add(new DataLayoutPass());
+ if (TM)
+ TM->addAnalysisPasses(*CodeGenPasses);
+ }
+ return CodeGenPasses;
+ }
+
+ PassManager *getPerModulePasses() const {
+ if (!PerModulePasses) {
+ PerModulePasses = new PassManager();
+ PerModulePasses->add(new DataLayoutPass());
+ if (TM)
+ TM->addAnalysisPasses(*PerModulePasses);
+ }
+ return PerModulePasses;
+ }
+
+ FunctionPassManager *getPerFunctionPasses() const {
+ if (!PerFunctionPasses) {
+ PerFunctionPasses = new FunctionPassManager(TheModule);
+ PerFunctionPasses->add(new DataLayoutPass());
+ if (TM)
+ TM->addAnalysisPasses(*PerFunctionPasses);
+ }
+ return PerFunctionPasses;
+ }
+
+
+ void CreatePasses();
+
+ /// CreateTargetMachine - Generates the TargetMachine.
+ /// Returns Null if it is unable to create the target machine.
+ /// Some of our clang tests specify triples which are not built
+ /// into clang. This is okay because these tests check the generated
+ /// IR, and they require DataLayout which depends on the triple.
+ /// In this case, we allow this method to fail and not report an error.
+ /// When MustCreateTM is used, we print an error if we are unable to load
+ /// the requested target.
+ TargetMachine *CreateTargetMachine(bool MustCreateTM);
+
+ /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
+ ///
+ /// \return True on success.
+ bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS);
+
+public:
+ EmitAssemblyHelper(DiagnosticsEngine &_Diags,
+ const CodeGenOptions &CGOpts,
+ const flang::TargetOptions &TOpts,
+ const LangOptions &LOpts,
+ Module *M)
+ : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),
+ TheModule(M), CodeGenerationTime("Code Generation Time"),
+ CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {}
+
+ ~EmitAssemblyHelper() {
+ delete CodeGenPasses;
+ delete PerModulePasses;
+ delete PerFunctionPasses;
+ }
+
+ std::unique_ptr<TargetMachine> TM;
+
+ void EmitAssembly(BackendAction Action, raw_ostream *OS);
+};
+
+// We need this wrapper to access LangOpts and CGOpts from extension functions
+// that we add to the PassManagerBuilder.
+class PassManagerBuilderWrapper : public PassManagerBuilder {
+public:
+ PassManagerBuilderWrapper(const CodeGenOptions &CGOpts,
+ const LangOptions &LangOpts)
+ : PassManagerBuilder(), CGOpts(CGOpts), LangOpts(LangOpts) {}
+ const CodeGenOptions &getCGOpts() const { return CGOpts; }
+ const LangOptions &getLangOpts() const { return LangOpts; }
+private:
+ const CodeGenOptions &CGOpts;
+ const LangOptions &LangOpts;
+};
+
+}
+
+static void addBoundsCheckingPass(const PassManagerBuilder &Builder,
+ PassManagerBase &PM) {
+ PM.add(createBoundsCheckingPass());
+}
+
+void EmitAssemblyHelper::CreatePasses() {
+ unsigned OptLevel = CodeGenOpts.OptimizationLevel;
+ CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();
+
+ // Handle disabling of LLVM optimization, where we want to preserve the
+ // internal module before any optimization.
+ if (CodeGenOpts.DisableLLVMOpts) {
+ OptLevel = 0;
+ Inlining = CodeGenOpts.NoInlining;
+ }
+
+ PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts);
+ PMBuilder.OptLevel = OptLevel;
+ PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
+ PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB;
+ PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
+ PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;
+
+ PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
+ PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
+
+ // Figure out TargetLibraryInfo.
+ Triple TargetTriple(TheModule->getTargetTriple());
+ PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);
+ if (!CodeGenOpts.SimplifyLibCalls)
+ PMBuilder.LibraryInfo->disableAllFunctions();
+
+ switch (Inlining) {
+ case CodeGenOptions::NoInlining: break;
+ case CodeGenOptions::NormalInlining: {
+ // FIXME: Derive these constants in a principled fashion.
+ unsigned Threshold = 225;
+ if (CodeGenOpts.OptimizeSize == 1) // -Os
+ Threshold = 75;
+ else if (CodeGenOpts.OptimizeSize == 2) // -Oz
+ Threshold = 25;
+ else if (OptLevel > 2)
+ Threshold = 275;
+ PMBuilder.Inliner = createFunctionInliningPass(Threshold);
+ break;
+ }
+ case CodeGenOptions::OnlyAlwaysInlining:
+ // Respect always_inline.
+ if (OptLevel == 0)
+ // Do not insert lifetime intrinsics at -O0.
+ PMBuilder.Inliner = createAlwaysInlinerPass(false);
+ else
+ PMBuilder.Inliner = createAlwaysInlinerPass();
+ break;
+ }
+
+ // Set up the per-function pass manager.
+ FunctionPassManager *FPM = getPerFunctionPasses();
+ if (CodeGenOpts.VerifyModule)
+ FPM->add(createVerifierPass());
+ PMBuilder.populateFunctionPassManager(*FPM);
+
+ // Set up the per-module pass manager.
+ PassManager *MPM = getPerModulePasses();
+
+ if (!CodeGenOpts.DisableGCov &&
+ (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) {
+ // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
+ // LLVM's -default-gcov-version flag is set to something invalid.
+ GCOVOptions Options;
+ Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
+ Options.EmitData = CodeGenOpts.EmitGcovArcs;
+ memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4);
+ Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum;
+ Options.NoRedZone = CodeGenOpts.DisableRedZone;
+ Options.FunctionNamesInData =
+ !CodeGenOpts.CoverageNoFunctionNamesInData;
+ MPM->add(createGCOVProfilerPass(Options));
+ if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo)
+ MPM->add(createStripSymbolsPass(true));
+ }
+
+ PMBuilder.populateModulePassManager(*MPM);
+}
+
+TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
+ // Create the TargetMachine for generating code.
+ std::string Error;
+ std::string Triple = TheModule->getTargetTriple();
+ const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
+ if (!TheTarget) {
+ if (MustCreateTM)
+ Diags.Report(diag::err_fe_unable_to_create_target) << Error;
+ return 0;
+ }
+
+ // FIXME: Expose these capabilities via actual APIs!!!! Aside from just
+ // being gross, this is also totally broken if we ever care about
+ // concurrency.
+
+ //TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
+
+ //TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections);
+ //TargetMachine::setDataSections (CodeGenOpts.DataSections);
+
+ // FIXME: Parse this earlier.
+ llvm::CodeModel::Model CM;
+ if (CodeGenOpts.CodeModel == "small") {
+ CM = llvm::CodeModel::Small;
+ } else if (CodeGenOpts.CodeModel == "kernel") {
+ CM = llvm::CodeModel::Kernel;
+ } else if (CodeGenOpts.CodeModel == "medium") {
+ CM = llvm::CodeModel::Medium;
+ } else if (CodeGenOpts.CodeModel == "large") {
+ CM = llvm::CodeModel::Large;
+ } else {
+ assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
+ CM = llvm::CodeModel::Default;
+ }
+
+ SmallVector<const char *, 16> BackendArgs;
+ BackendArgs.push_back("clang"); // Fake program name.
+ if (!CodeGenOpts.DebugPass.empty()) {
+ BackendArgs.push_back("-debug-pass");
+ BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
+ }
+ if (!CodeGenOpts.LimitFloatPrecision.empty()) {
+ BackendArgs.push_back("-limit-float-precision");
+ BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
+ }
+ if (llvm::TimePassesIsEnabled)
+ BackendArgs.push_back("-time-passes");
+ for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i)
+ BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str());
+ if (CodeGenOpts.NoGlobalMerge)
+ BackendArgs.push_back("-global-merge=false");
+ BackendArgs.push_back(0);
+ llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
+ BackendArgs.data());
+
+ std::string FeaturesStr;
+ if (TargetOpts.Features.size()) {
+ SubtargetFeatures Features;
+ for (std::vector<std::string>::const_iterator
+ it = TargetOpts.Features.begin(),
+ ie = TargetOpts.Features.end(); it != ie; ++it)
+ Features.AddFeature(*it);
+ FeaturesStr = Features.getString();
+ }
+
+ llvm::Reloc::Model RM = llvm::Reloc::Default;
+ if (CodeGenOpts.RelocationModel == "static") {
+ RM = llvm::Reloc::Static;
+ } else if (CodeGenOpts.RelocationModel == "pic") {
+ RM = llvm::Reloc::PIC_;
+ } else {
+ assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
+ "Invalid PIC model!");
+ RM = llvm::Reloc::DynamicNoPIC;
+ }
+
+ CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
+ switch (CodeGenOpts.OptimizationLevel) {
+ default: break;
+ case 0: OptLevel = CodeGenOpt::None; break;
+ case 3: OptLevel = CodeGenOpt::Aggressive; break;
+ }
+
+ llvm::TargetOptions Options;
+
+ // Set frame pointer elimination mode.
+ if (!CodeGenOpts.DisableFPElim) {
+ Options.NoFramePointerElim = false;
+ //Options.NoFramePointerElimNonLeaf = false;
+ } else if (CodeGenOpts.OmitLeafFramePointer) {
+ Options.NoFramePointerElim = false;
+ //Options.NoFramePointerElimNonLeaf = true;
+ } else {
+ Options.NoFramePointerElim = true;
+ //Options.NoFramePointerElimNonLeaf = true;
+ }
+
+ if (CodeGenOpts.UseInitArray)
+ Options.UseInitArray = true;
+
+ // Set float ABI type.
+ if (CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp")
+ Options.FloatABIType = llvm::FloatABI::Soft;
+ else if (CodeGenOpts.FloatABI == "hard")
+ Options.FloatABIType = llvm::FloatABI::Hard;
+ else {
+ assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
+ Options.FloatABIType = llvm::FloatABI::Default;
+ }
+
+ // Set FP fusion mode.
+ switch (CodeGenOpts.getFPContractMode()) {
+ case CodeGenOptions::FPC_Off:
+ Options.AllowFPOpFusion = llvm::FPOpFusion::Strict;
+ break;
+ case CodeGenOptions::FPC_On:
+ Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
+ break;
+ case CodeGenOptions::FPC_Fast:
+ Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
+ break;
+ }
+
+ Options.LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD;
+ Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath;
+ Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath;
+ Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
+ Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath;
+ Options.UseSoftFloat = CodeGenOpts.SoftFloat;
+ Options.StackAlignmentOverride = CodeGenOpts.StackAlignment;
+ //Options.RealignStack = CodeGenOpts.StackRealignment;
+ Options.DisableTailCalls = CodeGenOpts.DisableTailCalls;
+ Options.TrapFuncName = CodeGenOpts.TrapFuncName;
+ //Options.PositionIndependentExecutable = LangOpts.PIELevel != 0;
+ //Options.EnableSegmentedStacks = CodeGenOpts.EnableSegmentedStacks;
+
+ TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,
+ FeaturesStr, Options,
+ RM, CM, OptLevel);
+
+ //if (CodeGenOpts.RelaxAll)
+ // TM->setMCRelaxAll(true);
+ //if (CodeGenOpts.SaveTempLabels)
+ // TM->setMCSaveTempLabels(true);
+ //if (CodeGenOpts.NoDwarf2CFIAsm)
+ // TM->setMCUseCFI(false);
+ //if (!CodeGenOpts.NoDwarfDirectoryAsm)
+ // TM->setMCUseDwarfDirectory(true);
+ //if (CodeGenOpts.NoExecStack)
+ // TM->setMCNoExecStack(true);
+
+ return TM;
+}
+
+bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,
+ formatted_raw_ostream &OS) {
+
+ // Create the code generator passes.
+ PassManager *PM = getCodeGenPasses();
+
+ // Add LibraryInfo.
+ llvm::Triple TargetTriple(TheModule->getTargetTriple());
+ TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
+ if (!CodeGenOpts.SimplifyLibCalls)
+ TLI->disableAllFunctions();
+ PM->add(TLI);
+
+ // Add Target specific analysis passes.
+ TM->addAnalysisPasses(*PM);
+
+ // Normal mode, emit a .s or .o file by running the code generator. Note,
+ // this also adds codegenerator level optimization passes.
+ TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
+ if (Action == Backend_EmitObj)
+ CGFT = TargetMachine::CGFT_ObjectFile;
+ else if (Action == Backend_EmitMCNull)
+ CGFT = TargetMachine::CGFT_Null;
+ else
+ assert(Action == Backend_EmitAssembly && "Invalid action!");
+
+ if (TM->addPassesToEmitFile(*PM, OS, CGFT,
+ /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
+ Diags.Report(diag::err_fe_unable_to_interface_with_target);
+ return false;
+ }
+
+ return true;
+}
+
+void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {
+ TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0);
+ llvm::formatted_raw_ostream FormattedOS;
+
+ bool UsesCodeGen = (Action != Backend_EmitNothing &&
+ Action != Backend_EmitBC &&
+ Action != Backend_EmitLL);
+
+ if (!TM)
+ TM.reset(CreateTargetMachine(UsesCodeGen));
+
+ if (UsesCodeGen && !TM) return;
+ CreatePasses();
+
+ switch (Action) {
+ case Backend_EmitNothing:
+ break;
+
+ case Backend_EmitBC:
+ getPerModulePasses()->add(createBitcodeWriterPass(*OS));
+ break;
+
+ case Backend_EmitLL:
+ FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
+ getPerModulePasses()->add(createPrintModulePass(FormattedOS));
+ break;
+
+ default:
+ FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
+ if (!AddEmitPasses(Action, FormattedOS))
+ return;
+ }
+
+ // Before executing passes, print the final values of the LLVM options.
+ cl::PrintOptionValues();
+
+ // Run passes. For now we do all passes at once, but eventually we
+ // would like to have the option of streaming code generation.
+
+ if (PerFunctionPasses) {
+ PrettyStackTraceString CrashInfo("Per-function optimization");
+
+ PerFunctionPasses->doInitialization();
+ for (Module::iterator I = TheModule->begin(),
+ E = TheModule->end(); I != E; ++I)
+ if (!I->isDeclaration())
+ PerFunctionPasses->run(*I);
+ PerFunctionPasses->doFinalization();
+ }
+
+ if (PerModulePasses) {
+ PrettyStackTraceString CrashInfo("Per-module optimization passes");
+ PerModulePasses->run(*TheModule);
+ }
+
+ if (CodeGenPasses) {
+ PrettyStackTraceString CrashInfo("Code generation");
+ CodeGenPasses->run(*TheModule);
+ }
+}
+
+void flang::EmitBackendOutput(DiagnosticsEngine &Diags,
+ const CodeGenOptions &CGOpts,
+ const flang::TargetOptions &TOpts,
+ const LangOptions &LOpts,
+ Module *M,
+ BackendAction Action, raw_ostream *OS) {
+ EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
+
+ AsmHelper.EmitAssembly(Action, OS);
+}
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index bbef51ec3b..d35a48bad0 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -24,7 +24,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/Support/CallSite.h"
+#include "llvm/IR/CallSite.h"
#include "llvm/Transforms/Utils/Local.h"
namespace flang {
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index a6c7464788..6ddcc2b592 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -22,7 +22,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
-#include "llvm/Support/CFG.h"
+#include "llvm/IR/CFG.h"
namespace flang {
namespace CodeGen {
diff --git a/lib/CodeGen/CGIntrinsic.cpp b/lib/CodeGen/CGIntrinsic.cpp
index cbdb6c043a..1c9dba11e9 100644
--- a/lib/CodeGen/CGIntrinsic.cpp
+++ b/lib/CodeGen/CGIntrinsic.cpp
@@ -24,7 +24,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
-#include "llvm/Support/CFG.h"
+#include "llvm/IR/CFG.h"
namespace flang {
namespace CodeGen {
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 5af6b01215..150df60999 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -19,7 +19,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Intrinsics.h"
-#include "llvm/Support/CallSite.h"
+#include "llvm/IR/CallSite.h"
namespace flang {
namespace CodeGen {
diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp
new file mode 100644
index 0000000000..53ee5aafd3
--- /dev/null
+++ b/lib/CodeGen/CodeGenAction.cpp
@@ -0,0 +1,245 @@
+//===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/CodeGen/CodeGenAction.h"
+#include "flang/CodeGen/BackendUtil.h"
+#include "flang/AST/ASTConsumer.h"
+#include "flang/AST/ASTContext.h"
+#include "flang/AST/DeclGroup.h"
+#include "flang/CodeGen/BackendUtil.h"
+#include "flang/CodeGen/ModuleBuilder.h"
+#include "flang/Frontend/CompilerInstance.h"
+#include "flang/Frontend/FrontendDiagnostic.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IRReader/IRReader.h"
+#include "llvm/Linker/Linker.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/Timer.h"
+
+using namespace flang;
+using namespace llvm;
+
+namespace flang {
+ class BackendConsumer : public ASTConsumer {
+ virtual void anchor();
+ DiagnosticsEngine &Diags;
+ BackendAction Action;
+ const CodeGenOptions &CodeGenOpts;
+ const TargetOptions &TargetOpts;
+ const LangOptions &LangOpts;
+ raw_ostream *AsmOutStream;
+ ASTContext *Context;
+
+ Timer LLVMIRGeneration;
+
+ std::unique_ptr<CodeGenerator> Gen;
+
+ std::unique_ptr<llvm::Module> TheModule, LinkModule;
+
+ public:
+ BackendConsumer(BackendAction action, DiagnosticsEngine &_Diags,
+ const CodeGenOptions &compopts,
+ const TargetOptions &targetopts,
+ const LangOptions &langopts,
+ bool TimePasses,
+ const std::string &infile,
+ llvm::Module *LinkModule,
+ raw_ostream *OS,
+ LLVMContext &C) :
+ Diags(_Diags),
+ Action(action),
+ CodeGenOpts(compopts),
+ TargetOpts(targetopts),
+ LangOpts(langopts),
+ AsmOutStream(OS),
+ Context(),
+ LLVMIRGeneration("LLVM IR Generation Time"),
+ Gen(CreateLLVMCodeGen(Diags, infile, compopts, targetopts, C)),
+ LinkModule(LinkModule)
+ {
+ llvm::TimePassesIsEnabled = TimePasses;
+ }
+
+ llvm::Module *takeModule() { return TheModule.release(); }
+ llvm::Module *takeLinkModule() { return LinkModule.release(); }
+
+ virtual void Initialize(ASTContext &Ctx) {
+ Context = &Ctx;
+
+ if (llvm::TimePassesIsEnabled)
+ LLVMIRGeneration.startTimer();
+
+ Gen->Initialize(Ctx);
+
+ TheModule.reset(Gen->GetModule());
+
+ if (llvm::TimePassesIsEnabled)
+ LLVMIRGeneration.stopTimer();
+ }
+
+ virtual void HandleTranslationUnit(ASTContext &C) {
+ {
+ PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
+ if (llvm::TimePassesIsEnabled)
+ LLVMIRGeneration.startTimer();
+
+ Gen->HandleTranslationUnit(C);
+
+ if (llvm::TimePassesIsEnabled)
+ LLVMIRGeneration.stopTimer();
+ }
+
+ // Silently ignore if we weren't initialized for some reason.
+ if (!TheModule)
+ return;
+
+ // Make sure IR generation is happy with the module. This is released by
+ // the module provider.
+ llvm::Module *M = Gen->ReleaseModule();
+ if (!M) {
+ // The module has been released by IR gen on failures, do not double
+ // free.
+ TheModule.release();
+ return;
+ }
+
+ assert(TheModule.get() == M &&
+ "Unexpected module change during IR generation");
+
+ // Link LinkModule into this module if present, preserving its validity.
+ if (LinkModule) {
+ std::string ErrorMsg;
+ if (Linker::LinkModules(M, LinkModule.get(), Linker::PreserveSource,
+ &ErrorMsg)) {
+ Diags.Report(diag::err_fe_cannot_link_module)
+ << LinkModule->getModuleIdentifier() << ErrorMsg;
+ return;
+ }
+ }
+
+ EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
+ TheModule.get(), Action, AsmOutStream);
+
+ }
+
+ };
+
+ void BackendConsumer::anchor() {}
+}
+
+//
+
+CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext)
+ : Act(_Act), LinkModule(0),
+ VMContext(_VMContext ? _VMContext : new LLVMContext),
+ OwnsVMContext(!_VMContext) {}
+
+CodeGenAction::~CodeGenAction() {
+ TheModule.reset();
+ if (OwnsVMContext)
+ delete VMContext;
+}
+
+bool CodeGenAction::hasIRSupport() const { return true; }
+
+void CodeGenAction::EndSourceFileAction() {
+ // If the consumer creation failed, do nothing.
+ if (!getCompilerInstance().hasASTConsumer())
+ return;
+
+ // If we were given a link module, release consumer's ownership of it.
+ if (LinkModule)
+ BEConsumer->takeLinkModule();
+
+ // Steal the module from the consumer.
+ TheModule.reset(BEConsumer->takeModule());
+}
+
+llvm::Module *CodeGenAction::takeModule() {
+ return TheModule.release();
+}
+
+llvm::LLVMContext *CodeGenAction::takeLLVMContext() {
+ OwnsVMContext = false;
+ return VMContext;
+}
+
+static raw_ostream *GetOutputStream(CompilerInstance &CI,
+ StringRef InFile,
+ BackendAction Action) {
+ switch (Action) {
+ case Backend_EmitAssembly:
+ return CI.createDefaultOutputFile(false, InFile, "s");
+ case Backend_EmitLL:
+ return CI.createDefaultOutputFile(false, InFile, "ll");
+ case Backend_EmitBC:
+ return CI.createDefaultOutputFile(true, InFile, "bc");
+ case Backend_EmitNothing:
+ return 0;
+ case Backend_EmitMCNull:
+ case Backend_EmitObj:
+ return CI.createDefaultOutputFile(true, InFile, "o");
+ }
+
+ llvm_unreachable("Invalid action!");
+}
+
+ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) {
+ BackendAction BA = static_cast<BackendAction>(Act);
+ std::unique_ptr<raw_ostream> OS(GetOutputStream(CI, InFile, BA));
+ if (BA != Backend_EmitNothing && !OS)
+ return 0;
+
+ llvm::Module *LinkModuleToUse = LinkModule;
+
+ BEConsumer =
+ new BackendConsumer(BA, CI.getDiagnostics(),
+ CI.getCodeGenOpts(), CI.getTargetOpts(),
+ CI.getLangOpts(),
+ CI.getFrontendOpts().ShowTimers, InFile,
+ LinkModuleToUse, OS.release(), *VMContext);
+ return BEConsumer;
+}
+
+void CodeGenAction::ExecuteAction() {
+ // Otherwise follow the normal AST path.
+ this->ASTFrontendAction::ExecuteAction();
+}
+
+//
+
+void EmitAssemblyAction::anchor() { }
+EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext)
+ : CodeGenAction(Backend_EmitAssembly, _VMContext) {}
+
+void EmitBCAction::anchor() { }
+EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext)
+ : CodeGenAction(Backend_EmitBC, _VMContext) {}
+
+void EmitLLVMAction::anchor() { }
+EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext)
+ : CodeGenAction(Backend_EmitLL, _VMContext) {}
+
+void EmitLLVMOnlyAction::anchor() { }
+EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext)
+ : CodeGenAction(Backend_EmitNothing, _VMContext) {}
+
+void EmitCodeGenOnlyAction::anchor() { }
+EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext)
+ : CodeGenAction(Backend_EmitMCNull, _VMContext) {}
+
+void EmitObjAction::anchor() { }
+EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext)
+ : CodeGenAction(Backend_EmitObj, _VMContext) {}
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 867a314aa9..3326cc2b4d 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -26,7 +26,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
namespace llvm {
class BasicBlock;
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 74536bbd05..c96a47d1bf 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -28,10 +28,10 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/Support/CallSite.h"
+#include "llvm/IR/CallSite.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/Mangler.h"
+#include "llvm/IR/Mangler.h"
namespace flang {
namespace CodeGen {
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index dfa1a31080..abafbfaa07 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -24,8 +24,8 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Module.h"
-#include "llvm/Support/ValueHandle.h"
-#include "llvm/Transforms/Utils/BlackList.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/SpecialCaseList.h"
namespace llvm {
class Module;
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index 8cd6ad3ef1..ba87058e91 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -18,7 +18,6 @@
#include "flang/AST/Expr.h"
#include "flang/Basic/Diagnostic.h"
#include "flang/Frontend/CodeGenOptions.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/LLVMContext.h"
@@ -27,17 +26,17 @@ using namespace flang;
namespace {
- using llvm::OwningPtr;
+ using std::unique_ptr;
class CodeGeneratorImpl : public CodeGenerator {
DiagnosticsEngine &Diags;
- OwningPtr<const llvm::DataLayout> TD;
+ std::unique_ptr<const llvm::DataLayout> TD;
ASTContext *Ctx;
const CodeGenOptions CodeGenOpts; // Intentionally copied in.
const TargetOptions Target;
protected:
- OwningPtr<llvm::Module> M;
- OwningPtr<CodeGen::CodeGenModule> Builder;
+ std::unique_ptr<llvm::Module> M;
+ std::unique_ptr<CodeGen::CodeGenModule> Builder;
public:
CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string& ModuleName,
const CodeGenOptions &CGO,
@@ -54,7 +53,7 @@ namespace {
}
virtual llvm::Module* ReleaseModule() {
- return M.take();
+ return M.release();
}
virtual void Initialize(ASTContext &Context) {
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 160c465914..388822da8d 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -141,7 +141,7 @@ void Sema::PopExecutableProgramUnit(SourceLocation Loc) {
// was already reported as undeclared label use.
ReportUnterminatedStmt(CurExecutableStmts->LastEntered(), Loc, false);
}
- auto Body = CurExecutableStmts->LeaveOuterBody(Context, cast<Decl>(CurContext)->getLocation());
+ auto Body = CurExecutableStmts->LeaveOuterBody(Context, Decl::castFromDeclContext(CurContext)->getLocation());
if(auto FD = dyn_cast<FunctionDecl>(CurContext))
FD->setBody(Body);
else
@@ -172,7 +172,7 @@ Stmt *BlockStmtBuilder::CreateBody(ASTContext &C,
void BlockStmtBuilder::LeaveIfThen(ASTContext &C) {
auto Last = ControlFlowStack.back();
- assert(isa<IfStmt>(Last));
+ assert(isa<IfStmt>(Last.Statement));
auto Body = CreateBody(C, Last);
cast<IfStmt>(Last.Statement)->setThenStmt(Body);
@@ -181,7 +181,7 @@ void BlockStmtBuilder::LeaveIfThen(ASTContext &C) {
void BlockStmtBuilder::LeaveWhereThen(ASTContext &C) {
auto Last = ControlFlowStack.back();
- assert(isa<WhereStmt>(Last));
+ assert(isa<WhereStmt>(Last.Statement));
auto Body = CreateBody(C, Last);
cast<WhereStmt>(Last.Statement)->setThenStmt(Body);
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index a0e2375b99..c0ba3e4c62 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -6,7 +6,6 @@ set( LLVM_LINK_COMPONENTS
codegen
ipo
selectiondag
- jit
interpreter
linker
)
diff --git a/tools/driver/Main.cpp b/tools/driver/Main.cpp
index 744f3441f4..327b22de5e 100644
--- a/tools/driver/Main.cpp
+++ b/tools/driver/Main.cpp
@@ -23,12 +23,12 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/JIT.h"
+//#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/PassManager.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Instrumentation.h"
-#include "llvm/Analysis/Verifier.h"
+#include "llvm/IR/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Target/TargetMachine.h"
@@ -47,8 +47,6 @@
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/Timer.h"
-#include "llvm/Support/system_error.h"
-#include "llvm/ADT/OwningPtr.h"
using namespace llvm;
using namespace flang;
@@ -128,6 +126,7 @@ namespace {
} // end anonymous namespace
+/*
extern "C" void jit_write_start(void *) { }
extern "C" void jit_write_character(void *,const char *Ptr, size_t Length) {
@@ -158,7 +157,7 @@ extern "C" void jit_init() {}
static int Execute(llvm::Module *Module, const char * const *envp) {
std::string Error;
- OwningPtr<llvm::ExecutionEngine> EE(
+ std::unique_ptr<llvm::ExecutionEngine> EE(
llvm::ExecutionEngine::createJIT(Module, &Error));
if (!EE) {
llvm::errs() << "unable to make execution engine: " << Error << "\n";
@@ -204,6 +203,7 @@ static int Execute(llvm::Module *Module, const char * const *envp) {
return EE->runFunctionAsMain(EntryFn, Args, envp);
}
+*/
std::string GetOutputName(StringRef Filename,
BackendAction Action) {
@@ -237,10 +237,10 @@ static bool EmitFile(llvm::raw_ostream &Out,
Action == Backend_EmitObj ? llvm::TargetMachine::CGFT_ObjectFile :
llvm::TargetMachine::CGFT_AssemblyFile;
- llvm::PassManager PM;
+ PassManager PM;
Target.setAsmVerbosityDefault(true);
- Target.setMCRelaxAll(true);
+ //Target.setMCRelaxAll(true);
llvm::formatted_raw_ostream FOS(Out);
// Ask the target to add backend passes as necessary.
@@ -262,11 +262,11 @@ static bool EmitOutputFile(const std::string &Input,
llvm::Module *Module,
llvm::TargetMachine* TM,
BackendAction Action) {
- std::string err;
- llvm::raw_fd_ostream Out(Input.c_str(), err, llvm::raw_fd_ostream::F_Binary);//FIXME: llvm 3.4: llvm::sys::fs::F_Binary);
- if (!err.empty()){
+ std::error_code err;
+ llvm::raw_fd_ostream Out(Input.c_str(), err, llvm::sys::fs::F_None);
+ if (!err){
llvm::errs() << "Could not open output file '" << Input << "': "
- << err <<"\n";
+ << err.message() <<"\n";
return true;
}
return EmitFile(Out, Module, TM, Action);
@@ -295,13 +295,14 @@ static bool LinkFiles(ArrayRef<std::string> OutputFiles) {
static bool ParseFile(const std::string &Filename,
const std::vector<std::string> &IncludeDirs,
SmallVectorImpl<std::string> &OutputFiles) {
- llvm::OwningPtr<llvm::MemoryBuffer> MB;
- if (llvm::error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(Filename.c_str(),
- MB)) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
+ MemoryBuffer::getFileOrSTDIN(Filename);
+ if (std::error_code EC = MBOrErr.getError()) {
llvm::errs() << "Could not open input file '" << Filename << "': "
- << ec.message() <<"\n";
+ << EC.message() <<"\n";
return true;
}
+ std::unique_ptr<llvm::MemoryBuffer> MB = std::move(MBOrErr.get());
// Record the location of the include directory so that the lexer can find it
// later.
@@ -309,7 +310,7 @@ static bool ParseFile(const std::string &Filename,
SrcMgr.setIncludeDirs(IncludeDirs);
// Tell SrcMgr about this buffer, which is what Parser will pick up.
- SrcMgr.AddNewSourceBuffer(MB.take(), llvm::SMLoc());
+ SrcMgr.AddNewSourceBuffer(std::move(MB), llvm::SMLoc());
LangOptions Opts;
Opts.DefaultReal8 = DefaultReal8;
@@ -382,7 +383,7 @@ static bool ParseFile(const std::string &Filename,
if(!(EmitLLVM && OptLevel == 0)) {
auto TheModule = CG->GetModule();
auto PM = new PassManager();
- PM->add(new DataLayout(TheModule));
+ PM->add(new DataLayoutPass());
TM->addAnalysisPasses(*PM);
PM->add(createPromoteMemoryToRegisterPass());
@@ -404,8 +405,8 @@ static bool ParseFile(const std::string &Filename,
}
if(Interpret) {
- const char *Env[] = { "", nullptr };
- Execute(CG->ReleaseModule(), Env);
+ //const char *Env[] = { "", nullptr };
+ //Execute(CG->ReleaseModule(), Env);
} else if(OutputFile == "-")
EmitFile(llvm::outs(), CG->GetModule(), TM, BA);
else {