summaryrefslogtreecommitdiffstats
path: root/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTContext.cpp216
-rw-r--r--lib/AST/CXXInheritance.cpp51
-rw-r--r--lib/AST/Decl.cpp47
-rw-r--r--lib/AST/DeclBase.cpp48
-rw-r--r--lib/AST/DeclCXX.cpp190
-rw-r--r--lib/AST/DeclObjC.cpp4
-rw-r--r--lib/AST/DeclPrinter.cpp35
-rw-r--r--lib/AST/DeclTemplate.cpp4
-rw-r--r--lib/AST/DeclarationName.cpp2
-rw-r--r--lib/AST/Expr.cpp64
-rw-r--r--lib/AST/ExprCXX.cpp46
-rw-r--r--lib/AST/ExprConstant.cpp53
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp78
-rw-r--r--lib/AST/RecordLayoutBuilder.h1
-rw-r--r--lib/AST/StmtDumper.cpp264
-rw-r--r--lib/AST/StmtPrinter.cpp16
-rw-r--r--lib/AST/StmtProfile.cpp25
-rw-r--r--lib/AST/TemplateBase.cpp2
-rw-r--r--lib/AST/TemplateName.cpp28
-rw-r--r--lib/AST/Type.cpp46
-rw-r--r--lib/AST/TypeLoc.cpp29
-rw-r--r--lib/AST/TypePrinter.cpp40
22 files changed, 808 insertions, 481 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 6c9ecf0..cc7055d 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -260,24 +260,40 @@ ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
}
NamedDecl *
-ASTContext::getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD) {
+ASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) {
llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos
- = InstantiatedFromUnresolvedUsingDecl.find(UUD);
- if (Pos == InstantiatedFromUnresolvedUsingDecl.end())
+ = InstantiatedFromUsingDecl.find(UUD);
+ if (Pos == InstantiatedFromUsingDecl.end())
return 0;
return Pos->second;
}
void
-ASTContext::setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD,
- NamedDecl *UUD) {
- assert((isa<UnresolvedUsingValueDecl>(UUD) ||
- isa<UnresolvedUsingTypenameDecl>(UUD)) &&
- "original declaration is not an unresolved using decl");
- assert(!InstantiatedFromUnresolvedUsingDecl[UD] &&
- "Already noted what using decl what instantiated from");
- InstantiatedFromUnresolvedUsingDecl[UD] = UUD;
+ASTContext::setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern) {
+ assert((isa<UsingDecl>(Pattern) ||
+ isa<UnresolvedUsingValueDecl>(Pattern) ||
+ isa<UnresolvedUsingTypenameDecl>(Pattern)) &&
+ "pattern decl is not a using decl");
+ assert(!InstantiatedFromUsingDecl[Inst] && "pattern already exists");
+ InstantiatedFromUsingDecl[Inst] = Pattern;
+}
+
+UsingShadowDecl *
+ASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) {
+ llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos
+ = InstantiatedFromUsingShadowDecl.find(Inst);
+ if (Pos == InstantiatedFromUsingShadowDecl.end())
+ return 0;
+
+ return Pos->second;
+}
+
+void
+ASTContext::setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
+ UsingShadowDecl *Pattern) {
+ assert(!InstantiatedFromUsingShadowDecl[Inst] && "pattern already exists");
+ InstantiatedFromUsingShadowDecl[Inst] = Pattern;
}
FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) {
@@ -711,10 +727,6 @@ ASTContext::getTypeInfo(const Type *T) {
break;
}
case Type::MemberPointer: {
- // FIXME: This is ABI dependent. We use the Itanium C++ ABI.
- // http://www.codesourcery.com/public/cxx-abi/abi.html#member-pointers
- // If we ever want to support other ABIs this needs to be abstracted.
-
QualType Pointee = cast<MemberPointerType>(T)->getPointeeType();
std::pair<uint64_t, unsigned> PtrDiffInfo =
getTypeInfo(getPointerDiffType());
@@ -997,31 +1009,31 @@ void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,
ObjCImpls[CatD] = ImplD;
}
-/// \brief Allocate an uninitialized DeclaratorInfo.
+/// \brief Allocate an uninitialized TypeSourceInfo.
///
-/// The caller should initialize the memory held by DeclaratorInfo using
+/// The caller should initialize the memory held by TypeSourceInfo using
/// the TypeLoc wrappers.
///
/// \param T the type that will be the basis for type source info. This type
/// should refer to how the declarator was written in source code, not to
/// what type semantic analysis resolved the declarator to.
-DeclaratorInfo *ASTContext::CreateDeclaratorInfo(QualType T,
+TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T,
unsigned DataSize) {
if (!DataSize)
DataSize = TypeLoc::getFullDataSizeForType(T);
else
assert(DataSize == TypeLoc::getFullDataSizeForType(T) &&
- "incorrect data size provided to CreateDeclaratorInfo!");
+ "incorrect data size provided to CreateTypeSourceInfo!");
- DeclaratorInfo *DInfo =
- (DeclaratorInfo*)BumpAlloc.Allocate(sizeof(DeclaratorInfo) + DataSize, 8);
- new (DInfo) DeclaratorInfo(T);
- return DInfo;
+ TypeSourceInfo *TInfo =
+ (TypeSourceInfo*)BumpAlloc.Allocate(sizeof(TypeSourceInfo) + DataSize, 8);
+ new (TInfo) TypeSourceInfo(T);
+ return TInfo;
}
-DeclaratorInfo *ASTContext::getTrivialDeclaratorInfo(QualType T,
+TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T,
SourceLocation L) {
- DeclaratorInfo *DI = CreateDeclaratorInfo(T);
+ TypeSourceInfo *DI = CreateTypeSourceInfo(T);
DI->getTypeLoc().initialize(L);
return DI;
}
@@ -1092,6 +1104,20 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
return *NewEntry;
}
+const CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) {
+ RD = cast<CXXRecordDecl>(RD->getDefinition(*this));
+ assert(RD && "Cannot get key function for forward declarations!");
+
+ const CXXMethodDecl *&Entry = KeyFunctions[RD];
+ if (!Entry)
+ Entry = ASTRecordLayoutBuilder::ComputeKeyFunction(RD);
+ else
+ assert(Entry == ASTRecordLayoutBuilder::ComputeKeyFunction(RD) &&
+ "Key function changed!");
+
+ return Entry;
+}
+
//===----------------------------------------------------------------------===//
// Type creation/memoization methods
//===----------------------------------------------------------------------===//
@@ -1174,32 +1200,42 @@ QualType ASTContext::getObjCGCQualType(QualType T,
return getExtQualType(TypeNode, Quals);
}
-QualType ASTContext::getNoReturnType(QualType T) {
+QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) {
QualType ResultType;
- if (T->isPointerType()) {
- QualType Pointee = T->getAs<PointerType>()->getPointeeType();
- ResultType = getNoReturnType(Pointee);
+ if (const PointerType *Pointer = T->getAs<PointerType>()) {
+ QualType Pointee = Pointer->getPointeeType();
+ ResultType = getNoReturnType(Pointee, AddNoReturn);
+ if (ResultType == Pointee)
+ return T;
+
ResultType = getPointerType(ResultType);
- } else if (T->isBlockPointerType()) {
- QualType Pointee = T->getAs<BlockPointerType>()->getPointeeType();
- ResultType = getNoReturnType(Pointee);
+ } else if (const BlockPointerType *BlockPointer
+ = T->getAs<BlockPointerType>()) {
+ QualType Pointee = BlockPointer->getPointeeType();
+ ResultType = getNoReturnType(Pointee, AddNoReturn);
+ if (ResultType == Pointee)
+ return T;
+
ResultType = getBlockPointerType(ResultType);
- } else {
- assert (T->isFunctionType()
- && "can't noreturn qualify non-pointer to function or block type");
-
- if (const FunctionNoProtoType *FNPT = T->getAs<FunctionNoProtoType>()) {
- ResultType = getFunctionNoProtoType(FNPT->getResultType(), true);
+ } else if (const FunctionType *F = T->getAs<FunctionType>()) {
+ if (F->getNoReturnAttr() == AddNoReturn)
+ return T;
+
+ if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(F)) {
+ ResultType = getFunctionNoProtoType(FNPT->getResultType(), AddNoReturn);
} else {
- const FunctionProtoType *F = T->getAs<FunctionProtoType>();
+ const FunctionProtoType *FPT = cast<FunctionProtoType>(F);
ResultType
- = getFunctionType(F->getResultType(), F->arg_type_begin(),
- F->getNumArgs(), F->isVariadic(), F->getTypeQuals(),
- F->hasExceptionSpec(), F->hasAnyExceptionSpec(),
- F->getNumExceptions(), F->exception_begin(), true);
+ = getFunctionType(FPT->getResultType(), FPT->arg_type_begin(),
+ FPT->getNumArgs(), FPT->isVariadic(),
+ FPT->getTypeQuals(),
+ FPT->hasExceptionSpec(), FPT->hasAnyExceptionSpec(),
+ FPT->getNumExceptions(), FPT->exception_begin(),
+ AddNoReturn);
}
- }
-
+ } else
+ return T;
+
return getQualifiedType(ResultType, T.getLocalQualifiers());
}
@@ -1766,6 +1802,9 @@ QualType ASTContext::getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl) {
Decl->TypeForDecl = PrevDecl->TypeForDecl;
else
Decl->TypeForDecl = new (*this, TypeAlignment) EnumType(Enum);
+ } else if (UnresolvedUsingTypenameDecl *Using =
+ dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
+ Decl->TypeForDecl = new (*this, TypeAlignment) UnresolvedUsingType(Using);
} else
assert(false && "TypeDecl without a type?");
@@ -2238,7 +2277,7 @@ QualType ASTContext::getTagDeclType(const TagDecl *Decl) {
/// getSizeType - Return the unique type for "size_t" (C99 7.17), the result
/// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and
/// needs to agree with the definition in <stddef.h>.
-QualType ASTContext::getSizeType() const {
+CanQualType ASTContext::getSizeType() const {
return getFromTargetType(Target.getSizeType());
}
@@ -2354,8 +2393,9 @@ DeclarationName ASTContext::getNameForTemplate(TemplateName Name) {
}
}
- assert(Name.getAsOverloadedFunctionDecl());
- return Name.getAsOverloadedFunctionDecl()->getDeclName();
+ OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate();
+ assert(Storage);
+ return (*Storage->begin())->getDeclName();
}
TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) {
@@ -2364,27 +2404,7 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) {
if (TemplateDecl *Template = Name.getAsTemplateDecl())
return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl()));
- // If this template name refers to a set of overloaded function templates,
- /// the canonical template name merely stores the set of function templates.
- if (OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl()) {
- OverloadedFunctionDecl *CanonOvl = 0;
- for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
- FEnd = Ovl->function_end();
- F != FEnd; ++F) {
- Decl *Canon = F->get()->getCanonicalDecl();
- if (CanonOvl || Canon != F->get()) {
- if (!CanonOvl)
- CanonOvl = OverloadedFunctionDecl::Create(*this,
- Ovl->getDeclContext(),
- Ovl->getDeclName());
-
- CanonOvl->addOverload(
- AnyFunctionDecl::getFromNamedDecl(cast<NamedDecl>(Canon)));
- }
- }
-
- return TemplateName(CanonOvl? CanonOvl : Ovl);
- }
+ assert(!Name.getAsOverloadedTemplate());
DependentTemplateName *DTN = Name.getAsDependentTemplateName();
assert(DTN && "Non-dependent template names must refer to template decls.");
@@ -2651,7 +2671,7 @@ int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) {
unsigned ASTContext::getIntegerRank(Type *T) {
assert(T->isCanonicalUnqualified() && "T should be canonicalized");
if (EnumType* ET = dyn_cast<EnumType>(T))
- T = ET->getDecl()->getIntegerType().getTypePtr();
+ T = ET->getDecl()->getPromotionType().getTypePtr();
if (T->isSpecificBuiltinType(BuiltinType::WChar))
T = getFromTargetType(Target.getWCharType()).getTypePtr();
@@ -2732,6 +2752,8 @@ QualType ASTContext::isPromotableBitField(Expr *E) {
QualType ASTContext::getPromotedIntegerType(QualType Promotable) {
assert(!Promotable.isNull());
assert(Promotable->isPromotableIntegerType());
+ if (const EnumType *ET = Promotable->getAs<EnumType>())
+ return ET->getDecl()->getPromotionType();
if (Promotable->isSignedIntegerType())
return IntTy;
uint64_t PromotableSize = getTypeSize(Promotable);
@@ -2812,7 +2834,7 @@ QualType ASTContext::getCFConstantStringType() {
for (unsigned i = 0; i < 4; ++i) {
FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl,
SourceLocation(), 0,
- FieldTypes[i], /*DInfo=*/0,
+ FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false);
CFConstantStringTypeDecl->addDecl(Field);
@@ -2848,7 +2870,7 @@ QualType ASTContext::getObjCFastEnumerationStateType() {
FieldDecl *Field = FieldDecl::Create(*this,
ObjCFastEnumerationStateTypeDecl,
SourceLocation(), 0,
- FieldTypes[i], /*DInfo=*/0,
+ FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false);
ObjCFastEnumerationStateTypeDecl->addDecl(Field);
@@ -2884,7 +2906,7 @@ QualType ASTContext::getBlockDescriptorType() {
T,
SourceLocation(),
&Idents.get(FieldNames[i]),
- FieldTypes[i], /*DInfo=*/0,
+ FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false);
T->addDecl(Field);
@@ -2931,7 +2953,7 @@ QualType ASTContext::getBlockDescriptorExtendedType() {
T,
SourceLocation(),
&Idents.get(FieldNames[i]),
- FieldTypes[i], /*DInfo=*/0,
+ FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false);
T->addDecl(Field);
@@ -3009,7 +3031,7 @@ QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) {
continue;
FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
&Idents.get(FieldNames[i]),
- FieldTypes[i], /*DInfo=*/0,
+ FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0, /*Mutable=*/false);
T->addDecl(Field);
}
@@ -3052,7 +3074,7 @@ QualType ASTContext::getBlockParmType(
for (size_t i = 0; i < 5; ++i) {
FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
&Idents.get(FieldNames[i]),
- FieldTypes[i], /*DInfo=*/0,
+ FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0, /*Mutable=*/false);
T->addDecl(Field);
}
@@ -3072,7 +3094,7 @@ QualType ASTContext::getBlockParmType(
FieldType);
FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
- Name, FieldType, /*DInfo=*/0,
+ Name, FieldType, /*TInfo=*/0,
/*BitWidth=*/0, /*Mutable=*/false);
T->addDecl(Field);
}
@@ -3690,36 +3712,40 @@ void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
ObjCConstantStringType = getObjCInterfaceType(Decl);
}
-/// \brief Retrieve the template name that represents a qualified
-/// template name such as \c std::vector.
-TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
- bool TemplateKeyword,
- TemplateDecl *Template) {
- llvm::FoldingSetNodeID ID;
- QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);
+/// \brief Retrieve the template name that corresponds to a non-empty
+/// lookup.
+TemplateName ASTContext::getOverloadedTemplateName(NamedDecl * const *Begin,
+ NamedDecl * const *End) {
+ unsigned size = End - Begin;
+ assert(size > 1 && "set is not overloaded!");
- void *InsertPos = 0;
- QualifiedTemplateName *QTN =
- QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
- if (!QTN) {
- QTN = new (*this,4) QualifiedTemplateName(NNS, TemplateKeyword, Template);
- QualifiedTemplateNames.InsertNode(QTN, InsertPos);
+ void *memory = Allocate(sizeof(OverloadedTemplateStorage) +
+ size * sizeof(FunctionTemplateDecl*));
+ OverloadedTemplateStorage *OT = new(memory) OverloadedTemplateStorage(size);
+
+ NamedDecl **Storage = OT->getStorage();
+ for (NamedDecl * const *I = Begin; I != End; ++I) {
+ NamedDecl *D = *I;
+ assert(isa<FunctionTemplateDecl>(D) ||
+ (isa<UsingShadowDecl>(D) &&
+ isa<FunctionTemplateDecl>(D->getUnderlyingDecl())));
+ *Storage++ = D;
}
- return TemplateName(QTN);
+ return TemplateName(OT);
}
/// \brief Retrieve the template name that represents a qualified
/// template name such as \c std::vector.
TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
bool TemplateKeyword,
- OverloadedFunctionDecl *Template) {
+ TemplateDecl *Template) {
llvm::FoldingSetNodeID ID;
QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);
void *InsertPos = 0;
QualifiedTemplateName *QTN =
- QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+ QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
if (!QTN) {
QTN = new (*this,4) QualifiedTemplateName(NNS, TemplateKeyword, Template);
QualifiedTemplateNames.InsertNode(QTN, InsertPos);
@@ -4334,6 +4360,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
if (LHSClass != RHSClass) {
// C99 6.7.2.2p4: Each enumerated type shall be compatible with char,
// a signed integer type, or an unsigned integer type.
+ // Compatibility is based on the underlying type, not the promotion
+ // type.
if (const EnumType* ETy = LHS->getAs<EnumType>()) {
if (ETy->getDecl()->getIntegerType() == RHSCan.getUnqualifiedType())
return RHS;
@@ -4493,6 +4521,8 @@ unsigned ASTContext::getIntWidth(QualType T) {
if (FixedWidthIntType *FWIT = dyn_cast<FixedWidthIntType>(T)) {
return FWIT->getWidth();
}
+ if (EnumType *ET = dyn_cast<EnumType>(T))
+ T = ET->getDecl()->getIntegerType();
// For builtin types, just use the standard type sizing method
return (unsigned)getTypeSize(T);
}
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 023bca4..92a58b7 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -90,6 +90,57 @@ bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) cons
return lookupInBases(&FindBaseClass, Base->getCanonicalDecl(), Paths);
}
+static bool BaseIsNot(const CXXRecordDecl *Base, void *OpaqueTarget) {
+ // OpaqueTarget is a CXXRecordDecl*.
+ return Base->getCanonicalDecl() != (const CXXRecordDecl*) OpaqueTarget;
+}
+
+bool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const {
+ return forallBases(BaseIsNot, (void*) Base->getCanonicalDecl());
+}
+
+bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
+ void *OpaqueData,
+ bool AllowShortCircuit) const {
+ ASTContext &Context = getASTContext();
+ llvm::SmallVector<const CXXRecordDecl*, 8> Queue;
+
+ const CXXRecordDecl *Record = this;
+ bool AllMatches = true;
+ while (true) {
+ for (CXXRecordDecl::base_class_const_iterator
+ I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
+ const RecordType *Ty = I->getType()->getAs<RecordType>();
+ if (!Ty) {
+ if (AllowShortCircuit) return false;
+ AllMatches = false;
+ continue;
+ }
+
+ CXXRecordDecl *Base =
+ cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition(Context));
+ if (!Base) {
+ if (AllowShortCircuit) return false;
+ AllMatches = false;
+ continue;
+ }
+
+ Queue.push_back(Base);
+ if (!BaseMatches(Base, OpaqueData)) {
+ if (AllowShortCircuit) return false;
+ AllMatches = false;
+ continue;
+ }
+ }
+
+ if (Queue.empty()) break;
+ Record = Queue.back(); // not actually a queue.
+ Queue.pop_back();
+ }
+
+ return AllMatches;
+}
+
bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
void *UserData,
CXXBasePaths &Paths) const {
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 572d76f..4d0d422 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -38,7 +38,7 @@ void Attr::Destroy(ASTContext &C) {
}
/// \brief Return the TypeLoc wrapper for the type source info.
-TypeLoc DeclaratorInfo::getTypeLoc() const {
+TypeLoc TypeSourceInfo::getTypeLoc() const {
return TypeLoc(Ty, (void*)(this + 1));
}
@@ -86,17 +86,17 @@ const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) {
ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- QualType T, DeclaratorInfo *DInfo,
+ QualType T, TypeSourceInfo *TInfo,
StorageClass S, Expr *DefArg) {
- return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, DInfo, S, DefArg);
+ return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo, S, DefArg);
}
SourceRange ParmVarDecl::getDefaultArgRange() const {
if (const Expr *E = getInit())
return E->getSourceRange();
- if (const Expr *E = getUninstantiatedDefaultArg())
- return E->getSourceRange();
+ if (hasUninstantiatedDefaultArg())
+ return getUninstantiatedDefaultArg()->getSourceRange();
return SourceRange();
}
@@ -136,11 +136,11 @@ bool VarDecl::isExternC() const {
FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName N, QualType T,
- DeclaratorInfo *DInfo,
+ TypeSourceInfo *TInfo,
StorageClass S, bool isInline,
bool hasWrittenPrototype) {
FunctionDecl *New
- = new (C) FunctionDecl(Function, DC, L, N, T, DInfo, S, isInline);
+ = new (C) FunctionDecl(Function, DC, L, N, T, TInfo, S, isInline);
New->HasWrittenPrototype = hasWrittenPrototype;
return New;
}
@@ -151,8 +151,8 @@ BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T,
- DeclaratorInfo *DInfo, Expr *BW, bool Mutable) {
- return new (C) FieldDecl(Decl::Field, DC, L, Id, T, DInfo, BW, Mutable);
+ TypeSourceInfo *TInfo, Expr *BW, bool Mutable) {
+ return new (C) FieldDecl(Decl::Field, DC, L, Id, T, TInfo, BW, Mutable);
}
bool FieldDecl::isAnonymousStructOrUnion() const {
@@ -179,8 +179,8 @@ void EnumConstantDecl::Destroy(ASTContext& C) {
TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- DeclaratorInfo *DInfo) {
- return new (C) TypedefDecl(DC, L, Id, DInfo);
+ TypeSourceInfo *TInfo) {
+ return new (C) TypedefDecl(DC, L, Id, TInfo);
}
EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
@@ -195,9 +195,12 @@ void EnumDecl::Destroy(ASTContext& C) {
Decl::Destroy(C);
}
-void EnumDecl::completeDefinition(ASTContext &C, QualType NewType) {
+void EnumDecl::completeDefinition(ASTContext &C,
+ QualType NewType,
+ QualType NewPromotionType) {
assert(!isDefinition() && "Cannot redefine enums!");
IntegerType = NewType;
+ PromotionType = NewPromotionType;
TagDecl::completeDefinition();
}
@@ -535,9 +538,9 @@ SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
//===----------------------------------------------------------------------===//
VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo,
+ IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
StorageClass S) {
- return new (C) VarDecl(Var, DC, L, Id, T, DInfo, S);
+ return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S);
}
void VarDecl::Destroy(ASTContext& C) {
@@ -838,8 +841,20 @@ unsigned FunctionDecl::getMinRequiredArguments() const {
}
bool FunctionDecl::isInlined() const {
- if (isInlineSpecified() || (isa<CXXMethodDecl>(this) && !isOutOfLine()))
+ // FIXME: This is not enough. Consider:
+ //
+ // inline void f();
+ // void f() { }
+ //
+ // f is inlined, but does not have inline specified.
+ // To fix this we should add an 'inline' flag to FunctionDecl.
+ if (isInlineSpecified())
return true;
+
+ if (isa<CXXMethodDecl>(this)) {
+ if (!isOutOfLine() || getCanonicalDecl()->isInlineSpecified())
+ return true;
+ }
switch (getTemplateSpecializationKind()) {
case TSK_Undeclared:
@@ -1199,7 +1214,7 @@ TagDecl* TagDecl::getDefinition(ASTContext& C) const {
TagDecl::TagKind TagDecl::getTagKindForTypeSpec(unsigned TypeSpec) {
switch (TypeSpec) {
- default: llvm::llvm_unreachable("unexpected type specifier");
+ default: llvm_unreachable("unexpected type specifier");
case DeclSpec::TST_struct: return TK_struct;
case DeclSpec::TST_class: return TK_class;
case DeclSpec::TST_union: return TK_union;
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 2dcd80b..3afb4e4 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -190,7 +190,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case CXXConstructor:
case CXXDestructor:
case CXXConversion:
- case OverloadedFunction:
case Typedef:
case EnumConstant:
case Var:
@@ -199,7 +198,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case NonTypeTemplateParm:
case ObjCMethod:
case ObjCContainer:
- case ObjCCategory:
case ObjCInterface:
case ObjCProperty:
case ObjCCompatibleAlias:
@@ -221,8 +219,9 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ObjCImplementation:
return IDNS_ObjCImplementation;
+ case ObjCCategory:
case ObjCCategoryImpl:
- return IDNS_ObjCCategoryImpl;
+ return IDNS_ObjCCategoryName;
case Field:
case ObjCAtDefsField:
@@ -637,6 +636,46 @@ bool DeclContext::decls_empty() const {
return !FirstDecl;
}
+void DeclContext::removeDecl(Decl *D) {
+ assert(D->getLexicalDeclContext() == this &&
+ "decl being removed from non-lexical context");
+ assert((D->NextDeclInContext || D == LastDecl) &&
+ "decl is not in decls list");
+
+ // Remove D from the decl chain. This is O(n) but hopefully rare.
+ if (D == FirstDecl) {
+ if (D == LastDecl)
+ FirstDecl = LastDecl = 0;
+ else
+ FirstDecl = D->NextDeclInContext;
+ } else {
+ for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) {
+ assert(I && "decl not found in linked list");
+ if (I->NextDeclInContext == D) {
+ I->NextDeclInContext = D->NextDeclInContext;
+ if (D == LastDecl) LastDecl = I;
+ break;
+ }
+ }
+ }
+
+ // Mark that D is no longer in the decl chain.
+ D->NextDeclInContext = 0;
+
+ // Remove D from the lookup table if necessary.
+ if (isa<NamedDecl>(D)) {
+ NamedDecl *ND = cast<NamedDecl>(D);
+
+ void *OpaqueMap = getPrimaryContext()->LookupPtr;
+ if (!OpaqueMap) return;
+
+ StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(OpaqueMap);
+ StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
+ assert(Pos != Map->end() && "no lookup entry for decl");
+ Pos->second.remove(ND);
+ }
+}
+
void DeclContext::addHiddenDecl(Decl *D) {
assert(D->getLexicalDeclContext() == this &&
"Decl inserted into wrong lexical context");
@@ -742,6 +781,9 @@ void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) {
// from being visible?
if (isa<ClassTemplateSpecializationDecl>(D))
return;
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (FD->isFunctionTemplateSpecialization())
+ return;
DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this) {
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 4001988..292a3ed 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -15,6 +15,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/TypeLoc.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -438,6 +439,18 @@ void CXXRecordDecl::addConversionFunction(FunctionTemplateDecl *ConvDecl) {
Conversions.addDecl(ConvDecl);
}
+
+void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) {
+ Method->setVirtualAsWritten(true);
+ setAggregate(false);
+ setPOD(false);
+ setEmpty(false);
+ setPolymorphic(true);
+ setHasTrivialConstructor(false);
+ setHasTrivialCopyConstructor(false);
+ setHasTrivialCopyAssignment(false);
+}
+
CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
@@ -459,8 +472,8 @@ CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
= new (getASTContext()) MemberSpecializationInfo(RD, TSK);
}
-TemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() {
- if (ClassTemplateSpecializationDecl *Spec
+TemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{
+ if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(this))
return Spec->getSpecializationKind();
@@ -507,8 +520,7 @@ CXXRecordDecl::getDefaultConstructor(ASTContext &Context) {
return 0;
}
-const CXXDestructorDecl *
-CXXRecordDecl::getDestructor(ASTContext &Context) {
+CXXDestructorDecl *CXXRecordDecl::getDestructor(ASTContext &Context) {
QualType ClassType = Context.getTypeDeclType(this);
DeclarationName Name
@@ -519,7 +531,7 @@ CXXRecordDecl::getDestructor(ASTContext &Context) {
llvm::tie(I, E) = lookup(Name);
assert(I != E && "Did not find a destructor!");
- const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I);
+ CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I);
assert(++I == E && "Found more than one destructor!");
return Dtor;
@@ -528,9 +540,9 @@ CXXRecordDecl::getDestructor(ASTContext &Context) {
CXXMethodDecl *
CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
- QualType T, DeclaratorInfo *DInfo,
+ QualType T, TypeSourceInfo *TInfo,
bool isStatic, bool isInline) {
- return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, DInfo,
+ return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, TInfo,
isStatic, isInline);
}
@@ -577,6 +589,8 @@ typedef llvm::DenseMap<const CXXMethodDecl*,
static OverriddenMethodsMapTy *OverriddenMethods = 0;
void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
+ assert(MD->isCanonicalDecl() && "Method is not canonical!");
+
// FIXME: The CXXMethodDecl dtor needs to remove and free the entry.
if (!OverriddenMethods)
@@ -630,55 +644,107 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {
return C.getPointerType(ClassTy);
}
-CXXBaseOrMemberInitializer::
-CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
- CXXConstructorDecl *C,
- SourceLocation L, SourceLocation R)
- : Args(0), NumArgs(0), CtorOrAnonUnion(), IdLoc(L), RParenLoc(R) {
- BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
- assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
- BaseOrMember |= 0x01;
+static bool MethodHasBody(const CXXMethodDecl *MD, const FunctionDecl *&fn) {
+ // Simple case: function has a body
+ if (MD->getBody(fn))
+ return true;
+ // Complex case: function is an instantiation of a function which has a
+ // body, but the definition hasn't been instantiated.
+ const FunctionDecl *PatternDecl = MD->getTemplateInstantiationPattern();
+ if (PatternDecl && PatternDecl->getBody(fn))
+ return true;
+
+ return false;
+}
+
+bool CXXMethodDecl::hasInlineBody() const {
+ const FunctionDecl *fn;
+ return MethodHasBody(this, fn) && !fn->isOutOfLine();
+}
+
+CXXBaseOrMemberInitializer::
+CXXBaseOrMemberInitializer(ASTContext &Context,
+ TypeSourceInfo *TInfo, CXXConstructorDecl *C,
+ SourceLocation L,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation R)
+ : BaseOrMember(TInfo), Args(0), NumArgs(0), CtorOrAnonUnion(C),
+ LParenLoc(L), RParenLoc(R)
+{
if (NumArgs > 0) {
this->NumArgs = NumArgs;
- // FIXME. Allocation via Context
- this->Args = new Stmt*[NumArgs];
+ this->Args = new (Context) Stmt*[NumArgs];
for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
this->Args[Idx] = Args[Idx];
}
- CtorOrAnonUnion = C;
}
CXXBaseOrMemberInitializer::
-CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
- CXXConstructorDecl *C,
- SourceLocation L, SourceLocation R)
- : Args(0), NumArgs(0), CtorOrAnonUnion(), IdLoc(L), RParenLoc(R) {
- BaseOrMember = reinterpret_cast<uintptr_t>(Member);
- assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");
-
+CXXBaseOrMemberInitializer(ASTContext &Context,
+ FieldDecl *Member, SourceLocation MemberLoc,
+ CXXConstructorDecl *C, SourceLocation L,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation R)
+ : BaseOrMember(Member), MemberLocation(MemberLoc), Args(0), NumArgs(0),
+ CtorOrAnonUnion(C), LParenLoc(L), RParenLoc(R)
+{
if (NumArgs > 0) {
this->NumArgs = NumArgs;
- this->Args = new Stmt*[NumArgs];
+ this->Args = new (Context) Stmt*[NumArgs];
for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
this->Args[Idx] = Args[Idx];
}
- CtorOrAnonUnion = C;
}
-CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() {
- delete [] Args;
+void CXXBaseOrMemberInitializer::Destroy(ASTContext &Context) {
+ for (unsigned I = 0; I != NumArgs; ++I)
+ Args[I]->Destroy(Context);
+ Context.Deallocate(Args);
+ this->~CXXBaseOrMemberInitializer();
+}
+
+TypeLoc CXXBaseOrMemberInitializer::getBaseClassLoc() const {
+ if (isBaseInitializer())
+ return BaseOrMember.get<TypeSourceInfo*>()->getTypeLoc();
+ else
+ return TypeLoc();
+}
+
+Type *CXXBaseOrMemberInitializer::getBaseClass() {
+ if (isBaseInitializer())
+ return BaseOrMember.get<TypeSourceInfo*>()->getType().getTypePtr();
+ else
+ return 0;
+}
+
+const Type *CXXBaseOrMemberInitializer::getBaseClass() const {
+ if (isBaseInitializer())
+ return BaseOrMember.get<TypeSourceInfo*>()->getType().getTypePtr();
+ else
+ return 0;
+}
+
+SourceLocation CXXBaseOrMemberInitializer::getSourceLocation() const {
+ if (isMemberInitializer())
+ return getMemberLocation();
+
+ return getBaseClassLoc().getSourceRange().getBegin();
+}
+
+SourceRange CXXBaseOrMemberInitializer::getSourceRange() const {
+ return SourceRange(getSourceLocation(), getRParenLoc());
}
CXXConstructorDecl *
CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
- QualType T, DeclaratorInfo *DInfo,
+ QualType T, TypeSourceInfo *TInfo,
bool isExplicit,
bool isInline, bool isImplicitlyDeclared) {
assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
"Name must refer to a constructor");
- return new (C) CXXConstructorDecl(RD, L, N, T, DInfo, isExplicit, isInline,
+ return new (C) CXXConstructorDecl(RD, L, N, T, TInfo, isExplicit, isInline,
isImplicitlyDeclared);
}
@@ -790,69 +856,11 @@ CXXConstructorDecl::Destroy(ASTContext& C) {
CXXConversionDecl *
CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
- QualType T, DeclaratorInfo *DInfo,
+ QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicit) {
assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName &&
"Name must refer to a conversion function");
- return new (C) CXXConversionDecl(RD, L, N, T, DInfo, isInline, isExplicit);
-}
-
-OverloadedFunctionDecl *
-OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
- DeclarationName N) {
- return new (C) OverloadedFunctionDecl(DC, N);
-}
-
-OverloadIterator::OverloadIterator(NamedDecl *ND) : D(0) {
- if (!ND)
- return;
-
- if (isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND))
- D = ND;
- else if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(ND)) {
- if (Ovl->size() != 0) {
- D = ND;
- Iter = Ovl->function_begin();
- }
- }
-}
-
-void OverloadedFunctionDecl::addOverload(AnyFunctionDecl F) {
- Functions.push_back(F);
- this->setLocation(F.get()->getLocation());
-}
-
-OverloadIterator::reference OverloadIterator::operator*() const {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- return FD;
-
- if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
- return FTD;
-
- assert(isa<OverloadedFunctionDecl>(D));
- return *Iter;
-}
-
-OverloadIterator &OverloadIterator::operator++() {
- if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) {
- D = 0;
- return *this;
- }
-
- if (++Iter == cast<OverloadedFunctionDecl>(D)->function_end())
- D = 0;
-
- return *this;
-}
-
-bool OverloadIterator::Equals(const OverloadIterator &Other) const {
- if (!D || !Other.D)
- return D == Other.D;
-
- if (D != Other.D)
- return false;
-
- return !isa<OverloadedFunctionDecl>(D) || Iter == Other.Iter;
+ return new (C) CXXConversionDecl(RD, L, N, T, TInfo, isInline, isExplicit);
}
FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index c33720f..2506f27 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -501,9 +501,9 @@ bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- QualType T, DeclaratorInfo *DInfo,
+ QualType T, TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW) {
- return new (C) ObjCIvarDecl(DC, L, Id, T, DInfo, ac, BW);
+ return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
}
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index a5982cf..32ac53d 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -52,7 +52,6 @@ namespace {
void VisitVarDecl(VarDecl *D);
void VisitParmVarDecl(ParmVarDecl *D);
void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
- void VisitOverloadedFunctionDecl(OverloadedFunctionDecl *D);
void VisitNamespaceDecl(NamespaceDecl *D);
void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
@@ -149,6 +148,17 @@ void Decl::printGroup(Decl** Begin, unsigned NumDecls,
}
}
+void DeclContext::dumpDeclContext() const {
+ // Get the translation unit
+ const DeclContext *DC = this;
+ while (!DC->isTranslationUnit())
+ DC = DC->getParent();
+
+ ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
+ DeclPrinter Printer(llvm::errs(), Ctx, Ctx.PrintingPolicy, 0);
+ Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
+}
+
void Decl::dump() const {
print(llvm::errs());
}
@@ -362,6 +372,24 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
}
Proto += ")";
+
+ if (FT && FT->hasExceptionSpec()) {
+ Proto += " throw(";
+ if (FT->hasAnyExceptionSpec())
+ Proto += "...";
+ else
+ for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) {
+ if (I)
+ Proto += ", ";
+
+
+ std::string ExceptionType;
+ FT->getExceptionType(I).getAsStringInternal(ExceptionType, SubPolicy);
+ Proto += ExceptionType;
+ }
+ Proto += ")";
+ }
+
if (D->hasAttr<NoReturnAttr>())
Proto += " __attribute((noreturn))";
if (CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D)) {
@@ -488,11 +516,6 @@ void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
//----------------------------------------------------------------------------
// C++ declarations
//----------------------------------------------------------------------------
-void DeclPrinter::VisitOverloadedFunctionDecl(OverloadedFunctionDecl *D) {
- assert(false &&
- "OverloadedFunctionDecls aren't really decls and are never printed");
-}
-
void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
Out << "namespace " << D->getNameAsString() << " {\n";
VisitDeclContext(D);
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 902339e..75b3975 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -262,8 +262,8 @@ NonTypeTemplateParmDecl *
NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D, unsigned P,
IdentifierInfo *Id, QualType T,
- DeclaratorInfo *DInfo) {
- return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, DInfo);
+ TypeSourceInfo *TInfo) {
+ return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, TInfo);
}
SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 3471657..0ce03c2 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -338,7 +338,7 @@ void DeclarationName::setFETokenInfo(void *T) {
DeclarationName DeclarationName::getUsingDirectiveName() {
// Single instance of DeclarationNameExtra for using-directive
- static DeclarationNameExtra UDirExtra =
+ static const DeclarationNameExtra UDirExtra =
{ DeclarationNameExtra::CXXUsingDirective };
uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 624a620..139e04b 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -110,7 +110,7 @@ void DeclRefExpr::computeDependence() {
DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- NamedDecl *D, SourceLocation NameLoc,
+ ValueDecl *D, SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs,
QualType T)
: Expr(DeclRefExprClass, T, false, false),
@@ -118,7 +118,6 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
(Qualifier? HasQualifierFlag : 0) |
(TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
Loc(NameLoc) {
- assert(!isa<OverloadedFunctionDecl>(D));
if (Qualifier) {
NameQualifier *NQ = getNameQualifier();
NQ->NNS = Qualifier;
@@ -134,7 +133,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- NamedDecl *D,
+ ValueDecl *D,
SourceLocation NameLoc,
QualType T,
const TemplateArgumentListInfo *TemplateArgs) {
@@ -204,7 +203,8 @@ std::string PredefinedExpr::ComputeName(ASTContext &Context, IdentType IT,
}
Proto += ")";
- AFT->getResultType().getAsStringInternal(Proto, Policy);
+ if (!isa<CXXConstructorDecl>(FD) && !isa<CXXDestructorDecl>(FD))
+ AFT->getResultType().getAsStringInternal(Proto, Policy);
Out << Proto;
@@ -471,7 +471,7 @@ QualType CallExpr::getCallReturnType() const {
}
MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
- SourceRange qualrange, NamedDecl *memberdecl,
+ SourceRange qualrange, ValueDecl *memberdecl,
SourceLocation l, const TemplateArgumentListInfo *targs,
QualType ty)
: Expr(MemberExprClass, ty,
@@ -494,7 +494,7 @@ MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
NestedNameSpecifier *qual,
SourceRange qualrange,
- NamedDecl *memberdecl,
+ ValueDecl *memberdecl,
SourceLocation l,
const TemplateArgumentListInfo *targs,
QualType ty) {
@@ -558,12 +558,40 @@ const char *CastExpr::getCastKindName() const {
return "FloatingCast";
case CastExpr::CK_MemberPointerToBoolean:
return "MemberPointerToBoolean";
+ case CastExpr::CK_AnyPointerToObjCPointerCast:
+ return "AnyPointerToObjCPointerCast";
+ case CastExpr::CK_AnyPointerToBlockPointerCast:
+ return "AnyPointerToBlockPointerCast";
}
assert(0 && "Unhandled cast kind!");
return 0;
}
+Expr *CastExpr::getSubExprAsWritten() {
+ Expr *SubExpr = 0;
+ CastExpr *E = this;
+ do {
+ SubExpr = E->getSubExpr();
+
+ // Skip any temporary bindings; they're implicit.
+ if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(SubExpr))
+ SubExpr = Binder->getSubExpr();
+
+ // Conversions by constructor and conversion functions have a
+ // subexpression describing the call; strip it off.
+ if (E->getCastKind() == CastExpr::CK_ConstructorConversion)
+ SubExpr = cast<CXXConstructExpr>(SubExpr)->getArg(0);
+ else if (E->getCastKind() == CastExpr::CK_UserDefinedConversion)
+ SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument();
+
+ // If the subexpression we're left with is an implicit cast, look
+ // through that, too.
+ } while ((E = dyn_cast<ImplicitCastExpr>(SubExpr)));
+
+ return SubExpr;
+}
+
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
/// corresponds to, e.g. "<<=".
const char *BinaryOperator::getOpcodeStr(Opcode Op) {
@@ -944,8 +972,7 @@ static bool DeclCanBeLvalue(const NamedDecl *Decl, ASTContext &Ctx) {
return isa<VarDecl>(Decl) || isa<FieldDecl>(Decl) ||
// C++ 3.10p2: An lvalue refers to an object or function.
(Ctx.getLangOptions().CPlusPlus &&
- (isa<FunctionDecl>(Decl) || isa<OverloadedFunctionDecl>(Decl) ||
- isa<FunctionTemplateDecl>(Decl)));
+ (isa<FunctionDecl>(Decl) || isa<FunctionTemplateDecl>(Decl)));
}
/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or an
@@ -982,6 +1009,7 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
// Check whether the expression can be sanely treated like an l-value
Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
switch (getStmtClass()) {
+ case ObjCIsaExprClass:
case StringLiteralClass: // C99 6.5.1p4
case ObjCEncodeExprClass: // @encode behaves like its string in every way.
return LV_Valid;
@@ -1343,6 +1371,13 @@ Expr *Expr::IgnoreParenNoopCasts(ASTContext &Ctx) {
}
}
+bool Expr::isDefaultArgument() const {
+ const Expr *E = this;
+ while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
+ E = ICE->getSubExprAsWritten();
+
+ return isa<CXXDefaultArgExpr>(E);
+}
/// hasAnyTypeDependentArguments - Determines if any of the expressions
/// in Exprs is type-dependent.
@@ -1598,13 +1633,18 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
// constant expression (5.19). In that case, the member can appear
// in integral constant expressions.
if (Def->isOutOfLine()) {
- Dcl->setInitKnownICE(Ctx, false);
+ Dcl->setInitKnownICE(false);
+ return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
+ }
+
+ if (Dcl->isCheckingICE()) {
return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
}
-
+
+ Dcl->setCheckingICE();
ICEDiag Result = CheckICE(Init, Ctx);
// Cache the result of the ICE test.
- Dcl->setInitKnownICE(Ctx, Result.Val == 0);
+ Dcl->setInitKnownICE(Result.Val == 0);
return Result;
}
}
@@ -1804,7 +1844,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
}
EvalResult EvalResult;
if (!Evaluate(EvalResult, Ctx))
- llvm::llvm_unreachable("ICE cannot be evaluated!");
+ llvm_unreachable("ICE cannot be evaluated!");
assert(!EvalResult.HasSideEffects && "ICE with side effects!");
assert(EvalResult.Val.isInt() && "ICE that isn't integer!");
Result = EvalResult.Val.getInt();
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index d1a0390..a9f96ad 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -199,6 +199,7 @@ bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
switch(UTT) {
default: assert(false && "Unknown type trait or not implemented");
case UTT_IsPOD: return QueriedType->isPODType();
+ case UTT_IsLiteral: return QueriedType->isLiteralType();
case UTT_IsClass: // Fallthrough
case UTT_IsUnion:
if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
@@ -518,7 +519,8 @@ Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
}
CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType,
+ bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -527,8 +529,8 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs)
: Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
- Base(Base), IsArrow(IsArrow),
- HasExplicitTemplateArgumentList(TemplateArgs),
+ Base(Base), BaseType(BaseType), IsArrow(IsArrow),
+ HasExplicitTemplateArgs(TemplateArgs != 0),
OperatorLoc(OperatorLoc),
Qualifier(Qualifier), QualifierRange(QualifierRange),
FirstQualifierFoundInScope(FirstQualifierFoundInScope),
@@ -539,7 +541,7 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
CXXDependentScopeMemberExpr *
CXXDependentScopeMemberExpr::Create(ASTContext &C,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -548,22 +550,22 @@ CXXDependentScopeMemberExpr::Create(ASTContext &C,
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs) {
if (!TemplateArgs)
- return new (C) CXXDependentScopeMemberExpr(C, Base, IsArrow, OperatorLoc,
- Qualifier, QualifierRange,
- FirstQualifierFoundInScope,
- Member, MemberLoc);
+ return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
+ IsArrow, OperatorLoc,
+ Qualifier, QualifierRange,
+ FirstQualifierFoundInScope,
+ Member, MemberLoc);
std::size_t size = sizeof(CXXDependentScopeMemberExpr);
if (TemplateArgs)
size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
- return new (Mem) CXXDependentScopeMemberExpr(C, Base, IsArrow, OperatorLoc,
- Qualifier, QualifierRange,
- FirstQualifierFoundInScope,
- Member,
- MemberLoc,
- TemplateArgs);
+ return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
+ IsArrow, OperatorLoc,
+ Qualifier, QualifierRange,
+ FirstQualifierFoundInScope,
+ Member, MemberLoc, TemplateArgs);
}
Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
@@ -571,12 +573,15 @@ Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
}
Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
+ if (isImplicitAccess())
+ return child_iterator(&Base);
return child_iterator(&Base + 1);
}
UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
bool HasUnresolvedUsing,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType,
+ bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -584,7 +589,8 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs)
: Expr(UnresolvedMemberExprClass, T, Dependent, Dependent),
- Base(Base), IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
+ Base(Base), BaseType(BaseType), IsArrow(IsArrow),
+ HasUnresolvedUsing(HasUnresolvedUsing),
HasExplicitTemplateArgs(TemplateArgs != 0),
OperatorLoc(OperatorLoc),
Qualifier(Qualifier), QualifierRange(QualifierRange),
@@ -596,7 +602,7 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
UnresolvedMemberExpr *
UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
bool HasUnresolvedUsing,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -610,8 +616,8 @@ UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
return new (Mem) UnresolvedMemberExpr(
Dependent ? C.DependentTy : C.OverloadTy,
- Dependent, HasUnresolvedUsing, Base, IsArrow,
- OperatorLoc, Qualifier, QualifierRange,
+ Dependent, HasUnresolvedUsing, Base, BaseType,
+ IsArrow, OperatorLoc, Qualifier, QualifierRange,
Member, MemberLoc, TemplateArgs);
}
@@ -620,5 +626,7 @@ Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
}
Stmt::child_iterator UnresolvedMemberExpr::child_end() {
+ if (isImplicitAccess())
+ return child_iterator(&Base);
return child_iterator(&Base + 1);
}
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index a20e1cc..13831dc 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -848,16 +848,8 @@ static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) {
// Enums are integer constant exprs.
- if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
- // FIXME: This is an ugly hack around the fact that enums don't set their
- // signedness consistently; see PR3173.
- APSInt SI = ECD->getInitVal();
- SI.setIsUnsigned(!E->getType()->isSignedIntegerType());
- // FIXME: This is an ugly hack around the fact that enums don't
- // set their width (!?!) consistently; see PR3173.
- SI.extOrTrunc(Info.Ctx.getIntWidth(E->getType()));
- return Success(SI, E);
- }
+ if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
+ return Success(ECD->getInitVal(), E);
// In C++, const, non-volatile integers initialized with ICEs are ICEs.
// In C, they can also be folded, although they are not ICEs.
@@ -866,15 +858,24 @@ bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) {
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
const VarDecl *Def = 0;
if (const Expr *Init = VD->getDefinition(Def)) {
- if (APValue *V = VD->getEvaluatedValue())
- return Success(V->getInt(), E);
-
+ if (APValue *V = VD->getEvaluatedValue()) {
+ if (V->isInt())
+ return Success(V->getInt(), E);
+ return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+ }
+
+ if (VD->isEvaluatingValue())
+ return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+
+ VD->setEvaluatingValue();
+
if (Visit(const_cast<Expr*>(Init))) {
// Cache the evaluated value in the variable declaration.
- VD->setEvaluatedValue(Info.Ctx, Result);
+ VD->setEvaluatedValue(Result);
return true;
}
+ VD->setEvaluatedValue(APValue());
return false;
}
}
@@ -1506,6 +1507,7 @@ public:
bool VisitFloatingLiteral(const FloatingLiteral *E);
bool VisitCastExpr(CastExpr *E);
bool VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
+ bool VisitConditionalOperator(ConditionalOperator *E);
bool VisitChooseExpr(const ChooseExpr *E)
{ return Visit(E->getChosenSubExpr(Info.Ctx)); }
@@ -1513,8 +1515,7 @@ public:
{ return Visit(E->getSubExpr()); }
// FIXME: Missing: __real__/__imag__, array subscript of vector,
- // member of vector, ImplicitValueInitExpr,
- // conditional ?:
+ // member of vector, ImplicitValueInitExpr
};
} // end anonymous namespace
@@ -1547,16 +1548,10 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
if (!S->isWide()) {
const llvm::fltSemantics &Sem =
Info.Ctx.getFloatTypeSemantics(E->getType());
- llvm::SmallString<16> s;
- s.append(S->getStrData(), S->getStrData() + S->getByteLength());
- s += '\0';
- long l;
- char *endp;
- l = strtol(&s[0], &endp, 0);
- if (endp != s.end()-1)
+ unsigned Type = 0;
+ if (!S->getString().empty() && S->getString().getAsInteger(0, Type))
return false;
- unsigned type = (unsigned int)l;;
- Result = llvm::APFloat::getNaN(Sem, false, type);
+ Result = llvm::APFloat::getNaN(Sem, false, Type);
return true;
}
}
@@ -1673,6 +1668,14 @@ bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
return true;
}
+bool FloatExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
+ bool Cond;
+ if (!HandleConversionToBool(E->getCond(), Cond, Info))
+ return false;
+
+ return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
+}
+
//===----------------------------------------------------------------------===//
// Complex Evaluation (for float and integer)
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 326a1dc..c914f3f 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -663,31 +663,6 @@ void ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
Alignment = NewAlignment;
}
-static const CXXMethodDecl *GetKeyFunction(const CXXRecordDecl *RD) {
- if (!RD->isDynamicClass())
- return 0;
-
- for (CXXRecordDecl::method_iterator I = RD->method_begin(),
- E = RD->method_end(); I != E; ++I) {
- const CXXMethodDecl *MD = *I;
-
- if (!MD->isVirtual())
- continue;
-
- if (MD->isPure())
- continue;
-
- const FunctionDecl *fn;
- if (MD->getBody(fn) && !fn->isOutOfLine())
- continue;
-
- // We found it.
- return MD;
- }
-
- return 0;
-}
-
const ASTRecordLayout *
ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
const RecordDecl *D) {
@@ -711,8 +686,6 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
uint64_t NonVirtualSize =
IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
- const CXXMethodDecl *KeyFunction = GetKeyFunction(cast<CXXRecordDecl>(D));
-
return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size(),
@@ -722,8 +695,7 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
Builder.Bases.data(),
Builder.Bases.size(),
Builder.VBases.data(),
- Builder.VBases.size(),
- KeyFunction);
+ Builder.VBases.size());
}
const ASTRecordLayout *
@@ -739,3 +711,51 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size());
}
+
+const CXXMethodDecl *
+ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
+ assert(RD->isDynamicClass() && "Class does not have any virtual methods!");
+
+ // If a class isnt' polymorphic it doesn't have a key function.
+ if (!RD->isPolymorphic())
+ return 0;
+
+ // A class template specialization or instantation does not have a key
+ // function.
+ if (RD->getTemplateSpecializationKind() != TSK_Undeclared)
+ return 0;
+
+ // A class inside an anonymous namespace doesn't have a key function. (Or
+ // at least, there's no point to assigning a key function to such a class;
+ // this doesn't affect the ABI.)
+ if (RD->isInAnonymousNamespace())
+ return 0;
+
+ for (CXXRecordDecl::method_iterator I = RD->method_begin(),
+ E = RD->method_end(); I != E; ++I) {
+ const CXXMethodDecl *MD = *I;
+
+ if (!MD->isVirtual())
+ continue;
+
+ if (MD->isPure())
+ continue;
+
+ if (MD->isInlineSpecified())
+ continue;
+
+ // Ignore implicit member functions, they are always marked as inline, but
+ // they don't have a body until they're defined.
+ if (MD->isImplicit())
+ continue;
+
+ if (MD->hasInlineBody())
+ continue;
+
+ // We found it.
+ return MD;
+ }
+
+ return 0;
+}
+
diff --git a/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h
index 69e0498..d4171d3 100644
--- a/lib/AST/RecordLayoutBuilder.h
+++ b/lib/AST/RecordLayoutBuilder.h
@@ -151,6 +151,7 @@ public:
static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx,
const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
+ static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD);
};
} // end namespace clang
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index bbe6a71..ae76526 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -17,7 +17,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/SourceManager.h"
-#include <cstdio>
+#include "llvm/Support/raw_ostream.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -27,7 +27,7 @@ using namespace clang;
namespace {
class StmtDumper : public StmtVisitor<StmtDumper> {
SourceManager *SM;
- FILE *F;
+ llvm::raw_ostream &OS;
unsigned IndentLevel;
/// MaxDepth - When doing a normal dump (not dumpAll) we only want to dump
@@ -41,8 +41,8 @@ namespace {
unsigned LastLocLine;
public:
- StmtDumper(SourceManager *sm, FILE *f, unsigned maxDepth)
- : SM(sm), F(f), IndentLevel(0-1), MaxDepth(maxDepth) {
+ StmtDumper(SourceManager *sm, llvm::raw_ostream &os, unsigned maxDepth)
+ : SM(sm), OS(os), IndentLevel(0-1), MaxDepth(maxDepth) {
LastLocFilename = "";
LastLocLine = ~0U;
}
@@ -62,15 +62,15 @@ namespace {
Stmt::child_iterator CI = S->child_begin(), CE = S->child_end();
if (CI != CE) {
while (CI != CE) {
- fprintf(F, "\n");
+ OS << '\n';
DumpSubTree(*CI++);
}
}
- fprintf(F, ")");
+ OS << ')';
}
} else {
Indent();
- fprintf(F, "<<<NULL>>>");
+ OS << "<<<NULL>>>";
}
--IndentLevel;
}
@@ -79,27 +79,28 @@ namespace {
void Indent() const {
for (int i = 0, e = IndentLevel; i < e; ++i)
- fprintf(F, " ");
+ OS << " ";
}
void DumpType(QualType T) {
- fprintf(F, "'%s'", T.getAsString().c_str());
+ OS << "'" << T.getAsString() << "'";
if (!T.isNull()) {
// If the type is sugared, also dump a (shallow) desugared type.
QualType Simplified = T.getDesugaredType();
if (Simplified != T)
- fprintf(F, ":'%s'", Simplified.getAsString().c_str());
+ OS << ":'" << Simplified.getAsString() << "'";
}
}
void DumpStmt(const Stmt *Node) {
Indent();
- fprintf(F, "(%s %p", Node->getStmtClassName(), (void*)Node);
+ OS << "(" << Node->getStmtClassName()
+ << " " << (void*)Node;
DumpSourceRange(Node);
}
void DumpExpr(const Expr *Node) {
DumpStmt(Node);
- fprintf(F, " ");
+ OS << ' ';
DumpType(Node->getType());
}
void DumpSourceRange(const Stmt *Node);
@@ -138,6 +139,7 @@ namespace {
void VisitCXXConstructExpr(CXXConstructExpr *Node);
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node);
void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *Node);
+ void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node);
void DumpCXXTemporary(CXXTemporary *Temporary);
// ObjC
@@ -161,7 +163,7 @@ void StmtDumper::DumpLocation(SourceLocation Loc) {
SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
if (SpellingLoc.isInvalid()) {
- fprintf(stderr, "<invalid sloc>");
+ OS << "<invalid sloc>";
return;
}
@@ -170,15 +172,16 @@ void StmtDumper::DumpLocation(SourceLocation Loc) {
PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
- fprintf(stderr, "%s:%u:%u", PLoc.getFilename(), PLoc.getLine(),
- PLoc.getColumn());
+ OS << PLoc.getFilename() << ':' << PLoc.getLine()
+ << ':' << PLoc.getColumn();
LastLocFilename = PLoc.getFilename();
LastLocLine = PLoc.getLine();
} else if (PLoc.getLine() != LastLocLine) {
- fprintf(stderr, "line:%u:%u", PLoc.getLine(), PLoc.getColumn());
+ OS << "line" << ':' << PLoc.getLine()
+ << ':' << PLoc.getColumn();
LastLocLine = PLoc.getLine();
} else {
- fprintf(stderr, "col:%u", PLoc.getColumn());
+ OS << "col" << ':' << PLoc.getColumn();
}
}
@@ -190,13 +193,13 @@ void StmtDumper::DumpSourceRange(const Stmt *Node) {
// location.
SourceRange R = Node->getSourceRange();
- fprintf(stderr, " <");
+ OS << " <";
DumpLocation(R.getBegin());
if (R.getBegin() != R.getEnd()) {
- fprintf(stderr, ", ");
+ OS << ", ";
DumpLocation(R.getEnd());
}
- fprintf(stderr, ">");
+ OS << ">";
// <t2.c:123:421[blah], t2.c:412:321>
@@ -215,31 +218,30 @@ void StmtDumper::DumpDeclarator(Decl *D) {
// FIXME: Need to complete/beautify this... this code simply shows the
// nodes are where they need to be.
if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
- fprintf(F, "\"typedef %s %s\"",
- localType->getUnderlyingType().getAsString().c_str(),
- localType->getNameAsString().c_str());
+ OS << "\"typedef " << localType->getUnderlyingType().getAsString()
+ << " " << localType->getNameAsString() << "\"";
} else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
- fprintf(F, "\"");
+ OS << "\"";
// Emit storage class for vardecls.
if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
if (V->getStorageClass() != VarDecl::None)
- fprintf(F, "%s ",
- VarDecl::getStorageClassSpecifierString(V->getStorageClass()));
+ OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass())
+ << " ";
}
std::string Name = VD->getNameAsString();
VD->getType().getAsStringInternal(Name,
PrintingPolicy(VD->getASTContext().getLangOptions()));
- fprintf(F, "%s", Name.c_str());
+ OS << Name;
// If this is a vardecl with an initializer, emit it.
if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
if (V->getInit()) {
- fprintf(F, " =\n");
+ OS << " =\n";
DumpSubTree(V->getInit());
}
}
- fprintf(F, "\"");
+ OS << '"';
} else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
// print a free standing tag decl (e.g. "struct x;").
const char *tagname;
@@ -247,7 +249,7 @@ void StmtDumper::DumpDeclarator(Decl *D) {
tagname = II->getNameStart();
else
tagname = "<anonymous>";
- fprintf(F, "\"%s %s;\"", TD->getKindName(), tagname);
+ OS << '"' << TD->getKindName() << ' ' << tagname << ";\"";
// FIXME: print tag bodies.
} else if (UsingDirectiveDecl *UD = dyn_cast<UsingDirectiveDecl>(D)) {
// print using-directive decl (e.g. "using namespace x;")
@@ -256,7 +258,7 @@ void StmtDumper::DumpDeclarator(Decl *D) {
ns = II->getNameStart();
else
ns = "<anonymous>";
- fprintf(F, "\"%s %s;\"",UD->getDeclKindName(), ns);
+ OS << '"' << UD->getDeclKindName() << ns << ";\"";
} else {
assert(0 && "Unexpected decl");
}
@@ -264,28 +266,29 @@ void StmtDumper::DumpDeclarator(Decl *D) {
void StmtDumper::VisitDeclStmt(DeclStmt *Node) {
DumpStmt(Node);
- fprintf(F,"\n");
+ OS << "\n";
for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
DI != DE; ++DI) {
Decl* D = *DI;
++IndentLevel;
Indent();
- fprintf(F, "%p ", (void*) D);
+ OS << (void*) D << " ";
DumpDeclarator(D);
if (DI+1 != DE)
- fprintf(F,"\n");
+ OS << "\n";
--IndentLevel;
}
}
void StmtDumper::VisitLabelStmt(LabelStmt *Node) {
DumpStmt(Node);
- fprintf(F, " '%s'", Node->getName());
+ OS << " '" << Node->getName() << "'";
}
void StmtDumper::VisitGotoStmt(GotoStmt *Node) {
DumpStmt(Node);
- fprintf(F, " '%s':%p", Node->getLabel()->getName(), (void*)Node->getLabel());
+ OS << " '" << Node->getLabel()->getName()
+ << "':" << (void*)Node->getLabel();
}
//===----------------------------------------------------------------------===//
@@ -298,129 +301,130 @@ void StmtDumper::VisitExpr(Expr *Node) {
void StmtDumper::VisitCastExpr(CastExpr *Node) {
DumpExpr(Node);
- fprintf(F, " <%s>", Node->getCastKindName());
+ OS << " <" << Node->getCastKindName() << ">";
}
void StmtDumper::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
VisitCastExpr(Node);
if (Node->isLvalueCast())
- fprintf(F, " lvalue");
+ OS << " lvalue";
}
void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
DumpExpr(Node);
- fprintf(F, " ");
+ OS << " ";
switch (Node->getDecl()->getKind()) {
- default: fprintf(F,"Decl"); break;
- case Decl::Function: fprintf(F,"FunctionDecl"); break;
- case Decl::Var: fprintf(F,"Var"); break;
- case Decl::ParmVar: fprintf(F,"ParmVar"); break;
- case Decl::EnumConstant: fprintf(F,"EnumConstant"); break;
- case Decl::Typedef: fprintf(F,"Typedef"); break;
- case Decl::Record: fprintf(F,"Record"); break;
- case Decl::Enum: fprintf(F,"Enum"); break;
- case Decl::CXXRecord: fprintf(F,"CXXRecord"); break;
- case Decl::ObjCInterface: fprintf(F,"ObjCInterface"); break;
- case Decl::ObjCClass: fprintf(F,"ObjCClass"); break;
+ default: OS << "Decl"; break;
+ case Decl::Function: OS << "FunctionDecl"; break;
+ case Decl::Var: OS << "Var"; break;
+ case Decl::ParmVar: OS << "ParmVar"; break;
+ case Decl::EnumConstant: OS << "EnumConstant"; break;
+ case Decl::Typedef: OS << "Typedef"; break;
+ case Decl::Record: OS << "Record"; break;
+ case Decl::Enum: OS << "Enum"; break;
+ case Decl::CXXRecord: OS << "CXXRecord"; break;
+ case Decl::ObjCInterface: OS << "ObjCInterface"; break;
+ case Decl::ObjCClass: OS << "ObjCClass"; break;
}
- fprintf(F, "='%s' %p", Node->getDecl()->getNameAsString().c_str(),
- (void*)Node->getDecl());
+ OS << "='" << Node->getDecl()->getNameAsString()
+ << "' " << (void*)Node->getDecl();
+}
+
+void StmtDumper::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
+ DumpExpr(Node);
+ OS << " (";
+ if (!Node->requiresADL()) OS << "no ";
+ OS << "ADL) = '" << Node->getName().getAsString() << "'";
+
+ UnresolvedLookupExpr::decls_iterator
+ I = Node->decls_begin(), E = Node->decls_end();
+ if (I == E) OS << " empty";
+ for (; I != E; ++I)
+ OS << " " << (void*) *I;
}
void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
DumpExpr(Node);
- fprintf(F, " %sDecl='%s' %p", Node->getDecl()->getDeclKindName(),
- Node->getDecl()->getNameAsString().c_str(), (void*)Node->getDecl());
+ OS << " " << Node->getDecl()->getDeclKindName()
+ << "Decl='" << Node->getDecl()->getNameAsString()
+ << "' " << (void*)Node->getDecl();
if (Node->isFreeIvar())
- fprintf(F, " isFreeIvar");
+ OS << " isFreeIvar";
}
void StmtDumper::VisitPredefinedExpr(PredefinedExpr *Node) {
DumpExpr(Node);
switch (Node->getIdentType()) {
default: assert(0 && "unknown case");
- case PredefinedExpr::Func: fprintf(F, " __func__"); break;
- case PredefinedExpr::Function: fprintf(F, " __FUNCTION__"); break;
- case PredefinedExpr::PrettyFunction: fprintf(F, " __PRETTY_FUNCTION__");break;
+ case PredefinedExpr::Func: OS << " __func__"; break;
+ case PredefinedExpr::Function: OS << " __FUNCTION__"; break;
+ case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break;
}
}
void StmtDumper::VisitCharacterLiteral(CharacterLiteral *Node) {
DumpExpr(Node);
- fprintf(F, " %d", Node->getValue());
+ OS << Node->getValue();
}
void StmtDumper::VisitIntegerLiteral(IntegerLiteral *Node) {
DumpExpr(Node);
bool isSigned = Node->getType()->isSignedIntegerType();
- fprintf(F, " %s", Node->getValue().toString(10, isSigned).c_str());
+ OS << " " << Node->getValue().toString(10, isSigned);
}
void StmtDumper::VisitFloatingLiteral(FloatingLiteral *Node) {
DumpExpr(Node);
- fprintf(F, " %f", Node->getValueAsApproximateDouble());
+ OS << " " << Node->getValueAsApproximateDouble();
}
void StmtDumper::VisitStringLiteral(StringLiteral *Str) {
DumpExpr(Str);
// FIXME: this doesn't print wstrings right.
- fprintf(F, " %s\"", Str->isWide() ? "L" : "");
-
- for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
- switch (char C = Str->getStrData()[i]) {
- default:
- if (isprint(C))
- fputc(C, F);
- else
- fprintf(F, "\\%03o", C);
- break;
- // Handle some common ones to make dumps prettier.
- case '\\': fprintf(F, "\\\\"); break;
- case '"': fprintf(F, "\\\""); break;
- case '\n': fprintf(F, "\\n"); break;
- case '\t': fprintf(F, "\\t"); break;
- case '\a': fprintf(F, "\\a"); break;
- case '\b': fprintf(F, "\\b"); break;
- }
- }
- fprintf(F, "\"");
+ OS << " ";
+ if (Str->isWide())
+ OS << "L";
+ OS << '"';
+ OS.write_escaped(llvm::StringRef(Str->getStrData(),
+ Str->getByteLength()));
+ OS << '"';
}
void StmtDumper::VisitUnaryOperator(UnaryOperator *Node) {
DumpExpr(Node);
- fprintf(F, " %s '%s'", Node->isPostfix() ? "postfix" : "prefix",
- UnaryOperator::getOpcodeStr(Node->getOpcode()));
+ OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
+ << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
}
void StmtDumper::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
DumpExpr(Node);
- fprintf(F, " %s ", Node->isSizeOf() ? "sizeof" : "alignof");
+ OS << " " << (Node->isSizeOf() ? "sizeof" : "alignof") << " ";
if (Node->isArgumentType())
DumpType(Node->getArgumentType());
}
void StmtDumper::VisitMemberExpr(MemberExpr *Node) {
DumpExpr(Node);
- fprintf(F, " %s%s %p", Node->isArrow() ? "->" : ".",
- Node->getMemberDecl()->getNameAsString().c_str(),
- (void*)Node->getMemberDecl());
+ OS << " " << (Node->isArrow() ? "->" : ".")
+ << Node->getMemberDecl()->getNameAsString() << " "
+ << (void*)Node->getMemberDecl();
}
void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
DumpExpr(Node);
- fprintf(F, " %s", Node->getAccessor().getNameStart());
+ OS << " " << Node->getAccessor().getNameStart();
}
void StmtDumper::VisitBinaryOperator(BinaryOperator *Node) {
DumpExpr(Node);
- fprintf(F, " '%s'", BinaryOperator::getOpcodeStr(Node->getOpcode()));
+ OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
}
void StmtDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
DumpExpr(Node);
- fprintf(F, " '%s' ComputeLHSTy=",
- BinaryOperator::getOpcodeStr(Node->getOpcode()));
+ OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
+ << "' ComputeLHSTy=";
DumpType(Node->getComputationLHSType());
- fprintf(F, " ComputeResultTy=");
+ OS << " ComputeResultTy=";
DumpType(Node->getComputationResultType());
}
@@ -428,14 +432,15 @@ void StmtDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
void StmtDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) {
DumpExpr(Node);
- fprintf(F, " %s %p", Node->getLabel()->getName(), (void*)Node->getLabel());
+ OS << " " << Node->getLabel()->getName()
+ << " " << (void*)Node->getLabel();
}
void StmtDumper::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
DumpExpr(Node);
- fprintf(F, " ");
+ OS << " ";
DumpType(Node->getArgType1());
- fprintf(F, " ");
+ OS << " ";
DumpType(Node->getArgType2());
}
@@ -445,36 +450,35 @@ void StmtDumper::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
void StmtDumper::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
DumpExpr(Node);
- fprintf(F, " %s<%s> <%s>", Node->getCastName(),
- Node->getTypeAsWritten().getAsString().c_str(),
- Node->getCastKindName());
+ OS << " " << Node->getCastName()
+ << "<" << Node->getTypeAsWritten().getAsString() << ">"
+ << " <" << Node->getCastKindName() << ">";
}
void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
DumpExpr(Node);
- fprintf(F, " %s", Node->getValue() ? "true" : "false");
+ OS << " " << (Node->getValue() ? "true" : "false");
}
void StmtDumper::VisitCXXThisExpr(CXXThisExpr *Node) {
DumpExpr(Node);
- fprintf(F, " this");
+ OS << " this";
}
void StmtDumper::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
DumpExpr(Node);
- fprintf(F, " functional cast to %s",
- Node->getTypeAsWritten().getAsString().c_str());
+ OS << " functional cast to " << Node->getTypeAsWritten().getAsString();
}
void StmtDumper::VisitCXXConstructExpr(CXXConstructExpr *Node) {
DumpExpr(Node);
if (Node->isElidable())
- fprintf(F, " elidable");
+ OS << " elidable";
}
void StmtDumper::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
DumpExpr(Node);
- fprintf(F, " ");
+ OS << " ";
DumpCXXTemporary(Node->getTemporary());
}
@@ -482,7 +486,7 @@ void StmtDumper::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *Node) {
DumpExpr(Node);
++IndentLevel;
for (unsigned i = 0, e = Node->getNumTemporaries(); i != e; ++i) {
- fprintf(F, "\n");
+ OS << "\n";
Indent();
DumpCXXTemporary(Node->getTemporary(i));
}
@@ -490,7 +494,7 @@ void StmtDumper::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *Node) {
}
void StmtDumper::DumpCXXTemporary(CXXTemporary *Temporary) {
- fprintf(F, "(CXXTemporary %p)", (void *)Temporary);
+ OS << "(CXXTemporary " << (void *)Temporary << ")";
}
//===----------------------------------------------------------------------===//
@@ -499,37 +503,34 @@ void StmtDumper::DumpCXXTemporary(CXXTemporary *Temporary) {
void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
DumpExpr(Node);
- fprintf(F, " selector=%s", Node->getSelector().getAsString().c_str());
- IdentifierInfo* clsName = Node->getClassName();
- if (clsName) fprintf(F, " class=%s", clsName->getNameStart());
+ OS << " selector=" << Node->getSelector().getAsString();
+ if (IdentifierInfo *clsName = Node->getClassName())
+ OS << " class=" << clsName->getNameStart();
}
void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
DumpExpr(Node);
-
- fprintf(F, " ");
+ OS << " ";
DumpType(Node->getEncodedType());
}
void StmtDumper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
DumpExpr(Node);
- fprintf(F, " ");
- fprintf(F, "%s", Node->getSelector().getAsString().c_str());
+ OS << " " << Node->getSelector().getAsString();
}
void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
DumpExpr(Node);
- fprintf(F, " ");
- fprintf(F, "%s", Node->getProtocol()->getNameAsString().c_str());
+ OS << " " << Node->getProtocol()->getNameAsString();
}
void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
DumpExpr(Node);
- fprintf(F, " Kind=PropertyRef Property=\"%s\"",
- Node->getProperty()->getNameAsString().c_str());
+ OS << " Kind=PropertyRef Property=\""
+ << Node->getProperty()->getNameAsString() << "\"";
}
void StmtDumper::VisitObjCImplicitSetterGetterRefExpr(
@@ -538,14 +539,19 @@ void StmtDumper::VisitObjCImplicitSetterGetterRefExpr(
ObjCMethodDecl *Getter = Node->getGetterMethod();
ObjCMethodDecl *Setter = Node->getSetterMethod();
- fprintf(F, " Kind=MethodRef Getter=\"%s\" Setter=\"%s\"",
- Getter->getSelector().getAsString().c_str(),
- Setter ? Setter->getSelector().getAsString().c_str() : "(null)");
+ OS << " Kind=MethodRef Getter=\""
+ << Getter->getSelector().getAsString()
+ << "\" Setter=\"";
+ if (Setter)
+ OS << Setter->getSelector().getAsString();
+ else
+ OS << "(null)";
+ OS << "\"";
}
void StmtDumper::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
DumpExpr(Node);
- fprintf(F, " super");
+ OS << " super";
}
//===----------------------------------------------------------------------===//
@@ -556,30 +562,30 @@ void StmtDumper::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
/// specified node and a few nodes underneath it, but not the whole subtree.
/// This is useful in a debugger.
void Stmt::dump(SourceManager &SM) const {
- StmtDumper P(&SM, stderr, 4);
+ StmtDumper P(&SM, llvm::errs(), 4);
P.DumpSubTree(const_cast<Stmt*>(this));
- fprintf(stderr, "\n");
+ llvm::errs() << "\n";
}
/// dump - This does a local dump of the specified AST fragment. It dumps the
/// specified node and a few nodes underneath it, but not the whole subtree.
/// This is useful in a debugger.
void Stmt::dump() const {
- StmtDumper P(0, stderr, 4);
+ StmtDumper P(0, llvm::errs(), 4);
P.DumpSubTree(const_cast<Stmt*>(this));
- fprintf(stderr, "\n");
+ llvm::errs() << "\n";
}
/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
void Stmt::dumpAll(SourceManager &SM) const {
- StmtDumper P(&SM, stderr, ~0U);
+ StmtDumper P(&SM, llvm::errs(), ~0U);
P.DumpSubTree(const_cast<Stmt*>(this));
- fprintf(stderr, "\n");
+ llvm::errs() << "\n";
}
/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
void Stmt::dumpAll() const {
- StmtDumper P(0, stderr, ~0U);
+ StmtDumper P(0, llvm::errs(), ~0U);
P.DumpSubTree(const_cast<Stmt*>(this));
- fprintf(stderr, "\n");
+ llvm::errs() << "\n";
}
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 205ea0d..a7e42af 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1145,17 +1145,19 @@ StmtPrinter::VisitCXXUnresolvedConstructExpr(
void StmtPrinter::VisitCXXDependentScopeMemberExpr(
CXXDependentScopeMemberExpr *Node) {
- PrintExpr(Node->getBase());
- OS << (Node->isArrow() ? "->" : ".");
+ if (!Node->isImplicitAccess()) {
+ PrintExpr(Node->getBase());
+ OS << (Node->isArrow() ? "->" : ".");
+ }
if (NestedNameSpecifier *Qualifier = Node->getQualifier())
Qualifier->print(OS, Policy);
- else if (Node->hasExplicitTemplateArgumentList())
+ else if (Node->hasExplicitTemplateArgs())
// FIXME: Track use of "template" keyword explicitly?
OS << "template ";
OS << Node->getMember().getAsString();
- if (Node->hasExplicitTemplateArgumentList()) {
+ if (Node->hasExplicitTemplateArgs()) {
OS << TemplateSpecializationType::PrintTemplateArgumentList(
Node->getTemplateArgs(),
Node->getNumTemplateArgs(),
@@ -1164,8 +1166,10 @@ void StmtPrinter::VisitCXXDependentScopeMemberExpr(
}
void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
- PrintExpr(Node->getBase());
- OS << (Node->isArrow() ? "->" : ".");
+ if (!Node->isImplicitAccess()) {
+ PrintExpr(Node->getBase());
+ OS << (Node->isArrow() ? "->" : ".");
+ }
if (NestedNameSpecifier *Qualifier = Node->getQualifier())
Qualifier->print(OS, Policy);
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index d832a46..e2d772b 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -554,18 +554,24 @@ StmtProfiler::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *S) {
void
StmtProfiler::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *S) {
- VisitExpr(S);
- ID.AddBoolean(S->isArrow());
+ ID.AddBoolean(S->isImplicitAccess());
+ if (!S->isImplicitAccess()) {
+ VisitExpr(S);
+ ID.AddBoolean(S->isArrow());
+ }
VisitNestedNameSpecifier(S->getQualifier());
VisitName(S->getMember());
- ID.AddBoolean(S->hasExplicitTemplateArgumentList());
- if (S->hasExplicitTemplateArgumentList())
+ ID.AddBoolean(S->hasExplicitTemplateArgs());
+ if (S->hasExplicitTemplateArgs())
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
}
void StmtProfiler::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *S) {
- VisitExpr(S);
- ID.AddBoolean(S->isArrow());
+ ID.AddBoolean(S->isImplicitAccess());
+ if (!S->isImplicitAccess()) {
+ VisitExpr(S);
+ ID.AddBoolean(S->isArrow());
+ }
VisitNestedNameSpecifier(S->getQualifier());
VisitName(S->getMemberName());
ID.AddBoolean(S->hasExplicitTemplateArgs());
@@ -653,13 +659,6 @@ void StmtProfiler::VisitDecl(Decl *D) {
ID.AddInteger(TTP->getIndex());
return;
}
-
- if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D)) {
- // The Itanium C++ ABI mangles references to a set of overloaded
- // functions using just the function name, so we do the same here.
- VisitName(Ovl->getDeclName());
- return;
- }
}
ID.AddPointer(D? D->getCanonicalDecl() : 0);
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index f341b45..e9b1725 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -102,7 +102,7 @@ SourceRange TemplateArgumentLoc::getSourceRange() const {
return getSourceDeclExpression()->getSourceRange();
case TemplateArgument::Type:
- return getSourceDeclaratorInfo()->getTypeLoc().getFullSourceRange();
+ return getTypeSourceInfo()->getTypeLoc().getFullSourceRange();
case TemplateArgument::Template:
if (getTemplateQualifierRange().isValid())
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index 5b4cf0a..b56c0ceb 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -29,25 +29,14 @@ TemplateDecl *TemplateName::getAsTemplateDecl() const {
return 0;
}
-OverloadedFunctionDecl *TemplateName::getAsOverloadedFunctionDecl() const {
- if (OverloadedFunctionDecl *Ovl
- = Storage.dyn_cast<OverloadedFunctionDecl *>())
- return Ovl;
-
- if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
- return QTN->getOverloadedFunctionDecl();
-
- return 0;
-}
-
bool TemplateName::isDependent() const {
if (TemplateDecl *Template = getAsTemplateDecl()) {
return isa<TemplateTemplateParmDecl>(Template) ||
Template->getDeclContext()->isDependentContext();
}
- if (OverloadedFunctionDecl *Ovl = getAsOverloadedFunctionDecl())
- return Ovl->getDeclContext()->isDependentContext();
+ assert(!getAsOverloadedTemplate() &&
+ "overloaded templates shouldn't survive to here");
return true;
}
@@ -57,9 +46,6 @@ TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
bool SuppressNNS) const {
if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
OS << Template->getNameAsString();
- else if (OverloadedFunctionDecl *Ovl
- = Storage.dyn_cast<OverloadedFunctionDecl *>())
- OS << Ovl->getNameAsString();
else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
if (!SuppressNNS)
QTN->getQualifier()->print(OS, Policy);
@@ -84,13 +70,3 @@ void TemplateName::dump() const {
LO.Bool = true;
print(llvm::errs(), PrintingPolicy(LO));
}
-
-TemplateDecl *QualifiedTemplateName::getTemplateDecl() const {
- return dyn_cast<TemplateDecl>(Template);
-}
-
-OverloadedFunctionDecl *
-QualifiedTemplateName::getOverloadedFunctionDecl() const {
- return dyn_cast<OverloadedFunctionDecl>(Template);
-}
-
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 5a2434d..687beae 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -434,6 +434,18 @@ bool Type::isWideCharType() const {
return false;
}
+/// \brief Determine whether this type is any of the built-in character
+/// types.
+bool Type::isAnyCharacterType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return (BT->getKind() >= BuiltinType::Char_U &&
+ BT->getKind() <= BuiltinType::Char32) ||
+ (BT->getKind() >= BuiltinType::Char_S &&
+ BT->getKind() <= BuiltinType::WChar);
+
+ return false;
+}
+
/// isSignedIntegerType - Return true if this is an integer type that is
/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
/// an enum decl which has a signed representation, or a vector of signed
@@ -639,6 +651,40 @@ bool Type::isPODType() const {
}
}
+bool Type::isLiteralType() const {
+ if (isIncompleteType())
+ return false;
+
+ // C++0x [basic.types]p10:
+ // A type is a literal type if it is:
+ switch (CanonicalType->getTypeClass()) {
+ // We're whitelisting
+ default: return false;
+
+ // -- a scalar type
+ case Builtin:
+ case Complex:
+ case Pointer:
+ case MemberPointer:
+ case Vector:
+ case ExtVector:
+ case ObjCObjectPointer:
+ case Enum:
+ return true;
+
+ // -- a class type with ...
+ case Record:
+ // FIXME: Do the tests
+ return false;
+
+ // -- an array of literal type
+ // Extension: variable arrays cannot be literal types, since they're
+ // runtime-sized.
+ case ConstantArray:
+ return cast<ArrayType>(CanonicalType)->getElementType()->isLiteralType();
+ }
+}
+
bool Type::isPromotableIntegerType() const {
if (const BuiltinType *BT = getAs<BuiltinType>())
switch (BT->getKind()) {
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index 50a5120..3ccb7a9 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -94,3 +94,32 @@ void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) {
TypeLocInitializer(Loc).Visit(TL);
} while ((TL = TL.getNextTypeLoc()));
}
+
+namespace {
+ struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
+ // Overload resolution does the real work for us.
+ static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
+ static bool isTypeSpec(TypeLoc _) { return false; }
+
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+ return isTypeSpec(TyLoc); \
+ }
+#include "clang/AST/TypeLocNodes.def"
+ };
+}
+
+
+/// \brief Determines if the given type loc corresponds to a
+/// TypeSpecTypeLoc. Since there is not actually a TypeSpecType in
+/// the type hierarchy, this is made somewhat complicated.
+///
+/// There are a lot of types that currently use TypeSpecTypeLoc
+/// because it's a convenient base class. Ideally we would not accept
+/// those here, but ideally we would have better implementations for
+/// them.
+bool TypeSpecTypeLoc::classof(const TypeLoc *TL) {
+ if (TL->getType().hasLocalQualifiers()) return false;
+ return TSTChecker().Visit(*TL);
+}
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 562e830..4a2b956 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -242,12 +242,13 @@ void TypePrinter::PrintDependentSizedExtVector(
void TypePrinter::PrintVector(const VectorType *T, std::string &S) {
// FIXME: We prefer to print the size directly here, but have no way
// to get the size of the type.
- S += " __attribute__((__vector_size__(";
- S += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
+ Print(T->getElementType(), S);
+ std::string V = "__attribute__((__vector_size__(";
+ V += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
std::string ET;
Print(T->getElementType(), ET);
- S += " * sizeof(" + ET + "))))";
- Print(T->getElementType(), S);
+ V += " * sizeof(" + ET + ")))) ";
+ S = V + S;
}
void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) {
@@ -284,6 +285,23 @@ void TypePrinter::PrintFunctionProto(const FunctionProtoType *T,
}
S += ")";
+
+ if (T->hasExceptionSpec()) {
+ S += " throw(";
+ if (T->hasAnyExceptionSpec())
+ S += "...";
+ else
+ for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) {
+ if (I)
+ S += ", ";
+
+ std::string ExceptionType;
+ Print(T->getExceptionType(I), ExceptionType);
+ S += ExceptionType;
+ }
+ S += ")";
+ }
+
if (T->getNoReturnAttr())
S += " __attribute__((noreturn))";
Print(T->getResultType(), S);
@@ -302,6 +320,15 @@ void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T,
Print(T->getResultType(), S);
}
+void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
+ std::string &S) {
+ IdentifierInfo *II = T->getDecl()->getIdentifier();
+ if (S.empty())
+ S = II->getName().str();
+ else
+ S = II->getName().str() + ' ' + S;
+}
+
void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) {
if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
S = ' ' + S;
@@ -683,9 +710,8 @@ void QualType::dump(const char *msg) const {
LangOptions LO;
getAsStringInternal(R, PrintingPolicy(LO));
if (msg)
- fprintf(stderr, "%s: %s\n", msg, R.c_str());
- else
- fprintf(stderr, "%s\n", R.c_str());
+ llvm::errs() << msg << ": ";
+ llvm::errs() << R << "\n";
}
void QualType::dump() const {
dump("");
OpenPOWER on IntegriCloud