diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-12-12 08:25:50 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-12-12 08:25:50 +0000 |
commit | 4287b3738923ee6c833c42937aed8735ee9c45e0 (patch) | |
tree | b1b4236e63bf4d802e587738c65e9720f7eae1b7 /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | e4bcb8e2dd976268eed4db589ddc94edd6408d40 (diff) | |
download | bcm5719-llvm-4287b3738923ee6c833c42937aed8735ee9c45e0.tar.gz bcm5719-llvm-4287b3738923ee6c833c42937aed8735ee9c45e0.zip |
Enable out-of-line definitions of C++ constructors and destructors
llvm-svn: 60947
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 39 |
1 files changed, 24 insertions, 15 deletions
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()); |