summaryrefslogtreecommitdiff
path: root/clang/lib/AST/DeclBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/DeclBase.cpp')
-rw-r--r--clang/lib/AST/DeclBase.cpp67
1 files changed, 59 insertions, 8 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 6ee767ccecf7..da1eadd9d931 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -240,15 +240,47 @@ TemplateDecl *Decl::getDescribedTemplate() const {
return nullptr;
}
+const TemplateParameterList *Decl::getDescribedTemplateParams() const {
+ if (auto *TD = getDescribedTemplate())
+ return TD->getTemplateParameters();
+ if (auto *CTPSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(this))
+ return CTPSD->getTemplateParameters();
+ if (auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(this))
+ return VTPSD->getTemplateParameters();
+ return nullptr;
+}
+
bool Decl::isTemplated() const {
- // A declaration is dependent if it is a template or a template pattern, or
+ // 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?
if (auto *AsDC = dyn_cast<DeclContext>(this))
return AsDC->isDependentContext();
auto *DC = getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext();
- return DC->isDependentContext() || isTemplateDecl() || getDescribedTemplate();
+ return DC->isDependentContext() || isTemplateDecl() ||
+ getDescribedTemplateParams();
+}
+
+unsigned Decl::getTemplateDepth() const {
+ if (auto *DC = dyn_cast<DeclContext>(this))
+ if (DC->isFileContext())
+ return 0;
+
+ if (auto *TPL = getDescribedTemplateParams())
+ return TPL->getDepth() + 1;
+
+ // If this is a dependent lambda, there might be an enclosing variable
+ // template. In this case, the next step is not the parent DeclContext (or
+ // even a DeclContext at all).
+ auto *RD = dyn_cast<CXXRecordDecl>(this);
+ if (RD && RD->isDependentLambda())
+ if (Decl *Context = RD->getLambdaContextDecl())
+ return Context->getTemplateDepth();
+
+ const DeclContext *DC =
+ getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext();
+ return cast<Decl>(DC)->getTemplateDepth();
}
const DeclContext *Decl::getParentFunctionOrMethod() const {
@@ -332,13 +364,18 @@ void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
}
}
-bool Decl::isLexicallyWithinFunctionOrMethod() const {
+bool Decl::isInLocalScopeForInstantiation() const {
const DeclContext *LDC = getLexicalDeclContext();
+ if (!LDC->isDependentContext())
+ return false;
while (true) {
if (LDC->isFunctionOrMethod())
return true;
if (!isa<TagDecl>(LDC))
return false;
+ if (const auto *CRD = dyn_cast<CXXRecordDecl>(LDC))
+ if (CRD->isLambda())
+ return true;
LDC = LDC->getLexicalParent();
}
return false;
@@ -378,6 +415,12 @@ ASTContext &Decl::getASTContext() const {
return getTranslationUnitDecl()->getASTContext();
}
+/// Helper to get the language options from the ASTContext.
+/// Defined out of line to avoid depending on ASTContext.h.
+const LangOptions &Decl::getLangOpts() const {
+ return getASTContext().getLangOpts();
+}
+
ASTMutationListener *Decl::getASTMutationListener() const {
return getASTContext().getASTMutationListener();
}
@@ -390,8 +433,10 @@ unsigned Decl::getMaxAlignment() const {
const AttrVec &V = getAttrs();
ASTContext &Ctx = getASTContext();
specific_attr_iterator<AlignedAttr> I(V.begin()), E(V.end());
- for (; I != E; ++I)
- Align = std::max(Align, I->getAlignment(Ctx));
+ for (; I != E; ++I) {
+ if (!I->isAlignmentErrorDependent())
+ Align = std::max(Align, I->getAlignment(Ctx));
+ }
return Align;
}
@@ -454,7 +499,8 @@ ExternalSourceSymbolAttr *Decl::getExternalSourceSymbolAttr() const {
}
bool Decl::hasDefiningAttr() const {
- return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>();
+ return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>() ||
+ hasAttr<LoaderUninitializedAttr>();
}
const Attr *Decl::getDefiningAttr() const {
@@ -462,6 +508,8 @@ const Attr *Decl::getDefiningAttr() const {
return AA;
if (auto *IFA = getAttr<IFuncAttr>())
return IFA;
+ if (auto *NZA = getAttr<LoaderUninitializedAttr>())
+ return NZA;
return nullptr;
}
@@ -587,7 +635,7 @@ AvailabilityResult Decl::getAvailability(std::string *Message,
continue;
if (Message)
- ResultMessage = Deprecated->getMessage();
+ ResultMessage = std::string(Deprecated->getMessage());
Result = AR_Deprecated;
continue;
@@ -595,7 +643,7 @@ AvailabilityResult Decl::getAvailability(std::string *Message,
if (const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
if (Message)
- *Message = Unavailable->getMessage();
+ *Message = std::string(Unavailable->getMessage());
return AR_Unavailable;
}
@@ -786,6 +834,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case TranslationUnit:
case ExternCContext:
case Decomposition:
+ case MSGuid:
case UsingDirective:
case BuiltinTemplate:
@@ -804,6 +853,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case OMPCapturedExpr:
case Empty:
case LifetimeExtendedTemporary:
+ case RequiresExprBody:
// Never looked up by name.
return 0;
}
@@ -1177,6 +1227,7 @@ DeclContext *DeclContext::getPrimaryContext() {
case Decl::Captured:
case Decl::OMPDeclareReduction:
case Decl::OMPDeclareMapper:
+ case Decl::RequiresExprBody:
// There is only one DeclContext for these entities.
return this;