diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-01 10:34:51 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-01 10:34:51 +0000 |
commit | bb1e3bc1e0be2b8f891db46457a8943451bf4d8b (patch) | |
tree | 1e68501209c9133fbda8d45171e59f8d6f12dd55 /lib/Sema/SemaTemplate.cpp | |
parent | 77212133072dc40f070a280af8217032f55a9eb4 (diff) | |
download | FreeBSD-src-bb1e3bc1e0be2b8f891db46457a8943451bf4d8b.zip FreeBSD-src-bb1e3bc1e0be2b8f891db46457a8943451bf4d8b.tar.gz |
Updaet clang to 92395.
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 93 |
1 files changed, 64 insertions, 29 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index ac1b1ec..8c6aa6a 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -102,7 +102,8 @@ TemplateNameKind Sema::isTemplateName(Scope *S, QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr); - LookupResult R(*this, TName, SourceLocation(), LookupOrdinaryName); + LookupResult R(*this, TName, Name.getSourceRange().getBegin(), + LookupOrdinaryName); R.suppressDiagnostics(); LookupTemplateName(R, S, SS, ObjectType, EnteringContext); if (R.empty()) @@ -202,6 +203,29 @@ void Sema::LookupTemplateName(LookupResult &Found, assert(!Found.isAmbiguous() && "Cannot handle template name-lookup ambiguities"); + if (Found.empty()) { + // If we did not find any names, attempt to correct any typos. + DeclarationName Name = Found.getLookupName(); + if (CorrectTypo(Found, S, &SS, LookupCtx)) { + FilterAcceptableTemplateNames(Context, Found); + if (!Found.empty() && isa<TemplateDecl>(*Found.begin())) { + if (LookupCtx) + Diag(Found.getNameLoc(), diag::err_no_member_template_suggest) + << Name << LookupCtx << Found.getLookupName() << SS.getRange() + << CodeModificationHint::CreateReplacement(Found.getNameLoc(), + Found.getLookupName().getAsString()); + else + Diag(Found.getNameLoc(), diag::err_no_template_suggest) + << Name << Found.getLookupName() + << CodeModificationHint::CreateReplacement(Found.getNameLoc(), + Found.getLookupName().getAsString()); + } else + Found.clear(); + } else { + Found.clear(); + } + } + FilterAcceptableTemplateNames(Context, Found); if (Found.empty()) return; @@ -691,7 +715,27 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, if (Previous.begin() != Previous.end()) PrevDecl = *Previous.begin(); - if (PrevDecl && TUK == TUK_Friend) { + // If there is a previous declaration with the same name, check + // whether this is a valid redeclaration. + ClassTemplateDecl *PrevClassTemplate + = dyn_cast_or_null<ClassTemplateDecl>(PrevDecl); + + // We may have found the injected-class-name of a class template, + // class template partial specialization, or class template specialization. + // In these cases, grab the template that is being defined or specialized. + if (!PrevClassTemplate && PrevDecl && isa<CXXRecordDecl>(PrevDecl) && + cast<CXXRecordDecl>(PrevDecl)->isInjectedClassName()) { + PrevDecl = cast<CXXRecordDecl>(PrevDecl->getDeclContext()); + PrevClassTemplate + = cast<CXXRecordDecl>(PrevDecl)->getDescribedClassTemplate(); + if (!PrevClassTemplate && isa<ClassTemplateSpecializationDecl>(PrevDecl)) { + PrevClassTemplate + = cast<ClassTemplateSpecializationDecl>(PrevDecl) + ->getSpecializedTemplate(); + } + } + + if (TUK == TUK_Friend) { // C++ [namespace.memdef]p3: // [...] When looking for a prior declaration of a class or a function // declared as a friend, and when the name of the friend class or @@ -700,15 +744,16 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, DeclContext *OutermostContext = CurContext; while (!OutermostContext->isFileContext()) OutermostContext = OutermostContext->getLookupParent(); - - if (OutermostContext->Equals(PrevDecl->getDeclContext()) || - OutermostContext->Encloses(PrevDecl->getDeclContext())) { + + if (PrevDecl && + (OutermostContext->Equals(PrevDecl->getDeclContext()) || + OutermostContext->Encloses(PrevDecl->getDeclContext()))) { SemanticContext = PrevDecl->getDeclContext(); } else { // Declarations in outer scopes don't matter. However, the outermost // context we computed is the semantic context for our new // declaration. - PrevDecl = 0; + PrevDecl = PrevClassTemplate = 0; SemanticContext = OutermostContext; } @@ -717,30 +762,10 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // class template to the template in scope, because that would perform // checking of the template parameter lists that can't be performed // until the outer context is instantiated. - PrevDecl = 0; + PrevDecl = PrevClassTemplate = 0; } } else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S)) - PrevDecl = 0; - - // If there is a previous declaration with the same name, check - // whether this is a valid redeclaration. - ClassTemplateDecl *PrevClassTemplate - = dyn_cast_or_null<ClassTemplateDecl>(PrevDecl); - - // We may have found the injected-class-name of a class template, - // class template partial specialization, or class template specialization. - // In these cases, grab the template that is being defined or specialized. - if (!PrevClassTemplate && PrevDecl && isa<CXXRecordDecl>(PrevDecl) && - cast<CXXRecordDecl>(PrevDecl)->isInjectedClassName()) { - PrevDecl = cast<CXXRecordDecl>(PrevDecl->getDeclContext()); - PrevClassTemplate - = cast<CXXRecordDecl>(PrevDecl)->getDescribedClassTemplate(); - if (!PrevClassTemplate && isa<ClassTemplateSpecializationDecl>(PrevDecl)) { - PrevClassTemplate - = cast<ClassTemplateSpecializationDecl>(PrevDecl) - ->getSpecializedTemplate(); - } - } + PrevDecl = PrevClassTemplate = 0; if (PrevClassTemplate) { // Ensure that the template parameter lists are compatible. @@ -2188,6 +2213,9 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param, Diag(SR.getBegin(), diag::err_template_arg_unnamed_type) << SR; Diag(Tag->getDecl()->getLocation(), diag::note_template_unnamed_type_here); return true; + } else if (Context.hasSameUnqualifiedType(Arg, Context.OverloadTy)) { + SourceRange SR = ArgInfo->getTypeLoc().getFullSourceRange(); + return Diag(SR.getBegin(), diag::err_template_arg_overload_type) << SR; } return false; @@ -2484,7 +2512,14 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // Check that we don't overflow the template parameter type. unsigned AllowedBits = Context.getTypeSize(IntegerType); - if (Value.getActiveBits() > AllowedBits) { + unsigned RequiredBits; + if (IntegerType->isUnsignedIntegerType()) + RequiredBits = Value.getActiveBits(); + else if (Value.isUnsigned()) + RequiredBits = Value.getActiveBits() + 1; + else + RequiredBits = Value.getMinSignedBits(); + if (RequiredBits > AllowedBits) { Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_too_large) << Value.toString(10) << Param->getType() |