[cfe-commits] r65488 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp test/SemaTemplate/class-template-id-2.cpp
Douglas Gregor
dgregor at apple.com
Wed Feb 25 15:52:29 PST 2009
Author: dgregor
Date: Wed Feb 25 17:52:28 2009
New Revision: 65488
URL: http://llvm.org/viewvc/llvm-project?rev=65488&view=rev
Log:
Implementing parsing of template-ids as class-names, so that we can
derive from a class template specialization, e.g.,
class B : public A<int> { };
Added:
cfe/trunk/test/SemaTemplate/class-template-id-2.cpp
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=65488&r1=65487&r2=65488&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Feb 25 17:52:28 2009
@@ -968,7 +968,8 @@
//===--------------------------------------------------------------------===//
// C++ 9: classes [class] and C structs/unions.
- TypeTy *ParseClassName(const CXXScopeSpec *SS = 0);
+ TypeTy *ParseClassName(SourceLocation &EndLocation,
+ const CXXScopeSpec *SS = 0);
void ParseClassSpecifier(DeclSpec &DS,
TemplateParameterLists *TemplateParams = 0);
void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=65488&r1=65487&r2=65488&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Feb 25 17:52:28 2009
@@ -1822,7 +1822,8 @@
if (Tok.is(tok::identifier)) {
// FIXME: Inaccurate.
SourceLocation NameLoc = Tok.getLocation();
- if (TypeTy *Type = ParseClassName()) {
+ SourceLocation EndLoc;
+ if (TypeTy *Type = ParseClassName(EndLoc)) {
D.setDestructor(Type, TildeLoc, NameLoc);
} else {
D.SetIdentifier(0, TildeLoc);
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=65488&r1=65487&r2=65488&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Feb 25 17:52:28 2009
@@ -216,16 +216,33 @@
/// ParseClassName - Parse a C++ class-name, which names a class. Note
/// that we only check that the result names a type; semantic analysis
/// will need to verify that the type names a class. The result is
-/// either a type or NULL, dependending on whether a type name was
+/// either a type or NULL, depending on whether a type name was
/// found.
///
/// class-name: [C++ 9.1]
/// identifier
-/// template-id [TODO]
+/// simple-template-id
///
-Parser::TypeTy *Parser::ParseClassName(const CXXScopeSpec *SS) {
- // Parse the class-name.
- // FIXME: Alternatively, parse a simple-template-id.
+Parser::TypeTy *Parser::ParseClassName(SourceLocation &EndLocation,
+ const CXXScopeSpec *SS) {
+ // Check whether we have a template-id that names a type.
+ if (Tok.is(tok::annot_template_id)) {
+ TemplateIdAnnotation *TemplateId
+ = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+ if (TemplateId->Kind == TNK_Class_template) {
+ if (AnnotateTemplateIdTokenAsType(SS))
+ return 0;
+
+ assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
+ TypeTy *Type = Tok.getAnnotationValue();
+ EndLocation = Tok.getAnnotationEndLoc();
+ ConsumeToken();
+ return Type;
+ }
+
+ // Fall through to produce an error below.
+ }
+
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_class_name);
return 0;
@@ -240,8 +257,7 @@
}
// Consume the identifier.
- ConsumeToken();
-
+ EndLocation = ConsumeToken();
return Type;
}
@@ -510,12 +526,13 @@
SourceLocation BaseLoc = Tok.getLocation();
// Parse the class-name.
- TypeTy *BaseType = ParseClassName(&SS);
+ SourceLocation EndLocation;
+ TypeTy *BaseType = ParseClassName(EndLocation, &SS);
if (!BaseType)
return true;
// Find the complete source range for the base-specifier.
- SourceRange Range(StartLoc, BaseLoc);
+ SourceRange Range(StartLoc, EndLocation);
// Notify semantic analysis that we have parsed a complete
// base-specifier.
Added: cfe/trunk/test/SemaTemplate/class-template-id-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-id-2.cpp?rev=65488&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/class-template-id-2.cpp (added)
+++ cfe/trunk/test/SemaTemplate/class-template-id-2.cpp Wed Feb 25 17:52:28 2009
@@ -0,0 +1,23 @@
+// RUN: clang -fsyntax-only -verify %s
+namespace N {
+ template<typename T> class A;
+
+ template<> class A<int> { };
+
+ class B : public A<int> { };
+}
+
+class C1 : public N::A<int> { };
+
+class C2 : public N::A<float> { }; // expected-error{{base class has incomplete type}} \
+ // FIXME: expected-note{{forward declaration of 'class A'}}
+
+struct D1 {
+ operator N::A<int>();
+};
+
+namespace N {
+ struct D2 {
+ operator A<int>();
+ };
+}
More information about the cfe-commits
mailing list