|
44 | 44 | #include <clang/Driver/ToolChain.h>
|
45 | 45 | #include <clang/Driver/Util.h>
|
46 | 46 | #include <clang/Index/USRGeneration.h>
|
47 |
| -#include <CodeGen/CodeGenModule.h> |
48 |
| -#include <CodeGen/CodeGenTypes.h> |
| 47 | + |
49 | 48 | #include <CodeGen/TargetInfo.h>
|
50 | 49 | #include <CodeGen/CGCall.h>
|
51 | 50 | #include <CodeGen/CGCXXABI.h>
|
@@ -3278,9 +3277,8 @@ bool Parser::IsValidDeclaration(const clang::SourceLocation& Loc)
|
3278 | 3277 |
|
3279 | 3278 | //-----------------------------------//
|
3280 | 3279 |
|
3281 |
| -void Parser::WalkAST() |
| 3280 | +void Parser::WalkAST(clang::TranslationUnitDecl* TU) |
3282 | 3281 | {
|
3283 |
| - auto TU = c->getASTContext().getTranslationUnitDecl(); |
3284 | 3282 | for (auto D : TU->decls())
|
3285 | 3283 | {
|
3286 | 3284 | if (D->getBeginLoc().isValid() &&
|
@@ -4049,107 +4047,130 @@ void Parser::HandleDiagnostics(ParserResult* res)
|
4049 | 4047 | }
|
4050 | 4048 | }
|
4051 | 4049 |
|
4052 |
| -ParserResult* Parser::ParseHeader(const std::vector<std::string>& SourceFiles) |
| 4050 | +void Parser::SetupLLVMCodegen() |
4053 | 4051 | {
|
4054 |
| - assert(opts->ASTContext && "Expected a valid ASTContext"); |
4055 |
| - |
4056 |
| - auto res = new ParserResult(); |
4057 |
| - |
4058 |
| - if (SourceFiles.empty()) |
4059 |
| - { |
4060 |
| - res->kind = ParserResultKind::FileNotFound; |
4061 |
| - return res; |
4062 |
| - } |
| 4052 | + // Initialize enough Clang codegen machinery so we can get at ABI details. |
| 4053 | + LLVMModule.reset(new llvm::Module("", LLVMCtx)); |
4063 | 4054 |
|
4064 |
| - Setup(); |
| 4055 | + LLVMModule->setTargetTriple(c->getTarget().getTriple().getTriple()); |
| 4056 | + LLVMModule->setDataLayout(c->getTarget().getDataLayout()); |
4065 | 4057 |
|
4066 |
| - std::unique_ptr<clang::SemaConsumer> SC(new clang::SemaConsumer()); |
4067 |
| - c->setASTConsumer(std::move(SC)); |
| 4058 | + CGM.reset(new clang::CodeGen::CodeGenModule(c->getASTContext(), |
| 4059 | + c->getHeaderSearchOpts(), c->getPreprocessorOpts(), |
| 4060 | + c->getCodeGenOpts(), *LLVMModule, c->getDiagnostics())); |
4068 | 4061 |
|
4069 |
| - c->createSema(clang::TU_Complete, 0); |
| 4062 | + CGT.reset(new clang::CodeGen::CodeGenTypes(*CGM.get())); |
4070 | 4063 |
|
4071 |
| - auto DiagClient = new DiagnosticConsumer(); |
4072 |
| - c->getDiagnostics().setClient(DiagClient); |
| 4064 | + codeGenTypes = CGT.get(); |
| 4065 | +} |
4073 | 4066 |
|
| 4067 | +bool Parser::SetupSourceFiles(const std::vector<std::string>& SourceFiles, |
| 4068 | + std::vector<const clang::FileEntry*>& FileEntries) |
| 4069 | +{ |
4074 | 4070 | // Check that the file is reachable.
|
4075 | 4071 | const clang::DirectoryLookup *Dir;
|
4076 | 4072 | llvm::SmallVector<
|
4077 | 4073 | std::pair<const clang::FileEntry *, const clang::DirectoryEntry *>,
|
4078 | 4074 | 0> Includers;
|
4079 | 4075 |
|
4080 |
| - std::vector<const clang::FileEntry*> FileEntries; |
4081 | 4076 | for (const auto& SourceFile : SourceFiles)
|
4082 | 4077 | {
|
4083 | 4078 | auto FileEntry = c->getPreprocessor().getHeaderSearchInfo().LookupFile(SourceFile,
|
4084 | 4079 | clang::SourceLocation(), /*isAngled*/true,
|
4085 | 4080 | nullptr, Dir, Includers, nullptr, nullptr, nullptr, nullptr, nullptr);
|
4086 | 4081 |
|
4087 | 4082 | if (!FileEntry)
|
4088 |
| - { |
4089 |
| - res->kind = ParserResultKind::FileNotFound; |
4090 |
| - return res; |
4091 |
| - } |
| 4083 | + return false; |
| 4084 | + |
4092 | 4085 | FileEntries.push_back(FileEntry);
|
4093 | 4086 | }
|
4094 | 4087 |
|
4095 | 4088 | // Create a virtual file that includes the header. This gets rid of some
|
4096 | 4089 | // Clang warnings about parsing an header file as the main file.
|
4097 | 4090 |
|
4098 |
| - std::string str; |
| 4091 | + std::string source; |
4099 | 4092 | for (const auto& SourceFile : SourceFiles)
|
4100 | 4093 | {
|
4101 |
| - str += "#include \"" + SourceFile + "\"" + "\n"; |
| 4094 | + source += "#include \"" + SourceFile + "\"" + "\n"; |
4102 | 4095 | }
|
4103 |
| - str += "\0"; |
| 4096 | + source += "\0"; |
4104 | 4097 |
|
4105 |
| - auto buffer = llvm::MemoryBuffer::getMemBuffer(str); |
| 4098 | + auto buffer = llvm::MemoryBuffer::getMemBufferCopy(source); |
4106 | 4099 | auto& SM = c->getSourceManager();
|
4107 | 4100 | SM.setMainFileID(SM.createFileID(std::move(buffer)));
|
4108 | 4101 |
|
4109 |
| - clang::DiagnosticConsumer* client = c->getDiagnostics().getClient(); |
4110 |
| - client->BeginSourceFile(c->getLangOpts(), &c->getPreprocessor()); |
| 4102 | + return true; |
| 4103 | +} |
4111 | 4104 |
|
4112 |
| - ParseAST(c->getSema()); |
| 4105 | +class SemaConsumer : public clang::SemaConsumer { |
| 4106 | + CppSharp::CppParser::Parser& Parser; |
| 4107 | + std::vector<const clang::FileEntry*>& FileEntries; |
| 4108 | +public: |
| 4109 | + SemaConsumer(CppSharp::CppParser::Parser& parser, |
| 4110 | + std::vector<const clang::FileEntry*>& entries) |
| 4111 | + : Parser(parser), FileEntries(entries) {} |
| 4112 | + virtual void HandleTranslationUnit(clang::ASTContext& Ctx) override; |
| 4113 | +}; |
4113 | 4114 |
|
4114 |
| - client->EndSourceFile(); |
| 4115 | +void SemaConsumer::HandleTranslationUnit(clang::ASTContext& Ctx) |
| 4116 | +{ |
| 4117 | + auto FileEntry = FileEntries[0]; |
| 4118 | + auto FileName = FileEntry->getName(); |
| 4119 | + auto Unit = Parser.opts->ASTContext->FindOrCreateModule(FileName); |
4115 | 4120 |
|
4116 |
| - HandleDiagnostics(res); |
| 4121 | + auto TU = Ctx.getTranslationUnitDecl(); |
| 4122 | + Parser.HandleDeclaration(TU, Unit); |
4117 | 4123 |
|
4118 |
| - if(client->getNumErrors() != 0) |
| 4124 | + if (Unit->originalPtr == nullptr) |
| 4125 | + Unit->originalPtr = (void*)FileEntry; |
| 4126 | + |
| 4127 | + Parser.WalkAST(TU); |
| 4128 | +} |
| 4129 | + |
| 4130 | +ParserResult* Parser::ParseHeader(const std::vector<std::string>& SourceFiles) |
| 4131 | +{ |
| 4132 | + assert(opts->ASTContext && "Expected a valid ASTContext"); |
| 4133 | + |
| 4134 | + auto res = new ParserResult(); |
| 4135 | + |
| 4136 | + if (SourceFiles.empty()) |
4119 | 4137 | {
|
4120 |
| - res->kind = ParserResultKind::Error; |
| 4138 | + res->kind = ParserResultKind::FileNotFound; |
4121 | 4139 | return res;
|
4122 | 4140 | }
|
4123 | 4141 |
|
4124 |
| - auto& AST = c->getASTContext(); |
| 4142 | + Setup(); |
| 4143 | + SetupLLVMCodegen(); |
4125 | 4144 |
|
4126 |
| - auto FileEntry = FileEntries[0]; |
4127 |
| - auto FileName = FileEntry->getName(); |
4128 |
| - auto Unit = opts->ASTContext->FindOrCreateModule(FileName); |
| 4145 | + std::vector<const clang::FileEntry*> FileEntries; |
| 4146 | + if (!SetupSourceFiles(SourceFiles, FileEntries)) |
| 4147 | + { |
| 4148 | + res->kind = ParserResultKind::FileNotFound; |
| 4149 | + return res; |
| 4150 | + } |
4129 | 4151 |
|
4130 |
| - auto TU = AST.getTranslationUnitDecl(); |
4131 |
| - HandleDeclaration(TU, Unit); |
| 4152 | + std::unique_ptr<SemaConsumer> SC(new SemaConsumer(*this, FileEntries)); |
| 4153 | + c->setASTConsumer(std::move(SC)); |
4132 | 4154 |
|
4133 |
| - if (Unit->originalPtr == nullptr) |
4134 |
| - Unit->originalPtr = (void*)FileEntry; |
| 4155 | + c->createSema(clang::TU_Complete, 0); |
4135 | 4156 |
|
4136 |
| - // Initialize enough Clang codegen machinery so we can get at ABI details. |
4137 |
| - llvm::LLVMContext Ctx; |
4138 |
| - std::unique_ptr<llvm::Module> M(new llvm::Module("", Ctx)); |
| 4157 | + auto DiagClient = new DiagnosticConsumer(); |
| 4158 | + c->getDiagnostics().setClient(DiagClient); |
4139 | 4159 |
|
4140 |
| - M->setTargetTriple(c->getTarget().getTriple().getTriple()); |
4141 |
| - M->setDataLayout(c->getTarget().getDataLayout()); |
| 4160 | + clang::DiagnosticConsumer* client = c->getDiagnostics().getClient(); |
| 4161 | + client->BeginSourceFile(c->getLangOpts(), &c->getPreprocessor()); |
4142 | 4162 |
|
4143 |
| - std::unique_ptr<clang::CodeGen::CodeGenModule> CGM( |
4144 |
| - new clang::CodeGen::CodeGenModule(c->getASTContext(), c->getHeaderSearchOpts(), |
4145 |
| - c->getPreprocessorOpts(), c->getCodeGenOpts(), *M, c->getDiagnostics())); |
| 4163 | + ParseAST(c->getSema()); |
4146 | 4164 |
|
4147 |
| - std::unique_ptr<clang::CodeGen::CodeGenTypes> CGT( |
4148 |
| - new clang::CodeGen::CodeGenTypes(*CGM.get())); |
| 4165 | + client->EndSourceFile(); |
4149 | 4166 |
|
4150 |
| - codeGenTypes = CGT.get(); |
| 4167 | + HandleDiagnostics(res); |
4151 | 4168 |
|
4152 |
| - WalkAST(); |
| 4169 | + if(client->getNumErrors() != 0) |
| 4170 | + { |
| 4171 | + res->kind = ParserResultKind::Error; |
| 4172 | + return res; |
| 4173 | + } |
4153 | 4174 |
|
4154 | 4175 | res->targetInfo = GetTargetInfo();
|
4155 | 4176 |
|
|
0 commit comments