summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-25 23:52:28 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-25 23:52:28 +0000
commitd54dfb871882852c00e525bceef0b92fe945d40a (patch)
treeec62f11d206d20332fa810da63ed41e63d3b6b57 /clang/lib/Parse/ParseDeclCXX.cpp
parentb750d928cecf9b3c4144ac40c6c87da91a34f444 (diff)
downloadbcm5719-llvm-d54dfb871882852c00e525bceef0b92fe945d40a.tar.gz
bcm5719-llvm-d54dfb871882852c00e525bceef0b92fe945d40a.zip
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> { }; llvm-svn: 65488
Diffstat (limited to 'clang/lib/Parse/ParseDeclCXX.cpp')
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp35
1 files changed, 26 insertions, 9 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 3ef3f93fdfd..9f704d2ea8a 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -216,16 +216,33 @@ Parser::DeclTy *Parser::ParseUsingDeclaration(unsigned Context,
/// 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 @@ Parser::TypeTy *Parser::ParseClassName(const CXXScopeSpec *SS) {
}
// Consume the identifier.
- ConsumeToken();
-
+ EndLocation = ConsumeToken();
return Type;
}
@@ -510,12 +526,13 @@ Parser::BaseResult Parser::ParseBaseSpecifier(DeclTy *ClassDecl)
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.
OpenPOWER on IntegriCloud