Bug Summary

File:tools/clang/lib/CodeGen/CodeGenAction.cpp
Warning:line 574, column 5
2nd function call argument is an uninitialized value

Annotated Source Code

/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp

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 "clang/CodeGen/CodeGenAction.h"
11#include "CodeGenModule.h"
12#include "CoverageMappingGen.h"
13#include "MacroPPCallbacks.h"
14#include "clang/AST/ASTConsumer.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/DeclCXX.h"
17#include "clang/AST/DeclGroup.h"
18#include "clang/Basic/FileManager.h"
19#include "clang/Basic/SourceManager.h"
20#include "clang/Basic/TargetInfo.h"
21#include "clang/CodeGen/BackendUtil.h"
22#include "clang/CodeGen/ModuleBuilder.h"
23#include "clang/Frontend/CompilerInstance.h"
24#include "clang/Frontend/FrontendDiagnostic.h"
25#include "clang/Lex/Preprocessor.h"
26#include "llvm/Bitcode/BitcodeReader.h"
27#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
28#include "llvm/IR/DebugInfo.h"
29#include "llvm/IR/DiagnosticInfo.h"
30#include "llvm/IR/DiagnosticPrinter.h"
31#include "llvm/IR/GlobalValue.h"
32#include "llvm/IR/LLVMContext.h"
33#include "llvm/IR/Module.h"
34#include "llvm/IRReader/IRReader.h"
35#include "llvm/Linker/Linker.h"
36#include "llvm/Pass.h"
37#include "llvm/Support/MemoryBuffer.h"
38#include "llvm/Support/SourceMgr.h"
39#include "llvm/Support/Timer.h"
40#include "llvm/Support/ToolOutputFile.h"
41#include "llvm/Support/YAMLTraits.h"
42#include "llvm/Transforms/IPO/Internalize.h"
43
44#include <memory>
45using namespace clang;
46using namespace llvm;
47
48namespace clang {
49 class BackendConsumer;
50 class ClangDiagnosticHandler final : public DiagnosticHandler {
51 public:
52 ClangDiagnosticHandler(const CodeGenOptions &CGOpts, BackendConsumer *BCon)
53 : CodeGenOpts(CGOpts), BackendCon(BCon) {}
54
55 bool handleDiagnostics(const DiagnosticInfo &DI) override;
56
57 bool isAnalysisRemarkEnabled(StringRef PassName) const override {
58 return (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
59 CodeGenOpts.OptimizationRemarkAnalysisPattern->match(PassName));
60 }
61 bool isMissedOptRemarkEnabled(StringRef PassName) const override {
62 return (CodeGenOpts.OptimizationRemarkMissedPattern &&
63 CodeGenOpts.OptimizationRemarkMissedPattern->match(PassName));
64 }
65 bool isPassedOptRemarkEnabled(StringRef PassName) const override {
66 return (CodeGenOpts.OptimizationRemarkPattern &&
67 CodeGenOpts.OptimizationRemarkPattern->match(PassName));
68 }
69
70 bool isAnyRemarkEnabled() const override {
71 return (CodeGenOpts.OptimizationRemarkAnalysisPattern ||
72 CodeGenOpts.OptimizationRemarkMissedPattern ||
73 CodeGenOpts.OptimizationRemarkPattern);
74 }
75
76 private:
77 const CodeGenOptions &CodeGenOpts;
78 BackendConsumer *BackendCon;
79 };
80
81 class BackendConsumer : public ASTConsumer {
82 using LinkModule = CodeGenAction::LinkModule;
83
84 virtual void anchor();
85 DiagnosticsEngine &Diags;
86 BackendAction Action;
87 const HeaderSearchOptions &HeaderSearchOpts;
88 const CodeGenOptions &CodeGenOpts;
89 const TargetOptions &TargetOpts;
90 const LangOptions &LangOpts;
91 std::unique_ptr<raw_pwrite_stream> AsmOutStream;
92 ASTContext *Context;
93
94 Timer LLVMIRGeneration;
95 unsigned LLVMIRGenerationRefCount;
96
97 /// True if we've finished generating IR. This prevents us from generating
98 /// additional LLVM IR after emitting output in HandleTranslationUnit. This
99 /// can happen when Clang plugins trigger additional AST deserialization.
100 bool IRGenFinished = false;
101
102 std::unique_ptr<CodeGenerator> Gen;
103
104 SmallVector<LinkModule, 4> LinkModules;
105
106 // This is here so that the diagnostic printer knows the module a diagnostic
107 // refers to.
108 llvm::Module *CurLinkModule = nullptr;
109
110 public:
111 BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
112 const HeaderSearchOptions &HeaderSearchOpts,
113 const PreprocessorOptions &PPOpts,
114 const CodeGenOptions &CodeGenOpts,
115 const TargetOptions &TargetOpts,
116 const LangOptions &LangOpts, bool TimePasses,
117 const std::string &InFile,
118 SmallVector<LinkModule, 4> LinkModules,
119 std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C,
120 CoverageSourceInfo *CoverageInfo = nullptr)
121 : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
122 CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
123 AsmOutStream(std::move(OS)), Context(nullptr),
124 LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
125 LLVMIRGenerationRefCount(0),
126 Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
127 CodeGenOpts, C, CoverageInfo)),
128 LinkModules(std::move(LinkModules)) {
129 llvm::TimePassesIsEnabled = TimePasses;
130 }
131 llvm::Module *getModule() const { return Gen->GetModule(); }
132 std::unique_ptr<llvm::Module> takeModule() {
133 return std::unique_ptr<llvm::Module>(Gen->ReleaseModule());
134 }
135
136 CodeGenerator *getCodeGenerator() { return Gen.get(); }
137
138 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
139 Gen->HandleCXXStaticMemberVarInstantiation(VD);
140 }
141
142 void Initialize(ASTContext &Ctx) override {
143 assert(!Context && "initialized multiple times")(static_cast <bool> (!Context && "initialized multiple times"
) ? void (0) : __assert_fail ("!Context && \"initialized multiple times\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 143, __extension__ __PRETTY_FUNCTION__))
;
144
145 Context = &Ctx;
146
147 if (llvm::TimePassesIsEnabled)
148 LLVMIRGeneration.startTimer();
149
150 Gen->Initialize(Ctx);
151
152 if (llvm::TimePassesIsEnabled)
153 LLVMIRGeneration.stopTimer();
154 }
155
156 bool HandleTopLevelDecl(DeclGroupRef D) override {
157 PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
158 Context->getSourceManager(),
159 "LLVM IR generation of declaration");
160
161 // Recurse.
162 if (llvm::TimePassesIsEnabled) {
163 LLVMIRGenerationRefCount += 1;
164 if (LLVMIRGenerationRefCount == 1)
165 LLVMIRGeneration.startTimer();
166 }
167
168 Gen->HandleTopLevelDecl(D);
169
170 if (llvm::TimePassesIsEnabled) {
171 LLVMIRGenerationRefCount -= 1;
172 if (LLVMIRGenerationRefCount == 0)
173 LLVMIRGeneration.stopTimer();
174 }
175
176 return true;
177 }
178
179 void HandleInlineFunctionDefinition(FunctionDecl *D) override {
180 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
181 Context->getSourceManager(),
182 "LLVM IR generation of inline function");
183 if (llvm::TimePassesIsEnabled)
184 LLVMIRGeneration.startTimer();
185
186 Gen->HandleInlineFunctionDefinition(D);
187
188 if (llvm::TimePassesIsEnabled)
189 LLVMIRGeneration.stopTimer();
190 }
191
192 void HandleInterestingDecl(DeclGroupRef D) override {
193 // Ignore interesting decls from the AST reader after IRGen is finished.
194 if (!IRGenFinished)
195 HandleTopLevelDecl(D);
196 }
197
198 // Links each entry in LinkModules into our module. Returns true on error.
199 bool LinkInModules() {
200 for (auto &LM : LinkModules) {
201 if (LM.PropagateAttrs)
202 for (Function &F : *LM.Module)
203 Gen->CGM().AddDefaultFnAttrs(F);
204
205 CurLinkModule = LM.Module.get();
206
207 bool Err;
208 if (LM.Internalize) {
209 Err = Linker::linkModules(
210 *getModule(), std::move(LM.Module), LM.LinkFlags,
211 [](llvm::Module &M, const llvm::StringSet<> &GVS) {
212 internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) {
213 return !GV.hasName() || (GVS.count(GV.getName()) == 0);
214 });
215 });
216 } else {
217 Err = Linker::linkModules(*getModule(), std::move(LM.Module),
218 LM.LinkFlags);
219 }
220
221 if (Err)
222 return true;
223 }
224 return false; // success
225 }
226
227 void HandleTranslationUnit(ASTContext &C) override {
228 {
229 PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
230 if (llvm::TimePassesIsEnabled) {
231 LLVMIRGenerationRefCount += 1;
232 if (LLVMIRGenerationRefCount == 1)
233 LLVMIRGeneration.startTimer();
234 }
235
236 Gen->HandleTranslationUnit(C);
237
238 if (llvm::TimePassesIsEnabled) {
239 LLVMIRGenerationRefCount -= 1;
240 if (LLVMIRGenerationRefCount == 0)
241 LLVMIRGeneration.stopTimer();
242 }
243
244 IRGenFinished = true;
245 }
246
247 // Silently ignore if we weren't initialized for some reason.
248 if (!getModule())
249 return;
250
251 // Install an inline asm handler so that diagnostics get printed through
252 // our diagnostics hooks.
253 LLVMContext &Ctx = getModule()->getContext();
254 LLVMContext::InlineAsmDiagHandlerTy OldHandler =
255 Ctx.getInlineAsmDiagnosticHandler();
256 void *OldContext = Ctx.getInlineAsmDiagnosticContext();
257 Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this);
258
259 std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler =
260 Ctx.getDiagnosticHandler();
261 Ctx.setDiagnosticHandler(llvm::make_unique<ClangDiagnosticHandler>(
262 CodeGenOpts, this));
263 Ctx.setDiagnosticsHotnessRequested(CodeGenOpts.DiagnosticsWithHotness);
264 if (CodeGenOpts.DiagnosticsHotnessThreshold != 0)
265 Ctx.setDiagnosticsHotnessThreshold(
266 CodeGenOpts.DiagnosticsHotnessThreshold);
267
268 std::unique_ptr<llvm::ToolOutputFile> OptRecordFile;
269 if (!CodeGenOpts.OptRecordFile.empty()) {
270 std::error_code EC;
271 OptRecordFile = llvm::make_unique<llvm::ToolOutputFile>(
272 CodeGenOpts.OptRecordFile, EC, sys::fs::F_None);
273 if (EC) {
274 Diags.Report(diag::err_cannot_open_file) <<
275 CodeGenOpts.OptRecordFile << EC.message();
276 return;
277 }
278
279 Ctx.setDiagnosticsOutputFile(
280 llvm::make_unique<yaml::Output>(OptRecordFile->os()));
281
282 if (CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone)
283 Ctx.setDiagnosticsHotnessRequested(true);
284 }
285
286 // Link each LinkModule into our module.
287 if (LinkInModules())
288 return;
289
290 EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef());
291
292 EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
293 LangOpts, C.getTargetInfo().getDataLayout(),
294 getModule(), Action, std::move(AsmOutStream));
295
296 Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
297
298 Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
299
300 if (OptRecordFile)
301 OptRecordFile->keep();
302 }
303
304 void HandleTagDeclDefinition(TagDecl *D) override {
305 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
306 Context->getSourceManager(),
307 "LLVM IR generation of declaration");
308 Gen->HandleTagDeclDefinition(D);
309 }
310
311 void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
312 Gen->HandleTagDeclRequiredDefinition(D);
313 }
314
315 void CompleteTentativeDefinition(VarDecl *D) override {
316 Gen->CompleteTentativeDefinition(D);
317 }
318
319 void AssignInheritanceModel(CXXRecordDecl *RD) override {
320 Gen->AssignInheritanceModel(RD);
321 }
322
323 void HandleVTable(CXXRecordDecl *RD) override {
324 Gen->HandleVTable(RD);
325 }
326
327 static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,
328 unsigned LocCookie) {
329 SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie);
330 ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc);
331 }
332
333 /// Get the best possible source location to represent a diagnostic that
334 /// may have associated debug info.
335 const FullSourceLoc
336 getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithLocationBase &D,
337 bool &BadDebugInfo, StringRef &Filename,
338 unsigned &Line, unsigned &Column) const;
339
340 void InlineAsmDiagHandler2(const llvm::SMDiagnostic &,
341 SourceLocation LocCookie);
342
343 void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI);
344 /// \brief Specialized handler for InlineAsm diagnostic.
345 /// \return True if the diagnostic has been successfully reported, false
346 /// otherwise.
347 bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D);
348 /// \brief Specialized handler for StackSize diagnostic.
349 /// \return True if the diagnostic has been successfully reported, false
350 /// otherwise.
351 bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D);
352 /// \brief Specialized handler for unsupported backend feature diagnostic.
353 void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D);
354 /// \brief Specialized handlers for optimization remarks.
355 /// Note that these handlers only accept remarks and they always handle
356 /// them.
357 void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D,
358 unsigned DiagID);
359 void
360 OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D);
361 void OptimizationRemarkHandler(
362 const llvm::OptimizationRemarkAnalysisFPCommute &D);
363 void OptimizationRemarkHandler(
364 const llvm::OptimizationRemarkAnalysisAliasing &D);
365 void OptimizationFailureHandler(
366 const llvm::DiagnosticInfoOptimizationFailure &D);
367 };
368
369 void BackendConsumer::anchor() {}
370}
371
372bool ClangDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) {
373 BackendCon->DiagnosticHandlerImpl(DI);
1
Calling 'BackendConsumer::DiagnosticHandlerImpl'
374 return true;
375}
376
377/// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr
378/// buffer to be a valid FullSourceLoc.
379static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D,
380 SourceManager &CSM) {
381 // Get both the clang and llvm source managers. The location is relative to
382 // a memory buffer that the LLVM Source Manager is handling, we need to add
383 // a copy to the Clang source manager.
384 const llvm::SourceMgr &LSM = *D.getSourceMgr();
385
386 // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr
387 // already owns its one and clang::SourceManager wants to own its one.
388 const MemoryBuffer *LBuf =
389 LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
390
391 // Create the copy and transfer ownership to clang::SourceManager.
392 // TODO: Avoid copying files into memory.
393 std::unique_ptr<llvm::MemoryBuffer> CBuf =
394 llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(),
395 LBuf->getBufferIdentifier());
396 // FIXME: Keep a file ID map instead of creating new IDs for each location.
397 FileID FID = CSM.createFileID(std::move(CBuf));
398
399 // Translate the offset into the file.
400 unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
401 SourceLocation NewLoc =
402 CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset);
403 return FullSourceLoc(NewLoc, CSM);
404}
405
406
407/// InlineAsmDiagHandler2 - This function is invoked when the backend hits an
408/// error parsing inline asm. The SMDiagnostic indicates the error relative to
409/// the temporary memory buffer that the inline asm parser has set up.
410void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D,
411 SourceLocation LocCookie) {
412 // There are a couple of different kinds of errors we could get here. First,
413 // we re-format the SMDiagnostic in terms of a clang diagnostic.
414
415 // Strip "error: " off the start of the message string.
416 StringRef Message = D.getMessage();
417 if (Message.startswith("error: "))
418 Message = Message.substr(7);
419
420 // If the SMDiagnostic has an inline asm source location, translate it.
421 FullSourceLoc Loc;
422 if (D.getLoc() != SMLoc())
423 Loc = ConvertBackendLocation(D, Context->getSourceManager());
424
425 unsigned DiagID;
426 switch (D.getKind()) {
427 case llvm::SourceMgr::DK_Error:
428 DiagID = diag::err_fe_inline_asm;
429 break;
430 case llvm::SourceMgr::DK_Warning:
431 DiagID = diag::warn_fe_inline_asm;
432 break;
433 case llvm::SourceMgr::DK_Note:
434 DiagID = diag::note_fe_inline_asm;
435 break;
436 case llvm::SourceMgr::DK_Remark:
437 llvm_unreachable("remarks unexpected")::llvm::llvm_unreachable_internal("remarks unexpected", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 437)
;
438 }
439 // If this problem has clang-level source location information, report the
440 // issue in the source with a note showing the instantiated
441 // code.
442 if (LocCookie.isValid()) {
443 Diags.Report(LocCookie, DiagID).AddString(Message);
444
445 if (D.getLoc().isValid()) {
446 DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here);
447 // Convert the SMDiagnostic ranges into SourceRange and attach them
448 // to the diagnostic.
449 for (const std::pair<unsigned, unsigned> &Range : D.getRanges()) {
450 unsigned Column = D.getColumnNo();
451 B << SourceRange(Loc.getLocWithOffset(Range.first - Column),
452 Loc.getLocWithOffset(Range.second - Column));
453 }
454 }
455 return;
456 }
457
458 // Otherwise, report the backend issue as occurring in the generated .s file.
459 // If Loc is invalid, we still need to report the issue, it just gets no
460 // location info.
461 Diags.Report(Loc, DiagID).AddString(Message);
462}
463
464#define ComputeDiagID(Severity, GroupName, DiagID) \
465 do { \
466 switch (Severity) { \
467 case llvm::DS_Error: \
468 DiagID = diag::err_fe_##GroupName; \
469 break; \
470 case llvm::DS_Warning: \
471 DiagID = diag::warn_fe_##GroupName; \
472 break; \
473 case llvm::DS_Remark: \
474 llvm_unreachable("'remark' severity not expected")::llvm::llvm_unreachable_internal("'remark' severity not expected"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 474)
; \
475 break; \
476 case llvm::DS_Note: \
477 DiagID = diag::note_fe_##GroupName; \
478 break; \
479 } \
480 } while (false)
481
482#define ComputeDiagRemarkID(Severity, GroupName, DiagID)do { switch (Severity) { case llvm::DS_Error: DiagID = diag::
err_fe_GroupName; break; case llvm::DS_Warning: DiagID = diag
::warn_fe_GroupName; break; case llvm::DS_Remark: DiagID = diag
::remark_fe_GroupName; break; case llvm::DS_Note: DiagID = diag
::note_fe_GroupName; break; } } while (false)
\
483 do { \
484 switch (Severity) { \
485 case llvm::DS_Error: \
486 DiagID = diag::err_fe_##GroupName; \
487 break; \
488 case llvm::DS_Warning: \
489 DiagID = diag::warn_fe_##GroupName; \
490 break; \
491 case llvm::DS_Remark: \
492 DiagID = diag::remark_fe_##GroupName; \
493 break; \
494 case llvm::DS_Note: \
495 DiagID = diag::note_fe_##GroupName; \
496 break; \
497 } \
498 } while (false)
499
500bool
501BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) {
502 unsigned DiagID;
503 ComputeDiagID(D.getSeverity(), inline_asm, DiagID);
504 std::string Message = D.getMsgStr().str();
505
506 // If this problem has clang-level source location information, report the
507 // issue as being a problem in the source with a note showing the instantiated
508 // code.
509 SourceLocation LocCookie =
510 SourceLocation::getFromRawEncoding(D.getLocCookie());
511 if (LocCookie.isValid())
512 Diags.Report(LocCookie, DiagID).AddString(Message);
513 else {
514 // Otherwise, report the backend diagnostic as occurring in the generated
515 // .s file.
516 // If Loc is invalid, we still need to report the diagnostic, it just gets
517 // no location info.
518 FullSourceLoc Loc;
519 Diags.Report(Loc, DiagID).AddString(Message);
520 }
521 // We handled all the possible severities.
522 return true;
523}
524
525bool
526BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) {
527 if (D.getSeverity() != llvm::DS_Warning)
528 // For now, the only support we have for StackSize diagnostic is warning.
529 // We do not know how to format other severities.
530 return false;
531
532 if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) {
533 // FIXME: Shouldn't need to truncate to uint32_t
534 Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()),
535 diag::warn_fe_frame_larger_than)
536 << static_cast<uint32_t>(D.getStackSize()) << Decl::castToDeclContext(ND);
537 return true;
538 }
539
540 return false;
541}
542
543const FullSourceLoc BackendConsumer::getBestLocationFromDebugLoc(
544 const llvm::DiagnosticInfoWithLocationBase &D, bool &BadDebugInfo,
545 StringRef &Filename, unsigned &Line, unsigned &Column) const {
546 SourceManager &SourceMgr = Context->getSourceManager();
7
Calling 'ASTContext::getSourceManager'
8
Returning from 'ASTContext::getSourceManager'
547 FileManager &FileMgr = SourceMgr.getFileManager();
9
Calling 'SourceManager::getFileManager'
10
Returning from 'SourceManager::getFileManager'
548 SourceLocation DILoc;
11
Calling implicit default constructor for 'SourceLocation'
12
Returning from default constructor for 'SourceLocation'
549
550 if (D.isLocationAvailable()) {
13
Calling 'DiagnosticInfoWithLocationBase::isLocationAvailable'
17
Returning from 'DiagnosticInfoWithLocationBase::isLocationAvailable'
18
Taking false branch
551 D.getLocation(&Filename, &Line, &Column);
552 const FileEntry *FE = FileMgr.getFile(Filename);
553 if (FE && Line > 0) {
554 // If -gcolumn-info was not used, Column will be 0. This upsets the
555 // source manager, so pass 1 if Column is not set.
556 DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1);
557 }
558 BadDebugInfo = DILoc.isInvalid();
559 }
560
561 // If a location isn't available, try to approximate it using the associated
562 // function definition. We use the definition's right brace to differentiate
563 // from diagnostics that genuinely relate to the function itself.
564 FullSourceLoc Loc(DILoc, SourceMgr);
19
Calling constructor for 'FullSourceLoc'
20
Returning from constructor for 'FullSourceLoc'
565 if (Loc.isInvalid())
21
Calling 'SourceLocation::isInvalid'
22
Returning from 'SourceLocation::isInvalid'
23
Taking true branch
566 if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName()))
24
Calling 'unique_ptr::operator->'
37
Returning from 'unique_ptr::operator->'
38
Calling 'DiagnosticInfoWithLocationBase::getFunction'
39
Returning from 'DiagnosticInfoWithLocationBase::getFunction'
40
Assuming 'FD' is null
41
Taking false branch
567 Loc = FD->getASTContext().getFullLoc(FD->getLocation());
568
569 if (DILoc.isInvalid() && D.isLocationAvailable())
42
Calling 'SourceLocation::isInvalid'
43
Returning from 'SourceLocation::isInvalid'
44
Calling 'DiagnosticInfoWithLocationBase::isLocationAvailable'
48
Returning from 'DiagnosticInfoWithLocationBase::isLocationAvailable'
49
Taking true branch
570 // If we were not able to translate the file:line:col information
571 // back to a SourceLocation, at least emit a note stating that
572 // we could not translate this location. This can happen in the
573 // case of #line directives.
574 Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
50
Calling 'DiagnosticsEngine::Report'
52
Returning from 'DiagnosticsEngine::Report'
53
Calling 'operator<<'
58
Returning from 'operator<<'
59
2nd function call argument is an uninitialized value
575 << Filename << Line << Column;
576
577 return Loc;
578}
579
580void BackendConsumer::UnsupportedDiagHandler(
581 const llvm::DiagnosticInfoUnsupported &D) {
582 // We only support errors.
583 assert(D.getSeverity() == llvm::DS_Error)(static_cast <bool> (D.getSeverity() == llvm::DS_Error)
? void (0) : __assert_fail ("D.getSeverity() == llvm::DS_Error"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 583, __extension__ __PRETTY_FUNCTION__))
;
584
585 StringRef Filename;
586 unsigned Line, Column;
4
'Line' declared without an initial value
587 bool BadDebugInfo = false;
588 FullSourceLoc Loc =
589 getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
5
Passing value via 4th parameter 'Line'
6
Calling 'BackendConsumer::getBestLocationFromDebugLoc'
590
591 Diags.Report(Loc, diag::err_fe_backend_unsupported) << D.getMessage().str();
592
593 if (BadDebugInfo)
594 // If we were not able to translate the file:line:col information
595 // back to a SourceLocation, at least emit a note stating that
596 // we could not translate this location. This can happen in the
597 // case of #line directives.
598 Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
599 << Filename << Line << Column;
600}
601
602void BackendConsumer::EmitOptimizationMessage(
603 const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) {
604 // We only support warnings and remarks.
605 assert(D.getSeverity() == llvm::DS_Remark ||(static_cast <bool> (D.getSeverity() == llvm::DS_Remark
|| D.getSeverity() == llvm::DS_Warning) ? void (0) : __assert_fail
("D.getSeverity() == llvm::DS_Remark || D.getSeverity() == llvm::DS_Warning"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 606, __extension__ __PRETTY_FUNCTION__))
606 D.getSeverity() == llvm::DS_Warning)(static_cast <bool> (D.getSeverity() == llvm::DS_Remark
|| D.getSeverity() == llvm::DS_Warning) ? void (0) : __assert_fail
("D.getSeverity() == llvm::DS_Remark || D.getSeverity() == llvm::DS_Warning"
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 606, __extension__ __PRETTY_FUNCTION__))
;
607
608 StringRef Filename;
609 unsigned Line, Column;
610 bool BadDebugInfo = false;
611 FullSourceLoc Loc =
612 getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
613
614 std::string Msg;
615 raw_string_ostream MsgStream(Msg);
616 MsgStream << D.getMsg();
617
618 if (D.getHotness())
619 MsgStream << " (hotness: " << *D.getHotness() << ")";
620
621 Diags.Report(Loc, DiagID)
622 << AddFlagValue(D.getPassName())
623 << MsgStream.str();
624
625 if (BadDebugInfo)
626 // If we were not able to translate the file:line:col information
627 // back to a SourceLocation, at least emit a note stating that
628 // we could not translate this location. This can happen in the
629 // case of #line directives.
630 Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
631 << Filename << Line << Column;
632}
633
634void BackendConsumer::OptimizationRemarkHandler(
635 const llvm::DiagnosticInfoOptimizationBase &D) {
636 // Without hotness information, don't show noisy remarks.
637 if (D.isVerbose() && !D.getHotness())
638 return;
639
640 if (D.isPassed()) {
641 // Optimization remarks are active only if the -Rpass flag has a regular
642 // expression that matches the name of the pass name in \p D.
643 if (CodeGenOpts.OptimizationRemarkPattern &&
644 CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName()))
645 EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark);
646 } else if (D.isMissed()) {
647 // Missed optimization remarks are active only if the -Rpass-missed
648 // flag has a regular expression that matches the name of the pass
649 // name in \p D.
650 if (CodeGenOpts.OptimizationRemarkMissedPattern &&
651 CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName()))
652 EmitOptimizationMessage(
653 D, diag::remark_fe_backend_optimization_remark_missed);
654 } else {
655 assert(D.isAnalysis() && "Unknown remark type")(static_cast <bool> (D.isAnalysis() && "Unknown remark type"
) ? void (0) : __assert_fail ("D.isAnalysis() && \"Unknown remark type\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 655, __extension__ __PRETTY_FUNCTION__))
;
656
657 bool ShouldAlwaysPrint = false;
658 if (auto *ORA = dyn_cast<llvm::OptimizationRemarkAnalysis>(&D))
659 ShouldAlwaysPrint = ORA->shouldAlwaysPrint();
660
661 if (ShouldAlwaysPrint ||
662 (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
663 CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
664 EmitOptimizationMessage(
665 D, diag::remark_fe_backend_optimization_remark_analysis);
666 }
667}
668
669void BackendConsumer::OptimizationRemarkHandler(
670 const llvm::OptimizationRemarkAnalysisFPCommute &D) {
671 // Optimization analysis remarks are active if the pass name is set to
672 // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a
673 // regular expression that matches the name of the pass name in \p D.
674
675 if (D.shouldAlwaysPrint() ||
676 (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
677 CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
678 EmitOptimizationMessage(
679 D, diag::remark_fe_backend_optimization_remark_analysis_fpcommute);
680}
681
682void BackendConsumer::OptimizationRemarkHandler(
683 const llvm::OptimizationRemarkAnalysisAliasing &D) {
684 // Optimization analysis remarks are active if the pass name is set to
685 // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a
686 // regular expression that matches the name of the pass name in \p D.
687
688 if (D.shouldAlwaysPrint() ||
689 (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
690 CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))
691 EmitOptimizationMessage(
692 D, diag::remark_fe_backend_optimization_remark_analysis_aliasing);
693}
694
695void BackendConsumer::OptimizationFailureHandler(
696 const llvm::DiagnosticInfoOptimizationFailure &D) {
697 EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure);
698}
699
700/// \brief This function is invoked when the backend needs
701/// to report something to the user.
702void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
703 unsigned DiagID = diag::err_fe_inline_asm;
704 llvm::DiagnosticSeverity Severity = DI.getSeverity();
705 // Get the diagnostic ID based.
706 switch (DI.getKind()) {
2
Control jumps to 'case DK_Unsupported:' at line 769
707 case llvm::DK_InlineAsm:
708 if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI)))
709 return;
710 ComputeDiagID(Severity, inline_asm, DiagID);
711 break;
712 case llvm::DK_StackSize:
713 if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI)))
714 return;
715 ComputeDiagID(Severity, backend_frame_larger_than, DiagID);
716 break;
717 case DK_Linker:
718 assert(CurLinkModule)(static_cast <bool> (CurLinkModule) ? void (0) : __assert_fail
("CurLinkModule", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 718, __extension__ __PRETTY_FUNCTION__))
;
719 // FIXME: stop eating the warnings and notes.
720 if (Severity != DS_Error)
721 return;
722 DiagID = diag::err_fe_cannot_link_module;
723 break;
724 case llvm::DK_OptimizationRemark:
725 // Optimization remarks are always handled completely by this
726 // handler. There is no generic way of emitting them.
727 OptimizationRemarkHandler(cast<OptimizationRemark>(DI));
728 return;
729 case llvm::DK_OptimizationRemarkMissed:
730 // Optimization remarks are always handled completely by this
731 // handler. There is no generic way of emitting them.
732 OptimizationRemarkHandler(cast<OptimizationRemarkMissed>(DI));
733 return;
734 case llvm::DK_OptimizationRemarkAnalysis:
735 // Optimization remarks are always handled completely by this
736 // handler. There is no generic way of emitting them.
737 OptimizationRemarkHandler(cast<OptimizationRemarkAnalysis>(DI));
738 return;
739 case llvm::DK_OptimizationRemarkAnalysisFPCommute:
740 // Optimization remarks are always handled completely by this
741 // handler. There is no generic way of emitting them.
742 OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisFPCommute>(DI));
743 return;
744 case llvm::DK_OptimizationRemarkAnalysisAliasing:
745 // Optimization remarks are always handled completely by this
746 // handler. There is no generic way of emitting them.
747 OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisAliasing>(DI));
748 return;
749 case llvm::DK_MachineOptimizationRemark:
750 // Optimization remarks are always handled completely by this
751 // handler. There is no generic way of emitting them.
752 OptimizationRemarkHandler(cast<MachineOptimizationRemark>(DI));
753 return;
754 case llvm::DK_MachineOptimizationRemarkMissed:
755 // Optimization remarks are always handled completely by this
756 // handler. There is no generic way of emitting them.
757 OptimizationRemarkHandler(cast<MachineOptimizationRemarkMissed>(DI));
758 return;
759 case llvm::DK_MachineOptimizationRemarkAnalysis:
760 // Optimization remarks are always handled completely by this
761 // handler. There is no generic way of emitting them.
762 OptimizationRemarkHandler(cast<MachineOptimizationRemarkAnalysis>(DI));
763 return;
764 case llvm::DK_OptimizationFailure:
765 // Optimization failures are always handled completely by this
766 // handler.
767 OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI));
768 return;
769 case llvm::DK_Unsupported:
770 UnsupportedDiagHandler(cast<DiagnosticInfoUnsupported>(DI));
3
Calling 'BackendConsumer::UnsupportedDiagHandler'
771 return;
772 default:
773 // Plugin IDs are not bound to any value as they are set dynamically.
774 ComputeDiagRemarkID(Severity, backend_plugin, DiagID)do { switch (Severity) { case llvm::DS_Error: DiagID = diag::
err_fe_backend_plugin; break; case llvm::DS_Warning: DiagID =
diag::warn_fe_backend_plugin; break; case llvm::DS_Remark: DiagID
= diag::remark_fe_backend_plugin; break; case llvm::DS_Note:
DiagID = diag::note_fe_backend_plugin; break; } } while (false
)
;
775 break;
776 }
777 std::string MsgStorage;
778 {
779 raw_string_ostream Stream(MsgStorage);
780 DiagnosticPrinterRawOStream DP(Stream);
781 DI.print(DP);
782 }
783
784 if (DiagID == diag::err_fe_cannot_link_module) {
785 Diags.Report(diag::err_fe_cannot_link_module)
786 << CurLinkModule->getModuleIdentifier() << MsgStorage;
787 return;
788 }
789
790 // Report the backend message using the usual diagnostic mechanism.
791 FullSourceLoc Loc;
792 Diags.Report(Loc, DiagID).AddString(MsgStorage);
793}
794#undef ComputeDiagID
795
796CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext)
797 : Act(_Act), VMContext(_VMContext ? _VMContext : new LLVMContext),
798 OwnsVMContext(!_VMContext) {}
799
800CodeGenAction::~CodeGenAction() {
801 TheModule.reset();
802 if (OwnsVMContext)
803 delete VMContext;
804}
805
806bool CodeGenAction::hasIRSupport() const { return true; }
807
808void CodeGenAction::EndSourceFileAction() {
809 // If the consumer creation failed, do nothing.
810 if (!getCompilerInstance().hasASTConsumer())
811 return;
812
813 // Steal the module from the consumer.
814 TheModule = BEConsumer->takeModule();
815}
816
817std::unique_ptr<llvm::Module> CodeGenAction::takeModule() {
818 return std::move(TheModule);
819}
820
821llvm::LLVMContext *CodeGenAction::takeLLVMContext() {
822 OwnsVMContext = false;
823 return VMContext;
824}
825
826static std::unique_ptr<raw_pwrite_stream>
827GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
828 switch (Action) {
829 case Backend_EmitAssembly:
830 return CI.createDefaultOutputFile(false, InFile, "s");
831 case Backend_EmitLL:
832 return CI.createDefaultOutputFile(false, InFile, "ll");
833 case Backend_EmitBC:
834 return CI.createDefaultOutputFile(true, InFile, "bc");
835 case Backend_EmitNothing:
836 return nullptr;
837 case Backend_EmitMCNull:
838 return CI.createNullOutputFile();
839 case Backend_EmitObj:
840 return CI.createDefaultOutputFile(true, InFile, "o");
841 }
842
843 llvm_unreachable("Invalid action!")::llvm::llvm_unreachable_internal("Invalid action!", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 843)
;
844}
845
846std::unique_ptr<ASTConsumer>
847CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
848 BackendAction BA = static_cast<BackendAction>(Act);
849 std::unique_ptr<raw_pwrite_stream> OS = GetOutputStream(CI, InFile, BA);
850 if (BA != Backend_EmitNothing && !OS)
851 return nullptr;
852
853 // Load bitcode modules to link with, if we need to.
854 if (LinkModules.empty())
855 for (const CodeGenOptions::BitcodeFileToLink &F :
856 CI.getCodeGenOpts().LinkBitcodeFiles) {
857 auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename);
858 if (!BCBuf) {
859 CI.getDiagnostics().Report(diag::err_cannot_open_file)
860 << F.Filename << BCBuf.getError().message();
861 LinkModules.clear();
862 return nullptr;
863 }
864
865 Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
866 getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext);
867 if (!ModuleOrErr) {
868 handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
869 CI.getDiagnostics().Report(diag::err_cannot_open_file)
870 << F.Filename << EIB.message();
871 });
872 LinkModules.clear();
873 return nullptr;
874 }
875 LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs,
876 F.Internalize, F.LinkFlags});
877 }
878
879 CoverageSourceInfo *CoverageInfo = nullptr;
880 // Add the preprocessor callback only when the coverage mapping is generated.
881 if (CI.getCodeGenOpts().CoverageMapping) {
882 CoverageInfo = new CoverageSourceInfo;
883 CI.getPreprocessor().addPPCallbacks(
884 std::unique_ptr<PPCallbacks>(CoverageInfo));
885 }
886
887 std::unique_ptr<BackendConsumer> Result(new BackendConsumer(
888 BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
889 CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
890 CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile,
891 std::move(LinkModules), std::move(OS), *VMContext, CoverageInfo));
892 BEConsumer = Result.get();
893
894 // Enable generating macro debug info only when debug info is not disabled and
895 // also macro debug info is enabled.
896 if (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo &&
897 CI.getCodeGenOpts().MacroDebugInfo) {
898 std::unique_ptr<PPCallbacks> Callbacks =
899 llvm::make_unique<MacroPPCallbacks>(BEConsumer->getCodeGenerator(),
900 CI.getPreprocessor());
901 CI.getPreprocessor().addPPCallbacks(std::move(Callbacks));
902 }
903
904 return std::move(Result);
905}
906
907static void BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic &SM,
908 void *Context,
909 unsigned LocCookie) {
910 SM.print(nullptr, llvm::errs());
911
912 auto Diags = static_cast<DiagnosticsEngine *>(Context);
913 unsigned DiagID;
914 switch (SM.getKind()) {
915 case llvm::SourceMgr::DK_Error:
916 DiagID = diag::err_fe_inline_asm;
917 break;
918 case llvm::SourceMgr::DK_Warning:
919 DiagID = diag::warn_fe_inline_asm;
920 break;
921 case llvm::SourceMgr::DK_Note:
922 DiagID = diag::note_fe_inline_asm;
923 break;
924 case llvm::SourceMgr::DK_Remark:
925 llvm_unreachable("remarks unexpected")::llvm::llvm_unreachable_internal("remarks unexpected", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 925)
;
926 }
927
928 Diags->Report(DiagID).AddString("cannot compile inline asm");
929}
930
931std::unique_ptr<llvm::Module> CodeGenAction::loadModule(MemoryBufferRef MBRef) {
932 CompilerInstance &CI = getCompilerInstance();
933 SourceManager &SM = CI.getSourceManager();
934
935 // For ThinLTO backend invocations, ensure that the context
936 // merges types based on ODR identifiers. We also need to read
937 // the correct module out of a multi-module bitcode file.
938 if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) {
939 VMContext->enableDebugTypeODRUniquing();
940
941 auto DiagErrors = [&](Error E) -> std::unique_ptr<llvm::Module> {
942 unsigned DiagID =
943 CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
944 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
945 CI.getDiagnostics().Report(DiagID) << EIB.message();
946 });
947 return {};
948 };
949
950 Expected<llvm::BitcodeModule> BMOrErr = FindThinLTOModule(MBRef);
951 if (!BMOrErr)
952 return DiagErrors(BMOrErr.takeError());
953
954 Expected<std::unique_ptr<llvm::Module>> MOrErr =
955 BMOrErr->parseModule(*VMContext);
956 if (!MOrErr)
957 return DiagErrors(MOrErr.takeError());
958 return std::move(*MOrErr);
959 }
960
961 llvm::SMDiagnostic Err;
962 if (std::unique_ptr<llvm::Module> M = parseIR(MBRef, Err, *VMContext))
963 return M;
964
965 // Translate from the diagnostic info to the SourceManager location if
966 // available.
967 // TODO: Unify this with ConvertBackendLocation()
968 SourceLocation Loc;
969 if (Err.getLineNo() > 0) {
970 assert(Err.getColumnNo() >= 0)(static_cast <bool> (Err.getColumnNo() >= 0) ? void (
0) : __assert_fail ("Err.getColumnNo() >= 0", "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/lib/CodeGen/CodeGenAction.cpp"
, 970, __extension__ __PRETTY_FUNCTION__))
;
971 Loc = SM.translateFileLineCol(SM.getFileEntryForID(SM.getMainFileID()),
972 Err.getLineNo(), Err.getColumnNo() + 1);
973 }
974
975 // Strip off a leading diagnostic code if there is one.
976 StringRef Msg = Err.getMessage();
977 if (Msg.startswith("error: "))
978 Msg = Msg.substr(7);
979
980 unsigned DiagID =
981 CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
982
983 CI.getDiagnostics().Report(Loc, DiagID) << Msg;
984 return {};
985}
986
987void CodeGenAction::ExecuteAction() {
988 // If this is an IR file, we have to treat it specially.
989 if (getCurrentFileKind().getLanguage() == InputKind::LLVM_IR) {
990 BackendAction BA = static_cast<BackendAction>(Act);
991 CompilerInstance &CI = getCompilerInstance();
992 std::unique_ptr<raw_pwrite_stream> OS =
993 GetOutputStream(CI, getCurrentFile(), BA);
994 if (BA != Backend_EmitNothing && !OS)
995 return;
996
997 bool Invalid;
998 SourceManager &SM = CI.getSourceManager();
999 FileID FID = SM.getMainFileID();
1000 llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid);
1001 if (Invalid)
1002 return;
1003
1004 TheModule = loadModule(*MainFile);
1005 if (!TheModule)
1006 return;
1007
1008 const TargetOptions &TargetOpts = CI.getTargetOpts();
1009 if (TheModule->getTargetTriple() != TargetOpts.Triple) {
1010 CI.getDiagnostics().Report(SourceLocation(),
1011 diag::warn_fe_override_module)
1012 << TargetOpts.Triple;
1013 TheModule->setTargetTriple(TargetOpts.Triple);
1014 }
1015
1016 EmbedBitcode(TheModule.get(), CI.getCodeGenOpts(),
1017 MainFile->getMemBufferRef());
1018
1019 LLVMContext &Ctx = TheModule->getContext();
1020 Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler,
1021 &CI.getDiagnostics());
1022
1023 EmitBackendOutput(CI.getDiagnostics(), CI.getHeaderSearchOpts(),
1024 CI.getCodeGenOpts(), TargetOpts, CI.getLangOpts(),
1025 CI.getTarget().getDataLayout(), TheModule.get(), BA,
1026 std::move(OS));
1027 return;
1028 }
1029
1030 // Otherwise follow the normal AST path.
1031 this->ASTFrontendAction::ExecuteAction();
1032}
1033
1034//
1035
1036void EmitAssemblyAction::anchor() { }
1037EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext)
1038 : CodeGenAction(Backend_EmitAssembly, _VMContext) {}
1039
1040void EmitBCAction::anchor() { }
1041EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext)
1042 : CodeGenAction(Backend_EmitBC, _VMContext) {}
1043
1044void EmitLLVMAction::anchor() { }
1045EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext)
1046 : CodeGenAction(Backend_EmitLL, _VMContext) {}
1047
1048void EmitLLVMOnlyAction::anchor() { }
1049EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext)
1050 : CodeGenAction(Backend_EmitNothing, _VMContext) {}
1051
1052void EmitCodeGenOnlyAction::anchor() { }
1053EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext)
1054 : CodeGenAction(Backend_EmitMCNull, _VMContext) {}
1055
1056void EmitObjAction::anchor() { }
1057EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext)
1058 : CodeGenAction(Backend_EmitObj, _VMContext) {}

