From: Enea Zaffanella Date: Wed, 17 Jul 2013 17:28:56 +0000 (+0000) Subject: Fixed source range of C++03 access declarations. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d4de59d3e54421ef88316d650e35802ba9c572cf;p=clang Fixed source range of C++03 access declarations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186522 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 52909fbb03..c3b8edca30 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -2786,6 +2786,9 @@ public: return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } + /// \brief Return true if it is a C++03 access declaration (no 'using'). + bool isAccessDeclaration() const { return UsingLocation.isInvalid(); } + /// \brief Return true if the using declaration has 'typename'. bool isTypeName() const { return FirstUsingShadow.getInt(); } @@ -2851,10 +2854,8 @@ public: bool IsTypeNameArg); static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(UsingLocation, getNameInfo().getEndLoc()); - } + + SourceRange getSourceRange() const LLVM_READONLY; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Using; } @@ -2904,6 +2905,9 @@ public: /// \brief Set the source location of the 'using' keyword. void setUsingLoc(SourceLocation L) { UsingLocation = L; } + /// \brief Return true if it is a C++03 access declaration (no 'using'). + bool isAccessDeclaration() const { return UsingLocation.isInvalid(); } + /// \brief Retrieve the nested-name-specifier that qualifies the name, /// with source-location information. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } @@ -2925,9 +2929,7 @@ public: static UnresolvedUsingValueDecl * CreateDeserialized(ASTContext &C, unsigned ID); - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(UsingLocation, getNameInfo().getEndLoc()); - } + SourceRange getSourceRange() const LLVM_READONLY; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == UnresolvedUsingValue; } diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 151bed5a83..18bfe15486 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -626,6 +626,21 @@ const internal::VariadicDynCastAllOfMatcher initListExpr; /// matches \code using X::x \endcode const internal::VariadicDynCastAllOfMatcher usingDecl; +/// \brief Matches unresolved using value declarations. +/// +/// Given +/// \code +/// template +/// class C : private X { +/// using X::x; +/// }; +/// \endcode +/// unresolvedUsingValueDecl() +/// matches \code using X::x \endcode +const internal::VariadicDynCastAllOfMatcher< + Decl, + UnresolvedUsingValueDecl> unresolvedUsingValueDecl; + /// \brief Matches constructor call expressions (including implicit ones). /// /// Example matches string(ptr, n) and ptr within arguments of f diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 4a9da79577..dacb867df6 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -1969,6 +1969,12 @@ UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, unsigned ID) { DeclarationNameInfo(), false); } +SourceRange UsingDecl::getSourceRange() const { + SourceLocation Begin = isAccessDeclaration() + ? getQualifierLoc().getBeginLoc() : UsingLocation; + return SourceRange(Begin, getNameInfo().getEndLoc()); +} + void UnresolvedUsingValueDecl::anchor() { } UnresolvedUsingValueDecl * @@ -1988,6 +1994,12 @@ UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, unsigned ID) { DeclarationNameInfo()); } +SourceRange UnresolvedUsingValueDecl::getSourceRange() const { + SourceLocation Begin = isAccessDeclaration() + ? getQualifierLoc().getBeginLoc() : UsingLocation; + return SourceRange(Begin, getNameInfo().getEndLoc()); +} + void UnresolvedUsingTypenameDecl::anchor() { } UnresolvedUsingTypenameDecl * diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index e738ff2b87..c3603038be 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -1155,7 +1155,10 @@ void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) { } void DeclPrinter::VisitUsingDecl(UsingDecl *D) { - Out << "using "; + if (!D->isAccessDeclaration()) + Out << "using "; + if (D->isTypeName()) + Out << "typename "; D->getQualifier()->print(Out, Policy); Out << *D; } @@ -1168,7 +1171,8 @@ DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { } void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { - Out << "using "; + if (!D->isAccessDeclaration()) + Out << "using "; D->getQualifier()->print(Out, Policy); Out << D->getName(); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 0b79953e56..c121efa41c 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -6770,13 +6770,8 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S, return 0; // Warn about access declarations. - // TODO: store that the declaration was written without 'using' and - // talk about access decls instead of using decls in the - // diagnostics. if (!HasUsingKeyword) { - UsingLoc = Name.getLocStart(); - - Diag(UsingLoc, + Diag(Name.getLocStart(), getLangOpts().CPlusPlus11 ? diag::err_access_decl : diag::warn_access_decl_deprecated) << FixItHint::CreateInsertion(SS.getRange().getBegin(), "using "); diff --git a/unittests/AST/SourceLocationTest.cpp b/unittests/AST/SourceLocationTest.cpp index 95ef2c425b..49ecfd3c98 100644 --- a/unittests/AST/SourceLocationTest.cpp +++ b/unittests/AST/SourceLocationTest.cpp @@ -224,5 +224,25 @@ TEST(CXXUnresolvedConstructExpr, SourceRange) { unresolvedConstructExpr(), Args, Lang_CXX11)); } +TEST(UsingDecl, SourceRange) { + RangeVerifier Verifier; + Verifier.expectRange(2, 22, 2, 25); + EXPECT_TRUE(Verifier.match( + "class B { protected: int i; };\n" + "class D : public B { B::i; };", + usingDecl())); +} + +TEST(UnresolvedUsingValueDecl, SourceRange) { + RangeVerifier Verifier; + Verifier.expectRange(3, 3, 3, 6); + EXPECT_TRUE(Verifier.match( + "template \n" + "class D : public B {\n" + " B::i;\n" + "};", + unresolvedUsingValueDecl())); +} + } // end namespace ast_matchers } // end namespace clang