Bug Summary

File:tools/clang/tools/libclang/Indexing.cpp
Warning:line 381, column 16
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name Indexing.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D CLANG_TOOL_EXTRA_BUILD -D _CINDEX_LIB_ -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/clang/tools/libclang -I /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/libclang -I /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/clang/tools/libclang -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-04-11-031539-24776-1 -x c++ /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/libclang/Indexing.cpp

/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/libclang/Indexing.cpp

1//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
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 "CIndexDiagnostic.h"
11#include "CIndexer.h"
12#include "CLog.h"
13#include "CXCursor.h"
14#include "CXIndexDataConsumer.h"
15#include "CXSourceLocation.h"
16#include "CXString.h"
17#include "CXTranslationUnit.h"
18#include "clang/AST/ASTConsumer.h"
19#include "clang/Frontend/ASTUnit.h"
20#include "clang/Frontend/CompilerInstance.h"
21#include "clang/Frontend/CompilerInvocation.h"
22#include "clang/Frontend/FrontendAction.h"
23#include "clang/Frontend/Utils.h"
24#include "clang/Index/IndexingAction.h"
25#include "clang/Lex/HeaderSearch.h"
26#include "clang/Lex/PPCallbacks.h"
27#include "clang/Lex/PPConditionalDirectiveRecord.h"
28#include "clang/Lex/Preprocessor.h"
29#include "clang/Lex/PreprocessorOptions.h"
30#include "llvm/Support/CrashRecoveryContext.h"
31#include "llvm/Support/MemoryBuffer.h"
32#include "llvm/Support/Mutex.h"
33#include "llvm/Support/MutexGuard.h"
34#include <cstdio>
35#include <utility>
36
37using namespace clang;
38using namespace clang::index;
39using namespace cxtu;
40using namespace cxindex;
41
42namespace {
43
44//===----------------------------------------------------------------------===//
45// Skip Parsed Bodies
46//===----------------------------------------------------------------------===//
47
48/// \brief A "region" in source code identified by the file/offset of the
49/// preprocessor conditional directive that it belongs to.
50/// Multiple, non-consecutive ranges can be parts of the same region.
51///
52/// As an example of different regions separated by preprocessor directives:
53///
54/// \code
55/// #1
56/// #ifdef BLAH
57/// #2
58/// #ifdef CAKE
59/// #3
60/// #endif
61/// #2
62/// #endif
63/// #1
64/// \endcode
65///
66/// There are 3 regions, with non-consecutive parts:
67/// #1 is identified as the beginning of the file
68/// #2 is identified as the location of "#ifdef BLAH"
69/// #3 is identified as the location of "#ifdef CAKE"
70///
71class PPRegion {
72 llvm::sys::fs::UniqueID UniqueID;
73 time_t ModTime;
74 unsigned Offset;
75public:
76 PPRegion() : UniqueID(0, 0), ModTime(), Offset() {}
77 PPRegion(llvm::sys::fs::UniqueID UniqueID, unsigned offset, time_t modTime)
78 : UniqueID(UniqueID), ModTime(modTime), Offset(offset) {}
79
80 const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
81 unsigned getOffset() const { return Offset; }
82 time_t getModTime() const { return ModTime; }
83
84 bool isInvalid() const { return *this == PPRegion(); }
85
86 friend bool operator==(const PPRegion &lhs, const PPRegion &rhs) {
87 return lhs.UniqueID == rhs.UniqueID && lhs.Offset == rhs.Offset &&
88 lhs.ModTime == rhs.ModTime;
89 }
90};
91
92typedef llvm::DenseSet<PPRegion> PPRegionSetTy;
93
94} // end anonymous namespace
95
96namespace llvm {
97 template <> struct isPodLike<PPRegion> {
98 static const bool value = true;
99 };
100
101 template <>
102 struct DenseMapInfo<PPRegion> {
103 static inline PPRegion getEmptyKey() {
104 return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-1), 0);
105 }
106 static inline PPRegion getTombstoneKey() {
107 return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-2), 0);
108 }
109
110 static unsigned getHashValue(const PPRegion &S) {
111 llvm::FoldingSetNodeID ID;
112 const llvm::sys::fs::UniqueID &UniqueID = S.getUniqueID();
113 ID.AddInteger(UniqueID.getFile());
114 ID.AddInteger(UniqueID.getDevice());
115 ID.AddInteger(S.getOffset());
116 ID.AddInteger(S.getModTime());
117 return ID.ComputeHash();
118 }
119
120 static bool isEqual(const PPRegion &LHS, const PPRegion &RHS) {
121 return LHS == RHS;
122 }
123 };
124}
125
126namespace {
127
128class SessionSkipBodyData {
129 llvm::sys::Mutex Mux;
130 PPRegionSetTy ParsedRegions;
131
132public:
133 SessionSkipBodyData() : Mux(/*recursive=*/false) {}
134 ~SessionSkipBodyData() {
135 //llvm::errs() << "RegionData: " << Skipped.size() << " - " << Skipped.getMemorySize() << "\n";
136 }
137
138 void copyTo(PPRegionSetTy &Set) {
139 llvm::MutexGuard MG(Mux);
140 Set = ParsedRegions;
141 }
142
143 void update(ArrayRef<PPRegion> Regions) {
144 llvm::MutexGuard MG(Mux);
145 ParsedRegions.insert(Regions.begin(), Regions.end());
146 }
147};
148
149class TUSkipBodyControl {
150 SessionSkipBodyData &SessionData;
151 PPConditionalDirectiveRecord &PPRec;
152 Preprocessor &PP;
153
154 PPRegionSetTy ParsedRegions;
155 SmallVector<PPRegion, 32> NewParsedRegions;
156 PPRegion LastRegion;
157 bool LastIsParsed;
158
159public:
160 TUSkipBodyControl(SessionSkipBodyData &sessionData,
161 PPConditionalDirectiveRecord &ppRec,
162 Preprocessor &pp)
163 : SessionData(sessionData), PPRec(ppRec), PP(pp) {
164 SessionData.copyTo(ParsedRegions);
165 }
166
167 bool isParsed(SourceLocation Loc, FileID FID, const FileEntry *FE) {
168 PPRegion region = getRegion(Loc, FID, FE);
169 if (region.isInvalid())
170 return false;
171
172 // Check common case, consecutive functions in the same region.
173 if (LastRegion == region)
174 return LastIsParsed;
175
176 LastRegion = region;
177 LastIsParsed = ParsedRegions.count(region);
178 if (!LastIsParsed)
179 NewParsedRegions.push_back(region);
180 return LastIsParsed;
181 }
182
183 void finished() {
184 SessionData.update(NewParsedRegions);
185 }
186
187private:
188 PPRegion getRegion(SourceLocation Loc, FileID FID, const FileEntry *FE) {
189 SourceLocation RegionLoc = PPRec.findConditionalDirectiveRegionLoc(Loc);
190 if (RegionLoc.isInvalid()) {
191 if (isParsedOnceInclude(FE)) {
192 const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
193 return PPRegion(ID, 0, FE->getModificationTime());
194 }
195 return PPRegion();
196 }
197
198 const SourceManager &SM = PPRec.getSourceManager();
199 assert(RegionLoc.isFileID())(static_cast <bool> (RegionLoc.isFileID()) ? void (0) :
__assert_fail ("RegionLoc.isFileID()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/tools/libclang/Indexing.cpp"
, 199, __extension__ __PRETTY_FUNCTION__))
;
200 FileID RegionFID;
201 unsigned RegionOffset;
202 std::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
203
204 if (RegionFID != FID) {
205 if (isParsedOnceInclude(FE)) {
206 const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
207 return PPRegion(ID, 0, FE->getModificationTime());
208 }
209 return PPRegion();
210 }
211
212 const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
213 return PPRegion(ID, RegionOffset, FE->getModificationTime());
214 }
215
216 bool isParsedOnceInclude(const FileEntry *FE) {
217 return PP.getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE);
218 }
219};
220
221//===----------------------------------------------------------------------===//
222// IndexPPCallbacks
223//===----------------------------------------------------------------------===//
224
225class IndexPPCallbacks : public PPCallbacks {
226 Preprocessor &PP;
227 CXIndexDataConsumer &DataConsumer;
228 bool IsMainFileEntered;
229
230public:
231 IndexPPCallbacks(Preprocessor &PP, CXIndexDataConsumer &dataConsumer)
232 : PP(PP), DataConsumer(dataConsumer), IsMainFileEntered(false) { }
233
234 void FileChanged(SourceLocation Loc, FileChangeReason Reason,
235 SrcMgr::CharacteristicKind FileType, FileID PrevFID) override {
236 if (IsMainFileEntered)
237 return;
238
239 SourceManager &SM = PP.getSourceManager();
240 SourceLocation MainFileLoc = SM.getLocForStartOfFile(SM.getMainFileID());
241
242 if (Loc == MainFileLoc && Reason == PPCallbacks::EnterFile) {
243 IsMainFileEntered = true;
244 DataConsumer.enteredMainFile(SM.getFileEntryForID(SM.getMainFileID()));
245 }
246 }
247
248 void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
249 StringRef FileName, bool IsAngled,
250 CharSourceRange FilenameRange, const FileEntry *File,
251 StringRef SearchPath, StringRef RelativePath,
252 const Module *Imported) override {
253 bool isImport = (IncludeTok.is(tok::identifier) &&
254 IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import);
255 DataConsumer.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled,
256 Imported);
257 }
258
259 /// MacroDefined - This hook is called whenever a macro definition is seen.
260 void MacroDefined(const Token &Id, const MacroDirective *MD) override {}
261
262 /// MacroUndefined - This hook is called whenever a macro #undef is seen.
263 /// MI is released immediately following this callback.
264 void MacroUndefined(const Token &MacroNameTok,
265 const MacroDefinition &MD,
266 const MacroDirective *UD) override {}
267
268 /// MacroExpands - This is called by when a macro invocation is found.
269 void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
270 SourceRange Range, const MacroArgs *Args) override {}
271
272 /// SourceRangeSkipped - This hook is called when a source range is skipped.
273 /// \param Range The SourceRange that was skipped. The range begins at the
274 /// #if/#else directive and ends after the #endif/#else directive.
275 void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
276 }
277};
278
279//===----------------------------------------------------------------------===//
280// IndexingConsumer
281//===----------------------------------------------------------------------===//
282
283class IndexingConsumer : public ASTConsumer {
284 CXIndexDataConsumer &DataConsumer;
285 TUSkipBodyControl *SKCtrl;
286
287public:
288 IndexingConsumer(CXIndexDataConsumer &dataConsumer, TUSkipBodyControl *skCtrl)
289 : DataConsumer(dataConsumer), SKCtrl(skCtrl) { }
290
291 // ASTConsumer Implementation
292
293 void Initialize(ASTContext &Context) override {
294 DataConsumer.setASTContext(Context);
295 DataConsumer.startedTranslationUnit();
296 }
297
298 void HandleTranslationUnit(ASTContext &Ctx) override {
299 if (SKCtrl)
300 SKCtrl->finished();
301 }
302
303 bool HandleTopLevelDecl(DeclGroupRef DG) override {
304 return !DataConsumer.shouldAbort();
305 }
306
307 bool shouldSkipFunctionBody(Decl *D) override {
308 if (!SKCtrl) {
309 // Always skip bodies.
310 return true;
311 }
312
313 const SourceManager &SM = DataConsumer.getASTContext().getSourceManager();
314 SourceLocation Loc = D->getLocation();
315 if (Loc.isMacroID())
316 return false;
317 if (SM.isInSystemHeader(Loc))
318 return true; // always skip bodies from system headers.
319
320 FileID FID;
321 unsigned Offset;
322 std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
323 // Don't skip bodies from main files; this may be revisited.
324 if (SM.getMainFileID() == FID)
325 return false;
326 const FileEntry *FE = SM.getFileEntryForID(FID);
327 if (!FE)
328 return false;
329
330 return SKCtrl->isParsed(Loc, FID, FE);
331 }
332};
333
334//===----------------------------------------------------------------------===//
335// CaptureDiagnosticConsumer
336//===----------------------------------------------------------------------===//
337
338class CaptureDiagnosticConsumer : public DiagnosticConsumer {
339 SmallVector<StoredDiagnostic, 4> Errors;
340public:
341
342 void HandleDiagnostic(DiagnosticsEngine::Level level,
343 const Diagnostic &Info) override {
344 if (level >= DiagnosticsEngine::Error)
345 Errors.push_back(StoredDiagnostic(level, Info));
346 }
347};
348
349//===----------------------------------------------------------------------===//
350// IndexingFrontendAction
351//===----------------------------------------------------------------------===//
352
353class IndexingFrontendAction : public ASTFrontendAction {
354 std::shared_ptr<CXIndexDataConsumer> DataConsumer;
355
356 SessionSkipBodyData *SKData;
357 std::unique_ptr<TUSkipBodyControl> SKCtrl;
358
359public:
360 IndexingFrontendAction(std::shared_ptr<CXIndexDataConsumer> dataConsumer,
361 SessionSkipBodyData *skData)
362 : DataConsumer(std::move(dataConsumer)), SKData(skData) {}
363
364 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
365 StringRef InFile) override {
366 PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
367
368 if (!PPOpts.ImplicitPCHInclude.empty()) {
1
Assuming the condition is false
2
Taking false branch
369 DataConsumer->importedPCH(
370 CI.getFileManager().getFile(PPOpts.ImplicitPCHInclude));
371 }
372
373 DataConsumer->setASTContext(CI.getASTContext());
374 Preprocessor &PP = CI.getPreprocessor();
375 PP.addPPCallbacks(llvm::make_unique<IndexPPCallbacks>(PP, *DataConsumer));
376 DataConsumer->setPreprocessor(CI.getPreprocessorPtr());
377
378 if (SKData) {
3
Assuming the condition is true
4
Taking true branch
379 auto *PPRec = new PPConditionalDirectiveRecord(PP.getSourceManager());
5
Memory is allocated
380 PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(PPRec));
6
Calling '~unique_ptr'
11
Returning from '~unique_ptr'
381 SKCtrl = llvm::make_unique<TUSkipBodyControl>(*SKData, *PPRec, PP);
12
Use of memory after it is freed
382 }
383
384 return llvm::make_unique<IndexingConsumer>(*DataConsumer, SKCtrl.get());
385 }
386
387 TranslationUnitKind getTranslationUnitKind() override {
388 if (DataConsumer->shouldIndexImplicitTemplateInsts())
389 return TU_Complete;
390 else
391 return TU_Prefix;
392 }
393 bool hasCodeCompletionSupport() const override { return false; }
394};
395
396//===----------------------------------------------------------------------===//
397// clang_indexSourceFileUnit Implementation
398//===----------------------------------------------------------------------===//
399
400static IndexingOptions getIndexingOptionsFromCXOptions(unsigned index_options) {
401 IndexingOptions IdxOpts;
402 if (index_options & CXIndexOpt_IndexFunctionLocalSymbols)
403 IdxOpts.IndexFunctionLocals = true;
404 return IdxOpts;
405}
406
407struct IndexSessionData {
408 CXIndex CIdx;
409 std::unique_ptr<SessionSkipBodyData> SkipBodyData;
410
411 explicit IndexSessionData(CXIndex cIdx)
412 : CIdx(cIdx), SkipBodyData(new SessionSkipBodyData) {}
413};
414
415} // anonymous namespace
416
417static CXErrorCode clang_indexSourceFile_Impl(
418 CXIndexAction cxIdxAction, CXClientData client_data,
419 IndexerCallbacks *client_index_callbacks, unsigned index_callbacks_size,
420 unsigned index_options, const char *source_filename,
421 const char *const *command_line_args, int num_command_line_args,
422 ArrayRef<CXUnsavedFile> unsaved_files, CXTranslationUnit *out_TU,
423 unsigned TU_options) {
424 if (out_TU)
425 *out_TU = nullptr;
426 bool requestedToGetTU = (out_TU != nullptr);
427
428 if (!cxIdxAction) {
429 return CXError_InvalidArguments;
430 }
431 if (!client_index_callbacks || index_callbacks_size == 0) {
432 return CXError_InvalidArguments;
433 }
434
435 IndexerCallbacks CB;
436 memset(&CB, 0, sizeof(CB));
437 unsigned ClientCBSize = index_callbacks_size < sizeof(CB)
438 ? index_callbacks_size : sizeof(CB);
439 memcpy(&CB, client_index_callbacks, ClientCBSize);
440
441 IndexSessionData *IdxSession = static_cast<IndexSessionData *>(cxIdxAction);
442 CIndexer *CXXIdx = static_cast<CIndexer *>(IdxSession->CIdx);
443
444 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
445 setThreadBackgroundPriority();
446
447 bool CaptureDiagnostics = !Logger::isLoggingEnabled();
448
449 CaptureDiagnosticConsumer *CaptureDiag = nullptr;
450 if (CaptureDiagnostics)
451 CaptureDiag = new CaptureDiagnosticConsumer();
452
453 // Configure the diagnostics.
454 IntrusiveRefCntPtr<DiagnosticsEngine>
455 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
456 CaptureDiag,
457 /*ShouldOwnClient=*/true));
458
459 // Recover resources if we crash before exiting this function.
460 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
461 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
462 DiagCleanup(Diags.get());
463
464 std::unique_ptr<std::vector<const char *>> Args(
465 new std::vector<const char *>());
466
467 // Recover resources if we crash before exiting this method.
468 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
469 ArgsCleanup(Args.get());
470
471 Args->insert(Args->end(), command_line_args,
472 command_line_args + num_command_line_args);
473
474 // The 'source_filename' argument is optional. If the caller does not
475 // specify it then it is assumed that the source file is specified
476 // in the actual argument list.
477 // Put the source file after command_line_args otherwise if '-x' flag is
478 // present it will be unused.
479 if (source_filename)
480 Args->push_back(source_filename);
481
482 std::shared_ptr<CompilerInvocation> CInvok =
483 createInvocationFromCommandLine(*Args, Diags);
484
485 if (!CInvok)
486 return CXError_Failure;
487
488 // Recover resources if we crash before exiting this function.
489 llvm::CrashRecoveryContextCleanupRegistrar<
490 std::shared_ptr<CompilerInvocation>,
491 llvm::CrashRecoveryContextDestructorCleanup<
492 std::shared_ptr<CompilerInvocation>>>
493 CInvokCleanup(&CInvok);
494
495 if (CInvok->getFrontendOpts().Inputs.empty())
496 return CXError_Failure;
497
498 typedef SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 8> MemBufferOwner;
499 std::unique_ptr<MemBufferOwner> BufOwner(new MemBufferOwner);
500
501 // Recover resources if we crash before exiting this method.
502 llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner> BufOwnerCleanup(
503 BufOwner.get());
504
505 for (auto &UF : unsaved_files) {
506 std::unique_ptr<llvm::MemoryBuffer> MB =
507 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
508 CInvok->getPreprocessorOpts().addRemappedFile(UF.Filename, MB.get());
509 BufOwner->push_back(std::move(MB));
510 }
511
512 // Since libclang is primarily used by batch tools dealing with
513 // (often very broken) source code, where spell-checking can have a
514 // significant negative impact on performance (particularly when
515 // precompiled headers are involved), we disable it.
516 CInvok->getLangOpts()->SpellChecking = false;
517
518 if (index_options & CXIndexOpt_SuppressWarnings)
519 CInvok->getDiagnosticOpts().IgnoreWarnings = true;
520
521 // Make sure to use the raw module format.
522 CInvok->getHeaderSearchOpts().ModuleFormat =
523 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat();
524
525 auto Unit = ASTUnit::create(CInvok, Diags, CaptureDiagnostics,
526 /*UserFilesAreVolatile=*/true);
527 if (!Unit)
528 return CXError_InvalidArguments;
529
530 auto *UPtr = Unit.get();
531 std::unique_ptr<CXTUOwner> CXTU(
532 new CXTUOwner(MakeCXTranslationUnit(CXXIdx, std::move(Unit))));
533
534 // Recover resources if we crash before exiting this method.
535 llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
536 CXTUCleanup(CXTU.get());
537
538 // Enable the skip-parsed-bodies optimization only for C++; this may be
539 // revisited.
540 bool SkipBodies = (index_options & CXIndexOpt_SkipParsedBodiesInSession) &&
541 CInvok->getLangOpts()->CPlusPlus;
542 if (SkipBodies)
543 CInvok->getFrontendOpts().SkipFunctionBodies = true;
544
545 auto DataConsumer =
546 std::make_shared<CXIndexDataConsumer>(client_data, CB, index_options,
547 CXTU->getTU());
548 auto InterAction = llvm::make_unique<IndexingFrontendAction>(DataConsumer,
549 SkipBodies ? IdxSession->SkipBodyData.get() : nullptr);
550 std::unique_ptr<FrontendAction> IndexAction;
551 IndexAction = createIndexingAction(DataConsumer,
552 getIndexingOptionsFromCXOptions(index_options),
553 std::move(InterAction));
554
555 // Recover resources if we crash before exiting this method.
556 llvm::CrashRecoveryContextCleanupRegistrar<FrontendAction>
557 IndexActionCleanup(IndexAction.get());
558
559 bool Persistent = requestedToGetTU;
560 bool OnlyLocalDecls = false;
561 bool PrecompilePreamble = false;
562 bool CreatePreambleOnFirstParse = false;
563 bool CacheCodeCompletionResults = false;
564 PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
565 PPOpts.AllowPCHWithCompilerErrors = true;
566
567 if (requestedToGetTU) {
568 OnlyLocalDecls = CXXIdx->getOnlyLocalDecls();
569 PrecompilePreamble = TU_options & CXTranslationUnit_PrecompiledPreamble;
570 CreatePreambleOnFirstParse =
571 TU_options & CXTranslationUnit_CreatePreambleOnFirstParse;
572 // FIXME: Add a flag for modules.
573 CacheCodeCompletionResults
574 = TU_options & CXTranslationUnit_CacheCompletionResults;
575 }
576
577 if (TU_options & CXTranslationUnit_DetailedPreprocessingRecord) {
578 PPOpts.DetailedRecord = true;
579 }
580
581 if (!requestedToGetTU && !CInvok->getLangOpts()->Modules)
582 PPOpts.DetailedRecord = false;
583
584 // Unless the user specified that they want the preamble on the first parse
585 // set it up to be created on the first reparse. This makes the first parse
586 // faster, trading for a slower (first) reparse.
587 unsigned PrecompilePreambleAfterNParses =
588 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
589 DiagnosticErrorTrap DiagTrap(*Diags);
590 bool Success = ASTUnit::LoadFromCompilerInvocationAction(
591 std::move(CInvok), CXXIdx->getPCHContainerOperations(), Diags,
592 IndexAction.get(), UPtr, Persistent, CXXIdx->getClangResourcesPath(),
593 OnlyLocalDecls, CaptureDiagnostics, PrecompilePreambleAfterNParses,
594 CacheCodeCompletionResults,
595 /*IncludeBriefCommentsInCodeCompletion=*/false,
596 /*UserFilesAreVolatile=*/true);
597 if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())
598 printDiagsToStderr(UPtr);
599
600 if (isASTReadError(UPtr))
601 return CXError_ASTReadError;
602
603 if (!Success)
604 return CXError_Failure;
605
606 if (out_TU)
607 *out_TU = CXTU->takeTU();
608
609 return CXError_Success;
610}
611
612//===----------------------------------------------------------------------===//
613// clang_indexTranslationUnit Implementation
614//===----------------------------------------------------------------------===//
615
616static void indexPreprocessingRecord(ASTUnit &Unit, CXIndexDataConsumer &IdxCtx) {
617 Preprocessor &PP = Unit.getPreprocessor();
618 if (!PP.getPreprocessingRecord())
619 return;
620
621 // FIXME: Only deserialize inclusion directives.
622
623 bool isModuleFile = Unit.isModuleFile();
624 for (PreprocessedEntity *PPE : Unit.getLocalPreprocessingEntities()) {
625 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
626 SourceLocation Loc = ID->getSourceRange().getBegin();
627 // Modules have synthetic main files as input, give an invalid location
628 // if the location points to such a file.
629 if (isModuleFile && Unit.isInMainFileID(Loc))
630 Loc = SourceLocation();
631 IdxCtx.ppIncludedFile(Loc, ID->getFileName(),
632 ID->getFile(),
633 ID->getKind() == InclusionDirective::Import,
634 !ID->wasInQuotes(), ID->importedModule());
635 }
636 }
637}
638
639static CXErrorCode clang_indexTranslationUnit_Impl(
640 CXIndexAction idxAction, CXClientData client_data,
641 IndexerCallbacks *client_index_callbacks, unsigned index_callbacks_size,
642 unsigned index_options, CXTranslationUnit TU) {
643 // Check arguments.
644 if (isNotUsableTU(TU)) {
645 LOG_BAD_TU(TU)do { if (clang::cxindex::LogRef Log = clang::cxindex::Logger::
make(__func__)) { *Log << "called with a bad TU: " <<
TU; } } while(false)
;
646 return CXError_InvalidArguments;
647 }
648 if (!client_index_callbacks || index_callbacks_size == 0) {
649 return CXError_InvalidArguments;
650 }
651
652 CIndexer *CXXIdx = TU->CIdx;
653 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
654 setThreadBackgroundPriority();
655
656 IndexerCallbacks CB;
657 memset(&CB, 0, sizeof(CB));
658 unsigned ClientCBSize = index_callbacks_size < sizeof(CB)
659 ? index_callbacks_size : sizeof(CB);
660 memcpy(&CB, client_index_callbacks, ClientCBSize);
661
662 auto DataConsumer = std::make_shared<CXIndexDataConsumer>(client_data, CB,
663 index_options, TU);
664
665 ASTUnit *Unit = cxtu::getASTUnit(TU);
666 if (!Unit)
667 return CXError_Failure;
668
669 ASTUnit::ConcurrencyCheck Check(*Unit);
670
671 if (const FileEntry *PCHFile = Unit->getPCHFile())
672 DataConsumer->importedPCH(PCHFile);
673
674 FileManager &FileMgr = Unit->getFileManager();
675
676 if (Unit->getOriginalSourceFileName().empty())
677 DataConsumer->enteredMainFile(nullptr);
678 else
679 DataConsumer->enteredMainFile(FileMgr.getFile(Unit->getOriginalSourceFileName()));
680
681 DataConsumer->setASTContext(Unit->getASTContext());
682 DataConsumer->startedTranslationUnit();
683
684 indexPreprocessingRecord(*Unit, *DataConsumer);
685 indexASTUnit(*Unit, DataConsumer, getIndexingOptionsFromCXOptions(index_options));
686 DataConsumer->indexDiagnostics();
687
688 return CXError_Success;
689}
690
691//===----------------------------------------------------------------------===//
692// libclang public APIs.
693//===----------------------------------------------------------------------===//
694
695int clang_index_isEntityObjCContainerKind(CXIdxEntityKind K) {
696 return CXIdxEntity_ObjCClass <= K && K <= CXIdxEntity_ObjCCategory;
697}
698
699const CXIdxObjCContainerDeclInfo *
700clang_index_getObjCContainerDeclInfo(const CXIdxDeclInfo *DInfo) {
701 if (!DInfo)
702 return nullptr;
703
704 const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
705 if (const ObjCContainerDeclInfo *
706 ContInfo = dyn_cast<ObjCContainerDeclInfo>(DI))
707 return &ContInfo->ObjCContDeclInfo;
708
709 return nullptr;
710}
711
712const CXIdxObjCInterfaceDeclInfo *
713clang_index_getObjCInterfaceDeclInfo(const CXIdxDeclInfo *DInfo) {
714 if (!DInfo)
715 return nullptr;
716
717 const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
718 if (const ObjCInterfaceDeclInfo *
719 InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI))
720 return &InterInfo->ObjCInterDeclInfo;
721
722 return nullptr;
723}
724
725const CXIdxObjCCategoryDeclInfo *
726clang_index_getObjCCategoryDeclInfo(const CXIdxDeclInfo *DInfo){
727 if (!DInfo)
728 return nullptr;
729
730 const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
731 if (const ObjCCategoryDeclInfo *
732 CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
733 return &CatInfo->ObjCCatDeclInfo;
734
735 return nullptr;
736}
737
738const CXIdxObjCProtocolRefListInfo *
739clang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *DInfo) {
740 if (!DInfo)
741 return nullptr;
742
743 const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
744
745 if (const ObjCInterfaceDeclInfo *
746 InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI))
747 return InterInfo->ObjCInterDeclInfo.protocols;
748
749 if (const ObjCProtocolDeclInfo *
750 ProtInfo = dyn_cast<ObjCProtocolDeclInfo>(DI))
751 return &ProtInfo->ObjCProtoRefListInfo;
752
753 if (const ObjCCategoryDeclInfo *CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
754 return CatInfo->ObjCCatDeclInfo.protocols;
755
756 return nullptr;
757}
758
759const CXIdxObjCPropertyDeclInfo *
760clang_index_getObjCPropertyDeclInfo(const CXIdxDeclInfo *DInfo) {
761 if (!DInfo)
762 return nullptr;
763
764 const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
765 if (const ObjCPropertyDeclInfo *PropInfo = dyn_cast<ObjCPropertyDeclInfo>(DI))
766 return &PropInfo->ObjCPropDeclInfo;
767
768 return nullptr;
769}
770
771const CXIdxIBOutletCollectionAttrInfo *
772clang_index_getIBOutletCollectionAttrInfo(const CXIdxAttrInfo *AInfo) {
773 if (!AInfo)
774 return nullptr;
775
776 const AttrInfo *DI = static_cast<const AttrInfo *>(AInfo);
777 if (const IBOutletCollectionInfo *
778 IBInfo = dyn_cast<IBOutletCollectionInfo>(DI))
779 return &IBInfo->IBCollInfo;
780
781 return nullptr;
782}
783
784const CXIdxCXXClassDeclInfo *
785clang_index_getCXXClassDeclInfo(const CXIdxDeclInfo *DInfo) {
786 if (!DInfo)
787 return nullptr;
788
789 const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
790 if (const CXXClassDeclInfo *ClassInfo = dyn_cast<CXXClassDeclInfo>(DI))
791 return &ClassInfo->CXXClassInfo;
792
793 return nullptr;
794}
795
796CXIdxClientContainer
797clang_index_getClientContainer(const CXIdxContainerInfo *info) {
798 if (!info)
799 return nullptr;
800 const ContainerInfo *Container = static_cast<const ContainerInfo *>(info);
801 return Container->IndexCtx->getClientContainerForDC(Container->DC);
802}
803
804void clang_index_setClientContainer(const CXIdxContainerInfo *info,
805 CXIdxClientContainer client) {
806 if (!info)
807 return;
808 const ContainerInfo *Container = static_cast<const ContainerInfo *>(info);
809 Container->IndexCtx->addContainerInMap(Container->DC, client);
810}
811
812CXIdxClientEntity clang_index_getClientEntity(const CXIdxEntityInfo *info) {
813 if (!info)
814 return nullptr;
815 const EntityInfo *Entity = static_cast<const EntityInfo *>(info);
816 return Entity->IndexCtx->getClientEntity(Entity->Dcl);
817}
818
819void clang_index_setClientEntity(const CXIdxEntityInfo *info,
820 CXIdxClientEntity client) {
821 if (!info)
822 return;
823 const EntityInfo *Entity = static_cast<const EntityInfo *>(info);
824 Entity->IndexCtx->setClientEntity(Entity->Dcl, client);
825}
826
827CXIndexAction clang_IndexAction_create(CXIndex CIdx) {
828 return new IndexSessionData(CIdx);
829}
830
831void clang_IndexAction_dispose(CXIndexAction idxAction) {
832 if (idxAction)
833 delete static_cast<IndexSessionData *>(idxAction);
834}
835
836int clang_indexSourceFile(CXIndexAction idxAction,
837 CXClientData client_data,
838 IndexerCallbacks *index_callbacks,
839 unsigned index_callbacks_size,
840 unsigned index_options,
841 const char *source_filename,
842 const char * const *command_line_args,
843 int num_command_line_args,
844 struct CXUnsavedFile *unsaved_files,
845 unsigned num_unsaved_files,
846 CXTranslationUnit *out_TU,
847 unsigned TU_options) {
848 SmallVector<const char *, 4> Args;
849 Args.push_back("clang");
850 Args.append(command_line_args, command_line_args + num_command_line_args);
851 return clang_indexSourceFileFullArgv(
852 idxAction, client_data, index_callbacks, index_callbacks_size,
853 index_options, source_filename, Args.data(), Args.size(), unsaved_files,
854 num_unsaved_files, out_TU, TU_options);
855}
856
857int clang_indexSourceFileFullArgv(
858 CXIndexAction idxAction, CXClientData client_data,
859 IndexerCallbacks *index_callbacks, unsigned index_callbacks_size,
860 unsigned index_options, const char *source_filename,
861 const char *const *command_line_args, int num_command_line_args,
862 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
863 CXTranslationUnit *out_TU, unsigned TU_options) {
864 LOG_FUNC_SECTIONif (clang::cxindex::LogRef Log = clang::cxindex::Logger::make
(__func__))
{
865 *Log << source_filename << ": ";
866 for (int i = 0; i != num_command_line_args; ++i)
867 *Log << command_line_args[i] << " ";
868 }
869
870 if (num_unsaved_files && !unsaved_files)
871 return CXError_InvalidArguments;
872
873 CXErrorCode result = CXError_Failure;
874 auto IndexSourceFileImpl = [=, &result]() {
875 result = clang_indexSourceFile_Impl(
876 idxAction, client_data, index_callbacks, index_callbacks_size,
877 index_options, source_filename, command_line_args,
878 num_command_line_args,
879 llvm::makeArrayRef(unsaved_files, num_unsaved_files), out_TU,
880 TU_options);
881 };
882
883 llvm::CrashRecoveryContext CRC;
884
885 if (!RunSafely(CRC, IndexSourceFileImpl)) {
886 fprintf(stderrstderr, "libclang: crash detected during indexing source file: {\n");
887 fprintf(stderrstderr, " 'source_filename' : '%s'\n", source_filename);
888 fprintf(stderrstderr, " 'command_line_args' : [");
889 for (int i = 0; i != num_command_line_args; ++i) {
890 if (i)
891 fprintf(stderrstderr, ", ");
892 fprintf(stderrstderr, "'%s'", command_line_args[i]);
893 }
894 fprintf(stderrstderr, "],\n");
895 fprintf(stderrstderr, " 'unsaved_files' : [");
896 for (unsigned i = 0; i != num_unsaved_files; ++i) {
897 if (i)
898 fprintf(stderrstderr, ", ");
899 fprintf(stderrstderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
900 unsaved_files[i].Length);
901 }
902 fprintf(stderrstderr, "],\n");
903 fprintf(stderrstderr, " 'options' : %d,\n", TU_options);
904 fprintf(stderrstderr, "}\n");
905
906 return 1;
907 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
908 if (out_TU)
909 PrintLibclangResourceUsage(*out_TU);
910 }
911
912 return result;
913}
914
915int clang_indexTranslationUnit(CXIndexAction idxAction,
916 CXClientData client_data,
917 IndexerCallbacks *index_callbacks,
918 unsigned index_callbacks_size,
919 unsigned index_options,
920 CXTranslationUnit TU) {
921 LOG_FUNC_SECTIONif (clang::cxindex::LogRef Log = clang::cxindex::Logger::make
(__func__))
{
922 *Log << TU;
923 }
924
925 CXErrorCode result;
926 auto IndexTranslationUnitImpl = [=, &result]() {
927 result = clang_indexTranslationUnit_Impl(
928 idxAction, client_data, index_callbacks, index_callbacks_size,
929 index_options, TU);
930 };
931
932 llvm::CrashRecoveryContext CRC;
933
934 if (!RunSafely(CRC, IndexTranslationUnitImpl)) {
935 fprintf(stderrstderr, "libclang: crash detected during indexing TU\n");
936
937 return 1;
938 }
939
940 return result;
941}
942
943void clang_indexLoc_getFileLocation(CXIdxLoc location,
944 CXIdxClientFile *indexFile,
945 CXFile *file,
946 unsigned *line,
947 unsigned *column,
948 unsigned *offset) {
949 if (indexFile) *indexFile = nullptr;
950 if (file) *file = nullptr;
951 if (line) *line = 0;
952 if (column) *column = 0;
953 if (offset) *offset = 0;
954
955 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
956 if (!location.ptr_data[0] || Loc.isInvalid())
957 return;
958
959 CXIndexDataConsumer &DataConsumer =
960 *static_cast<CXIndexDataConsumer*>(location.ptr_data[0]);
961 DataConsumer.translateLoc(Loc, indexFile, file, line, column, offset);
962}
963
964CXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc location) {
965 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
966 if (!location.ptr_data[0] || Loc.isInvalid())
967 return clang_getNullLocation();
968
969 CXIndexDataConsumer &DataConsumer =
970 *static_cast<CXIndexDataConsumer*>(location.ptr_data[0]);
971 return cxloc::translateSourceLocation(DataConsumer.getASTContext(), Loc);
972}
973

/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.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;
9
Memory is released
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); }
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)
7
Taking true branch
268 get_deleter()(__ptr);
8
Calling 'default_delete::operator()'
10
Returning; memory was released via 2nd parameter
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();
332 }
333
334 /// Return the stored pointer.
335 pointer
336 get() const noexcept
337 { return _M_t._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 */