/build/llvm-toolchain-snapshot-6.0~svn318601/include/llvm/IR/DiagnosticInfo.h

1//===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===//
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// This file declares the different classes involved in low level diagnostics.
11//
12// Diagnostics reporting is still done as part of the LLVMContext.
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_IR_DIAGNOSTICINFO_H
16#define LLVM_IR_DIAGNOSTICINFO_H
17
18#include "llvm-c/Types.h"
19#include "llvm/ADT/Optional.h"
20#include "llvm/ADT/SmallVector.h"
21#include "llvm/ADT/StringRef.h"
22#include "llvm/ADT/Twine.h"
23#include "llvm/IR/DebugLoc.h"
24#include "llvm/Support/CBindingWrapping.h"
25#include "llvm/Support/YAMLTraits.h"
26#include <algorithm>
27#include <cstdint>
28#include <functional>
29#include <iterator>
30#include <string>
31
32namespace llvm {
33
34// Forward declarations.
35class DiagnosticPrinter;
36class Function;
37class Instruction;
38class LLVMContext;
39class Module;
40class SMDiagnostic;
41
42/// \brief Defines the different supported severity of a diagnostic.
43enum DiagnosticSeverity : char {
44 DS_Error,
45 DS_Warning,
46 DS_Remark,
47 // A note attaches additional information to one of the previous diagnostic
48 // types.
49 DS_Note
50};
51
52/// \brief Defines the different supported kind of a diagnostic.
53/// This enum should be extended with a new ID for each added concrete subclass.
54enum DiagnosticKind {
55 DK_InlineAsm,
56 DK_ResourceLimit,
57 DK_StackSize,
58 DK_Linker,
59 DK_DebugMetadataVersion,
60 DK_DebugMetadataInvalid,
61 DK_ISelFallback,
62 DK_SampleProfile,
63 DK_OptimizationRemark,
64 DK_OptimizationRemarkMissed,
65 DK_OptimizationRemarkAnalysis,
66 DK_OptimizationRemarkAnalysisFPCommute,
67 DK_OptimizationRemarkAnalysisAliasing,
68 DK_OptimizationFailure,
69 DK_FirstRemark = DK_OptimizationRemark,
70 DK_LastRemark = DK_OptimizationFailure,
71 DK_MachineOptimizationRemark,
72 DK_MachineOptimizationRemarkMissed,
73 DK_MachineOptimizationRemarkAnalysis,
74 DK_FirstMachineRemark = DK_MachineOptimizationRemark,
75 DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
76 DK_MIRParser,
77 DK_PGOProfile,
78 DK_Unsupported,
79 DK_FirstPluginKind
80};
81
82/// \brief Get the next available kind ID for a plugin diagnostic.
83/// Each time this function is called, it returns a different number.
84/// Therefore, a plugin that wants to "identify" its own classes
85/// with a dynamic identifier, just have to use this method to get a new ID
86/// and assign it to each of its classes.
87/// The returned ID will be greater than or equal to DK_FirstPluginKind.
88/// Thus, the plugin identifiers will not conflict with the
89/// DiagnosticKind values.
90int getNextAvailablePluginDiagnosticKind();
91
92/// \brief This is the base abstract class for diagnostic reporting in
93/// the backend.
94/// The print method must be overloaded by the subclasses to print a
95/// user-friendly message in the client of the backend (let us call it a
96/// frontend).
97class DiagnosticInfo {
98private:
99 /// Kind defines the kind of report this is about.
100 const /* DiagnosticKind */ int Kind;
101 /// Severity gives the severity of the diagnostic.
102 const DiagnosticSeverity Severity;
103
104public:
105 DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
106 : Kind(Kind), Severity(Severity) {}
107
108 virtual ~DiagnosticInfo() = default;
109
110 /* DiagnosticKind */ int getKind() const { return Kind; }
111 DiagnosticSeverity getSeverity() const { return Severity; }
112
113 /// Print using the given \p DP a user-friendly message.
114 /// This is the default message that will be printed to the user.
115 /// It is used when the frontend does not directly take advantage
116 /// of the information contained in fields of the subclasses.
117 /// The printed message must not end with '.' nor start with a severity
118 /// keyword.
119 virtual void print(DiagnosticPrinter &DP) const = 0;
120};
121
122using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
123
124/// Diagnostic information for inline asm reporting.
125/// This is basically a message and an optional location.
126class DiagnosticInfoInlineAsm : public DiagnosticInfo {
127private:
128 /// Optional line information. 0 if not set.
129 unsigned LocCookie = 0;
130 /// Message to be reported.
131 const Twine &MsgStr;
132 /// Optional origin of the problem.
133 const Instruction *Instr = nullptr;
134
135public:
136 /// \p MsgStr is the message to be reported to the frontend.
137 /// This class does not copy \p MsgStr, therefore the reference must be valid
138 /// for the whole life time of the Diagnostic.
139 DiagnosticInfoInlineAsm(const Twine &MsgStr,
140 DiagnosticSeverity Severity = DS_Error)
141 : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {}
142
143 /// \p LocCookie if non-zero gives the line number for this report.
144 /// \p MsgStr gives the message.
145 /// This class does not copy \p MsgStr, therefore the reference must be valid
146 /// for the whole life time of the Diagnostic.
147 DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
148 DiagnosticSeverity Severity = DS_Error)
149 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
150 MsgStr(MsgStr) {}
151
152 /// \p Instr gives the original instruction that triggered the diagnostic.
153 /// \p MsgStr gives the message.
154 /// This class does not copy \p MsgStr, therefore the reference must be valid
155 /// for the whole life time of the Diagnostic.
156 /// Same for \p I.
157 DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
158 DiagnosticSeverity Severity = DS_Error);
159
160 unsigned getLocCookie() const { return LocCookie; }
161 const Twine &getMsgStr() const { return MsgStr; }
162 const Instruction *getInstruction() const { return Instr; }
163
164 /// \see DiagnosticInfo::print.
165 void print(DiagnosticPrinter &DP) const override;
166
167 static bool classof(const DiagnosticInfo *DI) {
168 return DI->getKind() == DK_InlineAsm;
169 }
170};
171
172/// Diagnostic information for stack size etc. reporting.
173/// This is basically a function and a size.
174class DiagnosticInfoResourceLimit : public DiagnosticInfo {
175private:
176 /// The function that is concerned by this resource limit diagnostic.
177 const Function &Fn;
178
179 /// Description of the resource type (e.g. stack size)
180 const char *ResourceName;
181
182 /// The computed size usage
183 uint64_t ResourceSize;
184
185 // Threshould passed
186 uint64_t ResourceLimit;
187
188public:
189 /// \p The function that is concerned by this stack size diagnostic.
190 /// \p The computed stack size.
191 DiagnosticInfoResourceLimit(const Function &Fn, const char *ResourceName,
192 uint64_t ResourceSize,
193 DiagnosticSeverity Severity = DS_Warning,
194 DiagnosticKind Kind = DK_ResourceLimit,
195 uint64_t ResourceLimit = 0)
196 : DiagnosticInfo(Kind, Severity), Fn(Fn), ResourceName(ResourceName),
197 ResourceSize(ResourceSize), ResourceLimit(ResourceLimit) {}
198
199 const Function &getFunction() const { return Fn; }
200 const char *getResourceName() const { return ResourceName; }
201 uint64_t getResourceSize() const { return ResourceSize; }
202 uint64_t getResourceLimit() const { return ResourceLimit; }
203
204 /// \see DiagnosticInfo::print.
205 void print(DiagnosticPrinter &DP) const override;
206
207 static bool classof(const DiagnosticInfo *DI) {
208 return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize;
209 }
210};
211
212class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
213public:
214 DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize,
215 DiagnosticSeverity Severity = DS_Warning,
216 uint64_t StackLimit = 0)
217 : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize, Severity,
218 DK_StackSize, StackLimit) {}
219
220 uint64_t getStackSize() const { return getResourceSize(); }
221 uint64_t getStackLimit() const { return getResourceLimit(); }
222
223 static bool classof(const DiagnosticInfo *DI) {
224 return DI->getKind() == DK_StackSize;
225 }
226};
227
228/// Diagnostic information for debug metadata version reporting.
229/// This is basically a module and a version.
230class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
231private:
232 /// The module that is concerned by this debug metadata version diagnostic.
233 const Module &M;
234 /// The actual metadata version.
235 unsigned MetadataVersion;
236
237public:
238 /// \p The module that is concerned by this debug metadata version diagnostic.
239 /// \p The actual metadata version.
240 DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
241 DiagnosticSeverity Severity = DS_Warning)
242 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
243 MetadataVersion(MetadataVersion) {}
244
245 const Module &getModule() const { return M; }
246 unsigned getMetadataVersion() const { return MetadataVersion; }
247
248 /// \see DiagnosticInfo::print.
249 void print(DiagnosticPrinter &DP) const override;
250
251 static bool classof(const DiagnosticInfo *DI) {
252 return DI->getKind() == DK_DebugMetadataVersion;
253 }
254};
255
256/// Diagnostic information for stripping invalid debug metadata.
257class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
258private:
259 /// The module that is concerned by this debug metadata version diagnostic.
260 const Module &M;
261
262public:
263 /// \p The module that is concerned by this debug metadata version diagnostic.
264 DiagnosticInfoIgnoringInvalidDebugMetadata(
265 const Module &M, DiagnosticSeverity Severity = DS_Warning)
266 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
267
268 const Module &getModule() const { return M; }
269
270 /// \see DiagnosticInfo::print.
271 void print(DiagnosticPrinter &DP) const override;
272
273 static bool classof(const DiagnosticInfo *DI) {
274 return DI->getKind() == DK_DebugMetadataInvalid;
275 }
276};
277
278/// Diagnostic information for the sample profiler.
279class DiagnosticInfoSampleProfile : public DiagnosticInfo {
280public:
281 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
282 const Twine &Msg,
283 DiagnosticSeverity Severity = DS_Error)
284 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
285 LineNum(LineNum), Msg(Msg) {}
286 DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
287 DiagnosticSeverity Severity = DS_Error)
288 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
289 Msg(Msg) {}
290 DiagnosticInfoSampleProfile(const Twine &Msg,
291 DiagnosticSeverity Severity = DS_Error)
292 : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
293
294 /// \see DiagnosticInfo::print.
295 void print(DiagnosticPrinter &DP) const override;
296
297 static bool classof(const DiagnosticInfo *DI) {
298 return DI->getKind() == DK_SampleProfile;
299 }
300
301 StringRef getFileName() const { return FileName; }
302 unsigned getLineNum() const { return LineNum; }
303 const Twine &getMsg() const { return Msg; }
304
305private:
306 /// Name of the input file associated with this diagnostic.
307 StringRef FileName;
308
309 /// Line number where the diagnostic occurred. If 0, no line number will
310 /// be emitted in the message.
311 unsigned LineNum = 0;
312
313 /// Message to report.
314 const Twine &Msg;
315};
316
317/// Diagnostic information for the PGO profiler.
318class DiagnosticInfoPGOProfile : public DiagnosticInfo {
319public:
320 DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
321 DiagnosticSeverity Severity = DS_Error)
322 : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
323
324 /// \see DiagnosticInfo::print.
325 void print(DiagnosticPrinter &DP) const override;
326
327 static bool classof(const DiagnosticInfo *DI) {
328 return DI->getKind() == DK_PGOProfile;
329 }
330
331 const char *getFileName() const { return FileName; }
332 const Twine &getMsg() const { return Msg; }
333
334private:
335 /// Name of the input file associated with this diagnostic.
336 const char *FileName;
337
338 /// Message to report.
339 const Twine &Msg;
340};
341
342class DiagnosticLocation {
343 StringRef Filename;
344 unsigned Line = 0;
345 unsigned Column = 0;
346
347public:
348 DiagnosticLocation() = default;
349 DiagnosticLocation(const DebugLoc &DL);
350 DiagnosticLocation(const DISubprogram *SP);
351
352 bool isValid() const { return !Filename.empty(); }
15
Assuming the condition is false
46
Assuming the condition is true
353 StringRef getFilename() const { return Filename; }
354 unsigned getLine() const { return Line; }
355 unsigned getColumn() const { return Column; }
356};
357
358/// Common features for diagnostics with an associated location.
359class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
360public:
361 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
362 /// the location information to use in the diagnostic.
363 DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
364 enum DiagnosticSeverity Severity,
365 const Function &Fn,
366 const DiagnosticLocation &Loc)
367 : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
368
369 /// Return true if location information is available for this diagnostic.
370 bool isLocationAvailable() const { return Loc.isValid(); }
14
Calling 'DiagnosticLocation::isValid'
16
Returning from 'DiagnosticLocation::isValid'
45
Calling 'DiagnosticLocation::isValid'
47
Returning from 'DiagnosticLocation::isValid'
371
372 /// Return a string with the location information for this diagnostic
373 /// in the format "file:line:col". If location information is not available,
374 /// it returns "<unknown>:0:0".
375 const std::string getLocationStr() const;
376
377 /// Return location information for this diagnostic in three parts:
378 /// the source file name, line number and column.
379 void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
380
381 const Function &getFunction() const { return Fn; }
382 DiagnosticLocation getLocation() const { return Loc; }
383
384private:
385 /// Function where this diagnostic is triggered.
386 const Function &Fn;
387
388 /// Debug location where this diagnostic is triggered.
389 DiagnosticLocation Loc;
390};
391
392/// \brief Common features for diagnostics dealing with optimization remarks
393/// that are used by both IR and MIR passes.
394class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
395public:
396 /// \brief Used to set IsVerbose via the stream interface.
397 struct setIsVerbose {};
398
399 /// \brief When an instance of this is inserted into the stream, the arguments
400 /// following will not appear in the remark printed in the compiler output
401 /// (-Rpass) but only in the optimization record file
402 /// (-fsave-optimization-record).
403 struct setExtraArgs {};
404
405 /// \brief Used in the streaming interface as the general argument type. It
406 /// internally converts everything into a key-value pair.
407 struct Argument {
408 std::string Key;
409 std::string Val;
410 // If set, the debug location corresponding to the value.
411 DiagnosticLocation Loc;
412
413 explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
414 Argument(StringRef Key, const Value *V);
415 Argument(StringRef Key, const Type *T);
416 Argument(StringRef Key, StringRef S);
417 Argument(StringRef Key, int N);
418 Argument(StringRef Key, long N);
419 Argument(StringRef Key, long long N);
420 Argument(StringRef Key, unsigned N);
421 Argument(StringRef Key, unsigned long N);
422 Argument(StringRef Key, unsigned long long N);
423 Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
424 Argument(StringRef Key, DebugLoc dl);
425 };
426
427 /// \p PassName is the name of the pass emitting this diagnostic. \p
428 /// RemarkName is a textual identifier for the remark (single-word,
429 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
430 /// \p Loc is the location information to use in the diagnostic. If line table
431 /// information is available, the diagnostic will include the source code
432 /// location.
433 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
434 enum DiagnosticSeverity Severity,
435 const char *PassName, StringRef RemarkName,
436 const Function &Fn,
437 const DiagnosticLocation &Loc)
438 : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
439 PassName(PassName), RemarkName(RemarkName) {}
440
441 void insert(StringRef S);
442 void insert(Argument A);
443 void insert(setIsVerbose V);
444 void insert(setExtraArgs EA);
445
446 /// \see DiagnosticInfo::print.
447 void print(DiagnosticPrinter &DP) const override;
448
449 /// Return true if this optimization remark is enabled by one of
450 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
451 /// or -pass-remarks-analysis). Note that this only handles the LLVM
452 /// flags. We cannot access Clang flags from here (they are handled
453 /// in BackendConsumer::OptimizationRemarkHandler).
454 virtual bool isEnabled() const = 0;
455
456 StringRef getPassName() const { return PassName; }
457 std::string getMsg() const;
458 Optional<uint64_t> getHotness() const { return Hotness; }
459 void setHotness(Optional<uint64_t> H) { Hotness = H; }
460
461 bool isVerbose() const { return IsVerbose; }
462
463 static bool classof(const DiagnosticInfo *DI) {
464 return (DI->getKind() >= DK_FirstRemark &&
465 DI->getKind() <= DK_LastRemark) ||
466 (DI->getKind() >= DK_FirstMachineRemark &&
467 DI->getKind() <= DK_LastMachineRemark);
468 }
469
470 bool isPassed() const {
471 return (getKind() == DK_OptimizationRemark ||
472 getKind() == DK_MachineOptimizationRemark);
473 }
474
475 bool isMissed() const {
476 return (getKind() == DK_OptimizationRemarkMissed ||
477 getKind() == DK_MachineOptimizationRemarkMissed);
478 }
479
480 bool isAnalysis() const {
481 return (getKind() == DK_OptimizationRemarkAnalysis ||
482 getKind() == DK_MachineOptimizationRemarkAnalysis);
483 }
484
485protected:
486 /// Name of the pass that triggers this report. If this matches the
487 /// regular expression given in -Rpass=regexp, then the remark will
488 /// be emitted.
489 const char *PassName;
490
491 /// Textual identifier for the remark (single-word, camel-case). Can be used
492 /// by external tools reading the YAML output file for optimization remarks to
493 /// identify the remark.
494 StringRef RemarkName;
495
496 /// If profile information is available, this is the number of times the
497 /// corresponding code was executed in a profile instrumentation run.
498 Optional<uint64_t> Hotness;
499
500 /// Arguments collected via the streaming interface.
501 SmallVector<Argument, 4> Args;
502
503 /// The remark is expected to be noisy.
504 bool IsVerbose = false;
505
506 /// \brief If positive, the index of the first argument that only appear in
507 /// the optimization records and not in the remark printed in the compiler
508 /// output.
509 int FirstExtraArgIndex = -1;
510
511 friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
512};
513
514/// Allow the insertion operator to return the actual remark type rather than a
515/// common base class. This allows returning the result of the insertion
516/// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
517template <class RemarkT>
518RemarkT &
519operator<<(RemarkT &R,
520 typename std::enable_if<
521 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
522 StringRef>::type S) {
523 R.insert(S);
524 return R;
525}
526
527/// Also allow r-value for the remark to allow insertion into a
528/// temporarily-constructed remark.
529template <class RemarkT>
530RemarkT &
531operator<<(RemarkT &&R,
532 typename std::enable_if<
533 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
534 StringRef>::type S) {
535 R.insert(S);
536 return R;
537}
538
539template <class RemarkT>
540RemarkT &
541operator<<(RemarkT &R,
542 typename std::enable_if<
543 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
544 DiagnosticInfoOptimizationBase::Argument>::type A) {
545 R.insert(A);
546 return R;
547}
548
549template <class RemarkT>
550RemarkT &
551operator<<(RemarkT &&R,
552 typename std::enable_if<
553 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
554 DiagnosticInfoOptimizationBase::Argument>::type A) {
555 R.insert(A);
556 return R;
557}
558
559template <class RemarkT>
560RemarkT &
561operator<<(RemarkT &R,
562 typename std::enable_if<
563 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
564 DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
565 R.insert(V);
566 return R;
567}
568
569template <class RemarkT>
570RemarkT &
571operator<<(RemarkT &&R,
572 typename std::enable_if<
573 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
574 DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
575 R.insert(V);
576 return R;
577}
578
579template <class RemarkT>
580RemarkT &
581operator<<(RemarkT &R,
582 typename std::enable_if<
583 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
584 DiagnosticInfoOptimizationBase::setExtraArgs>::type EA) {
585 R.insert(EA);
586 return R;
587}
588
589/// \brief Common features for diagnostics dealing with optimization remarks
590/// that are used by IR passes.
591class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
592public:
593 /// \p PassName is the name of the pass emitting this diagnostic. \p
594 /// RemarkName is a textual identifier for the remark (single-word,
595 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
596 /// \p Loc is the location information to use in the diagnostic. If line table
597 /// information is available, the diagnostic will include the source code
598 /// location. \p CodeRegion is IR value (currently basic block) that the
599 /// optimization operates on. This is currently used to provide run-time
600 /// hotness information with PGO.
601 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
602 enum DiagnosticSeverity Severity,
603 const char *PassName, StringRef RemarkName,
604 const Function &Fn,
605 const DiagnosticLocation &Loc,
606 const Value *CodeRegion = nullptr)
607 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
608 Loc),
609 CodeRegion(CodeRegion) {}
610
611 /// \brief This is ctor variant allows a pass to build an optimization remark
612 /// from an existing remark.
613 ///
614 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
615 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
616 /// remark. The string \p Prepend will be emitted before the original
617 /// message.
618 DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
619 const DiagnosticInfoIROptimization &Orig)
620 : DiagnosticInfoOptimizationBase(
621 (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
622 Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
623 CodeRegion(Orig.getCodeRegion()) {
624 *this << Prepend;
625 std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
626 }
627
628 /// Legacy interface.
629 /// \p PassName is the name of the pass emitting this diagnostic.
630 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
631 /// the location information to use in the diagnostic. If line table
632 /// information is available, the diagnostic will include the source code
633 /// location. \p Msg is the message to show. Note that this class does not
634 /// copy this message, so this reference must be valid for the whole life time
635 /// of the diagnostic.
636 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
637 enum DiagnosticSeverity Severity,
638 const char *PassName, const Function &Fn,
639 const DiagnosticLocation &Loc, const Twine &Msg)
640 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
641 *this << Msg.str();
642 }
643
644 const Value *getCodeRegion() const { return CodeRegion; }
645
646 static bool classof(const DiagnosticInfo *DI) {
647 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
648 }
649
650private:
651 /// The IR value (currently basic block) that the optimization operates on.
652 /// This is currently used to provide run-time hotness information with PGO.
653 const Value *CodeRegion;
654};
655
656/// Diagnostic information for applied optimization remarks.
657class OptimizationRemark : public DiagnosticInfoIROptimization {
658public:
659 /// \p PassName is the name of the pass emitting this diagnostic. If this name
660 /// matches the regular expression given in -Rpass=, then the diagnostic will
661 /// be emitted. \p RemarkName is a textual identifier for the remark (single-
662 /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
663 /// region that the optimization operates on (currently only block is
664 /// supported).
665 OptimizationRemark(const char *PassName, StringRef RemarkName,
666 const DiagnosticLocation &Loc, const Value *CodeRegion);
667
668 /// Same as above, but the debug location and code region are derived from \p
669 /// Instr.
670 OptimizationRemark(const char *PassName, StringRef RemarkName,
671 const Instruction *Inst);
672
673 /// Same as above, but the debug location and code region are derived from \p
674 /// Func.
675 OptimizationRemark(const char *PassName, StringRef RemarkName,
676 const Function *Func);
677
678 static bool classof(const DiagnosticInfo *DI) {
679 return DI->getKind() == DK_OptimizationRemark;
680 }
681
682 /// \see DiagnosticInfoOptimizationBase::isEnabled.
683 bool isEnabled() const override;
684
685private:
686 /// This is deprecated now and only used by the function API below.
687 /// \p PassName is the name of the pass emitting this diagnostic. If
688 /// this name matches the regular expression given in -Rpass=, then the
689 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
690 /// is being emitted. \p Loc is the location information to use in the
691 /// diagnostic. If line table information is available, the diagnostic
692 /// will include the source code location. \p Msg is the message to show.
693 /// Note that this class does not copy this message, so this reference
694 /// must be valid for the whole life time of the diagnostic.
695 OptimizationRemark(const char *PassName, const Function &Fn,
696 const DiagnosticLocation &Loc, const Twine &Msg)
697 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
698 Fn, Loc, Msg) {}
699};
700
701/// Diagnostic information for missed-optimization remarks.
702class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
703public:
704 /// \p PassName is the name of the pass emitting this diagnostic. If this name
705 /// matches the regular expression given in -Rpass-missed=, then the
706 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
707 /// remark (single-word, camel-case). \p Loc is the debug location and \p
708 /// CodeRegion is the region that the optimization operates on (currently only
709 /// block is supported).
710 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
711 const DiagnosticLocation &Loc,
712 const Value *CodeRegion);
713
714 /// \brief Same as above but \p Inst is used to derive code region and debug
715 /// location.
716 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
717 const Instruction *Inst);
718
719 static bool classof(const DiagnosticInfo *DI) {
720 return DI->getKind() == DK_OptimizationRemarkMissed;
721 }
722
723 /// \see DiagnosticInfoOptimizationBase::isEnabled.
724 bool isEnabled() const override;
725
726private:
727 /// This is deprecated now and only used by the function API below.
728 /// \p PassName is the name of the pass emitting this diagnostic. If
729 /// this name matches the regular expression given in -Rpass-missed=, then the
730 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
731 /// is being emitted. \p Loc is the location information to use in the
732 /// diagnostic. If line table information is available, the diagnostic
733 /// will include the source code location. \p Msg is the message to show.
734 /// Note that this class does not copy this message, so this reference
735 /// must be valid for the whole life time of the diagnostic.
736 OptimizationRemarkMissed(const char *PassName, const Function &Fn,
737 const DiagnosticLocation &Loc, const Twine &Msg)
738 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
739 PassName, Fn, Loc, Msg) {}
740};
741
742/// Diagnostic information for optimization analysis remarks.
743class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
744public:
745 /// \p PassName is the name of the pass emitting this diagnostic. If this name
746 /// matches the regular expression given in -Rpass-analysis=, then the
747 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
748 /// remark (single-word, camel-case). \p Loc is the debug location and \p
749 /// CodeRegion is the region that the optimization operates on (currently only
750 /// block is supported).
751 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
752 const DiagnosticLocation &Loc,
753 const Value *CodeRegion);
754
755 /// \brief This is ctor variant allows a pass to build an optimization remark
756 /// from an existing remark.
757 ///
758 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
759 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
760 /// remark. The string \p Prepend will be emitted before the original
761 /// message.
762 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
763 const OptimizationRemarkAnalysis &Orig)
764 : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
765
766 /// \brief Same as above but \p Inst is used to derive code region and debug
767 /// location.
768 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
769 const Instruction *Inst);
770
771 static bool classof(const DiagnosticInfo *DI) {
772 return DI->getKind() == DK_OptimizationRemarkAnalysis;
773 }
774
775 /// \see DiagnosticInfoOptimizationBase::isEnabled.
776 bool isEnabled() const override;
777
778 static const char *AlwaysPrint;
779
780 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
781
782protected:
783 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
784 const Function &Fn, const DiagnosticLocation &Loc,
785 const Twine &Msg)
786 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
787
788 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
789 StringRef RemarkName,
790 const DiagnosticLocation &Loc,
791 const Value *CodeRegion);
792
793private:
794 /// This is deprecated now and only used by the function API below.
795 /// \p PassName is the name of the pass emitting this diagnostic. If
796 /// this name matches the regular expression given in -Rpass-analysis=, then
797 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
798 /// is being emitted. \p Loc is the location information to use in the
799 /// diagnostic. If line table information is available, the diagnostic will
800 /// include the source code location. \p Msg is the message to show. Note that
801 /// this class does not copy this message, so this reference must be valid for
802 /// the whole life time of the diagnostic.
803 OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
804 const DiagnosticLocation &Loc, const Twine &Msg)
805 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
806 PassName, Fn, Loc, Msg) {}
807};
808
809/// Diagnostic information for optimization analysis remarks related to
810/// floating-point non-commutativity.
811class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
812public:
813 /// \p PassName is the name of the pass emitting this diagnostic. If this name
814 /// matches the regular expression given in -Rpass-analysis=, then the
815 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
816 /// remark (single-word, camel-case). \p Loc is the debug location and \p
817 /// CodeRegion is the region that the optimization operates on (currently only
818 /// block is supported). The front-end will append its own message related to
819 /// options that address floating-point non-commutativity.
820 OptimizationRemarkAnalysisFPCommute(const char *PassName,
821 StringRef RemarkName,
822 const DiagnosticLocation &Loc,
823 const Value *CodeRegion)
824 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
825 PassName, RemarkName, Loc, CodeRegion) {}
826
827 static bool classof(const DiagnosticInfo *DI) {
828 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
829 }
830
831private:
832 /// This is deprecated now and only used by the function API below.
833 /// \p PassName is the name of the pass emitting this diagnostic. If
834 /// this name matches the regular expression given in -Rpass-analysis=, then
835 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
836 /// is being emitted. \p Loc is the location information to use in the
837 /// diagnostic. If line table information is available, the diagnostic will
838 /// include the source code location. \p Msg is the message to show. The
839 /// front-end will append its own message related to options that address
840 /// floating-point non-commutativity. Note that this class does not copy this
841 /// message, so this reference must be valid for the whole life time of the
842 /// diagnostic.
843 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
844 const DiagnosticLocation &Loc,
845 const Twine &Msg)
846 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
847 PassName, Fn, Loc, Msg) {}
848};
849
850/// Diagnostic information for optimization analysis remarks related to
851/// pointer aliasing.
852class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
853public:
854 /// \p PassName is the name of the pass emitting this diagnostic. If this name
855 /// matches the regular expression given in -Rpass-analysis=, then the
856 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
857 /// remark (single-word, camel-case). \p Loc is the debug location and \p
858 /// CodeRegion is the region that the optimization operates on (currently only
859 /// block is supported). The front-end will append its own message related to
860 /// options that address pointer aliasing legality.
861 OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
862 const DiagnosticLocation &Loc,
863 const Value *CodeRegion)
864 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
865 PassName, RemarkName, Loc, CodeRegion) {}
866
867 static bool classof(const DiagnosticInfo *DI) {
868 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
869 }
870
871private:
872 /// This is deprecated now and only used by the function API below.
873 /// \p PassName is the name of the pass emitting this diagnostic. If
874 /// this name matches the regular expression given in -Rpass-analysis=, then
875 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
876 /// is being emitted. \p Loc is the location information to use in the
877 /// diagnostic. If line table information is available, the diagnostic will
878 /// include the source code location. \p Msg is the message to show. The
879 /// front-end will append its own message related to options that address
880 /// pointer aliasing legality. Note that this class does not copy this
881 /// message, so this reference must be valid for the whole life time of the
882 /// diagnostic.
883 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
884 const DiagnosticLocation &Loc,
885 const Twine &Msg)
886 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
887 PassName, Fn, Loc, Msg) {}
888};
889
890/// Diagnostic information for machine IR parser.
891class DiagnosticInfoMIRParser : public DiagnosticInfo {
892 const SMDiagnostic &Diagnostic;
893
894public:
895 DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
896 const SMDiagnostic &Diagnostic)
897 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
898
899 const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
900
901 void print(DiagnosticPrinter &DP) const override;
902
903 static bool classof(const DiagnosticInfo *DI) {
904 return DI->getKind() == DK_MIRParser;
905 }
906};
907
908/// Diagnostic information for ISel fallback path.
909class DiagnosticInfoISelFallback : public DiagnosticInfo {
910 /// The function that is concerned by this diagnostic.
911 const Function &Fn;
912
913public:
914 DiagnosticInfoISelFallback(const Function &Fn,
915 DiagnosticSeverity Severity = DS_Warning)
916 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
917
918 const Function &getFunction() const { return Fn; }
919
920 void print(DiagnosticPrinter &DP) const override;
921
922 static bool classof(const DiagnosticInfo *DI) {
923 return DI->getKind() == DK_ISelFallback;
924 }
925};
926
927// Create wrappers for C Binding types (see CBindingWrapping.h).
928DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)inline DiagnosticInfo *unwrap(LLVMDiagnosticInfoRef P) { return
reinterpret_cast<DiagnosticInfo*>(P); } inline LLVMDiagnosticInfoRef
wrap(const DiagnosticInfo *P) { return reinterpret_cast<LLVMDiagnosticInfoRef
>(const_cast<DiagnosticInfo*>(P)); }
929
930/// Diagnostic information for optimization failures.
931class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
932public:
933 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
934 /// the location information to use in the diagnostic. If line table
935 /// information is available, the diagnostic will include the source code
936 /// location. \p Msg is the message to show. Note that this class does not
937 /// copy this message, so this reference must be valid for the whole life time
938 /// of the diagnostic.
939 DiagnosticInfoOptimizationFailure(const Function &Fn,
940 const DiagnosticLocation &Loc,
941 const Twine &Msg)
942 : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
943 nullptr, Fn, Loc, Msg) {}
944
945 /// \p PassName is the name of the pass emitting this diagnostic. \p
946 /// RemarkName is a textual identifier for the remark (single-word,
947 /// camel-case). \p Loc is the debug location and \p CodeRegion is the
948 /// region that the optimization operates on (currently basic block is
949 /// supported).
950 DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
951 const DiagnosticLocation &Loc,
952 const Value *CodeRegion);
953
954 static bool classof(const DiagnosticInfo *DI) {
955 return DI->getKind() == DK_OptimizationFailure;
956 }
957
958 /// \see DiagnosticInfoOptimizationBase::isEnabled.
959 bool isEnabled() const override;
960};
961
962/// Diagnostic information for unsupported feature in backend.
963class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
964private:
965 Twine Msg;
966
967public:
968 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
969 /// the location information to use in the diagnostic. If line table
970 /// information is available, the diagnostic will include the source code
971 /// location. \p Msg is the message to show. Note that this class does not
972 /// copy this message, so this reference must be valid for the whole life time
973 /// of the diagnostic.
974 DiagnosticInfoUnsupported(
975 const Function &Fn, const Twine &Msg,
976 const DiagnosticLocation &Loc = DiagnosticLocation(),
977 DiagnosticSeverity Severity = DS_Error)
978 : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
979 Msg(Msg) {}
980
981 static bool classof(const DiagnosticInfo *DI) {
982 return DI->getKind() == DK_Unsupported;
983 }
984
985 const Twine &getMessage() const { return Msg; }
986
987 void print(DiagnosticPrinter &DP) const override;
988};
989
990namespace yaml {
991template <> struct MappingTraits<DiagnosticInfoOptimizationBase *> {
992 static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag);
993};
994} // namespace yaml
995
996} // end namespace llvm
997
998#endif // LLVM_IR_DIAGNOSTICINFO_H

/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0/bits/unique_ptr.h

1// unique_ptr implementation -*- C++ -*-
2
3// Copyright (C) 2008-2017 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/unique_ptr.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30#ifndef _UNIQUE_PTR_H1
31#define _UNIQUE_PTR_H1 1
32
33#include <bits/c++config.h>
34#include <debug/assertions.h>
35#include <type_traits>
36#include <utility>
37#include <tuple>
38#include <bits/stl_function.h>
39#include <bits/functional_hash.h>
40
41namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
42{
43_GLIBCXX_BEGIN_NAMESPACE_VERSION
44
45 /**
46 * @addtogroup pointer_abstractions
47 * @{
48 */
49
50#if _GLIBCXX_USE_DEPRECATED1
51 template<typename> class auto_ptr;
52#endif
53
54 /// Primary template of default_delete, used by unique_ptr
55 template<typename _Tp>
56 struct default_delete
57 {
58 /// Default constructor
59 constexpr default_delete() noexcept = default;
60
61 /** @brief Converting constructor.
62 *
63 * Allows conversion from a deleter for arrays of another type, @p _Up,
64 * only if @p _Up* is convertible to @p _Tp*.
65 */
66 template<typename _Up, typename = typename
67 enable_if<is_convertible<_Up*, _Tp*>::value>::type>
68 default_delete(const default_delete<_Up>&) noexcept { }
69
70 /// Calls @c delete @p __ptr
71 void
72 operator()(_Tp* __ptr) const
73 {
74 static_assert(!is_void<_Tp>::value,
75 "can't delete pointer to incomplete type");
76 static_assert(sizeof(_Tp)>0,
77 "can't delete pointer to incomplete type");
78 delete __ptr;
79 }
80 };
81
82 // _GLIBCXX_RESOLVE_LIB_DEFECTS
83 // DR 740 - omit specialization for array objects with a compile time length
84 /// Specialization for arrays, default_delete.
85 template<typename _Tp>
86 struct default_delete<_Tp[]>
87 {
88 public:
89 /// Default constructor
90 constexpr default_delete() noexcept = default;
91
92 /** @brief Converting constructor.
93 *
94 * Allows conversion from a deleter for arrays of another type, such as
95 * a const-qualified version of @p _Tp.
96 *
97 * Conversions from types derived from @c _Tp are not allowed because
98 * it is unsafe to @c delete[] an array of derived types through a
99 * pointer to the base type.
100 */
101 template<typename _Up, typename = typename
102 enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
103 default_delete(const default_delete<_Up[]>&) noexcept { }
104
105 /// Calls @c delete[] @p __ptr
106 template<typename _Up>
107 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
108 operator()(_Up* __ptr) const
109 {
110 static_assert(sizeof(_Tp)>0,
111 "can't delete pointer to incomplete type");
112 delete [] __ptr;
113 }
114 };
115
116 template <typename _Tp, typename _Dp>
117 class __uniq_ptr_impl
118 {
119 template <typename _Up, typename _Ep, typename = void>
120 struct _Ptr
121 {
122 using type = _Up*;
123 };
124
125 template <typename _Up, typename _Ep>
126 struct
127 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
128 {
129 using type = typename remove_reference<_Ep>::type::pointer;
130 };
131
132 public:
133 using _DeleterConstraint = enable_if<
134 __and_<__not_<is_pointer<_Dp>>,
135 is_default_constructible<_Dp>>::value>;
136
137 using pointer = typename _Ptr<_Tp, _Dp>::type;
138
139 __uniq_ptr_impl() = default;
140 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
141
142 template<typename _Del>
143 __uniq_ptr_impl(pointer __p, _Del&& __d)
144 : _M_t(__p, std::forward<_Del>(__d)) { }
145
146 pointer& _M_ptr() { return std::get<0>(_M_t); }
147 pointer _M_ptr() const { return std::get<0>(_M_t); }
27
Calling 'get'
34
Returning from 'get'
148 _Dp& _M_deleter() { return std::get<1>(_M_t); }
149 const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
150
151 private:
152 tuple<pointer, _Dp> _M_t;
153 };
154
155 /// 20.7.1.2 unique_ptr for single objects.
156 template <typename _Tp, typename _Dp = default_delete<_Tp>>
157 class unique_ptr
158 {
159 template <class _Up>
160 using _DeleterConstraint =
161 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
162
163 __uniq_ptr_impl<_Tp, _Dp> _M_t;
164
165 public:
166 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
167 using element_type = _Tp;
168 using deleter_type = _Dp;
169
170 // helper template for detecting a safe conversion from another
171 // unique_ptr
172 template<typename _Up, typename _Ep>
173 using __safe_conversion_up = __and_<
174 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
175 __not_<is_array<_Up>>,
176 __or_<__and_<is_reference<deleter_type>,
177 is_same<deleter_type, _Ep>>,
178 __and_<__not_<is_reference<deleter_type>>,
179 is_convertible<_Ep, deleter_type>>
180 >
181 >;
182
183 // Constructors.
184
185 /// Default constructor, creates a unique_ptr that owns nothing.
186 template <typename _Up = _Dp,
187 typename = _DeleterConstraint<_Up>>
188 constexpr unique_ptr() noexcept
189 : _M_t()
190 { }
191
192 /** Takes ownership of a pointer.
193 *
194 * @param __p A pointer to an object of @c element_type
195 *
196 * The deleter will be value-initialized.
197 */
198 template <typename _Up = _Dp,
199 typename = _DeleterConstraint<_Up>>
200 explicit
201 unique_ptr(pointer __p) noexcept
202 : _M_t(__p)
203 { }
204
205 /** Takes ownership of a pointer.
206 *
207 * @param __p A pointer to an object of @c element_type
208 * @param __d A reference to a deleter.
209 *
210 * The deleter will be initialized with @p __d
211 */
212 unique_ptr(pointer __p,
213 typename conditional<is_reference<deleter_type>::value,
214 deleter_type, const deleter_type&>::type __d) noexcept
215 : _M_t(__p, __d) { }
216
217 /** Takes ownership of a pointer.
218 *
219 * @param __p A pointer to an object of @c element_type
220 * @param __d An rvalue reference to a deleter.
221 *
222 * The deleter will be initialized with @p std::move(__d)
223 */
224 unique_ptr(pointer __p,
225 typename remove_reference<deleter_type>::type&& __d) noexcept
226 : _M_t(std::move(__p), std::move(__d))
227 { static_assert(!std::is_reference<deleter_type>::value,
228 "rvalue deleter bound to reference"); }
229
230 /// Creates a unique_ptr that owns nothing.
231 template <typename _Up = _Dp,
232 typename = _DeleterConstraint<_Up>>
233 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
234
235 // Move constructors.
236
237 /// Move constructor.
238 unique_ptr(unique_ptr&& __u) noexcept
239 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
240
241 /** @brief Converting constructor from another type
242 *
243 * Requires that the pointer owned by @p __u is convertible to the
244 * type of pointer owned by this object, @p __u does not own an array,
245 * and @p __u has a compatible deleter type.
246 */
247 template<typename _Up, typename _Ep, typename = _Require<
248 __safe_conversion_up<_Up, _Ep>,
249 typename conditional<is_reference<_Dp>::value,
250 is_same<_Ep, _Dp>,
251 is_convertible<_Ep, _Dp>>::type>>
252 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
253 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
254 { }
255
256#if _GLIBCXX_USE_DEPRECATED1
257 /// Converting constructor from @c auto_ptr
258 template<typename _Up, typename = _Require<
259 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
260 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
261#endif
262
263 /// Destructor, invokes the deleter if the stored pointer is not null.
264 ~unique_ptr() noexcept
265 {
266 auto& __ptr = _M_t._M_ptr();
267 if (__ptr != nullptr)
268 get_deleter()(__ptr);
269 __ptr = pointer();
270 }
271
272 // Assignment.
273
274 /** @brief Move assignment operator.
275 *
276 * @param __u The object to transfer ownership from.
277 *
278 * Invokes the deleter first if this object owns a pointer.
279 */
280 unique_ptr&
281 operator=(unique_ptr&& __u) noexcept
282 {
283 reset(__u.release());
284 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
285 return *this;
286 }
287
288 /** @brief Assignment from another type.
289 *
290 * @param __u The object to transfer ownership from, which owns a
291 * convertible pointer to a non-array object.
292 *
293 * Invokes the deleter first if this object owns a pointer.
294 */
295 template<typename _Up, typename _Ep>
296 typename enable_if< __and_<
297 __safe_conversion_up<_Up, _Ep>,
298 is_assignable<deleter_type&, _Ep&&>
299 >::value,
300 unique_ptr&>::type
301 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
302 {
303 reset(__u.release());
304 get_deleter() = std::forward<_Ep>(__u.get_deleter());
305 return *this;
306 }
307
308 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
309 unique_ptr&
310 operator=(nullptr_t) noexcept
311 {
312 reset();
313 return *this;
314 }
315
316 // Observers.
317
318 /// Dereference the stored pointer.
319 typename add_lvalue_reference<element_type>::type
320 operator*() const
321 {
322 __glibcxx_assert(get() != pointer());
323 return *get();
324 }
325
326 /// Return the stored pointer.
327 pointer
328 operator->() const noexcept
329 {
330 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
331 return get();
25
Calling 'unique_ptr::get'
36
Returning from 'unique_ptr::get'
332 }
333
334 /// Return the stored pointer.
335 pointer
336 get() const noexcept
337 { return _M_t._M_ptr(); }
26
Calling '__uniq_ptr_impl::_M_ptr'
35
Returning from '__uniq_ptr_impl::_M_ptr'
338
339 /// Return a reference to the stored deleter.
340 deleter_type&
341 get_deleter() noexcept
342 { return _M_t._M_deleter(); }
343
344 /// Return a reference to the stored deleter.
345 const deleter_type&
346 get_deleter() const noexcept
347 { return _M_t._M_deleter(); }
348
349 /// Return @c true if the stored pointer is not null.
350 explicit operator bool() const noexcept
351 { return get() == pointer() ? false : true; }
352
353 // Modifiers.
354
355 /// Release ownership of any stored pointer.
356 pointer
357 release() noexcept
358 {
359 pointer __p = get();
360 _M_t._M_ptr() = pointer();
361 return __p;
362 }
363
364 /** @brief Replace the stored pointer.
365 *
366 * @param __p The new pointer to store.
367 *
368 * The deleter will be invoked if a pointer is already owned.
369 */
370 void
371 reset(pointer __p = pointer()) noexcept
372 {
373 using std::swap;
374 swap(_M_t._M_ptr(), __p);
375 if (__p != pointer())
376 get_deleter()(__p);
377 }
378
379 /// Exchange the pointer and deleter with another object.
380 void
381 swap(unique_ptr& __u) noexcept
382 {
383 using std::swap;
384 swap(_M_t, __u._M_t);
385 }
386
387 // Disable copy from lvalue.
388 unique_ptr(const unique_ptr&) = delete;
389 unique_ptr& operator=(const unique_ptr&) = delete;
390 };
391
392 /// 20.7.1.3 unique_ptr for array objects with a runtime length
393 // [unique.ptr.runtime]
394 // _GLIBCXX_RESOLVE_LIB_DEFECTS
395 // DR 740 - omit specialization for array objects with a compile time length
396 template<typename _Tp, typename _Dp>
397 class unique_ptr<_Tp[], _Dp>
398 {
399 template <typename _Up>
400 using _DeleterConstraint =
401 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
402
403 __uniq_ptr_impl<_Tp, _Dp> _M_t;
404
405 template<typename _Up>
406 using __remove_cv = typename remove_cv<_Up>::type;
407
408 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
409 template<typename _Up>
410 using __is_derived_Tp
411 = __and_< is_base_of<_Tp, _Up>,
412 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
413
414 public:
415 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
416 using element_type = _Tp;
417 using deleter_type = _Dp;
418
419 // helper template for detecting a safe conversion from another
420 // unique_ptr
421 template<typename _Up, typename _Ep,
422 typename _Up_up = unique_ptr<_Up, _Ep>,
423 typename _Up_element_type = typename _Up_up::element_type>
424 using __safe_conversion_up = __and_<
425 is_array<_Up>,
426 is_same<pointer, element_type*>,
427 is_same<typename _Up_up::pointer, _Up_element_type*>,
428 is_convertible<_Up_element_type(*)[], element_type(*)[]>,
429 __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>,
430 __and_<__not_<is_reference<deleter_type>>,
431 is_convertible<_Ep, deleter_type>>>
432 >;
433
434 // helper template for detecting a safe conversion from a raw pointer
435 template<typename _Up>
436 using __safe_conversion_raw = __and_<
437 __or_<__or_<is_same<_Up, pointer>,
438 is_same<_Up, nullptr_t>>,
439 __and_<is_pointer<_Up>,
440 is_same<pointer, element_type*>,
441 is_convertible<
442 typename remove_pointer<_Up>::type(*)[],
443 element_type(*)[]>
444 >
445 >
446 >;
447
448 // Constructors.
449
450 /// Default constructor, creates a unique_ptr that owns nothing.
451 template <typename _Up = _Dp,
452 typename = _DeleterConstraint<_Up>>
453 constexpr unique_ptr() noexcept
454 : _M_t()
455 { }
456
457 /** Takes ownership of a pointer.
458 *
459 * @param __p A pointer to an array of a type safely convertible
460 * to an array of @c element_type
461 *
462 * The deleter will be value-initialized.
463 */
464 template<typename _Up,
465 typename _Vp = _Dp,
466 typename = _DeleterConstraint<_Vp>,
467 typename = typename enable_if<
468 __safe_conversion_raw<_Up>::value, bool>::type>
469 explicit
470 unique_ptr(_Up __p) noexcept
471 : _M_t(__p)
472 { }
473
474 /** Takes ownership of a pointer.
475 *
476 * @param __p A pointer to an array of a type safely convertible
477 * to an array of @c element_type
478 * @param __d A reference to a deleter.
479 *
480 * The deleter will be initialized with @p __d
481 */
482 template<typename _Up,
483 typename = typename enable_if<
484 __safe_conversion_raw<_Up>::value, bool>::type>
485 unique_ptr(_Up __p,
486 typename conditional<is_reference<deleter_type>::value,
487 deleter_type, const deleter_type&>::type __d) noexcept
488 : _M_t(__p, __d) { }
489
490 /** Takes ownership of a pointer.
491 *
492 * @param __p A pointer to an array of a type safely convertible
493 * to an array of @c element_type
494 * @param __d A reference to a deleter.
495 *
496 * The deleter will be initialized with @p std::move(__d)
497 */
498 template<typename _Up,
499 typename = typename enable_if<
500 __safe_conversion_raw<_Up>::value, bool>::type>
501 unique_ptr(_Up __p, typename
502 remove_reference<deleter_type>::type&& __d) noexcept
503 : _M_t(std::move(__p), std::move(__d))
504 { static_assert(!is_reference<deleter_type>::value,
505 "rvalue deleter bound to reference"); }
506
507 /// Move constructor.
508 unique_ptr(unique_ptr&& __u) noexcept
509 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
510
511 /// Creates a unique_ptr that owns nothing.
512 template <typename _Up = _Dp,
513 typename = _DeleterConstraint<_Up>>
514 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
515
516 template<typename _Up, typename _Ep,
517 typename = _Require<__safe_conversion_up<_Up, _Ep>>>
518 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
519 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
520 { }
521
522 /// Destructor, invokes the deleter if the stored pointer is not null.
523 ~unique_ptr()
524 {
525 auto& __ptr = _M_t._M_ptr();
526 if (__ptr != nullptr)
527 get_deleter()(__ptr);
528 __ptr = pointer();
529 }
530
531 // Assignment.
532
533 /** @brief Move assignment operator.
534 *
535 * @param __u The object to transfer ownership from.
536 *
537 * Invokes the deleter first if this object owns a pointer.
538 */
539 unique_ptr&
540 operator=(unique_ptr&& __u) noexcept
541 {
542 reset(__u.release());
543 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
544 return *this;
545 }
546
547 /** @brief Assignment from another type.
548 *
549 * @param __u The object to transfer ownership from, which owns a
550 * convertible pointer to an array object.
551 *
552 * Invokes the deleter first if this object owns a pointer.
553 */
554 template<typename _Up, typename _Ep>
555 typename
556 enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
557 is_assignable<deleter_type&, _Ep&&>
558 >::value,
559 unique_ptr&>::type
560 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
561 {
562 reset(__u.release());
563 get_deleter() = std::forward<_Ep>(__u.get_deleter());
564 return *this;
565 }
566
567 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
568 unique_ptr&
569 operator=(nullptr_t) noexcept
570 {
571 reset();
572 return *this;
573 }
574
575 // Observers.
576
577 /// Access an element of owned array.
578 typename std::add_lvalue_reference<element_type>::type
579 operator[](size_t __i) const
580 {
581 __glibcxx_assert(get() != pointer());
582 return get()[__i];
583 }
584
585 /// Return the stored pointer.
586 pointer
587 get() const noexcept
588 { return _M_t._M_ptr(); }
589
590 /// Return a reference to the stored deleter.
591 deleter_type&
592 get_deleter() noexcept
593 { return _M_t._M_deleter(); }
594
595 /// Return a reference to the stored deleter.
596 const deleter_type&
597 get_deleter() const noexcept
598 { return _M_t._M_deleter(); }
599
600 /// Return @c true if the stored pointer is not null.
601 explicit operator bool() const noexcept
602 { return get() == pointer() ? false : true; }
603
604 // Modifiers.
605
606 /// Release ownership of any stored pointer.
607 pointer
608 release() noexcept
609 {
610 pointer __p = get();
611 _M_t._M_ptr() = pointer();
612 return __p;
613 }
614
615 /** @brief Replace the stored pointer.
616 *
617 * @param __p The new pointer to store.
618 *
619 * The deleter will be invoked if a pointer is already owned.
620 */
621 template <typename _Up,
622 typename = _Require<
623 __or_<is_same<_Up, pointer>,
624 __and_<is_same<pointer, element_type*>,
625 is_pointer<_Up>,
626 is_convertible<
627 typename remove_pointer<_Up>::type(*)[],
628 element_type(*)[]
629 >
630 >
631 >
632 >>
633 void
634 reset(_Up __p) noexcept
635 {
636 pointer __ptr = __p;
637 using std::swap;
638 swap(_M_t._M_ptr(), __ptr);
639 if (__ptr != nullptr)
640 get_deleter()(__ptr);
641 }
642
643 void reset(nullptr_t = nullptr) noexcept
644 {
645 reset(pointer());
646 }
647
648 /// Exchange the pointer and deleter with another object.
649 void
650 swap(unique_ptr& __u) noexcept
651 {
652 using std::swap;
653 swap(_M_t, __u._M_t);
654 }
655
656 // Disable copy from lvalue.
657 unique_ptr(const unique_ptr&) = delete;
658 unique_ptr& operator=(const unique_ptr&) = delete;
659 };
660
661 template<typename _Tp, typename _Dp>
662 inline
663#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
664 // Constrained free swap overload, see p0185r1
665 typename enable_if<__is_swappable<_Dp>::value>::type
666#else
667 void
668#endif
669 swap(unique_ptr<_Tp, _Dp>& __x,
670 unique_ptr<_Tp, _Dp>& __y) noexcept
671 { __x.swap(__y); }
672
673#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
674 template<typename _Tp, typename _Dp>
675 typename enable_if<!__is_swappable<_Dp>::value>::type
676 swap(unique_ptr<_Tp, _Dp>&,
677 unique_ptr<_Tp, _Dp>&) = delete;
678#endif
679
680 template<typename _Tp, typename _Dp,
681 typename _Up, typename _Ep>
682 inline bool
683 operator==(const unique_ptr<_Tp, _Dp>& __x,
684 const unique_ptr<_Up, _Ep>& __y)
685 { return __x.get() == __y.get(); }
686
687 template<typename _Tp, typename _Dp>
688 inline bool
689 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
690 { return !__x; }
691
692 template<typename _Tp, typename _Dp>
693 inline bool
694 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
695 { return !__x; }
696
697 template<typename _Tp, typename _Dp,
698 typename _Up, typename _Ep>
699 inline bool
700 operator!=(const unique_ptr<_Tp, _Dp>& __x,
701 const unique_ptr<_Up, _Ep>& __y)
702 { return __x.get() != __y.get(); }
703
704 template<typename _Tp, typename _Dp>
705 inline bool
706 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
707 { return (bool)__x; }
708
709 template<typename _Tp, typename _Dp>
710 inline bool
711 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
712 { return (bool)__x; }
713
714 template<typename _Tp, typename _Dp,
715 typename _Up, typename _Ep>
716 inline bool
717 operator<(const unique_ptr<_Tp, _Dp>& __x,
718 const unique_ptr<_Up, _Ep>& __y)
719 {
720 typedef typename
721 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
722 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
723 return std::less<_CT>()(__x.get(), __y.get());
724 }
725
726 template<typename _Tp, typename _Dp>
727 inline bool
728 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
729 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
730 nullptr); }
731
732 template<typename _Tp, typename _Dp>
733 inline bool
734 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
735 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
736 __x.get()); }
737
738 template<typename _Tp, typename _Dp,
739 typename _Up, typename _Ep>
740 inline bool
741 operator<=(const unique_ptr<_Tp, _Dp>& __x,
742 const unique_ptr<_Up, _Ep>& __y)
743 { return !(__y < __x); }
744
745 template<typename _Tp, typename _Dp>
746 inline bool
747 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
748 { return !(nullptr < __x); }
749
750 template<typename _Tp, typename _Dp>
751 inline bool
752 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
753 { return !(__x < nullptr); }
754
755 template<typename _Tp, typename _Dp,
756 typename _Up, typename _Ep>
757 inline bool
758 operator>(const unique_ptr<_Tp, _Dp>& __x,
759 const unique_ptr<_Up, _Ep>& __y)
760 { return (__y < __x); }
761
762 template<typename _Tp, typename _Dp>
763 inline bool
764 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
765 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
766 __x.get()); }
767
768 template<typename _Tp, typename _Dp>
769 inline bool
770 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
771 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
772 nullptr); }
773
774 template<typename _Tp, typename _Dp,
775 typename _Up, typename _Ep>
776 inline bool
777 operator>=(const unique_ptr<_Tp, _Dp>& __x,
778 const unique_ptr<_Up, _Ep>& __y)
779 { return !(__x < __y); }
780
781 template<typename _Tp, typename _Dp>
782 inline bool
783 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
784 { return !(__x < nullptr); }
785
786 template<typename _Tp, typename _Dp>
787 inline bool
788 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
789 { return !(nullptr < __x); }
790
791 /// std::hash specialization for unique_ptr.
792 template<typename _Tp, typename _Dp>
793 struct hash<unique_ptr<_Tp, _Dp>>
794 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
795 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
796 {
797 size_t
798 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
799 {
800 typedef unique_ptr<_Tp, _Dp> _UP;
801 return std::hash<typename _UP::pointer>()(__u.get());
802 }
803 };
804
805#if __cplusplus201103L > 201103L
806
807#define __cpp_lib_make_unique 201304
808
809 template<typename _Tp>
810 struct _MakeUniq
811 { typedef unique_ptr<_Tp> __single_object; };
812
813 template<typename _Tp>
814 struct _MakeUniq<_Tp[]>
815 { typedef unique_ptr<_Tp[]> __array; };
816
817 template<typename _Tp, size_t _Bound>
818 struct _MakeUniq<_Tp[_Bound]>
819 { struct __invalid_type { }; };
820
821 /// std::make_unique for single objects
822 template<typename _Tp, typename... _Args>
823 inline typename _MakeUniq<_Tp>::__single_object
824 make_unique(_Args&&... __args)
825 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
826
827 /// std::make_unique for arrays of unknown bound
828 template<typename _Tp>
829 inline typename _MakeUniq<_Tp>::__array
830 make_unique(size_t __num)
831 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
832
833 /// Disable std::make_unique for arrays of known bound
834 template<typename _Tp, typename... _Args>
835 inline typename _MakeUniq<_Tp>::__invalid_type
836 make_unique(_Args&&...) = delete;
837#endif
838
839 // @} group pointer_abstractions
840
841_GLIBCXX_END_NAMESPACE_VERSION
842} // namespace
843
844#endif /* _UNIQUE_PTR_H */

