diff options
-rw-r--r-- | include/clang/AST/Decl.h | 10 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 25 | ||||
-rw-r--r-- | lib/AST/CXXInheritance.cpp | 25 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 23 |
5 files changed, 44 insertions, 41 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 813e83accd..ac79a91792 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -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, diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index c858c5c0df..cc95390338 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -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); diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp index b59b45f646..d4f6e87173 100644 --- a/lib/AST/CXXInheritance.cpp +++ b/lib/AST/CXXInheritance.cpp @@ -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); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d1eaa6bb60..2fb8d10250 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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(); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 4be5c62ee0..d094ea4b0f 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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); |