diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-11-07 22:02:30 +0000 |
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-11-07 22:02:30 +0000 |
| commit | e442635c37e56c92ba66f74bf73192751576c4e8 (patch) | |
| tree | b8d81feffff20b386b443d5f87d367e72a87aba8 /clang/lib | |
| parent | cc0d2cfa014b3b53c605af443eef670b6ee596f3 (diff) | |
| download | bcm5719-llvm-e442635c37e56c92ba66f74bf73192751576c4e8.tar.gz bcm5719-llvm-e442635c37e56c92ba66f74bf73192751576c4e8.zip | |
Changes in preparation for nested-name-specifiers.
-When parsing declarators, don't depend on "CurScope->isCXXClassScope() == true" for constructors/destructors
-For C++ member declarations, don't depend on "Declarator.getContext() == Declarator::MemberContext"
llvm-svn: 58866
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 39 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 36 |
2 files changed, 44 insertions, 31 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 58cc9e2c6b3..2b18be02a3d 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1355,6 +1355,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D, bool PtrOperator) { /// conversion-function-id [TODO] /// '~' class-name /// template-id [TODO] +/// void Parser::ParseDirectDeclarator(Declarator &D) { // Parse the first direct-declarator seen. if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) { @@ -1362,31 +1363,35 @@ void Parser::ParseDirectDeclarator(Declarator &D) { // Determine whether this identifier is a C++ constructor name or // a normal identifier. if (getLang().CPlusPlus && - CurScope->isCXXClassScope() && Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope)) D.SetConstructor(Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope), Tok.getIdentifierInfo(), Tok.getLocation()); else D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); ConsumeToken(); - } else if (getLang().CPlusPlus && Tok.is(tok::tilde) && - CurScope->isCXXClassScope() && D.mayHaveIdentifier()) { + } else if (getLang().CPlusPlus && + Tok.is(tok::tilde) && D.mayHaveIdentifier()) { // This should be a C++ destructor. SourceLocation TildeLoc = ConsumeToken(); - - // Use the next identifier and "~" to form a name for the - // destructor. This is useful both for diagnostics and for - // correctness of the parser, since we use presence/absence of the - // identifier to determine what we parsed. - // FIXME: We could end up with a template-id here, once we parse - // templates, and will have to do something different to form the - // name of the destructor. - assert(Tok.is(tok::identifier) && "Expected identifier"); - IdentifierInfo *II = Tok.getIdentifierInfo(); - II = &PP.getIdentifierTable().get(std::string("~") + II->getName()); - - if (TypeTy *Type = ParseClassName()) - D.SetDestructor(Type, II, TildeLoc); + if (Tok.is(tok::identifier)) { + // Use the next identifier and "~" to form a name for the + // destructor. This is useful both for diagnostics and for + // correctness of the parser, since we use presence/absence of the + // identifier to determine what we parsed. + // FIXME: We could end up with a template-id here, once we parse + // templates, and will have to do something different to form the + // name of the destructor. + IdentifierInfo *II = Tok.getIdentifierInfo(); + II = &PP.getIdentifierTable().get(std::string("~") + II->getName()); + + if (TypeTy *Type = ParseClassName()) + D.SetDestructor(Type, II, TildeLoc); + else + D.SetIdentifier(0, TildeLoc); + } else { + Diag(Tok, diag::err_expected_class_name); + D.SetIdentifier(0, TildeLoc); + } } else if (Tok.is(tok::kw_operator)) { SourceLocation OperatorLoc = Tok.getLocation(); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 12a4b08e919..18d77c4a18c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -811,7 +811,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { FunctionDecl *NewFD; if (D.getKind() == Declarator::DK_Constructor) { // This is a C++ constructor declaration. - assert(D.getContext() == Declarator::MemberContext && + assert(CurContext->isCXXRecord() && "Constructors can only be declared in a member context"); bool isInvalidDecl = CheckConstructorDeclarator(D, R, SC); @@ -827,21 +827,29 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { NewFD->setInvalidDecl(); } else if (D.getKind() == Declarator::DK_Destructor) { // This is a C++ destructor declaration. - assert(D.getContext() == Declarator::MemberContext && - "Destructor can only be declared in a member context"); + if (CurContext->isCXXRecord()) { + bool isInvalidDecl = CheckDestructorDeclarator(D, R, SC); - bool isInvalidDecl = CheckDestructorDeclarator(D, R, SC); - - NewFD = CXXDestructorDecl::Create(Context, - cast<CXXRecordDecl>(CurContext), - D.getIdentifierLoc(), II, R, - isInline, - /*isImplicitlyDeclared=*/false); + NewFD = CXXDestructorDecl::Create(Context, + cast<CXXRecordDecl>(CurContext), + D.getIdentifierLoc(), II, R, + isInline, + /*isImplicitlyDeclared=*/false); - if (isInvalidDecl) + if (isInvalidDecl) + NewFD->setInvalidDecl(); + } else { + Diag(D.getIdentifierLoc(), diag::err_destructor_not_member); + // Create a FunctionDecl to satisfy the function definition parsing + // code path. + NewFD = FunctionDecl::Create(Context, CurContext, D.getIdentifierLoc(), + II, R, SC, isInline, LastDeclarator, + // FIXME: Move to DeclGroup... + D.getDeclSpec().getSourceRange().getBegin()); NewFD->setInvalidDecl(); + } } else if (D.getKind() == Declarator::DK_Conversion) { - if (D.getContext() != Declarator::MemberContext) { + if (!CurContext->isCXXRecord()) { Diag(D.getIdentifierLoc(), diag::err_conv_function_not_member); return 0; @@ -856,7 +864,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { if (isInvalidDecl) NewFD->setInvalidDecl(); } - } else if (D.getContext() == Declarator::MemberContext) { + } else if (CurContext->isCXXRecord()) { // This is a C++ method declaration. NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(CurContext), D.getIdentifierLoc(), II, R, @@ -1037,7 +1045,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { case DeclSpec::SCS_register: SC = VarDecl::Register; break; case DeclSpec::SCS_private_extern: SC = VarDecl::PrivateExtern; break; } - if (D.getContext() == Declarator::MemberContext) { + if (CurContext->isCXXRecord()) { assert(SC == VarDecl::Static && "Invalid storage class for member!"); // This is a static data member for a C++ class. NewVD = CXXClassVarDecl::Create(Context, cast<CXXRecordDecl>(CurContext), |

