diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/Decl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/Decl.cpp | 584 |
1 files changed, 345 insertions, 239 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/Decl.cpp b/contrib/llvm/tools/clang/lib/AST/Decl.cpp index ea4b2f5..42bebc5 100644 --- a/contrib/llvm/tools/clang/lib/AST/Decl.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Decl.cpp @@ -207,13 +207,13 @@ static Optional<Visibility> getVisibilityOf(const NamedDecl *D, // If we're ultimately computing the visibility of a type, look for // a 'type_visibility' attribute before looking for 'visibility'. if (kind == NamedDecl::VisibilityForType) { - if (const TypeVisibilityAttr *A = D->getAttr<TypeVisibilityAttr>()) { + if (const auto *A = D->getAttr<TypeVisibilityAttr>()) { return getVisibilityFromAttr(A); } } // If this declaration has an explicit visibility attribute, use it. - if (const VisibilityAttr *A = D->getAttr<VisibilityAttr>()) { + if (const auto *A = D->getAttr<VisibilityAttr>()) { return getVisibilityFromAttr(A); } @@ -252,8 +252,7 @@ getLVForTemplateParameterList(const TemplateParameterList *Params, // template <enum X> class A { ... }; // We have to be careful here, though, because we can be dealing with // dependent types. - if (const NonTypeTemplateParmDecl *NTTP = - dyn_cast<NonTypeTemplateParmDecl>(P)) { + if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) { // Handle the non-pack case first. if (!NTTP->isExpandedParameterPack()) { if (!NTTP->getType()->isDependentType()) { @@ -273,7 +272,7 @@ getLVForTemplateParameterList(const TemplateParameterList *Params, // Template template parameters can be restricted by their // template parameters, recursively. - const TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(P); + const auto *TTP = cast<TemplateTemplateParmDecl>(P); // Handle the non-pack case first. if (!TTP->isExpandedParameterPack()) { @@ -329,7 +328,7 @@ static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args, continue; case TemplateArgument::Declaration: - if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl())) { + if (const auto *ND = dyn_cast<NamedDecl>(Arg.getAsDecl())) { assert(!usesTypeVisibility(ND)); LV.merge(getLVForDecl(ND, computation)); } @@ -541,7 +540,7 @@ static bool useInlineVisibilityHidden(const NamedDecl *D) { if (!Opts.CPlusPlus || !Opts.InlineVisibilityHidden) return false; - const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); + const auto *FD = dyn_cast<FunctionDecl>(D); if (!FD) return false; @@ -569,7 +568,7 @@ template <typename T> static bool isFirstInExternCContext(T *D) { } static bool isSingleLineLanguageLinkage(const Decl &D) { - if (const LinkageSpecDecl *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext())) + if (const auto *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext())) if (!SD->hasBraces()) return true; return false; @@ -587,7 +586,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, // - an object, reference, function or function template that is // explicitly declared static; or, // (This bullet corresponds to C99 6.2.2p3.) - if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { + if (const auto *Var = dyn_cast<VarDecl>(D)) { // Explicitly declared static. if (Var->getStorageClass() == SC_Static) return LinkageInfo::internal(); @@ -634,8 +633,10 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, assert(!isa<FieldDecl>(D) && "Didn't expect a FieldDecl!"); if (D->isInAnonymousNamespace()) { - const VarDecl *Var = dyn_cast<VarDecl>(D); - const FunctionDecl *Func = dyn_cast<FunctionDecl>(D); + const auto *Var = dyn_cast<VarDecl>(D); + const auto *Func = dyn_cast<FunctionDecl>(D); + // FIXME: In C++11 onwards, anonymous namespaces should give decls + // within them internal linkage, not unique external linkage. if ((!Var || !isFirstInExternCContext(Var)) && (!Func || !isFirstInExternCContext(Func))) return LinkageInfo::uniqueExternal(); @@ -658,7 +659,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, for (const DeclContext *DC = D->getDeclContext(); !isa<TranslationUnitDecl>(DC); DC = DC->getParent()) { - const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC); + const auto *ND = dyn_cast<NamespaceDecl>(DC); if (!ND) continue; if (Optional<Visibility> Vis = getExplicitVisibility(ND, computation)) { LV.mergeVisibility(*Vis, true); @@ -692,7 +693,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, // name of // // - an object or reference, unless it has internal linkage; or - if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { + if (const auto *Var = dyn_cast<VarDecl>(D)) { // GCC applies the following optimization to variables and static // data members, but not to functions: // @@ -732,13 +733,12 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, // As per function and class template specializations (below), // consider LV for the template and template arguments. We're at file // scope, so we do not need to worry about nested specializations. - if (const VarTemplateSpecializationDecl *spec - = dyn_cast<VarTemplateSpecializationDecl>(Var)) { + if (const auto *spec = dyn_cast<VarTemplateSpecializationDecl>(Var)) { mergeTemplateLV(LV, spec, computation); } // - a function, unless it has internal linkage; or - } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { + } else if (const auto *Function = dyn_cast<FunctionDecl>(D)) { // In theory, we can modify the function's LV by the LV of its // type unless it has C linkage (see comment above about variables // for justification). In practice, GCC doesn't do this, so it's @@ -785,7 +785,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, // - a named enumeration (7.2), or an unnamed enumeration // defined in a typedef declaration in which the enumeration // has the typedef name for linkage purposes (7.1.3); or - } else if (const TagDecl *Tag = dyn_cast<TagDecl>(D)) { + } else if (const auto *Tag = dyn_cast<TagDecl>(D)) { // Unnamed tags have no linkage. if (!Tag->hasNameForLinkage()) return LinkageInfo::none(); @@ -793,8 +793,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, // If this is a class template specialization, consider the // linkage of the template and template arguments. We're at file // scope, so we do not need to worry about nested specializations. - if (const ClassTemplateSpecializationDecl *spec - = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) { + if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) { mergeTemplateLV(LV, spec, computation); } @@ -808,7 +807,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, // - a template, unless it is a function template that has // internal linkage (Clause 14); - } else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) { + } else if (const auto *temp = dyn_cast<TemplateDecl>(D)) { bool considerVisibility = !hasExplicitVisibilityAlready(computation); LinkageInfo tempLV = getLVForTemplateParameterList(temp->getTemplateParameters(), computation); @@ -824,10 +823,14 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, } else if (isa<ObjCInterfaceDecl>(D)) { // fallout + } else if (auto *TD = dyn_cast<TypedefNameDecl>(D)) { + // A typedef declaration has linkage if it gives a type a name for + // linkage purposes. + if (!TD->getAnonDeclWithTypedefName(/*AnyRedecl*/true)) + return LinkageInfo::none(); + // Everything not covered here has no linkage. } else { - // FIXME: A typedef declaration has linkage if it gives a type a name for - // linkage purposes. return LinkageInfo::none(); } @@ -897,7 +900,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, // Specifically, if this decl exists and has an explicit attribute. const NamedDecl *explicitSpecSuppressor = nullptr; - if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { + if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) { // If the type of the function uses a type with unique-external // linkage, it's not legally usable from outside this translation unit. // But only look at the type-as-written. If this function has an @@ -928,9 +931,8 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, explicitSpecSuppressor = MD; } - } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { - if (const ClassTemplateSpecializationDecl *spec - = dyn_cast<ClassTemplateSpecializationDecl>(RD)) { + } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) { + if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(RD)) { mergeTemplateLV(LV, spec, computation); if (spec->isExplicitSpecialization()) { explicitSpecSuppressor = spec; @@ -945,9 +947,8 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, } // Static data members. - } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { - if (const VarTemplateSpecializationDecl *spec - = dyn_cast<VarTemplateSpecializationDecl>(VD)) + } else if (const auto *VD = dyn_cast<VarDecl>(D)) { + if (const auto *spec = dyn_cast<VarTemplateSpecializationDecl>(VD)) mergeTemplateLV(LV, spec, computation); // Modify the variable's linkage by its type, but ignore the @@ -962,7 +963,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, } // Template members. - } else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) { + } else if (const auto *temp = dyn_cast<TemplateDecl>(D)) { bool considerVisibility = (!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit() && @@ -971,8 +972,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, getLVForTemplateParameterList(temp->getTemplateParameters(), computation); LV.mergeMaybeWithVisibility(tempLV, considerVisibility); - if (const RedeclarableTemplateDecl *redeclTemp = - dyn_cast<RedeclarableTemplateDecl>(temp)) { + if (const auto *redeclTemp = dyn_cast<RedeclarableTemplateDecl>(temp)) { if (isExplicitMemberSpecialization(redeclTemp)) { explicitSpecSuppressor = temp->getTemplatedDecl(); } @@ -1048,7 +1048,7 @@ getExplicitVisibilityAux(const NamedDecl *ND, // If this is a member class of a specialization of a class template // and the corresponding decl has explicit visibility, use that. - if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND)) { + if (const auto *RD = dyn_cast<CXXRecordDecl>(ND)) { CXXRecordDecl *InstantiatedFrom = RD->getInstantiatedFromMemberClass(); if (InstantiatedFrom) return getVisibilityOf(InstantiatedFrom, kind); @@ -1057,8 +1057,7 @@ 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 ClassTemplateSpecializationDecl *spec - = dyn_cast<ClassTemplateSpecializationDecl>(ND)) + if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(ND)) return getVisibilityOf(spec->getSpecializedTemplate()->getTemplatedDecl(), kind); @@ -1069,7 +1068,7 @@ getExplicitVisibilityAux(const NamedDecl *ND, return getExplicitVisibilityAux(MostRecent, kind, true); } - if (const VarDecl *Var = dyn_cast<VarDecl>(ND)) { + if (const auto *Var = dyn_cast<VarDecl>(ND)) { if (Var->isStaticDataMember()) { VarDecl *InstantiatedFrom = Var->getInstantiatedFromStaticDataMember(); if (InstantiatedFrom) @@ -1083,7 +1082,7 @@ getExplicitVisibilityAux(const NamedDecl *ND, return None; } // Also handle function template specializations. - if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(ND)) { + if (const auto *fn = dyn_cast<FunctionDecl>(ND)) { // If the function is a specialization of a template with an // explicit visibility attribute, use that. if (FunctionTemplateSpecializationInfo *templateInfo @@ -1101,7 +1100,7 @@ getExplicitVisibilityAux(const NamedDecl *ND, } // The visibility of a template is stored in the templated decl. - if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(ND)) + if (const auto *TD = dyn_cast<TemplateDecl>(ND)) return getVisibilityOf(TD->getTemplatedDecl(), kind); return None; @@ -1122,7 +1121,7 @@ static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl, return getLVForDecl(cast<NamedDecl>(ContextDecl), computation); } - if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC)) + if (const auto *ND = dyn_cast<NamedDecl>(DC)) return getLVForDecl(ND, computation); return LinkageInfo::external(); @@ -1130,7 +1129,7 @@ static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl, static LinkageInfo getLVForLocalDecl(const NamedDecl *D, LVComputationKind computation) { - if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { + if (const auto *Function = dyn_cast<FunctionDecl>(D)) { if (Function->isInAnonymousNamespace() && !Function->isInExternCContext()) return LinkageInfo::uniqueExternal(); @@ -1153,7 +1152,7 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D, return LV; } - if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { + if (const auto *Var = dyn_cast<VarDecl>(D)) { if (Var->hasExternalStorage()) { if (Var->isInAnonymousNamespace() && !Var->isInExternCContext()) return LinkageInfo::uniqueExternal(); @@ -1189,14 +1188,14 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D, return LinkageInfo::none(); LinkageInfo LV; - if (const BlockDecl *BD = dyn_cast<BlockDecl>(OuterD)) { + if (const auto *BD = dyn_cast<BlockDecl>(OuterD)) { if (!BD->getBlockManglingNumber()) return LinkageInfo::none(); LV = getLVForClosure(BD->getDeclContext()->getRedeclContext(), BD->getBlockManglingContextDecl(), computation); } else { - const FunctionDecl *FD = cast<FunctionDecl>(OuterD); + const auto *FD = cast<FunctionDecl>(OuterD); if (!FD->isInlined() && !isTemplateInstantiation(FD->getTemplateSpecializationKind())) return LinkageInfo::none(); @@ -1224,13 +1223,45 @@ getOutermostEnclosingLambda(const CXXRecordDecl *Record) { static LinkageInfo computeLVForDecl(const NamedDecl *D, LVComputationKind computation) { + // Internal_linkage attribute overrides other considerations. + if (D->hasAttr<InternalLinkageAttr>()) + return LinkageInfo::internal(); + // Objective-C: treat all Objective-C declarations as having external // linkage. switch (D->getKind()) { default: break; + + // Per C++ [basic.link]p2, only the names of objects, references, + // functions, types, templates, namespaces, and values ever have linkage. + // + // Note that the name of a typedef, namespace alias, using declaration, + // and so on are not the name of the corresponding type, namespace, or + // declaration, so they do *not* have linkage. + case Decl::ImplicitParam: + case Decl::Label: + case Decl::NamespaceAlias: case Decl::ParmVar: + case Decl::Using: + case Decl::UsingShadow: + case Decl::UsingDirective: return LinkageInfo::none(); + + case Decl::EnumConstant: + // C++ [basic.link]p4: an enumerator has the linkage of its enumeration. + return getLVForDecl(cast<EnumDecl>(D->getDeclContext()), computation); + + case Decl::Typedef: + case Decl::TypeAlias: + // A typedef declaration has linkage if it gives a type a name for + // linkage purposes. + if (!D->getASTContext().getLangOpts().CPlusPlus || + !cast<TypedefNameDecl>(D) + ->getAnonDeclWithTypedefName(/*AnyRedecl*/true)) + return LinkageInfo::none(); + break; + case Decl::TemplateTemplateParm: // count these as external case Decl::NonTypeTemplateParm: case Decl::ObjCAtDefsField: @@ -1245,7 +1276,7 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D, return LinkageInfo::external(); case Decl::CXXRecord: { - const CXXRecordDecl *Record = cast<CXXRecordDecl>(D); + const auto *Record = cast<CXXRecordDecl>(D); if (Record->isLambda()) { if (!Record->getLambdaManglingNumber()) { // This lambda has no mangling number, so it's internal. @@ -1314,6 +1345,10 @@ class LinkageComputer { public: static LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation) { + // Internal_linkage attribute overrides other considerations. + if (D->hasAttr<InternalLinkageAttr>()) + return LinkageInfo::internal(); + if (computation == LVForLinkageOnly && D->hasCachedLinkage()) return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false); @@ -1336,7 +1371,7 @@ public: // computed also does. NamedDecl *Old = nullptr; for (auto I : D->redecls()) { - NamedDecl *T = cast<NamedDecl>(I); + auto *T = cast<NamedDecl>(I); if (T == D) continue; if (!T->isInvalidDecl() && T->hasCachedLinkage()) { @@ -1388,28 +1423,29 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend(); I != E; ++I) { - if (const ClassTemplateSpecializationDecl *Spec - = dyn_cast<ClassTemplateSpecializationDecl>(*I)) { + if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(*I)) { OS << Spec->getName(); const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); TemplateSpecializationType::PrintTemplateArgumentList(OS, TemplateArgs.data(), TemplateArgs.size(), P); - } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) { + } else if (const auto *ND = dyn_cast<NamespaceDecl>(*I)) { if (P.SuppressUnwrittenScope && (ND->isAnonymousNamespace() || ND->isInline())) continue; - if (ND->isAnonymousNamespace()) - OS << "(anonymous namespace)"; + if (ND->isAnonymousNamespace()) { + OS << (P.MSVCFormatting ? "`anonymous namespace\'" + : "(anonymous namespace)"); + } else OS << *ND; - } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) { + } else if (const auto *RD = dyn_cast<RecordDecl>(*I)) { if (!RD->getIdentifier()) OS << "(anonymous " << RD->getKindName() << ')'; else OS << *RD; - } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) { + } else if (const auto *FD = dyn_cast<FunctionDecl>(*I)) { const FunctionProtoType *FT = nullptr; if (FD->hasWrittenPrototype()) FT = dyn_cast<FunctionProtoType>(FD->getType()->castAs<FunctionType>()); @@ -1430,6 +1466,15 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, } } OS << ')'; + } else if (const auto *ED = dyn_cast<EnumDecl>(*I)) { + // C++ [dcl.enum]p10: Each enum-name and each unscoped + // enumerator is declared in the scope that immediately contains + // the enum-specifier. Each scoped enumerator is declared in the + // scope of the enumeration. + if (ED->isScoped() || ED->getIdentifier()) + OS << *ED; + else + continue; } else { OS << *cast<NamedDecl>(*I); } @@ -1451,32 +1496,6 @@ void NamedDecl::getNameForDiagnostic(raw_ostream &OS, printName(OS); } -static bool isKindReplaceableBy(Decl::Kind OldK, Decl::Kind NewK) { - // For method declarations, we never replace. - if (ObjCMethodDecl::classofKind(NewK)) - return false; - - if (OldK == NewK) - return true; - - // A compatibility alias for a class can be replaced by an interface. - if (ObjCCompatibleAliasDecl::classofKind(OldK) && - ObjCInterfaceDecl::classofKind(NewK)) - return true; - - // A typedef-declaration, alias-declaration, or Objective-C class declaration - // can replace another declaration of the same type. Semantic analysis checks - // that we have matching types. - if ((TypedefNameDecl::classofKind(OldK) || - ObjCInterfaceDecl::classofKind(OldK)) && - (TypedefNameDecl::classofKind(NewK) || - ObjCInterfaceDecl::classofKind(NewK))) - return true; - - // Otherwise, a kind mismatch implies that the declaration is not replaced. - return false; -} - template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { return true; } @@ -1500,9 +1519,19 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const { if (OldD->isFromASTFile() && isFromASTFile()) return false; - if (!isKindReplaceableBy(OldD->getKind(), getKind())) + // A kind mismatch implies that the declaration is not replaced. + if (OldD->getKind() != getKind()) + return false; + + // For method declarations, we never replace. (Why?) + if (isa<ObjCMethodDecl>(this)) return false; + // For parameters, pick the newer one. This is either an error or (in + // Objective-C) permitted as an extension. + if (isa<ParmVarDecl>(this)) + return true; + // Inline namespaces can give us two declarations with the same // name and kind in the same scope but different contexts; we should // keep both declarations in this case. @@ -1510,28 +1539,8 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const { OldD->getDeclContext()->getRedeclContext())) return false; - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) - // For function declarations, we keep track of redeclarations. - // FIXME: This returns false for functions that should in fact be replaced. - // Instead, perform some kind of type check? - if (FD->getPreviousDecl() != OldD) - return false; - - // For function templates, the underlying function declarations are linked. - if (const FunctionTemplateDecl *FunctionTemplate = - dyn_cast<FunctionTemplateDecl>(this)) - return FunctionTemplate->getTemplatedDecl()->declarationReplaces( - cast<FunctionTemplateDecl>(OldD)->getTemplatedDecl()); - - // Using shadow declarations can be overloaded on their target declarations - // if they introduce functions. - // FIXME: If our target replaces the old target, can we replace the old - // shadow declaration? - if (auto *USD = dyn_cast<UsingShadowDecl>(this)) - if (USD->getTargetDecl() != cast<UsingShadowDecl>(OldD)->getTargetDecl()) - return false; - - // Using declarations can be overloaded if they introduce functions. + // Using declarations can be replaced if they import the same name from the + // same context. if (auto *UD = dyn_cast<UsingDecl>(this)) { ASTContext &Context = getASTContext(); return Context.getCanonicalNestedNameSpecifier(UD->getQualifier()) == @@ -1546,13 +1555,20 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const { } // UsingDirectiveDecl's are not really NamedDecl's, and all have same name. - // We want to keep it, unless it nominates same namespace. + // They can be replaced if they nominate the same namespace. + // FIXME: Is this true even if they have different module visibility? if (auto *UD = dyn_cast<UsingDirectiveDecl>(this)) return UD->getNominatedNamespace()->getOriginalNamespace() == cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace() ->getOriginalNamespace(); - if (!IsKnownNewer && isRedeclarable(getKind())) { + if (isRedeclarable(getKind())) { + if (getCanonicalDecl() != OldD->getCanonicalDecl()) + return false; + + if (IsKnownNewer) + return true; + // Check whether this is actually newer than OldD. We want to keep the // newer declaration. This loop will usually only iterate once, because // OldD is usually the previous declaration. @@ -1567,11 +1583,16 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const { if (D->isCanonicalDecl()) return false; } + + // It's a newer declaration of the same kind of declaration in the same + // scope: we want this decl instead of the existing one. + return true; } - // It's a newer declaration of the same kind of declaration in the same scope, - // and not an overload: we want this decl instead of the existing one. - return true; + // In all other cases, we need to keep both declarations in case they have + // different visibility. Any attempt to use the name will result in an + // ambiguity if more than one is visible. + return false; } bool NamedDecl::hasLinkage() const { @@ -1580,12 +1601,15 @@ bool NamedDecl::hasLinkage() const { NamedDecl *NamedDecl::getUnderlyingDeclImpl() { NamedDecl *ND = this; - while (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND)) + while (auto *UD = dyn_cast<UsingShadowDecl>(ND)) ND = UD->getTargetDecl(); - if (ObjCCompatibleAliasDecl *AD = dyn_cast<ObjCCompatibleAliasDecl>(ND)) + if (auto *AD = dyn_cast<ObjCCompatibleAliasDecl>(ND)) return AD->getClassInterface(); + if (auto *AD = dyn_cast<NamespaceAliasDecl>(ND)) + return AD->getNamespace(); + return ND; } @@ -1599,8 +1623,7 @@ bool NamedDecl::isCXXInstanceMember() const { if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<MSPropertyDecl>(D)) return true; - if (const CXXMethodDecl *MD = - dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction())) + if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction())) return MD->isInstance(); return false; } @@ -1628,7 +1651,7 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) { // Make sure the extended decl info is allocated. if (!hasExtInfo()) { // Save (non-extended) type source info pointer. - TypeSourceInfo *savedTInfo = DeclInfo.get<TypeSourceInfo*>(); + auto *savedTInfo = DeclInfo.get<TypeSourceInfo*>(); // Allocate external info struct. DeclInfo = new (getASTContext()) ExtInfo; // Restore savedTInfo into (extended) decl info. @@ -1653,22 +1676,20 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) { } } -void -DeclaratorDecl::setTemplateParameterListsInfo(ASTContext &Context, - unsigned NumTPLists, - TemplateParameterList **TPLists) { - assert(NumTPLists > 0); +void DeclaratorDecl::setTemplateParameterListsInfo( + ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) { + assert(!TPLists.empty()); // Make sure the extended decl info is allocated. if (!hasExtInfo()) { // Save (non-extended) type source info pointer. - TypeSourceInfo *savedTInfo = DeclInfo.get<TypeSourceInfo*>(); + auto *savedTInfo = DeclInfo.get<TypeSourceInfo*>(); // Allocate external info struct. DeclInfo = new (getASTContext()) ExtInfo; // Restore savedTInfo into (extended) decl info. getExtInfo()->TInfo = savedTInfo; } // Set the template parameter lists info. - getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists); + getExtInfo()->setTemplateParameterListsInfo(Context, TPLists); } SourceLocation DeclaratorDecl::getOuterLocStart() const { @@ -1726,13 +1747,8 @@ SourceRange DeclaratorDecl::getSourceRange() const { return SourceRange(getOuterLocStart(), RangeEnd); } -void -QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context, - unsigned NumTPLists, - TemplateParameterList **TPLists) { - assert((NumTPLists == 0 || TPLists != nullptr) && - "Empty array of template parameters with positive size!"); - +void QualifierInfo::setTemplateParameterListsInfo( + ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) { // Free previous template parameters (if any). if (NumTemplParamLists > 0) { Context.Deallocate(TemplParamLists); @@ -1740,10 +1756,10 @@ QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context, NumTemplParamLists = 0; } // Set info on matched template parameter lists (if any). - if (NumTPLists > 0) { - TemplParamLists = new (Context) TemplateParameterList*[NumTPLists]; - NumTemplParamLists = NumTPLists; - std::copy(TPLists, TPLists + NumTPLists, TemplParamLists); + if (!TPLists.empty()) { + TemplParamLists = new (Context) TemplateParameterList *[TPLists.size()]; + NumTemplParamLists = TPLists.size(); + std::copy(TPLists.begin(), TPLists.end(), TemplParamLists); } } @@ -1756,7 +1772,6 @@ const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) { case SC_None: break; case SC_Auto: return "auto"; case SC_Extern: return "extern"; - case SC_OpenCLWorkGroupLocal: return "<<work-group-local>>"; case SC_PrivateExtern: return "__private_extern__"; case SC_Register: return "register"; case SC_Static: return "static"; @@ -1995,7 +2010,7 @@ VarDecl *VarDecl::getDefinition(ASTContext &C) { VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const { DefinitionKind Kind = DeclarationOnly; - + const VarDecl *First = getFirstDecl(); for (auto I : First->redecls()) { Kind = std::max(Kind, I->isThisDeclarationADefinition(C)); @@ -2016,6 +2031,31 @@ const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const { return nullptr; } +bool VarDecl::hasInit() const { + if (auto *P = dyn_cast<ParmVarDecl>(this)) + if (P->hasUnparsedDefaultArg() || P->hasUninstantiatedDefaultArg()) + return false; + + return !Init.isNull(); +} + +Expr *VarDecl::getInit() { + if (!hasInit()) + return nullptr; + + if (auto *S = Init.dyn_cast<Stmt *>()) + return cast<Expr>(S); + + return cast_or_null<Expr>(Init.get<EvaluatedStmt *>()->Value); +} + +Stmt **VarDecl::getInitAddress() { + if (auto *ES = Init.dyn_cast<EvaluatedStmt *>()) + return &ES->Value; + + return Init.getAddrOfPtr1(); +} + bool VarDecl::isOutOfLine() const { if (Decl::isOutOfLine()) return true; @@ -2045,7 +2085,7 @@ VarDecl *VarDecl::getOutOfLineDefinition() { } void VarDecl::setInit(Expr *I) { - if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) { + if (auto *Eval = Init.dyn_cast<EvaluatedStmt *>()) { Eval->~EvaluatedStmt(); getASTContext().Deallocate(Eval); } @@ -2084,15 +2124,14 @@ bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const { /// form, which contains extra information on the evaluated value of the /// initializer. EvaluatedStmt *VarDecl::ensureEvaluatedStmt() const { - EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>(); + auto *Eval = Init.dyn_cast<EvaluatedStmt *>(); if (!Eval) { - Stmt *S = Init.get<Stmt *>(); // Note: EvaluatedStmt contains an APValue, which usually holds // resources not allocated from the ASTContext. We need to do some // work to avoid leaking those, but we do so in VarDecl::evaluateValue // where we can detect whether there's anything to clean up or not. Eval = new (getASTContext()) EvaluatedStmt; - Eval->Value = S; + Eval->Value = Init.get<Stmt *>(); Init = Eval; } return Eval; @@ -2120,7 +2159,7 @@ APValue *VarDecl::evaluateValue( if (Eval->WasEvaluated) return Eval->Evaluated.isUninit() ? nullptr : &Eval->Evaluated; - const Expr *Init = cast<Expr>(Eval->Value); + const auto *Init = cast<Expr>(Eval->Value); assert(!Init->isValueDependent()); if (Eval->IsEvaluating) { @@ -2156,6 +2195,27 @@ APValue *VarDecl::evaluateValue( return Result ? &Eval->Evaluated : nullptr; } +APValue *VarDecl::getEvaluatedValue() const { + if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) + if (Eval->WasEvaluated) + return &Eval->Evaluated; + + return nullptr; +} + +bool VarDecl::isInitKnownICE() const { + if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) + return Eval->CheckedICE; + + return false; +} + +bool VarDecl::isInitICE() const { + assert(isInitKnownICE() && + "Check whether we already know that the initializer is an ICE"); + return Init.get<EvaluatedStmt *>()->IsICE; +} + bool VarDecl::checkInitIsICE() const { // Initializers of weak variables are never ICEs. if (isWeak()) @@ -2167,7 +2227,7 @@ bool VarDecl::checkInitIsICE() const { // integral constant expression. return Eval->IsICE; - const Expr *Init = cast<Expr>(Eval->Value); + const auto *Init = cast<Expr>(Eval->Value); assert(!Init->isValueDependent()); // In C++11, evaluate the initializer to check whether it's a constant @@ -2200,8 +2260,7 @@ VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const { } TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const { - if (const VarTemplateSpecializationDecl *Spec = - dyn_cast<VarTemplateSpecializationDecl>(this)) + if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this)) return Spec->getSpecializationKind(); if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) @@ -2211,8 +2270,7 @@ TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const { } SourceLocation VarDecl::getPointOfInstantiation() const { - if (const VarTemplateSpecializationDecl *Spec = - dyn_cast<VarTemplateSpecializationDecl>(this)) + if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this)) return Spec->getPointOfInstantiation(); if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) @@ -2285,7 +2343,7 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, QualType ParmVarDecl::getOriginalType() const { TypeSourceInfo *TSI = getTypeSourceInfo(); QualType T = TSI ? TSI->getType() : getType(); - if (const DecayedType *DT = dyn_cast<DecayedType>(T)) + if (const auto *DT = dyn_cast<DecayedType>(T)) return DT->getOriginalType(); return T; } @@ -2315,22 +2373,56 @@ Expr *ParmVarDecl::getDefaultArg() { assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!"); assert(!hasUninstantiatedDefaultArg() && "Default argument is not yet instantiated!"); - + Expr *Arg = getInit(); - if (ExprWithCleanups *E = dyn_cast_or_null<ExprWithCleanups>(Arg)) + if (auto *E = dyn_cast_or_null<ExprWithCleanups>(Arg)) return E->getSubExpr(); return Arg; } +void ParmVarDecl::setDefaultArg(Expr *defarg) { + ParmVarDeclBits.DefaultArgKind = DAK_Normal; + Init = defarg; +} + SourceRange ParmVarDecl::getDefaultArgRange() const { - if (const Expr *E = getInit()) - return E->getSourceRange(); + switch (ParmVarDeclBits.DefaultArgKind) { + case DAK_None: + case DAK_Unparsed: + // Nothing we can do here. + return SourceRange(); - if (hasUninstantiatedDefaultArg()) + case DAK_Uninstantiated: return getUninstantiatedDefaultArg()->getSourceRange(); - return SourceRange(); + case DAK_Normal: + if (const Expr *E = getInit()) + return E->getSourceRange(); + + // Missing an actual expression, may be invalid. + return SourceRange(); + } + llvm_unreachable("Invalid default argument kind."); +} + +void ParmVarDecl::setUninstantiatedDefaultArg(Expr *arg) { + ParmVarDeclBits.DefaultArgKind = DAK_Uninstantiated; + Init = arg; +} + +Expr *ParmVarDecl::getUninstantiatedDefaultArg() { + assert(hasUninstantiatedDefaultArg() && + "Wrong kind of initialization expression!"); + return cast_or_null<Expr>(Init.get<Stmt *>()); +} + +bool ParmVarDecl::hasDefaultArg() const { + // FIXME: We should just return false for DAK_None here once callers are + // prepared for the case that we encountered an invalid default argument and + // were unable to even build an invalid expression. + return hasUnparsedDefaultArg() || hasUninstantiatedDefaultArg() || + !Init.isNull(); } bool ParmVarDecl::isParameterPack() const { @@ -2360,7 +2452,7 @@ void FunctionDecl::getNameForDiagnostic( } bool FunctionDecl::isVariadic() const { - if (const FunctionProtoType *FT = getType()->getAs<FunctionProtoType>()) + if (const auto *FT = getType()->getAs<FunctionProtoType>()) return FT->isVariadic(); return false; } @@ -2421,7 +2513,7 @@ void FunctionDecl::setBody(Stmt *B) { void FunctionDecl::setPure(bool P) { IsPure = P; if (P) - if (CXXRecordDecl *Parent = dyn_cast<CXXRecordDecl>(getDeclContext())) + if (auto *Parent = dyn_cast<CXXRecordDecl>(getDeclContext())) Parent->markedVirtualFunctionPure(); } @@ -2476,7 +2568,7 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const { if (!getDeclContext()->getRedeclContext()->isTranslationUnit()) return false; - const FunctionProtoType *proto = getType()->castAs<FunctionProtoType>(); + const auto *proto = getType()->castAs<FunctionProtoType>(); if (proto->getNumParams() != 2 || proto->isVariadic()) return false; @@ -2505,7 +2597,7 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction() const { if (!getDeclContext()->getRedeclContext()->isTranslationUnit()) return false; - const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>(); + const auto *FPT = getType()->castAs<FunctionProtoType>(); if (FPT->getNumParams() == 0 || FPT->getNumParams() > 2 || FPT->isVariadic()) return false; @@ -2547,7 +2639,7 @@ bool FunctionDecl::isInExternCXXContext() const { } bool FunctionDecl::isGlobal() const { - if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this)) + if (const auto *Method = dyn_cast<CXXMethodDecl>(this)) return Method->isStatic(); if (getCanonicalDecl()->getStorageClass() == SC_Static) @@ -2556,7 +2648,7 @@ bool FunctionDecl::isGlobal() const { for (const DeclContext *DC = getDeclContext(); DC->isNamespace(); DC = DC->getParent()) { - if (const NamespaceDecl *Namespace = cast<NamespaceDecl>(DC)) { + if (const auto *Namespace = cast<NamespaceDecl>(DC)) { if (!Namespace->getDeclName()) return false; break; @@ -2608,8 +2700,8 @@ unsigned FunctionDecl::getBuiltinID() const { ASTContext &Context = getASTContext(); if (Context.getLangOpts().CPlusPlus) { - const LinkageSpecDecl *LinkageDecl = dyn_cast<LinkageSpecDecl>( - getFirstDecl()->getDeclContext()); + const auto *LinkageDecl = + dyn_cast<LinkageSpecDecl>(getFirstDecl()->getDeclContext()); // In C++, the first declaration of a builtin is always inside an implicit // extern "C". // FIXME: A recognised library function may not be directly in an extern "C" @@ -2649,7 +2741,7 @@ unsigned FunctionDecl::getBuiltinID() const { /// based on its FunctionType. This is the length of the ParamInfo array /// after it has been created. unsigned FunctionDecl::getNumParams() const { - const FunctionProtoType *FPT = getType()->getAs<FunctionProtoType>(); + const auto *FPT = getType()->getAs<FunctionProtoType>(); return FPT ? FPT->getNumParams() : 0; } @@ -2711,7 +2803,8 @@ bool FunctionDecl::isMSExternInline() const { assert(isInlined() && "expected to get called on an inlined function!"); const ASTContext &Context = getASTContext(); - if (!Context.getLangOpts().MSVCCompat && !hasAttr<DLLExportAttr>()) + if (!Context.getTargetInfo().getCXXABI().isMicrosoft() && + !hasAttr<DLLExportAttr>()) return false; for (const FunctionDecl *FD = getMostRecentDecl(); FD; @@ -2840,7 +2933,7 @@ bool FunctionDecl::hasUnusedResultAttr() const { QualType RetType = getReturnType(); if (RetType->isRecordType()) { const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl(); - const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(this); + const auto *MD = dyn_cast<CXXMethodDecl>(this); if (Ret && Ret->hasAttr<WarnUnusedResultAttr>() && !(MD && MD->getCorrespondingMethodInClass(Ret, true))) return true; @@ -2952,6 +3045,10 @@ FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const { return nullptr; } +MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const { + return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>(); +} + void FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD, @@ -2963,6 +3060,14 @@ FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C, TemplateOrSpecialization = Info; } +FunctionTemplateDecl *FunctionDecl::getDescribedFunctionTemplate() const { + return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl *>(); +} + +void FunctionDecl::setDescribedFunctionTemplate(FunctionTemplateDecl *Template) { + TemplateOrSpecialization = Template; +} + bool FunctionDecl::isImplicitlyInstantiable() const { // If the function is invalid, it can't be implicitly instantiated. if (isInvalidDecl()) @@ -3069,6 +3174,12 @@ FunctionDecl *FunctionDecl::getClassScopeSpecializationPattern() const { return getASTContext().getClassScopeSpecializationPattern(this); } +FunctionTemplateSpecializationInfo * +FunctionDecl::getTemplateSpecializationInfo() const { + return TemplateOrSpecialization + .dyn_cast<FunctionTemplateSpecializationInfo *>(); +} + const TemplateArgumentList * FunctionDecl::getTemplateSpecializationArgs() const { if (FunctionTemplateSpecializationInfo *Info @@ -3115,33 +3226,41 @@ FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context, const UnresolvedSetImpl &Templates, const TemplateArgumentListInfo &TemplateArgs) { assert(TemplateOrSpecialization.isNull()); - size_t Size = sizeof(DependentFunctionTemplateSpecializationInfo); - Size += Templates.size() * sizeof(FunctionTemplateDecl*); - Size += TemplateArgs.size() * sizeof(TemplateArgumentLoc); - void *Buffer = Context.Allocate(Size); DependentFunctionTemplateSpecializationInfo *Info = - new (Buffer) DependentFunctionTemplateSpecializationInfo(Templates, - TemplateArgs); + DependentFunctionTemplateSpecializationInfo::Create(Context, Templates, + TemplateArgs); TemplateOrSpecialization = Info; } +DependentFunctionTemplateSpecializationInfo * +FunctionDecl::getDependentSpecializationInfo() const { + return TemplateOrSpecialization + .dyn_cast<DependentFunctionTemplateSpecializationInfo *>(); +} + +DependentFunctionTemplateSpecializationInfo * +DependentFunctionTemplateSpecializationInfo::Create( + ASTContext &Context, const UnresolvedSetImpl &Ts, + const TemplateArgumentListInfo &TArgs) { + void *Buffer = Context.Allocate( + totalSizeToAlloc<TemplateArgumentLoc, FunctionTemplateDecl *>( + TArgs.size(), Ts.size())); + return new (Buffer) DependentFunctionTemplateSpecializationInfo(Ts, TArgs); +} + DependentFunctionTemplateSpecializationInfo:: DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts, const TemplateArgumentListInfo &TArgs) : AngleLocs(TArgs.getLAngleLoc(), TArgs.getRAngleLoc()) { - static_assert(sizeof(*this) % llvm::AlignOf<void *>::Alignment == 0, - "Trailing data is unaligned!"); - d.NumTemplates = Ts.size(); - d.NumArgs = TArgs.size(); + NumTemplates = Ts.size(); + NumArgs = TArgs.size(); - FunctionTemplateDecl **TsArray = - const_cast<FunctionTemplateDecl**>(getTemplates()); + FunctionTemplateDecl **TsArray = getTrailingObjects<FunctionTemplateDecl *>(); for (unsigned I = 0, E = Ts.size(); I != E; ++I) TsArray[I] = cast<FunctionTemplateDecl>(Ts[I]->getUnderlyingDecl()); - TemplateArgumentLoc *ArgsArray = - const_cast<TemplateArgumentLoc*>(getTemplateArgs()); + TemplateArgumentLoc *ArgsArray = getTrailingObjects<TemplateArgumentLoc>(); for (unsigned I = 0, E = TArgs.size(); I != E; ++I) new (&ArgsArray[I]) TemplateArgumentLoc(TArgs[I]); } @@ -3335,7 +3454,7 @@ bool FieldDecl::isAnonymousStructOrUnion() const { if (!isImplicit() || getDeclName()) return false; - if (const RecordType *Record = getType()->getAs<RecordType>()) + if (const auto *Record = getType()->getAs<RecordType>()) return Record->getDecl()->isAnonymousStructOrUnion(); return false; @@ -3343,7 +3462,7 @@ bool FieldDecl::isAnonymousStructOrUnion() const { unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const { assert(isBitField() && "not a bitfield"); - Expr *BitWidth = static_cast<Expr *>(InitStorage.getPointer()); + auto *BitWidth = static_cast<Expr *>(InitStorage.getPointer()); return BitWidth->EvaluateKnownConstInt(Ctx).getZExtValue(); } @@ -3372,7 +3491,7 @@ SourceRange FieldDecl::getSourceRange() const { case ISK_BitWidthOrNothing: case ISK_InClassCopyInit: case ISK_InClassListInit: - if (const Expr *E = static_cast<const Expr *>(InitStorage.getPointer())) + if (const auto *E = static_cast<const Expr *>(InitStorage.getPointer())) return SourceRange(getInnerLocStart(), E->getLocEnd()); // FALLTHROUGH @@ -3408,7 +3527,7 @@ SourceRange TagDecl::getSourceRange() const { TagDecl *TagDecl::getCanonicalDecl() { return getFirstDecl(); } void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) { - NamedDeclOrQualifier = TDD; + TypedefNameDeclOrQualifier = TDD; if (const Type *T = getTypeForDecl()) { (void)T; assert(T->isLinkageValid()); @@ -3419,7 +3538,7 @@ void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) { void TagDecl::startDefinition() { IsBeingDefined = true; - if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(this)) { + if (auto *D = dyn_cast<CXXRecordDecl>(this)) { struct CXXRecordDecl::DefinitionData *Data = new (getASTContext()) struct CXXRecordDecl::DefinitionData(D); for (auto I : redecls()) @@ -3452,7 +3571,7 @@ TagDecl *TagDecl::getDefinition() const { } } - if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this)) + if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(this)) return CXXRD->getDefinition(); for (auto R : redecls()) @@ -3466,7 +3585,7 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) { if (QualifierLoc) { // Make sure the extended qualifier info is allocated. if (!hasExtInfo()) - NamedDeclOrQualifier = new (getASTContext()) ExtInfo; + TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo; // Set qualifier info. getExtInfo()->QualifierLoc = QualifierLoc; } else { @@ -3474,7 +3593,7 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) { if (hasExtInfo()) { if (getExtInfo()->NumTemplParamLists == 0) { getASTContext().Deallocate(getExtInfo()); - NamedDeclOrQualifier = (TypedefNameDecl*)nullptr; + TypedefNameDeclOrQualifier = (TypedefNameDecl *)nullptr; } else getExtInfo()->QualifierLoc = QualifierLoc; @@ -3482,16 +3601,15 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) { } } -void TagDecl::setTemplateParameterListsInfo(ASTContext &Context, - unsigned NumTPLists, - TemplateParameterList **TPLists) { - assert(NumTPLists > 0); +void TagDecl::setTemplateParameterListsInfo( + ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) { + assert(!TPLists.empty()); // Make sure the extended decl info is allocated. if (!hasExtInfo()) // Allocate external info struct. - NamedDeclOrQualifier = new (getASTContext()) ExtInfo; + TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo; // Set the template parameter lists info. - getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists); + getExtInfo()->setTemplateParameterListsInfo(Context, TPLists); } //===----------------------------------------------------------------------===// @@ -3505,9 +3623,8 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, EnumDecl *PrevDecl, bool IsScoped, bool IsScopedUsingClassTag, bool IsFixed) { - EnumDecl *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl, - IsScoped, IsScopedUsingClassTag, - IsFixed); + auto *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl, + IsScoped, IsScopedUsingClassTag, IsFixed); Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules; C.getTypeDeclType(Enum, PrevDecl); return Enum; @@ -3647,10 +3764,6 @@ bool RecordDecl::isMsStruct(const ASTContext &C) const { return hasAttr<MSStructAttr>() || C.getLangOpts().MSBitfields == 1; } -static bool isFieldOrIndirectField(Decl::Kind K) { - return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K); -} - void RecordDecl::LoadFieldsFromExternalStorage() const { ExternalASTSource *Source = getASTContext().getExternalSource(); assert(hasExternalLexicalStorage() && Source && "No external storage?"); @@ -3659,16 +3772,10 @@ void RecordDecl::LoadFieldsFromExternalStorage() const { ExternalASTSource::Deserializing TheFields(Source); SmallVector<Decl*, 64> Decls; - LoadedFieldsFromExternalStorage = true; - switch (Source->FindExternalLexicalDecls(this, isFieldOrIndirectField, - Decls)) { - case ELR_Success: - break; - - case ELR_AlreadyLoaded: - case ELR_Failure: - return; - } + LoadedFieldsFromExternalStorage = true; + Source->FindExternalLexicalDecls(this, [](Decl::Kind K) { + return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K); + }, Decls); #ifndef NDEBUG // Check that all decls we got were FieldDecls. @@ -3690,7 +3797,7 @@ bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const { !Context.getLangOpts().SanitizeAddressFieldPadding) return false; const auto &Blacklist = Context.getSanitizerBlacklist(); - const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this); + const auto *CXXRD = dyn_cast<CXXRecordDecl>(this); // We may be able to relax some of these requirements. int ReasonToReject = -1; if (!CXXRD || CXXRD->isExternCContext()) @@ -3731,9 +3838,9 @@ const FieldDecl *RecordDecl::findFirstNamedDataMember() const { if (I->getIdentifier()) return I; - if (const RecordType *RT = I->getType()->getAs<RecordType>()) + if (const auto *RT = I->getType()->getAs<RecordType>()) if (const FieldDecl *NamedDataMember = - RT->getDecl()->findFirstNamedDataMember()) + RT->getDecl()->findFirstNamedDataMember()) return NamedDataMember; } @@ -3757,26 +3864,17 @@ void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) { } } -void BlockDecl::setCaptures(ASTContext &Context, - const Capture *begin, - const Capture *end, - bool capturesCXXThis) { - CapturesCXXThis = capturesCXXThis; +void BlockDecl::setCaptures(ASTContext &Context, ArrayRef<Capture> Captures, + bool CapturesCXXThis) { + this->CapturesCXXThis = CapturesCXXThis; + this->NumCaptures = Captures.size(); - if (begin == end) { - NumCaptures = 0; - Captures = nullptr; + if (Captures.empty()) { + this->Captures = nullptr; return; } - NumCaptures = end - begin; - - // Avoid new Capture[] because we don't want to provide a default - // constructor. - size_t allocationSize = NumCaptures * sizeof(Capture); - void *buffer = Context.Allocate(allocationSize, /*alignment*/sizeof(void*)); - memcpy(buffer, begin, allocationSize); - Captures = static_cast<Capture*>(buffer); + this->Captures = Captures.copy(Context).data(); } bool BlockDecl::capturesVariable(const VarDecl *variable) const { @@ -3889,18 +3987,28 @@ BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (C, ID) BlockDecl(nullptr, SourceLocation()); } +CapturedDecl::CapturedDecl(DeclContext *DC, unsigned NumParams) + : Decl(Captured, DC, SourceLocation()), DeclContext(Captured), + NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) {} + CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC, unsigned NumParams) { - return new (C, DC, NumParams * sizeof(ImplicitParamDecl *)) + return new (C, DC, additionalSizeToAlloc<ImplicitParamDecl *>(NumParams)) CapturedDecl(DC, NumParams); } CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, unsigned ID, unsigned NumParams) { - return new (C, ID, NumParams * sizeof(ImplicitParamDecl *)) + return new (C, ID, additionalSizeToAlloc<ImplicitParamDecl *>(NumParams)) CapturedDecl(nullptr, NumParams); } +Stmt *CapturedDecl::getBody() const { return BodyAndNothrow.getPointer(); } +void CapturedDecl::setBody(Stmt *B) { BodyAndNothrow.setPointer(B); } + +bool CapturedDecl::isNothrow() const { return BodyAndNothrow.getInt(); } +void CapturedDecl::setNothrow(bool Nothrow) { BodyAndNothrow.setInt(Nothrow); } + EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, SourceLocation L, IdentifierInfo *Id, QualType T, @@ -4042,9 +4150,9 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc, NextLocalImport() { assert(getNumModuleIdentifiers(Imported) == IdentifierLocs.size()); - SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(this + 1); - memcpy(StoredLocs, IdentifierLocs.data(), - IdentifierLocs.size() * sizeof(SourceLocation)); + auto *StoredLocs = getTrailingObjects<SourceLocation>(); + std::uninitialized_copy(IdentifierLocs.begin(), IdentifierLocs.end(), + StoredLocs); } ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc, @@ -4052,13 +4160,14 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc, : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, false), NextLocalImport() { - *reinterpret_cast<SourceLocation *>(this + 1) = EndLoc; + *getTrailingObjects<SourceLocation>() = EndLoc; } ImportDecl *ImportDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef<SourceLocation> IdentifierLocs) { - return new (C, DC, IdentifierLocs.size() * sizeof(SourceLocation)) + return new (C, DC, + additionalSizeToAlloc<SourceLocation>(IdentifierLocs.size())) ImportDecl(DC, StartLoc, Imported, IdentifierLocs); } @@ -4066,16 +4175,15 @@ ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, SourceLocation EndLoc) { - ImportDecl *Import = - new (C, DC, sizeof(SourceLocation)) ImportDecl(DC, StartLoc, - Imported, EndLoc); + ImportDecl *Import = new (C, DC, additionalSizeToAlloc<SourceLocation>(1)) + ImportDecl(DC, StartLoc, Imported, EndLoc); Import->setImplicit(); return Import; } ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, unsigned ID, unsigned NumLocations) { - return new (C, ID, NumLocations * sizeof(SourceLocation)) + return new (C, ID, additionalSizeToAlloc<SourceLocation>(NumLocations)) ImportDecl(EmptyShell()); } @@ -4083,16 +4191,14 @@ ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const { if (!ImportedAndComplete.getInt()) return None; - const SourceLocation *StoredLocs - = reinterpret_cast<const SourceLocation *>(this + 1); + const auto *StoredLocs = getTrailingObjects<SourceLocation>(); return llvm::makeArrayRef(StoredLocs, getNumModuleIdentifiers(getImportedModule())); } SourceRange ImportDecl::getSourceRange() const { if (!ImportedAndComplete.getInt()) - return SourceRange(getLocation(), - *reinterpret_cast<const SourceLocation *>(this + 1)); - + return SourceRange(getLocation(), *getTrailingObjects<SourceLocation>()); + return SourceRange(getLocation(), getIdentifierLocs().back()); } |