clang  3.7.0
CodeGenAction.cpp
Go to the documentation of this file.
1 //===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CoverageMappingGen.h"
11 #include "clang/AST/ASTConsumer.h"
12 #include "clang/AST/ASTContext.h"
13 #include "clang/AST/DeclCXX.h"
14 #include "clang/AST/DeclGroup.h"
17 #include "clang/Basic/TargetInfo.h"
23 #include "clang/Lex/Preprocessor.h"
24 #include "llvm/ADT/SmallString.h"
25 #include "llvm/Bitcode/ReaderWriter.h"
26 #include "llvm/IR/DebugInfo.h"
27 #include "llvm/IR/DiagnosticInfo.h"
28 #include "llvm/IR/DiagnosticPrinter.h"
29 #include "llvm/IR/LLVMContext.h"
30 #include "llvm/IR/Module.h"
31 #include "llvm/IRReader/IRReader.h"
32 #include "llvm/Linker/Linker.h"
33 #include "llvm/Pass.h"
34 #include "llvm/Support/MemoryBuffer.h"
35 #include "llvm/Support/SourceMgr.h"
36 #include "llvm/Support/Timer.h"
37 #include <memory>
38 using namespace clang;
39 using namespace llvm;
40 
41 namespace clang {
42  class BackendConsumer : public ASTConsumer {
43  virtual void anchor();
44  DiagnosticsEngine &Diags;
46  const CodeGenOptions &CodeGenOpts;
47  const TargetOptions &TargetOpts;
48  const LangOptions &LangOpts;
49  raw_pwrite_stream *AsmOutStream;
51 
52  Timer LLVMIRGeneration;
53 
54  std::unique_ptr<CodeGenerator> Gen;
55 
56  std::unique_ptr<llvm::Module> TheModule, LinkModule;
57 
58  public:
60  const HeaderSearchOptions &HeaderSearchOpts,
61  const PreprocessorOptions &PPOpts,
62  const CodeGenOptions &CodeGenOpts,
63  const TargetOptions &TargetOpts,
64  const LangOptions &LangOpts, bool TimePasses,
65  const std::string &InFile, llvm::Module *LinkModule,
66  raw_pwrite_stream *OS, LLVMContext &C,
67  CoverageSourceInfo *CoverageInfo = nullptr)
68  : Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts),
69  TargetOpts(TargetOpts), LangOpts(LangOpts), AsmOutStream(OS),
70  Context(nullptr), LLVMIRGeneration("LLVM IR Generation Time"),
71  Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
72  CodeGenOpts, C, CoverageInfo)),
73  LinkModule(LinkModule) {
74  llvm::TimePassesIsEnabled = TimePasses;
75  }
76 
77  std::unique_ptr<llvm::Module> takeModule() { return std::move(TheModule); }
78  llvm::Module *takeLinkModule() { return LinkModule.release(); }
79 
81  Gen->HandleCXXStaticMemberVarInstantiation(VD);
82  }
83 
84  void Initialize(ASTContext &Ctx) override {
85  if (Context) {
86  assert(Context == &Ctx);
87  return;
88  }
89 
90  Context = &Ctx;
91 
92  if (llvm::TimePassesIsEnabled)
93  LLVMIRGeneration.startTimer();
94 
95  Gen->Initialize(Ctx);
96 
97  TheModule.reset(Gen->GetModule());
98 
99  if (llvm::TimePassesIsEnabled)
100  LLVMIRGeneration.stopTimer();
101  }
102 
103  bool HandleTopLevelDecl(DeclGroupRef D) override {
104  PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
106  "LLVM IR generation of declaration");
107 
108  if (llvm::TimePassesIsEnabled)
109  LLVMIRGeneration.startTimer();
110 
111  Gen->HandleTopLevelDecl(D);
112 
113  if (llvm::TimePassesIsEnabled)
114  LLVMIRGeneration.stopTimer();
115 
116  return true;
117  }
118 
120  PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
122  "LLVM IR generation of inline method");
123  if (llvm::TimePassesIsEnabled)
124  LLVMIRGeneration.startTimer();
125 
126  Gen->HandleInlineMethodDefinition(D);
127 
128  if (llvm::TimePassesIsEnabled)
129  LLVMIRGeneration.stopTimer();
130  }
131 
133  {
134  PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
135  if (llvm::TimePassesIsEnabled)
136  LLVMIRGeneration.startTimer();
137 
138  Gen->HandleTranslationUnit(C);
139 
140  if (llvm::TimePassesIsEnabled)
141  LLVMIRGeneration.stopTimer();
142  }
143 
144  // Silently ignore if we weren't initialized for some reason.
145  if (!TheModule)
146  return;
147 
148  // Make sure IR generation is happy with the module. This is released by
149  // the module provider.
150  llvm::Module *M = Gen->ReleaseModule();
151  if (!M) {
152  // The module has been released by IR gen on failures, do not double
153  // free.
154  TheModule.release();
155  return;
156  }
157 
158  assert(TheModule.get() == M &&
159  "Unexpected module change during IR generation");
160 
161  // Link LinkModule into this module if present, preserving its validity.
162  if (LinkModule) {
163  if (Linker::LinkModules(
164  M, LinkModule.get(),
165  [=](const DiagnosticInfo &DI) { linkerDiagnosticHandler(DI); }))
166  return;
167  }
168 
169  // Install an inline asm handler so that diagnostics get printed through
170  // our diagnostics hooks.
171  LLVMContext &Ctx = TheModule->getContext();
172  LLVMContext::InlineAsmDiagHandlerTy OldHandler =
173  Ctx.getInlineAsmDiagnosticHandler();
174  void *OldContext = Ctx.getInlineAsmDiagnosticContext();
175  Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this);
176 
177  LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
178  Ctx.getDiagnosticHandler();
179  void *OldDiagnosticContext = Ctx.getDiagnosticContext();
180  Ctx.setDiagnosticHandler(DiagnosticHandler, this);
181 
182  EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
184  TheModule.get(), Action, AsmOutStream);
185 
186  Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
187 
188  Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext);
189  }
190 
191  void HandleTagDeclDefinition(TagDecl *D) override {
192  PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
194  "LLVM IR generation of declaration");
195  Gen->HandleTagDeclDefinition(D);
196  }
197 
198  void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
199  Gen->HandleTagDeclRequiredDefinition(D);
200  }
201 
203  Gen->CompleteTentativeDefinition(D);
204  }
205 
206  void HandleVTable(CXXRecordDecl *RD) override {
207  Gen->HandleVTable(RD);
208  }
209 
210  void HandleLinkerOptionPragma(llvm::StringRef Opts) override {
211  Gen->HandleLinkerOptionPragma(Opts);
212  }
213 
214  void HandleDetectMismatch(llvm::StringRef Name,
215  llvm::StringRef Value) override {
216  Gen->HandleDetectMismatch(Name, Value);
217  }
218 
219  void HandleDependentLibrary(llvm::StringRef Opts) override {
220  Gen->HandleDependentLibrary(Opts);
221  }
222 
223  static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,
224  unsigned LocCookie) {
226  ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc);
227  }
228 
229  void linkerDiagnosticHandler(const llvm::DiagnosticInfo &DI);
230 
231  static void DiagnosticHandler(const llvm::DiagnosticInfo &DI,
232  void *Context) {
233  ((BackendConsumer *)Context)->DiagnosticHandlerImpl(DI);
234  }
235 
236  void InlineAsmDiagHandler2(const llvm::SMDiagnostic &,
237  SourceLocation LocCookie);
238 
239  void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI);
240  /// \brief Specialized handler for InlineAsm diagnostic.
241  /// \return True if the diagnostic has been successfully reported, false
242  /// otherwise.
243  bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D);
244  /// \brief Specialized handler for StackSize diagnostic.
245  /// \return True if the diagnostic has been successfully reported, false
246  /// otherwise.
247  bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D);
248  /// \brief Specialized handlers for optimization remarks.
249  /// Note that these handlers only accept remarks and they always handle
250  /// them.
251  void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D,
252  unsigned DiagID);
253  void
254  OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D);
255  void OptimizationRemarkHandler(
256  const llvm::DiagnosticInfoOptimizationRemarkMissed &D);
257  void OptimizationRemarkHandler(
258  const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D);
259  void OptimizationFailureHandler(
260  const llvm::DiagnosticInfoOptimizationFailure &D);
261  };
262 
263  void BackendConsumer::anchor() {}
264 }
265 
266 /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr
267 /// buffer to be a valid FullSourceLoc.
268 static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D,
269  SourceManager &CSM) {
270  // Get both the clang and llvm source managers. The location is relative to
271  // a memory buffer that the LLVM Source Manager is handling, we need to add
272  // a copy to the Clang source manager.
273  const llvm::SourceMgr &LSM = *D.getSourceMgr();
274 
275  // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr
276  // already owns its one and clang::SourceManager wants to own its one.
277  const MemoryBuffer *LBuf =
278  LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
279 
280  // Create the copy and transfer ownership to clang::SourceManager.
281  // TODO: Avoid copying files into memory.
282  std::unique_ptr<llvm::MemoryBuffer> CBuf =
283  llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(),
284  LBuf->getBufferIdentifier());
285  // FIXME: Keep a file ID map instead of creating new IDs for each location.
286  FileID FID = CSM.createFileID(std::move(CBuf));
287 
288  // Translate the offset into the file.
289  unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
290  SourceLocation NewLoc =
291  CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset);
292  return FullSourceLoc(NewLoc, CSM);
293 }
294 
295 
296 /// InlineAsmDiagHandler2 - This function is invoked when the backend hits an
297 /// error parsing inline asm. The SMDiagnostic indicates the error relative to
298 /// the temporary memory buffer that the inline asm parser has set up.
299 void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D,
300  SourceLocation LocCookie) {
301  // There are a couple of different kinds of errors we could get here. First,
302  // we re-format the SMDiagnostic in terms of a clang diagnostic.
303 
304  // Strip "error: " off the start of the message string.
305  StringRef Message = D.getMessage();
306  if (Message.startswith("error: "))
307  Message = Message.substr(7);
308 
309  // If the SMDiagnostic has an inline asm source location, translate it.
310  FullSourceLoc Loc;
311  if (D.getLoc() != SMLoc())
313 
314  unsigned DiagID;
315  switch (D.getKind()) {
316  case llvm::SourceMgr::DK_Error:
317  DiagID = diag::err_fe_inline_asm;
318  break;
319  case llvm::SourceMgr::DK_Warning:
320  DiagID = diag::warn_fe_inline_asm;
321  break;
322  case llvm::SourceMgr::DK_Note:
323  DiagID = diag::note_fe_inline_asm;
324  break;
325  }
326  // If this problem has clang-level source location information, report the
327  // issue in the source with a note showing the instantiated
328  // code.
329  if (LocCookie.isValid()) {
330  Diags.Report(LocCookie, DiagID).AddString(Message);
331 
332  if (D.getLoc().isValid()) {
333  DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here);
334  // Convert the SMDiagnostic ranges into SourceRange and attach them
335  // to the diagnostic.
336  for (unsigned i = 0, e = D.getRanges().size(); i != e; ++i) {
337  std::pair<unsigned, unsigned> Range = D.getRanges()[i];
338  unsigned Column = D.getColumnNo();
339  B << SourceRange(Loc.getLocWithOffset(Range.first - Column),
340  Loc.getLocWithOffset(Range.second - Column));
341  }
342  }
343  return;
344  }
345 
346  // Otherwise, report the backend issue as occurring in the generated .s file.
347  // If Loc is invalid, we still need to report the issue, it just gets no
348  // location info.
349  Diags.Report(Loc, DiagID).AddString(Message);
350 }
351 
352 #define ComputeDiagID(Severity, GroupName, DiagID) \
353  do { \
354  switch (Severity) { \
355  case llvm::DS_Error: \
356  DiagID = diag::err_fe_##GroupName; \
357  break; \
358  case llvm::DS_Warning: \
359  DiagID = diag::warn_fe_##GroupName; \
360  break; \
361  case llvm::DS_Remark: \
362  llvm_unreachable("'remark' severity not expected"); \
363  break; \
364  case llvm::DS_Note: \
365  DiagID = diag::note_fe_##GroupName; \
366  break; \
367  } \
368  } while (false)
369 
370 #define ComputeDiagRemarkID(Severity, GroupName, DiagID) \
371  do { \
372  switch (Severity) { \
373  case llvm::DS_Error: \
374  DiagID = diag::err_fe_##GroupName; \
375  break; \
376  case llvm::DS_Warning: \
377  DiagID = diag::warn_fe_##GroupName; \
378  break; \
379  case llvm::DS_Remark: \
380  DiagID = diag::remark_fe_##GroupName; \
381  break; \
382  case llvm::DS_Note: \
383  DiagID = diag::note_fe_##GroupName; \
384  break; \
385  } \
386  } while (false)
387 
388 bool
389 BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) {
390  unsigned DiagID;
391  ComputeDiagID(D.getSeverity(), inline_asm, DiagID);
392  std::string Message = D.getMsgStr().str();
393 
394  // If this problem has clang-level source location information, report the
395  // issue as being a problem in the source with a note showing the instantiated
396  // code.
397  SourceLocation LocCookie =
398  SourceLocation::getFromRawEncoding(D.getLocCookie());
399  if (LocCookie.isValid())
400  Diags.Report(LocCookie, DiagID).AddString(Message);
401  else {
402  // Otherwise, report the backend diagnostic as occurring in the generated
403  // .s file.
404  // If Loc is invalid, we still need to report the diagnostic, it just gets
405  // no location info.
406  FullSourceLoc Loc;
407  Diags.Report(Loc, DiagID).AddString(Message);
408  }
409  // We handled all the possible severities.
410  return true;
411 }
412 
413 bool
414 BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) {
415  if (D.getSeverity() != llvm::DS_Warning)
416  // For now, the only support we have for StackSize diagnostic is warning.
417  // We do not know how to format other severities.
418  return false;
419 
420  if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) {
421  Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()),
422  diag::warn_fe_frame_larger_than)
423  << D.getStackSize() << Decl::castToDeclContext(ND);
424  return true;
425  }
426 
427  return false;
428 }
429 
431  const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) {
432  // We only support warnings and remarks.
433  assert(D.getSeverity() == llvm::DS_Remark ||
434  D.getSeverity() == llvm::DS_Warning);
435 
437  FileManager &FileMgr = SourceMgr.getFileManager();
438  StringRef Filename;
439  unsigned Line, Column;
440  SourceLocation DILoc;
441 
442  if (D.isLocationAvailable()) {
443  D.getLocation(&Filename, &Line, &Column);
444  const FileEntry *FE = FileMgr.getFile(Filename);
445  if (FE && Line > 0) {
446  // If -gcolumn-info was not used, Column will be 0. This upsets the
447  // source manager, so pass 1 if Column is not set.
448  DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1);
449  }
450  }
451 
452  // If a location isn't available, try to approximate it using the associated
453  // function definition. We use the definition's right brace to differentiate
454  // from diagnostics that genuinely relate to the function itself.
455  FullSourceLoc Loc(DILoc, SourceMgr);
456  if (Loc.isInvalid())
457  if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName()))
458  Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace());
459 
460  Diags.Report(Loc, DiagID)
461  << AddFlagValue(D.getPassName() ? D.getPassName() : "")
462  << D.getMsg().str();
463 
464  if (DILoc.isInvalid() && D.isLocationAvailable())
465  // If we were not able to translate the file:line:col information
466  // back to a SourceLocation, at least emit a note stating that
467  // we could not translate this location. This can happen in the
468  // case of #line directives.
469  Diags.Report(Loc, diag::note_fe_backend_optimization_remark_invalid_loc)
470  << Filename << Line << Column;
471 }
472 
474  const llvm::DiagnosticInfoOptimizationRemark &D) {
475  // Optimization remarks are active only if the -Rpass flag has a regular
476  // expression that matches the name of the pass name in \p D.
477  if (CodeGenOpts.OptimizationRemarkPattern &&
478  CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName()))
479  EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark);
480 }
481 
483  const llvm::DiagnosticInfoOptimizationRemarkMissed &D) {
484  // Missed optimization remarks are active only if the -Rpass-missed
485  // flag has a regular expression that matches the name of the pass
486  // name in \p D.
487  if (CodeGenOpts.OptimizationRemarkMissedPattern &&
488  CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName()))
489  EmitOptimizationMessage(D,
490  diag::remark_fe_backend_optimization_remark_missed);
491 }
492 
494  const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D) {
495  // Optimization analysis remarks are active only if the -Rpass-analysis
496  // flag has a regular expression that matches the name of the pass
497  // name in \p D.
498  if (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
499  CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName()))
500  EmitOptimizationMessage(
501  D, diag::remark_fe_backend_optimization_remark_analysis);
502 }
503 
505  const llvm::DiagnosticInfoOptimizationFailure &D) {
506  EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure);
507 }
508 
509 void BackendConsumer::linkerDiagnosticHandler(const DiagnosticInfo &DI) {
510  if (DI.getSeverity() != DS_Error)
511  return;
512 
513  std::string MsgStorage;
514  {
515  raw_string_ostream Stream(MsgStorage);
516  DiagnosticPrinterRawOStream DP(Stream);
517  DI.print(DP);
518  }
519 
520  Diags.Report(diag::err_fe_cannot_link_module)
521  << LinkModule->getModuleIdentifier() << MsgStorage;
522 }
523 
524 /// \brief This function is invoked when the backend needs
525 /// to report something to the user.
526 void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
527  unsigned DiagID = diag::err_fe_inline_asm;
528  llvm::DiagnosticSeverity Severity = DI.getSeverity();
529  // Get the diagnostic ID based.
530  switch (DI.getKind()) {
531  case llvm::DK_InlineAsm:
532  if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI)))
533  return;
534  ComputeDiagID(Severity, inline_asm, DiagID);
535  break;
536  case llvm::DK_StackSize:
537  if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI)))
538  return;
539  ComputeDiagID(Severity, backend_frame_larger_than, DiagID);
540  break;
541  case llvm::DK_OptimizationRemark:
542  // Optimization remarks are always handled completely by this
543  // handler. There is no generic way of emitting them.
544  OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemark>(DI));
545  return;
546  case llvm::DK_OptimizationRemarkMissed:
547  // Optimization remarks are always handled completely by this
548  // handler. There is no generic way of emitting them.
549  OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemarkMissed>(DI));
550  return;
551  case llvm::DK_OptimizationRemarkAnalysis:
552  // Optimization remarks are always handled completely by this
553  // handler. There is no generic way of emitting them.
554  OptimizationRemarkHandler(
555  cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI));
556  return;
557  case llvm::DK_OptimizationFailure:
558  // Optimization failures are always handled completely by this
559  // handler.
560  OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI));
561  return;
562  default:
563  // Plugin IDs are not bound to any value as they are set dynamically.
564  ComputeDiagRemarkID(Severity, backend_plugin, DiagID);
565  break;
566  }
567  std::string MsgStorage;
568  {
569  raw_string_ostream Stream(MsgStorage);
570  DiagnosticPrinterRawOStream DP(Stream);
571  DI.print(DP);
572  }
573 
574  // Report the backend message using the usual diagnostic mechanism.
575  FullSourceLoc Loc;
576  Diags.Report(Loc, DiagID).AddString(MsgStorage);
577 }
578 #undef ComputeDiagID
579 
580 CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext)
581  : Act(_Act), LinkModule(nullptr),
582  VMContext(_VMContext ? _VMContext : new LLVMContext),
583  OwnsVMContext(!_VMContext) {}
584 
586  TheModule.reset();
587  if (OwnsVMContext)
588  delete VMContext;
589 }
590 
591 bool CodeGenAction::hasIRSupport() const { return true; }
592 
594  // If the consumer creation failed, do nothing.
595  if (!getCompilerInstance().hasASTConsumer())
596  return;
597 
598  // If we were given a link module, release consumer's ownership of it.
599  if (LinkModule)
601 
602  // Steal the module from the consumer.
603  TheModule = BEConsumer->takeModule();
604 }
605 
606 std::unique_ptr<llvm::Module> CodeGenAction::takeModule() {
607  return std::move(TheModule);
608 }
609 
610 llvm::LLVMContext *CodeGenAction::takeLLVMContext() {
611  OwnsVMContext = false;
612  return VMContext;
613 }
614 
615 static raw_pwrite_stream *
617  switch (Action) {
619  return CI.createDefaultOutputFile(false, InFile, "s");
620  case Backend_EmitLL:
621  return CI.createDefaultOutputFile(false, InFile, "ll");
622  case Backend_EmitBC:
623  return CI.createDefaultOutputFile(true, InFile, "bc");
624  case Backend_EmitNothing:
625  return nullptr;
626  case Backend_EmitMCNull:
627  return CI.createNullOutputFile();
628  case Backend_EmitObj:
629  return CI.createDefaultOutputFile(true, InFile, "o");
630  }
631 
632  llvm_unreachable("Invalid action!");
633 }
634 
635 std::unique_ptr<ASTConsumer>
637  BackendAction BA = static_cast<BackendAction>(Act);
638  raw_pwrite_stream *OS = GetOutputStream(CI, InFile, BA);
639  if (BA != Backend_EmitNothing && !OS)
640  return nullptr;
641 
642  llvm::Module *LinkModuleToUse = LinkModule;
643 
644  // If we were not given a link module, and the user requested that one be
645  // loaded from bitcode, do so now.
646  const std::string &LinkBCFile = CI.getCodeGenOpts().LinkBitcodeFile;
647  if (!LinkModuleToUse && !LinkBCFile.empty()) {
648  auto BCBuf = CI.getFileManager().getBufferForFile(LinkBCFile);
649  if (!BCBuf) {
650  CI.getDiagnostics().Report(diag::err_cannot_open_file)
651  << LinkBCFile << BCBuf.getError().message();
652  return nullptr;
653  }
654 
655  ErrorOr<std::unique_ptr<llvm::Module>> ModuleOrErr =
656  getLazyBitcodeModule(std::move(*BCBuf), *VMContext);
657  if (std::error_code EC = ModuleOrErr.getError()) {
658  CI.getDiagnostics().Report(diag::err_cannot_open_file)
659  << LinkBCFile << EC.message();
660  return nullptr;
661  }
662  LinkModuleToUse = ModuleOrErr.get().release();
663  }
664 
665  CoverageSourceInfo *CoverageInfo = nullptr;
666  // Add the preprocessor callback only when the coverage mapping is generated.
667  if (CI.getCodeGenOpts().CoverageMapping) {
668  CoverageInfo = new CoverageSourceInfo;
670  std::unique_ptr<PPCallbacks>(CoverageInfo));
671  }
672  std::unique_ptr<BackendConsumer> Result(new BackendConsumer(
673  BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
675  CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile,
676  LinkModuleToUse, OS, *VMContext, CoverageInfo));
677  BEConsumer = Result.get();
678  return std::move(Result);
679 }
680 
681 static void BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic &SM,
682  void *Context,
683  unsigned LocCookie) {
684  SM.print(nullptr, llvm::errs());
685 }
686 
688  // If this is an IR file, we have to treat it specially.
689  if (getCurrentFileKind() == IK_LLVM_IR) {
690  BackendAction BA = static_cast<BackendAction>(Act);
692  raw_pwrite_stream *OS = GetOutputStream(CI, getCurrentFile(), BA);
693  if (BA != Backend_EmitNothing && !OS)
694  return;
695 
696  bool Invalid;
698  FileID FID = SM.getMainFileID();
699  llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid);
700  if (Invalid)
701  return;
702 
703  llvm::SMDiagnostic Err;
704  TheModule = parseIR(MainFile->getMemBufferRef(), Err, *VMContext);
705  if (!TheModule) {
706  // Translate from the diagnostic info to the SourceManager location if
707  // available.
708  // TODO: Unify this with ConvertBackendLocation()
709  SourceLocation Loc;
710  if (Err.getLineNo() > 0) {
711  assert(Err.getColumnNo() >= 0);
712  Loc = SM.translateFileLineCol(SM.getFileEntryForID(FID),
713  Err.getLineNo(), Err.getColumnNo() + 1);
714  }
715 
716  // Strip off a leading diagnostic code if there is one.
717  StringRef Msg = Err.getMessage();
718  if (Msg.startswith("error: "))
719  Msg = Msg.substr(7);
720 
721  unsigned DiagID =
723 
724  CI.getDiagnostics().Report(Loc, DiagID) << Msg;
725  return;
726  }
727  const TargetOptions &TargetOpts = CI.getTargetOpts();
728  if (TheModule->getTargetTriple() != TargetOpts.Triple) {
730  diag::warn_fe_override_module)
731  << TargetOpts.Triple;
732  TheModule->setTargetTriple(TargetOpts.Triple);
733  }
734 
735  LLVMContext &Ctx = TheModule->getContext();
736  Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler);
737  EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts,
739  TheModule.get(), BA, OS);
740  return;
741  }
742 
743  // Otherwise follow the normal AST path.
745 }
746 
747 //
748 
749 void EmitAssemblyAction::anchor() { }
750 EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext)
751  : CodeGenAction(Backend_EmitAssembly, _VMContext) {}
752 
753 void EmitBCAction::anchor() { }
754 EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext)
755  : CodeGenAction(Backend_EmitBC, _VMContext) {}
756 
757 void EmitLLVMAction::anchor() { }
758 EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext)
759  : CodeGenAction(Backend_EmitLL, _VMContext) {}
760 
761 void EmitLLVMOnlyAction::anchor() { }
762 EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext)
763  : CodeGenAction(Backend_EmitNothing, _VMContext) {}
764 
765 void EmitCodeGenOnlyAction::anchor() { }
766 EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext)
767  : CodeGenAction(Backend_EmitMCNull, _VMContext) {}
768 
769 void EmitObjAction::anchor() { }
770 EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext)
771  : CodeGenAction(Backend_EmitObj, _VMContext) {}
void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID)
Specialized handlers for optimization remarks. Note that these handlers only accept remarks and they ...
Defines the clang::ASTContext interface.
LangOptions & getLangOpts()
void HandleInlineMethodDefinition(CXXMethodDecl *D) override
This callback is invoked each time an inline method definition is completed.
PreprocessorOptions & getPreprocessorOpts()
static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM, void *Context, unsigned LocCookie)
static DeclContext * castToDeclContext(const Decl *)
Definition: DeclBase.cpp:674
llvm::Module * takeLinkModule()
Implements support for file system lookup, file system caching, and directory search management...
Definition: FileManager.h:115
bool hasIRSupport() const override
Does this action support use with IR files?
Defines the clang::FileManager interface and associated types.
Emit human-readable LLVM assembly.
Definition: BackendUtil.h:28
Run CodeGen, but don't emit anything.
Definition: BackendUtil.h:30
void EndSourceFileAction() override
Callback at the end of processing a single input.
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer...
Defines the SourceManager interface.
CompilerInstance & getCompilerInstance() const
bool HandleTopLevelDecl(DeclGroupRef D) override
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
Stores additional source code information like skipped ranges which is required by the coverage mappi...
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1118
void HandleTagDeclRequiredDefinition(const TagDecl *D) override
This callback is invoked the first time each TagDecl is required to be complete.
std::unique_ptr< llvm::Module > takeModule()
TargetInfo & getTarget() const
Don't emit anything (benchmarking mode)
Definition: BackendUtil.h:29
SourceManager & getSourceManager() const
Return the current source manager.
Options for controlling the target.
Definition: TargetOptions.h:24
void HandleTagDeclDefinition(TagDecl *D) override
InputKind getCurrentFileKind() const
static raw_pwrite_stream * GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action)
bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D)
Specialized handler for StackSize diagnostic.
#define ComputeDiagRemarkID(Severity, GroupName, DiagID)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:89
Emit LLVM bitcode files.
Definition: BackendUtil.h:27
static SourceLocation getFromRawEncoding(unsigned Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
void OptimizationFailureHandler(const llvm::DiagnosticInfoOptimizationFailure &D)
FrontendAction * Action
Definition: Tooling.cpp:168
void CompleteTentativeDefinition(VarDecl *D) override
CodeGenOptions & getCodeGenOpts()
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
BackendAction
Definition: BackendUtil.h:25
void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, StringRef TDesc, llvm::Module *M, BackendAction Action, raw_pwrite_stream *OS)
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:518
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
FrontendOptions & getFrontendOpts()
uint32_t Offset
Definition: CacheTokens.cpp:43
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:135
BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags, const HeaderSearchOptions &HeaderSearchOpts, const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, const TargetOptions &TargetOpts, const LangOptions &LangOpts, bool TimePasses, const std::string &InFile, llvm::Module *LinkModule, raw_pwrite_stream *OS, LLVMContext &C, CoverageSourceInfo *CoverageInfo=nullptr)
iterator begin()
Definition: DeclGroup.h:103
void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI)
This function is invoked when the backend needs to report something to the user.
void OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D)
static void DiagnosticHandler(const llvm::DiagnosticInfo &DI, void *Context)
static void BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic &SM, void *Context, unsigned LocCookie)
HeaderSearchOptions & getHeaderSearchOpts()
SourceLocation translateFileLineCol(const FileEntry *SourceFile, unsigned Line, unsigned Col) const
Get the source location for the given file:line:col triplet.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
bool isInvalid() const
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:866
BackendConsumer * BEConsumer
Definition: CodeGenAction.h:62
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
ASTContext * Context
EmitLLVMAction(llvm::LLVMContext *_VMContext=nullptr)
SourceManager & SM
CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext=nullptr)
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, unsigned LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
SourceManager & SourceMgr
Definition: Format.cpp:1205
Defines the clang::Preprocessor interface.
Emit native object files.
Definition: BackendUtil.h:31
EmitObjAction(llvm::LLVMContext *_VMContext=nullptr)
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
The result type of a method or function.
EmitBCAction(llvm::LLVMContext *_VMContext=nullptr)
static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D, SourceManager &CSM)
Emit native assembly files.
Definition: BackendUtil.h:26
EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext=nullptr)
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
AnnotatedLine & Line
bool isValid() const
Return true if this is a valid SourceLocation object.
TagDecl - Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:2694
const StringRef getCurrentFile() const
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:53
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1717
const char * getTargetDescription() const
void HandleLinkerOptionPragma(llvm::StringRef Opts) override
Handle a pragma that appends to Linker Options. Currently this only exists to support Microsoft's #pr...
std::string LinkBitcodeFile
The name of the bitcode file to link before optzns.
#define ComputeDiagID(Severity, GroupName, DiagID)
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:602
FileID getMainFileID() const
Returns the FileID of the main source file.
EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext=nullptr)
std::unique_ptr< llvm::Module > takeModule()
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
llvm::raw_null_ostream * createNullOutputFile()
FileManager & getFileManager() const
Return the current file manager to the caller.
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const FileEntry *Entry, bool isVolatile=false, bool ShouldCloseOpenFile=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
void HandleDependentLibrary(llvm::StringRef Opts) override
Handle a dependent library created by a pragma in the source. Currently this only exists to support M...
void InlineAsmDiagHandler2(const llvm::SMDiagnostic &, SourceLocation LocCookie)
void linkerDiagnosticHandler(const llvm::DiagnosticInfo &DI)
void HandleVTable(CXXRecordDecl *RD) override
Callback involved at the end of a translation unit to notify the consumer that a vtable for the given...
void Initialize(ASTContext &Ctx) override
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
SourceManager & getSourceManager()
Definition: ASTContext.h:494
raw_pwrite_stream * createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="")
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
EmitAssemblyAction(llvm::LLVMContext *_VMContext=nullptr)
Represents a C++ struct/union/class.
Definition: DeclCXX.h:285
llvm::LLVMContext * takeLLVMContext()
Take the LLVM context used by this action.
CodeGenerator * CreateLLVMCodeGen(DiagnosticsEngine &Diags, const std::string &ModuleName, const HeaderSearchOptions &HeaderSearchOpts, const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO, llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo=nullptr)
void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override
HandleCXXStaticMemberVarInstantiation - Tell the consumer that this.
Defines the clang::TargetInfo interface.
A SourceLocation and its associated SourceManager.
void HandleTranslationUnit(ASTContext &C) override
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
A trivial tuple used to represent a source range.
TargetOptions & getTargetOpts()
void HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) override
Handle a pragma that emits a mismatch identifier and value to the object file for the linker to work ...
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
Definition: Preprocessor.h:773
This class handles loading and caching of source files into memory.
unsigned Column
Definition: Format.cpp:1202