aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/NestedNameSpecifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/NestedNameSpecifier.cpp')
-rw-r--r--clang/lib/AST/NestedNameSpecifier.cpp89
1 files changed, 39 insertions, 50 deletions
diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp
index 137953fa8203..08e8819a4d69 100644
--- a/clang/lib/AST/NestedNameSpecifier.cpp
+++ b/clang/lib/AST/NestedNameSpecifier.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DependenceFlags.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
@@ -197,75 +198,53 @@ CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const {
llvm_unreachable("Invalid NNS Kind!");
}
-/// Whether this nested name specifier refers to a dependent
-/// type or not.
-bool NestedNameSpecifier::isDependent() const {
+NestedNameSpecifierDependence NestedNameSpecifier::getDependence() const {
switch (getKind()) {
- case Identifier:
+ case Identifier: {
// Identifier specifiers always represent dependent types
- return true;
+ auto F = NestedNameSpecifierDependence::Dependent |
+ NestedNameSpecifierDependence::Instantiation;
+ // Prefix can contain unexpanded template parameters.
+ if (getPrefix())
+ return F | getPrefix()->getDependence();
+ return F;
+ }
case Namespace:
case NamespaceAlias:
case Global:
- return false;
+ return NestedNameSpecifierDependence::None;
case Super: {
CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
for (const auto &Base : RD->bases())
if (Base.getType()->isDependentType())
- return true;
-
- return false;
+ // FIXME: must also be instantiation-dependent.
+ return NestedNameSpecifierDependence::Dependent;
+ return NestedNameSpecifierDependence::None;
}
case TypeSpec:
case TypeSpecWithTemplate:
- return getAsType()->isDependentType();
+ return toNestedNameSpecifierDependendence(getAsType()->getDependence());
}
-
llvm_unreachable("Invalid NNS Kind!");
}
-/// Whether this nested name specifier refers to a dependent
-/// type or not.
-bool NestedNameSpecifier::isInstantiationDependent() const {
- switch (getKind()) {
- case Identifier:
- // Identifier specifiers always represent dependent types
- return true;
-
- case Namespace:
- case NamespaceAlias:
- case Global:
- case Super:
- return false;
-
- case TypeSpec:
- case TypeSpecWithTemplate:
- return getAsType()->isInstantiationDependentType();
- }
+bool NestedNameSpecifier::isDependent() const {
+ return getDependence() & NestedNameSpecifierDependence::Dependent;
+}
- llvm_unreachable("Invalid NNS Kind!");
+bool NestedNameSpecifier::isInstantiationDependent() const {
+ return getDependence() & NestedNameSpecifierDependence::Instantiation;
}
bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
- switch (getKind()) {
- case Identifier:
- return getPrefix() && getPrefix()->containsUnexpandedParameterPack();
-
- case Namespace:
- case NamespaceAlias:
- case Global:
- case Super:
- return false;
-
- case TypeSpec:
- case TypeSpecWithTemplate:
- return getAsType()->containsUnexpandedParameterPack();
- }
+ return getDependence() & NestedNameSpecifierDependence::UnexpandedPack;
+}
- llvm_unreachable("Invalid NNS Kind!");
+bool NestedNameSpecifier::containsErrors() const {
+ return getDependence() & NestedNameSpecifierDependence::Error;
}
/// Print this nested name specifier to the given output
@@ -336,6 +315,14 @@ void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
// Print the template argument list.
printTemplateArgumentList(OS, SpecType->template_arguments(),
InnerPolicy);
+ } else if (const auto *DepSpecType =
+ dyn_cast<DependentTemplateSpecializationType>(T)) {
+ // Print the template name without its corresponding
+ // nested-name-specifier.
+ OS << DepSpecType->getIdentifier()->getName();
+ // Print the template argument list.
+ printTemplateArgumentList(OS, DepSpecType->template_arguments(),
+ InnerPolicy);
} else {
// Print the type normally
QualType(T, 0).print(OS, InnerPolicy);
@@ -481,12 +468,14 @@ static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
unsigned NewCapacity = std::max(
(unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
(unsigned)(BufferSize + (End - Start)));
- char *NewBuffer = static_cast<char *>(llvm::safe_malloc(NewCapacity));
- if (BufferCapacity) {
- memcpy(NewBuffer, Buffer, BufferSize);
- free(Buffer);
+ if (!BufferCapacity) {
+ char *NewBuffer = static_cast<char *>(llvm::safe_malloc(NewCapacity));
+ if (Buffer)
+ memcpy(NewBuffer, Buffer, BufferSize);
+ Buffer = NewBuffer;
+ } else {
+ Buffer = static_cast<char *>(llvm::safe_realloc(Buffer, NewCapacity));
}
- Buffer = NewBuffer;
BufferCapacity = NewCapacity;
}
assert(Buffer && Start && End && End > Start && "Illegal memory buffer copy");