Skip to content

Commit

Permalink
Merged master:bb4b70f79215 into amd-gfx:10744143d422
Browse files Browse the repository at this point in the history
Local branch amd-gfx 1074414 Merged master:ac3e720dc1af into amd-gfx:58d3a7df8949
Remote branch master bb4b70f [llvm-install-name-tool] Adds docs for llvm-install-name-tool
  • Loading branch information
Sw authored and Sw committed Aug 7, 2020
2 parents 1074414 + bb4b70f commit 2b82436
Show file tree
Hide file tree
Showing 87 changed files with 1,576 additions and 508 deletions.
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -2005,6 +2005,8 @@ def err_init_conversion_failed : Error<
"|: different return type%diff{ ($ vs $)|}5,6"
"|: different qualifiers (%5 vs %6)"
"|: different exception specifications}4">;
def note_forward_class_conversion : Note<"%0 is not defined, but forward "
"declared here; conversion would be valid if it's derived from %1">;

def err_lvalue_to_rvalue_ref : Error<"rvalue reference %diff{to type $ cannot "
"bind to lvalue of type $|cannot bind to incompatible lvalue}0,1">;
Expand Down
70 changes: 62 additions & 8 deletions clang/include/clang/Tooling/Syntax/Nodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,13 @@ enum class NodeKind : uint16_t {
TrailingReturnType,
ParametersAndQualifiers,
MemberPointer,
UnqualifiedId,
// Nested Name Specifiers.
NestedNameSpecifier,
NameSpecifier,
UnqualifiedId
GlobalNameSpecifier,
DecltypeNameSpecifier,
IdentifierNameSpecifier,
SimpleTemplateNameSpecifier
};
/// For debugging purposes.
raw_ostream &operator<<(raw_ostream &OS, NodeKind K);
Expand Down Expand Up @@ -138,6 +142,7 @@ enum class NodeRole : uint8_t {
/// Tokens or Keywords
ArrowToken,
ExternKeyword,
TemplateKeyword,
/// An inner statement for those that have only a single child of kind
/// statement, e.g. loop body for while, for, etc; inner statement for case,
/// default, etc.
Expand Down Expand Up @@ -167,6 +172,7 @@ enum class NodeRole : uint8_t {
IdExpression_id,
IdExpression_qualifier,
NestedNameSpecifier_specifier,
NestedNameSpecifier_delimiter,
ParenExpression_subExpression
};
/// For debugging purposes.
Expand Down Expand Up @@ -195,12 +201,60 @@ class Expression : public Tree {
};

/// A sequence of these specifiers make a `nested-name-specifier`.
/// e.g. the `std::` or `vector<int>::` in `std::vector<int>::size`.
class NameSpecifier final : public Tree {
/// e.g. the `std` or `vector<int>` in `std::vector<int>::size`.
class NameSpecifier : public Tree {
public:
NameSpecifier() : Tree(NodeKind::NameSpecifier) {}
NameSpecifier(NodeKind K) : Tree(K) {}
static bool classof(const Node *N) {
return N->kind() == NodeKind::NameSpecifier;
return N->kind() == NodeKind::GlobalNameSpecifier ||
N->kind() == NodeKind::DecltypeNameSpecifier ||
N->kind() == NodeKind::IdentifierNameSpecifier ||
N->kind() == NodeKind::SimpleTemplateNameSpecifier;
}
};

/// The global namespace name specifier, this specifier doesn't correspond to a
/// token instead an absence of tokens before a `::` characterizes it, in
/// `::std::vector<int>` it would be characterized by the absence of a token
/// before the first `::`
class GlobalNameSpecifier final : public NameSpecifier {
public:
GlobalNameSpecifier() : NameSpecifier(NodeKind::GlobalNameSpecifier) {}
static bool classof(const Node *N) {
return N->kind() == NodeKind::GlobalNameSpecifier;
}
};

/// A name specifier holding a decltype, of the form: `decltype ( expression ) `
/// e.g. the `decltype(s)` in `decltype(s)::size`.
class DecltypeNameSpecifier final : public NameSpecifier {
public:
DecltypeNameSpecifier() : NameSpecifier(NodeKind::DecltypeNameSpecifier) {}
static bool classof(const Node *N) {
return N->kind() == NodeKind::DecltypeNameSpecifier;
}
};

/// A identifier name specifier, of the form `identifier`
/// e.g. the `std` in `std::vector<int>::size`.
class IdentifierNameSpecifier final : public NameSpecifier {
public:
IdentifierNameSpecifier()
: NameSpecifier(NodeKind::IdentifierNameSpecifier) {}
static bool classof(const Node *N) {
return N->kind() == NodeKind::IdentifierNameSpecifier;
}
};

/// A name specifier with a simple-template-id, of the form `template_opt
/// identifier < template-args >` e.g. the `vector<int>` in
/// `std::vector<int>::size`.
class SimpleTemplateNameSpecifier final : public NameSpecifier {
public:
SimpleTemplateNameSpecifier()
: NameSpecifier(NodeKind::SimpleTemplateNameSpecifier) {}
static bool classof(const Node *N) {
return N->kind() == NodeKind::SimpleTemplateNameSpecifier;
}
};

Expand All @@ -213,6 +267,7 @@ class NestedNameSpecifier final : public Tree {
return N->kind() <= NodeKind::NestedNameSpecifier;
}
std::vector<NameSpecifier *> specifiers();
std::vector<Leaf *> delimiters();
};

/// Models an `unqualified-id`. C++ [expr.prim.id.unqual]
Expand All @@ -239,8 +294,7 @@ class IdExpression final : public Expression {
return N->kind() == NodeKind::IdExpression;
}
NestedNameSpecifier *qualifier();
// TODO after expose `id-expression` from `DependentScopeDeclRefExpr`:
// Add accessor for `template_opt`.
Leaf *templateKeyword();
UnqualifiedId *unqualifiedId();
};

Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8707,6 +8707,16 @@ static void emitBadConversionNotes(Sema &S, const InitializedEntity &entity,
if (entity.getKind() == InitializedEntity::EK_Result)
S.EmitRelatedResultTypeNoteForReturn(destType);
}
QualType fromType = op->getType();
auto *fromDecl = fromType.getTypePtr()->getPointeeCXXRecordDecl();
auto *destDecl = destType.getTypePtr()->getPointeeCXXRecordDecl();
if (fromDecl && destDecl && fromDecl->getDeclKind() == Decl::CXXRecord &&
destDecl->getDeclKind() == Decl::CXXRecord &&
!fromDecl->isInvalidDecl() && !destDecl->isInvalidDecl() &&
!fromDecl->hasDefinition())
S.Diag(fromDecl->getLocation(), diag::note_forward_class_conversion)
<< S.getASTContext().getTagDeclType(fromDecl)
<< S.getASTContext().getTagDeclType(destDecl);
}

