diff options
author | dim <dim@FreeBSD.org> | 2011-02-26 22:09:03 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-26 22:09:03 +0000 |
commit | a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51 (patch) | |
tree | abae0246ec9156cc1a7cbb947b2b0dfe95fa3189 /lib/AST/NestedNameSpecifier.cpp | |
parent | 39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df (diff) | |
download | FreeBSD-src-a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51.zip FreeBSD-src-a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51.tar.gz |
Vendor import of clang trunk r126547:
http://llvm.org/svn/llvm-project/cfe/trunk@126547
Diffstat (limited to 'lib/AST/NestedNameSpecifier.cpp')
-rw-r--r-- | lib/AST/NestedNameSpecifier.cpp | 182 |
1 files changed, 177 insertions, 5 deletions
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp index 650321d..6f1ec05 100644 --- a/lib/AST/NestedNameSpecifier.cpp +++ b/lib/AST/NestedNameSpecifier.cpp @@ -14,8 +14,10 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" #include "llvm/Support/raw_ostream.h" #include <cassert> @@ -46,7 +48,7 @@ NestedNameSpecifier::Create(const ASTContext &Context, NestedNameSpecifier Mockup; Mockup.Prefix.setPointer(Prefix); - Mockup.Prefix.setInt(Identifier); + Mockup.Prefix.setInt(StoredIdentifier); Mockup.Specifier = II; return FindOrInsert(Context, Mockup); } @@ -60,19 +62,34 @@ NestedNameSpecifier::Create(const ASTContext &Context, "Broken nested name specifier"); NestedNameSpecifier Mockup; Mockup.Prefix.setPointer(Prefix); - Mockup.Prefix.setInt(Namespace); + Mockup.Prefix.setInt(StoredNamespaceOrAlias); Mockup.Specifier = NS; return FindOrInsert(Context, Mockup); } NestedNameSpecifier * NestedNameSpecifier::Create(const ASTContext &Context, + NestedNameSpecifier *Prefix, + NamespaceAliasDecl *Alias) { + assert(Alias && "Namespace alias cannot be NULL"); + assert((!Prefix || + (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) && + "Broken nested name specifier"); + NestedNameSpecifier Mockup; + Mockup.Prefix.setPointer(Prefix); + Mockup.Prefix.setInt(StoredNamespaceOrAlias); + Mockup.Specifier = Alias; + return FindOrInsert(Context, Mockup); +} + +NestedNameSpecifier * +NestedNameSpecifier::Create(const ASTContext &Context, NestedNameSpecifier *Prefix, bool Template, const Type *T) { assert(T && "Type cannot be NULL"); NestedNameSpecifier Mockup; Mockup.Prefix.setPointer(Prefix); - Mockup.Prefix.setInt(Template? TypeSpecWithTemplate : TypeSpec); + Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec); Mockup.Specifier = const_cast<Type*>(T); return FindOrInsert(Context, Mockup); } @@ -82,7 +99,7 @@ NestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) { assert(II && "Identifier cannot be NULL"); NestedNameSpecifier Mockup; Mockup.Prefix.setPointer(0); - Mockup.Prefix.setInt(Identifier); + Mockup.Prefix.setInt(StoredIdentifier); Mockup.Specifier = II; return FindOrInsert(Context, Mockup); } @@ -94,6 +111,47 @@ NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) { return Context.GlobalNestedNameSpecifier; } +NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const { + if (Specifier == 0) + return Global; + + switch (Prefix.getInt()) { + case StoredIdentifier: + return Identifier; + + case StoredNamespaceOrAlias: + return isa<NamespaceDecl>(static_cast<NamedDecl *>(Specifier))? Namespace + : NamespaceAlias; + + case StoredTypeSpec: + return TypeSpec; + + case StoredTypeSpecWithTemplate: + return TypeSpecWithTemplate; + } + + return Global; +} + +/// \brief Retrieve the namespace stored in this nested name +/// specifier. +NamespaceDecl *NestedNameSpecifier::getAsNamespace() const { + if (Prefix.getInt() == StoredNamespaceOrAlias) + return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier)); + + return 0; +} + +/// \brief Retrieve the namespace alias stored in this nested name +/// specifier. +NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const { + if (Prefix.getInt() == StoredNamespaceOrAlias) + return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier)); + + return 0; +} + + /// \brief Whether this nested name specifier refers to a dependent /// type or not. bool NestedNameSpecifier::isDependent() const { @@ -103,6 +161,7 @@ bool NestedNameSpecifier::isDependent() const { return true; case Namespace: + case NamespaceAlias: case Global: return false; @@ -121,6 +180,7 @@ bool NestedNameSpecifier::containsUnexpandedParameterPack() const { return getPrefix() && getPrefix()->containsUnexpandedParameterPack(); case Namespace: + case NamespaceAlias: case Global: return false; @@ -147,7 +207,11 @@ NestedNameSpecifier::print(llvm::raw_ostream &OS, break; case Namespace: - OS << getAsNamespace()->getIdentifier()->getName(); + OS << getAsNamespace()->getName(); + break; + + case NamespaceAlias: + OS << getAsNamespaceAlias()->getName(); break; case Global: @@ -199,3 +263,111 @@ NestedNameSpecifier::print(llvm::raw_ostream &OS, void NestedNameSpecifier::dump(const LangOptions &LO) { print(llvm::errs(), PrintingPolicy(LO)); } + +unsigned +NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) { + assert(Qualifier && "Expected a non-NULL qualifier"); + + // Location of the trailing '::'. + unsigned Length = sizeof(unsigned); + + switch (Qualifier->getKind()) { + case NestedNameSpecifier::Global: + // Nothing more to add. + break; + + case NestedNameSpecifier::Identifier: + case NestedNameSpecifier::Namespace: + case NestedNameSpecifier::NamespaceAlias: + // The location of the identifier or namespace name. + Length += sizeof(unsigned); + break; + + case NestedNameSpecifier::TypeSpecWithTemplate: + case NestedNameSpecifier::TypeSpec: + // The "void*" that points at the TypeLoc data. + // Note: the 'template' keyword is part of the TypeLoc. + Length += sizeof(void *); + break; + } + + return Length; +} + +unsigned +NestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) { + unsigned Length = 0; + for (; Qualifier; Qualifier = Qualifier->getPrefix()) + Length += getLocalDataLength(Qualifier); + return Length; +} + +namespace { + /// \brief Load a (possibly unaligned) source location from a given address + /// and offset. + SourceLocation LoadSourceLocation(void *Data, unsigned Offset) { + unsigned Raw; + memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned)); + return SourceLocation::getFromRawEncoding(Raw); + } + + /// \brief Load a (possibly unaligned) pointer from a given address and + /// offset. + void *LoadPointer(void *Data, unsigned Offset) { + void *Result; + memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*)); + return Result; + } +} + +SourceRange NestedNameSpecifierLoc::getSourceRange() const { + if (!Qualifier) + return SourceRange(); + + NestedNameSpecifierLoc First = *this; + while (NestedNameSpecifierLoc Prefix = First.getPrefix()) + First = Prefix; + + return SourceRange(First.getLocalSourceRange().getBegin(), + getLocalSourceRange().getEnd()); +} + +SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const { + if (!Qualifier) + return SourceRange(); + + unsigned Offset = getDataLength(Qualifier->getPrefix()); + switch (Qualifier->getKind()) { + case NestedNameSpecifier::Global: + return LoadSourceLocation(Data, Offset); + + case NestedNameSpecifier::Identifier: + case NestedNameSpecifier::Namespace: + case NestedNameSpecifier::NamespaceAlias: + return SourceRange(LoadSourceLocation(Data, Offset), + LoadSourceLocation(Data, Offset + sizeof(unsigned))); + + case NestedNameSpecifier::TypeSpecWithTemplate: + case NestedNameSpecifier::TypeSpec: { + // The "void*" that points at the TypeLoc data. + // Note: the 'template' keyword is part of the TypeLoc. + void *TypeData = LoadPointer(Data, Offset); + TypeLoc TL(Qualifier->getAsType(), TypeData); + return SourceRange(TL.getBeginLoc(), + LoadSourceLocation(Data, Offset + sizeof(void*))); + } + } + + return SourceRange(); +} + +TypeLoc NestedNameSpecifierLoc::getTypeLoc() const { + assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec || + Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) && + "Nested-name-specifier location is not a type"); + + // The "void*" that points at the TypeLoc data. + unsigned Offset = getDataLength(Qualifier->getPrefix()); + void *TypeData = LoadPointer(Data, Offset); + return TypeLoc(Qualifier->getAsType(), TypeData); +} |