From: Nick Lewycky Date: Mon, 26 Jul 2010 16:56:01 +0000 (+0000) Subject: Add source location information to C++ base specifiers. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5606220447c7901ba8d80147ddab893bb7949dd5;p=clang Add source location information to C++ base specifiers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109396 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 3fee441750..0ec3408705 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -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. diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 0b56772c97..e76bcce8e1 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1175,7 +1175,7 @@ bool RecursiveASTVisitor::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(). diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index 8bf51e109e..19b02d258e 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -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) { diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index befdc7aede..b5fa362adb 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -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; diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 5801afd76f..d1ef3b15cd 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -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(VBaseType->getAs()->getDecl()); + CXXRecordDecl *VBaseClassDecl = cast( + VBaseTypeInfo->getType()->getAs()->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); } - - diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 48d05ba826..8a6108951d 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -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(Record[Idx++]); bool isBaseOfClass = static_cast(Record[Idx++]); AccessSpecifier AS = static_cast(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 * diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 046dce6f4d..ef8a78ae05 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -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); diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp index 160e45a2bb..86dfd879ca 100644 --- a/lib/Frontend/PCHReaderStmt.cpp +++ b/lib/Frontend/PCHReaderStmt.cpp @@ -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); } } diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 4474eaef48..83e042120e 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -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; } - diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 1d81258367..e6db331200 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -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(); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 0540dd9e0c..e1829d29b3 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -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, diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d732746530..34b0d96c08 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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; diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 1a7e35b355..60b8e927fd 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -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;