• 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 #include "clang/Basic/TargetOptions.h"
25 
26 #include "llvm/ADT/IntrusiveRefCntPtr.h"
27 #include "llvm/ADT/OwningPtr.h"
28 #include "llvm/ADT/StringRef.h"
29 
30 #include "slang_diagnostic_buffer.h"
31 #include "slang_pragma_recorder.h"
32 
33 namespace llvm {
34   class tool_output_file;
35 }
36 
37 namespace clang {
38   class Diagnostic;
39   class FileManager;
40   class FileSystemOptions;
41   class SourceManager;
42   class LangOptions;
43   class Preprocessor;
44   class TargetOptions;
45   class CodeGenOptions;
46   class ASTContext;
47   class ASTConsumer;
48   class Backend;
49   class TargetInfo;
50 }
51 
52 namespace slang {
53 
54 class Slang {
55   static clang::LangOptions LangOpts;
56   static clang::CodeGenOptions CodeGenOpts;
57 
58   static bool GlobalInitialized;
59 
60   static void LLVMErrorHandler(void *UserData, const std::string &Message);
61 
62  public:
63   typedef enum {
64     OT_Dependency,
65     OT_Assembly,
66     OT_LLVMAssembly,
67     OT_Bitcode,
68     OT_Nothing,
69     OT_Object,
70 
71     OT_Default = OT_Bitcode
72   } OutputType;
73 
74  private:
75   bool mInitialized;
76 
77   // The diagnostics engine instance (for status reporting during compilation)
78   llvm::IntrusiveRefCntPtr<clang::Diagnostic> mDiagnostics;
79   // The diagnostics id
80   llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> mDiagIDs;
81   // The clients of diagnostics engine. The ownership is taken by the
82   // mDiagnostics after creation.
83   DiagnosticBuffer *mDiagClient;
84   void createDiagnostic();
85 
86   // The target being compiled for
87   clang::TargetOptions mTargetOpts;
88   llvm::OwningPtr<clang::TargetInfo> mTarget;
89   void createTarget(const std::string &Triple, const std::string &CPU,
90                     const std::vector<std::string> &Features);
91 
92   // Below is for parsing and code generation
93 
94   // The file manager (for prepocessor doing the job such as header file search)
95   llvm::OwningPtr<clang::FileManager> mFileMgr;
96   llvm::OwningPtr<clang::FileSystemOptions> mFileSysOpt;
97   void createFileManager();
98 
99   // The source manager (responsible for the source code handling)
100   llvm::OwningPtr<clang::SourceManager> mSourceMgr;
101   void createSourceManager();
102 
103   // The preprocessor (source code preprocessor)
104   llvm::OwningPtr<clang::Preprocessor> mPP;
105   void createPreprocessor();
106 
107   // The AST context (the context to hold long-lived AST nodes)
108   llvm::OwningPtr<clang::ASTContext> mASTContext;
109   void createASTContext();
110 
111   // The AST consumer, responsible for code generation
112   llvm::OwningPtr<clang::ASTConsumer> mBackend;
113 
114   // Input file name
115   std::string mInputFileName;
116   std::string mOutputFileName;
117 
118   std::string mDepOutputFileName;
119   std::string mDepTargetBCFileName;
120   std::vector<std::string> mAdditionalDepTargets;
121   std::vector<std::string> mGeneratedFileNames;
122 
123   OutputType mOT;
124 
125   // Output stream
126   llvm::OwningPtr<llvm::tool_output_file> mOS;
127   // Dependency output stream
128   llvm::OwningPtr<llvm::tool_output_file> mDOS;
129 
130   std::vector<std::string> mIncludePaths;
131 
132  protected:
133   PragmaList mPragmas;
134 
getDiagnostics()135   inline clang::Diagnostic &getDiagnostics() { return *mDiagnostics; }
getTargetInfo()136   inline const clang::TargetInfo &getTargetInfo() const { return *mTarget; }
getFileManager()137   inline clang::FileManager &getFileManager() { return *mFileMgr; }
getSourceManager()138   inline clang::SourceManager &getSourceManager() { return *mSourceMgr; }
getPreprocessor()139   inline clang::Preprocessor &getPreprocessor() { return *mPP; }
getASTContext()140   inline clang::ASTContext &getASTContext() { return *mASTContext; }
141 
getTargetOptions()142   inline const clang::TargetOptions &getTargetOptions() const
143     { return mTargetOpts; }
144 
initDiagnostic()145   virtual void initDiagnostic() {}
initPreprocessor()146   virtual void initPreprocessor() {}
initASTContext()147   virtual void initASTContext() {}
148 
149   virtual clang::ASTConsumer
150   *createBackend(const clang::CodeGenOptions& CodeGenOpts,
151                  llvm::raw_ostream *OS,
152                  OutputType OT);
153 
154  public:
155   static const llvm::StringRef PragmaMetadataName;
156 
157   static void GlobalInitialization();
158 
159   Slang();
160 
161   void init(const std::string &Triple, const std::string &CPU,
162             const std::vector<std::string> &Features);
163 
164   bool setInputSource(llvm::StringRef InputFile, const char *Text,
165                       size_t TextLength);
166 
167   bool setInputSource(llvm::StringRef InputFile);
168 
getInputFileName()169   inline const std::string &getInputFileName() const { return mInputFileName; }
170 
setIncludePaths(const std::vector<std::string> & IncludePaths)171   inline void setIncludePaths(const std::vector<std::string> &IncludePaths) {
172     mIncludePaths = IncludePaths;
173   }
174 
setOutputType(OutputType OT)175   inline void setOutputType(OutputType OT) { mOT = OT; }
176 
177   bool setOutput(const char *OutputFile);
getOutputFileName()178   inline const std::string &getOutputFileName() const {
179     return mOutputFileName;
180   }
181 
182   bool setDepOutput(const char *OutputFile);
setDepTargetBC(const char * TargetBCFile)183   inline void setDepTargetBC(const char *TargetBCFile) {
184     mDepTargetBCFileName = TargetBCFile;
185   }
setAdditionalDepTargets(const std::vector<std::string> & AdditionalDepTargets)186   inline void setAdditionalDepTargets(
187       const std::vector<std::string> &AdditionalDepTargets) {
188     mAdditionalDepTargets = AdditionalDepTargets;
189   }
appendGeneratedFileName(const std::string & GeneratedFileName)190   inline void appendGeneratedFileName(
191       const std::string &GeneratedFileName) {
192     mGeneratedFileNames.push_back(GeneratedFileName);
193   }
194 
195   int generateDepFile();
196   int compile();
197 
getErrorMessage()198   inline const char *getErrorMessage() { return mDiagClient->str().c_str(); }
199 
200   // Reset the slang compiler state such that it can be reused to compile
201   // another file
202   virtual void reset();
203 
204   virtual ~Slang();
205 };
206 
207 }  // namespace slang
208 
209 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_H_  NOLINT
210