aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp75
1 files changed, 59 insertions, 16 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 21cf9da18a8b..80235d8496d2 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1385,7 +1385,8 @@ LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D,
case Decl::CXXRecord: {
const auto *Record = cast<CXXRecordDecl>(D);
if (Record->isLambda()) {
- if (!Record->getLambdaManglingNumber()) {
+ if (Record->hasKnownLambdaInternalLinkage() ||
+ !Record->getLambdaManglingNumber()) {
// This lambda has no mangling number, so it's internal.
return getInternalLinkageFor(D);
}
@@ -1402,7 +1403,8 @@ LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D,
// };
const CXXRecordDecl *OuterMostLambda =
getOutermostEnclosingLambda(Record);
- if (!OuterMostLambda->getLambdaManglingNumber())
+ if (OuterMostLambda->hasKnownLambdaInternalLinkage() ||
+ !OuterMostLambda->getLambdaManglingNumber())
return getInternalLinkageFor(D);
return getLVForClosure(
@@ -1558,6 +1560,24 @@ void NamedDecl::printQualifiedName(raw_ostream &OS) const {
void NamedDecl::printQualifiedName(raw_ostream &OS,
const PrintingPolicy &P) const {
+ if (getDeclContext()->isFunctionOrMethod()) {
+ // We do not print '(anonymous)' for function parameters without name.
+ printName(OS);
+ return;
+ }
+ printNestedNameSpecifier(OS, P);
+ if (getDeclName() || isa<DecompositionDecl>(this))
+ OS << *this;
+ else
+ OS << "(anonymous)";
+}
+
+void NamedDecl::printNestedNameSpecifier(raw_ostream &OS) const {
+ printNestedNameSpecifier(OS, getASTContext().getPrintingPolicy());
+}
+
+void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
+ const PrintingPolicy &P) const {
const DeclContext *Ctx = getDeclContext();
// For ObjC methods and properties, look through categories and use the
@@ -1571,10 +1591,8 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
Ctx = ID;
}
- if (Ctx->isFunctionOrMethod()) {
- printName(OS);
+ if (Ctx->isFunctionOrMethod())
return;
- }
using ContextsTy = SmallVector<const DeclContext *, 8>;
ContextsTy Contexts;
@@ -1644,11 +1662,6 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
}
OS << "::";
}
-
- if (getDeclName() || isa<DecompositionDecl>(this))
- OS << *this;
- else
- OS << "(anonymous)";
}
void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
@@ -2220,6 +2233,22 @@ Stmt **VarDecl::getInitAddress() {
return Init.getAddrOfPtr1();
}
+VarDecl *VarDecl::getInitializingDeclaration() {
+ VarDecl *Def = nullptr;
+ for (auto I : redecls()) {
+ if (I->hasInit())
+ return I;
+
+ if (I->isThisDeclarationADefinition()) {
+ if (isStaticDataMember())
+ return I;
+ else
+ Def = I;
+ }
+ }
+ return Def;
+}
+
bool VarDecl::isOutOfLine() const {
if (Decl::isOutOfLine())
return true;
@@ -2565,6 +2594,18 @@ bool VarDecl::isNoDestroy(const ASTContext &Ctx) const {
!hasAttr<AlwaysDestroyAttr>()));
}
+QualType::DestructionKind
+VarDecl::needsDestruction(const ASTContext &Ctx) const {
+ if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+ if (Eval->HasConstantDestruction)
+ return QualType::DK_none;
+
+ if (isNoDestroy(Ctx))
+ return QualType::DK_none;
+
+ return getType().isDestructedType();
+}
+
MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const {
if (isStaticDataMember())
// FIXME: Remove ?
@@ -2950,8 +2991,7 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const
Ty = Ty->getPointeeType();
if (Ty.getCVRQualifiers() != Qualifiers::Const)
return false;
- const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
- if (RD && isNamed(RD, "nothrow_t") && RD->isInStdNamespace())
+ if (Ty->isNothrowT())
Consume();
}
@@ -3235,6 +3275,9 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
return true;
}
+ if (Context.getLangOpts().CPlusPlus)
+ return false;
+
if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()) {
// With GNU inlining, a declaration with 'inline' but not 'extern', forces
// an externally visible definition.
@@ -3263,9 +3306,6 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
return FoundBody;
}
- if (Context.getLangOpts().CPlusPlus)
- 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,
@@ -3332,7 +3372,8 @@ SourceRange FunctionDecl::getExceptionSpecSourceRange() const {
/// an externally visible symbol, but "extern inline" will not create an
/// externally visible symbol.
bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
- assert((doesThisDeclarationHaveABody() || willHaveBody()) &&
+ assert((doesThisDeclarationHaveABody() || willHaveBody() ||
+ hasAttr<AliasAttr>()) &&
"Must be a function definition");
assert(isInlined() && "Function must be inline");
ASTContext &Context = getASTContext();
@@ -3344,6 +3385,8 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
// If it's not the case that both 'inline' and 'extern' are
// specified on the definition, then this inline definition is
// externally visible.
+ if (Context.getLangOpts().CPlusPlus)
+ return false;
if (!(isInlineSpecified() && getStorageClass() == SC_Extern))
return true;