summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-05-18 20:51:54 +0000
committerDouglas Gregor <dgregor@apple.com>2009-05-18 20:51:54 +0000
commit5e16fbe5621804a06a60b886b6f95e018751e92d (patch)
tree597c619d11e98bdce21d930caa9e2b1ba35ba53d /clang/lib/Sema/SemaDeclCXX.cpp
parent9b0276092336641907aebf4f8b7874314695632b (diff)
downloadbcm5719-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.cpp60
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);
OpenPOWER on IntegriCloud