]> granicus.if.org Git - clang/commitdiff
Random const correctness, and incidentally use computeDeclContext when building
authorJohn McCall <rjmccall@apple.com>
Thu, 12 Nov 2009 03:15:40 +0000 (03:15 +0000)
committerJohn McCall <rjmccall@apple.com>
Thu, 12 Nov 2009 03:15:40 +0000 (03:15 +0000)
a using declaration.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86942 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
include/clang/AST/DeclCXX.h
lib/AST/CXXInheritance.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp

index 813e83accdb1a1f7065e5cd9f70ecf6d05737824..ac79a91792d7136f064e004587cddc69c180c6a7 100644 (file)
@@ -232,6 +232,7 @@ public:
   void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; }
 
   virtual NamespaceDecl *getCanonicalDecl() { return OrigNamespace; }
+  const NamespaceDecl *getCanonicalDecl() const { return OrigNamespace; }
 
   virtual SourceRange getSourceRange() const {
     return SourceRange(getLocation(), RBracLoc);
@@ -552,6 +553,9 @@ public:
   }
 
   virtual VarDecl *getCanonicalDecl();
+  const VarDecl *getCanonicalDecl() const {
+    return const_cast<VarDecl*>(this)->getCanonicalDecl();
+  }
 
   /// hasLocalStorage - Returns true if a variable with function scope
   ///  is a non-static local variable.
@@ -1424,6 +1428,9 @@ public:
   virtual SourceRange getSourceRange() const;
 
   virtual TagDecl* getCanonicalDecl();
+  const TagDecl* getCanonicalDecl() const {
+    return const_cast<TagDecl*>(this)->getCanonicalDecl();
+  }
 
   /// isDefinition - Return true if this decl has its body specified.
   bool isDefinition() const {
@@ -1515,6 +1522,9 @@ public:
   EnumDecl *getCanonicalDecl() {
     return cast<EnumDecl>(TagDecl::getCanonicalDecl());
   }
+  const EnumDecl *getCanonicalDecl() const {
+    return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+  }
 
   static EnumDecl *Create(ASTContext &C, DeclContext *DC,
                           SourceLocation L, IdentifierInfo *Id,
index c858c5c0df787a3825db84e5ae91ae2014fe414f..cc953903382db3e439166fce35bf9ccbb9194d2f 100644 (file)
@@ -432,6 +432,9 @@ public:
   virtual CXXRecordDecl *getCanonicalDecl() {
     return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
   }
+  virtual const CXXRecordDecl *getCanonicalDecl() const {
+    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
+  }
 
   static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
                                SourceLocation L, IdentifierInfo *Id,
@@ -768,7 +771,7 @@ public:
   /// \param Base the base class we are searching for.
   ///
   /// \returns true if this class is derived from Base, false otherwise.
-  bool isDerivedFrom(CXXRecordDecl *Base);
+  bool isDerivedFrom(CXXRecordDecl *Base) const;
   
   /// \brief Determine whether this class is derived from the type \p Base.
   ///
@@ -786,7 +789,7 @@ public:
   ///
   /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than 
   /// tangling input and output in \p Paths  
-  bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths);
+  bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const;
   
   /// \brief Function type used by lookupInBases() to determine whether a 
   /// specific base class subobject matches the lookup criteria.
@@ -801,7 +804,7 @@ public:
   /// lookupInBases().
   ///
   /// \returns true if this base matched the search criteria, false otherwise.
-  typedef bool BaseMatchesCallback(CXXBaseSpecifier *Specifier,
+  typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier,
                                    CXXBasePath &Path,
                                    void *UserData);
   
@@ -826,7 +829,7 @@ public:
   /// \returns true if there exists any path from this class to a base class
   /// subobject that matches the search criteria.
   bool lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData,
-                     CXXBasePaths &Paths);
+                     CXXBasePaths &Paths) const;
   
   /// \brief Base-class lookup callback that determines whether the given
   /// base class specifier refers to a specific class declaration.
@@ -835,8 +838,8 @@ public:
   /// a given derived class has is a base class subobject of a particular type.
   /// The user data pointer should refer to the canonical CXXRecordDecl of the
   /// base class that we are searching for.
