]> granicus.if.org Git - clang/commitdiff
Add source location information to C++ base specifiers.
authorNick Lewycky <nicholas@mxc.ca>
Mon, 26 Jul 2010 16:56:01 +0000 (16:56 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Mon, 26 Jul 2010 16:56:01 +0000 (16:56 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109396 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/clang/AST/DeclCXX.h
include/clang/AST/RecursiveASTVisitor.h
include/clang/Frontend/PCHReader.h
lib/AST/ASTImporter.cpp
lib/AST/DeclCXX.cpp
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHReaderDecl.cpp
lib/Frontend/PCHReaderStmt.cpp
lib/Frontend/PCHWriter.cpp
lib/Parse/ParseDeclCXX.cpp
lib/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaTemplateInstantiate.cpp

index 3fee44175007c08f0d45905d5bec9a60aa1f4c09..0ec3408705e4813c668e288d35c95fb23894650a 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "clang/AST/Expr.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/AST/UnresolvedSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -159,7 +160,6 @@ class CXXBaseSpecifier {
   /// Range - The source code range that covers the full base
   /// specifier, including the "virtual" (if present) and access
   /// specifier (if present).
-  // FIXME: Move over to a TypeLoc!
   SourceRange Range;
 
   /// Virtual - Whether this is a virtual base class or not.
@@ -177,15 +177,17 @@ class CXXBaseSpecifier {
   /// VC++ bug.
   unsigned Access : 2;
 
-  /// BaseType - The type of the base class. This will be a class or
-  /// struct (or a typedef of such).
-  QualType BaseType;
+  /// BaseTypeInfo - The type of the base class. This will be a class or struct
+  /// (or a typedef of such). The source code range does not include the
+  /// "virtual" or access specifier.
+  TypeSourceInfo *BaseTypeInfo;
 
 public:
   CXXBaseSpecifier() { }
 
-  CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, QualType T)
-    : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseType(T) { }
+  CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A,
+                   TypeSourceInfo *TInfo)
+    : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseTypeInfo(TInfo) { }
 
   /// getSourceRange - Retrieves the source range that contains the
   /// entire base specifier.
@@ -195,7 +197,7 @@ public:
   /// class (or not).
   bool isVirtual() const { return Virtual; }
 
-  /// \brief Determine whether this base class if a base of a class declared
+  /// \brief Determine whether this base class is a base of a class declared
   /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
   bool isBaseOfClass() const { return BaseOfClass; }
   
@@ -221,7 +223,10 @@ public:
 
   /// getType - Retrieves the type of the base class. This type will
   /// always be an unqualified class type.
-  QualType getType() const { return BaseType; }
+  QualType getType() const { return BaseTypeInfo->getType(); }
+
+  /// getTypeLoc - Retrieves the type and source location of the base class.
+  TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
 };
 
 /// CXXRecordDecl - Represents a C++ struct/union/class.
index 0b56772c97dfb5d2d815b24fa830e9cbcc0c8689..e76bcce8e17ce7e13735948e95f9ab53fb01ad1e 100644 (file)
@@ -1175,7 +1175,7 @@ bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(
     for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
                                             E = D->bases_end();
          I != E; ++I) {
-      TRY_TO(TraverseType(I->getType()));
+      TRY_TO(TraverseTypeLoc(I->getTypeSourceInfo()->getTypeLoc()));
     }
     // We don't traverse the friends or the conversions, as they are
     // already in decls_begin()/decls_end().
index 8bf51e109e0f2f95611f2d6022cbd35508b545b9..19b02d258e3df83d232f0a71f734f49c9a3f45ba 100644 (file)
@@ -836,7 +836,8 @@ public:
                          const RecordData &Record, unsigned &Idx);
 
   /// \brief Read a C++ base specifier.
-  CXXBaseSpecifier ReadCXXBaseSpecifier(const RecordData &Record,unsigned &Idx);
+  CXXBaseSpecifier ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor,
+                                        const RecordData &Record,unsigned &Idx);
 
   /// \brief Read a source location.
   SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) {
index befdc7aede381c5154f6e0f7ea7afab967aeb22c..b5fa362adb44663de7345f35600121b39c0de9cd 100644 (file)
@@ -19,7 +19,6 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/StmtVisitor.h"
-#include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeVisitor.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
@@ -1752,7 +1751,7 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
                                  Base1->isVirtual(),
                                  Base1->isBaseOfClass(),
                                  Base1->getAccessSpecifierAsWritten(),
-                                 T));
+                                 Importer.Import(Base1->getTypeSourceInfo())));
       }
       if (!Bases.empty())
         D2CXX->setBases(Bases.data(), Bases.size());
@@ -2965,8 +2964,7 @@ TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
     return FromTSI;
 
   // FIXME: For now we just create a "trivial" type source info based
-  // on the type and a seingle location. Implement a real version of
-  // this.
+  // on the type and a single location. Implement a real version of this.
   QualType T = Import(FromTSI->getType());
   if (T.isNull())
     return 0;
