#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"
/// 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.
/// 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.
/// 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; }
/// 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.
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().
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) {
#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"
Base1->isVirtual(),
Base1->isBaseOfClass(),
Base1->getAccessSpecifierAsWritten(),
- T));
+ Importer.Import(Base1->getTypeSourceInfo())));
}
if (!Bases.empty())
D2CXX->setBases(Bases.data(), Bases.size());
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;
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);
}
}
AccessSpecifier AS) {
return DB << getAccessName(AS);
}
-
-
}
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 *
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);
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);
}
}
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);
}
void PCHWriter::DeclRead(pch::DeclID ID, const Decl *D) {
DeclIDs[D] = ID;
}
-
// 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
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();
}
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,
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()) {
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()) {
// 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,
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;
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;
}
Base->getSourceRange(),
Base->isVirtual(),
Base->getAccessSpecifierAsWritten(),
- BaseType,
- /*FIXME: Not totally accurate */
- Base->getSourceRange().getBegin()))
+ BaseTypeLoc))
InstantiatedBases.push_back(InstantiatedBase);
else
Invalid = true;