diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-02-17 23:15:12 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-02-17 23:15:12 +0000 |
commit | cc636688c4fd10b1732ce3e33b2b106024d545ca (patch) | |
tree | e671d5c8577f76078f1957da7922c85bf0571bf0 /lib/AST/DeclBase.cpp | |
parent | 9dd60b4526ccfab13cf0976999bf5f90b3423f43 (diff) |
Implement basic parsing and semantic analysis for explicit
specialization of class templates, e.g.,
template<typename T> class X;
template<> class X<int> { /* blah */ };
Each specialization is a different *Decl node (naturally), and can
have different members. We keep track of forward declarations and
definitions as for other class/struct/union types.
This is only the basic framework: we still have to deal with checking
the template headers properly, improving recovery when there are
failures, handling nested name specifiers, etc.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64848 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/DeclBase.cpp')
-rw-r--r-- | lib/AST/DeclBase.cpp | 51 |
1 files changed, 23 insertions, 28 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 826b4b0ba1..db29a8e3c6 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -319,17 +319,6 @@ DeclContext *DeclContext::getPrimaryContext() { // The original namespace is our primary context. return static_cast<NamespaceDecl*>(this)->getOriginalNamespace(); - case Decl::Enum: - case Decl::Record: - case Decl::CXXRecord: - // If this is a tag type that has a definition or is currently - // being defined, that definition is our primary context. - if (TagType *TagT = cast_or_null<TagType>(cast<TagDecl>(this)->TypeForDecl)) - if (TagT->isBeingDefined() || - (TagT->getDecl() && TagT->getDecl()->isDefinition())) - return TagT->getDecl(); - return this; - case Decl::ObjCMethod: return this; @@ -344,6 +333,17 @@ DeclContext *DeclContext::getPrimaryContext() { return this; default: + if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) { + // If this is a tag type that has a definition or is currently + // being defined, that definition is our primary context. + if (TagType *TagT + = cast_or_null<TagType>(cast<TagDecl>(this)->TypeForDecl)) + if (TagT->isBeingDefined() || + (TagT->getDecl() && TagT->getDecl()->isDefinition())) + return TagT->getDecl(); + return this; + } + assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast && "Unknown DeclContext kind"); return this; @@ -352,28 +352,11 @@ DeclContext *DeclContext::getPrimaryContext() { DeclContext *DeclContext::getNextContext() { switch (DeclKind) { - case Decl::TranslationUnit: - case Decl::Enum: - case Decl::Record: - case Decl::CXXRecord: - case Decl::ObjCMethod: - case Decl::ObjCInterface: - case Decl::ObjCCategory: - case Decl::ObjCProtocol: - case Decl::ObjCImplementation: - case Decl::ObjCCategoryImpl: - case Decl::LinkageSpec: - case Decl::Block: - // There is only one DeclContext for these entities. - return 0; - case Decl::Namespace: // Return the next namespace return static_cast<NamespaceDecl*>(this)->getNextNamespace(); default: - assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast && - "Unknown DeclContext kind"); return 0; } } @@ -463,6 +446,12 @@ const DeclContext *DeclContext::getLookupContext() const { } void DeclContext::makeDeclVisibleInContext(NamedDecl *D) { + // FIXME: This feels like a hack. Should DeclarationName support + // template-ids, or is there a better way to keep specializations + // from being visible? + if (isa<ClassTemplateSpecializationDecl>(D)) + return; + DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) { PrimaryContext->makeDeclVisibleInContext(D); @@ -486,6 +475,12 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) { if (!D->getDeclName()) return; + // FIXME: This feels like a hack. Should DeclarationName support + // template-ids, or is there a better way to keep specializations + // from being visible? + if (isa<ClassTemplateSpecializationDecl>(D)) + return; + bool MayBeRedeclaration = true; if (!isLookupMap()) { |