diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-05-18 20:51:54 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-05-18 20:51:54 +0000 |
| commit | 5e16fbe5621804a06a60b886b6f95e018751e92d (patch) | |
| tree | 597c619d11e98bdce21d930caa9e2b1ba35ba53d /clang/lib/Sema/SemaDeclCXX.cpp | |
| parent | 9b0276092336641907aebf4f8b7874314695632b (diff) | |
| download | bcm5719-llvm-5e16fbe5621804a06a60b886b6f95e018751e92d.tar.gz bcm5719-llvm-5e16fbe5621804a06a60b886b6f95e018751e92d.zip | |
Template instantiation for C++ try/catch statements.
llvm-svn: 72035
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 9a74b53da95..d968bc6b75a 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2534,13 +2534,14 @@ Sema::DeclPtrTy Sema::ActOnFinishLinkageSpecification(Scope *S, return LinkageSpec; } -/// ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch -/// handler. -Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) { - QualType ExDeclType = GetTypeForDeclarator(D, S); - SourceLocation Begin = D.getDeclSpec().getSourceRange().getBegin(); - - bool Invalid = D.isInvalidType(); +/// \brief Perform semantic analysis for the variable declaration that +/// occurs within a C++ catch clause, returning the newly-created +/// variable. +VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType, + IdentifierInfo *Name, + SourceLocation Loc, + SourceRange Range) { + bool Invalid = false; // Arrays and functions decay. if (ExDeclType->isArrayType()) @@ -2553,9 +2554,10 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) { // incomplete type, other than [cv] void*. // N2844 forbids rvalue references. if(ExDeclType->isRValueReferenceType()) { - Diag(Begin, diag::err_catch_rvalue_ref) << D.getSourceRange(); + Diag(Loc, diag::err_catch_rvalue_ref) << Range; Invalid = true; } + QualType BaseType = ExDeclType; int Mode = 0; // 0 for direct type, 1 for pointer, 2 for reference unsigned DK = diag::err_catch_incomplete; @@ -2570,18 +2572,36 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) { DK = diag::err_catch_incomplete_ref; } if (!Invalid && (Mode == 0 || !BaseType->isVoidType()) && - RequireCompleteType(Begin, BaseType, DK)) + !BaseType->isDependentType() && RequireCompleteType(Loc, BaseType, DK)) Invalid = true; - if (!Invalid && RequireNonAbstractType(Begin, ExDeclType, - diag::err_abstract_type_in_decl, - AbstractVariableType)) + if (!Invalid && !ExDeclType->isDependentType() && + RequireNonAbstractType(Loc, ExDeclType, + diag::err_abstract_type_in_decl, + AbstractVariableType)) Invalid = true; - // FIXME: Need to test for ability to copy-construct and destroy the exception - // variable. + // FIXME: Need to test for ability to copy-construct and destroy the + // exception variable. + // FIXME: Need to check for abstract classes. + VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc, + Name, ExDeclType, VarDecl::None, + Range.getBegin()); + + if (Invalid) + ExDecl->setInvalidDecl(); + + return ExDecl; +} + +/// ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch +/// handler. +Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) { + QualType ExDeclType = GetTypeForDeclarator(D, S); + + bool Invalid = D.isInvalidType(); IdentifierInfo *II = D.getIdentifier(); if (NamedDecl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) { // The scope should be freshly made just for us. There is just no way @@ -2593,21 +2613,25 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) { } } - VarDecl *ExDecl = VarDecl::Create(Context, CurContext, D.getIdentifierLoc(), - II, ExDeclType, VarDecl::None, Begin); if (D.getCXXScopeSpec().isSet() && !Invalid) { Diag(D.getIdentifierLoc(), diag::err_qualified_catch_declarator) << D.getCXXScopeSpec().getRange(); Invalid = true; } + VarDecl *ExDecl = BuildExceptionDeclaration(S, ExDeclType, + D.getIdentifier(), + D.getIdentifierLoc(), + D.getDeclSpec().getSourceRange()); + if (Invalid) ExDecl->setInvalidDecl(); // Add the exception declaration into this scope. - S->AddDecl(DeclPtrTy::make(ExDecl)); if (II) - IdResolver.AddDecl(ExDecl); + PushOnScopeChains(ExDecl, S); + else + CurContext->addDecl(Context, ExDecl); ProcessDeclAttributes(ExDecl, D); return DeclPtrTy::make(ExDecl); |

