diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 9 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaCXXScopeSpec.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 9 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 81 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 |
6 files changed, 99 insertions, 10 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 08f9b02d77f..bd01ec9e514 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1919,6 +1919,15 @@ public: SourceLocation RAngleLoc, AttributeList *Attr); + virtual DeclResult + ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, + unsigned TagSpec, + SourceLocation KWLoc, + const CXXScopeSpec &SS, + IdentifierInfo *Name, + SourceLocation NameLoc, + AttributeList *Attr); + bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation LAngleLoc, diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index bbc1bc52cb3..11ac0bd3005 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -273,8 +273,9 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S, SourceLocation CCLoc) { NestedNameSpecifier *Prefix = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); + QualType T = QualType::getFromOpaquePtr(Ty); return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false, - QualType::getFromOpaquePtr(Ty).getTypePtr()); + T.getTypePtr()); } /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5914292dab6..e27517e6896 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3254,12 +3254,15 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, goto CreateNewDecl; } - // FIXME: RequireCompleteDeclContext(SS)? + if (RequireCompleteDeclContext(SS)) + return DeclPtrTy::make((Decl *)0); + DC = computeDeclContext(SS); SearchDC = DC; // Look-up name inside 'foo::'. - PrevDecl = dyn_cast_or_null<TagDecl>( - LookupQualifiedName(DC, Name, LookupTagName, true).getAsDecl()); + PrevDecl + = dyn_cast_or_null<TagDecl>( + LookupQualifiedName(DC, Name, LookupTagName, true).getAsDecl()); // A tag 'foo::bar' must already exist. if (PrevDecl == 0) { diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 5f2b705498e..57aae296319 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -994,10 +994,7 @@ QualType Sema::CheckPointerToMemberOperands( Diag(Loc, diag::err_bad_memptr_rhs) << OpSpelling << RType << rex->getSourceRange(); return QualType(); - } else if (RequireCompleteType(Loc, QualType(MemPtr->getClass(), 0), - diag::err_memptr_rhs_incomplete, - rex->getSourceRange())) - return QualType(); + } QualType Class(MemPtr->getClass(), 0); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 22f2bef0e9d..7190df107ee 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2155,6 +2155,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, return DeclPtrTy::make(Specialization); } +// Explicit instantiation of a class template specialization Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, unsigned TagSpec, @@ -2244,7 +2245,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, } if (PrevDecl->getSpecializationKind() == TSK_ExplicitSpecialization) { - // C++0x [temp.explicit]p4: + // C++ DR 259, C++0x [temp.explicit]p4: // For a given set of template parameters, if an explicit // instantiation of a template appears after a declaration of // an explicit specialization for that template, the explicit @@ -2342,6 +2343,84 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, return DeclPtrTy::make(Specialization); } +// Explicit instantiation of a member class of a class template. +Sema::DeclResult +Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, + unsigned TagSpec, + SourceLocation KWLoc, + const CXXScopeSpec &SS, + IdentifierInfo *Name, + SourceLocation NameLoc, + AttributeList *Attr) { + + DeclPtrTy TagD = ActOnTag(S, TagSpec, Action::TK_Reference, + KWLoc, SS, Name, NameLoc, Attr, AS_none); + if (!TagD) + return true; + + TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>()); + if (Tag->isEnum()) { + Diag(TemplateLoc, diag::err_explicit_instantiation_enum) + << Context.getTypeDeclType(Tag); + return true; + } + + CXXRecordDecl *Record = cast<CXXRecordDecl>(Tag); + CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass(); + if (!Pattern) { + Diag(TemplateLoc, diag::err_explicit_instantiation_nontemplate_type) + << Context.getTypeDeclType(Record); + Diag(Record->getLocation(), diag::note_nontemplate_decl_here); + return true; + } + + // C++0x [temp.explicit]p2: + // [...] An explicit instantiation shall appear in an enclosing + // namespace of its template. [...] + // + // This is C++ DR 275. + if (getLangOptions().CPlusPlus0x) { + // FIXME: In C++98, we would like to turn these errors into + // warnings, dependent on a -Wc++0x flag. + DeclContext *PatternContext + = Pattern->getDeclContext()->getEnclosingNamespaceContext(); + if (!CurContext->Encloses(PatternContext)) { + Diag(TemplateLoc, diag::err_explicit_instantiation_out_of_scope) + << Record << cast<NamedDecl>(PatternContext) << SS.getRange(); + Diag(Pattern->getLocation(), diag::note_previous_declaration); + } + } + + // Find the enclosing template, because we need its template + // arguments to instantiate this class. + DeclContext *EnclosingTemplateCtx = Record->getDeclContext(); + while (!isa<ClassTemplateSpecializationDecl>(EnclosingTemplateCtx)) + EnclosingTemplateCtx = EnclosingTemplateCtx->getParent(); + ClassTemplateSpecializationDecl *EnclosingTemplate + = cast<ClassTemplateSpecializationDecl>(EnclosingTemplateCtx); + + if (!Record->getDefinition(Context)) { + // If the class has a definition, instantiate it (and all of its + // members, recursively). + Pattern = cast_or_null<CXXRecordDecl>(Pattern->getDefinition(Context)); + if (Pattern && InstantiateClass(TemplateLoc, Record, Pattern, + EnclosingTemplate->getTemplateArgs(), + /*ExplicitInstantiation=*/true)) + return true; + } else { + // Instantiate all of the members of class. + InstantiatingTemplate Inst(*this, TemplateLoc, Record); + InstantiateClassMembers(TemplateLoc, Record, + EnclosingTemplate->getTemplateArgs()); + } + + // FIXME: We don't have any representation for explicit + // instantiations of member classes. Such a representation is not + // needed for compilation, but it should be available for clients + // that want to see all of the declarations in the source code. + return TagD; +} + Sema::TypeResult Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, const IdentifierInfo &II, SourceLocation IdLoc) { diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 9c2c4230f9c..5c6ed758d92 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -863,7 +863,7 @@ Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS, ActOnCXXNestedNameSpecifier(0, SS, Range.getEnd(), Range.getEnd(), - *NNS->getAsIdentifier())); + *NNS->getAsIdentifier())); break; } |

