diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 27 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 39 |
2 files changed, 51 insertions, 15 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 29d636fabdc..2c5e46afa0e 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -246,6 +246,24 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S, } else if (LookupCtx) { assert(getLangOptions().CPlusPlus && "No qualified name lookup in C"); + switch (Name.getNameKind()) { + case DeclarationName::CXXConstructorName: + if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(LookupCtx)) + return const_cast<CXXRecordDecl *>(Record)->getConstructors(); + else + return 0; + + case DeclarationName::CXXDestructorName: + if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(LookupCtx)) + return Record->getDestructor(); + else + return 0; + + default: + // Normal name lookup. + break; + } + // Perform qualified name lookup into the LookupCtx. // FIXME: Will need to look into base classes and such. DeclContext::lookup_const_iterator I, E; @@ -932,6 +950,15 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { // after the point of declaration in a namespace that encloses the // declarations namespace. // + // FIXME: We need to perform this check later, once we know that + // we've actually found a redeclaration. Otherwise, just the fact + // that there is some entity with the same name will suppress this + // diagnostic, e.g., we fail to diagnose: + // class X { + // void f(); + // }; + // + // void X::f(int) { } // ill-formed, but we don't complain. if (PrevDecl == 0) { // No previous declaration in the qualifying scope. Diag(D.getIdentifierLoc(), diag::err_typecheck_no_member) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 1b189f87fcb..40fcecfb1cd 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1104,16 +1104,16 @@ Sema::DeclTy *Sema::ActOnConstructorDeclarator(CXXConstructorDecl *ConDecl) { // Check default arguments on the constructor CheckCXXDefaultArguments(ConDecl); - CXXRecordDecl *ClassDecl = dyn_cast_or_null<CXXRecordDecl>(CurContext); - if (!ClassDecl) { - ConDecl->setInvalidDecl(); - return ConDecl; - } + // Set the lexical context of this constructor + ConDecl->setLexicalDeclContext(CurContext); + + CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ConDecl->getDeclContext()); // Make sure this constructor is an overload of the existing // constructors. OverloadedFunctionDecl::function_iterator MatchedDecl; - if (!IsOverload(ConDecl, ClassDecl->getConstructors(), MatchedDecl)) { + if (!IsOverload(ConDecl, ClassDecl->getConstructors(), MatchedDecl) && + CurContext == (*MatchedDecl)->getLexicalDeclContext()) { Diag(ConDecl->getLocation(), diag::err_constructor_redeclared) << SourceRange(ConDecl->getLocation()); Diag((*MatchedDecl)->getLocation(), diag::note_previous_declaration) @@ -1122,7 +1122,6 @@ Sema::DeclTy *Sema::ActOnConstructorDeclarator(CXXConstructorDecl *ConDecl) { return ConDecl; } - // C++ [class.copy]p3: // A declaration of a constructor for a class X is ill-formed if // its first parameter is of type (optionally cv-qualified) X and @@ -1155,16 +1154,23 @@ Sema::DeclTy *Sema::ActOnConstructorDeclarator(CXXConstructorDecl *ConDecl) { Sema::DeclTy *Sema::ActOnDestructorDeclarator(CXXDestructorDecl *Destructor) { assert(Destructor && "Expected to receive a destructor declaration"); - CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CurContext); + CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Destructor->getDeclContext()); + + // Set the lexical context of this destructor + Destructor->setLexicalDeclContext(CurContext); // Make sure we aren't redeclaring the destructor. if (CXXDestructorDecl *PrevDestructor = ClassDecl->getDestructor()) { - Diag(Destructor->getLocation(), diag::err_destructor_redeclared); - Diag(PrevDestructor->getLocation(), - PrevDestructor->isThisDeclarationADefinition() ? - diag::note_previous_definition - : diag::note_previous_declaration); - Destructor->setInvalidDecl(); + if (CurContext == PrevDestructor->getLexicalDeclContext()) { + Diag(Destructor->getLocation(), diag::err_destructor_redeclared); + Diag(PrevDestructor->getLocation(), + PrevDestructor->isThisDeclarationADefinition() ? + diag::note_previous_definition + : diag::note_previous_declaration); + Destructor->setInvalidDecl(); + } + + // FIXME: Just drop the definition (for now). return Destructor; } @@ -1179,7 +1185,10 @@ Sema::DeclTy *Sema::ActOnDestructorDeclarator(CXXDestructorDecl *Destructor) { Sema::DeclTy *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) { assert(Conversion && "Expected to receive a conversion function declaration"); - CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CurContext); + // Set the lexical context of this conversion function + Conversion->setLexicalDeclContext(CurContext); + + CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Conversion->getDeclContext()); // Make sure we aren't redeclaring the conversion function. QualType ConvType = Context.getCanonicalType(Conversion->getConversionType()); |

