//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements semantic analysis for declaration specifiers.
//
//===----------------------------------------------------------------------===//
#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include <cstring>
using namespace clang;
static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
unsigned DiagID) {
return D.Report(Loc, DiagID);
}
void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
assert(TemplateId && "NULL template-id annotation?");
Kind = IK_TemplateId;
this->TemplateId = TemplateId;
StartLocation = TemplateId->TemplateNameLoc;
EndLocation = TemplateId->RAngleLoc;
}
void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
assert(TemplateId && "NULL template-id annotation?");
Kind = IK_ConstructorTemplateId;
this->TemplateId = TemplateId;
StartLocation = TemplateId->TemplateNameLoc;
EndLocation = TemplateId->RAngleLoc;
}
CXXScopeSpec::CXXScopeSpec(const CXXScopeSpec &Other)
: Range(Other.Range), ScopeRep(Other.ScopeRep), Buffer(0),
BufferSize(Other.BufferSize), BufferCapacity(Other.BufferSize)
{
if (BufferSize) {
Buffer = static_cast<char *>(malloc(BufferSize));
memcpy(Buffer, Other.Buffer, BufferSize);
}
}
CXXScopeSpec &CXXScopeSpec::operator=(const CXXScopeSpec &Other) {
Range = Other.Range;
ScopeRep = Other.ScopeRep;
if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
// Re-use our storage.
BufferSize = Other.BufferSize;
memcpy(Buffer, Other.Buffer, BufferSize);
return *this;
}
if (BufferCapacity)
free(Buffer);
if (Other.Buffer) {
BufferSize = Other.BufferSize;
BufferCapacity = BufferSize;
Buffer = static_cast<char *>(malloc(BufferSize));
memcpy(Buffer, Other.Buffer, BufferSize);
} else {
Buffer = 0;
BufferSize = 0;
BufferCapacity = 0;
}
return *this;
}
CXXScopeSpec::~CXXScopeSpec() {
if (BufferCapacity)
free(Buffer);
}
namespace {
void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
unsigned &BufferCapacity) {
if (BufferSize + (End - Start) > BufferCapacity) {
// Reallocate the buffer.
unsigned NewCapacity
= std::max((unsigned)(BufferCapacity? BufferCapacity * 2
: sizeof(void*) * 2),
(unsigned)(BufferSize + (End - Start)));
char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
memcpy(NewBuffer, Buffer, BufferSize);
if (BufferCapacity)
free(Buffer);
Buffer = NewBuffer;
BufferCapacity = NewCapacity;
}
memcpy(Buffer + BufferSize, Start, End - Start);
BufferSize += End-Start;
}
/// \brief Save a source location to the given buffer.
void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
unsigned &BufferSize, unsigned &BufferCapacity) {
unsigned Raw = Loc.getRawEncoding();
Append(reinterpret_cast<char *>(&Raw),
reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
Buffer, BufferSize, BufferCapacity);
}
/// \brief Save a pointer to the given buffer.
void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
unsigned &BufferCapacity) {
Append(reinterpret_cast<char *>(&Ptr),
reinterpret_cast<char *>(&Ptr) +