diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 104 | ||||
-rw-r--r-- | lib/AST/CXXInheritance.cpp | 36 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 8 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 20 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 12 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 48 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 10 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 9 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 9 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 5 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 39 | ||||
-rw-r--r-- | lib/AST/TypeLoc.cpp | 54 |
12 files changed, 287 insertions, 67 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 76ec852..c1bc709 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1200,43 +1200,58 @@ QualType ASTContext::getObjCGCQualType(QualType T, return getExtQualType(TypeNode, Quals); } -QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) { +static QualType getNoReturnCallConvType(ASTContext& Context, QualType T, + bool AddNoReturn, + CallingConv CallConv) { QualType ResultType; if (const PointerType *Pointer = T->getAs<PointerType>()) { QualType Pointee = Pointer->getPointeeType(); - ResultType = getNoReturnType(Pointee, AddNoReturn); + ResultType = getNoReturnCallConvType(Context, Pointee, AddNoReturn, + CallConv); if (ResultType == Pointee) return T; - - ResultType = getPointerType(ResultType); + + ResultType = Context.getPointerType(ResultType); } else if (const BlockPointerType *BlockPointer = T->getAs<BlockPointerType>()) { QualType Pointee = BlockPointer->getPointeeType(); - ResultType = getNoReturnType(Pointee, AddNoReturn); + ResultType = getNoReturnCallConvType(Context, Pointee, AddNoReturn, + CallConv); if (ResultType == Pointee) return T; - - ResultType = getBlockPointerType(ResultType); - } else if (const FunctionType *F = T->getAs<FunctionType>()) { - if (F->getNoReturnAttr() == AddNoReturn) + + ResultType = Context.getBlockPointerType(ResultType); + } else if (const FunctionType *F = T->getAs<FunctionType>()) { + if (F->getNoReturnAttr() == AddNoReturn && F->getCallConv() == CallConv) return T; - + if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(F)) { - ResultType = getFunctionNoProtoType(FNPT->getResultType(), AddNoReturn); + ResultType = Context.getFunctionNoProtoType(FNPT->getResultType(), + AddNoReturn, CallConv); } else { const FunctionProtoType *FPT = cast<FunctionProtoType>(F); ResultType - = getFunctionType(FPT->getResultType(), FPT->arg_type_begin(), - FPT->getNumArgs(), FPT->isVariadic(), - FPT->getTypeQuals(), - FPT->hasExceptionSpec(), FPT->hasAnyExceptionSpec(), - FPT->getNumExceptions(), FPT->exception_begin(), - AddNoReturn); + = Context.getFunctionType(FPT->getResultType(), FPT->arg_type_begin(), + FPT->getNumArgs(), FPT->isVariadic(), + FPT->getTypeQuals(), + FPT->hasExceptionSpec(), + FPT->hasAnyExceptionSpec(), + FPT->getNumExceptions(), + FPT->exception_begin(), + AddNoReturn, CallConv); } } else return T; - - return getQualifiedType(ResultType, T.getLocalQualifiers()); + + return Context.getQualifiedType(ResultType, T.getLocalQualifiers()); +} + +QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) { + return getNoReturnCallConvType(*this, T, AddNoReturn, T.getCallConv()); +} + +QualType ASTContext::getCallConvType(QualType T, CallingConv CallConv) { + return getNoReturnCallConvType(*this, T, T.getNoReturnAttr(), CallConv); } /// getComplexType - Return the uniqued reference to the type for a complex @@ -1679,9 +1694,16 @@ QualType ASTContext::getDependentSizedExtVectorType(QualType vecType, return QualType(New, 0); } +static CallingConv getCanonicalCallingConv(CallingConv CC) { + if (CC == CC_C) + return CC_Default; + return CC; +} + /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// -QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn) { +QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn, + CallingConv CallConv) { // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; @@ -1693,8 +1715,10 @@ QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn) { return QualType(FT, 0); QualType Canonical; - if (!ResultTy.isCanonical()) { - Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn); + if (!ResultTy.isCanonical() || + getCanonicalCallingConv(CallConv) != CallConv) { + Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn, + getCanonicalCallingConv(CallConv)); // Get the new insert position for the node we care about. FunctionNoProtoType *NewIP = @@ -1715,7 +1739,8 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, unsigned NumArgs, bool isVariadic, unsigned TypeQuals, bool hasExceptionSpec, bool hasAnyExceptionSpec, unsigned NumExs, - const QualType *ExArray, bool NoReturn) { + const QualType *ExArray, bool NoReturn, + CallingConv CallConv) { // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; @@ -1737,7 +1762,7 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, // If this type isn't canonical, get the canonical version of it. // The exception spec is not part of the canonical type. QualType Canonical; - if (!isCanonical) { + if (!isCanonical || getCanonicalCallingConv(CallConv) != CallConv) { llvm::SmallVector<QualType, 16> CanonicalArgs; CanonicalArgs.reserve(NumArgs); for (unsigned i = 0; i != NumArgs; ++i) @@ -1746,7 +1771,8 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, Canonical = getFunctionType(getCanonicalType(ResultTy), CanonicalArgs.data(), NumArgs, isVariadic, TypeQuals, false, - false, 0, 0, NoReturn); + false, 0, 0, NoReturn, + getCanonicalCallingConv(CallConv)); // Get the new insert position for the node we care about. FunctionProtoType *NewIP = @@ -1763,7 +1789,7 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, NumExs*sizeof(QualType), TypeAlignment); new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic, TypeQuals, hasExceptionSpec, hasAnyExceptionSpec, - ExArray, NumExs, Canonical, NoReturn); + ExArray, NumExs, Canonical, NoReturn, CallConv); Types.push_back(FTP); FunctionProtoTypes.InsertNode(FTP, InsertPos); return QualType(FTP, 0); @@ -2101,7 +2127,8 @@ QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT, // No Match; ObjCObjectPointerType *QType = new (*this, TypeAlignment) - ObjCObjectPointerType(Canonical, InterfaceT, Protocols, NumProtocols); + ObjCObjectPointerType(*this, Canonical, InterfaceT, Protocols, + NumProtocols); Types.push_back(QType); ObjCObjectPointerTypes.InsertNode(QType, InsertPos); @@ -2135,7 +2162,7 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl, } ObjCInterfaceType *QType = new (*this, TypeAlignment) - ObjCInterfaceType(Canonical, const_cast<ObjCInterfaceDecl*>(Decl), + ObjCInterfaceType(*this, Canonical, const_cast<ObjCInterfaceDecl*>(Decl), Protocols, NumProtocols); Types.push_back(QType); @@ -3733,8 +3760,8 @@ void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) { /// \brief Retrieve the template name that corresponds to a non-empty /// lookup. -TemplateName ASTContext::getOverloadedTemplateName(NamedDecl * const *Begin, - NamedDecl * const *End) { +TemplateName ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin, + UnresolvedSetIterator End) { unsigned size = End - Begin; assert(size > 1 && "set is not overloaded!"); @@ -3743,7 +3770,7 @@ TemplateName ASTContext::getOverloadedTemplateName(NamedDecl * const *Begin, OverloadedTemplateStorage *OT = new(memory) OverloadedTemplateStorage(size); NamedDecl **Storage = OT->getStorage(); - for (NamedDecl * const *I = Begin; I != End; ++I) { + for (UnresolvedSetIterator I = Begin; I != End; ++I) { NamedDecl *D = *I; assert(isa<FunctionTemplateDecl>(D) || (isa<UsingShadowDecl>(D) && @@ -4211,6 +4238,10 @@ bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS) { return !mergeTypes(LHS, RHS).isNull(); } +static bool isSameCallingConvention(CallingConv lcc, CallingConv rcc) { + return (getCanonicalCallingConv(lcc) == getCanonicalCallingConv(rcc)); +} + QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) { const FunctionType *lbase = lhs->getAs<FunctionType>(); const FunctionType *rbase = rhs->getAs<FunctionType>(); @@ -4232,6 +4263,11 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) { allLTypes = false; if (NoReturn != rbase->getNoReturnAttr()) allRTypes = false; + CallingConv lcc = lbase->getCallConv(); + CallingConv rcc = rbase->getCallConv(); + // Compatible functions must have compatible calling conventions + if (!isSameCallingConvention(lcc, rcc)) + return QualType(); if (lproto && rproto) { // two C99 style function prototypes assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() && @@ -4267,7 +4303,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) { if (allRTypes) return rhs; return getFunctionType(retType, types.begin(), types.size(), lproto->isVariadic(), lproto->getTypeQuals(), - NoReturn); + NoReturn, lcc); } if (lproto) allRTypes = false; @@ -4294,12 +4330,12 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) { if (allRTypes) return rhs; return getFunctionType(retType, proto->arg_type_begin(), proto->getNumArgs(), proto->isVariadic(), - proto->getTypeQuals(), NoReturn); + proto->getTypeQuals(), NoReturn, lcc); } if (allLTypes) return lhs; if (allRTypes) return rhs; - return getFunctionNoProtoType(retType, NoReturn); + return getFunctionNoProtoType(retType, NoReturn, lcc); } QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) { diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp index 92a58b7..7208328 100644 --- a/lib/AST/CXXInheritance.cpp +++ b/lib/AST/CXXInheritance.cpp @@ -145,7 +145,11 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData, CXXBasePaths &Paths) const { bool FoundPath = false; - + + // The access of the path down to this record. + AccessSpecifier AccessToHere = Paths.ScratchPath.Access; + bool IsFirstStep = Paths.ScratchPath.empty(); + ASTContext &Context = getASTContext(); for (base_class_const_iterator BaseSpec = bases_begin(), BaseSpecEnd = bases_end(); BaseSpec != BaseSpecEnd; ++BaseSpec) { @@ -189,10 +193,31 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, else Element.SubobjectNumber = Subobjects.second; Paths.ScratchPath.push_back(Element); + + // Calculate the "top-down" access to this base class. + // The spec actually describes this bottom-up, but top-down is + // equivalent because the definition works out as follows: + // 1. Write down the access along each step in the inheritance + // chain, followed by the access of the decl itself. + // For example, in + // class A { public: int foo; }; + // class B : protected A {}; + // class C : public B {}; + // class D : private C {}; + // we would write: + // private public protected public + // 2. If 'private' appears anywhere except far-left, access is denied. + // 3. Otherwise, overall access is determined by the most restrictive + // access in the sequence. + if (IsFirstStep) + Paths.ScratchPath.Access = BaseSpec->getAccessSpecifier(); + else + Paths.ScratchPath.Access + = MergeAccess(AccessToHere, BaseSpec->getAccessSpecifier()); } if (BaseMatches(BaseSpec, Paths.ScratchPath, UserData)) { - // We've found a path that terminates that this base. + // We've found a path that terminates at this base. FoundPath = true; if (Paths.isRecordingPaths()) { // We have a path. Make a copy of it before moving on. @@ -223,13 +248,18 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, // Pop this base specifier off the current path (if we're // collecting paths). - if (Paths.isRecordingPaths()) + if (Paths.isRecordingPaths()) { Paths.ScratchPath.pop_back(); + } + // If we set a virtual earlier, and this isn't a path, forget it again. if (SetVirtual && !FoundPath) { Paths.DetectedVirtual = 0; } } + + // Reset the scratch path access. + Paths.ScratchPath.Access = AccessToHere; return FoundPath; } diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index e77661a..794b14a 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -629,9 +629,13 @@ VarDecl::~VarDecl() { } SourceRange VarDecl::getSourceRange() const { + SourceLocation Start = getTypeSpecStartLoc(); + if (Start.isInvalid()) + Start = getLocation(); + if (getInit()) - return SourceRange(getLocation(), getInit()->getLocEnd()); - return SourceRange(getLocation(), getLocation()); + return SourceRange(Start, getInit()->getLocEnd()); + return SourceRange(Start, getLocation()); } bool VarDecl::isOutOfLine() const { diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 3afb4e4..84aa81c 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -102,6 +102,17 @@ bool Decl::isFunctionOrFunctionTemplate() const { return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this); } +bool Decl::isDefinedOutsideFunctionOrMethod() const { + for (const DeclContext *DC = getDeclContext(); + DC && !DC->isTranslationUnit(); + DC = DC->getParent()) + if (DC->isFunctionOrMethod()) + return false; + + return true; +} + + //===----------------------------------------------------------------------===// // PrettyStackTraceDecl Implementation //===----------------------------------------------------------------------===// @@ -399,8 +410,13 @@ SourceLocation Decl::getBodyRBrace() const { #ifndef NDEBUG void Decl::CheckAccessDeclContext() const { - // If the decl is the toplevel translation unit or if we're not in a - // record decl context, we don't need to check anything. + // Suppress this check if any of the following hold: + // 1. this is the translation unit (and thus has no parent) + // 2. this is a template parameter (and thus doesn't belong to its context) + // 3. this is a ParmVarDecl (which can be in a record context during + // the brief period between its creation and the creation of the + // FunctionDecl) + // 4. the context is not a record if (isa<TranslationUnitDecl>(this) || !isa<CXXRecordDecl>(getDeclContext())) return; diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 1cce35c..fe6064d 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -312,8 +312,9 @@ void CXXRecordDecl::collectConversionFunctions( llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const { - const UnresolvedSet *Cs = getConversionFunctions(); - for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) { + const UnresolvedSetImpl *Cs = getConversionFunctions(); + for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end(); + I != E; ++I) { NamedDecl *TopConv = *I; CanQualType TConvType; if (FunctionTemplateDecl *TConversionTemplate = @@ -344,10 +345,11 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD, bool inTopClass = (RD == this); QualType ClassType = getASTContext().getTypeDeclType(this); if (const RecordType *Record = ClassType->getAs<RecordType>()) { - const UnresolvedSet *Cs + const UnresolvedSetImpl *Cs = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions(); - for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) { + for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end(); + I != E; ++I) { NamedDecl *Conv = *I; // Only those conversions not exact match of conversions in current // class are candidateconversion routines. @@ -410,7 +412,7 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD, /// getVisibleConversionFunctions - get all conversion functions visible /// in current class; including conversion function templates. -const UnresolvedSet *CXXRecordDecl::getVisibleConversionFunctions() { +const UnresolvedSetImpl *CXXRecordDecl::getVisibleConversionFunctions() { // If root class, all conversions are visible. if (bases_begin() == bases_end()) return &Conversions; diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 2506f27..ffda505 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -37,6 +37,21 @@ void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) { memcpy(List, InList, sizeof(void*)*Elts); } +void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts, + const SourceLocation *Locs, ASTContext &Ctx) { + if (Elts == 0) + return; + + Locations = new (Ctx) SourceLocation[Elts]; + memcpy(Locations, Locs, sizeof(SourceLocation) * Elts); + set(InList, Elts, Ctx); +} + +void ObjCProtocolList::Destroy(ASTContext &Ctx) { + Ctx.Deallocate(Locations); + Locations = 0; + ObjCList<ObjCProtocolDecl>::Destroy(Ctx); +} //===----------------------------------------------------------------------===// // ObjCInterfaceDecl @@ -141,16 +156,18 @@ ObjCContainerDecl::FindPropertyVisibleInPrimaryClass( void ObjCInterfaceDecl::mergeClassExtensionProtocolList( ObjCProtocolDecl *const* ExtList, unsigned ExtNum, + const SourceLocation *Locs, ASTContext &C) { if (ReferencedProtocols.empty()) { - ReferencedProtocols.set(ExtList, ExtNum, C); + ReferencedProtocols.set(ExtList, ExtNum, Locs, C); return; } // Check for duplicate protocol in class's protocol list. // This is (O)2. But it is extremely rare and number of protocols in // class or its extension are very few. llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs; + llvm::SmallVector<SourceLocation, 8> ProtocolLocs; for (unsigned i = 0; i < ExtNum; i++) { bool protocolExists = false; ObjCProtocolDecl *ProtoInExtension = ExtList[i]; @@ -164,18 +181,23 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList( } // Do we want to warn on a protocol in extension class which // already exist in the class? Probably not. - if (!protocolExists) + if (!protocolExists) { ProtocolRefs.push_back(ProtoInExtension); + ProtocolLocs.push_back(Locs[i]); + } } if (ProtocolRefs.empty()) return; // Merge ProtocolRefs into class's protocol list; + protocol_loc_iterator pl = protocol_loc_begin(); for (protocol_iterator p = protocol_begin(), e = protocol_end(); - p != e; p++) + p != e; ++p, ++pl) { ProtocolRefs.push_back(*p); + ProtocolLocs.push_back(*pl); + } ReferencedProtocols.Destroy(C); unsigned NumProtoRefs = ProtocolRefs.size(); - setProtocolList((ObjCProtocolDecl**)&ProtocolRefs[0], NumProtoRefs, C); + setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C); } ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID, @@ -627,9 +649,9 @@ SourceRange ObjCClassDecl::getSourceRange() const { ObjCForwardProtocolDecl:: ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, ObjCProtocolDecl *const *Elts, unsigned nElts, - ASTContext &C) + const SourceLocation *Locs, ASTContext &C) : Decl(ObjCForwardProtocol, DC, L) { - ReferencedProtocols.set(Elts, nElts, C); + ReferencedProtocols.set(Elts, nElts, Locs, C); } @@ -637,8 +659,9 @@ ObjCForwardProtocolDecl * ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, ObjCProtocolDecl *const *Elts, - unsigned NumElts) { - return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C); + unsigned NumElts, + const SourceLocation *Locs) { + return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C); } void ObjCForwardProtocolDecl::Destroy(ASTContext &C) { @@ -651,9 +674,11 @@ void ObjCForwardProtocolDecl::Destroy(ASTContext &C) { //===----------------------------------------------------------------------===// ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, + SourceLocation AtLoc, + SourceLocation ClassNameLoc, + SourceLocation CategoryNameLoc, IdentifierInfo *Id) { - return new (C) ObjCCategoryDecl(DC, L, Id); + return new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id); } ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const { @@ -765,9 +790,10 @@ ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, + SourceLocation AtLoc, QualType T, PropertyControl propControl) { - return new (C) ObjCPropertyDecl(DC, L, Id, T); + return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T); } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 4c3046b..fa44b51 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -98,10 +98,12 @@ void DeclRefExpr::computeDependence() { // initialized with an expression that is value-dependent. else if (VarDecl *Var = dyn_cast<VarDecl>(D)) { if (Var->getType()->isIntegralType() && - Var->getType().getCVRQualifiers() == Qualifiers::Const && - Var->getInit() && - Var->getInit()->isValueDependent()) - ValueDependent = true; + Var->getType().getCVRQualifiers() == Qualifiers::Const) { + const VarDecl *Def = 0; + if (const Expr *Init = Var->getDefinition(Def)) + if (Init->isValueDependent()) + ValueDependent = true; + } } // (TD) - a nested-name-specifier or a qualified-id that names a // member of an unknown specialization. diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 81584b7..a6574ef 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -135,10 +135,11 @@ UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent, return ULE; } -bool UnresolvedLookupExpr::ComputeDependence(NamedDecl * const *Begin, - NamedDecl * const *End, - const TemplateArgumentListInfo *Args) { - for (NamedDecl * const *I = Begin; I != End; ++I) +bool UnresolvedLookupExpr:: + ComputeDependence(UnresolvedSetImpl::const_iterator Begin, + UnresolvedSetImpl::const_iterator End, + const TemplateArgumentListInfo *Args) { + for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) if ((*I)->getDeclContext()->isDependentContext()) return true; diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index dfff209..086249c 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -506,7 +506,9 @@ APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) { APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) { if (E->isBuiltinCall(Info.Ctx) == - Builtin::BI__builtin___CFStringMakeConstantString) + Builtin::BI__builtin___CFStringMakeConstantString || + E->isBuiltinCall(Info.Ctx) == + Builtin::BI__builtin___NSStringMakeConstantString) return APValue(E); return APValue(); } @@ -971,6 +973,8 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { case Builtin::BI__builtin_object_size: { const Expr *Arg = E->getArg(0)->IgnoreParens(); Expr::EvalResult Base; + + // TODO: Perhaps we should let LLVM lower this? if (Arg->EvaluateAsAny(Base, Info.Ctx) && Base.Val.getKind() == APValue::LValue && !Base.HasSideEffects) @@ -992,7 +996,8 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { } } - // TODO: Perhaps we should let LLVM lower this? + // If evaluating the argument has side-effects we can't determine + // the size of the object and lower it to unknown now. if (E->getArg(0)->HasSideEffects(Info.Ctx)) { if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() <= 1) return Success(-1ULL, E); diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index cfd89ea..0aa0180 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -119,6 +119,11 @@ ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD, return; } } + if (i->isVirtual()) { + SelectPrimaryVBase(Base, FirstPrimary); + if (PrimaryBase.getBase()) + return; + } } } diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index e0055f1..edfb580 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -339,6 +339,25 @@ const RecordType *Type::getAsUnionType() const { return 0; } +ObjCInterfaceType::ObjCInterfaceType(ASTContext &Ctx, QualType Canonical, + ObjCInterfaceDecl *D, + ObjCProtocolDecl **Protos, unsigned NumP) : + Type(ObjCInterface, Canonical, /*Dependent=*/false), + Decl(D), Protocols(0), NumProtocols(NumP) +{ + if (NumProtocols) { + Protocols = new (Ctx) ObjCProtocolDecl*[NumProtocols]; + memcpy(Protocols, Protos, NumProtocols * sizeof(*Protocols)); + } +} + +void ObjCInterfaceType::Destroy(ASTContext& C) { + if (Protocols) + C.Deallocate(Protocols); + this->~ObjCInterfaceType(); + C.Deallocate(this); +} + const ObjCInterfaceType *Type::getAsObjCQualifiedInterfaceType() const { // There is no sugar for ObjCInterfaceType's, just return the canonical // type pointer if it is the right class. There is no typedef information to @@ -353,6 +372,26 @@ bool Type::isObjCQualifiedInterfaceType() const { return getAsObjCQualifiedInterfaceType() != 0; } +ObjCObjectPointerType::ObjCObjectPointerType(ASTContext &Ctx, + QualType Canonical, QualType T, + ObjCProtocolDecl **Protos, + unsigned NumP) : + Type(ObjCObjectPointer, Canonical, /*Dependent=*/false), + PointeeType(T), Protocols(NULL), NumProtocols(NumP) +{ + if (NumProtocols) { + Protocols = new (Ctx) ObjCProtocolDecl*[NumProtocols]; + memcpy(Protocols, Protos, NumProtocols * sizeof(*Protocols)); + } +} + +void ObjCObjectPointerType::Destroy(ASTContext& C) { + if (Protocols) + C.Deallocate(Protocols); + this->~ObjCObjectPointerType(); + C.Deallocate(this); +} + const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const { // There is no sugar for ObjCQualifiedIdType's, just return the canonical // type pointer if it is the right class. diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index 0840c52..fd9fbc1 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -14,6 +14,7 @@ #include "llvm/Support/raw_ostream.h" #include "clang/AST/TypeLocVisitor.h" #include "clang/AST/Expr.h" +#include "llvm/Support/ErrorHandling.h" using namespace clang; //===----------------------------------------------------------------------===// @@ -135,3 +136,56 @@ SourceRange TypeOfExprTypeLoc::getSourceRange() const { return SourceRange(getTypeofLoc(), getUnderlyingExpr()->getSourceRange().getEnd()); } + + +TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { + if (needsExtraLocalData()) + return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type); + else { + switch (getTypePtr()->getKind()) { + case BuiltinType::Void: + return TST_void; + case BuiltinType::Bool: + return TST_bool; + case BuiltinType::Char_U: + case BuiltinType::Char_S: + return TST_char; + case BuiltinType::Char16: + return TST_char16; + case BuiltinType::Char32: + return TST_char32; + case BuiltinType::WChar: + return TST_wchar; + case BuiltinType::UndeducedAuto: + return TST_auto; + + case BuiltinType::UChar: + case BuiltinType::UShort: + case BuiltinType::UInt: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + case BuiltinType::UInt128: + case BuiltinType::SChar: + case BuiltinType::Short: + case BuiltinType::Int: + case BuiltinType::Long: + case BuiltinType::LongLong: + case BuiltinType::Int128: + case BuiltinType::Float: + case BuiltinType::Double: + case BuiltinType::LongDouble: + llvm_unreachable("Builtin type needs extra local data!"); + // Fall through, if the impossible happens. + + case BuiltinType::NullPtr: + case BuiltinType::Overload: + case BuiltinType::Dependent: + case BuiltinType::ObjCId: + case BuiltinType::ObjCClass: + case BuiltinType::ObjCSel: + return TST_unspecified; + } + } + + return TST_unspecified; +} |