static void diagnoseListInit(Sema &S, const InitializedEntity &Entity,
Expand Down
143 changes: 114 additions & 29 deletions clang/lib/Tooling/Syntax/BuildTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,11 @@ class syntax::TreeBuilder {
foldNode(Range, New, nullptr);
}

void foldNode(ArrayRef<syntax::Token> Range, syntax::Tree *New,
NestedNameSpecifierLoc L) {
// FIXME: add mapping for NestedNameSpecifierLoc
foldNode(Range, New, nullptr);
}
/// Notifies that we should not consume trailing semicolon when computing
/// token range of \p D.
void noticeDeclWithoutSemicolon(Decl *D);
Expand Down Expand Up @@ -690,21 +695,6 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
return true;
}

syntax::NestedNameSpecifier *
BuildNestedNameSpecifier(NestedNameSpecifierLoc QualifierLoc) {
if (!QualifierLoc)
return nullptr;
for (auto it = QualifierLoc; it; it = it.getPrefix()) {
auto *NS = new (allocator()) syntax::NameSpecifier;
Builder.foldNode(Builder.getRange(it.getLocalSourceRange()), NS, nullptr);
Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier);
}
auto *NNS = new (allocator()) syntax::NestedNameSpecifier;
Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS,
nullptr);
return NNS;
}

bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) {
// The semantic AST node `UserDefinedLiteral` (UDL) may have one child node
// referencing the location of the UDL suffix (`_w` in `1.2_w`). The
Expand Down Expand Up @@ -754,23 +744,118 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
return true;
}

syntax::NameSpecifier *BuildNameSpecifier(const NestedNameSpecifier &NNS) {
switch (NNS.getKind()) {
case NestedNameSpecifier::Global:
return new (allocator()) syntax::GlobalNameSpecifier;
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Identifier:
return new (allocator()) syntax::IdentifierNameSpecifier;
case NestedNameSpecifier::TypeSpecWithTemplate:
return new (allocator()) syntax::SimpleTemplateNameSpecifier;
case NestedNameSpecifier::TypeSpec: {
const auto *NNSType = NNS.getAsType();
assert(NNSType);
if (isa<DecltypeType>(NNSType))
return new (allocator()) syntax::DecltypeNameSpecifier;
if (isa<TemplateSpecializationType, DependentTemplateSpecializationType>(
NNSType))
return new (allocator()) syntax::SimpleTemplateNameSpecifier;
return new (allocator()) syntax::IdentifierNameSpecifier;
}
case NestedNameSpecifier::Super:
// FIXME: Support Microsoft's __super
llvm::report_fatal_error("We don't yet support the __super specifier",
true);
}
}

