diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-01-13 17:31:36 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-01-13 17:31:36 +0000 |
commit | 9de54ea41bdcf97f238ba9c4a1fa1d091d5813d9 (patch) | |
tree | cba2865d8d63cf45bf9270ea576c1e68bd757a88 /clang/lib/Sema | |
parent | b89b99f1f267237d68712b728b4aa5c90907cb48 (diff) | |
download | bcm5719-llvm-9de54ea41bdcf97f238ba9c4a1fa1d091d5813d9.tar.gz bcm5719-llvm-9de54ea41bdcf97f238ba9c4a1fa1d091d5813d9.zip |
Reimplement constructor declarator parsing to cope with template-ids
that name constructors, the endless joys of out-of-line constructor
definitions, and various other corner cases that the previous hack
never imagined. Fixes PR5688 and tightens up semantic analysis for
constructor names.
Additionally, fixed a problem where we wouldn't properly enter the
declarator scope of a parenthesized declarator. We were entering the
scope, then leaving it when we saw the ")"; now, we re-enter the
declarator scope before parsing the parameter list.
Note that we are forced to perform some tentative parsing within a
class (call it C) to tell the difference between
C(int); // constructor
and
C (f)(int); // member function
which is rather unfortunate. And, although it isn't necessary for
correctness, we use the same tentative-parsing mechanism for
out-of-line constructors to improve diagnostics in icky cases like:
C::C C::f(int); // error: C::C refers to the constructor name, but
// we complain nicely and recover by treating it as
// a type.
llvm-svn: 93322
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 1 |
3 files changed, 26 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e53f141c960..948418b42a6 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1972,6 +1972,30 @@ DeclarationName Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { Context.getCanonicalType(Ty)); } + case UnqualifiedId::IK_ConstructorTemplateId: { + // In well-formed code, we can only have a constructor + // template-id that refers to the current context, so go there + // to find the actual type being constructed. + CXXRecordDecl *CurClass = dyn_cast<CXXRecordDecl>(CurContext); + if (!CurClass || CurClass->getIdentifier() != Name.TemplateId->Name) + return DeclarationName(); + + // Determine the type of the class being constructed. + QualType CurClassType; + if (ClassTemplateDecl *ClassTemplate + = CurClass->getDescribedClassTemplate()) + CurClassType = ClassTemplate->getInjectedClassNameType(Context); + else + CurClassType = Context.getTypeDeclType(CurClass); + + // FIXME: Check two things: that the template-id names the same type as + // CurClassType, and that the template-id does not occur when the name + // was qualified. + + return Context.DeclarationNames.getCXXConstructorName( + Context.getCanonicalType(CurClassType)); + } + case UnqualifiedId::IK_DestructorName: { QualType Ty = GetTypeFromParser(Name.DestructorName); if (Ty.isNull()) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index edeb7c13e10..a81a04e45e1 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -3002,6 +3002,7 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S, break; case UnqualifiedId::IK_ConstructorName: + case UnqualifiedId::IK_ConstructorTemplateId: // C++0x inherited constructors. if (getLangOptions().CPlusPlus0x) break; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 2bddf9ecd60..7c0460dbedf 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -897,6 +897,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, break; case UnqualifiedId::IK_ConstructorName: + case UnqualifiedId::IK_ConstructorTemplateId: case UnqualifiedId::IK_DestructorName: // Constructors and destructors don't have return types. Use // "void" instead. |