I'm puzzled at how to go about adding child decls too a namespace.
I've picked up, that the parser shouldn't use AST types and only make Actions.ActOn... calls.

Currently I'm thinking something like this:

llvm::SmallVector<DeclTy*, 16>  NamespaceChildren;
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
 NamespaceChildren.push_back(ParseExternalDeclaration());
}
Actions.ActOnNamespaceMembers(&NamespaceChildren[0], NamespaceChildren.size());

or something like this:

while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
 Actions.ActOnNamespaceMember(ParseExternalDeclaration());
}

Am I on the right track?

Kevin
Index: test/Parser/cxx-namespace.cpp
===================================================================
--- test/Parser/cxx-namespace.cpp	(revision 0)
+++ test/Parser/cxx-namespace.cpp	(revision 0)
@@ -0,0 +1,13 @@
+// RUN: clang -fsyntax-only -verify %s
+int intone;
+namespace one {
+  namespace two {
+    namespace three {
+      int intone;
+    }
+  }
+}
+
+namespace a { double i; }
+int i;
+namespace a {double* j = &i;}
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h	(revision 48369)
+++ include/clang/AST/Decl.h	(working copy)
@@ -73,6 +73,7 @@
          ObjCForwardProtocol,
          LinkageSpec,
    FileScopeAsm,
+   Namespace,
   
     // For each non-leaf class, we now define a mapping to the first/last member
     // of the class, to allow efficient classof.
@@ -757,6 +758,19 @@
   friend Decl* Decl::Create(llvm::Deserializer& D);
 };
 
+/// NamespaceDecl - Represents a cxx namespace .  For example:
+//.   namespace X { };
+/// This decl will be marked invalid if *any* members are invalid.
+///
+class NamespaceDecl : public ScopedDecl {
+
+public:
+  NamespaceDecl(SourceLocation L, IdentifierInfo *Id, ScopedDecl*PrevDecl)
+    : ScopedDecl(Decl::Namespace, L, Id, PrevDecl) {
+    assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
+  }
+};
+
 class FileScopeAsmDecl : public Decl {
   StringLiteral *AsmString;
 public:
Index: include/clang/Parse/Action.h
===================================================================
--- include/clang/Parse/Action.h	(revision 48369)
+++ include/clang/Parse/Action.h	(working copy)
@@ -122,6 +122,16 @@
   virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group) {
     return Group;
   }
+  
+  virtual DeclTy *ActOnStartOfNamespace(Scope *NamespaceScope, 
+                                        SourceLocation NameLoc, 
+                                        IdentifierInfo *Name, DeclTy *Attr) {
+    return 0;
+  }
+  
+  virtual DeclTy *ActOnFinishNamespace(DeclTy *Decl) {
+    return Decl;
+  }
 
   /// ActOnStartOfFunctionDef - This is called at the start of a function
   /// definition, instead of calling ActOnDeclarator.  The Declarator includes
@@ -304,7 +314,7 @@
     return 0;
   }
   virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
-                                  bool IsSimple,                                  
+                                  bool IsSimple,
                                   bool IsVolatile,
                                   unsigned NumOutputs,
                                   unsigned NumInputs,
Index: Sema/Sema.h
===================================================================
--- Sema/Sema.h	(revision 48369)
+++ Sema/Sema.h	(working copy)
@@ -195,6 +195,9 @@
 
   virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
   virtual void ObjCActOnStartOfMethodDef(Scope *S, DeclTy *D);
+  virtual DeclTy *ActOnStartOfNamespace(Scope *NamespaceScope, 
+                                        SourceLocation NameLoc,
+                                        IdentifierInfo *Name, DeclTy *Attr);
   
   virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtTy *Body);
   virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
@@ -256,7 +259,7 @@
   /// The raw attribute contains 1 argument, the id of the address space 
   /// for the type.
   QualType HandleAddressSpaceTypeAttribute(QualType curType, 
-                                           AttributeList *rawAttr);                                
+                                           AttributeList *rawAttr);
 
   // HandleVectorTypeAttribute - this attribute is only applicable to 
   // integral and float scalars, although arrays, pointers, and function
@@ -790,7 +793,7 @@
   // returns true if the cast is invalid
   bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty);
   
-  // returns true if there were any incompatible arguments.                           
+  // returns true if there were any incompatible arguments.
   bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
                                  ObjCMethodDecl *Method);
                     
