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