diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ASTContext.cpp | 5 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/Decl.cpp | 117 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/Expr.cpp | 335 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp | 56 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp | 5 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp | 23 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/Stmt.cpp | 6 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp | 17 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp | 6 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/Type.cpp | 10 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp | 9 |
11 files changed, 170 insertions, 419 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp index acf5e0b..cb4d336 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp @@ -481,7 +481,8 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); // Builtin type for __objc_yes and __objc_no - ObjCBuiltinBoolTy = SignedCharTy; + ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ? + SignedCharTy : BoolTy); ObjCConstantStringType = QualType(); @@ -2193,6 +2194,8 @@ ASTContext::getFunctionType(QualType ResultTy, Size += EPI.NumExceptions * sizeof(QualType); else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { Size += sizeof(Expr*); + } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { + Size += 2 * sizeof(FunctionDecl*); } if (EPI.ConsumedArguments) Size += NumArgs * sizeof(bool); diff --git a/contrib/llvm/tools/clang/lib/AST/Decl.cpp b/contrib/llvm/tools/clang/lib/AST/Decl.cpp index 399f2e4..53032bc 100644 --- a/contrib/llvm/tools/clang/lib/AST/Decl.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Decl.cpp @@ -69,33 +69,25 @@ typedef NamedDecl::LinkageInfo LinkageInfo; namespace { /// Flags controlling the computation of linkage and visibility. struct LVFlags { - bool ConsiderGlobalVisibility; - bool ConsiderVisibilityAttributes; - bool ConsiderTemplateParameterTypes; + const bool ConsiderGlobalVisibility; + const bool ConsiderVisibilityAttributes; + const bool ConsiderTemplateParameterTypes; LVFlags() : ConsiderGlobalVisibility(true), ConsiderVisibilityAttributes(true), ConsiderTemplateParameterTypes(true) { } + LVFlags(bool Global, bool Attributes, bool Parameters) : + ConsiderGlobalVisibility(Global), + ConsiderVisibilityAttributes(Attributes), + ConsiderTemplateParameterTypes(Parameters) { + } + /// \brief Returns a set of flags that is only useful for computing the /// linkage, not the visibility, of a declaration. static LVFlags CreateOnlyDeclLinkage() { - LVFlags F; - F.ConsiderGlobalVisibility = false; - F.ConsiderVisibilityAttributes = false; - F.ConsiderTemplateParameterTypes = false; - return F; - } - - /// Returns a set of flags, otherwise based on these, which ignores - /// off all sources of visibility except template arguments. - LVFlags onlyTemplateVisibility() const { - LVFlags F = *this; - F.ConsiderGlobalVisibility = false; - F.ConsiderVisibilityAttributes = false; - F.ConsiderTemplateParameterTypes = false; - return F; + return LVFlags(false, false, false); } }; } // end anonymous namespace @@ -284,7 +276,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { if (F.ConsiderVisibilityAttributes) { if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) { LV.setVisibility(*Vis, true); - F.ConsiderGlobalVisibility = false; } else { // If we're declared in a namespace with a visibility attribute, // use that namespace's visibility, but don't call it explicit. @@ -295,7 +286,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { if (!ND) continue; if (llvm::Optional<Visibility> Vis = ND->getExplicitVisibility()) { LV.setVisibility(*Vis, true); - F.ConsiderGlobalVisibility = false; break; } } @@ -335,8 +325,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { LinkageInfo TypeLV = getLVForType(Var->getType()); if (TypeLV.linkage() != ExternalLinkage) return LinkageInfo::uniqueExternal(); - LV.mergeVisibilityWithMin(TypeLV.visibility(), - TypeLV.visibilityExplicit()); + LV.mergeVisibilityWithMin(TypeLV); } if (Var->getStorageClass() == SC_PrivateExtern) @@ -412,7 +401,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { = Function->getTemplateSpecializationInfo()) { if (shouldConsiderTemplateLV(Function, specInfo)) { LV.merge(getLVForDecl(specInfo->getTemplate(), - F.onlyTemplateVisibility())); + LVFlags::CreateOnlyDeclLinkage())); const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments; LV.mergeWithMin(getLVForTemplateArgumentList(templateArgs, F)); } @@ -436,7 +425,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { if (shouldConsiderTemplateLV(spec)) { // From the template. LV.merge(getLVForDecl(spec->getSpecializedTemplate(), - F.onlyTemplateVisibility())); + LVFlags::CreateOnlyDeclLinkage())); // The arguments at which the template was instantiated. const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs(); @@ -444,12 +433,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { } } - // Consider -fvisibility unless the type has C linkage. - if (F.ConsiderGlobalVisibility) - F.ConsiderGlobalVisibility = - (Context.getLangOpts().CPlusPlus && - !Tag->getDeclContext()->isExternCContext()); - // - an enumerator belonging to an enumeration with external linkage; } else if (isa<EnumConstantDecl>(D)) { LinkageInfo EnumLV = getLVForDecl(cast<NamedDecl>(D->getDeclContext()), F); @@ -501,21 +484,46 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { LinkageInfo LV; LV.mergeVisibility(D->getASTContext().getLangOpts().getVisibilityMode()); - // The flags we're going to use to compute the class's visibility. - LVFlags ClassF = F; - + bool DHasExplicitVisibility = false; // If we have an explicit visibility attribute, merge that in. if (F.ConsiderVisibilityAttributes) { if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) { LV.mergeVisibility(*Vis, true); - // Ignore global visibility later, but not this attribute. - F.ConsiderGlobalVisibility = false; + DHasExplicitVisibility = true; + } + } + // Ignore both global visibility and attributes when computing our + // parent's visibility if we already have an explicit one. + LVFlags ClassF = DHasExplicitVisibility ? + LVFlags::CreateOnlyDeclLinkage() : F; - // Ignore both global visibility and attributes when computing our - // parent's visibility. - ClassF = F.onlyTemplateVisibility(); + // If we're paying attention to global visibility, apply + // -finline-visibility-hidden if this is an inline method. + // + // Note that we do this before merging information about + // the class visibility. + if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { + TemplateSpecializationKind TSK = TSK_Undeclared; + if (FunctionTemplateSpecializationInfo *spec + = MD->getTemplateSpecializationInfo()) { + TSK = spec->getTemplateSpecializationKind(); + } else if (MemberSpecializationInfo *MSI = + MD->getMemberSpecializationInfo()) { + TSK = MSI->getTemplateSpecializationKind(); } + + const FunctionDecl *Def = 0; + // InlineVisibilityHidden only applies to definitions, and + // isInlined() only gives meaningful answers on definitions + // anyway. + if (TSK != TSK_ExplicitInstantiationDeclaration && + TSK != TSK_ExplicitInstantiationDefinition && + F.ConsiderGlobalVisibility && + !LV.visibilityExplicit() && + MD->getASTContext().getLangOpts().InlineVisibilityHidden && + MD->hasBody(Def) && Def->isInlined()) + LV.mergeVisibility(HiddenVisibility, true); } // Class members only have linkage if their class has external @@ -534,8 +542,6 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { if (MD->getType()->getLinkage() == UniqueExternalLinkage) return LinkageInfo::uniqueExternal(); - TemplateSpecializationKind TSK = TSK_Undeclared; - // If this is a method template specialization, use the linkage for // the template parameters and arguments. if (FunctionTemplateSpecializationInfo *spec @@ -547,29 +553,6 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { LV.merge(getLVForTemplateParameterList( spec->getTemplate()->getTemplateParameters())); } - - TSK = spec->getTemplateSpecializationKind(); - } else if (MemberSpecializationInfo *MSI = - MD->getMemberSpecializationInfo()) { - TSK = MSI->getTemplateSpecializationKind(); - } - - // If we're paying attention to global visibility, apply - // -finline-visibility-hidden if this is an inline method. - // - // Note that ConsiderGlobalVisibility doesn't yet have information - // about whether containing classes have visibility attributes, - // and that's intentional. - if (TSK != TSK_ExplicitInstantiationDeclaration && - TSK != TSK_ExplicitInstantiationDefinition && - F.ConsiderGlobalVisibility && - MD->getASTContext().getLangOpts().InlineVisibilityHidden) { - // InlineVisibilityHidden only applies to definitions, and - // isInlined() only gives meaningful answers on definitions - // anyway. - const FunctionDecl *Def = 0; - if (MD->hasBody(Def) && Def->isInlined()) - LV.setVisibility(HiddenVisibility); } // Note that in contrast to basically every other situation, we @@ -597,7 +580,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { if (TypeLV.linkage() != ExternalLinkage) LV.mergeLinkage(UniqueExternalLinkage); if (!LV.visibilityExplicit()) - LV.mergeVisibility(TypeLV.visibility(), TypeLV.visibilityExplicit()); + LV.mergeVisibility(TypeLV); } return LV; @@ -802,7 +785,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) { LinkageInfo LV; if (Flags.ConsiderVisibilityAttributes) { if (llvm::Optional<Visibility> Vis = Function->getExplicitVisibility()) - LV.setVisibility(*Vis); + LV.setVisibility(*Vis, true); } if (const FunctionDecl *Prev = Function->getPreviousDecl()) { @@ -823,10 +806,10 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) { LinkageInfo LV; if (Var->getStorageClass() == SC_PrivateExtern) - LV.setVisibility(HiddenVisibility); + LV.setVisibility(HiddenVisibility, true); else if (Flags.ConsiderVisibilityAttributes) { if (llvm::Optional<Visibility> Vis = Var->getExplicitVisibility()) - LV.setVisibility(*Vis); + LV.setVisibility(*Vis, true); } if (const VarDecl *Prev = Var->getPreviousDecl()) { diff --git a/contrib/llvm/tools/clang/lib/AST/Expr.cpp b/contrib/llvm/tools/clang/lib/AST/Expr.cpp index 868109e..fcde542 100644 --- a/contrib/llvm/tools/clang/lib/AST/Expr.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Expr.cpp @@ -1590,6 +1590,16 @@ void InitListExpr::setArrayFiller(Expr *filler) { inits[i] = filler; } +bool InitListExpr::isStringLiteralInit() const { + if (getNumInits() != 1) + return false; + const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(getType()); + if (!CAT || !CAT->getElementType()->isIntegerType()) + return false; + const Expr *Init = getInit(0)->IgnoreParenImpCasts(); + return isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init); +} + SourceRange InitListExpr::getSourceRange() const { if (SyntacticForm) return SyntacticForm->getSourceRange(); @@ -1986,331 +1996,6 @@ QualType Expr::findBoundMemberType(const Expr *expr) { return QualType(); } -static Expr::CanThrowResult MergeCanThrow(Expr::CanThrowResult CT1, - Expr::CanThrowResult CT2) { - // CanThrowResult constants are ordered so that the maximum is the correct - // merge result. - return CT1 > CT2 ? CT1 : CT2; -} - -static Expr::CanThrowResult CanSubExprsThrow(ASTContext &C, const Expr *CE) { - Expr *E = const_cast<Expr*>(CE); - Expr::CanThrowResult R = Expr::CT_Cannot; - for (Expr::child_range I = E->children(); I && R != Expr::CT_Can; ++I) { - R = MergeCanThrow(R, cast<Expr>(*I)->CanThrow(C)); - } - return R; -} - -static Expr::CanThrowResult CanCalleeThrow(ASTContext &Ctx, const Expr *E, - const Decl *D, - bool NullThrows = true) { - if (!D) - return NullThrows ? Expr::CT_Can : Expr::CT_Cannot; - - // See if we can get a function type from the decl somehow. - const ValueDecl *VD = dyn_cast<ValueDecl>(D); - if (!VD) // If we have no clue what we're calling, assume the worst. - return Expr::CT_Can; - - // As an extension, we assume that __attribute__((nothrow)) functions don't - // throw. - if (isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>()) - return Expr::CT_Cannot; - - QualType T = VD->getType(); - const FunctionProtoType *FT; - if ((FT = T->getAs<FunctionProtoType>())) { - } else if (const PointerType *PT = T->getAs<PointerType>()) - FT = PT->getPointeeType()->getAs<FunctionProtoType>(); - else if (const ReferenceType *RT = T->getAs<ReferenceType>()) - FT = RT->getPointeeType()->getAs<FunctionProtoType>(); - else if (const MemberPointerType *MT = T->getAs<MemberPointerType>()) - FT = MT->getPointeeType()->getAs<FunctionProtoType>(); - else if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) - FT = BT->getPointeeType()->getAs<FunctionProtoType>(); - - if (!FT) - return Expr::CT_Can; - - if (FT->getExceptionSpecType() == EST_Delayed) { - assert(isa<CXXConstructorDecl>(D) && - "only constructor exception specs can be unknown"); - Ctx.getDiagnostics().Report(E->getLocStart(), - diag::err_exception_spec_unknown) - << E->getSourceRange(); - return Expr::CT_Can; - } - - return FT->isNothrow(Ctx) ? Expr::CT_Cannot : Expr::CT_Can; -} - -static Expr::CanThrowResult CanDynamicCastThrow(const CXXDynamicCastExpr *DC) { - if (DC->isTypeDependent()) - return Expr::CT_Dependent; - - if (!DC->getTypeAsWritten()->isReferenceType()) - return Expr::CT_Cannot; - - if (DC->getSubExpr()->isTypeDependent()) - return Expr::CT_Dependent; - - return DC->getCastKind() == clang::CK_Dynamic? Expr::CT_Can : Expr::CT_Cannot; -} - -static Expr::CanThrowResult CanTypeidThrow(ASTContext &C, - const CXXTypeidExpr *DC) { - if (DC->isTypeOperand()) - return Expr::CT_Cannot; - - Expr *Op = DC->getExprOperand(); - if (Op->isTypeDependent()) - return Expr::CT_Dependent; - - const RecordType *RT = Op->getType()->getAs<RecordType>(); - if (!RT) - return Expr::CT_Cannot; - - if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic()) - return Expr::CT_Cannot; - - if (Op->Classify(C).isPRValue()) - return Expr::CT_Cannot; - - return Expr::CT_Can; -} - -Expr::CanThrowResult Expr::CanThrow(ASTContext &C) const { - // C++ [expr.unary.noexcept]p3: - // [Can throw] if in a potentially-evaluated context the expression would - // contain: - switch (getStmtClass()) { - case CXXThrowExprClass: - // - a potentially evaluated throw-expression - return CT_Can; - - case CXXDynamicCastExprClass: { - // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), - // where T is a reference type, that requires a run-time check - CanThrowResult CT = CanDynamicCastThrow(cast<CXXDynamicCastExpr>(this)); - if (CT == CT_Can) - return CT; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - case CXXTypeidExprClass: - // - a potentially evaluated typeid expression applied to a glvalue - // expression whose type is a polymorphic class type - return CanTypeidThrow(C, cast<CXXTypeidExpr>(this)); - - // - a potentially evaluated call to a function, member function, function - // pointer, or member function pointer that does not have a non-throwing - // exception-specification - case CallExprClass: - case CXXMemberCallExprClass: - case CXXOperatorCallExprClass: - case UserDefinedLiteralClass: { - const CallExpr *CE = cast<CallExpr>(this); - CanThrowResult CT; - if (isTypeDependent()) - CT = CT_Dependent; - else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) - CT = CT_Cannot; - else - CT = CanCalleeThrow(C, this, CE->getCalleeDecl()); - if (CT == CT_Can) - return CT; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - case CXXConstructExprClass: - case CXXTemporaryObjectExprClass: { - CanThrowResult CT = CanCalleeThrow(C, this, - cast<CXXConstructExpr>(this)->getConstructor()); - if (CT == CT_Can) - return CT; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - case LambdaExprClass: { - const LambdaExpr *Lambda = cast<LambdaExpr>(this); - CanThrowResult CT = Expr::CT_Cannot; - for (LambdaExpr::capture_init_iterator Cap = Lambda->capture_init_begin(), - CapEnd = Lambda->capture_init_end(); - Cap != CapEnd; ++Cap) - CT = MergeCanThrow(CT, (*Cap)->CanThrow(C)); - return CT; - } - - case CXXNewExprClass: { - CanThrowResult CT; - if (isTypeDependent()) - CT = CT_Dependent; - else - CT = CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew()); - if (CT == CT_Can) - return CT; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - case CXXDeleteExprClass: { - CanThrowResult CT; - QualType DTy = cast<CXXDeleteExpr>(this)->getDestroyedType(); - if (DTy.isNull() || DTy->isDependentType()) { - CT = CT_Dependent; - } else { - CT = CanCalleeThrow(C, this, - cast<CXXDeleteExpr>(this)->getOperatorDelete()); - if (const RecordType *RT = DTy->getAs<RecordType>()) { - const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - CT = MergeCanThrow(CT, CanCalleeThrow(C, this, RD->getDestructor())); - } - if (CT == CT_Can) - return CT; - } - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - case CXXBindTemporaryExprClass: { - // The bound temporary has to be destroyed again, which might throw. - CanThrowResult CT = CanCalleeThrow(C, this, - cast<CXXBindTemporaryExpr>(this)->getTemporary()->getDestructor()); - if (CT == CT_Can) - return CT; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - // ObjC message sends are like function calls, but never have exception - // specs. - case ObjCMessageExprClass: - case ObjCPropertyRefExprClass: - case ObjCSubscriptRefExprClass: - return CT_Can; - - // All the ObjC literals that are implemented as calls are - // potentially throwing unless we decide to close off that - // possibility. - case ObjCArrayLiteralClass: - case ObjCDictionaryLiteralClass: - case ObjCNumericLiteralClass: - return CT_Can; - - // Many other things have subexpressions, so we have to test those. - // Some are simple: - case ConditionalOperatorClass: - case CompoundLiteralExprClass: - case CXXConstCastExprClass: - case CXXDefaultArgExprClass: - case CXXReinterpretCastExprClass: - case DesignatedInitExprClass: - case ExprWithCleanupsClass: - case ExtVectorElementExprClass: - case InitListExprClass: - case MemberExprClass: - case ObjCIsaExprClass: - case ObjCIvarRefExprClass: - case ParenExprClass: - case ParenListExprClass: - case ShuffleVectorExprClass: - case VAArgExprClass: - return CanSubExprsThrow(C, this); - - // Some might be dependent for other reasons. - case ArraySubscriptExprClass: - case BinaryOperatorClass: - case CompoundAssignOperatorClass: - case CStyleCastExprClass: - case CXXStaticCastExprClass: - case CXXFunctionalCastExprClass: - case ImplicitCastExprClass: - case MaterializeTemporaryExprClass: - case UnaryOperatorClass: { - CanThrowResult CT = isTypeDependent() ? CT_Dependent : CT_Cannot; - return MergeCanThrow(CT, CanSubExprsThrow(C, this)); - } - - // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms. - case StmtExprClass: - return CT_Can; - - case ChooseExprClass: - if (isTypeDependent() || isValueDependent()) - return CT_Dependent; - return cast<ChooseExpr>(this)->getChosenSubExpr(C)->CanThrow(C); - - case GenericSelectionExprClass: - if (cast<GenericSelectionExpr>(this)->isResultDependent()) - return CT_Dependent; - return cast<GenericSelectionExpr>(this)->getResultExpr()->CanThrow(C); - - // Some expressions are always dependent. - case CXXDependentScopeMemberExprClass: - case CXXUnresolvedConstructExprClass: - case DependentScopeDeclRefExprClass: - return CT_Dependent; - - case AtomicExprClass: - case AsTypeExprClass: - case BinaryConditionalOperatorClass: - case BlockExprClass: - case CUDAKernelCallExprClass: - case DeclRefExprClass: - case ObjCBridgedCastExprClass: - case ObjCIndirectCopyRestoreExprClass: - case ObjCProtocolExprClass: - case ObjCSelectorExprClass: - case OffsetOfExprClass: - case PackExpansionExprClass: - case PseudoObjectExprClass: - case SubstNonTypeTemplateParmExprClass: - case SubstNonTypeTemplateParmPackExprClass: - case UnaryExprOrTypeTraitExprClass: - case UnresolvedLookupExprClass: - case UnresolvedMemberExprClass: - // FIXME: Can any of the above throw? If so, when? - return CT_Cannot; - - case AddrLabelExprClass: - case ArrayTypeTraitExprClass: - case BinaryTypeTraitExprClass: - case TypeTraitExprClass: - case CXXBoolLiteralExprClass: - case CXXNoexceptExprClass: - case CXXNullPtrLiteralExprClass: - case CXXPseudoDestructorExprClass: - case CXXScalarValueInitExprClass: - case CXXThisExprClass: - case CXXUuidofExprClass: - case CharacterLiteralClass: - case ExpressionTraitExprClass: - case FloatingLiteralClass: - case GNUNullExprClass: - case ImaginaryLiteralClass: - case ImplicitValueInitExprClass: - case IntegerLiteralClass: - case ObjCEncodeExprClass: - case ObjCStringLiteralClass: - case ObjCBoolLiteralExprClass: - case OpaqueValueExprClass: - case PredefinedExprClass: - case SizeOfPackExprClass: - case StringLiteralClass: - case UnaryTypeTraitExprClass: - // These expressions can never throw. - return CT_Cannot; - -#define STMT(CLASS, PARENT) case CLASS##Class: -#define STMT_RANGE(Base, First, Last) -#define LAST_STMT_RANGE(BASE, FIRST, LAST) -#define EXPR(CLASS, PARENT) -#define ABSTRACT_STMT(STMT) -#include "clang/AST/StmtNodes.inc" - case NoStmtClass: - llvm_unreachable("Invalid class for expression"); - } - llvm_unreachable("Bogus StmtClass"); -} - Expr* Expr::IgnoreParens() { Expr* E = this; while (true) { diff --git a/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp b/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp index 01c9fe7..66a88b0 100644 --- a/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp @@ -934,6 +934,7 @@ static bool IsGlobalLValue(APValue::LValueBase B) { case Expr::ObjCStringLiteralClass: case Expr::ObjCEncodeExprClass: case Expr::CXXTypeidExprClass: + case Expr::CXXUuidofExprClass: return true; case Expr::CallExprClass: return IsStringLiteralCall(cast<CallExpr>(E)); @@ -1491,15 +1492,19 @@ static unsigned getBaseIndex(const CXXRecordDecl *Derived, llvm_unreachable("base class missing from derived class's bases list"); } -/// Extract the value of a character from a string literal. +/// Extract the value of a character from a string literal. CharType is used to +/// determine the expected signedness of the result -- a string literal used to +/// initialize an array of 'signed char' or 'unsigned char' might contain chars +/// of the wrong signedness. static APSInt ExtractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, - uint64_t Index) { + uint64_t Index, QualType CharType) { // FIXME: Support PredefinedExpr, ObjCEncodeExpr, MakeStringConstant const StringLiteral *S = dyn_cast<StringLiteral>(Lit); assert(S && "unexpected string literal expression kind"); + assert(CharType->isIntegerType() && "unexpected character type"); APSInt Value(S->getCharByteWidth() * Info.Ctx.getCharWidth(), - Lit->getType()->getArrayElementTypeNoTypeQual()->isUnsignedIntegerType()); + CharType->isUnsignedIntegerType()); if (Index < S->getLength()) Value = S->getCodeUnit(Index); return Value; @@ -1546,7 +1551,7 @@ static bool ExtractSubobject(EvalInfo &Info, const Expr *E, assert(I == N - 1 && "extracting subobject of character?"); assert(!O->hasLValuePath() || O->getLValuePath().empty()); Obj = APValue(ExtractStringLiteralCharacter( - Info, O->getLValueBase().get<const Expr*>(), Index)); + Info, O->getLValueBase().get<const Expr*>(), Index, SubType)); return true; } else if (O->getArrayInitializedElts() > Index) O = &O->getArrayInitializedElt(Index); @@ -2868,6 +2873,7 @@ public: bool VisitStringLiteral(const StringLiteral *E) { return Success(E); } bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { return Success(E); } bool VisitCXXTypeidExpr(const CXXTypeidExpr *E); + bool VisitCXXUuidofExpr(const CXXUuidofExpr *E); bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E); bool VisitUnaryDeref(const UnaryOperator *E); bool VisitUnaryReal(const UnaryOperator *E); @@ -2973,6 +2979,10 @@ bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { return Success(E); } +bool LValueExprEvaluator::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { + return Success(E); +} + bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) { // Handle static data members. if (const VarDecl *VD = dyn_cast<VarDecl>(E->getMemberDecl())) { @@ -3849,8 +3859,7 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) { // C++11 [dcl.init.string]p1: A char array [...] can be initialized by [...] // an appropriately-typed string literal enclosed in braces. - if (E->getNumInits() == 1 && E->getInit(0)->isGLValue() && - Info.Ctx.hasSameUnqualifiedType(E->getType(), E->getInit(0)->getType())) { + if (E->isStringLiteralInit()) { LValue LV; if (!EvaluateLValue(E->getInit(0), LV, Info)) return false; @@ -5079,14 +5088,37 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { } } + // The comparison here must be unsigned, and performed with the same + // width as the pointer. + unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy); + uint64_t CompareLHS = LHSOffset.getQuantity(); + uint64_t CompareRHS = RHSOffset.getQuantity(); + assert(PtrSize <= 64 && "Unexpected pointer width"); + uint64_t Mask = ~0ULL >> (64 - PtrSize); + CompareLHS &= Mask; + CompareRHS &= Mask; + + // If there is a base and this is a relational operator, we can only + // compare pointers within the object in question; otherwise, the result + // depends on where the object is located in memory. + if (!LHSValue.Base.isNull() && E->isRelationalOp()) { + QualType BaseTy = getType(LHSValue.Base); + if (BaseTy->isIncompleteType()) + return Error(E); + CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy); + uint64_t OffsetLimit = Size.getQuantity(); + if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit) + return Error(E); + } + switch (E->getOpcode()) { default: llvm_unreachable("missing comparison operator"); - case BO_LT: return Success(LHSOffset < RHSOffset, E); - case BO_GT: return Success(LHSOffset > RHSOffset, E); - case BO_LE: return Success(LHSOffset <= RHSOffset, E); - case BO_GE: return Success(LHSOffset >= RHSOffset, E); - case BO_EQ: return Success(LHSOffset == RHSOffset, E); - case BO_NE: return Success(LHSOffset != RHSOffset, E); + case BO_LT: return Success(CompareLHS < CompareRHS, E); + case BO_GT: return Success(CompareLHS > CompareRHS, E); + case BO_LE: return Success(CompareLHS <= CompareRHS, E); + case BO_GE: return Success(CompareLHS >= CompareRHS, E); + case BO_EQ: return Success(CompareLHS == CompareRHS, E); + case BO_NE: return Success(CompareLHS != CompareRHS, E); } } } diff --git a/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp b/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp index fd616db..6b9fe26 100644 --- a/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp @@ -49,7 +49,10 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC, return DeclContext::lookup_result(); } -ExternalLoadResult +void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) { +} + +ExternalLoadResult ExternalASTSource::FindExternalLexicalDecls(const DeclContext *DC, bool (*isKindWeWant)(Decl::Kind), SmallVectorImpl<Decl*> &Result) { diff --git a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp index d7b6354..0d405f1 100644 --- a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp @@ -2280,9 +2280,7 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T, } -/// Mangles a member expression. Implicit accesses are not handled, -/// but that should be okay, because you shouldn't be able to -/// make an implicit access in a function template declaration. +/// Mangles a member expression. void CXXNameMangler::mangleMemberExpr(const Expr *base, bool isArrow, NestedNameSpecifier *qualifier, @@ -2291,8 +2289,17 @@ void CXXNameMangler::mangleMemberExpr(const Expr *base, unsigned arity) { // <expression> ::= dt <expression> <unresolved-name> // ::= pt <expression> <unresolved-name> - Out << (isArrow ? "pt" : "dt"); - mangleExpression(base); + if (base) { + if (base->isImplicitCXXThis()) { + // Note: GCC mangles member expressions to the implicit 'this' as + // *this., whereas we represent them as this->. The Itanium C++ ABI + // does not specify anything here, so we follow GCC. + Out << "dtdefpT"; + } else { + Out << (isArrow ? "pt" : "dt"); + mangleExpression(base); + } + } mangleUnresolvedName(qualifier, firstQualifierLookup, member, arity); } @@ -2346,6 +2353,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { // <expr-primary> ::= L <type> <value number> E # integer literal // ::= L <type <value float> E # floating literal // ::= L <mangled-name> E # external name + // ::= fpT # 'this' expression QualType ImplicitlyConvertedToType; recurse: @@ -2361,7 +2369,6 @@ recurse: // These all can only appear in local or variable-initialization // contexts and so should never appear in a mangling. case Expr::AddrLabelExprClass: - case Expr::CXXThisExprClass: case Expr::DesignatedInitExprClass: case Expr::ImplicitValueInitExprClass: case Expr::ParenListExprClass: @@ -2919,6 +2926,10 @@ recurse: mangleExpression(cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr()); break; } + + case Expr::CXXThisExprClass: + Out << "fpT"; + break; } } diff --git a/contrib/llvm/tools/clang/lib/AST/Stmt.cpp b/contrib/llvm/tools/clang/lib/AST/Stmt.cpp index 6af20df..e4d9f0a 100644 --- a/contrib/llvm/tools/clang/lib/AST/Stmt.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Stmt.cpp @@ -97,8 +97,8 @@ Stmt *Stmt::IgnoreImplicit() { /// \brief Strip off all label-like statements. /// -/// This will strip off label statements, case statements, and default -/// statements recursively. +/// This will strip off label statements, case statements, attributed +/// statements and default statements recursively. const Stmt *Stmt::stripLabelLikeStatements() const { const Stmt *S = this; while (true) { @@ -106,6 +106,8 @@ const Stmt *Stmt::stripLabelLikeStatements() const { S = LS->getSubStmt(); else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S)) S = SC->getSubStmt(); + else if (const AttributedStmt *AS = dyn_cast<AttributedStmt>(S)) + S = AS->getSubStmt(); else return S; } diff --git a/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp b/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp index 3a44183..0d1066b 100644 --- a/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp +++ b/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp @@ -169,6 +169,23 @@ void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { PrintStmt(Node->getSubStmt(), 0); } +void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) { + OS << "[["; + bool first = true; + for (AttrVec::const_iterator it = Node->getAttrs().begin(), + end = Node->getAttrs().end(); + it != end; ++it) { + if (!first) { + OS << ", "; + first = false; + } + // TODO: check this + (*it)->printPretty(OS, Context); + } + OS << "]] "; + PrintStmt(Node->getSubStmt(), 0); +} + void StmtPrinter::PrintRawIfStmt(IfStmt *If) { OS << "if ("; PrintExpr(If->getCond()); diff --git a/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp b/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp index e5526ce..e50523a 100644 --- a/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp +++ b/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp @@ -109,6 +109,11 @@ void StmtProfiler::VisitLabelStmt(const LabelStmt *S) { VisitDecl(S->getDecl()); } +void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) { + VisitStmt(S); + // TODO: maybe visit attributes? +} + void StmtProfiler::VisitIfStmt(const IfStmt *S) { VisitStmt(S); VisitDecl(S->getConditionVariable()); @@ -758,6 +763,7 @@ void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) { void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) { VisitExpr(S); + ID.AddBoolean(S->isImplicit()); } void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) { diff --git a/contrib/llvm/tools/clang/lib/AST/Type.cpp b/contrib/llvm/tools/clang/lib/AST/Type.cpp index c82aeaa..3f6a094 100644 --- a/contrib/llvm/tools/clang/lib/AST/Type.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Type.cpp @@ -1546,6 +1546,14 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, else if (epi.NoexceptExpr->isInstantiationDependent()) setInstantiationDependent(); } + } else if (getExceptionSpecType() == EST_Uninstantiated) { + // Store the function decl from which we will resolve our + // exception specification. + FunctionDecl **slot = reinterpret_cast<FunctionDecl**>(argSlot + numArgs); + slot[0] = epi.ExceptionSpecDecl; + slot[1] = epi.ExceptionSpecTemplate; + // This exception specification doesn't make the type dependent, because + // it's not instantiated as part of instantiating the type. } if (epi.ConsumedArguments) { @@ -1629,6 +1637,8 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, ID.AddPointer(epi.Exceptions[i].getAsOpaquePtr()); } else if (epi.ExceptionSpecType == EST_ComputedNoexcept && epi.NoexceptExpr){ epi.NoexceptExpr->Profile(ID, Context, false); + } else if (epi.ExceptionSpecType == EST_Uninstantiated) { + ID.AddPointer(epi.ExceptionSpecDecl->getCanonicalDecl()); } if (epi.ConsumedArguments) { for (unsigned i = 0; i != NumArgs; ++i) diff --git a/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp b/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp index 7a45972..107d9fb 100644 --- a/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp +++ b/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp @@ -2157,13 +2157,12 @@ VTableLayout::VTableLayout(uint64_t NumVTableComponents, VTableThunks(new VTableThunkTy[NumVTableThunks]), AddressPoints(AddressPoints) { std::copy(VTableComponents, VTableComponents+NumVTableComponents, - this->VTableComponents); - std::copy(VTableThunks, VTableThunks+NumVTableThunks, this->VTableThunks); + this->VTableComponents.get()); + std::copy(VTableThunks, VTableThunks+NumVTableThunks, + this->VTableThunks.get()); } -VTableLayout::~VTableLayout() { - delete[] VTableComponents; -} +VTableLayout::~VTableLayout() { } VTableContext::~VTableContext() { llvm::DeleteContainerSeconds(VTableLayouts); |