diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 | 
| commit | 73490b890977362d28dd6326843a1ecae413921d (patch) | |
| tree | 3fdd91eae574e32453a4baf462961c742df2691a /lib/AST | |
| parent | a5f348eb914e67b51914117fac117c18c1f8d650 (diff) | |
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 e028186d46e5..7f5fa35842af 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 4a46eab2e603..b59b45f6467e 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 da7959b16f9f..d270a958f0ae 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 7836b3f827ce..9a1c65416f71 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 101ddd250933..56a597570dd0 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 0e4a29f916fa..a4de3e5b0f7a 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 3a838fadafa4..6e0da4714912 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 0465999a94cc..cf71d6b986a2 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 05d0c2683545..2af19765dfaa 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 0293862baedb..5fb0178834ff 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 04e708370af3..50a512028e96 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()));  } -   | 
