diff options
Diffstat (limited to 'clang/lib/AST/DeclBase.cpp')
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index d12330de1500..c94fc602155b 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -152,6 +152,15 @@ void Decl::setInvalidDecl(bool Invalid) { } } +bool DeclContext::hasValidDeclKind() const { + switch (getDeclKind()) { +#define DECL(DERIVED, BASE) case Decl::DERIVED: return true; +#define ABSTRACT_DECL(DECL) +#include "clang/AST/DeclNodes.inc" + } + return false; +} + const char *DeclContext::getDeclKindName() const { switch (getDeclKind()) { #define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED; @@ -252,12 +261,12 @@ const TemplateParameterList *Decl::getDescribedTemplateParams() const { bool Decl::isTemplated() const { // A declaration is templated if it is a template or a template pattern, or - // is within (lexcially for a friend, semantically otherwise) a dependent - // context. - // FIXME: Should local extern declarations be treated like friends? + // is within (lexcially for a friend or local function declaration, + // semantically otherwise) a dependent context. if (auto *AsDC = dyn_cast<DeclContext>(this)) return AsDC->isDependentContext(); - auto *DC = getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext(); + auto *DC = getFriendObjectKind() || isLocalExternDecl() + ? getLexicalDeclContext() : getDeclContext(); return DC->isDependentContext() || isTemplateDecl() || getDescribedTemplateParams(); } @@ -286,8 +295,7 @@ unsigned Decl::getTemplateDepth() const { const DeclContext *Decl::getParentFunctionOrMethod(bool LexicalParent) const { for (const DeclContext *DC = LexicalParent ? getLexicalDeclContext() : getDeclContext(); - DC && !DC->isTranslationUnit() && !DC->isNamespace(); - DC = DC->getParent()) + DC && !DC->isFileContext(); DC = DC->getParent()) if (DC->isFunctionOrMethod()) return DC; @@ -397,6 +405,11 @@ bool Decl::isInStdNamespace() const { return DC && DC->isStdNamespace(); } +bool Decl::isFileContextDecl() const { + const auto *DC = dyn_cast<DeclContext>(this); + return DC && DC->isFileContext(); +} + TranslationUnitDecl *Decl::getTranslationUnitDecl() { if (auto *TUD = dyn_cast<TranslationUnitDecl>(this)) return TUD; @@ -750,6 +763,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case ObjCMethod: case ObjCProperty: case MSProperty: + case HLSLBuffer: return IDNS_Ordinary; case Label: return IDNS_Label; @@ -829,6 +843,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case LinkageSpec: case Export: case FileScopeAsm: + case TopLevelStmt: case StaticAssert: case ObjCPropertyImpl: case PragmaComment: @@ -860,6 +875,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case Empty: case LifetimeExtendedTemporary: case RequiresExprBody: + case ImplicitConceptSpecialization: // Never looked up by name. return 0; } @@ -1032,6 +1048,11 @@ const FunctionType *Decl::getFunctionType(bool BlocksToo) const { return Ty->getAs<FunctionType>(); } +DeclContext *Decl::getNonTransparentDeclContext() { + assert(getDeclContext()); + return getDeclContext()->getNonTransparentContext(); +} + /// Starting at a given context (a Decl or DeclContext), look for a /// code context that is not a closure (a lambda, block, etc.). template <class T> static Decl *getNonClosureContext(T *D) { @@ -1188,7 +1209,7 @@ bool DeclContext::isTransparentContext() const { if (getDeclKind() == Decl::Enum) return !cast<EnumDecl>(this)->isScoped(); - return getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export; + return isa<LinkageSpecDecl, ExportDecl, HLSLBufferDecl>(this); } static bool isLinkageSpecContext(const DeclContext *DC, @@ -1253,6 +1274,15 @@ DeclContext *DeclContext::getPrimaryContext() { // There is only one DeclContext for these entities. return this; + case Decl::HLSLBuffer: + // Each buffer, even with the same name, is a distinct construct. + // Multiple buffers with the same name are allowed for backward + // compatibility. + // As long as buffers have unique resource bindings the names don't matter. + // The names get exposed via the CPU-side reflection API which + // supports querying bindings, so we cannot remove them. + return this; + case Decl::TranslationUnit: return static_cast<TranslationUnitDecl *>(this)->getFirstDecl(); case Decl::Namespace: @@ -1766,7 +1796,8 @@ void DeclContext::localUncachedLookup(DeclarationName Name, if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) { lookup_result LookupResults = lookup(Name); Results.insert(Results.end(), LookupResults.begin(), LookupResults.end()); - return; + if (!Results.empty()) + return; } // If we have a lookup table, check there first. Maybe we'll get lucky. |