aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-11-17 22:58:34 +0000
committerDouglas Gregor <dgregor@apple.com>2008-11-17 22:58:34 +0000
commit10bd36882406cdf4805e35add1ce2f11ab9ae152 (patch)
treedadf16647fecd2e461b2b18ae40f77dac201905b /lib/Sema/SemaDecl.cpp
parent34265e7133ad82148aa9b3ac097ed66728f4ff85 (diff)
Eliminate all of the placeholder identifiers used for constructors,
destructors, and conversion functions. The placeholders were used to work around the fact that the parser and some of Sema really wanted declarators to have simple identifiers; now, the code that deals with declarators will use DeclarationNames. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59469 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp88
1 files changed, 59 insertions, 29 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index ea2a3ad9a7..9c0a40e74a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -754,14 +754,49 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
return CheckInitList.HadError();
}
+/// GetNameForDeclarator - Determine the full declaration name for the
+/// given Declarator.
+DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
+ switch (D.getKind()) {
+ case Declarator::DK_Abstract:
+ assert(D.getIdentifier() == 0 && "abstract declarators have no name");
+ return DeclarationName();
+
+ case Declarator::DK_Normal:
+ assert (D.getIdentifier() != 0 && "normal declarators have an identifier");
+ return DeclarationName(D.getIdentifier());
+
+ case Declarator::DK_Constructor: {
+ QualType Ty = Context.getTypeDeclType((TypeDecl *)D.getDeclaratorIdType());
+ Ty = Context.getCanonicalType(Ty);
+ return Context.DeclarationNames.getCXXConstructorName(Ty);
+ }
+
+ case Declarator::DK_Destructor: {
+ QualType Ty = Context.getTypeDeclType((TypeDecl *)D.getDeclaratorIdType());
+ Ty = Context.getCanonicalType(Ty);
+ return Context.DeclarationNames.getCXXDestructorName(Ty);
+ }
+
+ case Declarator::DK_Conversion: {
+ QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
+ Ty = Context.getCanonicalType(Ty);
+ return Context.DeclarationNames.getCXXConversionFunctionName(Ty);
+ }
+ }
+
+ assert(false && "Unknown name kind");
+ return DeclarationName();
+}
+
Sema::DeclTy *
Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
ScopedDecl *LastDeclarator = dyn_cast_or_null<ScopedDecl>((Decl *)lastDecl);
- IdentifierInfo *II = D.getIdentifier();
-
+ DeclarationName Name = GetNameForDeclarator(D);
+
// All of these full declarators require an identifier. If it doesn't have
// one, the ParsedFreeStandingDeclSpec action should be used.
- if (II == 0) {
+ if (!Name) {
if (!D.getInvalidType()) // Reject this if we think it is valid.
Diag(D.getDeclSpec().getSourceRange().getBegin(),
diag::err_declarator_need_ident,
@@ -782,10 +817,10 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
// See if this is a redefinition of a variable in the same scope.
if (!D.getCXXScopeSpec().isSet()) {
DC = CurContext;
- PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S);
+ PrevDecl = LookupDecl(Name, Decl::IDNS_Ordinary, S);
} else { // Something like "int foo::x;"
DC = static_cast<DeclContext*>(D.getCXXScopeSpec().getScopeRep());
- PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S, DC);
+ PrevDecl = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC);
// C++ 7.3.1.2p2:
// Members (including explicit specializations of templates) of a named
@@ -798,16 +833,17 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
if (PrevDecl == 0) {
// No previous declaration in the qualifying scope.
Diag(D.getIdentifierLoc(), diag::err_typecheck_no_member,
- II->getName(), D.getCXXScopeSpec().getRange());
+ Name.getAsString(), D.getCXXScopeSpec().getRange());
} else if (!CurContext->Encloses(DC)) {
// The qualifying scope doesn't enclose the original declaration.
// Emit diagnostic based on current scope.
SourceLocation L = D.getIdentifierLoc();
SourceRange R = D.getCXXScopeSpec().getRange();
if (isa<FunctionDecl>(CurContext)) {
- Diag(L, diag::err_invalid_declarator_in_function, II->getName(), R);
+ Diag(L, diag::err_invalid_declarator_in_function, Name.getAsString(),
+ R);
} else {
- Diag(L, diag::err_invalid_declarator_scope, II->getName(),
+ Diag(L, diag::err_invalid_declarator_scope, Name.getAsString(),
cast<NamedDecl>(DC)->getName(), R);
}
}
@@ -878,13 +914,9 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
bool isInvalidDecl = CheckConstructorDeclarator(D, R, SC);
// Create the new declaration
- QualType ClassType = Context.getTypeDeclType(cast<CXXRecordDecl>(DC));
- ClassType = Context.getCanonicalType(ClassType);
- DeclarationName ConName
- = Context.DeclarationNames.getCXXConstructorName(ClassType);
NewFD = CXXConstructorDecl::Create(Context,
cast<CXXRecordDecl>(DC),
- D.getIdentifierLoc(), ConName, R,
+ D.getIdentifierLoc(), Name, R,
isExplicit, isInline,
/*isImplicitlyDeclared=*/false);
@@ -895,14 +927,9 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
if (DC->isCXXRecord()) {
bool isInvalidDecl = CheckDestructorDeclarator(D, R, SC);
- QualType ClassType = Context.getTypeDeclType(cast<CXXRecordDecl>(DC));
- ClassType = Context.getCanonicalType(ClassType);
- DeclarationName DesName
- = Context.DeclarationNames.getCXXDestructorName(ClassType);
-
NewFD = CXXDestructorDecl::Create(Context,
cast<CXXRecordDecl>(DC),
- D.getIdentifierLoc(), DesName, R,
+ D.getIdentifierLoc(), Name, R,
isInline,
/*isImplicitlyDeclared=*/false);
@@ -913,7 +940,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
// Create a FunctionDecl to satisfy the function definition parsing
// code path.
NewFD = FunctionDecl::Create(Context, DC, D.getIdentifierLoc(),
- II, R, SC, isInline, LastDeclarator,
+ Name, R, SC, isInline, LastDeclarator,
// FIXME: Move to DeclGroup...
D.getDeclSpec().getSourceRange().getBegin());
NewFD->setInvalidDecl();
@@ -926,14 +953,9 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
} else {
bool isInvalidDecl = CheckConversionDeclarator(D, R, SC);
- QualType ConvType = R->getAsFunctionType()->getResultType();
- ConvType = Context.getCanonicalType(ConvType);
- DeclarationName ConvName
- = Context.DeclarationNames.getCXXConversionFunctionName(ConvType);
-
NewFD = CXXConversionDecl::Create(Context,
cast<CXXRecordDecl>(DC),
- D.getIdentifierLoc(), ConvName, R,
+ D.getIdentifierLoc(), Name, R,
isInline, isExplicit);
if (isInvalidDecl)
@@ -942,13 +964,13 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
} else if (DC->isCXXRecord()) {
// This is a C++ method declaration.
NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(DC),
- D.getIdentifierLoc(), II, R,
+ D.getIdentifierLoc(), Name, R,
(SC == FunctionDecl::Static), isInline,
LastDeclarator);
} else {
NewFD = FunctionDecl::Create(Context, DC,
D.getIdentifierLoc(),
- II, R, SC, isInline, LastDeclarator,
+ Name, R, SC, isInline, LastDeclarator,
// FIXME: Move to DeclGroup...
D.getDeclSpec().getSourceRange().getBegin());
}
@@ -1128,6 +1150,14 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
Diag(D.getIdentifierLoc(), diag::err_mutable_nonmember);
InvalidDecl = true;
}
+
+ IdentifierInfo *II = Name.getAsIdentifierInfo();
+ if (!II) {
+ Diag(D.getIdentifierLoc(), diag::err_bad_variable_name,
+ Name.getAsString());
+ return 0;
+ }
+
if (DC->isCXXRecord()) {
assert(SC == VarDecl::Static && "Invalid storage class for member!");
// This is a static data member for a C++ class.
@@ -1184,7 +1214,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
New->setLexicalDeclContext(CurContext);
// If this has an identifier, add it to the scope stack.
- if (II)
+ if (Name)
PushOnScopeChains(New, S);
// If any semantic error occurred, mark the decl as invalid.
if (D.getInvalidType() || InvalidDecl)