diff options
| author | 2019-01-27 16:42:12 +0000 | |
|---|---|---|
| committer | 2019-01-27 16:42:12 +0000 | |
| commit | b773203fb58f3ef282fb69c832d8710cab5bc82d (patch) | |
| tree | e75913f147570fbd75169647b144df85b88a038c /gnu/llvm/tools/clang/lib/AST/Decl.cpp | |
| parent | tweak errno in previous (diff) | |
| download | wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip | |
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/AST/Decl.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/AST/Decl.cpp | 290 |
1 files changed, 194 insertions, 96 deletions
diff --git a/gnu/llvm/tools/clang/lib/AST/Decl.cpp b/gnu/llvm/tools/clang/lib/AST/Decl.cpp index 918466236bf..1bf01b90123 100644 --- a/gnu/llvm/tools/clang/lib/AST/Decl.cpp +++ b/gnu/llvm/tools/clang/lib/AST/Decl.cpp @@ -27,6 +27,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/ODRHash.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/Stmt.h" @@ -76,6 +77,24 @@ Decl *clang::getPrimaryMergedDecl(Decl *D) { return D->getASTContext().getPrimaryMergedDecl(D); } +void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const { + SourceLocation Loc = this->Loc; + if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation(); + if (Loc.isValid()) { + Loc.print(OS, Context.getSourceManager()); + OS << ": "; + } + OS << Message; + + if (auto *ND = dyn_cast_or_null<NamedDecl>(TheDecl)) { + OS << " '"; + ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true); + OS << "'"; + } + + OS << '\n'; +} + // Defined here so that it can be inlined into its direct callers. bool Decl::isOutOfLine() const { return !getLexicalDeclContext()->Equals(getDeclContext()); @@ -224,7 +243,7 @@ LinkageInfo LinkageComputer::getLVForType(const Type &T, return getTypeLinkageAndVisibility(&T); } -/// \brief Get the most restrictive linkage for the types in the given +/// Get the most restrictive linkage for the types in the given /// template parameter list. For visibility purposes, template /// parameters are part of the signature of a template. LinkageInfo LinkageComputer::getLVForTemplateParameterList( @@ -291,7 +310,7 @@ static const Decl *getOutermostFuncOrBlockContext(const Decl *D) { return Ret; } -/// \brief Get the most restrictive linkage for the types and +/// Get the most restrictive linkage for the types and /// declarations in the given template argument list. /// /// Note that we don't take an LVComputationKind because we always @@ -312,12 +331,12 @@ LinkageComputer::getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args, LV.merge(getLVForType(*Arg.getAsType(), computation)); continue; - case TemplateArgument::Declaration: - if (const auto *ND = dyn_cast<NamedDecl>(Arg.getAsDecl())) { - assert(!usesTypeVisibility(ND)); - LV.merge(getLVForDecl(ND, computation)); - } + case TemplateArgument::Declaration: { + const NamedDecl *ND = Arg.getAsDecl(); + assert(!usesTypeVisibility(ND)); + LV.merge(getLVForDecl(ND, computation)); continue; + } case TemplateArgument::NullPtr: LV.merge(getTypeLinkageAndVisibility(Arg.getNullPtrType())); @@ -614,7 +633,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, // equivalent in C99) // The C++ modules TS adds "non-exported" to this list. if (Context.getLangOpts().CPlusPlus && - Var->getType().isConstQualified() && + Var->getType().isConstQualified() && !Var->getType().isVolatileQualified() && !Var->isInline() && !isExportedFromModuleIntefaceUnit(Var)) { @@ -706,7 +725,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, // If we're paying attention to global visibility, apply // -finline-visibility-hidden if this is an inline method. if (useInlineVisibilityHidden(D)) - LV.mergeVisibility(HiddenVisibility, true); + LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false); } } @@ -896,7 +915,7 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D, // Note that we do this before merging information about // the class visibility. if (!LV.isVisibilityExplicit() && useInlineVisibilityHidden(D)) - LV.mergeVisibility(HiddenVisibility, true); + LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false); } // If this class member has an explicit visibility attribute, the only @@ -1030,7 +1049,7 @@ bool NamedDecl::isLinkageValid() const { ObjCStringFormatFamily NamedDecl::getObjCFStringFormattingFamily() const { StringRef name = getName(); if (name.empty()) return SFF_None; - + if (name.front() == 'C') if (name == "CFStringCreateWithFormat" || name == "CFStringCreateWithFormatAndArguments" || @@ -1073,9 +1092,18 @@ getExplicitVisibilityAux(const NamedDecl *ND, // If there wasn't explicit visibility there, and this is a // specialization of a class template, check for visibility // on the pattern. - if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(ND)) - return getVisibilityOf(spec->getSpecializedTemplate()->getTemplatedDecl(), - kind); + if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(ND)) { + // Walk all the template decl till this point to see if there are + // explicit visibility attributes. + const auto *TD = spec->getSpecializedTemplate()->getTemplatedDecl(); + while (TD != nullptr) { + auto Vis = getVisibilityOf(TD, kind); + if (Vis != None) + return Vis; + TD = TD->getPreviousDecl(); + } + return None; + } // Use the most recent declaration. if (!IsMostRecent && !isa<NamespaceDecl>(ND)) { @@ -1234,7 +1262,27 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, !isTemplateInstantiation(FD->getTemplateSpecializationKind())) return LinkageInfo::none(); + // If a function is hidden by -fvisibility-inlines-hidden option and + // is not explicitly attributed as a hidden function, + // we should not make static local variables in the function hidden. LV = getLVForDecl(FD, computation); + if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) && + !LV.isVisibilityExplicit()) { + assert(cast<VarDecl>(D)->isStaticLocal()); + // If this was an implicitly hidden inline method, check again for + // explicit visibility on the parent class, and use that for static locals + // if present. + if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) + LV = getLVForDecl(MD->getParent(), computation); + if (!LV.isVisibilityExplicit()) { + Visibility globalVisibility = + computation.isValueVisibility() + ? Context.getLangOpts().getValueVisibilityMode() + : Context.getLangOpts().getTypeVisibilityMode(); + return LinkageInfo(VisibleNoLinkage, globalVisibility, + /*visibilityExplicit=*/false); + } + } } if (!isExternallyVisible(LV.getLinkage())) return LinkageInfo::none(); @@ -1310,7 +1358,7 @@ LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D, case Decl::ObjCPropertyImpl: case Decl::ObjCProtocol: return getExternalLinkageFor(D); - + case Decl::CXXRecord: { const auto *Record = cast<CXXRecordDecl>(D); if (Record->isLambda()) { @@ -1320,25 +1368,25 @@ LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D, } // This lambda has its linkage/visibility determined: - // - either by the outermost lambda if that lambda has no mangling - // number. + // - either by the outermost lambda if that lambda has no mangling + // number. // - or by the parent of the outer most lambda - // This prevents infinite recursion in settings such as nested lambdas - // used in NSDMI's, for e.g. + // This prevents infinite recursion in settings such as nested lambdas + // used in NSDMI's, for e.g. // struct L { // int t{}; - // int t2 = ([](int a) { return [](int b) { return b; };})(t)(t); + // int t2 = ([](int a) { return [](int b) { return b; };})(t)(t); // }; - const CXXRecordDecl *OuterMostLambda = + const CXXRecordDecl *OuterMostLambda = getOutermostEnclosingLambda(Record); if (!OuterMostLambda->getLambdaManglingNumber()) return getInternalLinkageFor(D); - + return getLVForClosure( OuterMostLambda->getDeclContext()->getRedeclContext(), OuterMostLambda->getLambdaContextDecl(), computation); } - + break; } } @@ -1346,7 +1394,7 @@ LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D, // Handle linkage for namespace-scope names. if (D->getDeclContext()->getRedeclContext()->isFileContext()) return getLVForNamespaceScopeDecl(D, computation, IgnoreVarTypeLinkage); - + // C++ [basic.link]p5: // In addition, a member function, static data member, a named // class or enumeration of class scope, or an unnamed class or @@ -1497,9 +1545,10 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, using ContextsTy = SmallVector<const DeclContext *, 8>; ContextsTy Contexts; - // Collect contexts. - while (Ctx && isa<NamedDecl>(Ctx)) { - Contexts.push_back(Ctx); + // Collect named contexts. + while (Ctx) { + if (isa<NamedDecl>(Ctx)) + Contexts.push_back(Ctx); Ctx = Ctx->getParent(); } @@ -1689,7 +1738,7 @@ NamedDecl *NamedDecl::getUnderlyingDeclImpl() { bool NamedDecl::isCXXInstanceMember() const { if (!isCXXClassMember()) return false; - + const NamedDecl *D = this; if (isa<UsingShadowDecl>(D)) D = cast<UsingShadowDecl>(D)->getTargetDecl(); @@ -1909,7 +1958,7 @@ VarDecl::TLSKind VarDecl::getTLSKind() const { SourceRange VarDecl::getSourceRange() const { if (const Expr *Init = getInit()) { SourceLocation InitEnd = Init->getLocEnd(); - // If Init is implicit, ignore its source range and fallback on + // If Init is implicit, ignore its source range and fallback on // DeclaratorDecl::getSourceRange() to handle postfix elements. if (InitEnd.isValid() && InitEnd != getLocation()) return SourceRange(getOuterLocStart(), InitEnd); @@ -2145,11 +2194,11 @@ bool VarDecl::isOutOfLine() const { return false; // If this static data member was instantiated from a static data member of - // a class template, check whether that static data member was defined + // a class template, check whether that static data member was defined // out-of-line. if (VarDecl *VD = getInstantiatedFromStaticDataMember()) return VD->isOutOfLine(); - + return false; } @@ -2403,6 +2452,23 @@ void VarDecl::setDescribedVarTemplate(VarTemplateDecl *Template) { getASTContext().setTemplateOrSpecializationInfo(this, Template); } +bool VarDecl::isKnownToBeDefined() const { + const auto &LangOpts = getASTContext().getLangOpts(); + // In CUDA mode without relocatable device code, variables of form 'extern + // __shared__ Foo foo[]' are pointers to the base of the GPU core's shared + // memory pool. These are never undefined variables, even if they appear + // inside of an anon namespace or static function. + // + // With CUDA relocatable device code enabled, these variables don't get + // special handling; they're treated like regular extern variables. + if (LangOpts.CUDA && !LangOpts.CUDARelocatableDeviceCode && + hasExternalStorage() && hasAttr<CUDASharedAttr>() && + isa<IncompleteArrayType>(getType())) + return true; + + return hasDefinition(); +} + MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const { if (isStaticDataMember()) // FIXME: Remove ? @@ -2827,6 +2893,14 @@ bool FunctionDecl::isNoReturn() const { return false; } +bool FunctionDecl::isCPUDispatchMultiVersion() const { + return isMultiVersion() && hasAttr<CPUDispatchAttr>(); +} + +bool FunctionDecl::isCPUSpecificMultiVersion() const { + return isMultiVersion() && hasAttr<CPUSpecificAttr>(); +} + void FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { redeclarable_base::setPreviousDecl(PrevDecl); @@ -2837,14 +2911,14 @@ FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch"); FunTmpl->setPreviousDecl(PrevFunTmpl); } - + if (PrevDecl && PrevDecl->IsInline) IsInline = true; } FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); } -/// \brief Returns a value indicating whether this function +/// Returns a value indicating whether this function /// corresponds to a builtin function. /// /// The function corresponds to a built-in function if it is @@ -2901,6 +2975,13 @@ unsigned FunctionDecl::getBuiltinID() const { Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) return 0; + // CUDA does not have device-side standard library. printf and malloc are the + // only special cases that are supported by device-side runtime. + if (Context.getLangOpts().CUDA && hasAttr<CUDADeviceAttr>() && + !hasAttr<CUDAHostAttr>() && + !(BuiltinID == Builtin::BIprintf || BuiltinID == Builtin::BImalloc)) + return 0; + return BuiltinID; } @@ -2939,7 +3020,7 @@ unsigned FunctionDecl::getMinRequiredArguments() const { return NumRequiredArgs; } -/// \brief The combination of the extern and inline keywords under MSVC forces +/// The combination of the extern and inline keywords under MSVC forces /// the function to be required. /// /// Note: This function assumes that we will only get called when isInlined() @@ -2982,13 +3063,13 @@ static bool RedeclForcesDefC99(const FunctionDecl *Redecl) { if (Redecl->isImplicit()) return false; - if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == SC_Extern) + if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == SC_Extern) return true; // Not an inline definition return false; } -/// \brief For a function declaration in C or C++, determine whether this +/// For a function declaration in C or C++, determine whether this /// declaration causes the definition to be externally visible. /// /// For instance, this determines if adding the current declaration to the set @@ -3027,7 +3108,7 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { if (!Prev->isInlineSpecified() || Prev->getStorageClass() != SC_Extern) return false; - } else if (Prev->isInlineSpecified() && + } else if (Prev->isInlineSpecified() && Prev->getStorageClass() != SC_Extern) { return false; } @@ -3039,8 +3120,8 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { return false; // C99 6.7.4p6: - // [...] If all of the file scope declarations for a function in a - // translation unit include the inline function specifier without extern, + // [...] If all of the file scope declarations for a function in a + // translation unit include the inline function specifier without extern, // then the definition in that translation unit is an inline definition. if (isInlineSpecified() && getStorageClass() != SC_Extern) return false; @@ -3088,12 +3169,9 @@ SourceRange FunctionDecl::getExceptionSpecSourceRange() const { const Attr *FunctionDecl::getUnusedResultAttr() const { QualType RetType = getReturnType(); - if (RetType->isRecordType()) { - if (const auto *Ret = - dyn_cast_or_null<RecordDecl>(RetType->getAsTagDecl())) { - if (const auto *R = Ret->getAttr<WarnUnusedResultAttr>()) - return R; - } + if (const auto *Ret = RetType->getAsRecordDecl()) { + if (const auto *R = Ret->getAttr<WarnUnusedResultAttr>()) + return R; } else if (const auto *ET = RetType->getAs<EnumType>()) { if (const EnumDecl *ED = ET->getDecl()) { if (const auto *R = ED->getAttr<WarnUnusedResultAttr>()) @@ -3103,7 +3181,7 @@ const Attr *FunctionDecl::getUnusedResultAttr() const { return getAttr<WarnUnusedResultAttr>(); } -/// \brief For an inline function definition in C, or for a gnu_inline function +/// For an inline function definition in C, or for a gnu_inline function /// in C++, determine whether the definition will be externally visible. /// /// Inline function definitions are always available for inlining optimizations. @@ -3116,16 +3194,16 @@ const Attr *FunctionDecl::getUnusedResultAttr() const { /// inline definition becomes externally visible (C99 6.7.4p6). /// /// In GNU89 mode, or if the gnu_inline attribute is attached to the function -/// definition, we use the GNU semantics for inline, which are nearly the -/// opposite of C99 semantics. In particular, "inline" by itself will create -/// an externally visible symbol, but "extern inline" will not create an +/// definition, we use the GNU semantics for inline, which are nearly the +/// opposite of C99 semantics. In particular, "inline" by itself will create +/// an externally visible symbol, but "extern inline" will not create an /// externally visible symbol. bool FunctionDecl::isInlineDefinitionExternallyVisible() const { assert((doesThisDeclarationHaveABody() || willHaveBody()) && "Must be a function definition"); assert(isInlined() && "Function must be inline"); ASTContext &Context = getASTContext(); - + if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()) { // Note: If you change the logic here, please change // doesDeclarationForceExternallyVisibleDefinition as well. @@ -3135,15 +3213,15 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const { // externally visible. if (!(isInlineSpecified() && getStorageClass() == SC_Extern)) return true; - + // If any declaration is 'inline' but not 'extern', then this definition // is externally visible. for (auto Redecl : redecls()) { - if (Redecl->isInlineSpecified() && + if (Redecl->isInlineSpecified() && Redecl->getStorageClass() != SC_Extern) return true; - } - + } + return false; } @@ -3152,17 +3230,17 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const { "should not use C inline rules in C++"); // C99 6.7.4p6: - // [...] If all of the file scope declarations for a function in a - // translation unit include the inline function specifier without extern, + // [...] If all of the file scope declarations for a function in a + // translation unit include the inline function specifier without extern, // then the definition in that translation unit is an inline definition. for (auto Redecl : redecls()) { if (RedeclForcesDefC99(Redecl)) return true; } - + // C99 6.7.4p6: - // An inline definition does not provide an external definition for the - // function, and does not forbid an external definition in another + // An inline definition does not provide an external definition for the + // function, and does not forbid an external definition in another // translation unit. return false; } @@ -3212,13 +3290,13 @@ MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const { return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>(); } -void +void FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD, TemplateSpecializationKind TSK) { - assert(TemplateOrSpecialization.isNull() && + assert(TemplateOrSpecialization.isNull() && "Member function is already a specialization"); - MemberSpecializationInfo *Info + MemberSpecializationInfo *Info = new (C) MemberSpecializationInfo(FD, TSK); TemplateOrSpecialization = Info; } @@ -3235,12 +3313,12 @@ bool FunctionDecl::isImplicitlyInstantiable() const { // If the function is invalid, it can't be implicitly instantiated. if (isInvalidDecl()) return false; - + switch (getTemplateSpecializationKind()) { case TSK_Undeclared: case TSK_ExplicitInstantiationDefinition: return false; - + case TSK_ImplicitInstantiation: return true; @@ -3259,12 +3337,12 @@ bool FunctionDecl::isImplicitlyInstantiable() const { bool HasPattern = false; if (PatternDecl) HasPattern = PatternDecl->hasBody(PatternDecl); - + // C++0x [temp.explicit]p9: // Except for inline functions, other explicit instantiation declarations // have the effect of suppressing the implicit instantiation of the entity - // to which they refer. - if (!HasPattern || !PatternDecl) + // to which they refer. + if (!HasPattern || !PatternDecl) return true; return PatternDecl->isInlined(); @@ -3274,7 +3352,7 @@ bool FunctionDecl::isTemplateInstantiation() const { switch (getTemplateSpecializationKind()) { case TSK_Undeclared: case TSK_ExplicitSpecialization: - return false; + return false; case TSK_ImplicitInstantiation: case TSK_ExplicitInstantiationDeclaration: case TSK_ExplicitInstantiationDefinition: @@ -3282,7 +3360,7 @@ bool FunctionDecl::isTemplateInstantiation() const { } llvm_unreachable("All TSK values handled."); } - + FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { // Handle class scope explicit specialization special case. if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { @@ -3291,13 +3369,13 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { return nullptr; } - // If this is a generic lambda call operator specialization, its + // If this is a generic lambda call operator specialization, its // instantiation pattern is always its primary template's pattern - // even if its primary template was instantiated from another + // even if its primary template was instantiated from another // member template (which happens with nested generic lambdas). - // Since a lambda's call operator's body is transformed eagerly, - // we don't have to go hunting for a prototype definition template - // (i.e. instantiated-from-member-template) to use as an instantiation + // Since a lambda's call operator's body is transformed eagerly, + // we don't have to go hunting for a prototype definition template + // (i.e. instantiated-from-member-template) to use as an instantiation // pattern. if (isGenericLambdaCallOperatorSpecialization( @@ -3316,7 +3394,7 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { } return getDefinitionOrSelf(Primary->getTemplatedDecl()); - } + } if (auto *MFD = getInstantiatedFromMemberFunction()) return getDefinitionOrSelf(MFD); @@ -3371,7 +3449,7 @@ FunctionDecl::setFunctionTemplateSpecialization(ASTContext &C, TemplateSpecializationKind TSK, const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation PointOfInstantiation) { - assert(TSK != TSK_Undeclared && + assert(TSK != TSK_Undeclared && "Must specify the type of function template specialization"); FunctionTemplateSpecializationInfo *Info = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); @@ -3439,7 +3517,7 @@ TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const { = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>(); if (MSInfo) return MSInfo->getTemplateSpecializationKind(); - + return TSK_Undeclared; } @@ -3479,22 +3557,22 @@ SourceLocation FunctionDecl::getPointOfInstantiation() const { else if (MemberSpecializationInfo *MSInfo = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) return MSInfo->getPointOfInstantiation(); - + return SourceLocation(); } bool FunctionDecl::isOutOfLine() const { if (Decl::isOutOfLine()) return true; - - // If this function was instantiated from a member function of a + + // If this function was instantiated from a member function of a // class template, check whether that member function was defined out-of-line. if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) { const FunctionDecl *Definition; if (FD->hasBody(Definition)) return Definition->isOutOfLine(); } - + // If this function was instantiated from a function template, // check whether that function template was defined out-of-line. if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) { @@ -3502,7 +3580,7 @@ bool FunctionDecl::isOutOfLine() const { if (FunTmpl->getTemplatedDecl()->hasBody(Definition)) return Definition->isOutOfLine(); } - + return false; } @@ -3515,7 +3593,7 @@ unsigned FunctionDecl::getMemoryFunctionKind() const { if (!FnInfo) return 0; - + // Builtin handling. switch (getBuiltinID()) { case Builtin::BI__builtin_memset: @@ -3605,16 +3683,19 @@ unsigned FunctionDecl::getMemoryFunctionKind() const { return 0; } +unsigned FunctionDecl::getODRHash() const { + assert(HasODRHash); + return ODRHash; +} + unsigned FunctionDecl::getODRHash() { if (HasODRHash) return ODRHash; - if (FunctionDecl *Definition = getDefinition()) { - if (Definition != this) { - HasODRHash = true; - ODRHash = Definition->getODRHash(); - return ODRHash; - } + if (auto *FT = getInstantiatedFromMemberFunction()) { + HasODRHash = true; + ODRHash = FT->getODRHash(); + return ODRHash; } class ODRHash Hash; @@ -3658,6 +3739,11 @@ unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const { return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue(); } +bool FieldDecl::isZeroLengthBitField(const ASTContext &Ctx) const { + return isUnnamedBitfield() && !getBitWidth()->isValueDependent() && + getBitWidthValue(Ctx) == 0; +} + unsigned FieldDecl::getFieldIndex() const { const FieldDecl *Canonical = getCanonicalDecl(); if (Canonical != this) @@ -3904,6 +3990,17 @@ void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED, SpecializationInfo = new (C) MemberSpecializationInfo(ED, TSK); } +unsigned EnumDecl::getODRHash() { + if (HasODRHash) + return ODRHash; + + class ODRHash Hash; + Hash.AddEnumDecl(this); + HasODRHash = true; + ODRHash = Hash.CalculateHash(); + return ODRHash; +} + //===----------------------------------------------------------------------===// // RecordDecl Implementation //===----------------------------------------------------------------------===// @@ -3915,7 +4012,10 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C, : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc), HasFlexibleArrayMember(false), AnonymousStructOrUnion(false), HasObjectMember(false), HasVolatileMember(false), - LoadedFieldsFromExternalStorage(false) { + LoadedFieldsFromExternalStorage(false), + NonTrivialToPrimitiveDefaultInitialize(false), + NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false), + ParamDestroyedInCallee(false), ArgPassingRestrictions(APK_CanPassInRegs) { assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); } @@ -4365,9 +4465,7 @@ bool TypedefNameDecl::isTransparentTagSlow() const { }; bool isTransparent = determineIsTransparent(); - CacheIsTransparentTag = 1; - if (isTransparent) - CacheIsTransparentTag |= 0x2; + MaybeModedTInfo.setInt((isTransparent << 1) | 1); return isTransparent; } @@ -4433,7 +4531,7 @@ EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, unsigned ID) { // ImportDecl Implementation //===----------------------------------------------------------------------===// -/// \brief Retrieve the number of module identifiers needed to name the given +/// Retrieve the number of module identifiers needed to name the given /// module. static unsigned getNumModuleIdentifiers(Module *Mod) { unsigned Result = 1; @@ -4444,7 +4542,7 @@ static unsigned getNumModuleIdentifiers(Module *Mod) { return Result; } -ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc, +ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef<SourceLocation> IdentifierLocs) : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, true) { @@ -4454,7 +4552,7 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc, StoredLocs); } -ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc, +ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, SourceLocation EndLoc) : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, false) { *getTrailingObjects<SourceLocation>() = EndLoc; |
