I've gotten serious and have written some code.

Following the clang web page's advice, I've tried to start implementing c++ namespaces. Currently, I'm trying to figure out how to add namespace members to my NamespaceDecl.

I'm very new to clang and learning as I go.   Comments/Suggestions welcome.

Kevin Tew



Index: test/Parser/cxx-namespace.cpp
===================================================================
--- test/Parser/cxx-namespace.cpp	(revision 0)
+++ test/Parser/cxx-namespace.cpp	(revision 0)
@@ -0,0 +1,9 @@
+// RUN: clang -fsyntax-only -verify %s
+int intone;
+namespace one {
+  namespace two {
+    namespace three {
+      int intone;
+    }
+  }
+}
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h	(revision 47546)
+++ include/clang/AST/Decl.h	(working copy)
@@ -60,6 +60,7 @@
     //           RecordDecl,
                    Struct,
                    Union,
+                   Namespace,
                    Class,
     //       ValueDecl
                EnumConstant,
@@ -771,6 +772,19 @@
   friend Decl* Decl::Create(llvm::Deserializer& D);
 };
 
+/// RecordDecl - Represents a cxx namespace .  For example:
+//.   namespace X { };
+/// This decl will be marked invalid if *any* members are invalid.
+///
+class NamespaceDecl : public RecordDecl {
+
+public:
+  NamespaceDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl*PrevDecl)
+    : RecordDecl(DK, 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 47546)
+++ include/clang/Parse/Action.h	(working copy)
@@ -122,6 +122,14 @@
   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
Index: Sema/Sema.h
===================================================================
--- Sema/Sema.h	(revision 47546)
+++ Sema/Sema.h	(working copy)
@@ -195,6 +195,7 @@
 
   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,
Index: Sema/SemaDecl.cpp
===================================================================
--- Sema/SemaDecl.cpp	(revision 47546)
+++ Sema/SemaDecl.cpp	(working copy)
@@ -1972,3 +1972,9 @@
 
   d->addAttr(new AlignedAttr(Align));
 }
+
+Sema::DeclTy *Sema::ActOnStartOfNamespace(Scope *NamespaceScope, SourceLocation NameLoc, IdentifierInfo *Name, DeclTy *Attr) {
+  NamespaceDecl* ND = new NamespaceDecl(Decl::Namespace, NameLoc, Name, 0);
+  return ND;
+}
+
Index: Driver/ASTConsumers.cpp
===================================================================
--- Driver/ASTConsumers.cpp	(revision 47546)
+++ 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 tag 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 47546)
+++ Parse/ParseDeclCXX.cpp	(working copy)
@@ -62,6 +62,8 @@
     // FIXME: parse this.
   } else if (Tok.is(tok::l_brace)) {
     SourceLocation LBrace = ConsumeBrace();
+    EnterScope(Scope::DeclScope);
+    DeclTy *Res = Actions.ActOnStartOfNamespace(CurScope, IdentLoc, Ident, AttrList);
     // FIXME: push a scope, push a namespace decl.
     
     while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
@@ -70,8 +72,11 @@
     }
     
     SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
-    
+    ExitScope();
+   
     // FIXME: act on this.
+    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