// FIXME: Fix `NestedNameSpecifierLoc::getLocalSourceRange` for the
// `DependentTemplateSpecializationType` case.
/// Given a nested-name-specifier return the range for the last name specifier
///
/// e.g. `std::T::template X<U>::` => `template X<U>::`
SourceRange getLocalSourceRange(const NestedNameSpecifierLoc &NNSLoc) {
auto SR = NNSLoc.getLocalSourceRange();

// The method `NestedNameSpecifierLoc::getLocalSourceRange` *should* return
// the desired `SourceRange`, but there is a corner
// case. For a `DependentTemplateSpecializationType` this method returns its
// qualifiers as well, in other words in the example above this method
// returns `T::template X<U>::` instead of only `template X<U>::`
if (auto TL = NNSLoc.getTypeLoc()) {
if (auto DependentTL =
TL.getAs<DependentTemplateSpecializationTypeLoc>()) {
// The 'template' keyword is always present in dependent template
// specializations. Except in the case of incorrect code
// TODO: Treat the case of incorrect code.
SR.setBegin(DependentTL.getTemplateKeywordLoc());
}
}

return SR;
}

syntax::NestedNameSpecifier *
BuildNestedNameSpecifier(const NestedNameSpecifierLoc &QualifierLoc) {
if (!QualifierLoc)
return nullptr;
for (auto it = QualifierLoc; it; it = it.getPrefix()) {
assert(it.hasQualifier());
auto *NS = BuildNameSpecifier(*it.getNestedNameSpecifier());
assert(NS);
if (!isa<syntax::GlobalNameSpecifier>(NS))
Builder.foldNode(Builder.getRange(getLocalSourceRange(it)).drop_back(),
NS, it);
Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier);
Builder.markChildToken(it.getEndLoc(),
syntax::NodeRole::NestedNameSpecifier_delimiter);
}
auto *NNS = new (allocator()) syntax::NestedNameSpecifier;
Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS,
QualifierLoc);
return NNS;
}

bool WalkUpFromDeclRefExpr(DeclRefExpr *S) {
if (auto *NNS = BuildNestedNameSpecifier(S->getQualifierLoc()))
Builder.markChild(NNS, syntax::NodeRole::IdExpression_qualifier);
auto *Qualifier = BuildNestedNameSpecifier(S->getQualifierLoc());
if (Qualifier)
Builder.markChild(Qualifier, syntax::NodeRole::IdExpression_qualifier);

auto TemplateKeywordLoc = S->getTemplateKeywordLoc();
if (TemplateKeywordLoc.isValid())
Builder.markChildToken(TemplateKeywordLoc,
syntax::NodeRole::TemplateKeyword);

auto *unqualifiedId = new (allocator()) syntax::UnqualifiedId;
// Get `UnqualifiedId` from `DeclRefExpr`.
// FIXME: Extract this logic so that it can be used by `MemberExpr`,
// and other semantic constructs, now it is tied to `DeclRefExpr`.
if (!S->hasExplicitTemplateArgs()) {
Builder.foldNode(Builder.getRange(S->getNameInfo().getSourceRange()),
unqualifiedId, nullptr);
} else {
auto templateIdSourceRange =
SourceRange(S->getNameInfo().getBeginLoc(), S->getRAngleLoc());
Builder.foldNode(Builder.getRange(templateIdSourceRange), unqualifiedId,
nullptr);
}

Builder.foldNode(Builder.getRange(S->getLocation(), S->getEndLoc()),
unqualifiedId, nullptr);

Builder.markChild(unqualifiedId, syntax::NodeRole::IdExpression_id);

Builder.foldNode(Builder.getExprRange(S),
new (allocator()) syntax::IdExpression, S);
return true;
}

