diff options
-rw-r--r-- | include/clang/AST/ASTContext.h | 9 | ||||
-rw-r--r-- | include/clang/Basic/PartialDiagnostic.h | 110 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 2 | ||||
-rw-r--r-- | lib/Basic/Diagnostic.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 32 | ||||
-rw-r--r-- | lib/Sema/SemaAccess.cpp | 27 | ||||
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 19 | ||||
-rw-r--r-- | lib/Sema/SemaExceptionSpec.cpp | 24 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 12 |
14 files changed, 202 insertions, 86 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 79988e6148..22aec7f5be 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -17,6 +17,7 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/PartialDiagnostic.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/NestedNameSpecifier.h" @@ -265,6 +266,9 @@ class ASTContext { llvm::MallocAllocator MallocAlloc; llvm::BumpPtrAllocator BumpAlloc; + /// \brief Allocator for partial diagnostics. + PartialDiagnostic::StorageAllocator DiagAllocator; + public: const TargetInfo &Target; IdentifierTable &Idents; @@ -290,6 +294,11 @@ public: if (FreeMemory) MallocAlloc.Deallocate(Ptr); } + + PartialDiagnostic::StorageAllocator &getDiagAllocator() { + return DiagAllocator; + } + const LangOptions& getLangOptions() const { return LangOpts; } FullSourceLoc getFullLoc(SourceLocation Loc) const { diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h index fb861dcf93..56082b7b09 100644 --- a/include/clang/Basic/PartialDiagnostic.h +++ b/include/clang/Basic/PartialDiagnostic.h @@ -69,6 +69,43 @@ class PartialDiagnostic { CodeModificationHint CodeModificationHints[MaxCodeModificationHints]; }; +public: + /// \brief An allocator for Storage objects, which uses a small cache to + /// objects, used to reduce malloc()/free() traffic for partial diagnostics. + class StorageAllocator { + static const unsigned NumCached = 4; + Storage Cached[NumCached]; + Storage *FreeList[NumCached]; + unsigned NumFreeListEntries; + + public: + StorageAllocator(); + ~StorageAllocator(); + + /// \brief Allocate new storage. + Storage *Allocate() { + if (NumFreeListEntries == 0) + return new Storage; + + Storage *Result = FreeList[--NumFreeListEntries]; + Result->NumDiagArgs = 0; + Result->NumDiagRanges = 0; + Result->NumCodeModificationHints = 0; + return Result; + } + + /// \brief Free the given storage object. + void Deallocate(Storage *S) { + if (S >= Cached && S <= Cached + NumCached) { + FreeList[NumFreeListEntries++] = S; + return; + } + + delete S; + } + }; + +private: // NOTE: Sema assumes that PartialDiagnostic is location-invariant // in the sense that its bits can be safely memcpy'ed and destructed // in the new location. @@ -76,12 +113,38 @@ class PartialDiagnostic { /// DiagID - The diagnostic ID. mutable unsigned DiagID; - /// DiagStorare - Storge for args and ranges. + /// DiagStorage - Storage for args and ranges. mutable Storage *DiagStorage; + /// \brief Allocator used to allocate storage for this diagnostic. + StorageAllocator *Allocator; + + /// \brief Retrieve storage for this particular diagnostic. + Storage *getStorage() const { + if (DiagStorage) + return DiagStorage; + + if (Allocator) + DiagStorage = Allocator->Allocate(); + else + DiagStorage = new Storage; + return DiagStorage; + } + + void freeStorage() { + if (!DiagStorage) + return; + + if (Allocator) + Allocator->Deallocate(DiagStorage); + else + delete DiagStorage; + DiagStorage = 0; + } + void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const { if (!DiagStorage) - DiagStorage = new Storage; + DiagStorage = getStorage(); assert(DiagStorage->NumDiagArgs < Storage::MaxArguments && "Too many arguments to diagnostic!"); @@ -91,7 +154,7 @@ class PartialDiagnostic { void AddSourceRange(const SourceRange &R) const { if (!DiagStorage) - DiagStorage = new Storage; + DiagStorage = getStorage(); assert(DiagStorage->NumDiagRanges < llvm::array_lengthof(DiagStorage->DiagRanges) && @@ -104,7 +167,7 @@ class PartialDiagnostic { return; if (!DiagStorage) - DiagStorage = new Storage; + DiagStorage = getStorage(); assert(DiagStorage->NumCodeModificationHints < Storage::MaxCodeModificationHints && @@ -114,36 +177,36 @@ class PartialDiagnostic { } public: - PartialDiagnostic(unsigned DiagID) - : DiagID(DiagID), DiagStorage(0) { } - + PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator) + : DiagID(DiagID), DiagStorage(0), Allocator(&Allocator) { } + PartialDiagnostic(const PartialDiagnostic &Other) - : DiagID(Other.DiagID), DiagStorage(0) + : DiagID(Other.DiagID), DiagStorage(0), Allocator(Other.Allocator) { - if (Other.DiagStorage) - DiagStorage = new Storage(*Other.DiagStorage); + if (Other.DiagStorage) { + DiagStorage = getStorage(); + *DiagStorage = *Other.DiagStorage; + } } PartialDiagnostic &operator=(const PartialDiagnostic &Other) { DiagID = Other.DiagID; if (Other.DiagStorage) { - if (DiagStorage) - *DiagStorage = *Other.DiagStorage; - else - DiagStorage = new Storage(*Other.DiagStorage); + if (!DiagStorage) + DiagStorage = getStorage(); + + *DiagStorage = *Other.DiagStorage; } else { - delete DiagStorage; - DiagStorage = 0; + freeStorage(); } return *this; } ~PartialDiagnostic() { - delete DiagStorage; + freeStorage(); } - unsigned getDiagID() const { return DiagID; } void Emit(const DiagnosticBuilder &DB) const { @@ -165,6 +228,13 @@ public: DB.AddCodeModificationHint(DiagStorage->CodeModificationHints[i]); } + /// \brief Clear out this partial diagnostic, giving it a new diagnostic ID + /// and removing all of its arguments, ranges, and fix-it hints. + void Reset(unsigned DiagID = 0) { + this->DiagID = DiagID; + freeStorage(); + } + friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, QualType T) { PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()), @@ -207,10 +277,6 @@ public: }; -inline PartialDiagnostic PDiag(unsigned DiagID = 0) { - return PartialDiagnostic(DiagID); -} - inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const PartialDiagnostic &PD) { PD.Emit(DB); diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 9e92855681..cb6b76c248 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -1017,6 +1017,8 @@ DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C, DependentStoredDeclsMap *Map = static_cast<DependentStoredDeclsMap*>(Parent->LookupPtr); + // FIXME: Allocate the copy of the PartialDiagnostic via the ASTContext's + // BumpPtrAllocator, rather than the ASTContext itself. DependentDiagnostic *DD = new (C) DependentDiagnostic(PDiag); // TODO: Maybe we shouldn't reverse the order during insertion. diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index 21a8aeae42..9b8bae3142 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/PartialDiagnostic.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Parse/ParseDiagnostic.h" @@ -1246,3 +1247,13 @@ StoredDiagnostic::Deserialize(FileManager &FM, SourceManager &SM, /// DiagnosticClient should be included in the number of diagnostics /// reported by Diagnostic. bool DiagnosticClient::IncludeInDiagnosticCounts() const { return true; } + +PartialDiagnostic::StorageAllocator::StorageAllocator() { + for (unsigned I = 0; I != NumCached; ++I) + FreeList[I] = Cached + I; + NumFreeListEntries = NumCached; +} + +PartialDiagnostic::StorageAllocator::~StorageAllocator() { + assert(NumFreeListEntries == NumCached && "A partial is on the lamb"); +} diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 9c661ba1b1..859e497576 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -312,30 +312,33 @@ public: bool isMemberAccess() const { return IsMember; } - AccessedEntity(MemberNonce _, + AccessedEntity(ASTContext &Context, + MemberNonce _, CXXRecordDecl *NamingClass, AccessSpecifier Access, NamedDecl *Target) : Access(Access), IsMember(true), Target(Target), NamingClass(NamingClass), - Diag(0) { + Diag(0, Context.getDiagAllocator()) { } - AccessedEntity(MemberNonce _, + AccessedEntity(ASTContext &Context, + MemberNonce _, CXXRecordDecl *NamingClass, DeclAccessPair FoundDecl) : Access(FoundDecl.getAccess()), IsMember(true), Target(FoundDecl.getDecl()), NamingClass(NamingClass), - Diag(0) { + Diag(0, Context.getDiagAllocator()) { } - AccessedEntity(BaseNonce _, + AccessedEntity(ASTContext &Context, + BaseNonce _, CXXRecordDecl *BaseClass, CXXRecordDecl *DerivedClass, AccessSpecifier Access) : Access(Access), IsMember(false), Target(BaseClass), NamingClass(DerivedClass), - Diag(0) { + Diag(0, Context.getDiagAllocator()) { } bool isQuiet() const { return Diag.getDiagID() == 0; } @@ -363,7 +366,7 @@ public: PartialDiagnostic &setDiag(unsigned DiagID) { assert(isQuiet() && "partial diagnostic already defined"); assert(DiagID && "creating null diagnostic"); - Diag = PartialDiagnostic(DiagID); + Diag.Reset(DiagID); return Diag; } const PartialDiagnostic &getDiag() const { @@ -615,6 +618,11 @@ public: /// \brief Emit a partial diagnostic. SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD); + /// \brief Build a partial diagnostic. + PartialDiagnostic PDiag(unsigned DiagID = 0) { + return PartialDiagnostic(DiagID, Context.getDiagAllocator()); + } + virtual void DeleteExpr(ExprTy *E); virtual void DeleteStmt(StmtTy *S); @@ -732,10 +740,12 @@ public: bool RequireCompleteType(SourceLocation Loc, QualType T, const PartialDiagnostic &PD, - std::pair<SourceLocation, - PartialDiagnostic> Note = - std::make_pair(SourceLocation(), PDiag())); - + std::pair<SourceLocation, PartialDiagnostic> Note); + bool RequireCompleteType(SourceLocation Loc, QualType T, + const PartialDiagnostic &PD); + bool RequireCompleteType(SourceLocation Loc, QualType T, + unsigned DiagID); + QualType getQualifiedNameType(const CXXScopeSpec &SS, QualType T); QualType BuildTypeofExprType(Expr *E); diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 9ceb17cd0f..e7ea204137 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -768,14 +768,16 @@ void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD, if (!TargetD) return; if (DD.isAccessToMember()) { - AccessedEntity Entity(AccessedEntity::Member, + AccessedEntity Entity(Context, + AccessedEntity::Member, cast<CXXRecordDecl>(NamingD), Access, cast<NamedDecl>(TargetD)); Entity.setDiag(DD.getDiagnostic()); CheckAccess(*this, Loc, Entity); } else { - AccessedEntity Entity(AccessedEntity::Base, + AccessedEntity Entity(Context, + AccessedEntity::Base, cast<CXXRecordDecl>(TargetD), cast<CXXRecordDecl>(NamingD), Access); @@ -791,7 +793,8 @@ Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, Found.getAccess() == AS_public) return AR_accessible; - AccessedEntity Entity(AccessedEntity::Member, E->getNamingClass(), Found); + AccessedEntity Entity(Context, AccessedEntity::Member, E->getNamingClass(), + Found); Entity.setDiag(diag::err_access) << E->getSourceRange(); return CheckAccess(*this, E->getNameLoc(), Entity); @@ -805,7 +808,8 @@ Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, Found.getAccess() == AS_public) return AR_accessible; - AccessedEntity Entity(AccessedEntity::Member, E->getNamingClass(), Found); + AccessedEntity Entity(Context, AccessedEntity::Member, E->getNamingClass(), + Found); Entity.setDiag(diag::err_access) << E->getSourceRange(); return CheckAccess(*this, E->getMemberLoc(), Entity); @@ -823,7 +827,7 @@ Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc, return AR_accessible; CXXRecordDecl *NamingClass = Dtor->getParent(); - AccessedEntity Entity(AccessedEntity::Member, NamingClass, + AccessedEntity Entity(Context, AccessedEntity::Member, NamingClass, DeclAccessPair::make(Dtor, Access)); Entity.setDiag(PDiag); // TODO: avoid copy @@ -839,7 +843,7 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, return AR_accessible; CXXRecordDecl *NamingClass = Constructor->getParent(); - AccessedEntity Entity(AccessedEntity::Member, NamingClass, + AccessedEntity Entity(Context, AccessedEntity::Member, NamingClass, DeclAccessPair::make(Constructor, Access)); Entity.setDiag(diag::err_access_ctor); @@ -857,7 +861,7 @@ Sema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc, return AR_accessible; CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Target->getDeclContext()); - AccessedEntity Entity(AccessedEntity::Member, NamingClass, + AccessedEntity Entity(Context, AccessedEntity::Member, NamingClass, DeclAccessPair::make(Target, Access)); Entity.setDiag(Diag); return CheckAccess(*this, UseLoc, Entity); @@ -874,7 +878,7 @@ Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc, Found.getAccess() == AS_public) return AR_accessible; - AccessedEntity Entity(AccessedEntity::Member, NamingClass, Found); + AccessedEntity Entity(Context, AccessedEntity::Member, NamingClass, Found); Entity.setDiag(diag::err_access) << PlacementRange; @@ -895,7 +899,7 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, assert(RT && "found member operator but object expr not of record type"); CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl()); - AccessedEntity Entity(AccessedEntity::Member, NamingClass, Found); + AccessedEntity Entity(Context, AccessedEntity::Member, NamingClass, Found); Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange()); @@ -929,7 +933,8 @@ Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc, BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl()); DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl()); - AccessedEntity Entity(AccessedEntity::Base, BaseD, DerivedD, Path.Access); + AccessedEntity Entity(Context, AccessedEntity::Base, BaseD, DerivedD, + Path.Access); if (DiagID) Entity.setDiag(DiagID) << Derived << Base; @@ -946,7 +951,7 @@ void Sema::CheckLookupAccess(const LookupResult &R) { for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { if (I.getAccess() != AS_public) { - AccessedEntity Entity(AccessedEntity::Member, + AccessedEntity Entity(Context, AccessedEntity::Member, R.getNamingClass(), I.getPair()); Entity.setDiag(diag::err_access); diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 285ee4945d..2b93d38e2a 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -315,7 +315,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, assert(DestPointer && "Reference to void is not possible"); } else if (DestRecord) { if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee, - PDiag(diag::err_bad_dynamic_cast_incomplete) + Self.PDiag(diag::err_bad_dynamic_cast_incomplete) << DestRange)) return; } else { @@ -353,7 +353,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, const RecordType *SrcRecord = SrcPointee->getAs<RecordType>(); if (SrcRecord) { if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee, - PDiag(diag::err_bad_dynamic_cast_incomplete) + Self.PDiag(diag::err_bad_dynamic_cast_incomplete) << SrcExpr->getSourceRange())) return; } else { @@ -698,8 +698,8 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, QualType OrigDestType, unsigned &msg, CastExpr::CastKind &Kind) { // We can only work with complete types. But don't complain if it doesn't work - if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, PDiag(0)) || - Self.RequireCompleteType(OpRange.getBegin(), DestType, PDiag(0))) + if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, Self.PDiag(0)) || + Self.RequireCompleteType(OpRange.getBegin(), DestType, Self.PDiag(0))) return TC_NotApplicable; // Downcast can only happen in class hierarchies, so we need classes. diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index a7671a2cf8..efd34f93c9 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1865,7 +1865,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location, CXXDestructorDecl *Dtor = FieldClassDecl->getDestructor(Context); CheckDestructorAccess(Field->getLocation(), Dtor, - PartialDiagnostic(diag::err_access_dtor_field) + PDiag(diag::err_access_dtor_field) << Field->getDeclName() << FieldType); @@ -1893,7 +1893,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location, // FIXME: caret should be on the start of the class name CheckDestructorAccess(Base->getSourceRange().getBegin(), Dtor, - PartialDiagnostic(diag::err_access_dtor_base) + PDiag(diag::err_access_dtor_base) << Base->getType() << Base->getSourceRange()); @@ -1918,7 +1918,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location, CXXDestructorDecl *Dtor = BaseClassDecl->getDestructor(Context); CheckDestructorAccess(ClassDecl->getLocation(), Dtor, - PartialDiagnostic(diag::err_access_dtor_vbase) + PDiag(diag::err_access_dtor_vbase) << VBase->getType()); MarkDeclarationReferenced(Location, const_cast<CXXDestructorDecl*>(Dtor)); @@ -1939,9 +1939,6 @@ void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) { bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID, AbstractDiagSelID SelID, const CXXRecordDecl *CurrentRD) { - if (!getLangOptions().CPlusPlus) - return false; - if (SelID == -1) return RequireNonAbstractType(Loc, T, PDiag(DiagID), CurrentRD); @@ -3851,7 +3848,7 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation, BaseClassDecl)) { CheckDirectMemberAccess(Base->getSourceRange().getBegin(), BaseAssignOpMethod, - PartialDiagnostic(diag::err_access_assign_base) + PDiag(diag::err_access_assign_base) << Base->getType()); MarkDeclarationReferenced(CurrentLocation, BaseAssignOpMethod); @@ -3870,7 +3867,7 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation, FieldClassDecl)) { CheckDirectMemberAccess(Field->getLocation(), FieldAssignOpMethod, - PartialDiagnostic(diag::err_access_assign_field) + PDiag(diag::err_access_assign_field) << Field->getDeclName() << Field->getType()); MarkDeclarationReferenced(CurrentLocation, FieldAssignOpMethod); @@ -3952,7 +3949,7 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, BaseClassDecl->getCopyConstructor(Context, TypeQuals)) { CheckDirectMemberAccess(Base->getSourceRange().getBegin(), BaseCopyCtor, - PartialDiagnostic(diag::err_access_copy_base) + PDiag(diag::err_access_copy_base) << Base->getType()); MarkDeclarationReferenced(CurrentLocation, BaseCopyCtor); @@ -3971,7 +3968,7 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, FieldClassDecl->getCopyConstructor(Context, TypeQuals)) { CheckDirectMemberAccess(Field->getLocation(), FieldCopyCtor, - PartialDiagnostic(diag::err_access_copy_field) + PDiag(diag::err_access_copy_field) << Field->getDeclName() << Field->getType()); MarkDeclarationReferenced(CurrentLocation, FieldCopyCtor); @@ -4066,7 +4063,7 @@ void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) { CXXDestructorDecl *Destructor = ClassDecl->getDestructor(Context); MarkDeclarationReferenced(VD->getLocation(), Destructor); CheckDestructorAccess(VD->getLocation(), Destructor, - PartialDiagnostic(diag::err_access_dtor_var) + PDiag(diag::err_access_dtor_var) << VD->getDeclName() << VD->getType()); } diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp index 5767551c53..eae30dc972 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/lib/Sema/SemaExceptionSpec.cpp @@ -98,8 +98,8 @@ bool Sema::CheckDistantExceptionSpec(QualType T) { bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { bool MissingExceptionSpecification = false; bool MissingEmptyExceptionSpecification = false; - if (!CheckEquivalentExceptionSpec(diag::err_mismatched_exception_spec, - diag::note_previous_declaration, + if (!CheckEquivalentExceptionSpec(PDiag(diag::err_mismatched_exception_spec), + PDiag(diag::note_previous_declaration), Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(), New->getType()->getAs<FunctionProtoType>(), @@ -234,8 +234,9 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { bool Sema::CheckEquivalentExceptionSpec( const FunctionProtoType *Old, SourceLocation OldLoc, const FunctionProtoType *New, SourceLocation NewLoc) { - return CheckEquivalentExceptionSpec(diag::err_mismatched_exception_spec, - diag::note_previous_declaration, + return CheckEquivalentExceptionSpec( + PDiag(diag::err_mismatched_exception_spec), + PDiag(diag::note_previous_declaration), Old, OldLoc, New, NewLoc); } @@ -451,7 +452,8 @@ bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID, const FunctionProtoType *Source, SourceLocation SourceLoc) { if (CheckSpecForTypesEquivalent(*this, - PDiag(diag::err_deep_exception_specs_differ) << 0, 0, + PDiag(diag::err_deep_exception_specs_differ) << 0, + PDiag(), Target->getResultType(), TargetLoc, Source->getResultType(), SourceLoc)) return true; @@ -462,7 +464,8 @@ bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID, "Functions have different argument counts."); for (unsigned i = 0, E = Target->getNumArgs(); i != E; ++i) { if (CheckSpecForTypesEquivalent(*this, - PDiag(diag::err_deep_exception_specs_differ) << 1, 0, + PDiag(diag::err_deep_exception_specs_differ) << 1, + PDiag(), Target->getArgType(i), TargetLoc, Source->getArgType(i), SourceLoc)) return true; @@ -487,15 +490,16 @@ bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) // This means that the source of the conversion can only throw a subset of // the exceptions of the target, and any exception specs on arguments or // return types must be equivalent. - return CheckExceptionSpecSubset(diag::err_incompatible_exception_specs, - 0, ToFunc, From->getSourceRange().getBegin(), + return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs), + PDiag(), ToFunc, + From->getSourceRange().getBegin(), FromFunc, SourceLocation()); } bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, const CXXMethodDecl *Old) { - return CheckExceptionSpecSubset(diag::err_override_exception_spec, - diag::note_overridden_virtual_function, + return CheckExceptionSpecSubset(PDiag(diag::err_override_exception_spec), + PDiag(diag::note_overridden_virtual_function), Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(), New->getType()->getAs<FunctionProtoType>(), diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 9dddc2093a..4bf26a5224 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2520,7 +2520,7 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, SourceLocation OpLoc, const CXXScopeSpec &SS) { RecordDecl *RDecl = RTy->getDecl(); if (SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0), - PDiag(diag::err_typecheck_incomplete_tag) + SemaRef.PDiag(diag::err_typecheck_incomplete_tag) << BaseRange)) return true; @@ -5785,7 +5785,7 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { case Expr::MLV_IncompleteType: case Expr::MLV_IncompleteVoidType: return S.RequireCompleteType(Loc, E->getType(), - PDiag(diag::err_typecheck_incomplete_type_not_modifiable_lvalue) + S.PDiag(diag::err_typecheck_incomplete_type_not_modifiable_lvalue) << E->getSourceRange()); case Expr::MLV_DuplicateVectorComponents: Diag = diag::err_typecheck_duplicate_vector_components_not_mlvalue; @@ -6347,8 +6347,8 @@ Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, static void SuggestParentheses(Sema &Self, SourceLocation Loc, const PartialDiagnostic &PD, SourceRange ParenRange, - const PartialDiagnostic &SecondPD = PartialDiagnostic(0), - SourceRange SecondParenRange = SourceRange()) { + const PartialDiagnostic &SecondPD, + SourceRange SecondParenRange) { SourceLocation EndLoc = Self.PP.getLocForEndOfToken(ParenRange.getEnd()); if (!ParenRange.getEnd().isFileID() || EndLoc.isInvalid()) { // We can't display the parentheses, so just dig the @@ -6403,20 +6403,20 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc, if (BinOp::isComparisonOp(lhsopc)) SuggestParentheses(Self, OpLoc, - PDiag(diag::warn_precedence_bitwise_rel) + Self.PDiag(diag::warn_precedence_bitwise_rel) << SourceRange(lhs->getLocStart(), OpLoc) << BinOp::getOpcodeStr(Opc) << BinOp::getOpcodeStr(lhsopc), lhs->getSourceRange(), - PDiag(diag::note_precedence_bitwise_first) + Self.PDiag(diag::note_precedence_bitwise_first) << BinOp::getOpcodeStr(Opc), SourceRange(cast<BinOp>(lhs)->getRHS()->getLocStart(), rhs->getLocEnd())); else if (BinOp::isComparisonOp(rhsopc)) SuggestParentheses(Self, OpLoc, - PDiag(diag::warn_precedence_bitwise_rel) + Self.PDiag(diag::warn_precedence_bitwise_rel) << SourceRange(OpLoc, rhs->getLocEnd()) << BinOp::getOpcodeStr(Opc) << BinOp::getOpcodeStr(rhsopc), rhs->getSourceRange(), - PDiag(diag::note_precedence_bitwise_first) + Self.PDiag(diag::note_precedence_bitwise_first) << BinOp::getOpcodeStr(Opc), SourceRange(lhs->getLocEnd(), cast<BinOp>(rhs)->getLHS()->getLocStart())); } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index bb67a75972..58d7d67508 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -4695,7 +4695,7 @@ void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc, if (!ICS.isAmbiguous()) continue; S.DiagnoseAmbiguousConversion(ICS, OpLoc, - PDiag(diag::note_ambiguous_type_conversion)); + S.PDiag(diag::note_ambiguous_type_conversion)); } } @@ -6135,7 +6135,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call); if (RequireCompleteType(LParenLoc, Object->getType(), - PartialDiagnostic(diag::err_incomplete_object_call) + PDiag(diag::err_incomplete_object_call) << Object->getSourceRange())) return true; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index fd65c32c20..733022aac3 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -427,7 +427,7 @@ static bool CheckCXXSwitchCondition(Sema &S, SourceLocation SwitchLoc, // Make sure that the condition expression has a complete type, // otherwise we'll never find any conversions. if (S.RequireCompleteType(SwitchLoc, CondType, - PDiag(diag::err_switch_incomplete_class_type) + S.PDiag(diag::err_switch_incomplete_class_type) << CondExpr->getSourceRange())) return true; diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 08329e8996..d1f0815eae 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4067,11 +4067,11 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, UnresolvedSetIterator Result = getMostSpecialized(Candidates.begin(), Candidates.end(), TPOC_Other, FD->getLocation(), - PartialDiagnostic(diag::err_function_template_spec_no_match) + PDiag(diag::err_function_template_spec_no_match) << FD->getDeclName(), - PartialDiagnostic(diag::err_function_template_spec_ambiguous) + PDiag(diag::err_function_template_spec_ambiguous) << FD->getDeclName() << (ExplicitTemplateArgs != 0), - PartialDiagnostic(diag::note_function_template_spec_matched)); + PDiag(diag::note_function_template_spec_matched)); if (Result == Candidates.end()) return true; @@ -4834,9 +4834,9 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S, UnresolvedSetIterator Result = getMostSpecialized(Matches.begin(), Matches.end(), TPOC_Other, D.getIdentifierLoc(), - PartialDiagnostic(diag::err_explicit_instantiation_not_known) << Name, - PartialDiagnostic(diag::err_explicit_instantiation_ambiguous) << Name, - PartialDiagnostic(diag::note_explicit_instantiation_candidate)); + PDiag(diag::err_explicit_instantiation_not_known) << Name, + PDiag(diag::err_explicit_instantiation_ambiguous) << Name, + PDiag(diag::note_explicit_instantiation_candidate)); if (Result == Matches.end()) return true; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index c7b1ef15aa..660718f98f 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1973,6 +1973,18 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, return true; } +bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, + const PartialDiagnostic &PD) { + return RequireCompleteType(Loc, T, PD, + std::make_pair(SourceLocation(), PDiag(0))); +} + +bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, + unsigned DiagID) { + return RequireCompleteType(Loc, T, PDiag(DiagID), + std::make_pair(SourceLocation(), PDiag(0))); +} + /// \brief Retrieve a version of the type 'T' that is qualified by the /// nested-name-specifier contained in SS. QualType Sema::getQualifiedNameType(const CXXScopeSpec &SS, QualType T) { |