summaryrefslogtreecommitdiffstats
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp193
1 files changed, 137 insertions, 56 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index dc9fb59..ffe4967 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -25,7 +25,6 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Parse/DeclSpec.h"
#include "llvm/Support/ErrorHandling.h"
-#include <vector>
using namespace clang;
@@ -286,6 +285,28 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
}
Linkage NamedDecl::getLinkage() const {
+
+ // Objective-C: treat all Objective-C declarations as having external
+ // linkage.
+ switch (getKind()) {
+ default:
+ break;
+ case Decl::ObjCAtDefsField:
+ case Decl::ObjCCategory:
+ case Decl::ObjCCategoryImpl:
+ case Decl::ObjCClass:
+ case Decl::ObjCCompatibleAlias:
+ case Decl::ObjCForwardProtocol:
+ case Decl::ObjCImplementation:
+ case Decl::ObjCInterface:
+ case Decl::ObjCIvar:
+ case Decl::ObjCMethod:
+ case Decl::ObjCProperty:
+ case Decl::ObjCPropertyImpl:
+ case Decl::ObjCProtocol:
+ return ExternalLinkage;
+ }
+
// Handle linkage for namespace-scope names.
if (getDeclContext()->getLookupContext()->isFileContext())
if (Linkage L = getLinkageForNamespaceScopeDecl(this))
@@ -354,88 +375,79 @@ std::string NamedDecl::getQualifiedNameAsString() const {
}
std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
- // FIXME: Collect contexts, then accumulate names to avoid unnecessary
- // std::string thrashing.
- std::vector<std::string> Names;
- std::string QualName;
const DeclContext *Ctx = getDeclContext();
if (Ctx->isFunctionOrMethod())
return getNameAsString();
- while (Ctx) {
+ typedef llvm::SmallVector<const DeclContext *, 8> ContextsTy;
+ ContextsTy Contexts;
+
+ // Collect contexts.
+ while (Ctx && isa<NamedDecl>(Ctx)) {
+ Contexts.push_back(Ctx);
+ Ctx = Ctx->getParent();
+ };
+
+ std::string QualName;
+ llvm::raw_string_ostream OS(QualName);
+
+ for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend();
+ I != E; ++I) {
if (const ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
+ = dyn_cast<ClassTemplateSpecializationDecl>(*I)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
TemplateArgs.getFlatArgumentList(),
TemplateArgs.flat_size(),
P);
- Names.push_back(Spec->getIdentifier()->getNameStart() + TemplateArgsStr);
- } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(Ctx)) {
+ OS << Spec->getName() << TemplateArgsStr;
+ } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
if (ND->isAnonymousNamespace())
- Names.push_back("<anonymous namespace>");
+ OS << "<anonymous namespace>";
else
- Names.push_back(ND->getNameAsString());
- } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(Ctx)) {
- if (!RD->getIdentifier()) {
- std::string RecordString = "<anonymous ";
- RecordString += RD->getKindName();
- RecordString += ">";
- Names.push_back(RecordString);
- } else {
- Names.push_back(RD->getNameAsString());
- }
- } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Ctx)) {
- std::string Proto = FD->getNameAsString();
-
+ OS << ND;
+ } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) {
+ if (!RD->getIdentifier())
+ OS << "<anonymous " << RD->getKindName() << '>';
+ else
+ OS << RD;
+ } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
const FunctionProtoType *FT = 0;
if (FD->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>());
- Proto += "(";
+ OS << FD << '(';
if (FT) {
- llvm::raw_string_ostream POut(Proto);
unsigned NumParams = FD->getNumParams();
for (unsigned i = 0; i < NumParams; ++i) {
if (i)
- POut << ", ";
+ OS << ", ";
std::string Param;
FD->getParamDecl(i)->getType().getAsStringInternal(Param, P);
- POut << Param;
+ OS << Param;
}
if (FT->isVariadic()) {
if (NumParams > 0)
- POut << ", ";
- POut << "...";
+ OS << ", ";
+ OS << "...";
}
}
- Proto += ")";
-
- Names.push_back(Proto);
- } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
- Names.push_back(ND->getNameAsString());
- else
- break;
-
- Ctx = Ctx->getParent();
+ OS << ')';
+ } else {
+ OS << cast<NamedDecl>(*I);
+ }
+ OS << "::";
}
- std::vector<std::string>::reverse_iterator
- I = Names.rbegin(),
- End = Names.rend();
-
- for (; I!=End; ++I)
- QualName += *I + "::";
-
if (getDeclName())
- QualName += getNameAsString();
+ OS << this;
else
- QualName += "<anonymous>";
+ OS << "<anonymous>";
- return QualName;
+ return OS.str();
}
bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
@@ -494,6 +506,24 @@ NamedDecl *NamedDecl::getUnderlyingDecl() {
}
}
+bool NamedDecl::isCXXInstanceMember() const {
+ assert(isCXXClassMember() &&
+ "checking whether non-member is instance member");
+
+ const NamedDecl *D = this;
+ if (isa<UsingShadowDecl>(D))
+ D = cast<UsingShadowDecl>(D)->getTargetDecl();
+
+ if (isa<FieldDecl>(D))
+ return true;
+ if (isa<CXXMethodDecl>(D))
+ return cast<CXXMethodDecl>(D)->isInstance();
+ if (isa<FunctionTemplateDecl>(D))
+ return cast<CXXMethodDecl>(cast<FunctionTemplateDecl>(D)
+ ->getTemplatedDecl())->isInstance();
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// DeclaratorDecl Implementation
//===----------------------------------------------------------------------===//
@@ -568,8 +598,8 @@ const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) {
VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
- StorageClass S) {
- return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S);
+ StorageClass S, StorageClass SCAsWritten) {
+ return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S, SCAsWritten);
}
void VarDecl::Destroy(ASTContext& C) {
@@ -793,8 +823,10 @@ void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
- StorageClass S, Expr *DefArg) {
- return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo, S, DefArg);
+ StorageClass S, StorageClass SCAsWritten,
+ Expr *DefArg) {
+ return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo,
+ S, SCAsWritten, DefArg);
}
Expr *ParmVarDecl::getDefaultArg() {
@@ -874,6 +906,12 @@ void FunctionDecl::getNameForDiagnostic(std::string &S,
}
+bool FunctionDecl::isVariadic() const {
+ if (const FunctionProtoType *FT = getType()->getAs<FunctionProtoType>())
+ return FT->isVariadic();
+ return false;
+}
+
Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
if (I->Body) {
@@ -1291,6 +1329,40 @@ FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
}
}
+void
+FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context,
+ const UnresolvedSetImpl &Templates,
+ const TemplateArgumentListInfo &TemplateArgs) {
+ assert(TemplateOrSpecialization.isNull());
+ size_t Size = sizeof(DependentFunctionTemplateSpecializationInfo);
+ Size += Templates.size() * sizeof(FunctionTemplateDecl*);
+ Size += TemplateArgs.size() * sizeof(TemplateArgumentLoc);
+ void *Buffer = Context.Allocate(Size);
+ DependentFunctionTemplateSpecializationInfo *Info =
+ new (Buffer) DependentFunctionTemplateSpecializationInfo(Templates,
+ TemplateArgs);
+ TemplateOrSpecialization = Info;
+}
+
+DependentFunctionTemplateSpecializationInfo::
+DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts,
+ const TemplateArgumentListInfo &TArgs)
+ : AngleLocs(TArgs.getLAngleLoc(), TArgs.getRAngleLoc()) {
+
+ d.NumTemplates = Ts.size();
+ d.NumArgs = TArgs.size();
+
+ FunctionTemplateDecl **TsArray =
+ const_cast<FunctionTemplateDecl**>(getTemplates());
+ for (unsigned I = 0, E = Ts.size(); I != E; ++I)
+ TsArray[I] = cast<FunctionTemplateDecl>(Ts[I]->getUnderlyingDecl());
+
+ TemplateArgumentLoc *ArgsArray =
+ const_cast<TemplateArgumentLoc*>(getTemplateArgs());
+ for (unsigned I = 0, E = TArgs.size(); I != E; ++I)
+ new (&ArgsArray[I]) TemplateArgumentLoc(TArgs[I]);
+}
+
TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const {
// For a function template specialization, query the specialization
// information object.
@@ -1407,6 +1479,10 @@ void TagDecl::startDefinition() {
if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
TagT->decl.setPointer(this);
TagT->decl.setInt(1);
+ } else if (InjectedClassNameType *Injected
+ = const_cast<InjectedClassNameType *>(
+ TypeForDecl->getAs<InjectedClassNameType>())) {
+ Injected->Decl = cast<CXXRecordDecl>(this);
}
if (isa<CXXRecordDecl>(this)) {
@@ -1428,6 +1504,11 @@ void TagDecl::completeDefinition() {
assert(TagT->decl.getPointer() == this &&
"Attempt to redefine a tag definition?");
TagT->decl.setInt(0);
+ } else if (InjectedClassNameType *Injected
+ = const_cast<InjectedClassNameType *>(
+ TypeForDecl->getAs<InjectedClassNameType>())) {
+ assert(Injected->Decl == this &&
+ "Attempt to redefine a class template definition?");
}
}
@@ -1606,10 +1687,10 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName N, QualType T,
TypeSourceInfo *TInfo,
- StorageClass S, bool isInline,
- bool hasWrittenPrototype) {
- FunctionDecl *New
- = new (C) FunctionDecl(Function, DC, L, N, T, TInfo, S, isInline);
+ StorageClass S, StorageClass SCAsWritten,
+ bool isInline, bool hasWrittenPrototype) {
+ FunctionDecl *New = new (C) FunctionDecl(Function, DC, L, N, T, TInfo,
+ S, SCAsWritten, isInline);
New->HasWrittenPrototype = hasWrittenPrototype;
return New;
}
OpenPOWER on IntegriCloud