/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0/tuple

1// <tuple> -*- C++ -*-
2
3// Copyright (C) 2007-2017 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/tuple
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_TUPLE1
30#define _GLIBCXX_TUPLE1 1
31
32#pragma GCC system_header
33
34#if __cplusplus201103L < 201103L
35# include <bits/c++0x_warning.h>
36#else
37
38#include <utility>
39#include <array>
40#include <bits/uses_allocator.h>
41#include <bits/invoke.h>
42
43namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
44{
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
46
47 /**
48 * @addtogroup utilities
49 * @{
50 */
51
52 template<typename... _Elements>
53 class tuple;
54
55 template<typename _Tp>
56 struct __is_empty_non_tuple : is_empty<_Tp> { };
57
58 // Using EBO for elements that are tuples causes ambiguous base errors.
59 template<typename _El0, typename... _El>
60 struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
61
62 // Use the Empty Base-class Optimization for empty, non-final types.
63 template<typename _Tp>
64 using __empty_not_final
65 = typename conditional<__is_final(_Tp), false_type,
66 __is_empty_non_tuple<_Tp>>::type;
67
68 template<std::size_t _Idx, typename _Head,
69 bool = __empty_not_final<_Head>::value>
70 struct _Head_base;
71
72 template<std::size_t _Idx, typename _Head>
73 struct _Head_base<_Idx, _Head, true>
74 : public _Head
75 {
76 constexpr _Head_base()
77 : _Head() { }
78
79 constexpr _Head_base(const _Head& __h)
80 : _Head(__h) { }
81
82 constexpr _Head_base(const _Head_base&) = default;
83 constexpr _Head_base(_Head_base&&) = default;
84
85 template<typename _UHead>
86 constexpr _Head_base(_UHead&& __h)
87 : _Head(std::forward<_UHead>(__h)) { }
88
89 _Head_base(allocator_arg_t, __uses_alloc0)
90 : _Head() { }
91
92 template<typename _Alloc>
93 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
94 : _Head(allocator_arg, *__a._M_a) { }
95
96 template<typename _Alloc>
97 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
98 : _Head(*__a._M_a) { }
99
100 template<typename _UHead>
101 _Head_base(__uses_alloc0, _UHead&& __uhead)
102 : _Head(std::forward<_UHead>(__uhead)) { }
103
104 template<typename _Alloc, typename _UHead>
105 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
106 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
107
108 template<typename _Alloc, typename _UHead>
109 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
110 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
111
112 static constexpr _Head&
113 _M_head(_Head_base& __b) noexcept { return __b; }
114
115 static constexpr const _Head&
116 _M_head(const _Head_base& __b) noexcept { return __b; }
117 };
118
119 template<std::size_t _Idx, typename _Head>
120 struct _Head_base<_Idx, _Head, false>
121 {
122 constexpr _Head_base()
123 : _M_head_impl() { }
124
125 constexpr _Head_base(const _Head& __h)
126 : _M_head_impl(__h) { }
127
128 constexpr _Head_base(const _Head_base&) = default;
129 constexpr _Head_base(_Head_base&&) = default;
130
131 template<typename _UHead>
132 constexpr _Head_base(_UHead&& __h)
133 : _M_head_impl(std::forward<_UHead>(__h)) { }
134
135 _Head_base(allocator_arg_t, __uses_alloc0)
136 : _M_head_impl() { }
137
138 template<typename _Alloc>
139 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
140 : _M_head_impl(allocator_arg, *__a._M_a) { }
141
142 template<typename _Alloc>
143 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
144 : _M_head_impl(*__a._M_a) { }
145
146 template<typename _UHead>
147 _Head_base(__uses_alloc0, _UHead&& __uhead)
148 : _M_head_impl(std::forward<_UHead>(__uhead)) { }
149
150 template<typename _Alloc, typename _UHead>
151 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
152 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
153 { }
154
155 template<typename _Alloc, typename _UHead>
156 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
157 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
158
159 static constexpr _Head&
160 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
161
162 static constexpr const _Head&
163 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
164
165 _Head _M_head_impl;
166 };
167
168 /**
169 * Contains the actual implementation of the @c tuple template, stored
170 * as a recursive inheritance hierarchy from the first element (most
171 * derived class) to the last (least derived class). The @c Idx
172 * parameter gives the 0-based index of the element stored at this
173 * point in the hierarchy; we use it to implement a constant-time
174 * get() operation.
175 */
176 template<std::size_t _Idx, typename... _Elements>
177 struct _Tuple_impl;
178
179 /**
180 * Recursive tuple implementation. Here we store the @c Head element
181 * and derive from a @c Tuple_impl containing the remaining elements
182 * (which contains the @c Tail).
183 */
184 template<std::size_t _Idx, typename _Head, typename... _Tail>
185 struct _Tuple_impl<_Idx, _Head, _Tail...>
186 : public _Tuple_impl<_Idx + 1, _Tail...>,
187 private _Head_base<_Idx, _Head>
188 {
189 template<std::size_t, typename...> friend class _Tuple_impl;
190
191 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
192 typedef _Head_base<_Idx, _Head> _Base;
193
194 static constexpr _Head&
195 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
196
197 static constexpr const _Head&
198 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
30
Calling '_Head_base::_M_head'
31
Returning from '_Head_base::_M_head'
199
200 static constexpr _Inherited&
201 _M_tail(_Tuple_impl& __t) noexcept { return __t; }
202
203 static constexpr const _Inherited&
204 _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
205
206 constexpr _Tuple_impl()
207 : _Inherited(), _Base() { }
208
209 explicit
210 constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
211 : _Inherited(__tail...), _Base(__head) { }
212
213 template<typename _UHead, typename... _UTail, typename = typename
214 enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
215 explicit
216 constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
217 : _Inherited(std::forward<_UTail>(__tail)...),
218 _Base(std::forward<_UHead>(__head)) { }
219
220 constexpr _Tuple_impl(const _Tuple_impl&) = default;
221
222 constexpr
223 _Tuple_impl(_Tuple_impl&& __in)
224 noexcept(__and_<is_nothrow_move_constructible<_Head>,
225 is_nothrow_move_constructible<_Inherited>>::value)
226 : _Inherited(std::move(_M_tail(__in))),
227 _Base(std::forward<_Head>(_M_head(__in))) { }
228
229 template<typename... _UElements>
230 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
231 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
232 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
233
234 template<typename _UHead, typename... _UTails>
235 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
236 : _Inherited(std::move
237 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
238 _Base(std::forward<_UHead>
239 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
240
241 template<typename _Alloc>
242 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
243 : _Inherited(__tag, __a),
244 _Base(__tag, __use_alloc<_Head>(__a)) { }
245
246 template<typename _Alloc>
247 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
248 const _Head& __head, const _Tail&... __tail)
249 : _Inherited(__tag, __a, __tail...),
250 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
251
252 template<typename _Alloc, typename _UHead, typename... _UTail,
253 typename = typename enable_if<sizeof...(_Tail)
254 == sizeof...(_UTail)>::type>
255 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
256 _UHead&& __head, _UTail&&... __tail)
257 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
258 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
259 std::forward<_UHead>(__head)) { }
260
261 template<typename _Alloc>
262 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
263 const _Tuple_impl& __in)
264 : _Inherited(__tag, __a, _M_tail(__in)),
265 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
266
267 template<typename _Alloc>
268 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
269 _Tuple_impl&& __in)
270 : _Inherited(__tag, __a, std::move(_M_tail(__in))),
271 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
272 std::forward<_Head>(_M_head(__in))) { }
273
274 template<typename _Alloc, typename... _UElements>
275 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
276 const _Tuple_impl<_Idx, _UElements...>& __in)
277 : _Inherited(__tag, __a,
278 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
279 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
280 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
281
282 template<typename _Alloc, typename _UHead, typename... _UTails>
283 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
284 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
285 : _Inherited(__tag, __a, std::move
286 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
287 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
288 std::forward<_UHead>
289 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
290
291 _Tuple_impl&
292 operator=(const _Tuple_impl& __in)
293 {
294 _M_head(*this) = _M_head(__in);
295 _M_tail(*this) = _M_tail(__in);
296 return *this;
297 }
298
299 _Tuple_impl&
300 operator=(_Tuple_impl&& __in)
301 noexcept(__and_<is_nothrow_move_assignable<_Head>,
302 is_nothrow_move_assignable<_Inherited>>::value)
303 {
304 _M_head(*this) = std::forward<_Head>(_M_head(__in));
305 _M_tail(*this) = std::move(_M_tail(__in));
306 return *this;
307 }
308
309 template<typename... _UElements>
310 _Tuple_impl&
311 operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
312 {
313 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
314 _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
315 return *this;
316 }
317
318 template<typename _UHead, typename... _UTails>
319 _Tuple_impl&
320 operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
321 {
322 _M_head(*this) = std::forward<_UHead>
323 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
324 _M_tail(*this) = std::move
325 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
326 return *this;
327 }
328
329 protected:
330 void
331 _M_swap(_Tuple_impl& __in)
332 noexcept(__is_nothrow_swappable<_Head>::value
333 && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
334 {
335 using std::swap;
336 swap(_M_head(*this), _M_head(__in));
337 _Inherited::_M_swap(_M_tail(__in));
338 }
339 };
340
341 // Basis case of inheritance recursion.
342 template<std::size_t _Idx, typename _Head>
343 struct _Tuple_impl<_Idx, _Head>
344 : private _Head_base<_Idx, _Head>
345 {
346 template<std::size_t, typename...> friend class _Tuple_impl;
347
348 typedef _Head_base<_Idx, _Head> _Base;
349
350 static constexpr _Head&
351 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
352
353 static constexpr const _Head&
354 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
355
356 constexpr _Tuple_impl()
357 : _Base() { }
358
359 explicit
360 constexpr _Tuple_impl(const _Head& __head)
361 : _Base(__head) { }
362
363 template<typename _UHead>
364 explicit
365 constexpr _Tuple_impl(_UHead&& __head)
366 : _Base(std::forward<_UHead>(__head)) { }
367
368 constexpr _Tuple_impl(const _Tuple_impl&) = default;
369
370 constexpr
371 _Tuple_impl(_Tuple_impl&& __in)
372 noexcept(is_nothrow_move_constructible<_Head>::value)
373 : _Base(std::forward<_Head>(_M_head(__in))) { }
374
375 template<typename _UHead>
376 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
377 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
378
379 template<typename _UHead>
380 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
381 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
382 { }
383
384 template<typename _Alloc>
385 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
386 : _Base(__tag, __use_alloc<_Head>(__a)) { }
387
388 template<typename _Alloc>
389 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
390 const _Head& __head)
391 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
392
393 template<typename _Alloc, typename _UHead>
394 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
395 _UHead&& __head)
396 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
397 std::forward<_UHead>(__head)) { }
398
399 template<typename _Alloc>
400 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
401 const _Tuple_impl& __in)
402 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
403
404 template<typename _Alloc>
405 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
406 _Tuple_impl&& __in)
407 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
408 std::forward<_Head>(_M_head(__in))) { }
409
410 template<typename _Alloc, typename _UHead>
411 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
412 const _Tuple_impl<_Idx, _UHead>& __in)
413 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
414 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
415
416 template<typename _Alloc, typename _UHead>
417 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
418 _Tuple_impl<_Idx, _UHead>&& __in)
419 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
420 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
421 { }
422
423 _Tuple_impl&
424 operator=(const _Tuple_impl& __in)
425 {
426 _M_head(*this) = _M_head(__in);
427 return *this;
428 }
429
430 _Tuple_impl&
431 operator=(_Tuple_impl&& __in)
432 noexcept(is_nothrow_move_assignable<_Head>::value)
433 {
434 _M_head(*this) = std::forward<_Head>(_M_head(__in));
435 return *this;
436 }
437
438 template<typename _UHead>
439 _Tuple_impl&
440 operator=(const _Tuple_impl<_Idx, _UHead>& __in)
441 {
442 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
443 return *this;
444 }
445
446 template<typename _UHead>
447 _Tuple_impl&
448 operator=(_Tuple_impl<_Idx, _UHead>&& __in)
449 {
450 _M_head(*this)
451 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
452 return *this;
453 }
454
455 protected:
456 void
457 _M_swap(_Tuple_impl& __in)
458 noexcept(__is_nothrow_swappable<_Head>::value)
459 {
460 using std::swap;
461 swap(_M_head(*this), _M_head(__in));
462 }
463 };
464
465 // Concept utility functions, reused in conditionally-explicit
466 // constructors.
467 template<bool, typename... _Elements>
468 struct _TC
469 {
470 template<typename... _UElements>
471 static constexpr bool _ConstructibleTuple()
472 {
473 return __and_<is_constructible<_Elements, const _UElements&>...>::value;
474 }
475
476 template<typename... _UElements>
477 static constexpr bool _ImplicitlyConvertibleTuple()
478 {
479 return __and_<is_convertible<const _UElements&, _Elements>...>::value;
480 }
481
482 template<typename... _UElements>
483 static constexpr bool _MoveConstructibleTuple()
484 {
485 return __and_<is_constructible<_Elements, _UElements&&>...>::value;
486 }
487
488 template<typename... _UElements>
489 static constexpr bool _ImplicitlyMoveConvertibleTuple()
490 {
491 return __and_<is_convertible<_UElements&&, _Elements>...>::value;
492 }
493
494 template<typename _SrcTuple>
495 static constexpr bool _NonNestedTuple()
496 {
497 return __and_<__not_<is_same<tuple<_Elements...>,
498 typename remove_cv<
499 typename remove_reference<_SrcTuple>::type
500 >::type>>,
501 __not_<is_convertible<_SrcTuple, _Elements...>>,
502 __not_<is_constructible<_Elements..., _SrcTuple>>
503 >::value;
504 }
505 template<typename... _UElements>
506 static constexpr bool _NotSameTuple()
507 {
508 return __not_<is_same<tuple<_Elements...>,
509 typename remove_const<
510 typename remove_reference<_UElements...>::type
511 >::type>>::value;
512 }
513 };
514
515 template<typename... _Elements>
516 struct _TC<false, _Elements...>
517 {
518 template<typename... _UElements>
519 static constexpr bool _ConstructibleTuple()
520 {
521 return false;
522 }
523
524 template<typename... _UElements>
525 static constexpr bool _ImplicitlyConvertibleTuple()
526 {
527 return false;
528 }
529
530 template<typename... _UElements>
531 static constexpr bool _MoveConstructibleTuple()
532 {
533 return false;
534 }
535
536 template<typename... _UElements>
537 static constexpr bool _ImplicitlyMoveConvertibleTuple()
538 {
539 return false;
540 }
541
542 template<typename... _UElements>
543 static constexpr bool _NonNestedTuple()
544 {
545 return true;
546 }
547 template<typename... _UElements>
548 static constexpr bool _NotSameTuple()
549 {
550 return true;
551 }
552 };
553
554 /// Primary class template, tuple
555 template<typename... _Elements>
556 class tuple : public _Tuple_impl<0, _Elements...>
557 {
558 typedef _Tuple_impl<0, _Elements...> _Inherited;
559
560 // Used for constraining the default constructor so
561 // that it becomes dependent on the constraints.
562 template<typename _Dummy>
563 struct _TC2
564 {
565 static constexpr bool _DefaultConstructibleTuple()
566 {
567 return __and_<is_default_constructible<_Elements>...>::value;
568 }
569 static constexpr bool _ImplicitlyDefaultConstructibleTuple()
570 {
571 return __and_<__is_implicitly_default_constructible<_Elements>...>
572 ::value;
573 }
574 };
575
576 public:
577 template<typename _Dummy = void,
578 typename enable_if<_TC2<_Dummy>::
579 _ImplicitlyDefaultConstructibleTuple(),
580 bool>::type = true>
581 constexpr tuple()
582 : _Inherited() { }
583
584 template<typename _Dummy = void,
585 typename enable_if<_TC2<_Dummy>::
586 _DefaultConstructibleTuple()
587 &&
588 !_TC2<_Dummy>::
589 _ImplicitlyDefaultConstructibleTuple(),
590 bool>::type = false>
591 explicit constexpr tuple()
592 : _Inherited() { }
593
594 // Shortcut for the cases where constructors taking _Elements...
595 // need to be constrained.
596 template<typename _Dummy> using _TCC =
597 _TC<is_same<_Dummy, void>::value,
598 _Elements...>;
599
600 template<typename _Dummy = void,
601 typename enable_if<
602 _TCC<_Dummy>::template
603 _ConstructibleTuple<_Elements...>()
604 && _TCC<_Dummy>::template
605 _ImplicitlyConvertibleTuple<_Elements...>()
606 && (sizeof...(_Elements) >= 1),
607 bool>::type=true>
608 constexpr tuple(const _Elements&... __elements)
609 : _Inherited(__elements...) { }
610
611 template<typename _Dummy = void,
612 typename enable_if<
613 _TCC<_Dummy>::template
614 _ConstructibleTuple<_Elements...>()
615 && !_TCC<_Dummy>::template
616 _ImplicitlyConvertibleTuple<_Elements...>()
617 && (sizeof...(_Elements) >= 1),
618 bool>::type=false>
619 explicit constexpr tuple(const _Elements&... __elements)
620 : _Inherited(__elements...) { }
621
622 // Shortcut for the cases where constructors taking _UElements...
623 // need to be constrained.
624 template<typename... _UElements> using _TMC =
625 _TC<(sizeof...(_Elements) == sizeof...(_UElements))
626 && (_TC<(sizeof...(_UElements)==1), _Elements...>::
627 template _NotSameTuple<_UElements...>()),
628 _Elements...>;
629
630 // Shortcut for the cases where constructors taking tuple<_UElements...>
631 // need to be constrained.
632 template<typename... _UElements> using _TMCT =
633 _TC<(sizeof...(_Elements) == sizeof...(_UElements))
634 && !is_same<tuple<_Elements...>,
635 tuple<_UElements...>>::value,
636 _Elements...>;
637
638 template<typename... _UElements, typename
639 enable_if<
640 _TMC<_UElements...>::template
641 _MoveConstructibleTuple<_UElements...>()
642 && _TMC<_UElements...>::template
643 _ImplicitlyMoveConvertibleTuple<_UElements...>()
644 && (sizeof...(_Elements) >= 1),
645 bool>::type=true>
646 constexpr tuple(_UElements&&... __elements)
647 : _Inherited(std::forward<_UElements>(__elements)...) { }
648
649 template<typename... _UElements, typename
650 enable_if<
651 _TMC<_UElements...>::template
652 _MoveConstructibleTuple<_UElements...>()
653 && !_TMC<_UElements...>::template
654 _ImplicitlyMoveConvertibleTuple<_UElements...>()
655 && (sizeof...(_Elements) >= 1),
656 bool>::type=false>
657 explicit constexpr tuple(_UElements&&... __elements)
658 : _Inherited(std::forward<_UElements>(__elements)...) { }
659
660 constexpr tuple(const tuple&) = default;
661
662 constexpr tuple(tuple&&) = default;
663
664 // Shortcut for the cases where constructors taking tuples
665 // must avoid creating temporaries.
666 template<typename _Dummy> using _TNTC =
667 _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1,
668 _Elements...>;
669
670 template<typename... _UElements, typename _Dummy = void, typename
671 enable_if<_TMCT<_UElements...>::template
672 _ConstructibleTuple<_UElements...>()
673 && _TMCT<_UElements...>::template
674 _ImplicitlyConvertibleTuple<_UElements...>()
675 && _TNTC<_Dummy>::template
676 _NonNestedTuple<const tuple<_UElements...>&>(),
677 bool>::type=true>
678 constexpr tuple(const tuple<_UElements...>& __in)
679 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
680 { }
681
682 template<typename... _UElements, typename _Dummy = void, typename
683 enable_if<_TMCT<_UElements...>::template
684 _ConstructibleTuple<_UElements...>()
685 && !_TMCT<_UElements...>::template
686 _ImplicitlyConvertibleTuple<_UElements...>()
687 && _TNTC<_Dummy>::template
688 _NonNestedTuple<const tuple<_UElements...>&>(),
689 bool>::type=false>
690 explicit constexpr tuple(const tuple<_UElements...>& __in)
691 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
692 { }
693
694 template<typename... _UElements, typename _Dummy = void, typename
695 enable_if<_TMCT<_UElements...>::template
696 _MoveConstructibleTuple<_UElements...>()
697 && _TMCT<_UElements...>::template
698 _ImplicitlyMoveConvertibleTuple<_UElements...>()
699 && _TNTC<_Dummy>::template
700 _NonNestedTuple<tuple<_UElements...>&&>(),
701 bool>::type=true>
702 constexpr tuple(tuple<_UElements...>&& __in)
703 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
704
705 template<typename... _UElements, typename _Dummy = void, typename
706 enable_if<_TMCT<_UElements...>::template
707 _MoveConstructibleTuple<_UElements...>()
708 && !_TMCT<_UElements...>::template
709 _ImplicitlyMoveConvertibleTuple<_UElements...>()
710 && _TNTC<_Dummy>::template
711 _NonNestedTuple<tuple<_UElements...>&&>(),
712 bool>::type=false>
713 explicit constexpr tuple(tuple<_UElements...>&& __in)
714 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
715
716 // Allocator-extended constructors.
717
718 template<typename _Alloc>
719 tuple(allocator_arg_t __tag, const _Alloc& __a)
720 : _Inherited(__tag, __a) { }
721
722 template<typename _Alloc, typename _Dummy = void,
723 typename enable_if<
724 _TCC<_Dummy>::template
725 _ConstructibleTuple<_Elements...>()
726 && _TCC<_Dummy>::template
727 _ImplicitlyConvertibleTuple<_Elements...>(),
728 bool>::type=true>
729 tuple(allocator_arg_t __tag, const _Alloc& __a,
730 const _Elements&... __elements)
731 : _Inherited(__tag, __a, __elements...) { }
732
733 template<typename _Alloc, typename _Dummy = void,
734 typename enable_if<
735 _TCC<_Dummy>::template
736 _ConstructibleTuple<_Elements...>()
737 && !_TCC<_Dummy>::template
738 _ImplicitlyConvertibleTuple<_Elements...>(),
739 bool>::type=false>
740 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
741 const _Elements&... __elements)
742 : _Inherited(__tag, __a, __elements...) { }
743
744 template<typename _Alloc, typename... _UElements, typename
745 enable_if<_TMC<_UElements...>::template
746 _MoveConstructibleTuple<_UElements...>()
747 && _TMC<_UElements...>::template
748 _ImplicitlyMoveConvertibleTuple<_UElements...>(),
749 bool>::type=true>
750 tuple(allocator_arg_t __tag, const _Alloc& __a,
751 _UElements&&... __elements)
752 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
753 { }
754
755 template<typename _Alloc, typename... _UElements, typename
756 enable_if<_TMC<_UElements...>::template
757 _MoveConstructibleTuple<_UElements...>()
758 && !_TMC<_UElements...>::template
759 _ImplicitlyMoveConvertibleTuple<_UElements...>(),
760 bool>::type=false>
761 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
762 _UElements&&... __elements)
763 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
764 { }
765
766 template<typename _Alloc>
767 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
768 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
769
770 template<typename _Alloc>
771 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
772 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
773
774 template<typename _Alloc, typename _Dummy = void,
775 typename... _UElements, typename
776 enable_if<_TMCT<_UElements...>::template
777 _ConstructibleTuple<_UElements...>()
778 && _TMCT<_UElements...>::template
779 _ImplicitlyConvertibleTuple<_UElements...>()
780 && _TNTC<_Dummy>::template
781 _NonNestedTuple<tuple<_UElements...>&&>(),
782 bool>::type=true>
783 tuple(allocator_arg_t __tag, const _Alloc& __a,
784 const tuple<_UElements...>& __in)
785 : _Inherited(__tag, __a,
786 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
787 { }
788
789 template<typename _Alloc, typename _Dummy = void,
790 typename... _UElements, typename
791 enable_if<_TMCT<_UElements...>::template
792 _ConstructibleTuple<_UElements...>()
793 && !_TMCT<_UElements...>::template
794 _ImplicitlyConvertibleTuple<_UElements...>()
795 && _TNTC<_Dummy>::template
796 _NonNestedTuple<tuple<_UElements...>&&>(),
797 bool>::type=false>
798 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
799 const tuple<_UElements...>& __in)
800 : _Inherited(__tag, __a,
801 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
802 { }
803
804 template<typename _Alloc, typename _Dummy = void,
805 typename... _UElements, typename
806 enable_if<_TMCT<_UElements...>::template
807 _MoveConstructibleTuple<_UElements...>()
808 && _TMCT<_UElements...>::template
809 _ImplicitlyMoveConvertibleTuple<_UElements...>()
810 && _TNTC<_Dummy>::template
811 _NonNestedTuple<tuple<_UElements...>&&>(),
812 bool>::type=true>
813 tuple(allocator_arg_t __tag, const _Alloc& __a,
814 tuple<_UElements...>&& __in)
815 : _Inherited(__tag, __a,
816 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
817 { }
818
819 template<typename _Alloc, typename _Dummy = void,
820 typename... _UElements, typename
821 enable_if<_TMCT<_UElements...>::template
822 _MoveConstructibleTuple<_UElements...>()
823 && !_TMCT<_UElements...>::template
824 _ImplicitlyMoveConvertibleTuple<_UElements...>()
825 && _TNTC<_Dummy>::template
826 _NonNestedTuple<tuple<_UElements...>&&>(),
827 bool>::type=false>
828 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
829 tuple<_UElements...>&& __in)
830 : _Inherited(__tag, __a,
831 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
832 { }
833
834 tuple&
835 operator=(const tuple& __in)
836 {
837 static_cast<_Inherited&>(*this) = __in;
838 return *this;
839 }
840
841 tuple&
842 operator=(tuple&& __in)
843 noexcept(is_nothrow_move_assignable<_Inherited>::value)
844 {
845 static_cast<_Inherited&>(*this) = std::move(__in);
846 return *this;
847 }
848
849 template<typename... _UElements>
850 typename
851 enable_if<sizeof...(_UElements)
852 == sizeof...(_Elements), tuple&>::type
853 operator=(const tuple<_UElements...>& __in)
854 {
855 static_cast<_Inherited&>(*this) = __in;
856 return *this;
857 }
858
859 template<typename... _UElements>
860 typename
861 enable_if<sizeof...(_UElements)
862 == sizeof...(_Elements), tuple&>::type
863 operator=(tuple<_UElements...>&& __in)
864 {
865 static_cast<_Inherited&>(*this) = std::move(__in);
866 return *this;
867 }
868
869 void
870 swap(tuple& __in)
871 noexcept(noexcept(__in._M_swap(__in)))
872 { _Inherited::_M_swap(__in); }
873 };
874
875#if __cpp_deduction_guides >= 201606
876 template<typename... _UTypes>
877 tuple(_UTypes...) -> tuple<_UTypes...>;
878 template<typename _T1, typename _T2>
879 tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
880 template<typename _Alloc, typename... _UTypes>
881 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
882 template<typename _Alloc, typename _T1, typename _T2>
883 tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
884 template<typename _Alloc, typename... _UTypes>
885 tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
886#endif
887
888 // Explicit specialization, zero-element tuple.
889 template<>
890 class tuple<>
891 {
892 public:
893 void swap(tuple&) noexcept { /* no-op */ }
894 // We need the default since we're going to define no-op
895 // allocator constructors.
896 tuple() = default;
897 // No-op allocator constructors.
898 template<typename _Alloc>
899 tuple(allocator_arg_t, const _Alloc&) { }
900 template<typename _Alloc>
901 tuple(allocator_arg_t, const _Alloc&, const tuple&) { }
902 };
903
904 /// Partial specialization, 2-element tuple.
905 /// Includes construction and assignment from a pair.
906 template<typename _T1, typename _T2>
907 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
908 {
909 typedef _Tuple_impl<0, _T1, _T2> _Inherited;
910
911 public:
912 template <typename _U1 = _T1,
913 typename _U2 = _T2,
914 typename enable_if<__and_<
915 __is_implicitly_default_constructible<_U1>,
916 __is_implicitly_default_constructible<_U2>>
917 ::value, bool>::type = true>
918
919 constexpr tuple()
920 : _Inherited() { }
921
922 template <typename _U1 = _T1,
923 typename _U2 = _T2,
924 typename enable_if<
925 __and_<
926 is_default_constructible<_U1>,
927 is_default_constructible<_U2>,
928 __not_<
929 __and_<__is_implicitly_default_constructible<_U1>,
930 __is_implicitly_default_constructible<_U2>>>>
931 ::value, bool>::type = false>
932
933 explicit constexpr tuple()
934 : _Inherited() { }
935
936 // Shortcut for the cases where constructors taking _T1, _T2
937 // need to be constrained.
938 template<typename _Dummy> using _TCC =
939 _TC<is_same<_Dummy, void>::value, _T1, _T2>;
940
941 template<typename _Dummy = void, typename
942 enable_if<_TCC<_Dummy>::template
943 _ConstructibleTuple<_T1, _T2>()
944 && _TCC<_Dummy>::template
945 _ImplicitlyConvertibleTuple<_T1, _T2>(),
946 bool>::type = true>
947 constexpr tuple(const _T1& __a1, const _T2& __a2)
948 : _Inherited(__a1, __a2) { }
949
950 template<typename _Dummy = void, typename
951 enable_if<_TCC<_Dummy>::template
952 _ConstructibleTuple<_T1, _T2>()
953 && !_TCC<_Dummy>::template
954 _ImplicitlyConvertibleTuple<_T1, _T2>(),
955 bool>::type = false>
956 explicit constexpr tuple(const _T1& __a1, const _T2& __a2)
957 : _Inherited(__a1, __a2) { }
958
959 // Shortcut for the cases where constructors taking _U1, _U2
960 // need to be constrained.
961 using _TMC = _TC<true, _T1, _T2>;
962
963 template<typename _U1, typename _U2, typename
964 enable_if<_TMC::template
965 _MoveConstructibleTuple<_U1, _U2>()
966 && _TMC::template
967 _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
968 && !is_same<typename decay<_U1>::type,
969 allocator_arg_t>::value,
970 bool>::type = true>
971 constexpr tuple(_U1&& __a1, _U2&& __a2)
972 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
973
974 template<typename _U1, typename _U2, typename
975 enable_if<_TMC::template
976 _MoveConstructibleTuple<_U1, _U2>()
977 && !_TMC::template
978 _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
979 && !is_same<typename decay<_U1>::type,
980 allocator_arg_t>::value,
981 bool>::type = false>
982 explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
983 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
984
985 constexpr tuple(const tuple&) = default;
986
987 constexpr tuple(tuple&&) = default;
988
989 template<typename _U1, typename _U2, typename
990 enable_if<_TMC::template
991 _ConstructibleTuple<_U1, _U2>()
992 && _TMC::template
993 _ImplicitlyConvertibleTuple<_U1, _U2>(),
994 bool>::type = true>
995 constexpr tuple(const tuple<_U1, _U2>& __in)
996 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
997
998 template<typename _U1, typename _U2, typename
999 enable_if<_TMC::template
1000 _ConstructibleTuple<_U1, _U2>()
1001 && !_TMC::template
1002 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1003 bool>::type = false>
1004 explicit constexpr tuple(const tuple<_U1, _U2>& __in)
1005 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1006
1007 template<typename _U1, typename _U2, typename
1008 enable_if<_TMC::template
1009 _MoveConstructibleTuple<_U1, _U2>()
1010 && _TMC::template
1011 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1012 bool>::type = true>
1013 constexpr tuple(tuple<_U1, _U2>&& __in)
1014 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1015
1016 template<typename _U1, typename _U2, typename
1017 enable_if<_TMC::template
1018 _MoveConstructibleTuple<_U1, _U2>()
1019 && !_TMC::template
1020 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1021 bool>::type = false>
1022 explicit constexpr tuple(tuple<_U1, _U2>&& __in)
1023 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1024
1025 template<typename _U1, typename _U2, typename
1026 enable_if<_TMC::template
1027 _ConstructibleTuple<_U1, _U2>()
1028 && _TMC::template
1029 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1030 bool>::type = true>
1031 constexpr tuple(const pair<_U1, _U2>& __in)
1032 : _Inherited(__in.first, __in.second) { }
1033
1034 template<typename _U1, typename _U2, typename
1035 enable_if<_TMC::template
1036 _ConstructibleTuple<_U1, _U2>()
1037 && !_TMC::template
1038 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1039 bool>::type = false>
1040 explicit constexpr tuple(const pair<_U1, _U2>& __in)
1041 : _Inherited(__in.first, __in.second) { }
1042
1043 template<typename _U1, typename _U2, typename
1044 enable_if<_TMC::template
1045 _MoveConstructibleTuple<_U1, _U2>()
1046 && _TMC::template
1047 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1048 bool>::type = true>
1049 constexpr tuple(pair<_U1, _U2>&& __in)
1050 : _Inherited(std::forward<_U1>(__in.first),
1051 std::forward<_U2>(__in.second)) { }
1052
1053 template<typename _U1, typename _U2, typename
1054 enable_if<_TMC::template
1055 _MoveConstructibleTuple<_U1, _U2>()
1056 && !_TMC::template
1057 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1058 bool>::type = false>
1059 explicit constexpr tuple(pair<_U1, _U2>&& __in)
1060 : _Inherited(std::forward<_U1>(__in.first),
1061 std::forward<_U2>(__in.second)) { }
1062
1063 // Allocator-extended constructors.
1064
1065 template<typename _Alloc>
1066 tuple(allocator_arg_t __tag, const _Alloc& __a)
1067 : _Inherited(__tag, __a) { }
1068
1069 template<typename _Alloc, typename _Dummy = void,
1070 typename enable_if<
1071 _TCC<_Dummy>::template
1072 _ConstructibleTuple<_T1, _T2>()
1073 && _TCC<_Dummy>::template
1074 _ImplicitlyConvertibleTuple<_T1, _T2>(),
1075 bool>::type=true>
1076
1077 tuple(allocator_arg_t __tag, const _Alloc& __a,
1078 const _T1& __a1, const _T2& __a2)
1079 : _Inherited(__tag, __a, __a1, __a2) { }
1080
1081 template<typename _Alloc, typename _Dummy = void,
1082 typename enable_if<
1083 _TCC<_Dummy>::template
1084 _ConstructibleTuple<_T1, _T2>()
1085 && !_TCC<_Dummy>::template
1086 _ImplicitlyConvertibleTuple<_T1, _T2>(),
1087 bool>::type=false>
1088
1089 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1090 const _T1& __a1, const _T2& __a2)
1091 : _Inherited(__tag, __a, __a1, __a2) { }
1092
1093 template<typename _Alloc, typename _U1, typename _U2, typename
1094 enable_if<_TMC::template
1095 _MoveConstructibleTuple<_U1, _U2>()
1096 && _TMC::template
1097 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1098 bool>::type = true>
1099 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1100 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1101 std::forward<_U2>(__a2)) { }
1102
1103 template<typename _Alloc, typename _U1, typename _U2, typename
1104 enable_if<_TMC::template
1105 _MoveConstructibleTuple<_U1, _U2>()
1106 && !_TMC::template
1107 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1108 bool>::type = false>
1109 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1110 _U1&& __a1, _U2&& __a2)
1111 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1112 std::forward<_U2>(__a2)) { }
1113
1114 template<typename _Alloc>
1115 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1116 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1117
1118 template<typename _Alloc>
1119 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1120 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1121
1122 template<typename _Alloc, typename _U1, typename _U2, typename
1123 enable_if<_TMC::template
1124 _ConstructibleTuple<_U1, _U2>()
1125 && _TMC::template
1126 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1127 bool>::type = true>
1128 tuple(allocator_arg_t __tag, const _Alloc& __a,
1129 const tuple<_U1, _U2>& __in)
1130 : _Inherited(__tag, __a,
1131 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1132 { }
1133
1134 template<typename _Alloc, typename _U1, typename _U2, typename
1135 enable_if<_TMC::template
1136 _ConstructibleTuple<_U1, _U2>()
1137 && !_TMC::template
1138 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1139 bool>::type = false>
1140 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1141 const tuple<_U1, _U2>& __in)
1142 : _Inherited(__tag, __a,
1143 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1144 { }
1145
1146 template<typename _Alloc, typename _U1, typename _U2, typename
1147 enable_if<_TMC::template
1148 _MoveConstructibleTuple<_U1, _U2>()
1149 && _TMC::template
1150 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1151 bool>::type = true>
1152 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1153 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1154 { }
1155
1156 template<typename _Alloc, typename _U1, typename _U2, typename
1157 enable_if<_TMC::template
1158 _MoveConstructibleTuple<_U1, _U2>()
1159 && !_TMC::template
1160 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1161 bool>::type = false>
1162 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1163 tuple<_U1, _U2>&& __in)
1164 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1165 { }
1166
1167 template<typename _Alloc, typename _U1, typename _U2, typename
1168 enable_if<_TMC::template
1169 _ConstructibleTuple<_U1, _U2>()
1170 && _TMC::template
1171 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1172 bool>::type = true>
1173 tuple(allocator_arg_t __tag, const _Alloc& __a,
1174 const pair<_U1, _U2>& __in)
1175 : _Inherited(__tag, __a, __in.first, __in.second) { }
1176
1177 template<typename _Alloc, typename _U1, typename _U2, typename
1178 enable_if<_TMC::template
1179 _ConstructibleTuple<_U1, _U2>()
1180 && !_TMC::template
1181 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1182 bool>::type = false>
1183 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1184 const pair<_U1, _U2>& __in)
1185 : _Inherited(__tag, __a, __in.first, __in.second) { }
1186
1187 template<typename _Alloc, typename _U1, typename _U2, typename
1188 enable_if<_TMC::template
1189 _MoveConstructibleTuple<_U1, _U2>()
1190 && _TMC::template
1191 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1192 bool>::type = true>
1193 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1194 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1195 std::forward<_U2>(__in.second)) { }
1196
1197 template<typename _Alloc, typename _U1, typename _U2, typename
1198 enable_if<_TMC::template
1199 _MoveConstructibleTuple<_U1, _U2>()
1200 && !_TMC::template
1201 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1202 bool>::type = false>
1203 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1204 pair<_U1, _U2>&& __in)
1205 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1206 std::forward<_U2>(__in.second)) { }
1207
1208 tuple&
1209 operator=(const tuple& __in)
1210 {
1211 static_cast<_Inherited&>(*this) = __in;
1212 return *this;
1213 }
1214
1215 tuple&
1216 operator=(tuple&& __in)
1217 noexcept(is_nothrow_move_assignable<_Inherited>::value)
1218 {
1219 static_cast<_Inherited&>(*this) = std::move(__in);
1220 return *this;
1221 }
1222
1223 template<typename _U1, typename _U2>
1224 tuple&
1225 operator=(const tuple<_U1, _U2>& __in)
1226 {
1227 static_cast<_Inherited&>(*this) = __in;
1228 return *this;
1229 }
1230
1231 template<typename _U1, typename _U2>
1232 tuple&
1233 operator=(tuple<_U1, _U2>&& __in)
1234 {
1235 static_cast<_Inherited&>(*this) = std::move(__in);
1236 return *this;
1237 }
1238
1239 template<typename _U1, typename _U2>
1240 tuple&
1241 operator=(const pair<_U1, _U2>& __in)
1242 {
1243 this->_M_head(*this) = __in.first;
1244 this->_M_tail(*this)._M_head(*this) = __in.second;
1245 return *this;
1246 }
1247
1248 template<typename _U1, typename _U2>
1249 tuple&
1250 operator=(pair<_U1, _U2>&& __in)
1251 {
1252 this->_M_head(*this) = std::forward<_U1>(__in.first);
1253 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1254 return *this;
1255 }
1256
1257 void
1258 swap(tuple& __in)
1259 noexcept(noexcept(__in._M_swap(__in)))
1260 { _Inherited::_M_swap(__in); }
1261 };
1262
1263
1264 /// class tuple_size
1265 template<typename... _Elements>
1266 struct tuple_size<tuple<_Elements...>>
1267 : public integral_constant<std::size_t, sizeof...(_Elements)> { };
1268
1269#if __cplusplus201103L > 201402L
1270 template <typename _Tp>
1271 inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1272#endif
1273
1274 /**
1275 * Recursive case for tuple_element: strip off the first element in
1276 * the tuple and retrieve the (i-1)th element of the remaining tuple.
1277 */
1278 template<std::size_t __i, typename _Head, typename... _Tail>
1279 struct tuple_element<__i, tuple<_Head, _Tail...> >
1280 : tuple_element<__i - 1, tuple<_Tail...> > { };
1281
1282 /**
1283 * Basis case for tuple_element: The first element is the one we're seeking.
1284 */
1285 template<typename _Head, typename... _Tail>
1286 struct tuple_element<0, tuple<_Head, _Tail...> >
1287 {
1288 typedef _Head type;
1289 };
1290
1291 /**
1292 * Error case for tuple_element: invalid index.
1293 */
1294 template<size_t __i>
1295 struct tuple_element<__i, tuple<>>
1296 {
1297 static_assert(__i < tuple_size<tuple<>>::value,
1298 "tuple index is in range");
1299 };
1300
1301 template<std::size_t __i, typename _Head, typename... _Tail>
1302 constexpr _Head&
1303 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1304 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1305
1306 template<std::size_t __i, typename _Head, typename... _Tail>
1307 constexpr const _Head&
1308 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1309 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
29
Calling '_Tuple_impl::_M_head'
32
Returning from '_Tuple_impl::_M_head'
1310
1311 /// Return a reference to the ith element of a tuple.
1312 template<std::size_t __i, typename... _Elements>
1313 constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1314 get(tuple<_Elements...>& __t) noexcept
1315 { return std::__get_helper<__i>(__t); }
1316
1317 /// Return a const reference to the ith element of a const tuple.
1318 template<std::size_t __i, typename... _Elements>
1319 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1320 get(const tuple<_Elements...>& __t) noexcept
1321 { return std::__get_helper<__i>(__t); }
28
Calling '__get_helper'
33
Returning from '__get_helper'
1322
1323 /// Return an rvalue reference to the ith element of a tuple rvalue.
1324 template<std::size_t __i, typename... _Elements>
1325 constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1326 get(tuple<_Elements...>&& __t) noexcept
1327 {
1328 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1329 return std::forward<__element_type&&>(std::get<__i>(__t));
1330 }
1331
1332#if __cplusplus201103L > 201103L
1333
1334#define __cpp_lib_tuples_by_type 201304
1335
1336 template<typename _Head, size_t __i, typename... _Tail>
1337 constexpr _Head&
1338 __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1339 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1340
1341 template<typename _Head, size_t __i, typename... _Tail>
1342 constexpr const _Head&
1343 __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1344 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1345
1346 /// Return a reference to the unique element of type _Tp of a tuple.
1347 template <typename _Tp, typename... _Types>
1348 constexpr _Tp&
1349 get(tuple<_Types...>& __t) noexcept
1350 { return std::__get_helper2<_Tp>(__t); }
1351
1352 /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1353 template <typename _Tp, typename... _Types>
1354 constexpr _Tp&&
1355 get(tuple<_Types...>&& __t) noexcept
1356 { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
1357
1358 /// Return a const reference to the unique element of type _Tp of a tuple.
1359 template <typename _Tp, typename... _Types>
1360 constexpr const _Tp&
1361 get(const tuple<_Types...>& __t) noexcept
1362 { return std::__get_helper2<_Tp>(__t); }
1363#endif
1364
1365 // This class performs the comparison operations on tuples
1366 template<typename _Tp, typename _Up, size_t __i, size_t __size>
1367 struct __tuple_compare
1368 {
1369 static constexpr bool
1370 __eq(const _Tp& __t, const _Up& __u)
1371 {
1372 return bool(std::get<__i>(__t) == std::get<__i>(__u))
1373 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1374 }
1375
1376 static constexpr bool
1377 __less(const _Tp& __t, const _Up& __u)
1378 {
1379 return bool(std::get<__i>(__t) < std::get<__i>(__u))
1380 || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1381 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1382 }
1383 };
1384
1385 template<typename _Tp, typename _Up, size_t __size>
1386 struct __tuple_compare<_Tp, _Up, __size, __size>
1387 {
1388 static constexpr bool
1389 __eq(const _Tp&, const _Up&) { return true; }
1390
1391 static constexpr bool
1392 __less(const _Tp&, const _Up&) { return false; }
1393 };
1394
1395 template<typename... _TElements, typename... _UElements>
1396 constexpr bool
1397 operator==(const tuple<_TElements...>& __t,
1398 const tuple<_UElements...>& __u)
1399 {
1400 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1401 "tuple objects can only be compared if they have equal sizes.");
1402 using __compare = __tuple_compare<tuple<_TElements...>,
1403 tuple<_UElements...>,
1404 0, sizeof...(_TElements)>;
1405 return __compare::__eq(__t, __u);
1406 }
1407
1408 template<typename... _TElements, typename... _UElements>
1409 constexpr bool
1410 operator<(const tuple<_TElements...>& __t,
1411 const tuple<_UElements...>& __u)
1412 {
1413 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1414 "tuple objects can only be compared if they have equal sizes.");
1415 using __compare = __tuple_compare<tuple<_TElements...>,
1416 tuple<_UElements...>,
1417 0, sizeof...(_TElements)>;
1418 return __compare::__less(__t, __u);
1419 }
1420
1421 template<typename... _TElements, typename... _UElements>
1422 constexpr bool
1423 operator!=(const tuple<_TElements...>& __t,
1424 const tuple<_UElements...>& __u)
1425 { return !(__t == __u); }
1426
1427 template<typename... _TElements, typename... _UElements>
1428 constexpr bool
1429 operator>(const tuple<_TElements...>& __t,
1430 const tuple<_UElements...>& __u)
1431 { return __u < __t; }
1432
1433 template<typename... _TElements, typename... _UElements>
1434 constexpr bool
1435 operator<=(const tuple<_TElements...>& __t,
1436 const tuple<_UElements...>& __u)
1437 { return !(__u < __t); }
1438
1439 template<typename... _TElements, typename... _UElements>
1440 constexpr bool
1441 operator>=(const tuple<_TElements...>& __t,
1442 const tuple<_UElements...>& __u)
1443 { return !(__t < __u); }
1444
1445 // NB: DR 705.
1446 template<typename... _Elements>
1447 constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1448 make_tuple(_Elements&&... __args)
1449 {
1450 typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1451 __result_type;
1452 return __result_type(std::forward<_Elements>(__args)...);
1453 }
1454
1455 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1456 // 2275. Why is forward_as_tuple not constexpr?
1457 template<typename... _Elements>
1458 constexpr tuple<_Elements&&...>
1459 forward_as_tuple(_Elements&&... __args) noexcept
1460 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1461
1462 template<size_t, typename, typename, size_t>
1463 struct __make_tuple_impl;
1464
1465 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1466 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1467 : __make_tuple_impl<_Idx + 1,
1468 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1469 _Tuple, _Nm>
1470 { };
1471
1472 template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1473 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1474 {
1475 typedef tuple<_Tp...> __type;
1476 };
1477
1478 template<typename _Tuple>
1479 struct __do_make_tuple
1480 : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
1481 { };
1482
1483 // Returns the std::tuple equivalent of a tuple-like type.
1484 template<typename _Tuple>
1485 struct __make_tuple
1486 : public __do_make_tuple<typename std::remove_cv
1487 <typename std::remove_reference<_Tuple>::type>::type>
1488 { };
1489
1490 // Combines several std::tuple's into a single one.
1491 template<typename...>
1492 struct __combine_tuples;
1493
1494 template<>
1495 struct __combine_tuples<>
1496 {
1497 typedef tuple<> __type;
1498 };
1499
1500 template<typename... _Ts>
1501 struct __combine_tuples<tuple<_Ts...>>
1502 {
1503 typedef tuple<_Ts...> __type;
1504 };
1505
1506 template<typename... _T1s, typename... _T2s, typename... _Rem>
1507 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1508 {
1509 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1510 _Rem...>::__type __type;
1511 };
1512
1513 // Computes the result type of tuple_cat given a set of tuple-like types.
1514 template<typename... _Tpls>
1515 struct __tuple_cat_result
1516 {
1517 typedef typename __combine_tuples
1518 <typename __make_tuple<_Tpls>::__type...>::__type __type;
1519 };
1520
1521 // Helper to determine the index set for the first tuple-like
1522 // type of a given set.
1523 template<typename...>
1524 struct __make_1st_indices;
1525
1526 template<>
1527 struct __make_1st_indices<>
1528 {
1529 typedef std::_Index_tuple<> __type;
1530 };
1531
1532 template<typename _Tp, typename... _Tpls>
1533 struct __make_1st_indices<_Tp, _Tpls...>
1534 {
1535 typedef typename std::_Build_index_tuple<std::tuple_size<
1536 typename std::remove_reference<_Tp>::type>::value>::__type __type;
1537 };
1538
1539 // Performs the actual concatenation by step-wise expanding tuple-like
1540 // objects into the elements, which are finally forwarded into the
1541 // result tuple.
1542 template<typename _Ret, typename _Indices, typename... _Tpls>
1543 struct __tuple_concater;
1544
1545 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1546 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1547 {
1548 template<typename... _Us>
1549 static constexpr _Ret
1550 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1551 {
1552 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1553 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1554 return __next::_S_do(std::forward<_Tpls>(__tps)...,
1555 std::forward<_Us>(__us)...,
1556 std::get<_Is>(std::forward<_Tp>(__tp))...);
1557 }
1558 };
1559
1560 template<typename _Ret>
1561 struct __tuple_concater<_Ret, std::_Index_tuple<>>
1562 {
1563 template<typename... _Us>
1564 static constexpr _Ret
1565 _S_do(_Us&&... __us)
1566 {
1567 return _Ret(std::forward<_Us>(__us)...);
1568 }
1569 };
1570
1571 /// tuple_cat
1572 template<typename... _Tpls, typename = typename
1573 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1574 constexpr auto
1575 tuple_cat(_Tpls&&... __tpls)
1576 -> typename __tuple_cat_result<_Tpls...>::__type
1577 {
1578 typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1579 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1580 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1581 return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1582 }
1583
1584 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1585 // 2301. Why is tie not constexpr?
1586 /// tie
1587 template<typename... _Elements>
1588 constexpr tuple<_Elements&...>
1589 tie(_Elements&... __args) noexcept
1590 { return tuple<_Elements&...>(__args...); }
1591
1592 /// swap
1593 template<typename... _Elements>
1594 inline
1595#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
1596 // Constrained free swap overload, see p0185r1
1597 typename enable_if<__and_<__is_swappable<_Elements>...>::value
1598 >::type
1599#else
1600 void
1601#endif
1602 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1603 noexcept(noexcept(__x.swap(__y)))
1604 { __x.swap(__y); }
1605
1606#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
1607 template<typename... _Elements>
1608 typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
1609 swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
1610#endif
1611
1612 // A class (and instance) which can be used in 'tie' when an element
1613 // of a tuple is not required.
1614 // _GLIBCXX14_CONSTEXPR
1615 // 2933. PR for LWG 2773 could be clearer
1616 struct _Swallow_assign
1617 {
1618 template<class _Tp>
1619 _GLIBCXX14_CONSTEXPR const _Swallow_assign&
1620 operator=(const _Tp&) const
1621 { return *this; }
1622 };
1623
1624 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1625 // 2773. Making std::ignore constexpr
1626 _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
1627
1628 /// Partial specialization for tuples
1629 template<typename... _Types, typename _Alloc>
1630 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1631
1632 // See stl_pair.h...
1633 template<class _T1, class _T2>
1634 template<typename... _Args1, typename... _Args2>
1635 inline
1636 pair<_T1, _T2>::
1637 pair(piecewise_construct_t,
1638 tuple<_Args1...> __first, tuple<_Args2...> __second)
1639 : pair(__first, __second,
1640 typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1641 typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1642 { }
1643
1644 template<class _T1, class _T2>
1645 template<typename... _Args1, std::size_t... _Indexes1,
1646 typename... _Args2, std::size_t... _Indexes2>
1647 inline
1648 pair<_T1, _T2>::
1649 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1650 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1651 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1652 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1653 { }
1654
1655#if __cplusplus201103L > 201402L
1656# define __cpp_lib_apply 201603
1657
1658 template <typename _Fn, typename _Tuple, size_t... _Idx>
1659 constexpr decltype(auto)
1660 __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
1661 {
1662 return std::__invoke(std::forward<_Fn>(__f),
1663 std::get<_Idx>(std::forward<_Tuple>(__t))...);
1664 }
1665
1666 template <typename _Fn, typename _Tuple>
1667 constexpr decltype(auto)
1668 apply(_Fn&& __f, _Tuple&& __t)
1669 {
1670 using _Indices = make_index_sequence<tuple_size_v<decay_t<_Tuple>>>;
1671 return std::__apply_impl(std::forward<_Fn>(__f),
1672 std::forward<_Tuple>(__t),
1673 _Indices{});
1674 }
1675
1676#define __cpp_lib_make_from_tuple 201606
1677
1678 template <typename _Tp, typename _Tuple, size_t... _Idx>
1679 constexpr _Tp
1680 __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
1681 { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
1682
1683 template <typename _Tp, typename _Tuple>
1684 constexpr _Tp
1685 make_from_tuple(_Tuple&& __t)
1686 {
1687 return __make_from_tuple_impl<_Tp>(
1688 std::forward<_Tuple>(__t),
1689 make_index_sequence<tuple_size_v<decay_t<_Tuple>>>{});
1690 }
1691#endif // C++17
1692
1693 /// @}
1694
1695_GLIBCXX_END_NAMESPACE_VERSION
1696} // namespace std
1697
1698#endif // C++11
1699
1700#endif // _GLIBCXX_TUPLE

/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h

1//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===//
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/// \file
11/// \brief Defines the Diagnostic-related interfaces.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_H
16#define LLVM_CLANG_BASIC_DIAGNOSTIC_H
17
18#include "clang/Basic/DiagnosticIDs.h"
19#include "clang/Basic/DiagnosticOptions.h"
20#include "clang/Basic/SourceLocation.h"
21#include "clang/Basic/Specifiers.h"
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/IntrusiveRefCntPtr.h"
25#include "llvm/ADT/iterator_range.h"
26#include "llvm/ADT/SmallVector.h"
27#include "llvm/ADT/StringRef.h"
28#include <algorithm>
29#include <cassert>
30#include <cstdint>
31#include <list>
32#include <map>
33#include <memory>
34#include <string>
35#include <type_traits>
36#include <utility>
37#include <vector>
38
39namespace clang {
40
41class DeclContext;
42class DiagnosticBuilder;
43class DiagnosticConsumer;
44class IdentifierInfo;
45class LangOptions;
46class Preprocessor;
47class StoredDiagnostic;
48
49namespace tok {
50
51 enum TokenKind : unsigned short;
52
53} // end namespace tok
54
55/// \brief Annotates a diagnostic with some code that should be
56/// inserted, removed, or replaced to fix the problem.
57///
58/// This kind of hint should be used when we are certain that the
59/// introduction, removal, or modification of a particular (small!)
60/// amount of code will correct a compilation error. The compiler
61/// should also provide full recovery from such errors, such that
62/// suppressing the diagnostic output can still result in successful
63/// compilation.
64class FixItHint {
65public:
66 /// \brief Code that should be replaced to correct the error. Empty for an
67 /// insertion hint.
68 CharSourceRange RemoveRange;
69
70 /// \brief Code in the specific range that should be inserted in the insertion
71 /// location.
72 CharSourceRange InsertFromRange;
73
74 /// \brief The actual code to insert at the insertion location, as a
75 /// string.
76 std::string CodeToInsert;
77
78 bool BeforePreviousInsertions;
79
80 /// \brief Empty code modification hint, indicating that no code
81 /// modification is known.
82 FixItHint() : BeforePreviousInsertions(false) { }
83
84 bool isNull() const {
85 return !RemoveRange.isValid();
86 }
87
88 /// \brief Create a code modification hint that inserts the given
89 /// code string at a specific location.
90 static FixItHint CreateInsertion(SourceLocation InsertionLoc,
91 StringRef Code,
92 bool BeforePreviousInsertions = false) {
93 FixItHint Hint;
94 Hint.RemoveRange =
95 CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
96 Hint.CodeToInsert = Code;
97 Hint.BeforePreviousInsertions = BeforePreviousInsertions;
98 return Hint;
99 }
100
101 /// \brief Create a code modification hint that inserts the given
102 /// code from \p FromRange at a specific location.
103 static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
104 CharSourceRange FromRange,
105 bool BeforePreviousInsertions = false) {
106 FixItHint Hint;
107 Hint.RemoveRange =
108 CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
109 Hint.InsertFromRange = FromRange;
110 Hint.BeforePreviousInsertions = BeforePreviousInsertions;
111 return Hint;
112 }
113
114 /// \brief Create a code modification hint that removes the given
115 /// source range.
116 static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
117 FixItHint Hint;
118 Hint.RemoveRange = RemoveRange;
119 return Hint;
120 }
121 static FixItHint CreateRemoval(SourceRange RemoveRange) {
122 return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
123 }
124
125 /// \brief Create a code modification hint that replaces the given
126 /// source range with the given code string.
127 static FixItHint CreateReplacement(CharSourceRange RemoveRange,
128 StringRef Code) {
129 FixItHint Hint;
130 Hint.RemoveRange = RemoveRange;
131 Hint.CodeToInsert = Code;
132 return Hint;
133 }
134
135 static FixItHint CreateReplacement(SourceRange RemoveRange,
136 StringRef Code) {
137 return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code);
138 }
139};
140
141/// \brief Concrete class used by the front-end to report problems and issues.
142///
143/// This massages the diagnostics (e.g. handling things like "report warnings
144/// as errors" and passes them off to the DiagnosticConsumer for reporting to
145/// the user. DiagnosticsEngine is tied to one translation unit and one
146/// SourceManager.
147class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
148public:
149 /// \brief The level of the diagnostic, after it has been through mapping.
150 enum Level {
151 Ignored = DiagnosticIDs::Ignored,
152 Note = DiagnosticIDs::Note,
153 Remark = DiagnosticIDs::Remark,
154 Warning = DiagnosticIDs::Warning,
155 Error = DiagnosticIDs::Error,
156 Fatal = DiagnosticIDs::Fatal
157 };
158
159 enum ArgumentKind {
160 ak_std_string, ///< std::string
161 ak_c_string, ///< const char *
162 ak_sint, ///< int
163 ak_uint, ///< unsigned
164 ak_tokenkind, ///< enum TokenKind : unsigned
165 ak_identifierinfo, ///< IdentifierInfo
166 ak_qualtype, ///< QualType
167 ak_declarationname, ///< DeclarationName
168 ak_nameddecl, ///< NamedDecl *
169 ak_nestednamespec, ///< NestedNameSpecifier *
170 ak_declcontext, ///< DeclContext *
171 ak_qualtype_pair, ///< pair<QualType, QualType>
172 ak_attr ///< Attr *
173 };
174
175 /// \brief Represents on argument value, which is a union discriminated
176 /// by ArgumentKind, with a value.
177 typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
178
179private:
180 unsigned char AllExtensionsSilenced; // Used by __extension__
181 bool SuppressAfterFatalError; // Suppress diagnostics after a fatal error?
182 bool SuppressAllDiagnostics; // Suppress all diagnostics.
183 bool ElideType; // Elide common types of templates.
184 bool PrintTemplateTree; // Print a tree when comparing templates.
185 bool ShowColors; // Color printing is enabled.
186 OverloadsShown ShowOverloads; // Which overload candidates to show.
187 unsigned ErrorLimit; // Cap of # errors emitted, 0 -> no limit.
188 unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
189 // 0 -> no limit.
190 unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation
191 // backtrace stack, 0 -> no limit.
192 IntrusiveRefCntPtr<DiagnosticIDs> Diags;
193 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
194 DiagnosticConsumer *Client;
195 std::unique_ptr<DiagnosticConsumer> Owner;
196 SourceManager *SourceMgr;
197
198 /// \brief Mapping information for diagnostics.
199 ///
200 /// Mapping info is packed into four bits per diagnostic. The low three
201 /// bits are the mapping (an instance of diag::Severity), or zero if unset.
202 /// The high bit is set when the mapping was established as a user mapping.
203 /// If the high bit is clear, then the low bits are set to the default
204 /// value, and should be mapped with -pedantic, -Werror, etc.
205 ///
206 /// A new DiagState is created and kept around when diagnostic pragmas modify
207 /// the state so that we know what is the diagnostic state at any given
208 /// source location.
209 class DiagState {
210 llvm::DenseMap<unsigned, DiagnosticMapping> DiagMap;
211
212 public:
213 // "Global" configuration state that can actually vary between modules.
214 unsigned IgnoreAllWarnings : 1; // Ignore all warnings: -w
215 unsigned EnableAllWarnings : 1; // Enable all warnings.
216 unsigned WarningsAsErrors : 1; // Treat warnings like errors.
217 unsigned ErrorsAsFatal : 1; // Treat errors like fatal errors.
218 unsigned SuppressSystemWarnings : 1; // Suppress warnings in system headers.
219 diag::Severity ExtBehavior; // Map extensions to warnings or errors?
220
221 DiagState()
222 : IgnoreAllWarnings(false), EnableAllWarnings(false),
223 WarningsAsErrors(false), ErrorsAsFatal(false),
224 SuppressSystemWarnings(false), ExtBehavior(diag::Severity::Ignored) {}
225
226 typedef llvm::DenseMap<unsigned, DiagnosticMapping>::iterator iterator;
227 typedef llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator
228 const_iterator;
229
230 void setMapping(diag::kind Diag, DiagnosticMapping Info) {
231 DiagMap[Diag] = Info;
232 }
233 DiagnosticMapping lookupMapping(diag::kind Diag) const {
234 return DiagMap.lookup(Diag);
235 }
236
237 DiagnosticMapping &getOrAddMapping(diag::kind Diag);
238
239 const_iterator begin() const { return DiagMap.begin(); }
240 const_iterator end() const { return DiagMap.end(); }
241 };
242
243 /// \brief Keeps and automatically disposes all DiagStates that we create.
244 std::list<DiagState> DiagStates;
245
246 /// A mapping from files to the diagnostic states for those files. Lazily
247 /// built on demand for files in which the diagnostic state has not changed.
248 class DiagStateMap {
249 public:
250 /// Add an initial diagnostic state.
251 void appendFirst(DiagState *State);
252 /// Add a new latest state point.
253 void append(SourceManager &SrcMgr, SourceLocation Loc, DiagState *State);
254 /// Look up the diagnostic state at a given source location.
255 DiagState *lookup(SourceManager &SrcMgr, SourceLocation Loc) const;
256 /// Determine whether this map is empty.
257 bool empty() const { return Files.empty(); }
258 /// Clear out this map.
259 void clear() {
260 Files.clear();
261 FirstDiagState = CurDiagState = nullptr;
262 CurDiagStateLoc = SourceLocation();
263 }
264
265 /// Grab the most-recently-added state point.
266 DiagState *getCurDiagState() const { return CurDiagState; }
267 /// Get the location at which a diagnostic state was last added.
268 SourceLocation getCurDiagStateLoc() const { return CurDiagStateLoc; }
269
270 private:
271 /// \brief Represents a point in source where the diagnostic state was
272 /// modified because of a pragma.
273 ///
274 /// 'Loc' can be null if the point represents the diagnostic state
275 /// modifications done through the command-line.
276 struct DiagStatePoint {
277 DiagState *State;
278 unsigned Offset;
279 DiagStatePoint(DiagState *State, unsigned Offset)
280 : State(State), Offset(Offset) { }
281 };
282
283 /// Description of the diagnostic states and state transitions for a
284 /// particular FileID.
285 struct File {
286 /// The diagnostic state for the parent file. This is strictly redundant,
287 /// as looking up the DecomposedIncludedLoc for the FileID in the Files
288 /// map would give us this, but we cache it here for performance.
289 File *Parent = nullptr;
290 /// The offset of this file within its parent.
291 unsigned ParentOffset = 0;
292 /// Whether this file has any local (not imported from an AST file)
293 /// diagnostic state transitions.
294 bool HasLocalTransitions = false;
295 /// The points within the file where the state changes. There will always
296 /// be at least one of these (the state on entry to the file).
297 llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
298
299 DiagState *lookup(unsigned Offset) const;
300 };
301
302 /// The diagnostic states for each file.
303 mutable std::map<FileID, File> Files;
304
305 /// The initial diagnostic state.
306 DiagState *FirstDiagState;
307 /// The current diagnostic state.
308 DiagState *CurDiagState;
309 /// The location at which the current diagnostic state was established.
310 SourceLocation CurDiagStateLoc;
311
312 /// Get the diagnostic state information for a file.
313 File *getFile(SourceManager &SrcMgr, FileID ID) const;
314
315 friend class ASTReader;
316 friend class ASTWriter;
317 };
318
319 DiagStateMap DiagStatesByLoc;
320
321 /// \brief Keeps the DiagState that was active during each diagnostic 'push'
322 /// so we can get back at it when we 'pop'.
323 std::vector<DiagState *> DiagStateOnPushStack;
324
325 DiagState *GetCurDiagState() const {
326 return DiagStatesByLoc.getCurDiagState();
327 }
328
329 void PushDiagStatePoint(DiagState *State, SourceLocation L);
330
331 /// \brief Finds the DiagStatePoint that contains the diagnostic state of
332 /// the given source location.
333 DiagState *GetDiagStateForLoc(SourceLocation Loc) const {
334 return SourceMgr ? DiagStatesByLoc.lookup(*SourceMgr, Loc)
335 : DiagStatesByLoc.getCurDiagState();
336 }
337
338 /// \brief Sticky flag set to \c true when an error is emitted.
339 bool ErrorOccurred;
340
341 /// \brief Sticky flag set to \c true when an "uncompilable error" occurs.
342 /// I.e. an error that was not upgraded from a warning by -Werror.
343 bool UncompilableErrorOccurred;
344
345 /// \brief Sticky flag set to \c true when a fatal error is emitted.
346 bool FatalErrorOccurred;
347
348 /// \brief Indicates that an unrecoverable error has occurred.
349 bool UnrecoverableErrorOccurred;
350
351 /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred
352 /// during a parsing section, e.g. during parsing a function.
353 unsigned TrapNumErrorsOccurred;
354 unsigned TrapNumUnrecoverableErrorsOccurred;
355
356 /// \brief The level of the last diagnostic emitted.
357 ///
358 /// This is used to emit continuation diagnostics with the same level as the
359 /// diagnostic that they follow.
360 DiagnosticIDs::Level LastDiagLevel;
361
362 unsigned NumWarnings; ///< Number of warnings reported
363 unsigned NumErrors; ///< Number of errors reported
364
365 /// \brief A function pointer that converts an opaque diagnostic
366 /// argument to a strings.
367 ///
368 /// This takes the modifiers and argument that was present in the diagnostic.
369 ///
370 /// The PrevArgs array indicates the previous arguments formatted for this
371 /// diagnostic. Implementations of this function can use this information to
372 /// avoid redundancy across arguments.
373 ///
374 /// This is a hack to avoid a layering violation between libbasic and libsema.
375 typedef void (*ArgToStringFnTy)(
376 ArgumentKind Kind, intptr_t Val,
377 StringRef Modifier, StringRef Argument,
378 ArrayRef<ArgumentValue> PrevArgs,
379 SmallVectorImpl<char> &Output,
380 void *Cookie,
381 ArrayRef<intptr_t> QualTypeVals);
382 void *ArgToStringCookie;
383 ArgToStringFnTy ArgToStringFn;
384
385 /// \brief ID of the "delayed" diagnostic, which is a (typically
386 /// fatal) diagnostic that had to be delayed because it was found
387 /// while emitting another diagnostic.
388 unsigned DelayedDiagID;
389
390 /// \brief First string argument for the delayed diagnostic.
391 std::string DelayedDiagArg1;
392
393 /// \brief Second string argument for the delayed diagnostic.
394 std::string DelayedDiagArg2;
395
396 /// \brief Optional flag value.
397 ///
398 /// Some flags accept values, for instance: -Wframe-larger-than=<value> and
399 /// -Rpass=<value>. The content of this string is emitted after the flag name
400 /// and '='.
401 std::string FlagValue;
402
403public:
404 explicit DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> Diags,
405 DiagnosticOptions *DiagOpts,
406 DiagnosticConsumer *client = nullptr,
407 bool ShouldOwnClient = true);
408 DiagnosticsEngine(const DiagnosticsEngine &) = delete;
409 DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
410 ~DiagnosticsEngine();
411
412 const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
413 return Diags;
414 }
415
416 /// \brief Retrieve the diagnostic options.
417 DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
418
419 typedef llvm::iterator_range<DiagState::const_iterator> diag_mapping_range;
420
421 /// \brief Get the current set of diagnostic mappings.
422 diag_mapping_range getDiagnosticMappings() const {
423 const DiagState &DS = *GetCurDiagState();
424 return diag_mapping_range(DS.begin(), DS.end());
425 }
426
427 DiagnosticConsumer *getClient() { return Client; }
428 const DiagnosticConsumer *getClient() const { return Client; }
429
430 /// \brief Determine whether this \c DiagnosticsEngine object own its client.
431 bool ownsClient() const { return Owner != nullptr; }
432
433 /// \brief Return the current diagnostic client along with ownership of that
434 /// client.
435 std::unique_ptr<DiagnosticConsumer> takeClient() { return std::move(Owner); }
436
437 bool hasSourceManager() const { return SourceMgr != nullptr; }
438 SourceManager &getSourceManager() const {
439 assert(SourceMgr && "SourceManager not set!")(static_cast <bool> (SourceMgr && "SourceManager not set!"
) ? void (0) : __assert_fail ("SourceMgr && \"SourceManager not set!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 439, __extension__ __PRETTY_FUNCTION__))
;
440 return *SourceMgr;
441 }
442 void setSourceManager(SourceManager *SrcMgr) {
443 assert(DiagStatesByLoc.empty() &&(static_cast <bool> (DiagStatesByLoc.empty() &&
"Leftover diag state from a different SourceManager.") ? void
(0) : __assert_fail ("DiagStatesByLoc.empty() && \"Leftover diag state from a different SourceManager.\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 444, __extension__ __PRETTY_FUNCTION__))
444 "Leftover diag state from a different SourceManager.")(static_cast <bool> (DiagStatesByLoc.empty() &&
"Leftover diag state from a different SourceManager.") ? void
(0) : __assert_fail ("DiagStatesByLoc.empty() && \"Leftover diag state from a different SourceManager.\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 444, __extension__ __PRETTY_FUNCTION__))
;
445 SourceMgr = SrcMgr;
446 }
447
448 //===--------------------------------------------------------------------===//
449 // DiagnosticsEngine characterization methods, used by a client to customize
450 // how diagnostics are emitted.
451 //
452
453 /// \brief Copies the current DiagMappings and pushes the new copy
454 /// onto the top of the stack.
455 void pushMappings(SourceLocation Loc);
456
457 /// \brief Pops the current DiagMappings off the top of the stack,
458 /// causing the new top of the stack to be the active mappings.
459 ///
460 /// \returns \c true if the pop happens, \c false if there is only one
461 /// DiagMapping on the stack.
462 bool popMappings(SourceLocation Loc);
463
464 /// \brief Set the diagnostic client associated with this diagnostic object.
465 ///
466 /// \param ShouldOwnClient true if the diagnostic object should take
467 /// ownership of \c client.
468 void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true);
469
470 /// \brief Specify a limit for the number of errors we should
471 /// emit before giving up.
472 ///
473 /// Zero disables the limit.
474 void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
475
476 /// \brief Specify the maximum number of template instantiation
477 /// notes to emit along with a given diagnostic.
478 void setTemplateBacktraceLimit(unsigned Limit) {
479 TemplateBacktraceLimit = Limit;
480 }
481
482 /// \brief Retrieve the maximum number of template instantiation
483 /// notes to emit along with a given diagnostic.
484 unsigned getTemplateBacktraceLimit() const {
485 return TemplateBacktraceLimit;
486 }
487
488 /// \brief Specify the maximum number of constexpr evaluation
489 /// notes to emit along with a given diagnostic.
490 void setConstexprBacktraceLimit(unsigned Limit) {
491 ConstexprBacktraceLimit = Limit;
492 }
493
494 /// \brief Retrieve the maximum number of constexpr evaluation
495 /// notes to emit along with a given diagnostic.
496 unsigned getConstexprBacktraceLimit() const {
497 return ConstexprBacktraceLimit;
498 }
499
500 /// \brief When set to true, any unmapped warnings are ignored.
501 ///
502 /// If this and WarningsAsErrors are both set, then this one wins.
503 void setIgnoreAllWarnings(bool Val) {
504 GetCurDiagState()->IgnoreAllWarnings = Val;
505 }
506 bool getIgnoreAllWarnings() const {
507 return GetCurDiagState()->IgnoreAllWarnings;
508 }
509
510 /// \brief When set to true, any unmapped ignored warnings are no longer
511 /// ignored.
512 ///
513 /// If this and IgnoreAllWarnings are both set, then that one wins.
514 void setEnableAllWarnings(bool Val) {
515 GetCurDiagState()->EnableAllWarnings = Val;
516 }
517 bool getEnableAllWarnings() const {
518 return GetCurDiagState()->EnableAllWarnings;
519 }
520
521 /// \brief When set to true, any warnings reported are issued as errors.
522 void setWarningsAsErrors(bool Val) {
523 GetCurDiagState()->WarningsAsErrors = Val;
524 }
525 bool getWarningsAsErrors() const {
526 return GetCurDiagState()->WarningsAsErrors;
527 }
528
529 /// \brief When set to true, any error reported is made a fatal error.
530 void setErrorsAsFatal(bool Val) { GetCurDiagState()->ErrorsAsFatal = Val; }
531 bool getErrorsAsFatal() const { return GetCurDiagState()->ErrorsAsFatal; }
532
533 /// \brief When set to true (the default), suppress further diagnostics after
534 /// a fatal error.
535 void setSuppressAfterFatalError(bool Val) { SuppressAfterFatalError = Val; }
536
537 /// \brief When set to true mask warnings that come from system headers.
538 void setSuppressSystemWarnings(bool Val) {
539 GetCurDiagState()->SuppressSystemWarnings = Val;
540 }
541 bool getSuppressSystemWarnings() const {
542 return GetCurDiagState()->SuppressSystemWarnings;
543 }
544
545 /// \brief Suppress all diagnostics, to silence the front end when we
546 /// know that we don't want any more diagnostics to be passed along to the
547 /// client
548 void setSuppressAllDiagnostics(bool Val = true) {
549 SuppressAllDiagnostics = Val;
550 }
551 bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
552
553 /// \brief Set type eliding, to skip outputting same types occurring in
554 /// template types.
555 void setElideType(bool Val = true) { ElideType = Val; }
556 bool getElideType() { return ElideType; }
557
558 /// \brief Set tree printing, to outputting the template difference in a
559 /// tree format.
560 void setPrintTemplateTree(bool Val = false) { PrintTemplateTree = Val; }
561 bool getPrintTemplateTree() { return PrintTemplateTree; }
562
563 /// \brief Set color printing, so the type diffing will inject color markers
564 /// into the output.
565 void setShowColors(bool Val = false) { ShowColors = Val; }
566 bool getShowColors() { return ShowColors; }
567
568 /// \brief Specify which overload candidates to show when overload resolution
569 /// fails.
570 ///
571 /// By default, we show all candidates.
572 void setShowOverloads(OverloadsShown Val) {
573 ShowOverloads = Val;
574 }
575 OverloadsShown getShowOverloads() const { return ShowOverloads; }
576
577 /// \brief Pretend that the last diagnostic issued was ignored, so any
578 /// subsequent notes will be suppressed.
579 ///
580 /// This can be used by clients who suppress diagnostics themselves.
581 void setLastDiagnosticIgnored() {
582 if (LastDiagLevel == DiagnosticIDs::Fatal)
583 FatalErrorOccurred = true;
584 LastDiagLevel = DiagnosticIDs::Ignored;
585 }
586
587 /// \brief Determine whether the previous diagnostic was ignored. This can
588 /// be used by clients that want to determine whether notes attached to a
589 /// diagnostic will be suppressed.
590 bool isLastDiagnosticIgnored() const {
591 return LastDiagLevel == DiagnosticIDs::Ignored;
592 }
593
594 /// \brief Controls whether otherwise-unmapped extension diagnostics are
595 /// mapped onto ignore/warning/error.
596 ///
597 /// This corresponds to the GCC -pedantic and -pedantic-errors option.
598 void setExtensionHandlingBehavior(diag::Severity H) {
599 GetCurDiagState()->ExtBehavior = H;
600 }
601 diag::Severity getExtensionHandlingBehavior() const {
602 return GetCurDiagState()->ExtBehavior;
603 }
604
605 /// \brief Counter bumped when an __extension__ block is/ encountered.
606 ///
607 /// When non-zero, all extension diagnostics are entirely silenced, no
608 /// matter how they are mapped.
609 void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
610 void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
611 bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
612
613 /// \brief This allows the client to specify that certain warnings are
614 /// ignored.
615 ///
616 /// Notes can never be mapped, errors can only be mapped to fatal, and
617 /// WARNINGs and EXTENSIONs can be mapped arbitrarily.
618 ///
619 /// \param Loc The source location that this change of diagnostic state should
620 /// take affect. It can be null if we are setting the latest state.
621 void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc);
622
623 /// \brief Change an entire diagnostic group (e.g. "unknown-pragmas") to
624 /// have the specified mapping.
625 ///
626 /// \returns true (and ignores the request) if "Group" was unknown, false
627 /// otherwise.
628 ///
629 /// \param Flavor The flavor of group to affect. -Rfoo does not affect the
630 /// state of the -Wfoo group and vice versa.
631 ///
632 /// \param Loc The source location that this change of diagnostic state should
633 /// take affect. It can be null if we are setting the state from command-line.
634 bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group,
635 diag::Severity Map,
636 SourceLocation Loc = SourceLocation());
637
638 /// \brief Set the warning-as-error flag for the given diagnostic group.
639 ///
640 /// This function always only operates on the current diagnostic state.
641 ///
642 /// \returns True if the given group is unknown, false otherwise.
643 bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
644
645 /// \brief Set the error-as-fatal flag for the given diagnostic group.
646 ///
647 /// This function always only operates on the current diagnostic state.
648 ///
649 /// \returns True if the given group is unknown, false otherwise.
650 bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled);
651
652 /// \brief Add the specified mapping to all diagnostics of the specified
653 /// flavor.
654 ///
655 /// Mainly to be used by -Wno-everything to disable all warnings but allow
656 /// subsequent -W options to enable specific warnings.
657 void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map,
658 SourceLocation Loc = SourceLocation());
659
660 bool hasErrorOccurred() const { return ErrorOccurred; }
661
662 /// \brief Errors that actually prevent compilation, not those that are
663 /// upgraded from a warning by -Werror.
664 bool hasUncompilableErrorOccurred() const {
665 return UncompilableErrorOccurred;
666 }
667 bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
668
669 /// \brief Determine whether any kind of unrecoverable error has occurred.
670 bool hasUnrecoverableErrorOccurred() const {
671 return FatalErrorOccurred || UnrecoverableErrorOccurred;
672 }
673
674 unsigned getNumWarnings() const { return NumWarnings; }
675
676 void setNumWarnings(unsigned NumWarnings) {
677 this->NumWarnings = NumWarnings;
678 }
679
680 /// \brief Return an ID for a diagnostic with the specified format string and
681 /// level.
682 ///
683 /// If this is the first request for this diagnostic, it is registered and
684 /// created, otherwise the existing ID is returned.
685 ///
686 /// \param FormatString A fixed diagnostic format string that will be hashed
687 /// and mapped to a unique DiagID.
688 template <unsigned N>
689 unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
690 return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
691 StringRef(FormatString, N - 1));
692 }
693
694 /// \brief Converts a diagnostic argument (as an intptr_t) into the string
695 /// that represents it.
696 void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
697 StringRef Modifier, StringRef Argument,
698 ArrayRef<ArgumentValue> PrevArgs,
699 SmallVectorImpl<char> &Output,
700 ArrayRef<intptr_t> QualTypeVals) const {
701 ArgToStringFn(Kind, Val, Modifier, Argument, PrevArgs, Output,
702 ArgToStringCookie, QualTypeVals);
703 }
704
705 void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
706 ArgToStringFn = Fn;
707 ArgToStringCookie = Cookie;
708 }
709
710 /// \brief Note that the prior diagnostic was emitted by some other
711 /// \c DiagnosticsEngine, and we may be attaching a note to that diagnostic.
712 void notePriorDiagnosticFrom(const DiagnosticsEngine &Other) {
713 LastDiagLevel = Other.LastDiagLevel;
714 }
715
716 /// \brief Reset the state of the diagnostic object to its initial
717 /// configuration.
718 void Reset();
719
720 //===--------------------------------------------------------------------===//
721 // DiagnosticsEngine classification and reporting interfaces.
722 //
723
724 /// \brief Determine whether the diagnostic is known to be ignored.
725 ///
726 /// This can be used to opportunistically avoid expensive checks when it's
727 /// known for certain that the diagnostic has been suppressed at the
728 /// specified location \p Loc.
729 ///
730 /// \param Loc The source location we are interested in finding out the
731 /// diagnostic state. Can be null in order to query the latest state.
732 bool isIgnored(unsigned DiagID, SourceLocation Loc) const {
733 return Diags->getDiagnosticSeverity(DiagID, Loc, *this) ==
734 diag::Severity::Ignored;
735 }
736
737 /// \brief Based on the way the client configured the DiagnosticsEngine
738 /// object, classify the specified diagnostic ID into a Level, consumable by
739 /// the DiagnosticConsumer.
740 ///
741 /// To preserve invariant assumptions, this function should not be used to
742 /// influence parse or semantic analysis actions. Instead consider using
743 /// \c isIgnored().
744 ///
745 /// \param Loc The source location we are interested in finding out the
746 /// diagnostic state. Can be null in order to query the latest state.
747 Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const {
748 return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this);
749 }
750
751 /// \brief Issue the message to the client.
752 ///
753 /// This actually returns an instance of DiagnosticBuilder which emits the
754 /// diagnostics (through @c ProcessDiag) when it is destroyed.
755 ///
756 /// \param DiagID A member of the @c diag::kind enum.
757 /// \param Loc Represents the source location associated with the diagnostic,
758 /// which can be an invalid location if no position information is available.
759 inline DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID);
760 inline DiagnosticBuilder Report(unsigned DiagID);
761
762 void Report(const StoredDiagnostic &storedDiag);
763
764 /// \brief Determine whethere there is already a diagnostic in flight.
765 bool isDiagnosticInFlight() const { return CurDiagID != ~0U; }
766
767 /// \brief Set the "delayed" diagnostic that will be emitted once
768 /// the current diagnostic completes.
769 ///
770 /// If a diagnostic is already in-flight but the front end must
771 /// report a problem (e.g., with an inconsistent file system
772 /// state), this routine sets a "delayed" diagnostic that will be
773 /// emitted after the current diagnostic completes. This should
774 /// only be used for fatal errors detected at inconvenient
775 /// times. If emitting a delayed diagnostic causes a second delayed
776 /// diagnostic to be introduced, that second delayed diagnostic
777 /// will be ignored.
778 ///
779 /// \param DiagID The ID of the diagnostic being delayed.
780 ///
781 /// \param Arg1 A string argument that will be provided to the
782 /// diagnostic. A copy of this string will be stored in the
783 /// DiagnosticsEngine object itself.
784 ///
785 /// \param Arg2 A string argument that will be provided to the
786 /// diagnostic. A copy of this string will be stored in the
787 /// DiagnosticsEngine object itself.
788 void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "",
789 StringRef Arg2 = "");
790
791 /// \brief Clear out the current diagnostic.
792 void Clear() { CurDiagID = ~0U; }
793
794 /// \brief Return the value associated with this diagnostic flag.
795 StringRef getFlagValue() const { return FlagValue; }
796
797private:
798 /// \brief Report the delayed diagnostic.
799 void ReportDelayed();
800
801 // This is private state used by DiagnosticBuilder. We put it here instead of
802 // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
803 // object. This implementation choice means that we can only have one
804 // diagnostic "in flight" at a time, but this seems to be a reasonable
805 // tradeoff to keep these objects small. Assertions verify that only one
806 // diagnostic is in flight at a time.
807 friend class DiagnosticIDs;
808 friend class DiagnosticBuilder;
809 friend class Diagnostic;
810 friend class PartialDiagnostic;
811 friend class DiagnosticErrorTrap;
812
813 /// \brief The location of the current diagnostic that is in flight.
814 SourceLocation CurDiagLoc;
815
816 /// \brief The ID of the current diagnostic that is in flight.
817 ///
818 /// This is set to ~0U when there is no diagnostic in flight.
819 unsigned CurDiagID;
820
821 enum {
822 /// \brief The maximum number of arguments we can hold.
823 ///
824 /// We currently only support up to 10 arguments (%0-%9). A single
825 /// diagnostic with more than that almost certainly has to be simplified
826 /// anyway.
827 MaxArguments = 10,
828 };
829
830 /// \brief The number of entries in Arguments.
831 signed char NumDiagArgs;
832
833 /// \brief Specifies whether an argument is in DiagArgumentsStr or
834 /// in DiagArguments.
835 ///
836 /// This is an array of ArgumentKind::ArgumentKind enum values, one for each
837 /// argument.
838 unsigned char DiagArgumentsKind[MaxArguments];
839
840 /// \brief Holds the values of each string argument for the current
841 /// diagnostic.
842 ///
843 /// This is only used when the corresponding ArgumentKind is ak_std_string.
844 std::string DiagArgumentsStr[MaxArguments];
845
846 /// \brief The values for the various substitution positions.
847 ///
848 /// This is used when the argument is not an std::string. The specific
849 /// value is mangled into an intptr_t and the interpretation depends on
850 /// exactly what sort of argument kind it is.
851 intptr_t DiagArgumentsVal[MaxArguments];
852
853 /// \brief The list of ranges added to this diagnostic.
854 SmallVector<CharSourceRange, 8> DiagRanges;
855
856 /// \brief If valid, provides a hint with some code to insert, remove,
857 /// or modify at a particular position.
858 SmallVector<FixItHint, 8> DiagFixItHints;
859
860 DiagnosticMapping makeUserMapping(diag::Severity Map, SourceLocation L) {
861 bool isPragma = L.isValid();
862 DiagnosticMapping Mapping =
863 DiagnosticMapping::Make(Map, /*IsUser=*/true, isPragma);
864
865 // If this is a pragma mapping, then set the diagnostic mapping flags so
866 // that we override command line options.
867 if (isPragma) {
868 Mapping.setNoWarningAsError(true);
869 Mapping.setNoErrorAsFatal(true);
870 }
871
872 return Mapping;
873 }
874
875 /// \brief Used to report a diagnostic that is finally fully formed.
876 ///
877 /// \returns true if the diagnostic was emitted, false if it was suppressed.
878 bool ProcessDiag() {
879 return Diags->ProcessDiag(*this);
880 }
881
882 /// @name Diagnostic Emission
883 /// @{
884protected:
885 // Sema requires access to the following functions because the current design
886 // of SFINAE requires it to use its own SemaDiagnosticBuilder, which needs to
887 // access us directly to ensure we minimize the emitted code for the common
888 // Sema::Diag() patterns.
889 friend class Sema;
890
891 /// \brief Emit the current diagnostic and clear the diagnostic state.
892 ///
893 /// \param Force Emit the diagnostic regardless of suppression settings.
894 bool EmitCurrentDiagnostic(bool Force = false);
895
896 unsigned getCurrentDiagID() const { return CurDiagID; }
897
898 SourceLocation getCurrentDiagLoc() const { return CurDiagLoc; }
899
900 /// @}
901
902 friend class ASTReader;
903 friend class ASTWriter;
904};
905
906/// \brief RAII class that determines when any errors have occurred
907/// between the time the instance was created and the time it was
908/// queried.
909class DiagnosticErrorTrap {
910 DiagnosticsEngine &Diag;
911 unsigned NumErrors;
912 unsigned NumUnrecoverableErrors;
913
914public:
915 explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag)
916 : Diag(Diag) { reset(); }
917
918 /// \brief Determine whether any errors have occurred since this
919 /// object instance was created.
920 bool hasErrorOccurred() const {
921 return Diag.TrapNumErrorsOccurred > NumErrors;
922 }
923
924 /// \brief Determine whether any unrecoverable errors have occurred since this
925 /// object instance was created.
926 bool hasUnrecoverableErrorOccurred() const {
927 return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
928 }
929
930 /// \brief Set to initial state of "no errors occurred".
931 void reset() {
932 NumErrors = Diag.TrapNumErrorsOccurred;
933 NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
934 }
935};
936
937//===----------------------------------------------------------------------===//
938// DiagnosticBuilder
939//===----------------------------------------------------------------------===//
940
941/// \brief A little helper class used to produce diagnostics.
942///
943/// This is constructed by the DiagnosticsEngine::Report method, and
944/// allows insertion of extra information (arguments and source ranges) into
945/// the currently "in flight" diagnostic. When the temporary for the builder
946/// is destroyed, the diagnostic is issued.
947///
948/// Note that many of these will be created as temporary objects (many call
949/// sites), so we want them to be small and we never want their address taken.
950/// This ensures that compilers with somewhat reasonable optimizers will promote
951/// the common fields to registers, eliminating increments of the NumArgs field,
952/// for example.
953class DiagnosticBuilder {
954 mutable DiagnosticsEngine *DiagObj = nullptr;
955 mutable unsigned NumArgs = 0;
956
957 /// \brief Status variable indicating if this diagnostic is still active.
958 ///
959 // NOTE: This field is redundant with DiagObj (IsActive iff (DiagObj == 0)),
960 // but LLVM is not currently smart enough to eliminate the null check that
961 // Emit() would end up with if we used that as our status variable.
962 mutable bool IsActive = false;
963
964 /// \brief Flag indicating that this diagnostic is being emitted via a
965 /// call to ForceEmit.
966 mutable bool IsForceEmit = false;
967
968 friend class DiagnosticsEngine;
969
970 DiagnosticBuilder() = default;
971
972 explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
973 : DiagObj(diagObj), IsActive(true) {
974 assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!")(static_cast <bool> (diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!"
) ? void (0) : __assert_fail ("diagObj && \"DiagnosticBuilder requires a valid DiagnosticsEngine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 974, __extension__ __PRETTY_FUNCTION__))
;
975 diagObj->DiagRanges.clear();
976 diagObj->DiagFixItHints.clear();
977 }
978
979 friend class PartialDiagnostic;
980
981protected:
982 void FlushCounts() {
983 DiagObj->NumDiagArgs = NumArgs;
984 }
985
986 /// \brief Clear out the current diagnostic.
987 void Clear() const {
988 DiagObj = nullptr;
989 IsActive = false;
990 IsForceEmit = false;
991 }
992
993 /// \brief Determine whether this diagnostic is still active.
994 bool isActive() const { return IsActive; }
995
996 /// \brief Force the diagnostic builder to emit the diagnostic now.
997 ///
998 /// Once this function has been called, the DiagnosticBuilder object
999 /// should not be used again before it is destroyed.
1000 ///
1001 /// \returns true if a diagnostic was emitted, false if the
1002 /// diagnostic was suppressed.
1003 bool Emit() {
1004 // If this diagnostic is inactive, then its soul was stolen by the copy ctor
1005 // (or by a subclass, as in SemaDiagnosticBuilder).
1006 if (!isActive()) return false;
1007
1008 // When emitting diagnostics, we set the final argument count into
1009 // the DiagnosticsEngine object.
1010 FlushCounts();
1011
1012 // Process the diagnostic.
1013 bool Result = DiagObj->EmitCurrentDiagnostic(IsForceEmit);
1014
1015 // This diagnostic is dead.
1016 Clear();
1017
1018 return Result;
1019 }
1020
1021public:
1022 /// Copy constructor. When copied, this "takes" the diagnostic info from the
1023 /// input and neuters it.
1024 DiagnosticBuilder(const DiagnosticBuilder &D) {
1025 DiagObj = D.DiagObj;
1026 IsActive = D.IsActive;
1027 IsForceEmit = D.IsForceEmit;
1028 D.Clear();
1029 NumArgs = D.NumArgs;
1030 }
1031
1032 DiagnosticBuilder &operator=(const DiagnosticBuilder &) = delete;
1033
1034 /// \brief Emits the diagnostic.
1035 ~DiagnosticBuilder() {
1036 Emit();
1037 }
1038
1039 /// \brief Retrieve an empty diagnostic builder.
1040 static DiagnosticBuilder getEmpty() {
1041 return DiagnosticBuilder();
1042 }
1043
1044 /// \brief Forces the diagnostic to be emitted.
1045 const DiagnosticBuilder &setForceEmit() const {
1046 IsForceEmit = true;
1047 return *this;
1048 }
1049
1050 /// \brief Conversion of DiagnosticBuilder to bool always returns \c true.
1051 ///
1052 /// This allows is to be used in boolean error contexts (where \c true is
1053 /// used to indicate that an error has occurred), like:
1054 /// \code
1055 /// return Diag(...);
1056 /// \endcode
1057 operator bool() const { return true; }
1058
1059 void AddString(StringRef S) const {
1060 assert(isActive() && "Clients must not add to cleared diagnostic!")(static_cast <bool> (isActive() && "Clients must not add to cleared diagnostic!"
) ? void (0) : __assert_fail ("isActive() && \"Clients must not add to cleared diagnostic!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1060, __extension__ __PRETTY_FUNCTION__))
;
55
Within the expansion of the macro 'assert':
a
Calling 'DiagnosticBuilder::isActive'
b
Returning from 'DiagnosticBuilder::isActive'
c
Assuming the condition is true
1061 assert(NumArgs < DiagnosticsEngine::MaxArguments &&(static_cast <bool> (NumArgs < DiagnosticsEngine::MaxArguments
&& "Too many arguments to diagnostic!") ? void (0) :
__assert_fail ("NumArgs < DiagnosticsEngine::MaxArguments && \"Too many arguments to diagnostic!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1062, __extension__ __PRETTY_FUNCTION__))
56
Within the expansion of the macro 'assert':
a
Assuming the condition is true
1062 "Too many arguments to diagnostic!")(static_cast <bool> (NumArgs < DiagnosticsEngine::MaxArguments
&& "Too many arguments to diagnostic!") ? void (0) :
__assert_fail ("NumArgs < DiagnosticsEngine::MaxArguments && \"Too many arguments to diagnostic!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1062, __extension__ __PRETTY_FUNCTION__))
;
1063 DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
1064 DiagObj->DiagArgumentsStr[NumArgs++] = S;
1065 }
1066
1067 void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
1068 assert(isActive() && "Clients must not add to cleared diagnostic!")(static_cast <bool> (isActive() && "Clients must not add to cleared diagnostic!"
) ? void (0) : __assert_fail ("isActive() && \"Clients must not add to cleared diagnostic!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1068, __extension__ __PRETTY_FUNCTION__))
;
1069 assert(NumArgs < DiagnosticsEngine::MaxArguments &&(static_cast <bool> (NumArgs < DiagnosticsEngine::MaxArguments
&& "Too many arguments to diagnostic!") ? void (0) :
__assert_fail ("NumArgs < DiagnosticsEngine::MaxArguments && \"Too many arguments to diagnostic!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1070, __extension__ __PRETTY_FUNCTION__))
1070 "Too many arguments to diagnostic!")(static_cast <bool> (NumArgs < DiagnosticsEngine::MaxArguments
&& "Too many arguments to diagnostic!") ? void (0) :
__assert_fail ("NumArgs < DiagnosticsEngine::MaxArguments && \"Too many arguments to diagnostic!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1070, __extension__ __PRETTY_FUNCTION__))
;
1071 DiagObj->DiagArgumentsKind[NumArgs] = Kind;
1072 DiagObj->DiagArgumentsVal[NumArgs++] = V;
1073 }
1074
1075 void AddSourceRange(const CharSourceRange &R) const {
1076 assert(isActive() && "Clients must not add to cleared diagnostic!")(static_cast <bool> (isActive() && "Clients must not add to cleared diagnostic!"
) ? void (0) : __assert_fail ("isActive() && \"Clients must not add to cleared diagnostic!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1076, __extension__ __PRETTY_FUNCTION__))
;
1077 DiagObj->DiagRanges.push_back(R);
1078 }
1079
1080 void AddFixItHint(const FixItHint &Hint) const {
1081 assert(isActive() && "Clients must not add to cleared diagnostic!")(static_cast <bool> (isActive() && "Clients must not add to cleared diagnostic!"
) ? void (0) : __assert_fail ("isActive() && \"Clients must not add to cleared diagnostic!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1081, __extension__ __PRETTY_FUNCTION__))
;
1082 if (!Hint.isNull())
1083 DiagObj->DiagFixItHints.push_back(Hint);
1084 }
1085
1086 void addFlagValue(StringRef V) const { DiagObj->FlagValue = V; }
1087};
1088
1089struct AddFlagValue {
1090 explicit AddFlagValue(StringRef V) : Val(V) {}
1091 StringRef Val;
1092};
1093
1094/// \brief Register a value for the flag in the current diagnostic. This
1095/// value will be shown as the suffix "=value" after the flag name. It is
1096/// useful in cases where the diagnostic flag accepts values (e.g.,
1097/// -Rpass or -Wframe-larger-than).
1098inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1099 const AddFlagValue V) {
1100 DB.addFlagValue(V.Val);
1101 return DB;
1102}
1103
1104inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1105 StringRef S) {
1106 DB.AddString(S);
54
Calling 'DiagnosticBuilder::AddString'
57
Returning from 'DiagnosticBuilder::AddString'
1107 return DB;
1108}
1109
1110inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1111 const char *Str) {
1112 DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
1113 DiagnosticsEngine::ak_c_string);
1114 return DB;
1115}
1116
1117inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
1118 DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
1119 return DB;
1120}
1121
1122// We use enable_if here to prevent that this overload is selected for
1123// pointers or other arguments that are implicitly convertible to bool.
1124template <typename T>
1125inline
1126typename std::enable_if<std::is_same<T, bool>::value,
1127 const DiagnosticBuilder &>::type
1128operator<<(const DiagnosticBuilder &DB, T I) {
1129 DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
1130 return DB;
1131}
1132
1133inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1134 unsigned I) {
1135 DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
1136 return DB;
1137}
1138
1139inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1140 tok::TokenKind I) {
1141 DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
1142 return DB;
1143}
1144
1145inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1146 const IdentifierInfo *II) {
1147 DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
1148 DiagnosticsEngine::ak_identifierinfo);
1149 return DB;
1150}
1151
1152// Adds a DeclContext to the diagnostic. The enable_if template magic is here
1153// so that we only match those arguments that are (statically) DeclContexts;
1154// other arguments that derive from DeclContext (e.g., RecordDecls) will not
1155// match.
1156template <typename T>
1157inline typename std::enable_if<
1158 std::is_same<typename std::remove_const<T>::type, DeclContext>::value,
1159 const DiagnosticBuilder &>::type
1160operator<<(const DiagnosticBuilder &DB, T *DC) {
1161 DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
1162 DiagnosticsEngine::ak_declcontext);
1163 return DB;
1164}
1165
1166inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1167 SourceRange R) {
1168 DB.AddSourceRange(CharSourceRange::getTokenRange(R));
1169 return DB;
1170}
1171
1172inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1173 ArrayRef<SourceRange> Ranges) {
1174 for (SourceRange R : Ranges)
1175 DB.AddSourceRange(CharSourceRange::getTokenRange(R));
1176 return DB;
1177}
1178
1179inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1180 const CharSourceRange &R) {
1181 DB.AddSourceRange(R);
1182 return DB;
1183}
1184
1185inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1186 const FixItHint &Hint) {
1187 DB.AddFixItHint(Hint);
1188 return DB;
1189}
1190
1191inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1192 ArrayRef<FixItHint> Hints) {
1193 for (const FixItHint &Hint : Hints)
1194 DB.AddFixItHint(Hint);
1195 return DB;
1196}
1197
1198/// A nullability kind paired with a bit indicating whether it used a
1199/// context-sensitive keyword.
1200typedef std::pair<NullabilityKind, bool> DiagNullabilityKind;
1201
1202const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1203 DiagNullabilityKind nullability);
1204
1205inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
1206 unsigned DiagID) {
1207 assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!")(static_cast <bool> (CurDiagID == ~0U && "Multiple diagnostics in flight at once!"
) ? void (0) : __assert_fail ("CurDiagID == ~0U && \"Multiple diagnostics in flight at once!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1207, __extension__ __PRETTY_FUNCTION__))
;
51
Within the expansion of the macro 'assert':
a
Assuming the condition is true
1208 CurDiagLoc = Loc;
1209 CurDiagID = DiagID;
1210 FlagValue.clear();
1211 return DiagnosticBuilder(this);
1212}
1213
1214inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
1215 return Report(SourceLocation(), DiagID);
1216}
1217
1218//===----------------------------------------------------------------------===//
1219// Diagnostic
1220//===----------------------------------------------------------------------===//
1221
1222/// A little helper class (which is basically a smart pointer that forwards
1223/// info from DiagnosticsEngine) that allows clients to enquire about the
1224/// currently in-flight diagnostic.
1225class Diagnostic {
1226 const DiagnosticsEngine *DiagObj;
1227 StringRef StoredDiagMessage;
1228
1229public:
1230 explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
1231 Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage)
1232 : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {}
1233
1234 const DiagnosticsEngine *getDiags() const { return DiagObj; }
1235 unsigned getID() const { return DiagObj->CurDiagID; }
1236 const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; }
1237 bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
1238 SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
1239
1240 unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
1241
1242 /// \brief Return the kind of the specified index.
1243 ///
1244 /// Based on the kind of argument, the accessors below can be used to get
1245 /// the value.
1246 ///
1247 /// \pre Idx < getNumArgs()
1248 DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
1249 assert(Idx < getNumArgs() && "Argument index out of range!")(static_cast <bool> (Idx < getNumArgs() && "Argument index out of range!"
) ? void (0) : __assert_fail ("Idx < getNumArgs() && \"Argument index out of range!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1249, __extension__ __PRETTY_FUNCTION__))
;
1250 return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
1251 }
1252
1253 /// \brief Return the provided argument string specified by \p Idx.
1254 /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_std_string
1255 const std::string &getArgStdStr(unsigned Idx) const {
1256 assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&(static_cast <bool> (getArgKind(Idx) == DiagnosticsEngine
::ak_std_string && "invalid argument accessor!") ? void
(0) : __assert_fail ("getArgKind(Idx) == DiagnosticsEngine::ak_std_string && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1257, __extension__ __PRETTY_FUNCTION__))
1257 "invalid argument accessor!")(static_cast <bool> (getArgKind(Idx) == DiagnosticsEngine
::ak_std_string && "invalid argument accessor!") ? void
(0) : __assert_fail ("getArgKind(Idx) == DiagnosticsEngine::ak_std_string && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1257, __extension__ __PRETTY_FUNCTION__))
;
1258 return DiagObj->DiagArgumentsStr[Idx];
1259 }
1260
1261 /// \brief Return the specified C string argument.
1262 /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_c_string
1263 const char *getArgCStr(unsigned Idx) const {
1264 assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&(static_cast <bool> (getArgKind(Idx) == DiagnosticsEngine
::ak_c_string && "invalid argument accessor!") ? void
(0) : __assert_fail ("getArgKind(Idx) == DiagnosticsEngine::ak_c_string && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1265, __extension__ __PRETTY_FUNCTION__))
1265 "invalid argument accessor!")(static_cast <bool> (getArgKind(Idx) == DiagnosticsEngine
::ak_c_string && "invalid argument accessor!") ? void
(0) : __assert_fail ("getArgKind(Idx) == DiagnosticsEngine::ak_c_string && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1265, __extension__ __PRETTY_FUNCTION__))
;
1266 return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
1267 }
1268
1269 /// \brief Return the specified signed integer argument.
1270 /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_sint
1271 int getArgSInt(unsigned Idx) const {
1272 assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&(static_cast <bool> (getArgKind(Idx) == DiagnosticsEngine
::ak_sint && "invalid argument accessor!") ? void (0)
: __assert_fail ("getArgKind(Idx) == DiagnosticsEngine::ak_sint && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1273, __extension__ __PRETTY_FUNCTION__))
1273 "invalid argument accessor!")(static_cast <bool> (getArgKind(Idx) == DiagnosticsEngine
::ak_sint && "invalid argument accessor!") ? void (0)
: __assert_fail ("getArgKind(Idx) == DiagnosticsEngine::ak_sint && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1273, __extension__ __PRETTY_FUNCTION__))
;
1274 return (int)DiagObj->DiagArgumentsVal[Idx];
1275 }
1276
1277 /// \brief Return the specified unsigned integer argument.
1278 /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_uint
1279 unsigned getArgUInt(unsigned Idx) const {
1280 assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&(static_cast <bool> (getArgKind(Idx) == DiagnosticsEngine
::ak_uint && "invalid argument accessor!") ? void (0)
: __assert_fail ("getArgKind(Idx) == DiagnosticsEngine::ak_uint && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1281, __extension__ __PRETTY_FUNCTION__))
1281 "invalid argument accessor!")(static_cast <bool> (getArgKind(Idx) == DiagnosticsEngine
::ak_uint && "invalid argument accessor!") ? void (0)
: __assert_fail ("getArgKind(Idx) == DiagnosticsEngine::ak_uint && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1281, __extension__ __PRETTY_FUNCTION__))
;
1282 return (unsigned)DiagObj->DiagArgumentsVal[Idx];
1283 }
1284
1285 /// \brief Return the specified IdentifierInfo argument.
1286 /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo
1287 const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
1288 assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&(static_cast <bool> (getArgKind(Idx) == DiagnosticsEngine
::ak_identifierinfo && "invalid argument accessor!") ?
void (0) : __assert_fail ("getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1289, __extension__ __PRETTY_FUNCTION__))
1289 "invalid argument accessor!")(static_cast <bool> (getArgKind(Idx) == DiagnosticsEngine
::ak_identifierinfo && "invalid argument accessor!") ?
void (0) : __assert_fail ("getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1289, __extension__ __PRETTY_FUNCTION__))
;
1290 return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
1291 }
1292
1293 /// \brief Return the specified non-string argument in an opaque form.
1294 /// \pre getArgKind(Idx) != DiagnosticsEngine::ak_std_string
1295 intptr_t getRawArg(unsigned Idx) const {
1296 assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&(static_cast <bool> (getArgKind(Idx) != DiagnosticsEngine
::ak_std_string && "invalid argument accessor!") ? void
(0) : __assert_fail ("getArgKind(Idx) != DiagnosticsEngine::ak_std_string && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1297, __extension__ __PRETTY_FUNCTION__))
1297 "invalid argument accessor!")(static_cast <bool> (getArgKind(Idx) != DiagnosticsEngine
::ak_std_string && "invalid argument accessor!") ? void
(0) : __assert_fail ("getArgKind(Idx) != DiagnosticsEngine::ak_std_string && \"invalid argument accessor!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1297, __extension__ __PRETTY_FUNCTION__))
;
1298 return DiagObj->DiagArgumentsVal[Idx];
1299 }
1300
1301 /// \brief Return the number of source ranges associated with this diagnostic.
1302 unsigned getNumRanges() const {
1303 return DiagObj->DiagRanges.size();
1304 }
1305
1306 /// \pre Idx < getNumRanges()
1307 const CharSourceRange &getRange(unsigned Idx) const {
1308 assert(Idx < getNumRanges() && "Invalid diagnostic range index!")(static_cast <bool> (Idx < getNumRanges() &&
"Invalid diagnostic range index!") ? void (0) : __assert_fail
("Idx < getNumRanges() && \"Invalid diagnostic range index!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1308, __extension__ __PRETTY_FUNCTION__))
;
1309 return DiagObj->DiagRanges[Idx];
1310 }
1311
1312 /// \brief Return an array reference for this diagnostic's ranges.
1313 ArrayRef<CharSourceRange> getRanges() const {
1314 return DiagObj->DiagRanges;
1315 }
1316
1317 unsigned getNumFixItHints() const {
1318 return DiagObj->DiagFixItHints.size();
1319 }
1320
1321 const FixItHint &getFixItHint(unsigned Idx) const {
1322 assert(Idx < getNumFixItHints() && "Invalid index!")(static_cast <bool> (Idx < getNumFixItHints() &&
"Invalid index!") ? void (0) : __assert_fail ("Idx < getNumFixItHints() && \"Invalid index!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318601/tools/clang/include/clang/Basic/Diagnostic.h"
, 1322, __extension__ __PRETTY_FUNCTION__))
;
1323 return DiagObj->DiagFixItHints[Idx];
1324 }
1325
1326 ArrayRef<FixItHint> getFixItHints() const {
1327 return DiagObj->DiagFixItHints;
1328 }
1329
1330 /// \brief Format this diagnostic into a string, substituting the
1331 /// formal arguments into the %0 slots.
1332 ///
1333 /// The result is appended onto the \p OutStr array.
1334 void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const;
1335
1336 /// \brief Format the given format-string into the output buffer using the
1337 /// arguments stored in this diagnostic.
1338 void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
1339 SmallVectorImpl<char> &OutStr) const;
1340};
1341
1342/**
1343 * \brief Represents a diagnostic in a form that can be retained until its
1344 * corresponding source manager is destroyed.
1345 */
1346class StoredDiagnostic {
1347 unsigned ID;
1348 DiagnosticsEngine::Level Level;
1349 FullSourceLoc Loc;
1350 std::string Message;
1351 std::vector<CharSourceRange> Ranges;
1352 std::vector<FixItHint> FixIts;
1353
1354public:
1355 StoredDiagnostic() = default;
1356 StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
1357 StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
1358 StringRef Message);
1359 StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
1360 StringRef Message, FullSourceLoc Loc,
1361 ArrayRef<CharSourceRange> Ranges,
1362 ArrayRef<FixItHint> Fixits);
1363
1364 /// \brief Evaluates true when this object stores a diagnostic.
1365 explicit operator bool() const { return !Message.empty(); }
1366
1367 unsigned getID() const { return ID; }
1368 DiagnosticsEngine::Level getLevel() const { return Level; }
1369 const FullSourceLoc &getLocation() const { return Loc; }
1370 StringRef getMessage() const { return Message; }
1371
1372 void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
1373
1374 typedef std::vector<CharSourceRange>::const_iterator range_iterator;
1375 range_iterator range_begin() const { return Ranges.begin(); }
1376 range_iterator range_end() const { return Ranges.end(); }
1377 unsigned range_size() const { return Ranges.size(); }
1378
1379 ArrayRef<CharSourceRange> getRanges() const {
1380 return llvm::makeArrayRef(Ranges);
1381 }
1382
1383 typedef std::vector<FixItHint>::const_iterator fixit_iterator;
1384 fixit_iterator fixit_begin() const { return FixIts.begin(); }
1385 fixit_iterator fixit_end() const { return FixIts.end(); }
1386 unsigned fixit_size() const { return FixIts.size(); }
1387
1388 ArrayRef<FixItHint> getFixIts() const {
1389 return llvm::makeArrayRef(FixIts);
1390 }
1391};
1392
1393/// \brief Abstract interface, implemented by clients of the front-end, which
1394/// formats and prints fully processed diagnostics.
1395class DiagnosticConsumer {
1396protected:
1397 unsigned NumWarnings = 0; ///< Number of warnings reported
1398 unsigned NumErrors = 0; ///< Number of errors reported
1399
1400public:
1401 DiagnosticConsumer() = default;
1402
1403 virtual ~DiagnosticConsumer();
1404
1405 unsigned getNumErrors() const { return NumErrors; }
1406 unsigned getNumWarnings() const { return NumWarnings; }
1407 virtual void clear() { NumWarnings = NumErrors = 0; }
1408
1409 /// \brief Callback to inform the diagnostic client that processing
1410 /// of a source file is beginning.
1411 ///
1412 /// Note that diagnostics may be emitted outside the processing of a source
1413 /// file, for example during the parsing of command line options. However,
1414 /// diagnostics with source range information are required to only be emitted
1415 /// in between BeginSourceFile() and EndSourceFile().
1416 ///
1417 /// \param LangOpts The language options for the source file being processed.
1418 /// \param PP The preprocessor object being used for the source; this is
1419 /// optional, e.g., it may not be present when processing AST source files.
1420 virtual void BeginSourceFile(const LangOptions &LangOpts,
1421 const Preprocessor *PP = nullptr) {}
1422
1423 /// \brief Callback to inform the diagnostic client that processing
1424 /// of a source file has ended.
1425 ///
1426 /// The diagnostic client should assume that any objects made available via
1427 /// BeginSourceFile() are inaccessible.
1428 virtual void EndSourceFile() {}
1429
1430 /// \brief Callback to inform the diagnostic client that processing of all
1431 /// source files has ended.
1432 virtual void finish() {}
1433
1434 /// \brief Indicates whether the diagnostics handled by this
1435 /// DiagnosticConsumer should be included in the number of diagnostics
1436 /// reported by DiagnosticsEngine.
1437 ///
1438 /// The default implementation returns true.
1439 virtual bool IncludeInDiagnosticCounts() const;
1440
1441 /// \brief Handle this diagnostic, reporting it to the user or
1442 /// capturing it to a log as needed.
1443 ///
1444 /// The default implementation just keeps track of the total number of
1445 /// warnings and errors.
1446 virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1447 const Diagnostic &Info);
1448};
1449
1450/// \brief A diagnostic client that ignores all diagnostics.
1451class IgnoringDiagConsumer : public DiagnosticConsumer {
1452 virtual void anchor();
1453
1454 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1455 const Diagnostic &Info) override {
1456 // Just ignore it.
1457 }
1458};
1459
1460/// \brief Diagnostic consumer that forwards diagnostics along to an
1461/// existing, already-initialized diagnostic consumer.
1462///
1463class ForwardingDiagnosticConsumer : public DiagnosticConsumer {
1464 DiagnosticConsumer &Target;
1465
1466public:
1467 ForwardingDiagnosticConsumer(DiagnosticConsumer &Target) : Target(Target) {}
1468
1469 ~ForwardingDiagnosticConsumer() override;
1470
1471 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1472 const Diagnostic &Info) override;
1473 void clear() override;
1474
1475 bool IncludeInDiagnosticCounts() const override;
1476};
1477
1478// Struct used for sending info about how a type should be printed.
1479struct TemplateDiffTypes {
1480 intptr_t FromType;
1481 intptr_t ToType;
1482 unsigned PrintTree : 1;
1483 unsigned PrintFromType : 1;
1484 unsigned ElideType : 1;
1485 unsigned ShowColors : 1;
1486 // The printer sets this variable to true if the template diff was used.
1487 unsigned TemplateDiffUsed : 1;
1488};
1489
1490/// Special character that the diagnostic printer will use to toggle the bold
1491/// attribute. The character itself will be not be printed.
1492const char ToggleHighlight = 127;
1493
1494
1495/// ProcessWarningOptions - Initialize the diagnostic client and process the
1496/// warning options specified on the command line.
1497void ProcessWarningOptions(DiagnosticsEngine &Diags,
1498 const DiagnosticOptions &Opts,
1499 bool ReportDiags = true);
1500
1501} // end namespace clang
1502
1503#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_H