diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/Sema.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/Sema.cpp | 139 |
1 files changed, 79 insertions, 60 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/Sema.cpp b/contrib/llvm/tools/clang/lib/Sema/Sema.cpp index b9aaf16..18d7e9d 100644 --- a/contrib/llvm/tools/clang/lib/Sema/Sema.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/Sema.cpp @@ -91,18 +91,20 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp), StdInitializerList(nullptr), CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr), - NSNumberDecl(nullptr), + NSNumberDecl(nullptr), NSValueDecl(nullptr), NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr), + ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr), ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr), DictionaryWithObjectsMethod(nullptr), MSAsmLabelNameCounter(0), GlobalNewDeleteDeclared(false), TUKind(TUKind), NumSFINAEErrors(0), + CachedFakeTopLevelModule(nullptr), AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false), NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1), CurrentInstantiationScope(nullptr), DisableTypoCorrection(false), - TyposCorrected(0), AnalysisWarnings(*this), + TyposCorrected(0), AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr), CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr) { @@ -122,9 +124,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, PP.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context); - ExprEvalContexts.push_back( - ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0, - false, nullptr, false)); + ExprEvalContexts.emplace_back(PotentiallyEvaluated, 0, false, nullptr, false); FunctionScopes.push_back(new FunctionScopeInfo(Diags)); @@ -195,8 +195,9 @@ void Sema::Initialize() { } // Initialize Microsoft "predefined C++ types". - if (PP.getLangOpts().MSVCCompat && PP.getLangOpts().CPlusPlus) { - if (IdResolver.begin(&Context.Idents.get("type_info")) == IdResolver.end()) + if (PP.getLangOpts().MSVCCompat) { + if (PP.getLangOpts().CPlusPlus && + IdResolver.begin(&Context.Idents.get("type_info")) == IdResolver.end()) PushOnScopeChains(Context.buildImplicitRecord("type_info", TTK_Class), TUScope); @@ -213,6 +214,29 @@ void Sema::Initialize() { addImplicitTypedef("image3d_t", Context.OCLImage3dTy); addImplicitTypedef("sampler_t", Context.OCLSamplerTy); addImplicitTypedef("event_t", Context.OCLEventTy); + if (getLangOpts().OpenCLVersion >= 200) { + addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy)); + addImplicitTypedef("atomic_uint", + Context.getAtomicType(Context.UnsignedIntTy)); + addImplicitTypedef("atomic_long", Context.getAtomicType(Context.LongTy)); + addImplicitTypedef("atomic_ulong", + Context.getAtomicType(Context.UnsignedLongTy)); + addImplicitTypedef("atomic_float", + Context.getAtomicType(Context.FloatTy)); + addImplicitTypedef("atomic_double", + Context.getAtomicType(Context.DoubleTy)); + // OpenCLC v2.0, s6.13.11.6 requires that atomic_flag is implemented as + // 32-bit integer and OpenCLC v2.0, s6.1.1 int is always 32-bit wide. + addImplicitTypedef("atomic_flag", Context.getAtomicType(Context.IntTy)); + addImplicitTypedef("atomic_intptr_t", + Context.getAtomicType(Context.getIntPtrType())); + addImplicitTypedef("atomic_uintptr_t", + Context.getAtomicType(Context.getUIntPtrType())); + addImplicitTypedef("atomic_size_t", + Context.getAtomicType(Context.getSizeType())); + addImplicitTypedef("atomic_ptrdiff_t", + Context.getAtomicType(Context.getPointerDiffType())); + } } DeclarationName BuiltinVaList = &Context.Idents.get("__builtin_va_list"); @@ -243,6 +267,8 @@ Sema::~Sema() { if (isMultiplexExternalSource) delete ExternalSource; + threadSafety::threadSafetyCleanup(ThreadSafetyDeclCache); + // Destroys data sharing attributes stack for OpenMP DestroyDataSharingAttributesStack(); @@ -331,24 +357,25 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty, assert((VK == VK_RValue || !E->isRValue()) && "can't cast rvalue to lvalue"); #endif + // Check whether we're implicitly casting from a nullable type to a nonnull + // type. + if (auto exprNullability = E->getType()->getNullability(Context)) { + if (*exprNullability == NullabilityKind::Nullable) { + if (auto typeNullability = Ty->getNullability(Context)) { + if (*typeNullability == NullabilityKind::NonNull) { + Diag(E->getLocStart(), diag::warn_nullability_lost) + << E->getType() << Ty; + } + } + } + } + QualType ExprTy = Context.getCanonicalType(E->getType()); QualType TypeTy = Context.getCanonicalType(Ty); if (ExprTy == TypeTy) return E; - // If this is a derived-to-base cast to a through a virtual base, we - // need a vtable. - if (Kind == CK_DerivedToBase && - BasePathInvolvesVirtualBase(*BasePath)) { - QualType T = E->getType(); - if (const PointerType *Pointer = T->getAs<PointerType>()) - T = Pointer->getPointeeType(); - if (const RecordType *RecordTy = T->getAs<RecordType>()) - MarkVTableUsed(E->getLocStart(), - cast<CXXRecordDecl>(RecordTy->getDecl())); - } - if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) { if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) { ImpCast->setType(Ty); @@ -512,14 +539,8 @@ void Sema::LoadExternalWeakUndeclaredIdentifiers() { SmallVector<std::pair<IdentifierInfo *, WeakInfo>, 4> WeakIDs; ExternalSource->ReadWeakUndeclaredIdentifiers(WeakIDs); - for (unsigned I = 0, N = WeakIDs.size(); I != N; ++I) { - llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator Pos - = WeakUndeclaredIdentifiers.find(WeakIDs[I].first); - if (Pos != WeakUndeclaredIdentifiers.end()) - continue; - - WeakUndeclaredIdentifiers.insert(WeakIDs[I]); - } + for (auto &WeakID : WeakIDs) + WeakUndeclaredIdentifiers.insert(WeakID); } @@ -544,10 +565,10 @@ static bool MethodsAndNestedClassesComplete(const CXXRecordDecl *RD, if (const CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(*I)) Complete = M->isDefined() || (M->isPure() && !isa<CXXDestructorDecl>(M)); else if (const FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(*I)) - // If the template function is marked as late template parsed at this point, - // it has not been instantiated and therefore we have not performed semantic - // analysis on it yet, so we cannot know if the type can be considered - // complete. + // If the template function is marked as late template parsed at this + // point, it has not been instantiated and therefore we have not + // performed semantic analysis on it yet, so we cannot know if the type + // can be considered complete. Complete = !F->getTemplatedDecl()->isLateTemplateParsed() && F->getTemplatedDecl()->isDefined(); else if (const CXXRecordDecl *R = dyn_cast<CXXRecordDecl>(*I)) { @@ -632,22 +653,6 @@ void Sema::ActOnEndOfTranslationUnit() { if (TUKind != TU_Prefix) { DiagnoseUseOfUnimplementedSelectors(); - // If any dynamic classes have their key function defined within - // this translation unit, then those vtables are considered "used" and must - // be emitted. - for (DynamicClassesType::iterator I = DynamicClasses.begin(ExternalSource), - E = DynamicClasses.end(); - I != E; ++I) { - assert(!(*I)->isDependentType() && - "Should not see dependent types here!"); - if (const CXXMethodDecl *KeyFunction = - Context.getCurrentKeyFunction(*I)) { - const FunctionDecl *Definition = nullptr; - if (KeyFunction->hasBody(Definition)) - MarkVTableUsed(Definition->getLocation(), *I, true); - } - } - // If DefinedUsedVTables ends up marking any virtual member functions it // might lead to more pending template instantiations, which we then need // to instantiate. @@ -679,6 +684,8 @@ void Sema::ActOnEndOfTranslationUnit() { // All delayed member exception specs should be checked or we end up accepting // incompatible declarations. + // FIXME: This is wrong for TUKind == TU_Prefix. In that case, we need to + // write out the lists to the AST file (if any). assert(DelayedDefaultedMemberExceptionSpecs.empty()); assert(DelayedExceptionSpecChecks.empty()); @@ -696,16 +703,13 @@ void Sema::ActOnEndOfTranslationUnit() { } // Check for #pragma weak identifiers that were never declared - // FIXME: This will cause diagnostics to be emitted in a non-determinstic - // order! Iterating over a densemap like this is bad. LoadExternalWeakUndeclaredIdentifiers(); - for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator - I = WeakUndeclaredIdentifiers.begin(), - E = WeakUndeclaredIdentifiers.end(); I != E; ++I) { - if (I->second.getUsed()) continue; + for (auto WeakID : WeakUndeclaredIdentifiers) { + if (WeakID.second.getUsed()) + continue; - Diag(I->second.getLocation(), diag::warn_weak_identifier_undeclared) - << I->first; + Diag(WeakID.second.getLocation(), diag::warn_weak_identifier_undeclared) + << WeakID.first; } if (LangOpts.CPlusPlus11 && @@ -732,11 +736,7 @@ void Sema::ActOnEndOfTranslationUnit() { ModMap.resolveConflicts(Mod, /*Complain=*/false); // Queue the submodules, so their exports will also be resolved. - for (Module::submodule_iterator Sub = Mod->submodule_begin(), - SubEnd = Mod->submodule_end(); - Sub != SubEnd; ++Sub) { - Stack.push_back(*Sub); - } + Stack.append(Mod->submodule_begin(), Mod->submodule_end()); } } @@ -871,6 +871,17 @@ void Sema::ActOnEndOfTranslationUnit() { } } + if (!Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation())) { + if (ExternalSource) + ExternalSource->ReadMismatchingDeleteExpressions(DeleteExprs); + for (const auto &DeletedFieldInfo : DeleteExprs) { + for (const auto &DeleteExprLoc : DeletedFieldInfo.second) { + AnalyzeDeleteExprMismatch(DeletedFieldInfo.first, DeleteExprLoc.first, + DeleteExprLoc.second); + } + } + } + // Check we've noticed that we're no longer parsing the initializer for every // variable. If we miss cases, then at best we have a performance issue and // at worst a rejects-valid bug. @@ -1230,6 +1241,9 @@ void ExternalSemaSource::ReadUndefinedButUsed( llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) { } +void ExternalSemaSource::ReadMismatchingDeleteExpressions(llvm::MapVector< + FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &) {} + void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const { SourceLocation Loc = this->Loc; if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation(); @@ -1478,3 +1492,8 @@ CapturedRegionScopeInfo *Sema::getCurCapturedRegion() { return dyn_cast<CapturedRegionScopeInfo>(FunctionScopes.back()); } + +const llvm::MapVector<FieldDecl *, Sema::DeleteLocs> & +Sema::getMismatchingDeleteExpressions() const { + return DeleteExprs; +} |