index 5801afd76f1dbea5b334dd7c4d40c474fab8c40c..d1ef3b15cdee28d9a7dfb892363000c78ecd98a4 100644 (file)
@@ -121,19 +121,19 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
   data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
   data().NumVBases = VBases.size();
   for (int I = 0, E = VBases.size(); I != E; ++I) {
-    QualType VBaseType = VBases[I]->getType();
-    
+    TypeSourceInfo *VBaseTypeInfo = VBases[I]->getTypeSourceInfo();
+
     // Skip dependent types; we can't do any checking on them now.
-    if (VBaseType->isDependentType())
+    if (VBaseTypeInfo->getType()->isDependentType())
       continue;
 
-    CXXRecordDecl *VBaseClassDecl
-      = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
+    CXXRecordDecl *VBaseClassDecl = cast<CXXRecordDecl>(
+      VBaseTypeInfo->getType()->getAs<RecordType>()->getDecl());
 
     data().VBases[I] =
       CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
                        VBaseClassDecl->getTagKind() == TTK_Class,
-                       VBases[I]->getAccessSpecifier(), VBaseType);
+                       VBases[I]->getAccessSpecifier(), VBaseTypeInfo);
   }
 }
 
@@ -1062,5 +1062,3 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
                                            AccessSpecifier AS) {
   return DB << getAccessName(AS);
 }
-
-
index 48d05ba826c3543126120b943d4219f1d1f69981..8a6108951d75d4ba644d7171cdb777eeb4110521 100644 (file)
@@ -3475,13 +3475,14 @@ void PCHReader::ReadUnresolvedSet(UnresolvedSetImpl &Set,
 }
 
 CXXBaseSpecifier
-PCHReader::ReadCXXBaseSpecifier(const RecordData &Record, unsigned &Idx) {
+PCHReader::ReadCXXBaseSpecifier(llvm::BitstreamCursor &DeclsCursor,
+                                const RecordData &Record, unsigned &Idx) {
   bool isVirtual = static_cast<bool>(Record[Idx++]);
   bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
   AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);
-  QualType T = GetType(Record[Idx++]);
+  TypeSourceInfo *TInfo = GetTypeSourceInfo(DeclsCursor, Record, Idx);
   SourceRange Range = ReadSourceRange(Record, Idx);
-  return CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, T);
+  return CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, TInfo);
 }
 
 NestedNameSpecifier *
index 046dce6f4d8b41f3f31715075431e7efc1000b3d..ef8a78ae0580fd3e40d97c1d75ea072f49fe5bd0 100644 (file)
@@ -727,17 +727,17 @@ void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {
     Data.DeclaredDestructor = Record[Idx++];
 
     // setBases() is unsuitable since it may try to iterate the bases of an
-    // unitialized base.
+    // uninitialized base.
     Data.NumBases = Record[Idx++];
     Data.Bases = new(C) CXXBaseSpecifier [Data.NumBases];
     for (unsigned i = 0; i != Data.NumBases; ++i)
-      Data.Bases[i] = Reader.ReadCXXBaseSpecifier(Record, Idx);
+      Data.Bases[i] = Reader.ReadCXXBaseSpecifier(Cursor, Record, Idx);
 
     // FIXME: Make VBases lazily computed when needed to avoid storing them.
     Data.NumVBases = Record[Idx++];
     Data.VBases = new(C) CXXBaseSpecifier [Data.NumVBases];
     for (unsigned i = 0; i != Data.NumVBases; ++i)
-      Data.VBases[i] = Reader.ReadCXXBaseSpecifier(Record, Idx);
+      Data.VBases[i] = Reader.ReadCXXBaseSpecifier(Cursor, Record, Idx);
 
     Reader.ReadUnresolvedSet(Data.Conversions, Record, Idx);
     Reader.ReadUnresolvedSet(Data.VisibleConversions, Record, Idx);
index 160e45a2bb9fda76eabe6d97fd3e4ebc679c635b..86dfd879ca6d461c4941bae3c95b05aee90c385f 100644 (file)
@@ -562,9 +562,8 @@ void PCHStmtReader::VisitCastExpr(CastExpr *E) {
   CXXBaseSpecifierArray &BasePath = E->getBasePath();
   unsigned NumBaseSpecs = Record[Idx++];
   while (NumBaseSpecs--) {
-    // FIXME: These gets leaked.
     CXXBaseSpecifier *BaseSpec = new (*Reader.getContext()) CXXBaseSpecifier;
-    *BaseSpec = Reader.ReadCXXBaseSpecifier(Record, Idx);
+    *BaseSpec = Reader.ReadCXXBaseSpecifier(DeclsCursor, Record, Idx);
     BasePath.push_back(BaseSpec);
   }
 }
index 4474eaef4856c0fa888c0960c5132f59bf8d09e2..83e042120ec8f3e65797c14bc72739a55a96b7c3 100644 (file)
@@ -2790,7 +2790,7 @@ void PCHWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
   Record.push_back(Base.isVirtual());
   Record.push_back(Base.isBaseOfClass());
   Record.push_back(Base.getAccessSpecifierAsWritten());
-  AddTypeRef(Base.getType(), Record);
+  AddTypeSourceInfo(Base.getTypeSourceInfo(), Record);
   AddSourceRange(Base.getSourceRange(), Record);
 }
 
