]> granicus.if.org Git - clang/commitdiff
Parse namespace aliases.
authorAnders Carlsson <andersca@mac.com>
Sat, 28 Mar 2009 04:07:16 +0000 (04:07 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 28 Mar 2009 04:07:16 +0000 (04:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67908 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Parser.h
lib/Parse/ParseDeclCXX.cpp
test/Parser/cxx-namespace-alias.cpp [new file with mode: 0644]

index 630b7ea49975b89033b9ef93914c334e10637d39..f502b3e4aa91ef2a8a9399ba039752c2236cf701 100644 (file)
@@ -997,7 +997,8 @@ private:
   DeclTy *ParseUsingDirective(unsigned Context, SourceLocation UsingLoc);
   DeclTy *ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc);
   DeclTy *ParseStaticAssertDeclaration();
-
+  DeclTy *ParseNamespaceAlias(SourceLocation AliasLoc, IdentifierInfo *Alias);
+  
   //===--------------------------------------------------------------------===//
   // C++ 9: classes [class] and C structs/unions.
   TypeTy *ParseClassName(SourceLocation &EndLocation, 
index 61182ef9cd4eb7383cd3b773851300846a0dbdec..229c1815f25aa241c57200554631d0dbd652e04d 100644 (file)
@@ -60,11 +60,11 @@ Parser::DeclTy *Parser::ParseNamespace(unsigned Context) {
     // FIXME: save these somewhere.
     AttrList = ParseAttributes();
   
-  if (Tok.is(tok::equal)) {
+  if (Tok.is(tok::equal))
     // FIXME: Verify no attributes were present.
-    // FIXME: parse this.
-  } else if (Tok.is(tok::l_brace)) {
-
+    return ParseNamespaceAlias(IdentLoc, Ident);
+  
+  if (Tok.is(tok::l_brace)) {
     SourceLocation LBrace = ConsumeBrace();
 
     // Enter a scope for the namespace.
@@ -96,6 +96,37 @@ Parser::DeclTy *Parser::ParseNamespace(unsigned Context) {
   return 0;
 }
 
+/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
+/// alias definition.
+///
+Parser::DeclTy *Parser::ParseNamespaceAlias(SourceLocation AliasLoc, 
+                                            IdentifierInfo *Alias) {
+  assert(Tok.is(tok::equal) && "Not equal token");
+  
+  ConsumeToken(); // eat the '='.
+  
+  CXXScopeSpec SS;
+  // Parse (optional) nested-name-specifier.
+  ParseOptionalCXXScopeSpecifier(SS);
+
+  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_namespace_name);
+    // Skip to end of the definition and eat the ';'.
+    SkipUntil(tok::semi);
+    return 0;
+  }
+
+  // Parse identifier.
+  IdentifierInfo *NamespaceName = Tok.getIdentifierInfo();
+  SourceLocation NamespaceLoc = ConsumeToken();
+  
+  // Eat the ';'.
+  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
+                   "namespace name", tok::semi);
+  
+  return 0;
+}
+
 /// ParseLinkage - We know that the current token is a string_literal
 /// and just before that, that extern was seen.
 ///
diff --git a/test/Parser/cxx-namespace-alias.cpp b/test/Parser/cxx-namespace-alias.cpp
new file mode 100644 (file)
index 0000000..65e1459
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: clang-cc -parse-noop -verify %s
+
+namespace A = B;
+
+namespace A = !; // expected-error {{expected namespace name}}
+namespace A = A::!; // expected-error {{expected namespace name}}
+
+