Index: Sema/SemaDecl.cpp
===================================================================
--- Sema/SemaDecl.cpp	(revision 48369)
+++ Sema/SemaDecl.cpp	(working copy)
@@ -2290,3 +2290,11 @@
 
   d->addAttr(new AlignedAttr(Align));
 }
+
+Sema::DeclTy *Sema::ActOnStartOfNamespace(Scope *NamespaceScope, 
+                                          SourceLocation NameLoc, 
+                                          IdentifierInfo *Name, DeclTy *Attr) {
+  NamespaceDecl* ND = new NamespaceDecl(NameLoc, Name, 0);
+  return ND;
+}
+
Index: AST/Decl.cpp
===================================================================
--- AST/Decl.cpp	(revision 48369)
+++ AST/Decl.cpp	(working copy)
@@ -28,6 +28,7 @@
 static unsigned nEnumConst = 0;
 static unsigned nEnumDecls = 0;
 static unsigned nTypedef = 0;
+static unsigned nNamespace = 0;
 static unsigned nFieldDecls = 0;
 static unsigned nInterfaceDecls = 0;
 static unsigned nClassDecls = 0;
@@ -186,6 +187,9 @@
 
 void Decl::addDeclKind(const Kind k) {
   switch (k) {
+    case Namespace:
+      nNamespace++;
+      break;
     case Typedef:
       nTypedef++;
       break;
Index: Driver/ASTConsumers.cpp
===================================================================
--- Driver/ASTConsumers.cpp	(revision 48369)
+++ Driver/ASTConsumers.cpp	(working copy)
@@ -40,6 +40,7 @@
     void PrintDecl(Decl *D);
     void PrintFunctionDeclStart(FunctionDecl *FD);    
     void PrintTypeDefDecl(TypedefDecl *TD);    
+    void PrintNamespaceDecl(NamespaceDecl *ND);    
     void PrintLinkageSpec(LinkageSpecDecl *LS);
     void PrintObjCMethodDecl(ObjCMethodDecl *OMD);    
     void PrintObjCImplementationDecl(ObjCImplementationDecl *OID);
@@ -92,6 +93,9 @@
     PrintObjCCompatibleAliasDecl(OID);
   } else if (isa<ObjCClassDecl>(D)) {
     Out << "@class [printing todo]\n";
+  } else if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D)) {
+    Out << "Read top-level namespace decl: '" << ND->getName() << "'\n";
+    PrintNamespaceDecl(ND);
   } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
     Out << "Read top-level tag decl: '" << TD->getName() << "'\n";
   } else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
@@ -160,6 +164,12 @@
   Out << "typedef " << S << ";\n";
 }
 
+void DeclPrinter::PrintNamespaceDecl(NamespaceDecl *ND) {
+  std::string S = ND->getName();
+  //ND->getUnderlyingType().getAsStringInternal(S);
+  Out << "namespace " << S << ";\n";
+}
+
 void DeclPrinter::PrintLinkageSpec(LinkageSpecDecl *LS) {
   const char *l;
   if (LS->getLanguage() == LinkageSpecDecl::lang_c)
Index: Parse/ParseDeclCXX.cpp
===================================================================
--- Parse/ParseDeclCXX.cpp	(revision 48369)
+++ Parse/ParseDeclCXX.cpp	(working copy)
@@ -62,16 +62,20 @@
     // FIXME: parse this.
   } else if (Tok.is(tok::l_brace)) {
     SourceLocation LBrace = ConsumeBrace();
-    // FIXME: push a scope, push a namespace decl.
+    EnterScope(Scope::DeclScope);
+    DeclTy *Res = Actions.ActOnStartOfNamespace(CurScope, IdentLoc, Ident,
+                                                AttrList);
     
+    llvm::SmallVector<DeclTy*, 16>  NamespaceChildren;
     while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
-      // FIXME capture the decls.
-      ParseExternalDeclaration();
+      NamespaceChildren.push_back(ParseExternalDeclaration());
     }
     
     SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
-    
-    // FIXME: act on this.
+    ExitScope();
+   
+    Actions.ActOnFinishNamespace(Res);
+    return Res;
   } else {
     unsigned D = Ident ? diag::err_expected_lbrace : 
                          diag::err_expected_ident_lbrace;
_______________________________________________
cfe-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

Reply via email to