-  static bool FindBaseClass(CXXBaseSpecifier *Specifier, CXXBasePath &Path,
-                            void *BaseRecord);
+  static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
+                            CXXBasePath &Path, void *BaseRecord);
   
   /// \brief Base-class lookup callback that determines whether there exists
   /// a tag with the given name.
@@ -844,8 +847,8 @@ public:
   /// This callback can be used with \c lookupInBases() to find tag members
   /// of the given name within a C++ class hierarchy. The user data pointer
   /// is an opaque \c DeclarationName pointer.
-  static bool FindTagMember(CXXBaseSpecifier *Specifier, CXXBasePath &Path,
-                            void *Name);
+  static bool FindTagMember(const CXXBaseSpecifier *Specifier,
+                            CXXBasePath &Path, void *Name);
 
   /// \brief Base-class lookup callback that determines whether there exists
   /// a member with the given name.
@@ -853,8 +856,8 @@ public:
   /// This callback can be used with \c lookupInBases() to find members
   /// of the given name within a C++ class hierarchy. The user data pointer
   /// is an opaque \c DeclarationName pointer.
-  static bool FindOrdinaryMember(CXXBaseSpecifier *Specifier, CXXBasePath &Path,
-                                 void *Name);
+  static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
+                                 CXXBasePath &Path, void *Name);
   
   /// \brief Base-class lookup callback that determines whether there exists
   /// a member with the given name that can be used in a nested-name-specifier.
@@ -862,7 +865,7 @@ public:
   /// This callback can be used with \c lookupInBases() to find membes of
   /// the given name within a C++ class hierarchy that can occur within
   /// nested-name-specifiers.
-  static bool FindNestedNameSpecifierMember(CXXBaseSpecifier *Specifier, 
+  static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
                                             CXXBasePath &Path,
                                             void *UserData);
   
index b59b45f6467e32eb6e83ae51bb61519876b7fbbe..d4f6e8717319d04426d193733aab1922ad0ae80e 100644 (file)
@@ -76,28 +76,28 @@ void CXXBasePaths::swap(CXXBasePaths &Other) {
   std::swap(DetectedVirtual, Other.DetectedVirtual);
 }
 
-bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base) {
+bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base) const {
   CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
                      /*DetectVirtual=*/false);
   return isDerivedFrom(Base, Paths);
 }
 
-bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) {
+bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const {
   if (getCanonicalDecl() == Base->getCanonicalDecl())
     return false;
   
-  Paths.setOrigin(this);
+  Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
   return lookupInBases(&FindBaseClass, Base->getCanonicalDecl(), Paths);
 }
 
 bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
                                   void *UserData,
-                                  CXXBasePaths &Paths) {
+                                  CXXBasePaths &Paths) const {
   bool FoundPath = false;
   
   ASTContext &Context = getASTContext();
-  for (base_class_iterator BaseSpec = bases_begin(), BaseSpecEnd = bases_end();
-       BaseSpec != BaseSpecEnd; ++BaseSpec) {
+  for (base_class_const_iterator BaseSpec = bases_begin(),
+         BaseSpecEnd = bases_end(); BaseSpec != BaseSpecEnd; ++BaseSpec) {
     // Find the record of the base class subobjects for this type.
     QualType BaseType = Context.getCanonicalType(BaseSpec->getType());
     BaseType = BaseType.getUnqualifiedType();
@@ -183,7 +183,7 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
   return FoundPath;
 }
 
-bool CXXRecordDecl::FindBaseClass(CXXBaseSpecifier *Specifier, 
+bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier, 
                                   CXXBasePath &Path,
                                   void *BaseRecord) {
   assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
@@ -192,7 +192,7 @@ bool CXXRecordDecl::FindBaseClass(CXXBaseSpecifier *Specifier,
            ->getCanonicalDecl() == BaseRecord;
 }
 
-bool CXXRecordDecl::FindTagMember(CXXBaseSpecifier *Specifier, 
+bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier, 
                                   CXXBasePath &Path,
                                   void *Name) {
   RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
@@ -208,7 +208,7 @@ bool CXXRecordDecl::FindTagMember(CXXBaseSpecifier *Specifier,
   return false;
 }
 
-bool CXXRecordDecl::FindOrdinaryMember(CXXBaseSpecifier *Specifier, 
+bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, 
                                        CXXBasePath &Path,
                                        void *Name) {
   RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
@@ -225,9 +225,10 @@ bool CXXRecordDecl::FindOrdinaryMember(CXXBaseSpecifier *Specifier,
   return false;
 }
 
-bool CXXRecordDecl::FindNestedNameSpecifierMember(CXXBaseSpecifier *Specifier, 
-                                                  CXXBasePath &Path,
-                                                  void *Name) {
+bool CXXRecordDecl::
+FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, 
+                              CXXBasePath &Path,
+                              void *Name) {
   RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
   
   DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
index d1eaa6bb60b0612066cad72fb42a30dea4c81196..2fb8d10250e7af772066476a124bc71a7b1acdb2 100644 (file)
@@ -2453,7 +2453,7 @@ struct FindOverriddenMethodData {
 /// \brief Member lookup function that determines whether a given C++
 /// method overrides a method in a base class, to be used with
 /// CXXRecordDecl::lookupInBases().
-static bool FindOverriddenMethod(CXXBaseSpecifier *Specifier,
+static bool FindOverriddenMethod(const CXXBaseSpecifier *Specifier,
                                  CXXBasePath &Path,
                                  void *UserData) {
   RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
index 4be5c62ee04313dd87de9dce8526ff5d4fc3fe60..d094ea4b0fad3d67e9af212a9bd2dbed1e61a3f9 100644 (file)
@@ -2839,14 +2839,13 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc,
   NestedNameSpecifier *NNS =
     static_cast<NestedNameSpecifier *>(SS.getScopeRep());
 
-  if (isUnknownSpecialization(SS)) {
+  DeclContext *LookupContext = computeDeclContext(SS);
+  if (!LookupContext) {
     return UnresolvedUsingDecl::Create(Context, CurContext, UsingLoc,
                                        SS.getRange(), NNS,
                                        IdentLoc, Name, IsTypeName);
   }
 
-  DeclContext *LookupContext = 0;
-
   if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(CurContext)) {
     // C++0x N2914 [namespace.udecl]p3:
     // A using-declaration used as a member-declaration shall refer to a member
@@ -2854,34 +2853,24 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc,
     // anonymous union that is a member of a base class of the class being
     // defined, or shall refer to an enumerator for an enumeration type that is
     // a member of a base class of the class being defined.
-    const Type *Ty = NNS->getAsType();
-    if (!Ty || !IsDerivedFrom(Context.getTagDeclType(RD), QualType(Ty, 0))) {
+
+    CXXRecordDecl *LookupRD = dyn_cast<CXXRecordDecl>(LookupContext);
+    if (!LookupRD || !RD->isDerivedFrom(LookupRD)) {
       Diag(SS.getRange().getBegin(),
            diag::err_using_decl_nested_name_specifier_is_not_a_base_class)
         << NNS << RD->getDeclName();
       return 0;
     }
-
-    QualType BaseTy = Context.getCanonicalType(QualType(Ty, 0));
-    LookupContext = BaseTy->getAs<RecordType>()->getDecl();
   } else {
     // C++0x N2914 [namespace.udecl]p8:
     // A using-declaration for a class member shall be a member-declaration.
-    if (NNS->getKind() == NestedNameSpecifier::TypeSpec) {
+    if (isa<CXXRecordDecl>(LookupContext)) {
       Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_class_member)
         << SS.getRange();
       return 0;
     }
-
-    // C++0x N2914 [namespace.udecl]p9:
-    // In a using-declaration, a prefix :: refers to the global namespace.
-    if (NNS->getKind() == NestedNameSpecifier::Global)
-      LookupContext = Context.getTranslationUnitDecl();
-    else
-      LookupContext = NNS->getAsNamespace();
   }
 
-
   // Lookup target name.
   LookupResult R;
   LookupQualifiedName(R, LookupContext, Name, LookupOrdinaryName);