aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-28 21:23:03 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-28 21:23:03 +0000
commit55e6d896ad333f07bb3b1ba487df214fc268a4ab (patch)
tree9ac2087dfbe8507c56dd39d17cad42836448829f /lib/AST
parent1de93ee5610e8a97e753c881c574f8d994e71373 (diff)
downloadsrc-55e6d896ad333f07bb3b1ba487df214fc268a4ab.tar.gz
src-55e6d896ad333f07bb3b1ba487df214fc268a4ab.zip
Notes
Notes: svn path=/vendor/clang/dist/; revision=327302 svn path=/vendor/clang/clang-trunk-r321545/; revision=327322; tag=vendor/clang/clang-trunk-r321545
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTImporter.cpp131
-rw-r--r--lib/AST/Decl.cpp2
-rw-r--r--lib/AST/Stmt.cpp43
3 files changed, 152 insertions, 24 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 0e627f9737ce..0d1d9807549f 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -134,12 +134,17 @@ namespace clang {
bool ImportTemplateArguments(const TemplateArgument *FromArgs,
unsigned NumFromArgs,
SmallVectorImpl<TemplateArgument> &ToArgs);
+ template <typename InContainerTy>
+ bool ImportTemplateArgumentListInfo(const InContainerTy &Container,
+ TemplateArgumentListInfo &ToTAInfo);
bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
bool Complain = true);
bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
bool Complain = true);
bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC);
+ bool IsStructuralMatch(FunctionTemplateDecl *From,
+ FunctionTemplateDecl *To);
bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To);
Decl *VisitDecl(Decl *D);
@@ -195,6 +200,7 @@ namespace clang {
ClassTemplateSpecializationDecl *D);
Decl *VisitVarTemplateDecl(VarTemplateDecl *D);
Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
+ Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
// Importing statements
DeclGroupRef ImportDeclGroup(DeclGroupRef DG);
@@ -280,6 +286,7 @@ namespace clang {
Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E);
Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
+ Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Expr *VisitExprWithCleanups(ExprWithCleanups *EWC);
Expr *VisitCXXThisExpr(CXXThisExpr *E);
Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
@@ -1247,6 +1254,18 @@ bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs,
return false;
}
+template <typename InContainerTy>
+bool ASTNodeImporter::ImportTemplateArgumentListInfo(
+ const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) {
+ for (const auto &FromLoc : Container) {
+ if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc))
+ ToTAInfo.addArgument(*ToLoc);
+ else
+ return true;
+ }
+ return false;
+}
+
bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
RecordDecl *ToRecord, bool Complain) {
// Eliminate a potential failure point where we attempt to re-import
@@ -1280,6 +1299,14 @@ bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
}
+bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From,
+ FunctionTemplateDecl *To) {
+ StructuralEquivalenceContext Ctx(
+ Importer.getFromContext(), Importer.getToContext(),
+ Importer.getNonEquivalentDecls(), false, false);
+ return Ctx.IsStructurallyEquivalent(From, To);
+}
+
bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC,
EnumConstantDecl *ToEC)
{
@@ -4197,6 +4224,64 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
return D2;
}
+Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ NamedDecl *ToD;
+
+ if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return nullptr;
+
+ if (ToD)
+ return ToD;
+
+ // Try to find a function in our own ("to") context with the same name, same
+ // type, and in the same context as the function we're importing.
+ if (!LexicalDC->isFunctionOrMethod()) {
+ unsigned IDNS = Decl::IDNS_Ordinary;
+ SmallVector<NamedDecl *, 2> FoundDecls;
+ DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
+ if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
+ continue;
+
+ if (FunctionTemplateDecl *FoundFunction =
+ dyn_cast<FunctionTemplateDecl>(FoundDecls[I])) {
+ if (FoundFunction->hasExternalFormalLinkage() &&
+ D->hasExternalFormalLinkage()) {
+ if (IsStructuralMatch(D, FoundFunction)) {
+ Importer.Imported(D, FoundFunction);
+ // FIXME: Actually try to merge the body and other attributes.
+ return FoundFunction;
+ }
+ }
+ }
+ }
+ }
+
+ TemplateParameterList *Params =
+ ImportTemplateParameterList(D->getTemplateParameters());
+ if (!Params)
+ return nullptr;
+
+ FunctionDecl *TemplatedFD =
+ cast_or_null<FunctionDecl>(Importer.Import(D->getTemplatedDecl()));
+ if (!TemplatedFD)
+ return nullptr;
+
+ FunctionTemplateDecl *ToFunc = FunctionTemplateDecl::Create(
+ Importer.getToContext(), DC, Loc, Name, Params, TemplatedFD);
+
+ TemplatedFD->setDescribedFunctionTemplate(ToFunc);
+ ToFunc->setAccess(D->getAccess());
+ ToFunc->setLexicalDeclContext(LexicalDC);
+ Importer.Imported(D, ToFunc);
+
+ LexicalDC->addDeclInternal(ToFunc);
+ return ToFunc;
+}
+
//----------------------------------------------------------------------------
// Import Statements
//----------------------------------------------------------------------------
@@ -4321,9 +4406,8 @@ Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc());
SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc());
- return new (Importer.getToContext()) CompoundStmt(Importer.getToContext(),
- ToStmts,
- ToLBraceLoc, ToRBraceLoc);
+ return CompoundStmt::Create(Importer.getToContext(), ToStmts, ToLBraceLoc,
+ ToRBraceLoc);
}
Stmt *ASTNodeImporter::VisitCaseStmt(CaseStmt *S) {
@@ -5759,6 +5843,47 @@ Expr *ASTNodeImporter::VisitCXXPseudoDestructorExpr(
Importer.Import(E->getTildeLoc()), Storage);
}
+Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
+ CXXDependentScopeMemberExpr *E) {
+ Expr *Base = nullptr;
+ if (!E->isImplicitAccess()) {
+ Base = Importer.Import(E->getBase());
+ if (!Base)
+ return nullptr;
+ }
+
+ QualType BaseType = Importer.Import(E->getBaseType());
+ if (BaseType.isNull())
+ return nullptr;
+
+ TemplateArgumentListInfo ToTAInfo(Importer.Import(E->getLAngleLoc()),
+ Importer.Import(E->getRAngleLoc()));
+ TemplateArgumentListInfo *ResInfo = nullptr;
+ if (E->hasExplicitTemplateArgs()) {
+ if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
+ return nullptr;
+ ResInfo = &ToTAInfo;
+ }
+
+ DeclarationName Name = Importer.Import(E->getMember());
+ if (!E->getMember().isEmpty() && Name.isEmpty())
+ return nullptr;
+
+ DeclarationNameInfo MemberNameInfo(Name, Importer.Import(E->getMemberLoc()));
+ // Import additional name location/type info.
+ ImportDeclarationNameLoc(E->getMemberNameInfo(), MemberNameInfo);
+ auto ToFQ = Importer.Import(E->getFirstQualifierFoundInScope());
+ if (!ToFQ && E->getFirstQualifierFoundInScope())
+ return nullptr;
+
+ return CXXDependentScopeMemberExpr::Create(
+ Importer.getToContext(), Base, BaseType, E->isArrow(),
+ Importer.Import(E->getOperatorLoc()),
+ Importer.Import(E->getQualifierLoc()),
+ Importer.Import(E->getTemplateKeywordLoc()),
+ cast_or_null<NamedDecl>(ToFQ), MemberNameInfo, ResInfo);
+}
+
Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 629037b1755c..4c1d591b41e9 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1550,7 +1550,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
// the enum-specifier. Each scoped enumerator is declared in the
// scope of the enumeration.
// For the case of unscoped enumerator, do not include in the qualified
- // name any information about its enum enclosing scope, as is visibility
+ // name any information about its enum enclosing scope, as its visibility
// is global.
if (ED->isScoped())
OS << *ED;
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 8d240c1336ab..982fd458493f 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -299,31 +299,34 @@ SourceLocation Stmt::getLocEnd() const {
llvm_unreachable("unknown statement kind");
}
-CompoundStmt::CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
- SourceLocation LB, SourceLocation RB)
- : Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
+CompoundStmt::CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB,
+ SourceLocation RB)
+ : Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
CompoundStmtBits.NumStmts = Stmts.size();
+ setStmts(Stmts);
+}
+
+void CompoundStmt::setStmts(ArrayRef<Stmt *> Stmts) {
assert(CompoundStmtBits.NumStmts == Stmts.size() &&
"NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
- if (Stmts.empty()) {
- Body = nullptr;
- return;
- }
-
- Body = new (C) Stmt*[Stmts.size()];
- std::copy(Stmts.begin(), Stmts.end(), Body);
+ std::copy(Stmts.begin(), Stmts.end(), body_begin());
}
-void CompoundStmt::setStmts(const ASTContext &C, ArrayRef<Stmt *> Stmts) {
- if (Body)
- C.Deallocate(Body);
- CompoundStmtBits.NumStmts = Stmts.size();
- assert(CompoundStmtBits.NumStmts == Stmts.size() &&
- "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
+CompoundStmt *CompoundStmt::Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
+ SourceLocation LB, SourceLocation RB) {
+ void *Mem =
+ C.Allocate(totalSizeToAlloc<Stmt *>(Stmts.size()), alignof(CompoundStmt));
+ return new (Mem) CompoundStmt(Stmts, LB, RB);
+}
- Body = new (C) Stmt*[Stmts.size()];
- std::copy(Stmts.begin(), Stmts.end(), Body);
+CompoundStmt *CompoundStmt::CreateEmpty(const ASTContext &C,
+ unsigned NumStmts) {
+ void *Mem =
+ C.Allocate(totalSizeToAlloc<Stmt *>(NumStmts), alignof(CompoundStmt));
+ CompoundStmt *New = new (Mem) CompoundStmt(EmptyShell());
+ New->CompoundStmtBits.NumStmts = NumStmts;
+ return New;
}
const char *LabelStmt::getName() const {
@@ -334,7 +337,7 @@ AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc,
ArrayRef<const Attr*> Attrs,
Stmt *SubStmt) {
assert(!Attrs.empty() && "Attrs should not be empty");
- void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * Attrs.size(),
+ void *Mem = C.Allocate(totalSizeToAlloc<const Attr *>(Attrs.size()),
alignof(AttributedStmt));
return new (Mem) AttributedStmt(Loc, Attrs, SubStmt);
}
@@ -342,7 +345,7 @@ AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc,
AttributedStmt *AttributedStmt::CreateEmpty(const ASTContext &C,
unsigned NumAttrs) {
assert(NumAttrs > 0 && "NumAttrs should be greater than zero");
- void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * NumAttrs,
+ void *Mem = C.Allocate(totalSizeToAlloc<const Attr *>(NumAttrs),
alignof(AttributedStmt));
return new (Mem) AttributedStmt(EmptyShell(), NumAttrs);
}