@@ -2805,4 +2805,3 @@ void PCHWriter::TypeRead(pch::TypeID ID, QualType T) {
 void PCHWriter::DeclRead(pch::DeclID ID, const Decl *D) {
   DeclIDs[D] = ID;
 }
-
index 1d812583672540bf156dc443941b14d70d33fe60..e6db33120088b6fb98e37751e7eb87f04e0c8605 100644 (file)
@@ -550,7 +550,19 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
 
   // Consume the identifier.
   EndLocation = IdLoc;
-  return Type;
+
+  // Fake up a Declarator to use with ActOnTypeName.
+  DeclSpec DS;
+  DS.SetRangeStart(IdLoc);
+  DS.SetRangeEnd(EndLocation);
+  DS.getTypeSpecScope() = *SS;
+
+  const char *PrevSpec = 0;
+  unsigned DiagID;
+  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type);
+
+  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
 }
 
 /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
@@ -2052,8 +2064,7 @@ Parser::OwningExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
     SourceLocation TypeLoc = Tok.getLocation();
     TypeTy *Ty = ParseTypeName().get();
     SourceRange TypeRange(Start, Tok.getLocation());
-    return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true, Ty,
-                                              TypeRange);
+    return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true, Ty, TypeRange);
   } else
     return ParseConstantExpression();
 }
index 0540dd9e0c54470049fb1974ed6458590621c9ee..e1829d29b34a79973dd82d377b2096e0adffeeb3 100644 (file)
@@ -2747,8 +2747,7 @@ public:
   CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class,
                                        SourceRange SpecifierRange,
                                        bool Virtual, AccessSpecifier Access,
-                                       QualType BaseType,
-                                       SourceLocation BaseLoc);
+                                       TypeSourceInfo *TInfo);
 
   /// SetClassDeclAttributesFromBase - Copies class decl traits
   /// (such as whether the class has a trivial constructor,
index d732746530fcaf2513e9adddfc2a601d3177ebd2..34b0d96c08707aa00f69c49cb6615328f10eb067 100644 (file)
@@ -447,8 +447,9 @@ CXXBaseSpecifier *
 Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
                          SourceRange SpecifierRange,
                          bool Virtual, AccessSpecifier Access,
-                         QualType BaseType,
-                         SourceLocation BaseLoc) {
+                         TypeSourceInfo *TInfo) {
+  QualType BaseType = TInfo->getType();
+
   // C++ [class.union]p1:
   //   A union shall not have base classes.
   if (Class->isUnion()) {
@@ -459,8 +460,10 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 
   if (BaseType->isDependentType())
     return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
-                                Class->getTagKind() == TTK_Class,
-                                Access, BaseType);
+                                          Class->getTagKind() == TTK_Class,
+                                          Access, TInfo);
+
+  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
 
   // Base specifiers must be record types.
   if (!BaseType->isRecordType()) {
@@ -503,8 +506,8 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
   
   // Create the base specifier.
   return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
-                              Class->getTagKind() == TTK_Class,
-                              Access, BaseType);
+                                        Class->getTagKind() == TTK_Class,
+                                        Access, TInfo);
 }
 
 void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
@@ -591,10 +594,10 @@ Sema::ActOnBaseSpecifier(DeclPtrTy classdecl, SourceRange SpecifierRange,
   if (!Class)
     return true;
 
-  QualType BaseType = GetTypeFromParser(basetype);
+  TypeSourceInfo *TInfo = 0;
+  GetTypeFromParser(basetype, &TInfo);
   if (CXXBaseSpecifier *BaseSpec = CheckBaseSpecifier(Class, SpecifierRange,
-                                                      Virtual, Access,
-                                                      BaseType, BaseLoc))
+                                                      Virtual, Access, TInfo))
     return BaseSpec;
 
   return true;
index 1a7e35b35507dff36f38737988c3fd1d657dd5d8..60b8e927fd2891d70c1ddf20ed4ecd864aaf4a88 100644 (file)
@@ -1101,11 +1101,11 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
       continue;
     }
 
-    QualType BaseType = SubstType(Base->getType(),
-                                  TemplateArgs,
-                                  Base->getSourceRange().getBegin(),
-                                  DeclarationName());
-    if (BaseType.isNull()) {
+    TypeSourceInfo *BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
+                                            TemplateArgs,
+                                            Base->getSourceRange().getBegin(),
+                                            DeclarationName());
+    if (!BaseTypeLoc) {
       Invalid = true;
       continue;
     }
@@ -1115,9 +1115,7 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
                                Base->getSourceRange(),
                                Base->isVirtual(),
                                Base->getAccessSpecifierAsWritten(),
-                               BaseType,
-                               /*FIXME: Not totally accurate */
-                               Base->getSourceRange().getBegin()))
+                               BaseTypeLoc))
       InstantiatedBases.push_back(InstantiatedBase);
     else
       Invalid = true;