git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74099 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anders Carlsson 2009-06-24 19:06:50 +00:00
Родитель 6fe1ef2bbb
Коммит 395b475a44
11 изменённых файлов: 80 добавлений и 4 удалений

Просмотреть файл

@ -694,8 +694,8 @@
DEF165220F8D46980098507F /* Util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util.h; path = clang/Driver/Util.h; sourceTree = "<group>"; };
DEF165230F8D46980098507F /* Phases.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Phases.h; path = clang/Driver/Phases.h; sourceTree = "<group>"; };
DEF165240F8D46980098507F /* DriverDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DriverDiagnostic.h; path = clang/Driver/DriverDiagnostic.h; sourceTree = "<group>"; };
DEF165700F8FB34D0098507F /* PCHWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHWriter.cpp; path = lib/Frontend/PCHWriter.cpp; sourceTree = "<group>"; };
DEF165740F8FB3510098507F /* PCHReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReader.cpp; path = lib/Frontend/PCHReader.cpp; sourceTree = "<group>"; };
DEF165700F8FB34D0098507F /* PCHWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = PCHWriter.cpp; path = lib/Frontend/PCHWriter.cpp; sourceTree = "<group>"; tabWidth = 2; };
DEF165740F8FB3510098507F /* PCHReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReader.cpp; path = lib/Frontend/PCHReader.cpp; sourceTree = "<group>"; tabWidth = 2; };
DEF165780F8FB3690098507F /* PCHWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PCHWriter.h; path = clang/Frontend/PCHWriter.h; sourceTree = "<group>"; };
DEF1657B0F8FB36E0098507F /* PCHReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PCHReader.h; path = clang/Frontend/PCHReader.h; sourceTree = "<group>"; };
DEF1657E0F8FB3730098507F /* PCHBitCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PCHBitCodes.h; path = clang/Frontend/PCHBitCodes.h; sourceTree = "<group>"; };

Просмотреть файл

@ -360,6 +360,9 @@ public:
QualType getTypeOfExprType(Expr *e);
QualType getTypeOfType(QualType t);
/// getDecltypeType - C++0x decltype.
QualType getDecltypeType(Expr *e);
/// getTagDeclType - Return the unique reference to the type for the
/// specified TagDecl (struct/union/class/enum) decl.
QualType getTagDeclType(TagDecl *Decl);

Просмотреть файл

@ -1358,6 +1358,21 @@ public:
static bool classof(const TypeOfType *) { return true; }
};
/// DecltypeType (C++0x)
class DecltypeType : public Type {
Expr *E;
DecltypeType(Expr *E, QualType can);
friend class ASTContext; // ASTContext creates these.
public:
Expr *getUnderlyingExpr() const { return E; }
virtual void getAsStringInternal(std::string &InnerString,
const PrintingPolicy &Policy) const;
static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
static bool classof(const DecltypeType *) { return true; }
};
class TagType : public Type {
/// Stores the TagDecl associated with this type. The decl will
/// point to the TagDecl that actually defines the entity (or is a

Просмотреть файл

@ -69,6 +69,7 @@ TYPE(FunctionNoProto, FunctionType)
NON_CANONICAL_TYPE(Typedef, Type)
NON_CANONICAL_TYPE(TypeOfExpr, Type)
NON_CANONICAL_TYPE(TypeOf, Type)
NON_CANONICAL_TYPE(Decltype, Type)
ABSTRACT_TYPE(Tag, Type)
TYPE(Record, TagType)
TYPE(Enum, TagType)

Просмотреть файл

@ -387,7 +387,9 @@ namespace clang {
/// \brief An ObjCQualifiedInterfaceType record.
TYPE_OBJC_QUALIFIED_INTERFACE = 22,
/// \brief An ObjCObjectPointerType record.
TYPE_OBJC_OBJECT_POINTER = 23
TYPE_OBJC_OBJECT_POINTER = 23,
/// \brief a DecltypeType record.
TYPE_DECLTYPE = 24
};
/// \brief The type IDs for special types constructed by semantic

Просмотреть файл

@ -460,6 +460,10 @@ ASTContext::getTypeInfo(const Type *T) {
case Type::TypeOf:
return getTypeInfo(cast<TypeOfType>(T)->getUnderlyingType().getTypePtr());
case Type::Decltype:
return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType()
.getTypePtr());
case Type::QualifiedName:
return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr());
@ -1659,6 +1663,19 @@ QualType ASTContext::getTypeOfType(QualType tofType) {
return QualType(tot, 0);
}
/// getDecltypeType - Unlike many "get<Type>" functions, we don't unique
/// DecltypeType AST's. The only motivation to unique these nodes would be
/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
/// an issue. This doesn't effect the type checker, since it operates
/// on canonical type's (which are always unique).
QualType ASTContext::getDecltypeType(Expr *e) {
// FIXME: Use the right type here!
QualType Canonical = getCanonicalType(e->getType());
DecltypeType *dt = new (*this, 8) DecltypeType(e, Canonical);
Types.push_back(dt);
return QualType(dt, 0);
}
/// getTagDeclType - Return the unique reference to the type for the
/// specified TagDecl (struct/union/class/enum) decl.
QualType ASTContext::getTagDeclType(TagDecl *Decl) {

Просмотреть файл

@ -1052,6 +1052,11 @@ TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
DecltypeType::DecltypeType(Expr *E, QualType can)
: Type(Decltype, can, E->isTypeDependent()), E(E) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
TagType::TagType(TypeClass TC, TagDecl *D, QualType can)
: Type(TC, can, D->isDependentType()), decl(D, 0) {}
@ -1421,6 +1426,16 @@ void TypeOfType::getAsStringInternal(std::string &InnerString, const PrintingPol
InnerString = "typeof(" + Tmp + ")" + InnerString;
}
void DecltypeType::getAsStringInternal(std::string &InnerString,
const PrintingPolicy &Policy) const {
if (!InnerString.empty()) // Prefix the basic type, e.g. 'decltype(t) X'.
InnerString = ' ' + InnerString;
std::string Str;
llvm::raw_string_ostream s(Str);
getUnderlyingExpr()->printPretty(s, 0, Policy);
InnerString = "decltype(" + s.str() + ")" + InnerString;
}
void FunctionNoProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
// If needed for precedence reasons, wrap the inner part in grouping parens.
if (!S.empty())

Просмотреть файл

@ -810,6 +810,9 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
case Type::TypeOf:
return Slot = getOrCreateType(cast<TypeOfType>(Ty)->getUnderlyingType(),
Unit);
case Type::Decltype:
return Slot = getOrCreateType(cast<DecltypeType>(Ty)->getUnderlyingExpr()
->getType(), Unit);
}
return Slot;

Просмотреть файл

@ -1822,7 +1822,10 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
QualType UnderlyingType = GetType(Record[0]);
return Context->getTypeOfType(UnderlyingType);
}
case pch::TYPE_DECLTYPE:
return Context->getDecltypeType(ReadTypeExpr());
case pch::TYPE_RECORD:
assert(Record.size() == 1 && "incorrect encoding of record type");
return Context->getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));

Просмотреть файл

@ -185,6 +185,11 @@ void PCHTypeWriter::VisitTypeOfType(const TypeOfType *T) {
Code = pch::TYPE_TYPEOF;
}
void PCHTypeWriter::VisitDecltypeType(const DecltypeType *T) {
Writer.AddStmt(T->getUnderlyingExpr());
Code = pch::TYPE_DECLTYPE;
}
void PCHTypeWriter::VisitTagType(const TagType *T) {
Writer.AddDeclRef(T->getDecl(), Record);
assert(!T->isBeingDefined() &&

Просмотреть файл

@ -546,6 +546,18 @@ TemplateTypeInstantiator::InstantiateTypeOfType(const TypeOfType *T,
return SemaRef.Context.getTypeOfType(Underlying);
}
QualType
TemplateTypeInstantiator::InstantiateDecltypeType(const DecltypeType *T,
unsigned Quals) const {
Sema::OwningExprResult E
= SemaRef.InstantiateExpr(T->getUnderlyingExpr(), TemplateArgs);
if (E.isInvalid())
return QualType();
return SemaRef.Context.getDecltypeType(E.takeAs<Expr>());
}
QualType
TemplateTypeInstantiator::InstantiateRecordType(const RecordType *T,
unsigned Quals) const {