//===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Decl and DeclContext classes.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/DeclBase.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DependentDiagnostic.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Type.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace clang;
//===----------------------------------------------------------------------===//
// Statistics
//===----------------------------------------------------------------------===//
#define DECL(DERIVED, BASE) static int n##DERIVED##s = 0;
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
static bool StatSwitch = false;
const char *Decl::getDeclKindName() const {
switch (DeclKind) {
default: assert(0 && "Declaration not in DeclNodes.inc!");
#define DECL(DERIVED, BASE) case DERIVED: return #DERIVED;
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
}
}
void Decl::setInvalidDecl(bool Invalid) {
InvalidDecl = Invalid;
if (Invalid) {
// Defensive maneuver for ill-formed code: we're likely not to make it to
// a point where we set the access specifier, so default it to "public"
// to avoid triggering asserts elsewhere in the front end.
setAccess(AS_public);
}
}
const char *DeclContext::getDeclKindName() const {
switch (DeclKind) {
default: assert(0 && "Declaration context not in DeclNodes.inc!");
#define DECL(DERIVED, BASE) case Decl::DERIVED: return #DERIVED;
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
}
}
bool Decl::CollectingStats(bool Enable) {
if (Enable) StatSwitch = true;
return StatSwitch;
}
void Decl::PrintStats() {
fprintf(stderr, "*** Decl Stats:\n");
int totalDecls = 0;
#define DECL(DERIVED, BASE) totalDecls += n##DERIVED##s;
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
fprintf(stderr, " %d decls total.\n", totalDecls);
int totalBytes = 0;
#define DECL(DERIVED, BASE) \
if (n##DERIVED##s > 0) { \
totalBytes += (int)(n##DERIVED##s * sizeof(DERIVED##Decl)); \
fprintf(stderr, " %d " #DERIVED " decls, %d each (%d bytes)\n", \
n##DERIVED##s, (int)sizeof(DERIVED##Decl), \
(int)(n##DERIVED##s * sizeof(DERIVED##Decl))); \
}
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
fprintf(stderr, "Total bytes = %d\n", totalBytes);
}
void Decl::add(Kind k) {
switch (k) {
default: assert(0 && "Declaration not in DeclNodes.inc!");
#define DECL(DERIVED, BASE) case DERIVED: ++n##DERIVED##s; break;
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
}
}
bool Decl::isTemplateParameterPack() const {
if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(this))
return TTP->isParameterPack();
return false;
}
bool Decl::isFunctionOrFunctionTemplate() const {
if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
}
bool Decl::isDefinedOutsideFunctionOrMethod() const {
for (const DeclContext *DC = getDeclContext();
DC && !DC->isTranslationUnit();
DC = DC->getParent())
if (DC->isFunctionOrMethod())
return false;
return true;
}
//===----------------------------------------------------------------------===//
// PrettyStackTraceDecl Implementation
//===----------------------------------------------------------------------===//
void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
SourceLocation TheLoc = Loc;
if (TheLoc.isInvalid() && TheDecl)
TheLoc = TheDecl->getLocation();
if (TheLoc.isValid()) {
TheLoc.print(OS, SM);
OS << ": ";
}
OS << Message;
if (const NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl))