[cfe-commits] r58866 - in /cfe/trunk: include/clang/AST/DeclBase.h include/clang/Basic/DiagnosticKinds.def lib/Parse/ParseDecl.cpp lib/Sema/SemaDecl.cpp test/SemaCXX/destructor.cpp
Argiris Kirtzidis
akyrtzi at gmail.com
Fri Nov 7 14:02:31 PST 2008
Author: akirtzidis
Date: Fri Nov 7 16:02:30 2008
New Revision: 58866
URL: http://llvm.org/viewvc/llvm-project?rev=58866&view=rev
Log:
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"
Modified:
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/SemaCXX/destructor.cpp
Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=58866&r1=58865&r2=58866&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Fri Nov 7 16:02:30 2008
@@ -310,6 +310,10 @@
}
}
+ bool isCXXRecord() const {
+ return DeclKind == Decl::CXXRecord;
+ }
+
const ScopedDecl *getDeclChain() const { return DeclChain; }
ScopedDecl *getDeclChain() { return DeclChain; }
void setDeclChain(ScopedDecl *D) { DeclChain = D; }
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=58866&r1=58865&r2=58866&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Nov 7 16:02:30 2008
@@ -691,6 +691,8 @@
"copy constructor must pass its first argument by reference")
// C++ destructors
+DIAG(err_destructor_not_member, ERROR,
+ "destructor must be a non-static member function")
DIAG(err_destructor_cannot_be, ERROR,
"destructor cannot be declared '%0'")
DIAG(err_invalid_qualified_destructor, ERROR,
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=58866&r1=58865&r2=58866&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Nov 7 16:02:30 2008
@@ -1355,6 +1355,7 @@
/// 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 @@
// 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();
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=58866&r1=58865&r2=58866&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Nov 7 16:02:30 2008
@@ -811,7 +811,7 @@
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 @@
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 @@
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 @@
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),
Modified: cfe/trunk/test/SemaCXX/destructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/destructor.cpp?rev=58866&r1=58865&r2=58866&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/destructor.cpp (original)
+++ cfe/trunk/test/SemaCXX/destructor.cpp Fri Nov 7 16:02:30 2008
@@ -35,3 +35,6 @@
~F(); // expected-error{{destructor cannot be redeclared}}
};
+~; // expected-error {{expected class name}}
+~undef(); // expected-error {{expected class name}}
+~F(){} // expected-error {{destructor must be a non-static member function}}
More information about the cfe-commits
mailing list