[cfe-commits] r90355 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaInit.h lib/Sema/SemaTemplateInstantiateDecl.cpp

Douglas Gregor dgregor at apple.com
Wed Dec 2 14:36:30 PST 2009


Author: dgregor
Date: Wed Dec  2 16:36:29 2009
New Revision: 90355

URL: http://llvm.org/viewvc/llvm-project?rev=90355&view=rev
Log:
Improve source location information for C++ member initializers in a
constructor, by keeping the DeclaratorInfo* rather than just the type
and a single location.

Added:
    cfe/trunk/lib/Sema/SemaInit.h
Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=90355&r1=90354&r2=90355&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Wed Dec  2 16:36:29 2009
@@ -888,12 +888,13 @@
 /// };
 /// @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 @@
   /// 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 @@
 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 @@
   /// 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; }
+  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.
-  Type *getBaseClass() {
-    if (isBaseInitializer())
-      return reinterpret_cast<Type*>(BaseOrMember & ~0x01);
-    else
-      return 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.
-  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 @@
     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.

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=90355&r1=90354&r2=90355&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Dec  2 16:36:29 2009
@@ -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 @@
 }
 
 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 *

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=90355&r1=90354&r2=90355&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Dec  2 16:36:29 2009
@@ -2110,10 +2110,13 @@
 
   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);
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=90355&r1=90354&r2=90355&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Dec  2 16:36:29 2009
@@ -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 @@
 
     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 @@
 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 @@
   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 @@
     //   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 @@
     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 @@
   // 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 @@
       }
       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 @@
         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 @@
         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 @@
       // 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 @@
       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;

Added: cfe/trunk/lib/Sema/SemaInit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.h?rev=90355&view=auto

==============================================================================
    (empty)

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=90355&r1=90354&r2=90355&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Dec  2 16:36:29 2009
@@ -1620,14 +1620,19 @@
     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 @@
       NewInit = BuildMemberInitializer(Member, (Expr **)NewArgs.data(),
                                        NewArgs.size(),
                                        Init->getSourceLocation(),
+                                       Init->getLParenLoc(),
                                        Init->getRParenLoc());
     }
 





More information about the cfe-commits mailing list