• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2010, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_H_  // NOLINT
18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_H_
19 
20 #include <cstdio>
21 #include <string>
22 #include <vector>
23 
24 // Terrible workaround for TargetOptions.h not using llvm::RefCountedBase!
25 #include "llvm/ADT/IntrusiveRefCntPtr.h"
26 using llvm::RefCountedBase;
27 
28 #include "clang/Basic/TargetOptions.h"
29 #include "clang/Lex/ModuleLoader.h"
30 
31 #include "llvm/ADT/StringRef.h"
32 
33 #include "llvm/Target/TargetMachine.h"
34 
35 #include "slang_diagnostic_buffer.h"
36 #include "slang_pragma_recorder.h"
37 
38 namespace llvm {
39   class tool_output_file;
40 }
41 
42 namespace clang {
43   class ASTConsumer;
44   class ASTContext;
45   class Backend;
46   class CodeGenOptions;
47   class Diagnostic;
48   class DiagnosticsEngine;
49   class FileManager;
50   class FileSystemOptions;
51   class LangOptions;
52   class Preprocessor;
53   class SourceManager;
54   class TargetInfo;
55 }  // namespace clang
56 
57 namespace slang {
58 
59 class Slang : public clang::ModuleLoader {
60   static clang::LangOptions LangOpts;
61   static clang::CodeGenOptions CodeGenOpts;
62 
63   static bool GlobalInitialized;
64 
65   static void LLVMErrorHandler(void *UserData, const std::string &Message,
66                                bool GenCrashDialog);
67 
68  public:
69   enum OutputType {
70     OT_Dependency,
71     OT_Assembly,
72     OT_LLVMAssembly,
73     OT_Bitcode,
74     OT_Nothing,
75     OT_Object,
76 
77     OT_Default = OT_Bitcode
78   };
79 
80  private:
81   bool mInitialized;
82 
83   // Diagnostics Mediator (An interface for both Producer and Consumer)
84   std::unique_ptr<clang::Diagnostic> mDiag;
85 
86   // Diagnostics Engine (Producer and Diagnostics Reporter)
87   clang::DiagnosticsEngine *mDiagEngine;
88 
89   // Diagnostics Consumer
90   // NOTE: The ownership is taken by mDiagEngine after creation.
91   DiagnosticBuffer *mDiagClient;
92 
93   // The target being compiled for
94   std::shared_ptr<clang::TargetOptions> mTargetOpts;
95   std::unique_ptr<clang::TargetInfo> mTarget;
96   void createTarget(uint32_t BitWidth);
97 
98 
99   // File manager (for prepocessor doing the job such as header file search)
100   std::unique_ptr<clang::FileManager> mFileMgr;
101   std::unique_ptr<clang::FileSystemOptions> mFileSysOpt;
102   void createFileManager();
103 
104 
105   // Source manager (responsible for the source code handling)
106   std::unique_ptr<clang::SourceManager> mSourceMgr;
107   void createSourceManager();
108 
109 
110   // Preprocessor (source code preprocessor)
111   std::unique_ptr<clang::Preprocessor> mPP;
112   void createPreprocessor();
113 
114 
115   // AST context (the context to hold long-lived AST nodes)
116   std::unique_ptr<clang::ASTContext> mASTContext;
117   void createASTContext();
118 
119 
120   // AST consumer, responsible for code generation
121   std::unique_ptr<clang::ASTConsumer> mBackend;
122 
123 
124   // File names
125   std::string mInputFileName;
126   std::string mOutputFileName;
127   std::string mOutput32FileName;
128 
129   std::string mDepOutputFileName;
130   std::string mDepTargetBCFileName;
131   std::vector<std::string> mAdditionalDepTargets;
132   std::vector<std::string> mGeneratedFileNames;
133 
134   OutputType mOT;
135 
136   // Output stream
137   std::unique_ptr<llvm::tool_output_file> mOS;
138 
139   // Dependency output stream
140   std::unique_ptr<llvm::tool_output_file> mDOS;
141 
142   std::vector<std::string> mIncludePaths;
143 
144  protected:
145   PragmaList mPragmas;
146 
getDiagnostics()147   clang::DiagnosticsEngine &getDiagnostics() { return *mDiagEngine; }
getTargetInfo()148   clang::TargetInfo const &getTargetInfo() const { return *mTarget; }
getFileManager()149   clang::FileManager &getFileManager() { return *mFileMgr; }
getSourceManager()150   clang::SourceManager &getSourceManager() { return *mSourceMgr; }
getPreprocessor()151   clang::Preprocessor &getPreprocessor() { return *mPP; }
getASTContext()152   clang::ASTContext &getASTContext() { return *mASTContext; }
153 
getTargetOptions()154   inline clang::TargetOptions const &getTargetOptions() const
155     { return *mTargetOpts.get(); }
156 
initDiagnostic()157   virtual void initDiagnostic() {}
initPreprocessor()158   virtual void initPreprocessor() {}
initASTContext()159   virtual void initASTContext() {}
160 
161   virtual clang::ASTConsumer *
162     createBackend(const clang::CodeGenOptions& CodeGenOpts,
163                   llvm::raw_ostream *OS,
164                   OutputType OT);
165 
166  public:
167   static const llvm::StringRef PragmaMetadataName;
168 
169   static void GlobalInitialization();
170 
171   Slang();
172 
173   void init(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine,
174             DiagnosticBuffer *DiagClient);
175 
176   virtual clang::ModuleLoadResult loadModule(
177       clang::SourceLocation ImportLoc,
178       clang::ModuleIdPath Path,
179       clang::Module::NameVisibilityKind VK,
180       bool IsInclusionDirective);
181 
182   bool setInputSource(llvm::StringRef InputFile, const char *Text,
183                       size_t TextLength);
184 
185   bool setInputSource(llvm::StringRef InputFile);
186 
getInputFileName()187   std::string const &getInputFileName() const { return mInputFileName; }
188 
setIncludePaths(const std::vector<std::string> & IncludePaths)189   void setIncludePaths(const std::vector<std::string> &IncludePaths) {
190     mIncludePaths = IncludePaths;
191   }
192 
setOutputType(OutputType OT)193   void setOutputType(OutputType OT) { mOT = OT; }
194 
195   bool setOutput(const char *OutputFile);
196 
197   // For use with 64-bit compilation/reflection. This only sets the filename of
198   // the 32-bit bitcode file, and doesn't actually verify it already exists.
setOutput32(const char * OutputFile)199   void setOutput32(const char *OutputFile) {
200     mOutput32FileName = OutputFile;
201   }
202 
getOutputFileName()203   std::string const &getOutputFileName() const {
204     return mOutputFileName;
205   }
206 
getOutput32FileName()207   std::string const &getOutput32FileName() const {
208     return mOutput32FileName;
209   }
210 
211   bool setDepOutput(const char *OutputFile);
212 
setDepTargetBC(const char * TargetBCFile)213   void setDepTargetBC(const char *TargetBCFile) {
214     mDepTargetBCFileName = TargetBCFile;
215   }
216 
setAdditionalDepTargets(std::vector<std::string> const & AdditionalDepTargets)217   void setAdditionalDepTargets(
218       std::vector<std::string> const &AdditionalDepTargets) {
219     mAdditionalDepTargets = AdditionalDepTargets;
220   }
221 
appendGeneratedFileName(std::string const & GeneratedFileName)222   void appendGeneratedFileName(std::string const &GeneratedFileName) {
223     mGeneratedFileNames.push_back(GeneratedFileName);
224   }
225 
226   int generateDepFile();
227 
228   int compile();
229 
getErrorMessage()230   char const *getErrorMessage() { return mDiagClient->str().c_str(); }
231 
232   void setDebugMetadataEmission(bool EmitDebug);
233 
234   void setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel);
235 
236   // Reset the slang compiler state such that it can be reused to compile
237   // another file
238   virtual void reset(bool SuppressWarnings = false);
239 
240   virtual ~Slang();
241 };
242 
243 }  // namespace slang
244 
245 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_H_  NOLINT
246