]> granicus.if.org Git - clang/commitdiff
Fixed source range of C++03 access declarations.
authorEnea Zaffanella <zaffanella@cs.unipr.it>
Wed, 17 Jul 2013 17:28:56 +0000 (17:28 +0000)
committerEnea Zaffanella <zaffanella@cs.unipr.it>
Wed, 17 Jul 2013 17:28:56 +0000 (17:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186522 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclCXX.h
include/clang/ASTMatchers/ASTMatchers.h
lib/AST/DeclCXX.cpp
lib/AST/DeclPrinter.cpp
lib/Sema/SemaDeclCXX.cpp
unittests/AST/SourceLocationTest.cpp

index 52909fbb037e7a3502448220642bac46279e8a8c..c3b8edca3080a69b8aef99cb8eedafb36ab067b6 100644 (file)
@@ -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; }
index 151bed5a837c991bba2d33c8f3b083ac4b7f37f9..18bfe15486d245e5c18ce93dd41f8a78b1dc9fc1 100644 (file)
@@ -626,6 +626,21 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
 ///   matches \code using X::x \endcode
 const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
 
+/// \brief Matches unresolved using value declarations.
+///
+/// Given
+/// \code
+///   template<typename X>
+///   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
index 4a9da79577a86294dfda7ee384733069065aa1cd..dacb867df65eb487f331fe0e6871e3f6ed37f48e 100644 (file)
@@ -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 *
index e738ff2b87a78dac574cc345bc42232d3b331019..c3603038be3fff8942f8bc9c6ef1ec8f1fc5d707 100644 (file)
@@ -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();
 }
index 0b79953e56d3b48f2df7477720dbf59ae1186a6d..c121efa41ccf8918cfc7c391b8b4041fd6a43f35 100644 (file)
@@ -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 ");
index 95ef2c425b5cb10fbac4733f4f237aab1e3f854b..49ecfd3c9812519aa129c8c51901a856796a4652 100644 (file)
@@ -224,5 +224,25 @@ TEST(CXXUnresolvedConstructExpr, SourceRange) {
       unresolvedConstructExpr(), Args, Lang_CXX11));
 }
 
+TEST(UsingDecl, SourceRange) {
+  RangeVerifier<UsingDecl> 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<UnresolvedUsingValueDecl> Verifier;
+  Verifier.expectRange(3, 3, 3, 6);
+  EXPECT_TRUE(Verifier.match(
+      "template <typename B>\n"
+      "class D : public B {\n"
+      "  B::i;\n"
+      "};",
+      unresolvedUsingValueDecl()));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang