diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 |
commit | 5563df30b9c8d1fe87a54baae0d6bd86642563f4 (patch) | |
tree | 3fdd91eae574e32453a4baf462961c742df2691a /lib/AST | |
parent | e5557c18e5d41b4b62f2af8a24af20eba40b0225 (diff) | |
download | FreeBSD-src-5563df30b9c8d1fe87a54baae0d6bd86642563f4.zip FreeBSD-src-5563df30b9c8d1fe87a54baae0d6bd86642563f4.tar.gz |
Update clang to r84949.
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 507 | ||||
-rw-r--r-- | lib/AST/CXXInheritance.cpp | 2 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 53 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 2 | ||||
-rw-r--r-- | lib/AST/DeclarationName.cpp | 4 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 50 | ||||
-rw-r--r-- | lib/AST/Stmt.cpp | 2 | ||||
-rw-r--r-- | lib/AST/StmtDumper.cpp | 8 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 2 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 91 | ||||
-rw-r--r-- | lib/AST/TypeLoc.cpp | 207 |
11 files changed, 519 insertions, 409 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index e028186..7f5fa35 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -40,7 +40,8 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, bool FreeMem, unsigned size_reserve) : GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0), ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), jmp_bufDecl(0), - sigjmp_bufDecl(0), SourceMgr(SM), LangOpts(LOpts), + sigjmp_bufDecl(0), BlockDescriptorType(0), BlockDescriptorExtendedType(0), + SourceMgr(SM), LangOpts(LOpts), LoadedExternalComments(false), FreeMemory(FreeMem), Target(t), Idents(idents), Selectors(sels), BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) { @@ -554,10 +555,6 @@ ASTContext::getTypeInfo(const Type *T) { assert(false && "Should not see dependent types"); break; - case Type::ObjCProtocolList: - assert(false && "Should not see protocol list types"); - break; - case Type::FunctionNoProto: case Type::FunctionProto: // GCC extension: alignof(function) = 32 bits @@ -571,8 +568,6 @@ ASTContext::getTypeInfo(const Type *T) { Align = getTypeAlign(cast<ArrayType>(T)->getElementType()); break; - case Type::ConstantArrayWithExpr: - case Type::ConstantArrayWithoutExpr: case Type::ConstantArray: { const ConstantArrayType *CAT = cast<ConstantArrayType>(T); @@ -583,14 +578,16 @@ ASTContext::getTypeInfo(const Type *T) { } case Type::ExtVector: case Type::Vector: { - std::pair<uint64_t, unsigned> EltInfo = - getTypeInfo(cast<VectorType>(T)->getElementType()); - Width = EltInfo.first*cast<VectorType>(T)->getNumElements(); + const VectorType *VT = cast<VectorType>(T); + std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(VT->getElementType()); + Width = EltInfo.first*VT->getNumElements(); Align = Width; // If the alignment is not a power of 2, round up to the next power of 2. // This happens for non-power-of-2 length vectors. - // FIXME: this should probably be a target property. - Align = 1 << llvm::Log2_32_Ceil(Align); + if (VT->getNumElements() & (VT->getNumElements()-1)) { + Align = llvm::NextPowerOf2(Align); + Width = llvm::RoundUpToAlignment(Width, Align); + } break; } @@ -749,9 +746,13 @@ ASTContext::getTypeInfo(const Type *T) { break; } - case Type::Elaborated: { - return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType().getTypePtr()); - } + case Type::SubstTemplateTypeParm: + return getTypeInfo(cast<SubstTemplateTypeParmType>(T)-> + getReplacementType().getTypePtr()); + + case Type::Elaborated: + return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType() + .getTypePtr()); case Type::Typedef: { const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl(); @@ -940,8 +941,14 @@ void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD, /// \param T the type that will be the basis for type source info. This type /// should refer to how the declarator was written in source code, not to /// what type semantic analysis resolved the declarator to. -DeclaratorInfo *ASTContext::CreateDeclaratorInfo(QualType T) { - unsigned DataSize = TypeLoc::getFullDataSizeForType(T); +DeclaratorInfo *ASTContext::CreateDeclaratorInfo(QualType T, + unsigned DataSize) { + if (!DataSize) + DataSize = TypeLoc::getFullDataSizeForType(T); + else + assert(DataSize == TypeLoc::getFullDataSizeForType(T) && + "incorrect data size provided to CreateDeclaratorInfo!"); + DeclaratorInfo *DInfo = (DeclaratorInfo*)BumpAlloc.Allocate(sizeof(DeclaratorInfo) + DataSize, 8); new (DInfo) DeclaratorInfo(T); @@ -1140,7 +1147,7 @@ QualType ASTContext::getComplexType(QualType T) { // If the pointee type isn't canonical, this won't be a canonical type either, // so fill in the canonical type field. QualType Canonical; - if (!T->isCanonical()) { + if (!T.isCanonical()) { Canonical = getComplexType(getCanonicalType(T)); // Get the new insert position for the node we care about. @@ -1177,7 +1184,7 @@ QualType ASTContext::getPointerType(QualType T) { // If the pointee type isn't canonical, this won't be a canonical type either, // so fill in the canonical type field. QualType Canonical; - if (!T->isCanonical()) { + if (!T.isCanonical()) { Canonical = getPointerType(getCanonicalType(T)); // Get the new insert position for the node we care about. @@ -1207,7 +1214,7 @@ QualType ASTContext::getBlockPointerType(QualType T) { // If the block pointee type isn't canonical, this won't be a canonical // type either so fill in the canonical type field. QualType Canonical; - if (!T->isCanonical()) { + if (!T.isCanonical()) { Canonical = getBlockPointerType(getCanonicalType(T)); // Get the new insert position for the node we care about. @@ -1224,22 +1231,25 @@ QualType ASTContext::getBlockPointerType(QualType T) { /// getLValueReferenceType - Return the uniqued reference to the type for an /// lvalue reference to the specified type. -QualType ASTContext::getLValueReferenceType(QualType T) { +QualType ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) { // Unique pointers, to guarantee there is only one pointer of a particular // structure. llvm::FoldingSetNodeID ID; - ReferenceType::Profile(ID, T); + ReferenceType::Profile(ID, T, SpelledAsLValue); void *InsertPos = 0; if (LValueReferenceType *RT = LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(RT, 0); + const ReferenceType *InnerRef = T->getAs<ReferenceType>(); + // If the referencee type isn't canonical, this won't be a canonical type // either, so fill in the canonical type field. QualType Canonical; - if (!T->isCanonical()) { - Canonical = getLValueReferenceType(getCanonicalType(T)); + if (!SpelledAsLValue || InnerRef || !T.isCanonical()) { + QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T); + Canonical = getLValueReferenceType(getCanonicalType(PointeeType)); // Get the new insert position for the node we care about. LValueReferenceType *NewIP = @@ -1248,9 +1258,11 @@ QualType ASTContext::getLValueReferenceType(QualType T) { } LValueReferenceType *New - = new (*this, TypeAlignment) LValueReferenceType(T, Canonical); + = new (*this, TypeAlignment) LValueReferenceType(T, Canonical, + SpelledAsLValue); Types.push_back(New); LValueReferenceTypes.InsertNode(New, InsertPos); + return QualType(New, 0); } @@ -1260,18 +1272,21 @@ QualType ASTContext::getRValueReferenceType(QualType T) { // Unique pointers, to guarantee there is only one pointer of a particular // structure. llvm::FoldingSetNodeID ID; - ReferenceType::Profile(ID, T); + ReferenceType::Profile(ID, T, false); void *InsertPos = 0; if (RValueReferenceType *RT = RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(RT, 0); + const ReferenceType *InnerRef = T->getAs<ReferenceType>(); + // If the referencee type isn't canonical, this won't be a canonical type // either, so fill in the canonical type field. QualType Canonical; - if (!T->isCanonical()) { - Canonical = getRValueReferenceType(getCanonicalType(T)); + if (InnerRef || !T.isCanonical()) { + QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T); + Canonical = getRValueReferenceType(getCanonicalType(PointeeType)); // Get the new insert position for the node we care about. RValueReferenceType *NewIP = @@ -1302,7 +1317,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) { // If the pointee or class type isn't canonical, this won't be a canonical // type either, so fill in the canonical type field. QualType Canonical; - if (!T->isCanonical()) { + if (!T.isCanonical()) { Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls)); // Get the new insert position for the node we care about. @@ -1342,7 +1357,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, // If the element type isn't canonical, this won't be a canonical type either, // so fill in the canonical type field. QualType Canonical; - if (!EltTy->isCanonical()) { + if (!EltTy.isCanonical()) { Canonical = getConstantArrayType(getCanonicalType(EltTy), ArySize, ASM, EltTypeQuals); // Get the new insert position for the node we care about. @@ -1358,53 +1373,6 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, return QualType(New, 0); } -/// getConstantArrayWithExprType - Return a reference to the type for -/// an array of the specified element type. -QualType -ASTContext::getConstantArrayWithExprType(QualType EltTy, - const llvm::APInt &ArySizeIn, - Expr *ArySizeExpr, - ArrayType::ArraySizeModifier ASM, - unsigned EltTypeQuals, - SourceRange Brackets) { - // Convert the array size into a canonical width matching the pointer - // size for the target. - llvm::APInt ArySize(ArySizeIn); - ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace())); - - // Compute the canonical ConstantArrayType. - QualType Canonical = getConstantArrayType(getCanonicalType(EltTy), - ArySize, ASM, EltTypeQuals); - // Since we don't unique expressions, it isn't possible to unique VLA's - // that have an expression provided for their size. - ConstantArrayWithExprType *New = new(*this, TypeAlignment) - ConstantArrayWithExprType(EltTy, Canonical, ArySize, ArySizeExpr, - ASM, EltTypeQuals, Brackets); - Types.push_back(New); - return QualType(New, 0); -} - -/// getConstantArrayWithoutExprType - Return a reference to the type for -/// an array of the specified element type. -QualType -ASTContext::getConstantArrayWithoutExprType(QualType EltTy, - const llvm::APInt &ArySizeIn, - ArrayType::ArraySizeModifier ASM, - unsigned EltTypeQuals) { - // Convert the array size into a canonical width matching the pointer - // size for the target. - llvm::APInt ArySize(ArySizeIn); - ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace())); - - // Compute the canonical ConstantArrayType. - QualType Canonical = getConstantArrayType(getCanonicalType(EltTy), - ArySize, ASM, EltTypeQuals); - ConstantArrayWithoutExprType *New = new(*this, TypeAlignment) - ConstantArrayWithoutExprType(EltTy, Canonical, ArySize, ASM, EltTypeQuals); - Types.push_back(New); - return QualType(New, 0); -} - /// getVariableArrayType - Returns a non-unique reference to the type for a /// variable array of the specified element type. QualType ASTContext::getVariableArrayType(QualType EltTy, @@ -1484,7 +1452,7 @@ QualType ASTContext::getIncompleteArrayType(QualType EltTy, // either, so fill in the canonical type field. QualType Canonical; - if (!EltTy->isCanonical()) { + if (!EltTy.isCanonical()) { Canonical = getIncompleteArrayType(getCanonicalType(EltTy), ASM, EltTypeQuals); @@ -1520,7 +1488,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) { // If the element type isn't canonical, this won't be a canonical type either, // so fill in the canonical type field. QualType Canonical; - if (!vecType->isCanonical()) { + if (!vecType.isCanonical()) { Canonical = getVectorType(getCanonicalType(vecType), NumElts); // Get the new insert position for the node we care about. @@ -1552,7 +1520,7 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) { // If the element type isn't canonical, this won't be a canonical type either, // so fill in the canonical type field. QualType Canonical; - if (!vecType->isCanonical()) { + if (!vecType.isCanonical()) { Canonical = getExtVectorType(getCanonicalType(vecType), NumElts); // Get the new insert position for the node we care about. @@ -1616,7 +1584,7 @@ QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn) { return QualType(FT, 0); QualType Canonical; - if (!ResultTy->isCanonical()) { + if (!ResultTy.isCanonical()) { Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn); // Get the new insert position for the node we care about. @@ -1639,12 +1607,6 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, unsigned TypeQuals, bool hasExceptionSpec, bool hasAnyExceptionSpec, unsigned NumExs, const QualType *ExArray, bool NoReturn) { - if (LangOpts.CPlusPlus) { - for (unsigned i = 0; i != NumArgs; ++i) - assert(!ArgArray[i].hasQualifiers() && - "C++ arguments can't have toplevel qualifiers!"); - } - // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; @@ -1658,11 +1620,9 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, return QualType(FTP, 0); // Determine whether the type being created is already canonical or not. - bool isCanonical = ResultTy->isCanonical(); - if (hasExceptionSpec) - isCanonical = false; + bool isCanonical = !hasExceptionSpec && ResultTy.isCanonical(); for (unsigned i = 0; i != NumArgs && isCanonical; ++i) - if (!ArgArray[i]->isCanonical()) + if (!ArgArray[i].isCanonicalAsParam()) isCanonical = false; // If this type isn't canonical, get the canonical version of it. @@ -1672,7 +1632,7 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, llvm::SmallVector<QualType, 16> CanonicalArgs; CanonicalArgs.reserve(NumArgs); for (unsigned i = 0; i != NumArgs; ++i) - CanonicalArgs.push_back(getCanonicalType(ArgArray[i])); + CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i])); Canonical = getFunctionType(getCanonicalType(ResultTy), CanonicalArgs.data(), NumArgs, @@ -1743,6 +1703,29 @@ QualType ASTContext::getTypedefType(TypedefDecl *Decl) { return QualType(Decl->TypeForDecl, 0); } +/// \brief Retrieve a substitution-result type. +QualType +ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm, + QualType Replacement) { + assert(Replacement.isCanonical() + && "replacement types must always be canonical"); + + llvm::FoldingSetNodeID ID; + SubstTemplateTypeParmType::Profile(ID, Parm, Replacement); + void *InsertPos = 0; + SubstTemplateTypeParmType *SubstParm + = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); + + if (!SubstParm) { + SubstParm = new (*this, TypeAlignment) + SubstTemplateTypeParmType(Parm, Replacement); + Types.push_back(SubstParm); + SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos); + } + + return QualType(SubstParm, 0); +} + /// \brief Retrieve the template type parameter type for a template /// parameter or parameter pack with the given depth, index, and (optionally) /// name. @@ -1933,7 +1916,17 @@ static bool CmpProtocolNames(const ObjCProtocolDecl *LHS, return LHS->getDeclName() < RHS->getDeclName(); } -static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols, +static bool areSortedAndUniqued(ObjCProtocolDecl **Protocols, + unsigned NumProtocols) { + if (NumProtocols == 0) return true; + + for (unsigned i = 1; i != NumProtocols; ++i) + if (!CmpProtocolNames(Protocols[i-1], Protocols[i])) + return false; + return true; +} + +static void SortAndUniqueProtocols(ObjCProtocolDecl **Protocols, unsigned &NumProtocols) { ObjCProtocolDecl **ProtocolsEnd = Protocols+NumProtocols; @@ -1950,10 +1943,6 @@ static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols, QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT, ObjCProtocolDecl **Protocols, unsigned NumProtocols) { - // Sort the protocol list alphabetically to canonicalize it. - if (NumProtocols) - SortAndUniqueProtocols(Protocols, NumProtocols); - llvm::FoldingSetNodeID ID; ObjCObjectPointerType::Profile(ID, InterfaceT, Protocols, NumProtocols); @@ -1962,9 +1951,31 @@ QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT, ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(QT, 0); + // Sort the protocol list alphabetically to canonicalize it. + QualType Canonical; + if (!InterfaceT.isCanonical() || + !areSortedAndUniqued(Protocols, NumProtocols)) { + if (!areSortedAndUniqued(Protocols, NumProtocols)) { + llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(NumProtocols); + unsigned UniqueCount = NumProtocols; + + std::copy(Protocols, Protocols + NumProtocols, Sorted.begin()); + SortAndUniqueProtocols(&Sorted[0], UniqueCount); + + Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT), + &Sorted[0], UniqueCount); + } else { + Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT), + Protocols, NumProtocols); + } + + // Regenerate InsertPos. + ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos); + } + // No Match; ObjCObjectPointerType *QType = new (*this, TypeAlignment) - ObjCObjectPointerType(InterfaceT, Protocols, NumProtocols); + ObjCObjectPointerType(Canonical, InterfaceT, Protocols, NumProtocols); Types.push_back(QType); ObjCObjectPointerTypes.InsertNode(QType, InsertPos); @@ -1975,10 +1986,6 @@ QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT, /// specified ObjC interface decl. The list of protocols is optional. QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCProtocolDecl **Protocols, unsigned NumProtocols) { - if (NumProtocols) - // Sort the protocol list alphabetically to canonicalize it. - SortAndUniqueProtocols(Protocols, NumProtocols); - llvm::FoldingSetNodeID ID; ObjCInterfaceType::Profile(ID, Decl, Protocols, NumProtocols); @@ -1987,31 +1994,26 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(QT, 0); - // No Match; - ObjCInterfaceType *QType = new (*this, TypeAlignment) - ObjCInterfaceType(const_cast<ObjCInterfaceDecl*>(Decl), - Protocols, NumProtocols); - Types.push_back(QType); - ObjCInterfaceTypes.InsertNode(QType, InsertPos); - return QualType(QType, 0); -} + // Sort the protocol list alphabetically to canonicalize it. + QualType Canonical; + if (NumProtocols && !areSortedAndUniqued(Protocols, NumProtocols)) { + llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(NumProtocols); + std::copy(Protocols, Protocols + NumProtocols, Sorted.begin()); -QualType ASTContext::getObjCProtocolListType(QualType T, - ObjCProtocolDecl **Protocols, - unsigned NumProtocols) { - llvm::FoldingSetNodeID ID; - ObjCProtocolListType::Profile(ID, T, Protocols, NumProtocols); + unsigned UniqueCount = NumProtocols; + SortAndUniqueProtocols(&Sorted[0], UniqueCount); - void *InsertPos = 0; - if (ObjCProtocolListType *QT = - ObjCProtocolListTypes.FindNodeOrInsertPos(ID, InsertPos)) - return QualType(QT, 0); + Canonical = getObjCInterfaceType(Decl, &Sorted[0], UniqueCount); + + ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos); + } + + ObjCInterfaceType *QType = new (*this, TypeAlignment) + ObjCInterfaceType(Canonical, const_cast<ObjCInterfaceDecl*>(Decl), + Protocols, NumProtocols); - // No Match; - ObjCProtocolListType *QType = new (*this, TypeAlignment) - ObjCProtocolListType(T, Protocols, NumProtocols); Types.push_back(QType); - ObjCProtocolListTypes.InsertNode(QType, InsertPos); + ObjCInterfaceTypes.InsertNode(QType, InsertPos); return QualType(QType, 0); } @@ -2168,6 +2170,24 @@ QualType ASTContext::getPointerDiffType() const { // Type Operators //===----------------------------------------------------------------------===// +CanQualType ASTContext::getCanonicalParamType(QualType T) { + // Push qualifiers into arrays, and then discard any remaining + // qualifiers. + T = getCanonicalType(T); + const Type *Ty = T.getTypePtr(); + + QualType Result; + if (isa<ArrayType>(Ty)) { + Result = getArrayDecayedType(QualType(Ty,0)); + } else if (isa<FunctionType>(Ty)) { + Result = getPointerType(QualType(Ty, 0)); + } else { + Result = QualType(Ty, 0); + } + + return CanQualType::CreateUnsafe(Result); +} + /// getCanonicalType - Return the canonical (structural) type corresponding to /// the specified potentially non-canonical type. The non-canonical version /// of a type may have many "decorated" versions of types. Decorators can @@ -2512,7 +2532,7 @@ int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) { /// routine will assert if passed a built-in type that isn't an integer or enum, /// or if it is not canonicalized. unsigned ASTContext::getIntegerRank(Type *T) { - assert(T->isCanonical() && "T should be canonicalized"); + assert(T->isCanonicalUnqualified() && "T should be canonicalized"); if (EnumType* ET = dyn_cast<EnumType>(T)) T = ET->getDecl()->getIntegerType().getTypePtr(); @@ -2713,6 +2733,226 @@ QualType ASTContext::getObjCFastEnumerationStateType() { return getTagDeclType(ObjCFastEnumerationStateTypeDecl); } +QualType ASTContext::getBlockDescriptorType() { + if (BlockDescriptorType) + return getTagDeclType(BlockDescriptorType); + + RecordDecl *T; + // FIXME: Needs the FlagAppleBlock bit. + T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + &Idents.get("__block_descriptor")); + + QualType FieldTypes[] = { + UnsignedLongTy, + UnsignedLongTy, + }; + + const char *FieldNames[] = { + "reserved", + "Size" + }; + + for (size_t i = 0; i < 2; ++i) { + FieldDecl *Field = FieldDecl::Create(*this, + T, + SourceLocation(), + &Idents.get(FieldNames[i]), + FieldTypes[i], /*DInfo=*/0, + /*BitWidth=*/0, + /*Mutable=*/false); + T->addDecl(Field); + } + + T->completeDefinition(*this); + + BlockDescriptorType = T; + + return getTagDeclType(BlockDescriptorType); +} + +void ASTContext::setBlockDescriptorType(QualType T) { + const RecordType *Rec = T->getAs<RecordType>(); + assert(Rec && "Invalid BlockDescriptorType"); + BlockDescriptorType = Rec->getDecl(); +} + +QualType ASTContext::getBlockDescriptorExtendedType() { + if (BlockDescriptorExtendedType) + return getTagDeclType(BlockDescriptorExtendedType); + + RecordDecl *T; + // FIXME: Needs the FlagAppleBlock bit. + T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + &Idents.get("__block_descriptor_withcopydispose")); + + QualType FieldTypes[] = { + UnsignedLongTy, + UnsignedLongTy, + getPointerType(VoidPtrTy), + getPointerType(VoidPtrTy) + }; + + const char *FieldNames[] = { + "reserved", + "Size", + "CopyFuncPtr", + "DestroyFuncPtr" + }; + + for (size_t i = 0; i < 4; ++i) { + FieldDecl *Field = FieldDecl::Create(*this, + T, + SourceLocation(), + &Idents.get(FieldNames[i]), + FieldTypes[i], /*DInfo=*/0, + /*BitWidth=*/0, + /*Mutable=*/false); + T->addDecl(Field); + } + + T->completeDefinition(*this); + + BlockDescriptorExtendedType = T; + + return getTagDeclType(BlockDescriptorExtendedType); +} + +void ASTContext::setBlockDescriptorExtendedType(QualType T) { + const RecordType *Rec = T->getAs<RecordType>(); + assert(Rec && "Invalid BlockDescriptorType"); + BlockDescriptorExtendedType = Rec->getDecl(); +} + +bool ASTContext::BlockRequiresCopying(QualType Ty) { + if (Ty->isBlockPointerType()) + return true; + if (isObjCNSObjectType(Ty)) + return true; + if (Ty->isObjCObjectPointerType()) + return true; + return false; +} + +QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) { + // type = struct __Block_byref_1_X { + // void *__isa; + // struct __Block_byref_1_X *__forwarding; + // unsigned int __flags; + // unsigned int __size; + // void *__copy_helper; // as needed + // void *__destroy_help // as needed + // int X; + // } * + + bool HasCopyAndDispose = BlockRequiresCopying(Ty); + + // FIXME: Move up + static int UniqueBlockByRefTypeID = 0; + char Name[36]; + sprintf(Name, "__Block_byref_%d_%s", ++UniqueBlockByRefTypeID, DeclName); + RecordDecl *T; + T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + &Idents.get(Name)); + T->startDefinition(); + QualType Int32Ty = IntTy; + assert(getIntWidth(IntTy) == 32 && "non-32bit int not supported"); + QualType FieldTypes[] = { + getPointerType(VoidPtrTy), + getPointerType(getTagDeclType(T)), + Int32Ty, + Int32Ty, + getPointerType(VoidPtrTy), + getPointerType(VoidPtrTy), + Ty + }; + + const char *FieldNames[] = { + "__isa", + "__forwarding", + "__flags", + "__size", + "__copy_helper", + "__destroy_helper", + DeclName, + }; + + for (size_t i = 0; i < 7; ++i) { + if (!HasCopyAndDispose && i >=4 && i <= 5) + continue; + FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(), + &Idents.get(FieldNames[i]), + FieldTypes[i], /*DInfo=*/0, + /*BitWidth=*/0, /*Mutable=*/false); + T->addDecl(Field); + } + + T->completeDefinition(*this); + + return getPointerType(getTagDeclType(T)); +} + + +QualType ASTContext::getBlockParmType( + bool BlockHasCopyDispose, + llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) { + // FIXME: Move up + static int UniqueBlockParmTypeID = 0; + char Name[36]; + sprintf(Name, "__block_literal_%u", ++UniqueBlockParmTypeID); + RecordDecl *T; + T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + &Idents.get(Name)); + QualType FieldTypes[] = { + getPointerType(VoidPtrTy), + IntTy, + IntTy, + getPointerType(VoidPtrTy), + (BlockHasCopyDispose ? + getPointerType(getBlockDescriptorExtendedType()) : + getPointerType(getBlockDescriptorType())) + }; + + const char *FieldNames[] = { + "__isa", + "__flags", + "__reserved", + "__FuncPtr", + "__descriptor" + }; + + for (size_t i = 0; i < 5; ++i) { + FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(), + &Idents.get(FieldNames[i]), + FieldTypes[i], /*DInfo=*/0, + /*BitWidth=*/0, /*Mutable=*/false); + T->addDecl(Field); + } + + for (size_t i = 0; i < BlockDeclRefDecls.size(); ++i) { + const Expr *E = BlockDeclRefDecls[i]; + const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E); + clang::IdentifierInfo *Name = 0; + if (BDRE) { + const ValueDecl *D = BDRE->getDecl(); + Name = &Idents.get(D->getName()); + } + QualType FieldType = E->getType(); + + if (BDRE && BDRE->isByRef()) + FieldType = BuildByRefType(BDRE->getDecl()->getNameAsCString(), + FieldType); + + FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(), + Name, FieldType, /*DInfo=*/0, + /*BitWidth=*/0, /*Mutable=*/false); + T->addDecl(Field); + } + + T->completeDefinition(*this); + + return getPointerType(getTagDeclType(T)); +} + void ASTContext::setObjCFastEnumerationStateType(QualType T) { const RecordType *Rec = T->getAs<RecordType>(); assert(Rec && "Invalid ObjCFAstEnumerationStateType"); @@ -2945,6 +3185,7 @@ static void EncodeBitField(const ASTContext *Context, std::string& S, S += llvm::utostr(N); } +// FIXME: Use SmallString for accumulating string. void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, bool ExpandPointedToStructures, bool ExpandStructures, @@ -3420,7 +3661,7 @@ Qualifiers::GC ASTContext::getObjCGCAttrKind(const QualType &Ty) const { /// compatible. static bool areCompatVectorTypes(const VectorType *LHS, const VectorType *RHS) { - assert(LHS->isCanonical() && RHS->isCanonical()); + assert(LHS->isCanonicalUnqualified() && RHS->isCanonicalUnqualified()); return LHS->getElementType() == RHS->getElementType() && LHS->getNumElements() == RHS->getNumElements(); } @@ -3979,7 +4220,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) { unsigned ASTContext::getIntWidth(QualType T) { if (T == BoolTy) return 1; - if (FixedWidthIntType* FWIT = dyn_cast<FixedWidthIntType>(T)) { + if (FixedWidthIntType *FWIT = dyn_cast<FixedWidthIntType>(T)) { return FWIT->getWidth(); } // For builtin types, just use the standard type sizing method @@ -3988,10 +4229,18 @@ unsigned ASTContext::getIntWidth(QualType T) { QualType ASTContext::getCorrespondingUnsignedType(QualType T) { assert(T->isSignedIntegerType() && "Unexpected type"); - if (const EnumType* ETy = T->getAs<EnumType>()) + + // Turn <4 x signed int> -> <4 x unsigned int> + if (const VectorType *VTy = T->getAs<VectorType>()) + return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()), + VTy->getNumElements()); + + // For enums, we return the unsigned version of the base type. + if (const EnumType *ETy = T->getAs<EnumType>()) T = ETy->getDecl()->getIntegerType(); - const BuiltinType* BTy = T->getAs<BuiltinType>(); - assert (BTy && "Unexpected signed integer type"); + + const BuiltinType *BTy = T->getAs<BuiltinType>(); + assert(BTy && "Unexpected signed integer type"); switch (BTy->getKind()) { case BuiltinType::Char_S: case BuiltinType::SChar: diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp index 4a46eab..b59b45f 100644 --- a/lib/AST/CXXInheritance.cpp +++ b/lib/AST/CXXInheritance.cpp @@ -50,7 +50,7 @@ CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() { /// different base class subobjects of the same type. BaseType must be /// an unqualified, canonical class type. bool CXXBasePaths::isAmbiguous(QualType BaseType) { - assert(BaseType->isCanonical() && "Base type must be the canonical type"); + assert(BaseType.isCanonical() && "Base type must be the canonical type"); assert(BaseType.hasQualifiers() == 0 && "Base type must be unqualified"); std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType]; return Subobjects.second + (Subobjects.first? 1 : 0) > 1; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index da7959b..d270a95 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -231,6 +231,8 @@ std::string NamedDecl::getQualifiedNameAsString() const { } std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const { + // FIXME: Collect contexts, then accumulate names to avoid unnecessary + // std::string thrashing. std::vector<std::string> Names; std::string QualName; const DeclContext *Ctx = getDeclContext(); @@ -252,7 +254,7 @@ std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const { TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(), P); - Names.push_back(Spec->getIdentifier()->getName() + TemplateArgsStr); + Names.push_back(Spec->getIdentifier()->getNameStart() + TemplateArgsStr); } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx)) Names.push_back(ND->getNameAsString()); else @@ -336,8 +338,15 @@ NamedDecl *NamedDecl::getUnderlyingDecl() { //===----------------------------------------------------------------------===// SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const { - if (DeclInfo) - return DeclInfo->getTypeLoc().getTypeSpecRange().getBegin(); + if (DeclInfo) { + TypeLoc TL = DeclInfo->getTypeLoc(); + while (true) { + TypeLoc NextTL = TL.getNextTypeLoc(); + if (!NextTL) + return TL.getSourceRange().getBegin(); + TL = NextTL; + } + } return SourceLocation(); } @@ -408,10 +417,15 @@ MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const { return getASTContext().getInstantiatedFromStaticDataMember(this); } -void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) { +void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, + SourceLocation PointOfInstantiation) { MemberSpecializationInfo *MSI = getMemberSpecializationInfo(); assert(MSI && "Not an instantiated static data member?"); MSI->setTemplateSpecializationKind(TSK); + if (TSK != TSK_ExplicitSpecialization && + PointOfInstantiation.isValid() && + MSI->getPointOfInstantiation().isInvalid()) + MSI->setPointOfInstantiation(PointOfInstantiation); } bool VarDecl::isTentativeDefinition(ASTContext &Context) const { @@ -812,18 +826,39 @@ TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const { } void -FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) { +FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, + SourceLocation PointOfInstantiation) { if (FunctionTemplateSpecializationInfo *FTSInfo = TemplateOrSpecialization.dyn_cast< - FunctionTemplateSpecializationInfo*>()) + FunctionTemplateSpecializationInfo*>()) { FTSInfo->setTemplateSpecializationKind(TSK); - else if (MemberSpecializationInfo *MSInfo - = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) + if (TSK != TSK_ExplicitSpecialization && + PointOfInstantiation.isValid() && + FTSInfo->getPointOfInstantiation().isInvalid()) + FTSInfo->setPointOfInstantiation(PointOfInstantiation); + } else if (MemberSpecializationInfo *MSInfo + = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) { MSInfo->setTemplateSpecializationKind(TSK); - else + if (TSK != TSK_ExplicitSpecialization && + PointOfInstantiation.isValid() && + MSInfo->getPointOfInstantiation().isInvalid()) + MSInfo->setPointOfInstantiation(PointOfInstantiation); + } else assert(false && "Function cannot have a template specialization kind"); } +SourceLocation FunctionDecl::getPointOfInstantiation() const { + if (FunctionTemplateSpecializationInfo *FTSInfo + = TemplateOrSpecialization.dyn_cast< + FunctionTemplateSpecializationInfo*>()) + return FTSInfo->getPointOfInstantiation(); + else if (MemberSpecializationInfo *MSInfo + = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) + return MSInfo->getPointOfInstantiation(); + + return SourceLocation(); +} + bool FunctionDecl::isOutOfLine() const { if (Decl::isOutOfLine()) return true; diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 7836b3f..9a1c654 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -299,7 +299,7 @@ void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) { switch (Arg.getKind()) { default: break; case TemplateArgument::Type: - assert(Arg.getAsType()->isCanonical() && "Type must be canonical!"); + assert(Arg.getAsType().isCanonical() && "Type must be canonical!"); break; } diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp index 101ddd2..56a5975 100644 --- a/lib/AST/DeclarationName.cpp +++ b/lib/AST/DeclarationName.cpp @@ -51,7 +51,7 @@ public: bool operator<(DeclarationName LHS, DeclarationName RHS) { if (IdentifierInfo *LhsId = LHS.getAsIdentifierInfo()) if (IdentifierInfo *RhsId = RHS.getAsIdentifierInfo()) - return strcmp(LhsId->getName(), RhsId->getName()) < 0; + return LhsId->getName() < RhsId->getName(); return LHS.getAsOpaqueInteger() < RHS.getAsOpaqueInteger(); } @@ -60,7 +60,7 @@ bool operator<(DeclarationName LHS, DeclarationName RHS) { DeclarationName::DeclarationName(Selector Sel) { if (!Sel.getAsOpaquePtr()) { - Ptr = StoredObjCZeroArgSelector; + Ptr = 0; return; } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 0e4a29f..a4de3e5 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -426,6 +426,18 @@ const char *CastExpr::getCastKindName() const { return "IntegralToPointer"; case CastExpr::CK_PointerToIntegral: return "PointerToIntegral"; + case CastExpr::CK_ToVoid: + return "ToVoid"; + case CastExpr::CK_VectorSplat: + return "VectorSplat"; + case CastExpr::CK_IntegralCast: + return "IntegralCast"; + case CastExpr::CK_IntegralToFloating: + return "IntegralToFloating"; + case CastExpr::CK_FloatingToIntegral: + return "FloatingToIntegral"; + case CastExpr::CK_FloatingCast: + return "FloatingCast"; } assert(0 && "Unhandled cast kind!"); @@ -1740,40 +1752,36 @@ unsigned ExtVectorElementExpr::getNumElements() const { /// containsDuplicateElements - Return true if any element access is repeated. bool ExtVectorElementExpr::containsDuplicateElements() const { - const char *compStr = Accessor->getName(); - unsigned length = Accessor->getLength(); + // FIXME: Refactor this code to an accessor on the AST node which returns the + // "type" of component access, and share with code below and in Sema. + llvm::StringRef Comp = Accessor->getName(); // Halving swizzles do not contain duplicate elements. - if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") || - !strcmp(compStr, "even") || !strcmp(compStr, "odd")) + if (Comp == "hi" || Comp == "lo" || Comp == "even" || Comp == "odd") return false; // Advance past s-char prefix on hex swizzles. - if (*compStr == 's' || *compStr == 'S') { - compStr++; - length--; - } + if (Comp[0] == 's' || Comp[0] == 'S') + Comp = Comp.substr(1); - for (unsigned i = 0; i != length-1; i++) { - const char *s = compStr+i; - for (const char c = *s++; *s; s++) - if (c == *s) + for (unsigned i = 0, e = Comp.size(); i != e; ++i) + if (Comp.substr(i + 1).find(Comp[i]) != llvm::StringRef::npos) return true; - } + return false; } /// getEncodedElementAccess - We encode the fields as a llvm ConstantArray. void ExtVectorElementExpr::getEncodedElementAccess( llvm::SmallVectorImpl<unsigned> &Elts) const { - const char *compStr = Accessor->getName(); - if (*compStr == 's' || *compStr == 'S') - compStr++; + llvm::StringRef Comp = Accessor->getName(); + if (Comp[0] == 's' || Comp[0] == 'S') + Comp = Comp.substr(1); - bool isHi = !strcmp(compStr, "hi"); - bool isLo = !strcmp(compStr, "lo"); - bool isEven = !strcmp(compStr, "even"); - bool isOdd = !strcmp(compStr, "odd"); + bool isHi = Comp == "hi"; + bool isLo = Comp == "lo"; + bool isEven = Comp == "even"; + bool isOdd = Comp == "odd"; for (unsigned i = 0, e = getNumElements(); i != e; ++i) { uint64_t Index; @@ -1787,7 +1795,7 @@ void ExtVectorElementExpr::getEncodedElementAccess( else if (isOdd) Index = 2 * i + 1; else - Index = ExtVectorType::getAccessorIdx(compStr[i]); + Index = ExtVectorType::getAccessorIdx(Comp[i]); Elts.push_back(Index); } diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 3a838fa..6e0da47 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -117,7 +117,7 @@ void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) { } const char *LabelStmt::getName() const { - return getID()->getName(); + return getID()->getNameStart(); } // This is defined here to avoid polluting Stmt.h with importing Expr.h diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp index 0465999..cf71d6b 100644 --- a/lib/AST/StmtDumper.cpp +++ b/lib/AST/StmtDumper.cpp @@ -244,7 +244,7 @@ void StmtDumper::DumpDeclarator(Decl *D) { // print a free standing tag decl (e.g. "struct x;"). const char *tagname; if (const IdentifierInfo *II = TD->getIdentifier()) - tagname = II->getName(); + tagname = II->getNameStart(); else tagname = "<anonymous>"; fprintf(F, "\"%s %s;\"", TD->getKindName(), tagname); @@ -253,7 +253,7 @@ void StmtDumper::DumpDeclarator(Decl *D) { // print using-directive decl (e.g. "using namespace x;") const char *ns; if (const IdentifierInfo *II = UD->getNominatedNamespace()->getIdentifier()) - ns = II->getName(); + ns = II->getNameStart(); else ns = "<anonymous>"; fprintf(F, "\"%s %s;\"",UD->getDeclKindName(), ns); @@ -403,7 +403,7 @@ void StmtDumper::VisitMemberExpr(MemberExpr *Node) { } void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { DumpExpr(Node); - fprintf(F, " %s", Node->getAccessor().getName()); + fprintf(F, " %s", Node->getAccessor().getNameStart()); } void StmtDumper::VisitBinaryOperator(BinaryOperator *Node) { DumpExpr(Node); @@ -495,7 +495,7 @@ void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) { DumpExpr(Node); fprintf(F, " selector=%s", Node->getSelector().getAsString().c_str()); IdentifierInfo* clsName = Node->getClassName(); - if (clsName) fprintf(F, " class=%s", clsName->getName()); + if (clsName) fprintf(F, " class=%s", clsName->getNameStart()); } void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 05d0c26..2af1976 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -1289,7 +1289,7 @@ void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context, return; } - if (Policy.Dump) { + if (Policy.Dump && &Context) { dump(Context.getSourceManager()); return; } diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 0293862..5fb0178 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -37,18 +37,6 @@ void Type::Destroy(ASTContext& C) { C.Deallocate(this); } -void ConstantArrayWithExprType::Destroy(ASTContext& C) { - // FIXME: destruction of SizeExpr commented out due to resource contention. - // SizeExpr->Destroy(C); - // See FIXME in SemaDecl.cpp:1536: if we were able to either steal - // or clone the SizeExpr there, then here we could freely delete it. - // Since we do not know how to steal or clone, we keep a pointer to - // a shared resource, but we cannot free it. - // (There probably is a trivial solution ... for people knowing clang!). - this->~ConstantArrayWithExprType(); - C.Deallocate(this); -} - void VariableArrayType::Destroy(ASTContext& C) { if (SizeExpr) SizeExpr->Destroy(C); @@ -177,8 +165,6 @@ bool Type::isDerivedType() const { case Pointer: case VariableArray: case ConstantArray: - case ConstantArrayWithExpr: - case ConstantArrayWithoutExpr: case IncompleteArray: case FunctionProto: case FunctionNoProto: @@ -642,6 +628,7 @@ bool Type::isSpecifierType() const { case TypeOfExpr: case TypeOf: case TemplateTypeParm: + case SubstTemplateTypeParm: case TemplateSpecialization: case QualifiedName: case Typename: @@ -737,18 +724,6 @@ void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType(), 0, 0); } -void ObjCProtocolListType::Profile(llvm::FoldingSetNodeID &ID, - QualType OIT, ObjCProtocolDecl **protocols, - unsigned NumProtocols) { - ID.AddPointer(OIT.getAsOpaquePtr()); - for (unsigned i = 0; i != NumProtocols; i++) - ID.AddPointer(protocols[i]); -} - -void ObjCProtocolListType::Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getBaseType(), &Protocols[0], getNumProtocols()); -} - /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to /// potentially looking through *all* consequtive typedefs. This returns the /// sum of the type qualifiers, so if you have: @@ -1072,10 +1047,10 @@ void LValueReferenceType::getAsStringInternal(std::string &S, const PrintingPoli // Handle things like 'int (&A)[4];' correctly. // FIXME: this should include vectors, but vectors use attributes I guess. - if (isa<ArrayType>(getPointeeType())) + if (isa<ArrayType>(getPointeeTypeAsWritten())) S = '(' + S + ')'; - getPointeeType().getAsStringInternal(S, Policy); + getPointeeTypeAsWritten().getAsStringInternal(S, Policy); } void RValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { @@ -1083,10 +1058,10 @@ void RValueReferenceType::getAsStringInternal(std::string &S, const PrintingPoli // Handle things like 'int (&&A)[4];' correctly. // FIXME: this should include vectors, but vectors use attributes I guess. - if (isa<ArrayType>(getPointeeType())) + if (isa<ArrayType>(getPointeeTypeAsWritten())) S = '(' + S + ')'; - getPointeeType().getAsStringInternal(S, Policy); + getPointeeTypeAsWritten().getAsStringInternal(S, Policy); } void MemberPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { @@ -1111,29 +1086,6 @@ void ConstantArrayType::getAsStringInternal(std::string &S, const PrintingPolicy getElementType().getAsStringInternal(S, Policy); } -void ConstantArrayWithExprType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { - if (Policy.ConstantArraySizeAsWritten) { - std::string SStr; - llvm::raw_string_ostream s(SStr); - getSizeExpr()->printPretty(s, 0, Policy); - S += '['; - S += s.str(); - S += ']'; - getElementType().getAsStringInternal(S, Policy); - } - else - ConstantArrayType::getAsStringInternal(S, Policy); -} - -void ConstantArrayWithoutExprType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { - if (Policy.ConstantArraySizeAsWritten) { - S += "[]"; - getElementType().getAsStringInternal(S, Policy); - } - else - ConstantArrayType::getAsStringInternal(S, Policy); -} - void IncompleteArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { S += "[]"; @@ -1290,7 +1242,7 @@ void FunctionProtoType::getAsStringInternal(std::string &S, const PrintingPolicy void TypedefType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. InnerString = ' ' + InnerString; - InnerString = getDecl()->getIdentifier()->getName() + InnerString; + InnerString = getDecl()->getIdentifier()->getName().str() + InnerString; } void TemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { @@ -1301,7 +1253,11 @@ void TemplateTypeParmType::getAsStringInternal(std::string &InnerString, const P InnerString = "type-parameter-" + llvm::utostr_32(Depth) + '-' + llvm::utostr_32(Index) + InnerString; else - InnerString = Name->getName() + InnerString; + InnerString = Name->getName().str() + InnerString; +} + +void SubstTemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { + getReplacementType().getAsStringInternal(InnerString, Policy); } std::string @@ -1495,25 +1451,6 @@ void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString, InnerString = ObjCQIString + InnerString; } -void ObjCProtocolListType::getAsStringInternal(std::string &InnerString, - const PrintingPolicy &Policy) const { - if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. - InnerString = ' ' + InnerString; - - std::string ObjCQIString = getBaseType().getAsString(Policy); - ObjCQIString += '<'; - bool isFirst = true; - for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) { - if (isFirst) - isFirst = false; - else - ObjCQIString += ','; - ObjCQIString += (*I)->getNameAsString(); - } - ObjCQIString += '>'; - InnerString = ObjCQIString + InnerString; -} - void ElaboratedType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { std::string TypeStr; @@ -1534,11 +1471,11 @@ void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy const char *Kind = Policy.SuppressTagKind? 0 : getDecl()->getKindName(); const char *ID; if (const IdentifierInfo *II = getDecl()->getIdentifier()) - ID = II->getName(); + ID = II->getNameStart(); else if (TypedefDecl *Typedef = getDecl()->getTypedefForAnonDecl()) { Kind = 0; assert(Typedef->getIdentifier() && "Typedef without identifier?"); - ID = Typedef->getIdentifier()->getName(); + ID = Typedef->getIdentifier()->getNameStart(); } else ID = "<anonymous>"; @@ -1573,7 +1510,7 @@ void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(), Policy); - MyPart = Spec->getIdentifier()->getName() + TemplateArgsStr; + MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr; } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl()) MyPart = Typedef->getIdentifier()->getName(); diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index 04e7083..50a5120 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -20,55 +20,32 @@ using namespace clang; //===----------------------------------------------------------------------===// namespace { - -/// \brief Return the source range for the visited TypeSpecLoc. -class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> { -public: -#define ABSTRACT_TYPELOC(CLASS) + class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> { + public: +#define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ - SourceRange Visit##CLASS(CLASS TyLoc) { return TyLoc.getSourceRange(); } + SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + return TyLoc.getSourceRange(); \ + } #include "clang/AST/TypeLocNodes.def" - - SourceRange VisitTypeLoc(TypeLoc TyLoc) { - assert(0 && "A typeloc wrapper was not handled!"); - return SourceRange(); - } -}; - -} - -SourceRange TypeLoc::getSourceRange() const { - if (isNull()) - return SourceRange(); - return TypeLocRanger().Visit(*this); + }; } -/// \brief Find the TypeSpecLoc that is part of this TypeLoc. -TypeSpecLoc TypeLoc::getTypeSpecLoc() const { - if (isNull()) - return TypeSpecLoc(); - UnqualTypeLoc Cur = getUnqualifiedLoc(); - if (const DeclaratorLoc *DL = dyn_cast<DeclaratorLoc>(&Cur)) - return DL->getTypeSpecLoc(); - return cast<TypeSpecLoc>(Cur); +SourceRange TypeLoc::getSourceRangeImpl(TypeLoc TL) { + if (TL.isNull()) return SourceRange(); + return TypeLocRanger().Visit(TL); } namespace { - -/// \brief Report the full source info data size for the visited TypeLoc. -class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> { -public: -#define ABSTRACT_TYPELOC(CLASS) + class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> { + public: +#define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ - unsigned Visit##CLASS(CLASS TyLoc) { return TyLoc.getFullDataSize(); } + unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + return TyLoc.getFullDataSize(); \ + } #include "clang/AST/TypeLocNodes.def" - - unsigned VisitTypeLoc(TypeLoc TyLoc) { - assert(0 && "A type loc wrapper was not handled!"); - return 0; - } -}; - + }; } /// \brief Returns the size of the type source info data block. @@ -78,138 +55,42 @@ unsigned TypeLoc::getFullDataSizeForType(QualType Ty) { } namespace { - -/// \brief Return the "next" TypeLoc for the visited TypeLoc, e.g for "int*" the -/// TypeLoc is a PointerLoc and next TypeLoc is for "int". -class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> { -public: -#define TYPELOC(CLASS, PARENT) -#define DECLARATOR_TYPELOC(CLASS, TYPE) \ - TypeLoc Visit##CLASS(CLASS TyLoc); + class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> { + public: +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ + TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + return TyLoc.getNextTypeLoc(); \ + } #include "clang/AST/TypeLocNodes.def" - - TypeLoc VisitTypeSpecLoc(TypeLoc TyLoc) { return TypeLoc(); } - TypeLoc VisitObjCProtocolListLoc(ObjCProtocolListLoc TL); - TypeLoc VisitQualifiedLoc(QualifiedLoc TyLoc) { - return TyLoc.getUnqualifiedLoc(); - } - - TypeLoc VisitTypeLoc(TypeLoc TyLoc) { - assert(0 && "A declarator loc wrapper was not handled!"); - return TypeLoc(); - } -}; - -} - -TypeLoc NextLoc::VisitObjCProtocolListLoc(ObjCProtocolListLoc TL) { - return TL.getBaseTypeLoc(); -} - -TypeLoc NextLoc::VisitPointerLoc(PointerLoc TL) { - return TL.getPointeeLoc(); -} -TypeLoc NextLoc::VisitMemberPointerLoc(MemberPointerLoc TL) { - return TL.getPointeeLoc(); -} -TypeLoc NextLoc::VisitBlockPointerLoc(BlockPointerLoc TL) { - return TL.getPointeeLoc(); -} -TypeLoc NextLoc::VisitReferenceLoc(ReferenceLoc TL) { - return TL.getPointeeLoc(); -} -TypeLoc NextLoc::VisitFunctionLoc(FunctionLoc TL) { - return TL.getResultLoc(); -} -TypeLoc NextLoc::VisitArrayLoc(ArrayLoc TL) { - return TL.getElementLoc(); + }; } /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the /// TypeLoc is a PointerLoc and next TypeLoc is for "int". -TypeLoc TypeLoc::getNextTypeLoc() const { - //llvm::errs() << "getNextTypeLoc: Ty=" << Ty << ", Data=" << Data << "\n"; - TypeLoc Tmp = NextLoc().Visit(*this); - //llvm::errs() << " result: Ty=" << Tmp.Ty << ", Data=" << Tmp.Data << "\n"; - return Tmp; +TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) { + return NextLoc().Visit(TL); } -//===----------------------------------------------------------------------===// -// TypeSpecLoc Implementation -//===----------------------------------------------------------------------===// - namespace { -class TypeSpecChecker : public TypeLocVisitor<TypeSpecChecker, bool> { -public: - bool VisitTypeSpecLoc(TypeSpecLoc TyLoc) { return true; } -}; - -} - -bool TypeSpecLoc::classof(const UnqualTypeLoc *TL) { - return TypeSpecChecker().Visit(*TL); -} - -//===----------------------------------------------------------------------===// -// DeclaratorLoc Implementation -//===----------------------------------------------------------------------===// - -namespace { - -/// \brief Return the TypeSpecLoc for the visited DeclaratorLoc. -class TypeSpecGetter : public TypeLocVisitor<TypeSpecGetter, TypeSpecLoc> { -public: -#define TYPELOC(CLASS, PARENT) -#define DECLARATOR_TYPELOC(CLASS, TYPE) \ - TypeSpecLoc Visit##CLASS(CLASS TyLoc) { return TyLoc.getTypeSpecLoc(); } + struct TypeLocInitializer : public TypeLocVisitor<TypeLocInitializer> { + SourceLocation Loc; + TypeLocInitializer(SourceLocation Loc) : Loc(Loc) {} + +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ + void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + TyLoc.initializeLocal(Loc); \ + } #include "clang/AST/TypeLocNodes.def" - - TypeSpecLoc VisitTypeLoc(TypeLoc TyLoc) { - assert(0 && "A declarator loc wrapper was not handled!"); - return TypeSpecLoc(); - } - - TypeSpecLoc VisitQualifiedLoc(QualifiedLoc TyLoc) { - return Visit(TyLoc.getUnqualifiedLoc()); - } -}; - -} - -/// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc. -TypeSpecLoc DeclaratorLoc::getTypeSpecLoc() const { - return TypeSpecGetter().Visit(*this); -} - -namespace { - -class DeclaratorLocChecker : public TypeLocVisitor<DeclaratorLocChecker, bool> { -public: - bool VisitDeclaratorLoc(DeclaratorLoc TyLoc) { return true; } -}; - -} - -bool DeclaratorLoc::classof(const UnqualTypeLoc *TL) { - return DeclaratorLocChecker().Visit(*TL); -} - -//===----------------------------------------------------------------------===// -// DefaultTypeSpecLoc Implementation -//===----------------------------------------------------------------------===// - -namespace { - -class DefaultTypeSpecLocChecker : - public TypeLocVisitor<DefaultTypeSpecLocChecker, bool> { -public: - bool VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { return true; } -}; - + }; } -bool DefaultTypeSpecLoc::classofType(const Type *Ty) { - return - DefaultTypeSpecLocChecker().Visit(UnqualTypeLoc(const_cast<Type*>(Ty), 0)); +/// \brief Initializes a type location, and all of its children +/// recursively, as if the entire tree had been written in the +/// given location. +void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) { + do { + TypeLocInitializer(Loc).Visit(TL); + } while ((TL = TL.getNextTypeLoc())); } - |