1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "clang/AST/ASTContext.h" |
15 | #include "clang/AST/ASTDiagnostic.h" |
16 | #include "clang/AST/DeclCXX.h" |
17 | #include "clang/AST/DeclFriend.h" |
18 | #include "clang/AST/DeclObjC.h" |
19 | #include "clang/AST/Expr.h" |
20 | #include "clang/AST/ExprCXX.h" |
21 | #include "clang/AST/PrettyDeclStackTrace.h" |
22 | #include "clang/AST/StmtCXX.h" |
23 | #include "clang/Basic/DiagnosticOptions.h" |
24 | #include "clang/Basic/PartialDiagnostic.h" |
25 | #include "clang/Basic/TargetInfo.h" |
26 | #include "clang/Lex/HeaderSearch.h" |
27 | #include "clang/Lex/Preprocessor.h" |
28 | #include "clang/Sema/CXXFieldCollector.h" |
29 | #include "clang/Sema/DelayedDiagnostic.h" |
30 | #include "clang/Sema/ExternalSemaSource.h" |
31 | #include "clang/Sema/Initialization.h" |
32 | #include "clang/Sema/MultiplexExternalSemaSource.h" |
33 | #include "clang/Sema/ObjCMethodList.h" |
34 | #include "clang/Sema/Scope.h" |
35 | #include "clang/Sema/ScopeInfo.h" |
36 | #include "clang/Sema/SemaConsumer.h" |
37 | #include "clang/Sema/SemaInternal.h" |
38 | #include "clang/Sema/TemplateDeduction.h" |
39 | #include "clang/Sema/TemplateInstCallback.h" |
40 | #include "llvm/ADT/DenseMap.h" |
41 | #include "llvm/ADT/SmallSet.h" |
42 | using namespace clang; |
43 | using namespace sema; |
44 | |
45 | SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, unsigned Offset) { |
46 | return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts); |
47 | } |
48 | |
49 | ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); } |
50 | |
51 | PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context, |
52 | const Preprocessor &PP) { |
53 | PrintingPolicy Policy = Context.getPrintingPolicy(); |
54 | |
55 | |
56 | Policy.Bool = Context.getLangOpts().Bool; |
57 | if (!Policy.Bool) { |
58 | if (const MacroInfo *BoolMacro = PP.getMacroInfo(Context.getBoolName())) { |
59 | Policy.Bool = BoolMacro->isObjectLike() && |
60 | BoolMacro->getNumTokens() == 1 && |
61 | BoolMacro->getReplacementToken(0).is(tok::kw__Bool); |
62 | } |
63 | } |
64 | |
65 | return Policy; |
66 | } |
67 | |
68 | void Sema::ActOnTranslationUnitScope(Scope *S) { |
69 | TUScope = S; |
70 | PushDeclContext(S, Context.getTranslationUnitDecl()); |
71 | } |
72 | |
73 | namespace clang { |
74 | namespace sema { |
75 | |
76 | class SemaPPCallbacks : public PPCallbacks { |
77 | Sema *S = nullptr; |
78 | llvm::SmallVector<SourceLocation, 8> IncludeStack; |
79 | |
80 | public: |
81 | void set(Sema &S) { this->S = &S; } |
82 | |
83 | void reset() { S = nullptr; } |
84 | |
85 | virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, |
86 | SrcMgr::CharacteristicKind FileType, |
87 | FileID PrevFID) override { |
88 | if (!S) |
89 | return; |
90 | switch (Reason) { |
91 | case EnterFile: { |
92 | SourceManager &SM = S->getSourceManager(); |
93 | SourceLocation IncludeLoc = SM.getIncludeLoc(SM.getFileID(Loc)); |
94 | if (IncludeLoc.isValid()) { |
95 | IncludeStack.push_back(IncludeLoc); |
96 | S->DiagnoseNonDefaultPragmaPack( |
97 | Sema::PragmaPackDiagnoseKind::NonDefaultStateAtInclude, IncludeLoc); |
98 | } |
99 | break; |
100 | } |
101 | case ExitFile: |
102 | if (!IncludeStack.empty()) |
103 | S->DiagnoseNonDefaultPragmaPack( |
104 | Sema::PragmaPackDiagnoseKind::ChangedStateAtExit, |
105 | IncludeStack.pop_back_val()); |
106 | break; |
107 | default: |
108 | break; |
109 | } |
110 | } |
111 | }; |
112 | |
113 | } |
114 | } |
115 | |
116 | Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, |
117 | TranslationUnitKind TUKind, CodeCompleteConsumer *CodeCompleter) |
118 | : ExternalSource(nullptr), isMultiplexExternalSource(false), |
119 | FPFeatures(pp.getLangOpts()), LangOpts(pp.getLangOpts()), PP(pp), |
120 | Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()), |
121 | SourceMgr(PP.getSourceManager()), CollectStats(false), |
122 | CodeCompleter(CodeCompleter), CurContext(nullptr), |
123 | OriginalLexicalContext(nullptr), MSStructPragmaOn(false), |
124 | MSPointerToMemberRepresentationMethod( |
125 | LangOpts.getMSPointerToMemberRepresentationMethod()), |
126 | VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)), PackStack(0), |
127 | DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr), |
128 | CodeSegStack(nullptr), CurInitSeg(nullptr), VisContext(nullptr), |
129 | PragmaAttributeCurrentTargetDecl(nullptr), |
130 | IsBuildingRecoveryCallExpr(false), Cleanup{}, LateTemplateParser(nullptr), |
131 | LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp), |
132 | StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr), |
133 | StdCoroutineTraitsCache(nullptr), CXXTypeInfoDecl(nullptr), |
134 | MSVCGuidDecl(nullptr), NSNumberDecl(nullptr), NSValueDecl(nullptr), |
135 | NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr), |
136 | ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr), |
137 | ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr), |
138 | DictionaryWithObjectsMethod(nullptr), GlobalNewDeleteDeclared(false), |
139 | TUKind(TUKind), NumSFINAEErrors(0), |
140 | FullyCheckedComparisonCategories( |
141 | static_cast<unsigned>(ComparisonCategoryType::Last) + 1), |
142 | AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false), |
143 | NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1), |
144 | CurrentInstantiationScope(nullptr), DisableTypoCorrection(false), |
145 | TyposCorrected(0), AnalysisWarnings(*this), |
146 | ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr), |
147 | CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr) { |
148 | TUScope = nullptr; |
149 | |
150 | LoadedExternalKnownNamespaces = false; |
151 | for (unsigned I = 0; I != NSAPI::NumNSNumberLiteralMethods; ++I) |
152 | NSNumberLiteralMethods[I] = nullptr; |
153 | |
154 | if (getLangOpts().ObjC) |
155 | NSAPIObj.reset(new NSAPI(Context)); |
156 | |
157 | if (getLangOpts().CPlusPlus) |
158 | FieldCollector.reset(new CXXFieldCollector()); |
159 | |
160 | |
161 | Diags.SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context); |
162 | |
163 | ExprEvalContexts.emplace_back( |
164 | ExpressionEvaluationContext::PotentiallyEvaluated, 0, CleanupInfo{}, |
165 | nullptr, ExpressionEvaluationContextRecord::EK_Other); |
166 | |
167 | PreallocatedFunctionScope.reset(new FunctionScopeInfo(Diags)); |
168 | |
169 | |
170 | InitDataSharingAttributesStack(); |
171 | |
172 | std::unique_ptr<sema::SemaPPCallbacks> Callbacks = |
173 | llvm::make_unique<sema::SemaPPCallbacks>(); |
174 | SemaPPCallbackHandler = Callbacks.get(); |
175 | PP.addPPCallbacks(std::move(Callbacks)); |
176 | SemaPPCallbackHandler->set(*this); |
177 | } |
178 | |
179 | void Sema::addImplicitTypedef(StringRef Name, QualType T) { |
180 | DeclarationName DN = &Context.Idents.get(Name); |
181 | if (IdResolver.begin(DN) == IdResolver.end()) |
182 | PushOnScopeChains(Context.buildImplicitTypedef(T, Name), TUScope); |
183 | } |
184 | |
185 | void Sema::Initialize() { |
186 | if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer)) |
187 | SC->InitializeSema(*this); |
188 | |
189 | |
190 | if (ExternalSemaSource *ExternalSema |
191 | = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource())) |
192 | ExternalSema->InitializeSema(*this); |
193 | |
194 | |
195 | |
196 | VAListTagName = PP.getIdentifierInfo("__va_list_tag"); |
197 | |
198 | if (!TUScope) |
199 | return; |
200 | |
201 | |
202 | if (Context.getTargetInfo().hasInt128Type()) { |
203 | |
204 | |
205 | DeclarationName Int128 = &Context.Idents.get("__int128_t"); |
206 | if (IdResolver.begin(Int128) == IdResolver.end()) |
207 | PushOnScopeChains(Context.getInt128Decl(), TUScope); |
208 | |
209 | DeclarationName UInt128 = &Context.Idents.get("__uint128_t"); |
210 | if (IdResolver.begin(UInt128) == IdResolver.end()) |
211 | PushOnScopeChains(Context.getUInt128Decl(), TUScope); |
212 | } |
213 | |
214 | |
215 | |
216 | if (getLangOpts().ObjC) { |
217 | |
218 | |
219 | DeclarationName SEL = &Context.Idents.get("SEL"); |
220 | if (IdResolver.begin(SEL) == IdResolver.end()) |
221 | PushOnScopeChains(Context.getObjCSelDecl(), TUScope); |
222 | |
223 | |
224 | |
225 | DeclarationName Id = &Context.Idents.get("id"); |
226 | if (IdResolver.begin(Id) == IdResolver.end()) |
227 | PushOnScopeChains(Context.getObjCIdDecl(), TUScope); |
228 | |
229 | |
230 | DeclarationName Class = &Context.Idents.get("Class"); |
231 | if (IdResolver.begin(Class) == IdResolver.end()) |
232 | PushOnScopeChains(Context.getObjCClassDecl(), TUScope); |
233 | |
234 | |
235 | DeclarationName Protocol = &Context.Idents.get("Protocol"); |
236 | if (IdResolver.begin(Protocol) == IdResolver.end()) |
237 | PushOnScopeChains(Context.getObjCProtocolDecl(), TUScope); |
238 | } |
239 | |
240 | |
241 | DeclarationName ConstantString = &Context.Idents.get("__NSConstantString"); |
242 | if (IdResolver.begin(ConstantString) == IdResolver.end()) |
243 | PushOnScopeChains(Context.getCFConstantStringDecl(), TUScope); |
244 | |
245 | |
246 | if (getLangOpts().MSVCCompat) { |
247 | if (getLangOpts().CPlusPlus && |
248 | IdResolver.begin(&Context.Idents.get("type_info")) == IdResolver.end()) |
249 | PushOnScopeChains(Context.buildImplicitRecord("type_info", TTK_Class), |
250 | TUScope); |
251 | |
252 | addImplicitTypedef("size_t", Context.getSizeType()); |
253 | } |
254 | |
255 | |
256 | |
257 | if (getLangOpts().OpenCL) { |
258 | getOpenCLOptions().addSupport( |
259 | Context.getTargetInfo().getSupportedOpenCLOpts()); |
260 | getOpenCLOptions().enableSupportedCore(getLangOpts()); |
261 | addImplicitTypedef("sampler_t", Context.OCLSamplerTy); |
262 | addImplicitTypedef("event_t", Context.OCLEventTy); |
263 | if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) { |
264 | addImplicitTypedef("clk_event_t", Context.OCLClkEventTy); |
265 | addImplicitTypedef("queue_t", Context.OCLQueueTy); |
266 | addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy); |
267 | addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy)); |
268 | addImplicitTypedef("atomic_uint", |
269 | Context.getAtomicType(Context.UnsignedIntTy)); |
270 | auto AtomicLongT = Context.getAtomicType(Context.LongTy); |
271 | addImplicitTypedef("atomic_long", AtomicLongT); |
272 | auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy); |
273 | addImplicitTypedef("atomic_ulong", AtomicULongT); |
274 | addImplicitTypedef("atomic_float", |
275 | Context.getAtomicType(Context.FloatTy)); |
276 | auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy); |
277 | addImplicitTypedef("atomic_double", AtomicDoubleT); |
278 | |
279 | |
280 | addImplicitTypedef("atomic_flag", Context.getAtomicType(Context.IntTy)); |
281 | auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType()); |
282 | addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT); |
283 | auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType()); |
284 | addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT); |
285 | auto AtomicSizeT = Context.getAtomicType(Context.getSizeType()); |
286 | addImplicitTypedef("atomic_size_t", AtomicSizeT); |
287 | auto AtomicPtrDiffT = Context.getAtomicType(Context.getPointerDiffType()); |
288 | addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT); |
289 | |
290 | |
291 | |
292 | |
293 | |
294 | |
295 | |
296 | |
297 | |
298 | |
299 | |
300 | |
301 | std::vector<QualType> Atomic64BitTypes; |
302 | Atomic64BitTypes.push_back(AtomicLongT); |
303 | Atomic64BitTypes.push_back(AtomicULongT); |
304 | Atomic64BitTypes.push_back(AtomicDoubleT); |
305 | if (Context.getTypeSize(AtomicSizeT) == 64) { |
306 | Atomic64BitTypes.push_back(AtomicSizeT); |
307 | Atomic64BitTypes.push_back(AtomicIntPtrT); |
308 | Atomic64BitTypes.push_back(AtomicUIntPtrT); |
309 | Atomic64BitTypes.push_back(AtomicPtrDiffT); |
310 | } |
311 | for (auto &I : Atomic64BitTypes) |
312 | setOpenCLExtensionForType(I, |
313 | "cl_khr_int64_base_atomics cl_khr_int64_extended_atomics"); |
314 | |
315 | setOpenCLExtensionForType(AtomicDoubleT, "cl_khr_fp64"); |
316 | } |
317 | |
318 | setOpenCLExtensionForType(Context.DoubleTy, "cl_khr_fp64"); |
319 | |
320 | #define GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) \ |
321 | setOpenCLExtensionForType(Context.Id, Ext); |
322 | #include "clang/Basic/OpenCLImageTypes.def" |
323 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ |
324 | addImplicitTypedef(#ExtType, Context.Id##Ty); \ |
325 | setOpenCLExtensionForType(Context.Id##Ty, #Ext); |
326 | #include "clang/Basic/OpenCLExtensionTypes.def" |
327 | }; |
328 | |
329 | if (Context.getTargetInfo().hasBuiltinMSVaList()) { |
330 | DeclarationName MSVaList = &Context.Idents.get("__builtin_ms_va_list"); |
331 | if (IdResolver.begin(MSVaList) == IdResolver.end()) |
332 | PushOnScopeChains(Context.getBuiltinMSVaListDecl(), TUScope); |
333 | } |
334 | |
335 | DeclarationName BuiltinVaList = &Context.Idents.get("__builtin_va_list"); |
336 | if (IdResolver.begin(BuiltinVaList) == IdResolver.end()) |
337 | PushOnScopeChains(Context.getBuiltinVaListDecl(), TUScope); |
338 | } |
339 | |
340 | Sema::~Sema() { |
341 | if (VisContext) FreeVisContext(); |
342 | |
343 | |
344 | for (sema::FunctionScopeInfo *FSI : FunctionScopes) |
345 | if (FSI != PreallocatedFunctionScope.get()) |
346 | delete FSI; |
347 | |
348 | |
349 | if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer)) |
350 | SC->ForgetSema(); |
351 | |
352 | |
353 | if (ExternalSemaSource *ExternalSema |
354 | = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource())) |
355 | ExternalSema->ForgetSema(); |
356 | |
357 | |
358 | if (isMultiplexExternalSource) |
359 | delete ExternalSource; |
360 | |
361 | threadSafety::threadSafetyCleanup(ThreadSafetyDeclCache); |
362 | |
363 | |
364 | DestroyDataSharingAttributesStack(); |
365 | |
366 | |
367 | |
368 | SemaPPCallbackHandler->reset(); |
369 | |
370 | (0) . __assert_fail ("DelayedTypos.empty() && \"Uncorrected typos!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 370, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DelayedTypos.empty() && "Uncorrected typos!"); |
371 | } |
372 | |
373 | |
374 | |
375 | |
376 | |
377 | bool Sema::(SourceLocation loc, |
378 | UnavailableAttr::ImplicitReason reason) { |
379 | |
380 | FunctionDecl *fn = dyn_cast<FunctionDecl>(CurContext); |
381 | if (!fn) return false; |
382 | |
383 | |
384 | if (inTemplateInstantiation()) |
385 | return false; |
386 | |
387 | |
388 | if (!Context.getSourceManager().isInSystemHeader(loc)) |
389 | return false; |
390 | |
391 | |
392 | if (fn->hasAttr<UnavailableAttr>()) return true; |
393 | |
394 | fn->addAttr(UnavailableAttr::CreateImplicit(Context, "", reason, loc)); |
395 | return true; |
396 | } |
397 | |
398 | ASTMutationListener *Sema::getASTMutationListener() const { |
399 | return getASTConsumer().GetASTMutationListener(); |
400 | } |
401 | |
402 | |
403 | |
404 | |
405 | |
406 | |
407 | void Sema::addExternalSource(ExternalSemaSource *E) { |
408 | (0) . __assert_fail ("E && \"Cannot use with NULL ptr\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 408, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(E && "Cannot use with NULL ptr"); |
409 | |
410 | if (!ExternalSource) { |
411 | ExternalSource = E; |
412 | return; |
413 | } |
414 | |
415 | if (isMultiplexExternalSource) |
416 | static_cast<MultiplexExternalSemaSource*>(ExternalSource)->addSource(*E); |
417 | else { |
418 | ExternalSource = new MultiplexExternalSemaSource(*ExternalSource, *E); |
419 | isMultiplexExternalSource = true; |
420 | } |
421 | } |
422 | |
423 | |
424 | void Sema::PrintStats() const { |
425 | llvm::errs() << "\n*** Semantic Analysis Stats:\n"; |
426 | llvm::errs() << NumSFINAEErrors << " SFINAE diagnostics trapped.\n"; |
427 | |
428 | BumpAlloc.PrintStats(); |
429 | AnalysisWarnings.PrintStats(); |
430 | } |
431 | |
432 | void Sema::diagnoseNullableToNonnullConversion(QualType DstType, |
433 | QualType SrcType, |
434 | SourceLocation Loc) { |
435 | Optional<NullabilityKind> ExprNullability = SrcType->getNullability(Context); |
436 | if (!ExprNullability || *ExprNullability != NullabilityKind::Nullable) |
437 | return; |
438 | |
439 | Optional<NullabilityKind> TypeNullability = DstType->getNullability(Context); |
440 | if (!TypeNullability || *TypeNullability != NullabilityKind::NonNull) |
441 | return; |
442 | |
443 | Diag(Loc, diag::warn_nullability_lost) << SrcType << DstType; |
444 | } |
445 | |
446 | void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr* E) { |
447 | if (Diags.isIgnored(diag::warn_zero_as_null_pointer_constant, |
448 | E->getBeginLoc())) |
449 | return; |
450 | |
451 | if (!getLangOpts().CPlusPlus11) |
452 | return; |
453 | |
454 | if (Kind != CK_NullToPointer && Kind != CK_NullToMemberPointer) |
455 | return; |
456 | if (E->IgnoreParenImpCasts()->getType()->isNullPtrType()) |
457 | return; |
458 | |
459 | |
460 | |
461 | SourceLocation MaybeMacroLoc = E->getBeginLoc(); |
462 | if (Diags.getSuppressSystemWarnings() && |
463 | SourceMgr.isInSystemMacro(MaybeMacroLoc) && |
464 | !findMacroSpelling(MaybeMacroLoc, "NULL")) |
465 | return; |
466 | |
467 | Diag(E->getBeginLoc(), diag::warn_zero_as_null_pointer_constant) |
468 | << FixItHint::CreateReplacement(E->getSourceRange(), "nullptr"); |
469 | } |
470 | |
471 | |
472 | |
473 | |
474 | ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty, |
475 | CastKind Kind, ExprValueKind VK, |
476 | const CXXCastPath *BasePath, |
477 | CheckedConversionKind CCK) { |
478 | #ifndef NDEBUG |
479 | if (VK == VK_RValue && !E->isRValue()) { |
480 | switch (Kind) { |
481 | default: |
482 | llvm_unreachable("can't implicitly cast lvalue to rvalue with this cast " |
483 | "kind"); |
484 | case CK_LValueToRValue: |
485 | case CK_ArrayToPointerDecay: |
486 | case CK_FunctionToPointerDecay: |
487 | case CK_ToVoid: |
488 | case CK_NonAtomicToAtomic: |
489 | break; |
490 | } |
491 | } |
492 | (0) . __assert_fail ("(VK == VK_RValue || !E->isRValue()) && \"can't cast rvalue to lvalue\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 492, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((VK == VK_RValue || !E->isRValue()) && "can't cast rvalue to lvalue"); |
493 | #endif |
494 | |
495 | diagnoseNullableToNonnullConversion(Ty, E->getType(), E->getBeginLoc()); |
496 | diagnoseZeroToNullptrConversion(Kind, E); |
497 | |
498 | QualType ExprTy = Context.getCanonicalType(E->getType()); |
499 | QualType TypeTy = Context.getCanonicalType(Ty); |
500 | |
501 | if (ExprTy == TypeTy) |
502 | return E; |
503 | |
504 | |
505 | |
506 | if (Kind == CK_ArrayToPointerDecay && getLangOpts().CPlusPlus && |
507 | E->getValueKind() == VK_RValue) { |
508 | |
509 | ExprResult Materialized = CreateMaterializeTemporaryExpr( |
510 | E->getType(), E, !getLangOpts().CPlusPlus11); |
511 | if (Materialized.isInvalid()) |
512 | return ExprError(); |
513 | E = Materialized.get(); |
514 | } |
515 | |
516 | if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) { |
517 | if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) { |
518 | ImpCast->setType(Ty); |
519 | ImpCast->setValueKind(VK); |
520 | return E; |
521 | } |
522 | } |
523 | |
524 | return ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK); |
525 | } |
526 | |
527 | |
528 | |
529 | CastKind Sema::ScalarTypeToBooleanCastKind(QualType ScalarTy) { |
530 | switch (ScalarTy->getScalarTypeKind()) { |
531 | case Type::STK_Bool: return CK_NoOp; |
532 | case Type::STK_CPointer: return CK_PointerToBoolean; |
533 | case Type::STK_BlockPointer: return CK_PointerToBoolean; |
534 | case Type::STK_ObjCObjectPointer: return CK_PointerToBoolean; |
535 | case Type::STK_MemberPointer: return CK_MemberPointerToBoolean; |
536 | case Type::STK_Integral: return CK_IntegralToBoolean; |
537 | case Type::STK_Floating: return CK_FloatingToBoolean; |
538 | case Type::STK_IntegralComplex: return CK_IntegralComplexToBoolean; |
539 | case Type::STK_FloatingComplex: return CK_FloatingComplexToBoolean; |
540 | case Type::STK_FixedPoint: return CK_FixedPointToBoolean; |
541 | } |
542 | llvm_unreachable("unknown scalar type kind"); |
543 | } |
544 | |
545 | |
546 | static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) { |
547 | if (D->getMostRecentDecl()->isUsed()) |
548 | return true; |
549 | |
550 | if (D->isExternallyVisible()) |
551 | return true; |
552 | |
553 | if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { |
554 | |
555 | |
556 | if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate()) |
557 | for (const auto *Spec : Template->specializations()) |
558 | if (ShouldRemoveFromUnused(SemaRef, Spec)) |
559 | return true; |
560 | |
561 | |
562 | |
563 | const FunctionDecl *DeclToCheck; |
564 | if (FD->hasBody(DeclToCheck)) |
565 | return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck); |
566 | |
567 | |
568 | |
569 | DeclToCheck = FD->getMostRecentDecl(); |
570 | if (DeclToCheck != FD) |
571 | return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck); |
572 | } |
573 | |
574 | if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { |
575 | |
576 | |
577 | |
578 | |
579 | |
580 | if (VD->isReferenced() && |
581 | VD->isUsableInConstantExpressions(SemaRef->Context)) |
582 | return true; |
583 | |
584 | if (VarTemplateDecl *Template = VD->getDescribedVarTemplate()) |
585 | |
586 | |
587 | for (const auto *Spec : Template->specializations()) |
588 | if (ShouldRemoveFromUnused(SemaRef, Spec)) |
589 | return true; |
590 | |
591 | |
592 | |
593 | const VarDecl *DeclToCheck = VD->getDefinition(); |
594 | if (DeclToCheck) |
595 | return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck); |
596 | |
597 | |
598 | |
599 | DeclToCheck = VD->getMostRecentDecl(); |
600 | if (DeclToCheck != VD) |
601 | return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck); |
602 | } |
603 | |
604 | return false; |
605 | } |
606 | |
607 | static bool isFunctionOrVarDeclExternC(NamedDecl *ND) { |
608 | if (auto *FD = dyn_cast<FunctionDecl>(ND)) |
609 | return FD->isExternC(); |
610 | return cast<VarDecl>(ND)->isExternC(); |
611 | } |
612 | |
613 | |
614 | |
615 | bool Sema::isExternalWithNoLinkageType(ValueDecl *VD) { |
616 | |
617 | |
618 | |
619 | return getLangOpts().CPlusPlus && VD->hasExternalFormalLinkage() && |
620 | !isExternalFormalLinkage(VD->getType()->getLinkage()) && |
621 | !isFunctionOrVarDeclExternC(VD); |
622 | } |
623 | |
624 | |
625 | |
626 | void Sema::getUndefinedButUsed( |
627 | SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined) { |
628 | for (const auto &UndefinedUse : UndefinedButUsed) { |
629 | NamedDecl *ND = UndefinedUse.first; |
630 | |
631 | |
632 | if (ND->isInvalidDecl()) continue; |
633 | |
634 | |
635 | if (ND->hasAttr<WeakRefAttr>()) continue; |
636 | |
637 | if (isa<CXXDeductionGuideDecl>(ND)) |
638 | continue; |
639 | |
640 | if (ND->hasAttr<DLLImportAttr>() || ND->hasAttr<DLLExportAttr>()) { |
641 | |
642 | |
643 | |
644 | continue; |
645 | } |
646 | |
647 | if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { |
648 | if (FD->isDefined()) |
649 | continue; |
650 | if (FD->isExternallyVisible() && |
651 | !isExternalWithNoLinkageType(FD) && |
652 | !FD->getMostRecentDecl()->isInlined() && |
653 | !FD->hasAttr<ExcludeFromExplicitInstantiationAttr>()) |
654 | continue; |
655 | if (FD->getBuiltinID()) |
656 | continue; |
657 | } else { |
658 | auto *VD = cast<VarDecl>(ND); |
659 | if (VD->hasDefinition() != VarDecl::DeclarationOnly) |
660 | continue; |
661 | if (VD->isExternallyVisible() && |
662 | !isExternalWithNoLinkageType(VD) && |
663 | !VD->getMostRecentDecl()->isInline() && |
664 | !VD->hasAttr<ExcludeFromExplicitInstantiationAttr>()) |
665 | continue; |
666 | |
667 | |
668 | |
669 | if (VD->isKnownToBeDefined()) |
670 | continue; |
671 | } |
672 | |
673 | Undefined.push_back(std::make_pair(ND, UndefinedUse.second)); |
674 | } |
675 | } |
676 | |
677 | |
678 | |
679 | static void checkUndefinedButUsed(Sema &S) { |
680 | if (S.UndefinedButUsed.empty()) return; |
681 | |
682 | |
683 | SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined; |
684 | S.getUndefinedButUsed(Undefined); |
685 | if (Undefined.empty()) return; |
686 | |
687 | for (auto Undef : Undefined) { |
688 | ValueDecl *VD = cast<ValueDecl>(Undef.first); |
689 | SourceLocation UseLoc = Undef.second; |
690 | |
691 | if (S.isExternalWithNoLinkageType(VD)) { |
692 | |
693 | |
694 | |
695 | |
696 | |
697 | |
698 | |
699 | |
700 | |
701 | S.Diag(VD->getLocation(), isExternallyVisible(VD->getType()->getLinkage()) |
702 | ? diag::ext_undefined_internal_type |
703 | : diag::err_undefined_internal_type) |
704 | << isa<VarDecl>(VD) << VD; |
705 | } else if (!VD->isExternallyVisible()) { |
706 | |
707 | |
708 | |
709 | S.Diag(VD->getLocation(), diag::warn_undefined_internal) |
710 | << isa<VarDecl>(VD) << VD; |
711 | } else if (auto *FD = dyn_cast<FunctionDecl>(VD)) { |
712 | (void)FD; |
713 | (0) . __assert_fail ("FD->getMostRecentDecl()->isInlined() && \"used object requires definition but isn't inline or internal?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 714, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(FD->getMostRecentDecl()->isInlined() && |
714 | (0) . __assert_fail ("FD->getMostRecentDecl()->isInlined() && \"used object requires definition but isn't inline or internal?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 714, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "used object requires definition but isn't inline or internal?"); |
715 | |
716 | S.Diag(VD->getLocation(), diag::warn_undefined_inline) << VD; |
717 | } else { |
718 | (0) . __assert_fail ("cast(VD)->getMostRecentDecl()->isInline() && \"used var requires definition but isn't inline or internal?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 719, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(cast<VarDecl>(VD)->getMostRecentDecl()->isInline() && |
719 | (0) . __assert_fail ("cast(VD)->getMostRecentDecl()->isInline() && \"used var requires definition but isn't inline or internal?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 719, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "used var requires definition but isn't inline or internal?"); |
720 | S.Diag(VD->getLocation(), diag::err_undefined_inline_var) << VD; |
721 | } |
722 | if (UseLoc.isValid()) |
723 | S.Diag(UseLoc, diag::note_used_here); |
724 | } |
725 | |
726 | S.UndefinedButUsed.clear(); |
727 | } |
728 | |
729 | void Sema::LoadExternalWeakUndeclaredIdentifiers() { |
730 | if (!ExternalSource) |
731 | return; |
732 | |
733 | SmallVector<std::pair<IdentifierInfo *, WeakInfo>, 4> WeakIDs; |
734 | ExternalSource->ReadWeakUndeclaredIdentifiers(WeakIDs); |
735 | for (auto &WeakID : WeakIDs) |
736 | WeakUndeclaredIdentifiers.insert(WeakID); |
737 | } |
738 | |
739 | |
740 | typedef llvm::DenseMap<const CXXRecordDecl*, bool> RecordCompleteMap; |
741 | |
742 | |
743 | |
744 | |
745 | |
746 | |
747 | static bool MethodsAndNestedClassesComplete(const CXXRecordDecl *RD, |
748 | RecordCompleteMap &MNCComplete) { |
749 | RecordCompleteMap::iterator Cache = MNCComplete.find(RD); |
750 | if (Cache != MNCComplete.end()) |
751 | return Cache->second; |
752 | if (!RD->isCompleteDefinition()) |
753 | return false; |
754 | bool Complete = true; |
755 | for (DeclContext::decl_iterator I = RD->decls_begin(), |
756 | E = RD->decls_end(); |
757 | I != E && Complete; ++I) { |
758 | if (const CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(*I)) |
759 | Complete = M->isDefined() || M->isDefaulted() || |
760 | (M->isPure() && !isa<CXXDestructorDecl>(M)); |
761 | else if (const FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(*I)) |
762 | |
763 | |
764 | |
765 | |
766 | Complete = !F->getTemplatedDecl()->isLateTemplateParsed() && |
767 | F->getTemplatedDecl()->isDefined(); |
768 | else if (const CXXRecordDecl *R = dyn_cast<CXXRecordDecl>(*I)) { |
769 | if (R->isInjectedClassName()) |
770 | continue; |
771 | if (R->hasDefinition()) |
772 | Complete = MethodsAndNestedClassesComplete(R->getDefinition(), |
773 | MNCComplete); |
774 | else |
775 | Complete = false; |
776 | } |
777 | } |
778 | MNCComplete[RD] = Complete; |
779 | return Complete; |
780 | } |
781 | |
782 | |
783 | |
784 | |
785 | |
786 | |
787 | |
788 | |
789 | static bool IsRecordFullyDefined(const CXXRecordDecl *RD, |
790 | RecordCompleteMap &RecordsComplete, |
791 | RecordCompleteMap &MNCComplete) { |
792 | RecordCompleteMap::iterator Cache = RecordsComplete.find(RD); |
793 | if (Cache != RecordsComplete.end()) |
794 | return Cache->second; |
795 | bool Complete = MethodsAndNestedClassesComplete(RD, MNCComplete); |
796 | for (CXXRecordDecl::friend_iterator I = RD->friend_begin(), |
797 | E = RD->friend_end(); |
798 | I != E && Complete; ++I) { |
799 | |
800 | if (TypeSourceInfo *TSI = (*I)->getFriendType()) { |
801 | |
802 | if (CXXRecordDecl *FriendD = TSI->getType()->getAsCXXRecordDecl()) |
803 | Complete = MethodsAndNestedClassesComplete(FriendD, MNCComplete); |
804 | else |
805 | Complete = false; |
806 | } else { |
807 | |
808 | if (const FunctionDecl *FD = |
809 | dyn_cast<FunctionDecl>((*I)->getFriendDecl())) |
810 | Complete = FD->isDefined(); |
811 | else |
812 | |
813 | Complete = false; |
814 | } |
815 | } |
816 | RecordsComplete[RD] = Complete; |
817 | return Complete; |
818 | } |
819 | |
820 | void Sema::emitAndClearUnusedLocalTypedefWarnings() { |
821 | if (ExternalSource) |
822 | ExternalSource->ReadUnusedLocalTypedefNameCandidates( |
823 | UnusedLocalTypedefNameCandidates); |
824 | for (const TypedefNameDecl *TD : UnusedLocalTypedefNameCandidates) { |
825 | if (TD->isReferenced()) |
826 | continue; |
827 | Diag(TD->getLocation(), diag::warn_unused_local_typedef) |
828 | << isa<TypeAliasDecl>(TD) << TD->getDeclName(); |
829 | } |
830 | UnusedLocalTypedefNameCandidates.clear(); |
831 | } |
832 | |
833 | |
834 | |
835 | |
836 | void Sema::ActOnStartOfTranslationUnit() { |
837 | if (getLangOpts().ModulesTS && |
838 | (getLangOpts().getCompilingModule() == LangOptions::CMK_ModuleInterface || |
839 | getLangOpts().getCompilingModule() == LangOptions::CMK_None)) { |
840 | SourceLocation StartOfTU = |
841 | SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); |
842 | |
843 | |
844 | |
845 | auto &Map = PP.getHeaderSearchInfo().getModuleMap(); |
846 | auto *GlobalModule = Map.createGlobalModuleForInterfaceUnit(StartOfTU); |
847 | (0) . __assert_fail ("GlobalModule && \"module creation should not fail\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 847, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(GlobalModule && "module creation should not fail"); |
848 | |
849 | |
850 | ModuleScopes.push_back({}); |
851 | ModuleScopes.back().Module = GlobalModule; |
852 | VisibleModules.setVisible(GlobalModule, StartOfTU); |
853 | |
854 | |
855 | auto *TU = Context.getTranslationUnitDecl(); |
856 | TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::Visible); |
857 | TU->setLocalOwningModule(GlobalModule); |
858 | } |
859 | } |
860 | |
861 | |
862 | |
863 | |
864 | void Sema::ActOnEndOfTranslationUnit() { |
865 | (0) . __assert_fail ("DelayedDiagnostics.getCurrentPool() == nullptr && \"reached end of translation unit with a pool attached?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 866, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DelayedDiagnostics.getCurrentPool() == nullptr |
866 | (0) . __assert_fail ("DelayedDiagnostics.getCurrentPool() == nullptr && \"reached end of translation unit with a pool attached?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 866, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> && "reached end of translation unit with a pool attached?"); |
867 | |
868 | |
869 | |
870 | if (PP.isCodeCompletionEnabled()) |
871 | return; |
872 | |
873 | |
874 | |
875 | |
876 | |
877 | |
878 | |
879 | |
880 | |
881 | |
882 | PendingInstantiations.insert(PendingInstantiations.end(), |
883 | LateParsedInstantiations.begin(), |
884 | LateParsedInstantiations.end()); |
885 | LateParsedInstantiations.clear(); |
886 | |
887 | |
888 | |
889 | if (TUKind != TU_Prefix) { |
890 | DiagnoseUseOfUnimplementedSelectors(); |
891 | |
892 | |
893 | |
894 | |
895 | DefineUsedVTables(); |
896 | |
897 | |
898 | |
899 | |
900 | |
901 | |
902 | |
903 | |
904 | |
905 | |
906 | if (ExternalSource) { |
907 | |
908 | SmallVector<PendingImplicitInstantiation, 4> Pending; |
909 | ExternalSource->ReadPendingInstantiations(Pending); |
910 | for (auto PII : Pending) |
911 | if (auto Func = dyn_cast<FunctionDecl>(PII.first)) |
912 | Func->setInstantiationIsPending(true); |
913 | PendingInstantiations.insert(PendingInstantiations.begin(), |
914 | Pending.begin(), Pending.end()); |
915 | } |
916 | |
917 | PerformPendingInstantiations(); |
918 | |
919 | (0) . __assert_fail ("LateParsedInstantiations.empty() && \"end of TU template instantiation should not create more \" \"late-parsed templates\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 921, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LateParsedInstantiations.empty() && |
920 | (0) . __assert_fail ("LateParsedInstantiations.empty() && \"end of TU template instantiation should not create more \" \"late-parsed templates\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 921, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "end of TU template instantiation should not create more " |
921 | (0) . __assert_fail ("LateParsedInstantiations.empty() && \"end of TU template instantiation should not create more \" \"late-parsed templates\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 921, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "late-parsed templates"); |
922 | |
923 | if (LateTemplateParserCleanup) |
924 | LateTemplateParserCleanup(OpaqueParser); |
925 | |
926 | CheckDelayedMemberExceptionSpecs(); |
927 | } |
928 | |
929 | DiagnoseUnterminatedPragmaPack(); |
930 | DiagnoseUnterminatedPragmaAttribute(); |
931 | |
932 | |
933 | |
934 | assert(DelayedOverridingExceptionSpecChecks.empty()); |
935 | assert(DelayedEquivalentExceptionSpecChecks.empty()); |
936 | assert(DelayedDefaultedMemberExceptionSpecs.empty()); |
937 | |
938 | |
939 | assert(DelayedDllExportClasses.empty()); |
940 | |
941 | |
942 | UnusedFileScopedDecls.erase( |
943 | std::remove_if(UnusedFileScopedDecls.begin(nullptr, true), |
944 | UnusedFileScopedDecls.end(), |
945 | [this](const DeclaratorDecl *DD) { |
946 | return ShouldRemoveFromUnused(this, DD); |
947 | }), |
948 | UnusedFileScopedDecls.end()); |
949 | |
950 | if (TUKind == TU_Prefix) { |
951 | |
952 | if (!PP.isIncrementalProcessingEnabled()) |
953 | TUScope = nullptr; |
954 | return; |
955 | } |
956 | |
957 | |
958 | LoadExternalWeakUndeclaredIdentifiers(); |
959 | for (auto WeakID : WeakUndeclaredIdentifiers) { |
960 | if (WeakID.second.getUsed()) |
961 | continue; |
962 | |
963 | Decl *PrevDecl = LookupSingleName(TUScope, WeakID.first, SourceLocation(), |
964 | LookupOrdinaryName); |
965 | if (PrevDecl != nullptr && |
966 | !(isa<FunctionDecl>(PrevDecl) || isa<VarDecl>(PrevDecl))) |
967 | Diag(WeakID.second.getLocation(), diag::warn_attribute_wrong_decl_type) |
968 | << "'weak'" << ExpectedVariableOrFunction; |
969 | else |
970 | Diag(WeakID.second.getLocation(), diag::warn_weak_identifier_undeclared) |
971 | << WeakID.first; |
972 | } |
973 | |
974 | if (LangOpts.CPlusPlus11 && |
975 | !Diags.isIgnored(diag::warn_delegating_ctor_cycle, SourceLocation())) |
976 | CheckDelegatingCtorCycles(); |
977 | |
978 | if (!Diags.hasErrorOccurred()) { |
979 | if (ExternalSource) |
980 | ExternalSource->ReadUndefinedButUsed(UndefinedButUsed); |
981 | checkUndefinedButUsed(*this); |
982 | } |
983 | |
984 | if (TUKind == TU_Module) { |
985 | |
986 | |
987 | if (getLangOpts().getCompilingModule() == |
988 | LangOptions::CMK_ModuleInterface && |
989 | (ModuleScopes.empty() || |
990 | ModuleScopes.back().Module->Kind != Module::ModuleInterfaceUnit)) { |
991 | |
992 | Diag(getSourceManager().getLocForStartOfFile( |
993 | getSourceManager().getMainFileID()), |
994 | diag::err_module_declaration_missing); |
995 | } |
996 | |
997 | |
998 | |
999 | if (Module *CurrentModule = PP.getCurrentModule()) { |
1000 | ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap(); |
1001 | |
1002 | SmallVector<Module *, 2> Stack; |
1003 | Stack.push_back(CurrentModule); |
1004 | while (!Stack.empty()) { |
1005 | Module *Mod = Stack.pop_back_val(); |
1006 | |
1007 | |
1008 | |
1009 | |
1010 | |
1011 | ModMap.resolveExports(Mod, ); |
1012 | ModMap.resolveUses(Mod, ); |
1013 | ModMap.resolveConflicts(Mod, ); |
1014 | |
1015 | |
1016 | Stack.append(Mod->submodule_begin(), Mod->submodule_end()); |
1017 | } |
1018 | } |
1019 | |
1020 | |
1021 | |
1022 | emitAndClearUnusedLocalTypedefWarnings(); |
1023 | } |
1024 | |
1025 | |
1026 | |
1027 | |
1028 | |
1029 | |
1030 | |
1031 | |
1032 | |
1033 | |
1034 | |
1035 | |
1036 | llvm::SmallSet<VarDecl *, 32> Seen; |
1037 | for (TentativeDefinitionsType::iterator |
1038 | T = TentativeDefinitions.begin(ExternalSource), |
1039 | TEnd = TentativeDefinitions.end(); |
1040 | T != TEnd; ++T) { |
1041 | VarDecl *VD = (*T)->getActingDefinition(); |
1042 | |
1043 | |
1044 | |
1045 | |
1046 | if (!VD || VD->isInvalidDecl() || !Seen.insert(VD).second) |
1047 | continue; |
1048 | |
1049 | if (const IncompleteArrayType *ArrayT |
1050 | = Context.getAsIncompleteArrayType(VD->getType())) { |
1051 | |
1052 | Diag(VD->getLocation(), diag::warn_tentative_incomplete_array); |
1053 | llvm::APInt One(Context.getTypeSize(Context.getSizeType()), true); |
1054 | QualType T = Context.getConstantArrayType(ArrayT->getElementType(), |
1055 | One, ArrayType::Normal, 0); |
1056 | VD->setType(T); |
1057 | } else if (RequireCompleteType(VD->getLocation(), VD->getType(), |
1058 | diag::err_tentative_def_incomplete_type)) |
1059 | VD->setInvalidDecl(); |
1060 | |
1061 | |
1062 | CheckCompleteVariableDeclaration(VD); |
1063 | |
1064 | |
1065 | if (!VD->isInvalidDecl()) |
1066 | Consumer.CompleteTentativeDefinition(VD); |
1067 | } |
1068 | |
1069 | |
1070 | |
1071 | |
1072 | |
1073 | if (!Diags.hasErrorOccurred() && TUKind != TU_Module) { |
1074 | |
1075 | for (UnusedFileScopedDeclsType::iterator |
1076 | I = UnusedFileScopedDecls.begin(ExternalSource), |
1077 | E = UnusedFileScopedDecls.end(); I != E; ++I) { |
1078 | if (ShouldRemoveFromUnused(this, *I)) |
1079 | continue; |
1080 | |
1081 | if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) { |
1082 | const FunctionDecl *DiagD; |
1083 | if (!FD->hasBody(DiagD)) |
1084 | DiagD = FD; |
1085 | if (DiagD->isDeleted()) |
1086 | continue; |
1087 | if (DiagD->isReferenced()) { |
1088 | if (isa<CXXMethodDecl>(DiagD)) |
1089 | Diag(DiagD->getLocation(), diag::warn_unneeded_member_function) |
1090 | << DiagD->getDeclName(); |
1091 | else { |
1092 | if (FD->getStorageClass() == SC_Static && |
1093 | !FD->isInlineSpecified() && |
1094 | !SourceMgr.isInMainFile( |
1095 | SourceMgr.getExpansionLoc(FD->getLocation()))) |
1096 | Diag(DiagD->getLocation(), |
1097 | diag::warn_unneeded_static_internal_decl) |
1098 | << DiagD->getDeclName(); |
1099 | else |
1100 | Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl) |
1101 | << << DiagD->getDeclName(); |
1102 | } |
1103 | } else { |
1104 | if (FD->getDescribedFunctionTemplate()) |
1105 | Diag(DiagD->getLocation(), diag::warn_unused_template) |
1106 | << << DiagD->getDeclName(); |
1107 | else |
1108 | Diag(DiagD->getLocation(), |
1109 | isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function |
1110 | : diag::warn_unused_function) |
1111 | << DiagD->getDeclName(); |
1112 | } |
1113 | } else { |
1114 | const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition(); |
1115 | if (!DiagD) |
1116 | DiagD = cast<VarDecl>(*I); |
1117 | if (DiagD->isReferenced()) { |
1118 | Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl) |
1119 | << << DiagD->getDeclName(); |
1120 | } else if (DiagD->getType().isConstQualified()) { |
1121 | const SourceManager &SM = SourceMgr; |
1122 | if (SM.getMainFileID() != SM.getFileID(DiagD->getLocation()) || |
1123 | !PP.getLangOpts().IsHeaderFile) |
1124 | Diag(DiagD->getLocation(), diag::warn_unused_const_variable) |
1125 | << DiagD->getDeclName(); |
1126 | } else { |
1127 | if (DiagD->getDescribedVarTemplate()) |
1128 | Diag(DiagD->getLocation(), diag::warn_unused_template) |
1129 | << << DiagD->getDeclName(); |
1130 | else |
1131 | Diag(DiagD->getLocation(), diag::warn_unused_variable) |
1132 | << DiagD->getDeclName(); |
1133 | } |
1134 | } |
1135 | } |
1136 | |
1137 | emitAndClearUnusedLocalTypedefWarnings(); |
1138 | } |
1139 | |
1140 | if (!Diags.isIgnored(diag::warn_unused_private_field, SourceLocation())) { |
1141 | |
1142 | |
1143 | RecordCompleteMap RecordsComplete; |
1144 | RecordCompleteMap MNCComplete; |
1145 | for (NamedDeclSetType::iterator I = UnusedPrivateFields.begin(), |
1146 | E = UnusedPrivateFields.end(); I != E; ++I) { |
1147 | const NamedDecl *D = *I; |
1148 | const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext()); |
1149 | if (RD && !RD->isUnion() && |
1150 | IsRecordFullyDefined(RD, RecordsComplete, MNCComplete)) { |
1151 | Diag(D->getLocation(), diag::warn_unused_private_field) |
1152 | << D->getDeclName(); |
1153 | } |
1154 | } |
1155 | } |
1156 | |
1157 | if (!Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation())) { |
1158 | if (ExternalSource) |
1159 | ExternalSource->ReadMismatchingDeleteExpressions(DeleteExprs); |
1160 | for (const auto &DeletedFieldInfo : DeleteExprs) { |
1161 | for (const auto &DeleteExprLoc : DeletedFieldInfo.second) { |
1162 | AnalyzeDeleteExprMismatch(DeletedFieldInfo.first, DeleteExprLoc.first, |
1163 | DeleteExprLoc.second); |
1164 | } |
1165 | } |
1166 | } |
1167 | |
1168 | |
1169 | |
1170 | |
1171 | (0) . __assert_fail ("ParsingInitForAutoVars.empty() && \"Didn't unmark var as having its initializer parsed\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 1172, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ParsingInitForAutoVars.empty() && |
1172 | (0) . __assert_fail ("ParsingInitForAutoVars.empty() && \"Didn't unmark var as having its initializer parsed\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 1172, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Didn't unmark var as having its initializer parsed"); |
1173 | |
1174 | if (!PP.isIncrementalProcessingEnabled()) |
1175 | TUScope = nullptr; |
1176 | } |
1177 | |
1178 | |
1179 | |
1180 | |
1181 | |
1182 | |
1183 | DeclContext *Sema::getFunctionLevelDeclContext() { |
1184 | DeclContext *DC = CurContext; |
1185 | |
1186 | while (true) { |
1187 | if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC) || isa<CapturedDecl>(DC)) { |
1188 | DC = DC->getParent(); |
1189 | } else if (isa<CXXMethodDecl>(DC) && |
1190 | cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call && |
1191 | cast<CXXRecordDecl>(DC->getParent())->isLambda()) { |
1192 | DC = DC->getParent()->getParent(); |
1193 | } |
1194 | else break; |
1195 | } |
1196 | |
1197 | return DC; |
1198 | } |
1199 | |
1200 | |
1201 | |
1202 | |
1203 | FunctionDecl *Sema::getCurFunctionDecl() { |
1204 | DeclContext *DC = getFunctionLevelDeclContext(); |
1205 | return dyn_cast<FunctionDecl>(DC); |
1206 | } |
1207 | |
1208 | ObjCMethodDecl *Sema::getCurMethodDecl() { |
1209 | DeclContext *DC = getFunctionLevelDeclContext(); |
1210 | while (isa<RecordDecl>(DC)) |
1211 | DC = DC->getParent(); |
1212 | return dyn_cast<ObjCMethodDecl>(DC); |
1213 | } |
1214 | |
1215 | NamedDecl *Sema::getCurFunctionOrMethodDecl() { |
1216 | DeclContext *DC = getFunctionLevelDeclContext(); |
1217 | if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC)) |
1218 | return cast<NamedDecl>(DC); |
1219 | return nullptr; |
1220 | } |
1221 | |
1222 | void Sema::EmitCurrentDiagnostic(unsigned DiagID) { |
1223 | |
1224 | |
1225 | |
1226 | |
1227 | |
1228 | |
1229 | |
1230 | if (Optional<TemplateDeductionInfo*> Info = isSFINAEContext()) { |
1231 | switch (DiagnosticIDs::getDiagnosticSFINAEResponse( |
1232 | Diags.getCurrentDiagID())) { |
1233 | case DiagnosticIDs::SFINAE_Report: |
1234 | |
1235 | break; |
1236 | |
1237 | case DiagnosticIDs::SFINAE_SubstitutionFailure: |
1238 | |
1239 | |
1240 | ++NumSFINAEErrors; |
1241 | |
1242 | |
1243 | |
1244 | if (*Info && !(*Info)->hasSFINAEDiagnostic()) { |
1245 | Diagnostic DiagInfo(&Diags); |
1246 | (*Info)->addSFINAEDiagnostic(DiagInfo.getLocation(), |
1247 | PartialDiagnostic(DiagInfo, Context.getDiagAllocator())); |
1248 | } |
1249 | |
1250 | Diags.setLastDiagnosticIgnored(); |
1251 | Diags.Clear(); |
1252 | return; |
1253 | |
1254 | case DiagnosticIDs::SFINAE_AccessControl: { |
1255 | |
1256 | |
1257 | |
1258 | |
1259 | if (!AccessCheckingSFINAE && !getLangOpts().CPlusPlus11) |
1260 | break; |
1261 | |
1262 | SourceLocation Loc = Diags.getCurrentDiagLoc(); |
1263 | |
1264 | |
1265 | ++NumSFINAEErrors; |
1266 | |
1267 | |
1268 | |
1269 | if (*Info && !(*Info)->hasSFINAEDiagnostic()) { |
1270 | Diagnostic DiagInfo(&Diags); |
1271 | (*Info)->addSFINAEDiagnostic(DiagInfo.getLocation(), |
1272 | PartialDiagnostic(DiagInfo, Context.getDiagAllocator())); |
1273 | } |
1274 | |
1275 | Diags.setLastDiagnosticIgnored(); |
1276 | Diags.Clear(); |
1277 | |
1278 | |
1279 | |
1280 | Diag(Loc, diag::warn_cxx98_compat_sfinae_access_control); |
1281 | |
1282 | |
1283 | |
1284 | Diags.setLastDiagnosticIgnored(); |
1285 | return; |
1286 | } |
1287 | |
1288 | case DiagnosticIDs::SFINAE_Suppress: |
1289 | |
1290 | |
1291 | if (*Info) { |
1292 | Diagnostic DiagInfo(&Diags); |
1293 | (*Info)->addSuppressedDiagnostic(DiagInfo.getLocation(), |
1294 | PartialDiagnostic(DiagInfo, Context.getDiagAllocator())); |
1295 | } |
1296 | |
1297 | |
1298 | Diags.setLastDiagnosticIgnored(); |
1299 | Diags.Clear(); |
1300 | return; |
1301 | } |
1302 | } |
1303 | |
1304 | |
1305 | |
1306 | Context.setPrintingPolicy(getPrintingPolicy()); |
1307 | |
1308 | |
1309 | if (!Diags.EmitCurrentDiagnostic()) |
1310 | return; |
1311 | |
1312 | |
1313 | |
1314 | |
1315 | |
1316 | if (!DiagnosticIDs::isBuiltinNote(DiagID)) |
1317 | PrintContextStack(); |
1318 | } |
1319 | |
1320 | Sema::SemaDiagnosticBuilder |
1321 | Sema::Diag(SourceLocation Loc, const PartialDiagnostic& PD) { |
1322 | SemaDiagnosticBuilder Builder(Diag(Loc, PD.getDiagID())); |
1323 | PD.Emit(Builder); |
1324 | |
1325 | return Builder; |
1326 | } |
1327 | |
1328 | |
1329 | |
1330 | static void emitCallStackNotes(Sema &S, FunctionDecl *FD) { |
1331 | auto FnIt = S.DeviceKnownEmittedFns.find(FD); |
1332 | while (FnIt != S.DeviceKnownEmittedFns.end()) { |
1333 | DiagnosticBuilder Builder( |
1334 | S.Diags.Report(FnIt->second.Loc, diag::note_called_by)); |
1335 | Builder << FnIt->second.FD; |
1336 | Builder.setForceEmit(); |
1337 | |
1338 | FnIt = S.DeviceKnownEmittedFns.find(FnIt->second.FD); |
1339 | } |
1340 | } |
1341 | |
1342 | |
1343 | |
1344 | static void emitDeferredDiags(Sema &S, FunctionDecl *FD) { |
1345 | auto It = S.DeviceDeferredDiags.find(FD); |
1346 | if (It == S.DeviceDeferredDiags.end()) |
1347 | return; |
1348 | bool HasWarningOrError = false; |
1349 | for (PartialDiagnosticAt &PDAt : It->second) { |
1350 | const SourceLocation &Loc = PDAt.first; |
1351 | const PartialDiagnostic &PD = PDAt.second; |
1352 | HasWarningOrError |= S.getDiagnostics().getDiagnosticLevel( |
1353 | PD.getDiagID(), Loc) >= DiagnosticsEngine::Warning; |
1354 | DiagnosticBuilder Builder(S.Diags.Report(Loc, PD.getDiagID())); |
1355 | Builder.setForceEmit(); |
1356 | PD.Emit(Builder); |
1357 | } |
1358 | S.DeviceDeferredDiags.erase(It); |
1359 | |
1360 | |
1361 | |
1362 | |
1363 | if (HasWarningOrError) |
1364 | emitCallStackNotes(S, FD); |
1365 | } |
1366 | |
1367 | |
1368 | |
1369 | |
1370 | |
1371 | |
1372 | |
1373 | |
1374 | |
1375 | |
1376 | |
1377 | |
1378 | |
1379 | |
1380 | |
1381 | |
1382 | |
1383 | |
1384 | |
1385 | |
1386 | |
1387 | |
1388 | |
1389 | |
1390 | |
1391 | Sema::DeviceDiagBuilder::DeviceDiagBuilder(Kind K, SourceLocation Loc, |
1392 | unsigned DiagID, FunctionDecl *Fn, |
1393 | Sema &S) |
1394 | : S(S), Loc(Loc), DiagID(DiagID), Fn(Fn), |
1395 | ShowCallStack(K == K_ImmediateWithCallStack || K == K_Deferred) { |
1396 | switch (K) { |
1397 | case K_Nop: |
1398 | break; |
1399 | case K_Immediate: |
1400 | case K_ImmediateWithCallStack: |
1401 | ImmediateDiag.emplace(S.Diag(Loc, DiagID)); |
1402 | break; |
1403 | case K_Deferred: |
1404 | (0) . __assert_fail ("Fn && \"Must have a function to attach the deferred diag to.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 1404, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Fn && "Must have a function to attach the deferred diag to."); |
1405 | auto &Diags = S.DeviceDeferredDiags[Fn]; |
1406 | PartialDiagId.emplace(Diags.size()); |
1407 | Diags.emplace_back(Loc, S.PDiag(DiagID)); |
1408 | break; |
1409 | } |
1410 | } |
1411 | |
1412 | Sema::DeviceDiagBuilder::DeviceDiagBuilder(DeviceDiagBuilder &&D) |
1413 | : S(D.S), Loc(D.Loc), DiagID(D.DiagID), Fn(D.Fn), |
1414 | ShowCallStack(D.ShowCallStack), ImmediateDiag(D.ImmediateDiag), |
1415 | PartialDiagId(D.PartialDiagId) { |
1416 | |
1417 | D.ShowCallStack = false; |
1418 | D.ImmediateDiag.reset(); |
1419 | D.PartialDiagId.reset(); |
1420 | } |
1421 | |
1422 | Sema::DeviceDiagBuilder::~DeviceDiagBuilder() { |
1423 | if (ImmediateDiag) { |
1424 | |
1425 | |
1426 | bool IsWarningOrError = S.getDiagnostics().getDiagnosticLevel( |
1427 | DiagID, Loc) >= DiagnosticsEngine::Warning; |
1428 | ImmediateDiag.reset(); |
1429 | if (IsWarningOrError && ShowCallStack) |
1430 | emitCallStackNotes(S, Fn); |
1431 | } else { |
1432 | (0) . __assert_fail ("(!PartialDiagId || ShowCallStack) && \"Must always show call stack for deferred diags.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 1433, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((!PartialDiagId || ShowCallStack) && |
1433 | (0) . __assert_fail ("(!PartialDiagId || ShowCallStack) && \"Must always show call stack for deferred diags.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 1433, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Must always show call stack for deferred diags."); |
1434 | } |
1435 | } |
1436 | |
1437 | |
1438 | |
1439 | |
1440 | void Sema::markKnownEmitted( |
1441 | Sema &S, FunctionDecl *OrigCaller, FunctionDecl *OrigCallee, |
1442 | SourceLocation OrigLoc, |
1443 | const llvm::function_ref<bool(Sema &, FunctionDecl *)> IsKnownEmitted) { |
1444 | |
1445 | if (IsKnownEmitted(S, OrigCallee)) { |
1446 | assert(!S.DeviceCallGraph.count(OrigCallee)); |
1447 | return; |
1448 | } |
1449 | |
1450 | |
1451 | |
1452 | |
1453 | struct CallInfo { |
1454 | FunctionDecl *Caller; |
1455 | FunctionDecl *Callee; |
1456 | SourceLocation Loc; |
1457 | }; |
1458 | llvm::SmallVector<CallInfo, 4> Worklist = {{OrigCaller, OrigCallee, OrigLoc}}; |
1459 | llvm::SmallSet<CanonicalDeclPtr<FunctionDecl>, 4> Seen; |
1460 | Seen.insert(OrigCallee); |
1461 | while (!Worklist.empty()) { |
1462 | CallInfo C = Worklist.pop_back_val(); |
1463 | (0) . __assert_fail ("!IsKnownEmitted(S, C.Callee) && \"Worklist should not contain known-emitted functions.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 1464, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!IsKnownEmitted(S, C.Callee) && |
1464 | (0) . __assert_fail ("!IsKnownEmitted(S, C.Callee) && \"Worklist should not contain known-emitted functions.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 1464, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Worklist should not contain known-emitted functions."); |
1465 | S.DeviceKnownEmittedFns[C.Callee] = {C.Caller, C.Loc}; |
1466 | emitDeferredDiags(S, C.Callee); |
1467 | |
1468 | |
1469 | |
1470 | |
1471 | if (auto *Templ = C.Callee->getPrimaryTemplate()) { |
1472 | FunctionDecl *TemplFD = Templ->getAsFunction(); |
1473 | if (!Seen.count(TemplFD) && !S.DeviceKnownEmittedFns.count(TemplFD)) { |
1474 | Seen.insert(TemplFD); |
1475 | Worklist.push_back( |
1476 | { C.Caller, TemplFD, C.Loc}); |
1477 | } |
1478 | } |
1479 | |
1480 | |
1481 | auto CGIt = S.DeviceCallGraph.find(C.Callee); |
1482 | if (CGIt == S.DeviceCallGraph.end()) |
1483 | continue; |
1484 | |
1485 | for (std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> FDLoc : |
1486 | CGIt->second) { |
1487 | FunctionDecl *NewCallee = FDLoc.first; |
1488 | SourceLocation CallLoc = FDLoc.second; |
1489 | if (Seen.count(NewCallee) || IsKnownEmitted(S, NewCallee)) |
1490 | continue; |
1491 | Seen.insert(NewCallee); |
1492 | Worklist.push_back( |
1493 | { C.Callee, NewCallee, CallLoc}); |
1494 | } |
1495 | |
1496 | |
1497 | |
1498 | S.DeviceCallGraph.erase(CGIt); |
1499 | } |
1500 | } |
1501 | |
1502 | Sema::DeviceDiagBuilder Sema::targetDiag(SourceLocation Loc, unsigned DiagID) { |
1503 | if (LangOpts.OpenMP && LangOpts.OpenMPIsDevice) |
1504 | return diagIfOpenMPDeviceCode(Loc, DiagID); |
1505 | if (getLangOpts().CUDA) |
1506 | return getLangOpts().CUDAIsDevice ? CUDADiagIfDeviceCode(Loc, DiagID) |
1507 | : CUDADiagIfHostCode(Loc, DiagID); |
1508 | return DeviceDiagBuilder(DeviceDiagBuilder::K_Immediate, Loc, DiagID, |
1509 | getCurFunctionDecl(), *this); |
1510 | } |
1511 | |
1512 | |
1513 | |
1514 | |
1515 | |
1516 | bool Sema::findMacroSpelling(SourceLocation &locref, StringRef name) { |
1517 | SourceLocation loc = locref; |
1518 | if (!loc.isMacroID()) return false; |
1519 | |
1520 | |
1521 | |
1522 | loc = getSourceManager().getExpansionLoc(loc); |
1523 | |
1524 | |
1525 | SmallVector<char, 16> buffer; |
1526 | if (getPreprocessor().getSpelling(loc, buffer) == name) { |
1527 | locref = loc; |
1528 | return true; |
1529 | } |
1530 | return false; |
1531 | } |
1532 | |
1533 | |
1534 | |
1535 | |
1536 | |
1537 | |
1538 | |
1539 | |
1540 | |
1541 | |
1542 | |
1543 | |
1544 | Scope *Sema::getScopeForContext(DeclContext *Ctx) { |
1545 | |
1546 | if (!Ctx) |
1547 | return nullptr; |
1548 | |
1549 | Ctx = Ctx->getPrimaryContext(); |
1550 | for (Scope *S = getCurScope(); S; S = S->getParent()) { |
1551 | |
1552 | |
1553 | if (S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) |
1554 | if (DeclContext *Entity = S->getEntity()) |
1555 | if (Ctx == Entity->getPrimaryContext()) |
1556 | return S; |
1557 | } |
1558 | |
1559 | return nullptr; |
1560 | } |
1561 | |
1562 | |
1563 | void Sema::PushFunctionScope() { |
1564 | if (FunctionScopes.empty()) { |
1565 | |
1566 | PreallocatedFunctionScope->Clear(); |
1567 | FunctionScopes.push_back(PreallocatedFunctionScope.get()); |
1568 | } else { |
1569 | FunctionScopes.push_back(new FunctionScopeInfo(getDiagnostics())); |
1570 | } |
1571 | if (LangOpts.OpenMP) |
1572 | pushOpenMPFunctionRegion(); |
1573 | } |
1574 | |
1575 | void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) { |
1576 | FunctionScopes.push_back(new BlockScopeInfo(getDiagnostics(), |
1577 | BlockScope, Block)); |
1578 | } |
1579 | |
1580 | LambdaScopeInfo *Sema::PushLambdaScope() { |
1581 | LambdaScopeInfo *const LSI = new LambdaScopeInfo(getDiagnostics()); |
1582 | FunctionScopes.push_back(LSI); |
1583 | return LSI; |
1584 | } |
1585 | |
1586 | void Sema::RecordParsingTemplateParameterDepth(unsigned Depth) { |
1587 | if (LambdaScopeInfo *const LSI = getCurLambda()) { |
1588 | LSI->AutoTemplateParameterDepth = Depth; |
1589 | return; |
1590 | } |
1591 | llvm_unreachable( |
1592 | "Remove assertion if intentionally called in a non-lambda context."); |
1593 | } |
1594 | |
1595 | |
1596 | |
1597 | static void checkEscapingByref(VarDecl *VD, Sema &S) { |
1598 | QualType T = VD->getType(); |
1599 | EnterExpressionEvaluationContext scope( |
1600 | S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); |
1601 | SourceLocation Loc = VD->getLocation(); |
1602 | Expr *VarRef = |
1603 | new (S.Context) DeclRefExpr(S.Context, VD, false, T, VK_LValue, Loc); |
1604 | ExprResult Result = S.PerformMoveOrCopyInitialization( |
1605 | InitializedEntity::InitializeBlock(Loc, T, false), VD, VD->getType(), |
1606 | VarRef, ); |
1607 | if (!Result.isInvalid()) { |
1608 | Result = S.MaybeCreateExprWithCleanups(Result); |
1609 | Expr *Init = Result.getAs<Expr>(); |
1610 | S.Context.setBlockVarCopyInit(VD, Init, S.canThrow(Init)); |
1611 | } |
1612 | |
1613 | |
1614 | |
1615 | if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) |
1616 | if (CXXDestructorDecl *DD = RD->getDestructor()) { |
1617 | auto *FPT = DD->getType()->getAs<FunctionProtoType>(); |
1618 | S.ResolveExceptionSpec(Loc, FPT); |
1619 | } |
1620 | } |
1621 | |
1622 | static void markEscapingByrefs(const FunctionScopeInfo &FSI, Sema &S) { |
1623 | |
1624 | |
1625 | for (const BlockDecl *BD : FSI.Blocks) { |
1626 | if (BD->doesNotEscape()) |
1627 | continue; |
1628 | for (const BlockDecl::Capture &BC : BD->captures()) { |
1629 | VarDecl *VD = BC.getVariable(); |
1630 | if (VD->hasAttr<BlocksAttr>()) |
1631 | VD->setEscapingByref(); |
1632 | } |
1633 | } |
1634 | |
1635 | for (VarDecl *VD : FSI.ByrefBlockVars) { |
1636 | |
1637 | if (!VD->isEscapingByref()) |
1638 | continue; |
1639 | |
1640 | |
1641 | |
1642 | |
1643 | if (VD->getType()->isStructureOrClassType()) |
1644 | checkEscapingByref(VD, S); |
1645 | } |
1646 | } |
1647 | |
1648 | void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP, |
1649 | const Decl *D, const BlockExpr *blkExpr) { |
1650 | (0) . __assert_fail ("!FunctionScopes.empty() && \"mismatched push/pop!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 1650, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!FunctionScopes.empty() && "mismatched push/pop!"); |
1651 | |
1652 | |
1653 | |
1654 | |
1655 | |
1656 | markEscapingByrefs(*FunctionScopes.back(), *this); |
1657 | |
1658 | FunctionScopeInfo *Scope = FunctionScopes.pop_back_val(); |
1659 | |
1660 | if (LangOpts.OpenMP) |
1661 | popOpenMPFunctionRegion(Scope); |
1662 | |
1663 | |
1664 | if (WP && D) |
1665 | AnalysisWarnings.IssueWarnings(*WP, Scope, D, blkExpr); |
1666 | else |
1667 | for (const auto &PUD : Scope->PossiblyUnreachableDiags) |
1668 | Diag(PUD.Loc, PUD.PD); |
1669 | |
1670 | |
1671 | if (Scope != PreallocatedFunctionScope.get()) |
1672 | delete Scope; |
1673 | } |
1674 | |
1675 | void Sema::PushCompoundScope(bool IsStmtExpr) { |
1676 | getCurFunction()->CompoundScopes.push_back(CompoundScopeInfo(IsStmtExpr)); |
1677 | } |
1678 | |
1679 | void Sema::PopCompoundScope() { |
1680 | FunctionScopeInfo *CurFunction = getCurFunction(); |
1681 | (0) . __assert_fail ("!CurFunction->CompoundScopes.empty() && \"mismatched push/pop\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/Sema.cpp", 1681, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!CurFunction->CompoundScopes.empty() && "mismatched push/pop"); |
1682 | |
1683 | CurFunction->CompoundScopes.pop_back(); |
1684 | } |
1685 | |
1686 | |
1687 | |
1688 | bool Sema::hasAnyUnrecoverableErrorsInThisFunction() const { |
1689 | return getCurFunction()->ErrorTrap.hasUnrecoverableErrorOccurred(); |
1690 | } |
1691 | |
1692 | void Sema::setFunctionHasBranchIntoScope() { |
1693 | if (!FunctionScopes.empty()) |
1694 | FunctionScopes.back()->setHasBranchIntoScope(); |
1695 | } |
1696 | |
1697 | void Sema::setFunctionHasBranchProtectedScope() { |
1698 | if (!FunctionScopes.empty()) |
1699 | FunctionScopes.back()->setHasBranchProtectedScope(); |
1700 | } |
1701 | |
1702 | void Sema::setFunctionHasIndirectGoto() { |
1703 | if (!FunctionScopes.empty()) |
1704 | FunctionScopes.back()->setHasIndirectGoto(); |
1705 | } |
1706 | |
1707 | BlockScopeInfo *Sema::getCurBlock() { |
1708 | if (FunctionScopes.empty()) |
1709 | return nullptr; |
1710 | |
1711 | auto CurBSI = dyn_cast<BlockScopeInfo>(FunctionScopes.back()); |
1712 | if (CurBSI && CurBSI->TheDecl && |
1713 | !CurBSI->TheDecl->Encloses(CurContext)) { |
1714 | |
1715 | assert(!CodeSynthesisContexts.empty()); |
1716 | return nullptr; |
1717 | } |
1718 | |
1719 | return CurBSI; |
1720 | } |
1721 | |
1722 | FunctionScopeInfo *Sema::getEnclosingFunction() const { |
1723 | if (FunctionScopes.empty()) |
1724 | return nullptr; |
1725 | |
1726 | for (int e = FunctionScopes.size() - 1; e >= 0; --e) { |
1727 | if (isa<sema::BlockScopeInfo>(FunctionScopes[e])) |
1728 | continue; |
1729 | return FunctionScopes[e]; |
1730 | } |
1731 | return nullptr; |
1732 | } |
1733 | |
1734 | LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) { |
1735 | if (FunctionScopes.empty()) |
1736 | return nullptr; |
1737 | |
1738 | auto I = FunctionScopes.rbegin(); |
1739 | if (IgnoreNonLambdaCapturingScope) { |
1740 | auto E = FunctionScopes.rend(); |
1741 | while (I != E && isa<CapturingScopeInfo>(*I) && !isa<LambdaScopeInfo>(*I)) |
1742 | ++I; |
1743 | if (I == E) |
1744 | return nullptr; |
1745 | } |
1746 | auto *CurLSI = dyn_cast<LambdaScopeInfo>(*I); |
1747 | if (CurLSI && CurLSI->Lambda && |
1748 | !CurLSI->Lambda->Encloses(CurContext)) { |
1749 | |
1750 | assert(!CodeSynthesisContexts.empty()); |
1751 | return nullptr; |
1752 | } |
1753 | |
1754 | return CurLSI; |
1755 | } |
1756 | |
1757 | |
1758 | LambdaScopeInfo *Sema::getCurGenericLambda() { |
1759 | if (LambdaScopeInfo *LSI = getCurLambda()) { |
1760 | return (LSI->AutoTemplateParams.size() || |
1761 | LSI->GLTemplateParameterList) ? LSI : nullptr; |
1762 | } |
1763 | return nullptr; |
1764 | } |
1765 | |
1766 | |
1767 | void Sema::(SourceRange ) { |
1768 | if (!LangOpts.RetainCommentsFromSystemHeaders && |
1769 | SourceMgr.isInSystemHeader(Comment.getBegin())) |
1770 | return; |
1771 | RawComment RC(SourceMgr, Comment, LangOpts.CommentOpts, false); |
1772 | if (RC.isAlmostTrailingComment()) { |
1773 | SourceRange MagicMarkerRange(Comment.getBegin(), |
1774 | Comment.getBegin().getLocWithOffset(3)); |
1775 | StringRef MagicMarkerText; |
1776 | switch (RC.getKind()) { |
1777 | case RawComment::RCK_OrdinaryBCPL: |
1778 | MagicMarkerText = "///<"; |
1779 | break; |
1780 | case RawComment::RCK_OrdinaryC: |
1781 | MagicMarkerText = "/**<"; |
1782 | break; |
1783 | default: |
1784 | llvm_unreachable("if this is an almost Doxygen comment, " |
1785 | "it should be ordinary"); |
1786 | } |
1787 | Diag(Comment.getBegin(), diag::warn_not_a_doxygen_trailing_member_comment) << |
1788 | FixItHint::CreateReplacement(MagicMarkerRange, MagicMarkerText); |
1789 | } |
1790 | Context.addComment(RC); |
1791 | } |
1792 | |
1793 | |
1794 | ExternalSemaSource::~ExternalSemaSource() {} |
1795 | |
1796 | void ExternalSemaSource::ReadMethodPool(Selector Sel) { } |
1797 | void ExternalSemaSource::updateOutOfDateSelector(Selector Sel) { } |
1798 | |
1799 | void ExternalSemaSource::ReadKnownNamespaces( |
1800 | SmallVectorImpl<NamespaceDecl *> &Namespaces) { |
1801 | } |
1802 | |
1803 | void ExternalSemaSource::ReadUndefinedButUsed( |
1804 | llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {} |
1805 | |
1806 | void ExternalSemaSource::ReadMismatchingDeleteExpressions(llvm::MapVector< |
1807 | FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &) {} |
1808 | |
1809 | |
1810 | |
1811 | |
1812 | |
1813 | |
1814 | |
1815 | |
1816 | |
1817 | |
1818 | |
1819 | |
1820 | bool Sema::tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, |
1821 | UnresolvedSetImpl &OverloadSet) { |
1822 | ZeroArgCallReturnTy = QualType(); |
1823 | OverloadSet.clear(); |
1824 | |
1825 | const OverloadExpr *Overloads = nullptr; |
1826 | bool IsMemExpr = false; |
1827 | if (E.getType() == Context.OverloadTy) { |
1828 | OverloadExpr::FindResult FR = OverloadExpr::find(const_cast<Expr*>(&E)); |
1829 | |
1830 | |
1831 | if (FR.HasFormOfMemberPointer) |
1832 | return false; |
1833 | |
1834 | Overloads = FR.Expression; |
1835 | } else if (E.getType() == Context.BoundMemberTy) { |
1836 | Overloads = dyn_cast<UnresolvedMemberExpr>(E.IgnoreParens()); |
1837 | IsMemExpr = true; |
1838 | } |
1839 | |
1840 | bool Ambiguous = false; |
1841 | bool IsMV = false; |
1842 | |
1843 | if (Overloads) { |
1844 | for (OverloadExpr::decls_iterator it = Overloads->decls_begin(), |
1845 | DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) { |
1846 | OverloadSet.addDecl(*it); |
1847 | |
1848 | |
1849 | |
1850 | if (IsMemExpr) |
1851 | continue; |
1852 | if (const FunctionDecl *OverloadDecl |
1853 | = dyn_cast<FunctionDecl>((*it)->getUnderlyingDecl())) { |
1854 | if (OverloadDecl->getMinRequiredArguments() == 0) { |
1855 | if (!ZeroArgCallReturnTy.isNull() && !Ambiguous && |
1856 | (!IsMV || !(OverloadDecl->isCPUDispatchMultiVersion() || |
1857 | OverloadDecl->isCPUSpecificMultiVersion()))) { |
1858 | ZeroArgCallReturnTy = QualType(); |
1859 | Ambiguous = true; |
1860 | } else { |
1861 | ZeroArgCallReturnTy = OverloadDecl->getReturnType(); |
1862 | IsMV = OverloadDecl->isCPUDispatchMultiVersion() || |
1863 | OverloadDecl->isCPUSpecificMultiVersion(); |
1864 | } |
1865 | } |
1866 | } |
1867 | } |
1868 | |
1869 | |
1870 | if (!IsMemExpr) |
1871 | return !ZeroArgCallReturnTy.isNull(); |
1872 | } |
1873 | |
1874 | |
1875 | |
1876 | |
1877 | if (IsMemExpr && !E.isTypeDependent()) { |
1878 | bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); |
1879 | getDiagnostics().setSuppressAllDiagnostics(true); |
1880 | ExprResult R = BuildCallToMemberFunction(nullptr, &E, SourceLocation(), |
1881 | None, SourceLocation()); |
1882 | getDiagnostics().setSuppressAllDiagnostics(Suppress); |
1883 | if (R.isUsable()) { |
1884 | ZeroArgCallReturnTy = R.get()->getType(); |
1885 | return true; |
1886 | } |
1887 | return false; |
1888 | } |
1889 | |
1890 | if (const DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(E.IgnoreParens())) { |
1891 | if (const FunctionDecl *Fun = dyn_cast<FunctionDecl>(DeclRef->getDecl())) { |
1892 | if (Fun->getMinRequiredArguments() == 0) |
1893 | ZeroArgCallReturnTy = Fun->getReturnType(); |
1894 | return true; |
1895 | } |
1896 | } |
1897 | |
1898 | |
1899 | |
1900 | QualType ExprTy = E.getType(); |
1901 | const FunctionType *FunTy = nullptr; |
1902 | QualType PointeeTy = ExprTy->getPointeeType(); |
1903 | if (!PointeeTy.isNull()) |
1904 | FunTy = PointeeTy->getAs<FunctionType>(); |
1905 | if (!FunTy) |
1906 | FunTy = ExprTy->getAs<FunctionType>(); |
1907 | |
1908 | if (const FunctionProtoType *FPT = |
1909 | dyn_cast_or_null<FunctionProtoType>(FunTy)) { |
1910 | if (FPT->getNumParams() == 0) |
1911 | ZeroArgCallReturnTy = FunTy->getReturnType(); |
1912 | return true; |
1913 | } |
1914 | return false; |
1915 | } |
1916 | |
1917 | |
1918 | |
1919 | |
1920 | |
1921 | |
1922 | |
1923 | |
1924 | |
1925 | |
1926 | |
1927 | |
1928 | |
1929 | static void noteOverloads(Sema &S, const UnresolvedSetImpl &Overloads, |
1930 | const SourceLocation FinalNoteLoc) { |
1931 | int ShownOverloads = 0; |
1932 | int SuppressedOverloads = 0; |
1933 | for (UnresolvedSetImpl::iterator It = Overloads.begin(), |
1934 | DeclsEnd = Overloads.end(); It != DeclsEnd; ++It) { |
1935 | |
1936 | |
1937 | if (ShownOverloads >= 4 && S.Diags.getShowOverloads() == Ovl_Best) { |
1938 | ++SuppressedOverloads; |
1939 | continue; |
1940 | } |
1941 | |
1942 | NamedDecl *Fn = (*It)->getUnderlyingDecl(); |
1943 | |
1944 | if (const auto *FD = Fn->getAsFunction()) { |
1945 | if (FD->isMultiVersion() && FD->hasAttr<TargetAttr>() && |
1946 | !FD->getAttr<TargetAttr>()->isDefaultVersion()) |
1947 | continue; |
1948 | } |
1949 | S.Diag(Fn->getLocation(), diag::note_possible_target_of_call); |
1950 | ++ShownOverloads; |
1951 | } |
1952 | |
1953 | if (SuppressedOverloads) |
1954 | S.Diag(FinalNoteLoc, diag::note_ovl_too_many_candidates) |
1955 | << SuppressedOverloads; |
1956 | } |
1957 | |
1958 | static void notePlausibleOverloads(Sema &S, SourceLocation Loc, |
1959 | const UnresolvedSetImpl &Overloads, |
1960 | bool (*IsPlausibleResult)(QualType)) { |
1961 | if (!IsPlausibleResult) |
1962 | return noteOverloads(S, Overloads, Loc); |
1963 | |
1964 | UnresolvedSet<2> PlausibleOverloads; |
1965 | for (OverloadExpr::decls_iterator It = Overloads.begin(), |
1966 | DeclsEnd = Overloads.end(); It != DeclsEnd; ++It) { |
1967 | const FunctionDecl *OverloadDecl = cast<FunctionDecl>(*It); |
1968 | QualType OverloadResultTy = OverloadDecl->getReturnType(); |
1969 | if (IsPlausibleResult(OverloadResultTy)) |
1970 | PlausibleOverloads.addDecl(It.getDecl()); |
1971 | } |
1972 | noteOverloads(S, PlausibleOverloads, Loc); |
1973 | } |
1974 | |
1975 | |
1976 | |
1977 | |
1978 | |
1979 | static bool IsCallableWithAppend(Expr *E) { |
1980 | E = E->IgnoreImplicit(); |
1981 | return (!isa<CStyleCastExpr>(E) && |
1982 | !isa<UnaryOperator>(E) && |
1983 | !isa<BinaryOperator>(E) && |
1984 | !isa<CXXOperatorCallExpr>(E)); |
1985 | } |
1986 | |
1987 | static bool IsCPUDispatchCPUSpecificMultiVersion(const Expr *E) { |
1988 | if (const auto *UO = dyn_cast<UnaryOperator>(E)) |
1989 | E = UO->getSubExpr(); |
1990 | |
1991 | if (const auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) { |
1992 | if (ULE->getNumDecls() == 0) |
1993 | return false; |
1994 | |
1995 | const NamedDecl *ND = *ULE->decls_begin(); |
1996 | if (const auto *FD = dyn_cast<FunctionDecl>(ND)) |
1997 | return FD->isCPUDispatchMultiVersion() || FD->isCPUSpecificMultiVersion(); |
1998 | } |
1999 | return false; |
2000 | } |
2001 | |
2002 | bool Sema::tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD, |
2003 | bool ForceComplain, |
2004 | bool (*IsPlausibleResult)(QualType)) { |
2005 | SourceLocation Loc = E.get()->getExprLoc(); |
2006 | SourceRange Range = E.get()->getSourceRange(); |
2007 | |
2008 | QualType ZeroArgCallTy; |
2009 | UnresolvedSet<4> Overloads; |
2010 | if (tryExprAsCall(*E.get(), ZeroArgCallTy, Overloads) && |
2011 | !ZeroArgCallTy.isNull() && |
2012 | (!IsPlausibleResult || IsPlausibleResult(ZeroArgCallTy))) { |
2013 | |
2014 | |
2015 | |
2016 | |
2017 | SourceLocation ParenInsertionLoc = getLocForEndOfToken(Range.getEnd()); |
2018 | bool IsMV = IsCPUDispatchCPUSpecificMultiVersion(E.get()); |
2019 | Diag(Loc, PD) << 1 << IsMV << Range |
2020 | << (IsCallableWithAppend(E.get()) |
2021 | ? FixItHint::CreateInsertion(ParenInsertionLoc, "()") |
2022 | : FixItHint()); |
2023 | if (!IsMV) |
2024 | notePlausibleOverloads(*this, Loc, Overloads, IsPlausibleResult); |
2025 | |
2026 | |
2027 | |
2028 | E = ActOnCallExpr(nullptr, E.get(), Range.getEnd(), None, |
2029 | Range.getEnd().getLocWithOffset(1)); |
2030 | return true; |
2031 | } |
2032 | |
2033 | if (!ForceComplain) return false; |
2034 | |
2035 | bool IsMV = IsCPUDispatchCPUSpecificMultiVersion(E.get()); |
2036 | Diag(Loc, PD) << 0 << IsMV << Range; |
2037 | if (!IsMV) |
2038 | notePlausibleOverloads(*this, Loc, Overloads, IsPlausibleResult); |
2039 | E = ExprError(); |
2040 | return true; |
2041 | } |
2042 | |
2043 | IdentifierInfo *Sema::getSuperIdentifier() const { |
2044 | if (!Ident_super) |
2045 | Ident_super = &Context.Idents.get("super"); |
2046 | return Ident_super; |
2047 | } |
2048 | |
2049 | IdentifierInfo *Sema::getFloat128Identifier() const { |
2050 | if (!Ident___float128) |
2051 | Ident___float128 = &Context.Idents.get("__float128"); |
2052 | return Ident___float128; |
2053 | } |
2054 | |
2055 | void Sema::PushCapturedRegionScope(Scope *S, CapturedDecl *CD, RecordDecl *RD, |
2056 | CapturedRegionKind K) { |
2057 | CapturingScopeInfo *CSI = new CapturedRegionScopeInfo( |
2058 | getDiagnostics(), S, CD, RD, CD->getContextParam(), K, |
2059 | (getLangOpts().OpenMP && K == CR_OpenMP) ? getOpenMPNestingLevel() : 0); |
2060 | CSI->ReturnType = Context.VoidTy; |
2061 | FunctionScopes.push_back(CSI); |
2062 | } |
2063 | |
2064 | CapturedRegionScopeInfo *Sema::getCurCapturedRegion() { |
2065 | if (FunctionScopes.empty()) |
2066 | return nullptr; |
2067 | |
2068 | return dyn_cast<CapturedRegionScopeInfo>(FunctionScopes.back()); |
2069 | } |
2070 | |
2071 | const llvm::MapVector<FieldDecl *, Sema::DeleteLocs> & |
2072 | Sema::getMismatchingDeleteExpressions() const { |
2073 | return DeleteExprs; |
2074 | } |
2075 | |
2076 | void Sema::setOpenCLExtensionForType(QualType T, llvm::StringRef ExtStr) { |
2077 | if (ExtStr.empty()) |
2078 | return; |
2079 | llvm::SmallVector<StringRef, 1> Exts; |
2080 | ExtStr.split(Exts, " ", -1, false); |
2081 | auto CanT = T.getCanonicalType().getTypePtr(); |
2082 | for (auto &I : Exts) |
2083 | OpenCLTypeExtMap[CanT].insert(I.str()); |
2084 | } |
2085 | |
2086 | void Sema::setOpenCLExtensionForDecl(Decl *FD, StringRef ExtStr) { |
2087 | llvm::SmallVector<StringRef, 1> Exts; |
2088 | ExtStr.split(Exts, " ", -1, false); |
2089 | if (Exts.empty()) |
2090 | return; |
2091 | for (auto &I : Exts) |
2092 | OpenCLDeclExtMap[FD].insert(I.str()); |
2093 | } |
2094 | |
2095 | void Sema::setCurrentOpenCLExtensionForType(QualType T) { |
2096 | if (CurrOpenCLExtension.empty()) |
2097 | return; |
2098 | setOpenCLExtensionForType(T, CurrOpenCLExtension); |
2099 | } |
2100 | |
2101 | void Sema::setCurrentOpenCLExtensionForDecl(Decl *D) { |
2102 | if (CurrOpenCLExtension.empty()) |
2103 | return; |
2104 | setOpenCLExtensionForDecl(D, CurrOpenCLExtension); |
2105 | } |
2106 | |
2107 | std::string Sema::getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD) { |
2108 | if (!OpenCLDeclExtMap.empty()) |
2109 | return getOpenCLExtensionsFromExtMap(FD, OpenCLDeclExtMap); |
2110 | |
2111 | return ""; |
2112 | } |
2113 | |
2114 | std::string Sema::getOpenCLExtensionsFromTypeExtMap(FunctionType *FT) { |
2115 | if (!OpenCLTypeExtMap.empty()) |
2116 | return getOpenCLExtensionsFromExtMap(FT, OpenCLTypeExtMap); |
2117 | |
2118 | return ""; |
2119 | } |
2120 | |
2121 | template <typename T, typename MapT> |
2122 | std::string Sema::getOpenCLExtensionsFromExtMap(T *FDT, MapT &Map) { |
2123 | std::string ExtensionNames = ""; |
2124 | auto Loc = Map.find(FDT); |
2125 | |
2126 | for (auto const& I : Loc->second) { |
2127 | ExtensionNames += I; |
2128 | ExtensionNames += " "; |
2129 | } |
2130 | ExtensionNames.pop_back(); |
2131 | |
2132 | return ExtensionNames; |
2133 | } |
2134 | |
2135 | bool Sema::isOpenCLDisabledDecl(Decl *FD) { |
2136 | auto Loc = OpenCLDeclExtMap.find(FD); |
2137 | if (Loc == OpenCLDeclExtMap.end()) |
2138 | return false; |
2139 | for (auto &I : Loc->second) { |
2140 | if (!getOpenCLOptions().isEnabled(I)) |
2141 | return true; |
2142 | } |
2143 | return false; |
2144 | } |
2145 | |
2146 | template <typename T, typename DiagLocT, typename DiagInfoT, typename MapT> |
2147 | bool Sema::checkOpenCLDisabledTypeOrDecl(T D, DiagLocT DiagLoc, |
2148 | DiagInfoT DiagInfo, MapT &Map, |
2149 | unsigned Selector, |
2150 | SourceRange SrcRange) { |
2151 | auto Loc = Map.find(D); |
2152 | if (Loc == Map.end()) |
2153 | return false; |
2154 | bool Disabled = false; |
2155 | for (auto &I : Loc->second) { |
2156 | if (I != CurrOpenCLExtension && !getOpenCLOptions().isEnabled(I)) { |
2157 | Diag(DiagLoc, diag::err_opencl_requires_extension) << Selector << DiagInfo |
2158 | << I << SrcRange; |
2159 | Disabled = true; |
2160 | } |
2161 | } |
2162 | return Disabled; |
2163 | } |
2164 | |
2165 | bool Sema::checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType QT) { |
2166 | |
2167 | Decl *Decl = nullptr; |
2168 | if (auto TypedefT = dyn_cast<TypedefType>(QT.getTypePtr())) |
2169 | Decl = TypedefT->getDecl(); |
2170 | if (auto TagT = dyn_cast<TagType>(QT.getCanonicalType().getTypePtr())) |
2171 | Decl = TagT->getDecl(); |
2172 | auto Loc = DS.getTypeSpecTypeLoc(); |
2173 | |
2174 | |
2175 | |
2176 | if (QT->isExtVectorType()) { |
2177 | auto TypePtr = QT->castAs<ExtVectorType>()->getElementType().getTypePtr(); |
2178 | return checkOpenCLDisabledTypeOrDecl(TypePtr, Loc, QT, OpenCLTypeExtMap); |
2179 | } |
2180 | |
2181 | if (checkOpenCLDisabledTypeOrDecl(Decl, Loc, QT, OpenCLDeclExtMap)) |
2182 | return true; |
2183 | |
2184 | |
2185 | return checkOpenCLDisabledTypeOrDecl(QT.getCanonicalType().getTypePtr(), Loc, |
2186 | QT, OpenCLTypeExtMap); |
2187 | } |
2188 | |
2189 | bool Sema::checkOpenCLDisabledDecl(const NamedDecl &D, const Expr &E) { |
2190 | IdentifierInfo *FnName = D.getIdentifier(); |
2191 | return checkOpenCLDisabledTypeOrDecl(&D, E.getBeginLoc(), FnName, |
2192 | OpenCLDeclExtMap, 1, D.getSourceRange()); |
2193 | } |
2194 | |