summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaCXXScopeSpec.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-03-14 23:13:10 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-03-14 23:13:10 +0000
commitf1c66b40213784a1c4612f04c14cafa2b0e89988 (patch)
treee7ce75134aa9dfc30fce2b5a85088baf65423294 /lib/Sema/SemaCXXScopeSpec.cpp
parent59e7f4e6e69872d2fc4031f66b47b8ad64967e51 (diff)
downloadclang-f1c66b40213784a1c4612f04c14cafa2b0e89988.tar.gz
Instantiating a class template should not instantiate the definition of any
scoped enumeration members. Later uses of an enumeration temploid as a nested name specifier should cause its instantiation. Plus some groundwork for explicit specialization of member enumerations of class templates. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152750 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCXXScopeSpec.cpp')
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp72
1 files changed, 41 insertions, 31 deletions
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 1c414dda5d..5e6c27b15d 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -13,6 +13,7 @@
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Template.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
@@ -209,43 +210,52 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,
DeclContext *DC) {
assert(DC != 0 && "given null context");
- if (TagDecl *tag = dyn_cast<TagDecl>(DC)) {
- // If this is a dependent type, then we consider it complete.
- if (tag->isDependentContext())
- return false;
+ TagDecl *tag = dyn_cast<TagDecl>(DC);
- // If we're currently defining this type, then lookup into the
- // type is okay: don't complain that it isn't complete yet.
- QualType type = Context.getTypeDeclType(tag);
- const TagType *tagType = type->getAs<TagType>();
- if (tagType && tagType->isBeingDefined())
- return false;
+ // If this is a dependent type, then we consider it complete.
+ if (!tag || tag->isDependentContext())
+ return false;
- SourceLocation loc = SS.getLastQualifierNameLoc();
- if (loc.isInvalid()) loc = SS.getRange().getBegin();
+ // If we're currently defining this type, then lookup into the
+ // type is okay: don't complain that it isn't complete yet.
+ QualType type = Context.getTypeDeclType(tag);
+ const TagType *tagType = type->getAs<TagType>();
+ if (tagType && tagType->isBeingDefined())
+ return false;
- // The type must be complete.
- if (RequireCompleteType(loc, type,
- PDiag(diag::err_incomplete_nested_name_spec)
- << SS.getRange())) {
- SS.SetInvalid(SS.getRange());
- return true;
- }
+ SourceLocation loc = SS.getLastQualifierNameLoc();
+ if (loc.isInvalid()) loc = SS.getRange().getBegin();
- // Fixed enum types are complete, but they aren't valid as scopes
- // until we see a definition, so awkwardly pull out this special
- // case.
- if (const EnumType *enumType = dyn_cast_or_null<EnumType>(tagType)) {
- if (!enumType->getDecl()->isCompleteDefinition()) {
- Diag(loc, diag::err_incomplete_nested_name_spec)
- << type << SS.getRange();
- SS.SetInvalid(SS.getRange());
- return true;
- }
- }
+ // The type must be complete.
+ if (RequireCompleteType(loc, type,
+ PDiag(diag::err_incomplete_nested_name_spec)
+ << SS.getRange())) {
+ SS.SetInvalid(SS.getRange());
+ return true;
}
- return false;
+ // Fixed enum types are complete, but they aren't valid as scopes
+ // until we see a definition, so awkwardly pull out this special
+ // case.
+ const EnumType *enumType = dyn_cast_or_null<EnumType>(tagType);
+ if (!enumType || enumType->getDecl()->isCompleteDefinition())
+ return false;
+
+ // Try to instantiate the definition, if this is a specialization of an
+ // enumeration temploid.
+ EnumDecl *ED = enumType->getDecl();
+ if (EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
+ MemberSpecializationInfo *MSI = ED->getMemberSpecializationInfo();
+ if (MSI->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+ return InstantiateEnum(loc, ED, Pattern,
+ getTemplateInstantiationArgs(ED),
+ TSK_ImplicitInstantiation);
+ }
+
+ Diag(loc, diag::err_incomplete_nested_name_spec)
+ << type << SS.getRange();
+ SS.SetInvalid(SS.getRange());
+ return true;
}
bool Sema::ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,