зеркало из https://github.com/microsoft/clang.git
Add a DecltypeType type.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74099 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
6fe1ef2bbb
Коммит
395b475a44
|
@ -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;
|
||||
|
|
|
@ -1823,6 +1823,9 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
|
|||
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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче