summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-01-13 17:31:36 +0000
committerDouglas Gregor <dgregor@apple.com>2010-01-13 17:31:36 +0000
commit9de54ea41bdcf97f238ba9c4a1fa1d091d5813d9 (patch)
treecba2865d8d63cf45bf9270ea576c1e68bd757a88 /clang/lib/Sema/SemaDecl.cpp
parentb89b99f1f267237d68712b728b4aa5c90907cb48 (diff)
downloadbcm5719-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/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp24
1 files changed, 24 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())
OpenPOWER on IntegriCloud