diff options
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 143 |
1 files changed, 112 insertions, 31 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 4c1d591b41e9c..3b9b85a20af6f 100644 --- a/lib/AST/Decl.cpp +++ b/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())); @@ -779,7 +798,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, // unique-external linkage, it's not legally usable from outside // this translation unit. However, we should use the C linkage // rules instead for extern "C" declarations. - if (Context.getLangOpts().CPlusPlus && !Function->isInExternCContext()) { + if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Function)) { // Only look at the type-as-written. Otherwise, deducing the return type // of a function could change its linkage. QualType TypeAsWritten = Function->getType(); @@ -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)) { @@ -1165,7 +1193,7 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, LVComputationKind computation) { if (const auto *Function = dyn_cast<FunctionDecl>(D)) { if (Function->isInAnonymousNamespace() && - !Function->isInExternCContext()) + !isFirstInExternCContext(Function)) return getInternalLinkageFor(Function); // This is a "void f();" which got merged with a file static. @@ -1188,7 +1216,7 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, if (const auto *Var = dyn_cast<VarDecl>(D)) { if (Var->hasExternalStorage()) { - if (Var->isInAnonymousNamespace() && !Var->isInExternCContext()) + if (Var->isInAnonymousNamespace() && !isFirstInExternCContext(Var)) return getInternalLinkageFor(Var); LinkageInfo LV; @@ -1497,9 +1525,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(); } @@ -2403,6 +2432,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 +2873,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); @@ -2844,7 +2898,7 @@ FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { 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 +2955,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 +3000,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() @@ -2988,7 +3049,7 @@ static bool RedeclForcesDefC99(const FunctionDecl *Redecl) { 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 @@ -3103,7 +3164,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. @@ -3605,16 +3666,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 +3722,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 +3973,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 +3995,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 +4448,7 @@ bool TypedefNameDecl::isTransparentTagSlow() const { }; bool isTransparent = determineIsTransparent(); - CacheIsTransparentTag = 1; - if (isTransparent) - CacheIsTransparentTag |= 0x2; + MaybeModedTInfo.setInt((isTransparent << 1) | 1); return isTransparent; } @@ -4433,7 +4514,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; |