diff options
Diffstat (limited to 'clang/lib/AST/NestedNameSpecifier.cpp')
| -rw-r--r-- | clang/lib/AST/NestedNameSpecifier.cpp | 89 | 
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");  | 
