]> granicus.if.org Git - clang/commitdiff
Improve source location information for C++ member initializers in a
authorDouglas Gregor <dgregor@apple.com>
Wed, 2 Dec 2009 22:36:29 +0000 (22:36 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 2 Dec 2009 22:36:29 +0000 (22:36 +0000)
constructor, by keeping the DeclaratorInfo* rather than just the type
and a single location.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90355 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclCXX.h
lib/AST/DeclCXX.cpp
lib/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaInit.h [new file with mode: 0644]
lib/Sema/SemaTemplateInstantiateDecl.cpp

index 87a47fec6babb9d2966725174c9974ae99551ef2..81f85e81a00ae675f22a54512f6d4cc840360027 100644 (file)
@@ -888,12 +888,13 @@ public:
 /// };
 /// @endcode
 class CXXBaseOrMemberInitializer {
-  /// BaseOrMember - This points to the entity being initialized,
-  /// which is either a base class (a Type) or a non-static data
-  /// member. When the low bit is 1, it's a base
-  /// class; when the low bit is 0, it's a member.
-  uintptr_t BaseOrMember;
-
+  /// \brief Either the base class name (stored as a DeclaratorInfo*) or the
+  /// field being initialized.
+  llvm::PointerUnion<DeclaratorInfo *, FieldDecl *> BaseOrMember;
+  
+  /// \brief The source location for the field name.
+  SourceLocation MemberLocation;
+  
   /// Args - The arguments used to initialize the base or member.
   Stmt **Args;
   unsigned NumArgs;
@@ -918,8 +919,8 @@ class CXXBaseOrMemberInitializer {
   /// and AnonUnionMember holds field decl for au_i1.
   llvm::PointerUnion<CXXConstructorDecl *, FieldDecl *> CtorOrAnonUnion;
 
-  /// IdLoc - Location of the id in ctor-initializer list.
-  SourceLocation IdLoc;
+  /// LParenLoc - Location of the left paren of the ctor-initializer.
+  SourceLocation LParenLoc;
 
   /// RParenLoc - Location of the right paren of the ctor-initializer.
   SourceLocation RParenLoc;
@@ -927,18 +928,22 @@ class CXXBaseOrMemberInitializer {
 public:
   /// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
   explicit
-  CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
-                             CXXConstructorDecl *C,
-                             SourceLocation L, SourceLocation R);
+  CXXBaseOrMemberInitializer(ASTContext &Context,
+                             DeclaratorInfo *DInfo, CXXConstructorDecl *C,
+                             SourceLocation L, 
+                             Expr **Args, unsigned NumArgs,
+                             SourceLocation R);
 
   /// CXXBaseOrMemberInitializer - Creates a new member initializer.
   explicit
-  CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
-                             CXXConstructorDecl *C,
-                             SourceLocation L, SourceLocation R);
+  CXXBaseOrMemberInitializer(ASTContext &Context,
+                             FieldDecl *Member, SourceLocation MemberLoc,
+                             CXXConstructorDecl *C, SourceLocation L,
+                             Expr **Args, unsigned NumArgs,
+                             SourceLocation R);
 
-  /// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer.
-  ~CXXBaseOrMemberInitializer();
+  /// \brief Destroy the base or member initializer.
+  void Destroy(ASTContext &Context);
 
   /// arg_iterator - Iterates through the member initialization
   /// arguments.
@@ -948,54 +953,54 @@ public:
   /// arguments.
   typedef ConstExprIterator const_arg_iterator;
 
-  /// getBaseOrMember - get the generic 'member' representing either the field
-  /// or a base class.
-  void* getBaseOrMember() const { return reinterpret_cast<void*>(BaseOrMember); }
-
   /// isBaseInitializer - Returns true when this initializer is
   /// initializing a base class.
-  bool isBaseInitializer() const { return (BaseOrMember & 0x1) != 0; }
+  bool isBaseInitializer() const { return BaseOrMember.is<DeclaratorInfo*>(); }
 
   /// isMemberInitializer - Returns true when this initializer is
   /// initializing a non-static data member.
-  bool isMemberInitializer() const { return (BaseOrMember & 0x1) == 0; }
-
-  /// getBaseClass - If this is a base class initializer, returns the
-  /// type used to specify the initializer. The resulting type will be
-  /// a class type or a typedef of a class type. If this is not a base
-  /// class initializer, returns NULL.
-  Type *getBaseClass() {
-    if (isBaseInitializer())
-      return reinterpret_cast<Type*>(BaseOrMember & ~0x01);
-    else
-      return 0;
-  }
+  bool isMemberInitializer() const { return BaseOrMember.is<FieldDecl*>(); }
 
-  /// getBaseClass - If this is a base class initializer, returns the
-  /// type used to specify the initializer. The resulting type will be
-  /// a class type or a typedef of a class type. If this is not a base
-  /// class initializer, returns NULL.
-  const Type *getBaseClass() const {
-    if (isBaseInitializer())
-      return reinterpret_cast<const Type*>(BaseOrMember & ~0x01);
-    else
-      return 0;
-  }
+  /// If this is a base class initializer, returns the type of the 
+  /// base class with location information. Otherwise, returns an NULL
+  /// type location.
+  TypeLoc getBaseClassLoc() const;
 
+  /// If this is a base class initializer, returns the type of the base class.
+  /// Otherwise, returns NULL.
+  const Type *getBaseClass() const;
+  Type *getBaseClass();
+  
+  /// \brief Returns the declarator information for a base class initializer.
+  DeclaratorInfo *getBaseClassInfo() const {
+    return BaseOrMember.dyn_cast<DeclaratorInfo *>();
+  }
+  
   /// getMember - If this is a member initializer, returns the
   /// declaration of the non-static data member being
   /// initialized. Otherwise, returns NULL.
   FieldDecl *getMember() {
     if (isMemberInitializer())
-      return reinterpret_cast<FieldDecl *>(BaseOrMember);
+      return BaseOrMember.get<FieldDecl*>();
     else
       return 0;
   }
 
-  void setMember(FieldDecl * anonUnionField) {
-    BaseOrMember = reinterpret_cast<uintptr_t>(anonUnionField);
+  SourceLocation getMemberLocation() const { 
+    return MemberLocation;
   }
 
+  void setMember(FieldDecl *Member) {
+    assert(isMemberInitializer());
+    BaseOrMember = Member;
+  }
+  
+  /// \brief Determine the source location of the initializer.
+  SourceLocation getSourceLocation() const;
+  
+  /// \brief Determine the source range covering the entire initializer.
+  SourceRange getSourceRange() const;
+  
   FieldDecl *getAnonUnionMember() const {
     return CtorOrAnonUnion.dyn_cast<FieldDecl *>();
   }
@@ -1007,7 +1012,7 @@ public:
     return CtorOrAnonUnion.dyn_cast<CXXConstructorDecl *>();
   }
 
-  SourceLocation getSourceLocation() const { return IdLoc; }
+  SourceLocation getLParenLoc() const { return LParenLoc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
 
   /// arg_begin() - Retrieve an iterator to the first initializer argument.
index c98b3f078b95b56a0be84959c13cc11806460c82..89ea097a33c112b707dc5525e0a456f13230b047 100644 (file)
@@ -15,6 +15,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -630,43 +631,76 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {
 }
 
 CXXBaseOrMemberInitializer::
-CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
-                           CXXConstructorDecl *C,
-                           SourceLocation L, SourceLocation R)
-  : Args(0), NumArgs(0), CtorOrAnonUnion(), IdLoc(L), RParenLoc(R) {
-  BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
-  assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
-  BaseOrMember |= 0x01;
-
+CXXBaseOrMemberInitializer(ASTContext &Context,
+                           DeclaratorInfo *DInfo, CXXConstructorDecl *C,
+                           SourceLocation L, 
+                           Expr **Args, unsigned NumArgs,
+                           SourceLocation R)
+  : BaseOrMember(DInfo), Args(0), NumArgs(0), CtorOrAnonUnion(C), 
+    LParenLoc(L), RParenLoc(R) 
+{
   if (NumArgs > 0) {
     this->NumArgs = NumArgs;
-    // FIXME. Allocation via Context
-    this->Args = new Stmt*[NumArgs];
+    this->Args = new (Context) Stmt*[NumArgs];
     for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
       this->Args[Idx] = Args[Idx];
   }
-  CtorOrAnonUnion = C;
 }
 
 CXXBaseOrMemberInitializer::
-CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
-                           CXXConstructorDecl *C,
-                           SourceLocation L, SourceLocation R)
-  : Args(0), NumArgs(0), CtorOrAnonUnion(), IdLoc(L), RParenLoc(R) {
-  BaseOrMember = reinterpret_cast<uintptr_t>(Member);
-  assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");
-
+CXXBaseOrMemberInitializer(ASTContext &Context,
+                           FieldDecl *Member, SourceLocation MemberLoc,
+                           CXXConstructorDecl *C, SourceLocation L,
+                           Expr **Args, unsigned NumArgs,
+                           SourceLocation R)
+  : BaseOrMember(Member), MemberLocation(MemberLoc), Args(0), NumArgs(0), 
+    CtorOrAnonUnion(C), LParenLoc(L), RParenLoc(R) 
+{
   if (NumArgs > 0) {
     this->NumArgs = NumArgs;
-    this->Args = new Stmt*[NumArgs];
+    this->Args = new (Context) Stmt*[NumArgs];
     for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
       this->Args[Idx] = Args[Idx];
   }
-  CtorOrAnonUnion = C;
 }
 
-CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() {
-  delete [] Args;
+void CXXBaseOrMemberInitializer::Destroy(ASTContext &Context) {
+  for (unsigned I = 0; I != NumArgs; ++I)
+    Args[I]->Destroy(Context);
+  Context.Deallocate(Args);
+  this->~CXXBaseOrMemberInitializer();
+}
+
+TypeLoc CXXBaseOrMemberInitializer::getBaseClassLoc() const {
+  if (isBaseInitializer())
+    return BaseOrMember.get<DeclaratorInfo*>()->getTypeLoc();
+  else
+    return TypeLoc();
+}
+
+Type *CXXBaseOrMemberInitializer::getBaseClass() {
+  if (isBaseInitializer())
+    return BaseOrMember.get<DeclaratorInfo*>()->getType().getTypePtr();
+  else
+    return 0;
+}
+
+const Type *CXXBaseOrMemberInitializer::getBaseClass() const {
+  if (isBaseInitializer())
+    return BaseOrMember.get<DeclaratorInfo*>()->getType().getTypePtr();
+  else
+    return 0;
+}
+
+SourceLocation CXXBaseOrMemberInitializer::getSourceLocation() const {
+  if (isMemberInitializer())
+    return getMemberLocation();
+  
+  return getBaseClassLoc().getSourceRange().getBegin();
+}
+
+SourceRange CXXBaseOrMemberInitializer::getSourceRange() const {
+  return SourceRange(getSourceLocation(), getRParenLoc());
 }
 
 CXXConstructorDecl *
index 2b48efb495265471d6a12d27edce558662bca231..bd41072d3a648c4666de0676100825b43b31cb05 100644 (file)
@@ -2110,10 +2110,13 @@ public:
 
   MemInitResult BuildMemberInitializer(FieldDecl *Member, Expr **Args,
                                        unsigned NumArgs, SourceLocation IdLoc,
+                                       SourceLocation LParenLoc,
                                        SourceLocation RParenLoc);
 
-  MemInitResult BuildBaseInitializer(QualType BaseType, Expr **Args,
-                                     unsigned NumArgs, SourceLocation IdLoc,
+  MemInitResult BuildBaseInitializer(QualType BaseType,
+                                     DeclaratorInfo *BaseDInfo,
+                                     Expr **Args, unsigned NumArgs,
+                                     SourceLocation LParenLoc,
                                      SourceLocation RParenLoc,
                                      CXXRecordDecl *ClassDecl);
 
index 4db769bd91a8d207c44fcca05cc6ca741a3ff768..37681719aaa87f376452c649a4d26c19bf70115e 100644 (file)
@@ -18,6 +18,7 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclVisitor.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Parse/DeclSpec.h"
@@ -977,19 +978,26 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
 
     if (Member)
       return BuildMemberInitializer(Member, (Expr**)Args, NumArgs, IdLoc,
-                                    RParenLoc);
+                                    LParenLoc, RParenLoc);
   }
   // It didn't name a member, so see if it names a class.
-  TypeTy *BaseTy = TemplateTypeTy ? TemplateTypeTy
-                     : getTypeName(*MemberOrBase, IdLoc, S, &SS);
-  if (!BaseTy)
+  QualType BaseType;
+
+  DeclaratorInfo *DInfo = 0;
+  if (TemplateTypeTy)
+    BaseType = GetTypeFromParser(TemplateTypeTy, &DInfo);
+  else
+    BaseType = QualType::getFromOpaquePtr(getTypeName(*MemberOrBase, IdLoc, 
+                                                      S, &SS));
+  if (BaseType.isNull())
     return Diag(IdLoc, diag::err_mem_init_not_member_or_class)
       << MemberOrBase << SourceRange(IdLoc, RParenLoc);
 
-  QualType BaseType = GetTypeFromParser(BaseTy);
+  if (!DInfo)
+    DInfo = Context.getTrivialDeclaratorInfo(BaseType, IdLoc);
 
-  return BuildBaseInitializer(BaseType, (Expr **)Args, NumArgs, IdLoc,
-                              RParenLoc, ClassDecl);
+  return BuildBaseInitializer(BaseType, DInfo, (Expr **)Args, NumArgs, 
+                              LParenLoc, RParenLoc, ClassDecl);
 }
 
 /// Checks an initializer expression for use of uninitialized fields, such as
@@ -1038,6 +1046,7 @@ static bool InitExprContainsUninitializedFields(const Stmt* S,
 Sema::MemInitResult
 Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
                              unsigned NumArgs, SourceLocation IdLoc,
+                             SourceLocation LParenLoc,
                              SourceLocation RParenLoc) {
   // FIXME: CXXBaseOrMemberInitializer should only contain a single 
   // subexpression so we can wrap it in a CXXExprWithTemporaries if necessary.
@@ -1119,22 +1128,25 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
   ExprTemporaries.clear();
   
   // FIXME: Perform direct initialization of the member.
-  return new (Context) CXXBaseOrMemberInitializer(Member, (Expr **)Args,
-                                                  NumArgs, C, IdLoc, RParenLoc);
+  return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
+                                                  C, LParenLoc, (Expr **)Args,
+                                                  NumArgs, RParenLoc);
 }
 
 Sema::MemInitResult
-Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
-                           unsigned NumArgs, SourceLocation IdLoc,
-                           SourceLocation RParenLoc, CXXRecordDecl *ClassDecl) {
+Sema::BuildBaseInitializer(QualType BaseType, DeclaratorInfo *BaseDInfo,
+                           Expr **Args, unsigned NumArgs, 
+                           SourceLocation LParenLoc, SourceLocation RParenLoc, 
+                           CXXRecordDecl *ClassDecl) {
   bool HasDependentArg = false;
   for (unsigned i = 0; i < NumArgs; i++)
     HasDependentArg |= Args[i]->isTypeDependent();
 
+  SourceLocation BaseLoc = BaseDInfo->getTypeLoc().getSourceRange().getBegin();
   if (!BaseType->isDependentType()) {
     if (!BaseType->isRecordType())
-      return Diag(IdLoc, diag::err_base_init_does_not_name_class)
-        << BaseType << SourceRange(IdLoc, RParenLoc);
+      return Diag(BaseLoc, diag::err_base_init_does_not_name_class)
+        << BaseType << BaseDInfo->getTypeLoc().getSourceRange();
 
     // C++ [class.base.init]p2:
     //   [...] Unless the mem-initializer-id names a nonstatic data
@@ -1180,16 +1192,16 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
     //   a direct non-virtual base class and an inherited virtual base
     //   class, the mem-initializer is ill-formed.
     if (DirectBaseSpec && VirtualBaseSpec)
-      return Diag(IdLoc, diag::err_base_init_direct_and_virtual)
-        << BaseType << SourceRange(IdLoc, RParenLoc);
+      return Diag(BaseLoc, diag::err_base_init_direct_and_virtual)
+        << BaseType << BaseDInfo->getTypeLoc().getSourceRange();
     // C++ [base.class.init]p2:
     // Unless the mem-initializer-id names a nonstatic data membeer of the
     // constructor's class ot a direst or virtual base of that class, the
     // mem-initializer is ill-formed.
     if (!DirectBaseSpec && !VirtualBaseSpec)
-      return Diag(IdLoc, diag::err_not_direct_base_or_virtual)
-      << BaseType << ClassDecl->getNameAsCString()
-      << SourceRange(IdLoc, RParenLoc);
+      return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
+        << BaseType << ClassDecl->getNameAsCString()
+        << BaseDInfo->getTypeLoc().getSourceRange();
   }
 
   CXXConstructorDecl *C = 0;
@@ -1201,7 +1213,8 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
     C = PerformInitializationByConstructor(BaseType, 
                                            MultiExprArg(*this, 
                                                         (void**)Args, NumArgs),
-                                           IdLoc, SourceRange(IdLoc, RParenLoc),
+                                           BaseLoc, 
+                                           SourceRange(BaseLoc, RParenLoc),
                                            Name, IK_Direct,
                                            ConstructorArgs);
     if (C) {
@@ -1215,8 +1228,9 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
   // subexpression so we can wrap it in a CXXExprWithTemporaries if necessary.
   ExprTemporaries.clear();
   
-  return new (Context) CXXBaseOrMemberInitializer(BaseType, (Expr **)Args,
-                                                  NumArgs, C, IdLoc, RParenLoc);
+  return new (Context) CXXBaseOrMemberInitializer(Context, BaseDInfo, C, 
+                                                  LParenLoc, (Expr **)Args, 
+                                                  NumArgs, RParenLoc);
 }
 
 bool
@@ -1278,7 +1292,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
       }
       else {
         CXXRecordDecl *VBaseDecl =
-        cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
+          cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
         assert(VBaseDecl && "SetBaseOrMemberInitializers - VBaseDecl null");
         CXXConstructorDecl *Ctor = VBaseDecl->getDefaultConstructor(Context);
         if (!Ctor) {
@@ -1299,13 +1313,18 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
         MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
         
         // FIXME: CXXBaseOrMemberInitializer should only contain a single 
-        // subexpression so we can wrap it in a CXXExprWithTemporaries if necessary.
+        // subexpression so we can wrap it in a CXXExprWithTemporaries if 
+        // necessary.
+        // FIXME: Is there any better source-location information we can give?
         ExprTemporaries.clear();
         CXXBaseOrMemberInitializer *Member =
-          new (Context) CXXBaseOrMemberInitializer(VBase->getType(),
-                                                   CtorArgs.takeAs<Expr>(),
-                                                   CtorArgs.size(), Ctor,
+          new (Context) CXXBaseOrMemberInitializer(Context,
+                             Context.getTrivialDeclaratorInfo(VBase->getType(), 
+                                                              SourceLocation()),
+                                                   Ctor,
                                                    SourceLocation(),
+                                                   CtorArgs.takeAs<Expr>(),
+                                                   CtorArgs.size(), 
                                                    SourceLocation());
         AllToInit.push_back(Member);
       }
@@ -1347,13 +1366,18 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
         MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
 
         // FIXME: CXXBaseOrMemberInitializer should only contain a single 
-        // subexpression so we can wrap it in a CXXExprWithTemporaries if necessary.
+        // subexpression so we can wrap it in a CXXExprWithTemporaries if 
+        // necessary.
+        // FIXME: Is there any better source-location information we can give?
         ExprTemporaries.clear();
         CXXBaseOrMemberInitializer *Member =
-          new (Context) CXXBaseOrMemberInitializer(Base->getType(),
-                                                   CtorArgs.takeAs<Expr>(),
-                                                   CtorArgs.size(), Ctor,
+          new (Context) CXXBaseOrMemberInitializer(Context,
+                             Context.getTrivialDeclaratorInfo(Base->getType(), 
+                                                              SourceLocation()),
+                                                   Ctor,
                                                    SourceLocation(),
+                                                   CtorArgs.takeAs<Expr>(),
+                                                   CtorArgs.size(), 
                                                    SourceLocation());
         AllToInit.push_back(Member);
       }
@@ -1428,9 +1452,12 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
       // subexpression so we can wrap it in a CXXExprWithTemporaries if necessary.
       ExprTemporaries.clear();
       CXXBaseOrMemberInitializer *Member =
-        new (Context) CXXBaseOrMemberInitializer(*Field,CtorArgs.takeAs<Expr>(),
-                                                 CtorArgs.size(), Ctor,
+        new (Context) CXXBaseOrMemberInitializer(Context,
+                                                 *Field, SourceLocation(),
+                                                 Ctor,
                                                  SourceLocation(),
+                                                 CtorArgs.takeAs<Expr>(),
+                                                 CtorArgs.size(),
                                                  SourceLocation());
 
       AllToInit.push_back(Member);
@@ -1538,13 +1565,15 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
       if (FieldDecl *Field = Member->getMember())
         Diag(Member->getSourceLocation(),
              diag::error_multiple_mem_initialization)
-        << Field->getNameAsString();
+          << Field->getNameAsString()
+          << Member->getSourceRange();
       else {
         Type *BaseClass = Member->getBaseClass();
         assert(BaseClass && "ActOnMemInitializers - neither field or base");
         Diag(Member->getSourceLocation(),
              diag::error_multiple_base_initialization)
-          << QualType(BaseClass, 0);
+          << QualType(BaseClass, 0)
+          << Member->getSourceRange();
       }
       Diag(PrevMember->getSourceLocation(), diag::note_previous_initializer)
         << 0;
diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h
new file mode 100644 (file)
index 0000000..e69de29
index 8808bf72db5187e3c31d851a69a6ccee0e6b0772..95725bf44f7d6dfc39bd868df867e0472fc8cdf8 100644 (file)
@@ -1620,14 +1620,19 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
     MemInitResult NewInit;
 
     if (Init->isBaseInitializer()) {
-      QualType BaseType(Init->getBaseClass(), 0);
-      BaseType = SubstType(BaseType, TemplateArgs, Init->getSourceLocation(),
-                           New->getDeclName());
-
-      NewInit = BuildBaseInitializer(BaseType,
+      DeclaratorInfo *BaseDInfo = SubstType(Init->getBaseClassInfo(), 
+                                            TemplateArgs, 
+                                            Init->getSourceLocation(), 
+                                            New->getDeclName());
+      if (!BaseDInfo) {
+        New->setInvalidDecl();
+        continue;
+      }
+      
+      NewInit = BuildBaseInitializer(BaseDInfo->getType(), BaseDInfo,
                                      (Expr **)NewArgs.data(),
                                      NewArgs.size(),
-                                     Init->getSourceLocation(),
+                                     Init->getLParenLoc(),
                                      Init->getRParenLoc(),
                                      New->getParent());
     } else if (Init->isMemberInitializer()) {
@@ -1643,6 +1648,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
       NewInit = BuildMemberInitializer(Member, (Expr **)NewArgs.data(),
                                        NewArgs.size(),
                                        Init->getSourceLocation(),
+                                       Init->getLParenLoc(),
                                        Init->getRParenLoc());
     }