diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 19adc6d829..7a5233a6af 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -878,6 +878,14 @@ class UsingDirectiveDecl : public NamedDecl { /// SourceLocation - Location of 'namespace' token. SourceLocation NamespaceLoc; + /// \brief The source range that covers the nested-name-specifier + /// preceding the namespace name. + SourceRange QualifierRange; + + /// \brief The nested-name-specifier that precedes the namespace + /// name, if any. + NestedNameSpecifier *Qualifier; + /// IdentLoc - Location of nominated namespace-name identifier. // FIXME: We don't store location of scope specifier. SourceLocation IdentLoc; @@ -898,16 +906,27 @@ class UsingDirectiveDecl : public NamedDecl { UsingDirectiveDecl(DeclContext *DC, SourceLocation L, SourceLocation NamespcLoc, + SourceRange QualifierRange, + NestedNameSpecifier *Qualifier, SourceLocation IdentLoc, NamespaceDecl *Nominated, DeclContext *CommonAncestor) : NamedDecl(Decl::UsingDirective, DC, L, getName()), - NamespaceLoc(NamespcLoc), IdentLoc(IdentLoc), + NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange), + Qualifier(Qualifier), IdentLoc(IdentLoc), NominatedNamespace(Nominated? Nominated->getOriginalNamespace() : 0), CommonAncestor(CommonAncestor) { } public: + /// \brief Retrieve the source range of the nested-name-specifier + /// that qualifiers the namespace name. + SourceRange getQualifierRange() const { return QualifierRange; } + + /// \brief Retrieve the nested-name-specifier that qualifies the + /// name of the namespace. + NestedNameSpecifier *getQualifier() const { return Qualifier; } + /// getNominatedNamespace - Returns namespace nominated by using-directive. NamespaceDecl *getNominatedNamespace() { return NominatedNamespace; } @@ -929,6 +948,8 @@ public: static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, SourceLocation NamespaceLoc, + SourceRange QualifierRange, + NestedNameSpecifier *Qualifier, SourceLocation IdentLoc, NamespaceDecl *Nominated, DeclContext *CommonAncestor); diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 5b806fae7b..5fb2a016b6 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -402,11 +402,13 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, SourceLocation NamespaceLoc, + SourceRange QualifierRange, + NestedNameSpecifier *Qualifier, SourceLocation IdentLoc, NamespaceDecl *Used, DeclContext *CommonAncestor) { - return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, IdentLoc, - Used, CommonAncestor); + return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange, + Qualifier, IdentLoc, Used, CommonAncestor); } NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 6412f750ae..bfd3dca3e6 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -51,12 +51,15 @@ namespace { void VisitFieldDecl(FieldDecl *D); void VisitVarDecl(VarDecl *D); void VisitParmVarDecl(ParmVarDecl *D); + void VisitOriginalParmVarDecl(OriginalParmVarDecl *D); void VisitFileScopeAsmDecl(FileScopeAsmDecl *D); + void VisitOverloadedFunctionDecl(OverloadedFunctionDecl *D); + void VisitUsingDirectiveDecl(UsingDirectiveDecl *D); void VisitNamespaceDecl(NamespaceDecl *D); void VisitLinkageSpecDecl(LinkageSpecDecl *D); void VisitTemplateDecl(TemplateDecl *D); - void VisitObjCClassDecl(ObjCClassDecl *D); void VisitObjCMethodDecl(ObjCMethodDecl *D); + void VisitObjCClassDecl(ObjCClassDecl *D); void VisitObjCImplementationDecl(ObjCImplementationDecl *D); void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); @@ -402,6 +405,10 @@ void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) { VisitVarDecl(D); } +void DeclPrinter::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) { + VisitVarDecl(D); +} + void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { Out << "__asm ("; D->getAsmString()->printPretty(Out, Context, 0, Policy, Indentation); @@ -411,6 +418,18 @@ void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { //---------------------------------------------------------------------------- // C++ declarations //---------------------------------------------------------------------------- +void DeclPrinter::VisitOverloadedFunctionDecl(OverloadedFunctionDecl *D) { + assert(false && + "OverloadedFunctionDecls aren't really decls and are never printed"); +} + +void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { + Out << "using namespace "; + if (D->getQualifier()) + D->getQualifier()->print(Out, Policy); + Out << D->getNominatedNamespace()->getNameAsString(); +} + void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) { Out << "namespace " << D->getNameAsString() << " {\n"; VisitDeclContext(D); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 0bf97f560d..cd722fe169 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1711,8 +1711,12 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S, while (CommonAncestor && !CommonAncestor->Encloses(CurContext)) CommonAncestor = CommonAncestor->getParent(); - UDir = UsingDirectiveDecl::Create(Context, CurContext, UsingLoc, - NamespcLoc, IdentLoc, + UDir = UsingDirectiveDecl::Create(Context, + CurContext, UsingLoc, + NamespcLoc, + SS.getRange(), + (NestedNameSpecifier *)SS.getScopeRep(), + IdentLoc, cast(NS), CommonAncestor); PushUsingDirective(S, UDir); diff --git a/test/Coverage/ast-printing.cpp b/test/Coverage/ast-printing.cpp new file mode 100644 index 0000000000..10d01c7437 --- /dev/null +++ b/test/Coverage/ast-printing.cpp @@ -0,0 +1,6 @@ +// RUN: clang-cc --fsyntax-only %s && +// RUN: clang-cc --ast-print %s && +// RUN: clang-cc --ast-dump %s +// FIXME: clang-cc --ast-print-xml -o %t %s + +#include "cxx-language-features.inc" diff --git a/test/Coverage/c-language-features.inc b/test/Coverage/c-language-features.inc index 5258040cc1..bcf4127299 100644 --- a/test/Coverage/c-language-features.inc +++ b/test/Coverage/c-language-features.inc @@ -140,6 +140,7 @@ void f4(int a0, int a1, int a2, va_list ap) { int t32 = __real (t32_cond ? t32_a : t32_b); struct { int x, y; } t33, *t34, t35[12], t36(int, float); + float t37, *t38, t39[9], t40(double); } // Extended vectors diff --git a/test/Coverage/cxx-language-features.inc b/test/Coverage/cxx-language-features.inc new file mode 100644 index 0000000000..92c9fd6f27 --- /dev/null +++ b/test/Coverage/cxx-language-features.inc @@ -0,0 +1,12 @@ +//-*- C++ -*- + +// Intended to exercise all syntactic parts of the C++ language that +// aren't part of C. + +namespace std { + namespace debug { + } +} + +using namespace std::debug; +using namespace std;