// Same logic as DeclRefExpr.
bool WalkUpFromDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) {
auto *Qualifier = BuildNestedNameSpecifier(S->getQualifierLoc());
if (Qualifier)
Builder.markChild(Qualifier, syntax::NodeRole::IdExpression_qualifier);

auto TemplateKeywordLoc = S->getTemplateKeywordLoc();
if (TemplateKeywordLoc.isValid())
Builder.markChildToken(TemplateKeywordLoc,
syntax::NodeRole::TemplateKeyword);

auto *unqualifiedId = new (allocator()) syntax::UnqualifiedId;

Builder.foldNode(Builder.getRange(S->getLocation(), S->getEndLoc()),
unqualifiedId, nullptr);

Builder.markChild(unqualifiedId, syntax::NodeRole::IdExpression_id);

Builder.foldNode(Builder.getExprRange(S),
Expand Down
28 changes: 26 additions & 2 deletions clang/lib/Tooling/Syntax/Nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,14 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeKind K) {
return OS << "ParametersAndQualifiers";
case NodeKind::MemberPointer:
return OS << "MemberPointer";
case NodeKind::NameSpecifier:
return OS << "NameSpecifier";
case NodeKind::GlobalNameSpecifier:
return OS << "GlobalNameSpecifier";
case NodeKind::DecltypeNameSpecifier:
return OS << "DecltypeNameSpecifier";
case NodeKind::IdentifierNameSpecifier:
return OS << "IdentifierNameSpecifier";
case NodeKind::SimpleTemplateNameSpecifier:
return OS << "SimpleTemplateNameSpecifier";
case NodeKind::NestedNameSpecifier:
return OS << "NestedNameSpecifier";
}
Expand All @@ -142,6 +148,8 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole R) {
return OS << "ArrowToken";
case syntax::NodeRole::ExternKeyword:
return OS << "ExternKeyword";
case syntax::NodeRole::TemplateKeyword:
return OS << "TemplateKeyword";
case syntax::NodeRole::BodyStatement:
return OS << "BodyStatement";
case syntax::NodeRole::CaseStatement_value:
Expand Down Expand Up @@ -190,12 +198,23 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole R) {
return OS << "IdExpression_qualifier";
case syntax::NodeRole::NestedNameSpecifier_specifier:
return OS << "NestedNameSpecifier_specifier";
case syntax::NodeRole::NestedNameSpecifier_delimiter:
return OS << "NestedNameSpecifier_delimiter";
case syntax::NodeRole::ParenExpression_subExpression:
return OS << "ParenExpression_subExpression";
}
llvm_unreachable("invalid role");
}

std::vector<syntax::Leaf *> syntax::NestedNameSpecifier::delimiters() {
std::vector<syntax::Leaf *> Children;
for (auto *C = firstChild(); C; C = C->nextSibling()) {
assert(C->role() == syntax::NodeRole::NestedNameSpecifier_delimiter);
Children.push_back(llvm::cast<syntax::Leaf>(C));
}
return Children;
}

std::vector<syntax::NameSpecifier *> syntax::NestedNameSpecifier::specifiers() {
std::vector<syntax::NameSpecifier *> Children;
for (auto *C = firstChild(); C; C = C->nextSibling()) {
Expand All @@ -210,6 +229,11 @@ syntax::NestedNameSpecifier *syntax::IdExpression::qualifier() {
findChild(syntax::NodeRole::IdExpression_qualifier));
}

syntax::Leaf *syntax::IdExpression::templateKeyword() {
return llvm::cast_or_null<syntax::Leaf>(
findChild(syntax::NodeRole::TemplateKeyword));
}

syntax::UnqualifiedId *syntax::IdExpression::unqualifiedId() {
return cast_or_null<syntax::UnqualifiedId>(
findChild(syntax::NodeRole::IdExpression_id));
Expand Down
3 changes: 2 additions & 1 deletion clang/test/Modules/namespaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ void testAnonymousNotMerged() {

// expected-note@Inputs/namespaces-right.h:60 {{passing argument to parameter here}}
// expected-note@Inputs/namespaces-right.h:67 {{passing argument to parameter here}}

// expected-note@Inputs/namespaces-left.h:63 {{'N11::(anonymous namespace)::Foo' is not defined, but forward declared here; conversion would be valid if it's derived from 'N11::(anonymous namespace)::Foo'}}
// expected-note@Inputs/namespaces-left.h:70 {{'N12::(anonymous namespace)::Foo' is not defined, but forward declared here; conversion would be valid if it's derived from 'N12::(anonymous namespace)::Foo'}}
// Test that bringing in one name from an overload set does not hide the rest.
void testPartialImportOfOverloadSet() {
void (*p)() = N13::p;
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaCXX/elaborated-type-specifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace NS {
}

void test_X_elab(NS::X x) {
struct S4 *s4 = 0;
struct S4 *s4 = 0; // expected-note{{'S4' is not defined, but forward declared here; conversion would be valid if it's derived from 'NS::S4'}}
x.test_elab2(s4); // expected-error{{cannot initialize a parameter of type 'NS::S4 *' with an lvalue of type 'struct S4 *'}}
}

Expand Down
Loading

0 comments on commit 2b82436

Please sign in to comment.