aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2010-07-26 16:56:01 +0000
committerNick Lewycky <nicholas@mxc.ca>2010-07-26 16:56:01 +0000
commit5606220447c7901ba8d80147ddab893bb7949dd5 (patch)
tree96cb5fa342be688f5f163b49b11ef356dc66f336
parent3d398aa5c2be8919bbc0144bce611c48119bc861 (diff)
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
-rw-r--r--include/clang/AST/DeclCXX.h21
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h2
-rw-r--r--include/clang/Frontend/PCHReader.h3
-rw-r--r--lib/AST/ASTImporter.cpp6
-rw-r--r--lib/AST/DeclCXX.cpp14
-rw-r--r--lib/Frontend/PCHReader.cpp7
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp6
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp3
-rw-r--r--lib/Frontend/PCHWriter.cpp3
-rw-r--r--lib/Parse/ParseDeclCXX.cpp17
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaDeclCXX.cpp21
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp14
13 files changed, 66 insertions, 54 deletions
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<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().
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<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);
}
-
-
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<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 *
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;