namespace clang {
class ASTContext;
+}
+
+
+// Defined in ASTContext.cpp
+void *operator new(size_t Bytes, clang::ASTContext &C,
+ size_t Alignment = 16) throw ();
+
+namespace clang {
/// Attr - This represents one attribute.
class Attr {
Next = attr;
}
+ // Clone this attribute.
+ virtual Attr* clone(ASTContext &C) const = 0;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *) { return true; }
};
+#define DEF_SIMPLE_ATTR(ATTR) \
+class ATTR##Attr : public Attr { \
+public: \
+ ATTR##Attr() : Attr(ATTR) {} \
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) ATTR##Attr; } \
+ static bool classof(const Attr *A) { return A->getKind() == ATTR; } \
+ static bool classof(const ATTR##Attr *A) { return true; } \
+}
+
class PackedAttr : public Attr {
unsigned Alignment;
/// getAlignment - The specified alignment in bits.
unsigned getAlignment() const { return Alignment; }
+ virtual Attr* clone(ASTContext &C) const {
+ return ::new (C) PackedAttr(Alignment);
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() == Packed;
/// getAlignment - The specified alignment in bits.
unsigned getAlignment() const { return Alignment; }
+
+ virtual Attr* clone(ASTContext &C) const { return ::new (C) AlignedAttr(Alignment); }
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
AnnotateAttr(const std::string &ann) : Attr(Annotate), Annotation(ann) {}
const std::string& getAnnotation() const { return Annotation; }
+
+ virtual Attr* clone(ASTContext &C) const { return ::new (C) AnnotateAttr(Annotation); }
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
const std::string& getLabel() const { return Label; }
+ virtual Attr* clone(ASTContext &C) const { return ::new (C) AsmLabelAttr(Label); }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() == AsmLabel;
static bool classof(const AsmLabelAttr *A) { return true; }
};
-class AlwaysInlineAttr : public Attr {
-public:
- AlwaysInlineAttr() : Attr(AlwaysInline) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == AlwaysInline; }
- static bool classof(const AlwaysInlineAttr *A) { return true; }
-};
+DEF_SIMPLE_ATTR(AlwaysInline);
class AliasAttr : public Attr {
std::string Aliasee;
const std::string& getAliasee() const { return Aliasee; }
- // Implement isa/cast/dyncast/etc.
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) AliasAttr(Aliasee); }
+ // Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) { return A->getKind() == Alias; }
static bool classof(const AliasAttr *A) { return true; }
};
int getPriority() const { return priority; }
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) ConstructorAttr(priority); }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) { return A->getKind() == Constructor; }
static bool classof(const ConstructorAttr *A) { return true; }
int getPriority() const { return priority; }
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) DestructorAttr(priority); }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) { return A->getKind() == Destructor; }
static bool classof(const DestructorAttr *A) { return true; }
};
-
class GNUInlineAttr : public Attr {
public:
GNUInlineAttr() : Attr(GNUInline) {}
-
+
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) GNUInlineAttr; }
+
// Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == GNUInline; }
+ static bool classof(const Attr *A) {
+ return A->getKind() == GNUInline;
+ }
static bool classof(const GNUInlineAttr *A) { return true; }
};
class IBOutletAttr : public Attr {
public:
IBOutletAttr() : Attr(IBOutletKind) {}
-
+
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) IBOutletAttr; }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() == IBOutletKind;
static bool classof(const IBOutletAttr *A) { return true; }
};
-class NoReturnAttr : public Attr {
-public:
- NoReturnAttr() : Attr(NoReturn) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == NoReturn; }
- static bool classof(const NoReturnAttr *A) { return true; }
-};
-
-class AnalyzerNoReturnAttr : public Attr {
-public:
- AnalyzerNoReturnAttr() : Attr(AnalyzerNoReturn) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == AnalyzerNoReturn;
- }
- static bool classof(const AnalyzerNoReturnAttr *A) { return true; }
-};
-
-class DeprecatedAttr : public Attr {
-public:
- DeprecatedAttr() : Attr(Deprecated) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Deprecated; }
- static bool classof(const DeprecatedAttr *A) { return true; }
-};
+DEF_SIMPLE_ATTR(NoReturn);
+DEF_SIMPLE_ATTR(AnalyzerNoReturn);
+DEF_SIMPLE_ATTR(Deprecated);
class SectionAttr : public Attr {
std::string Name;
SectionAttr(const std::string &N) : Attr(Section), Name(N) {}
const std::string& getName() const { return Name; }
-
+
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) SectionAttr(Name); }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() == Section;
static bool classof(const SectionAttr *A) { return true; }
};
-class UnavailableAttr : public Attr {
-public:
- UnavailableAttr() : Attr(Unavailable) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Unavailable; }
- static bool classof(const UnavailableAttr *A) { return true; }
-};
-
-class UnusedAttr : public Attr {
-public:
- UnusedAttr() : Attr(Unused) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Unused; }
- static bool classof(const UnusedAttr *A) { return true; }
-};
-
-class UsedAttr : public Attr {
-public:
- UsedAttr() : Attr(Used) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Used; }
- static bool classof(const UsedAttr *A) { return true; }
-};
-
-class WeakAttr : public Attr {
-public:
- WeakAttr() : Attr(Weak) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Weak; }
- static bool classof(const WeakAttr *A) { return true; }
-};
-
-class WeakImportAttr : public Attr {
-public:
- WeakImportAttr() : Attr(WeakImport) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == WeakImport; }
- static bool classof(const WeakImportAttr *A) { return true; }
-};
-
-class NoThrowAttr : public Attr {
-public:
- NoThrowAttr() : Attr(NoThrow) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == NoThrow; }
- static bool classof(const NoThrowAttr *A) { return true; }
-};
-
-class ConstAttr : public Attr {
-public:
- ConstAttr() : Attr(Const) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Const; }
- static bool classof(const ConstAttr *A) { return true; }
-};
-
-class PureAttr : public Attr {
-public:
- PureAttr() : Attr(Pure) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == Pure; }
- static bool classof(const PureAttr *A) { return true; }
-};
+DEF_SIMPLE_ATTR(Unavailable);
+DEF_SIMPLE_ATTR(Unused);
+DEF_SIMPLE_ATTR(Used);
+DEF_SIMPLE_ATTR(Weak);
+DEF_SIMPLE_ATTR(WeakImport);
+DEF_SIMPLE_ATTR(NoThrow);
+DEF_SIMPLE_ATTR(Const);
+DEF_SIMPLE_ATTR(Pure);
class NonNullAttr : public Attr {
unsigned* ArgNums;
bool isNonNull(unsigned arg) const {
return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
}
-
+
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) NonNullAttr(ArgNums, Size); }
+
static bool classof(const Attr *A) { return A->getKind() == NonNull; }
static bool classof(const NonNullAttr *A) { return true; }
};
int getFormatIdx() const { return formatIdx; }
int getFirstArg() const { return firstArg; }
- // Implement isa/cast/dyncast/etc.
+ virtual Attr *clone(ASTContext &C) const {
+ return ::new (C) FormatAttr(Type, formatIdx, firstArg);
+ }
+ // Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) { return A->getKind() == Format; }
static bool classof(const FormatAttr *A) { return true; }
};
VisibilityTypes getVisibility() const { return VisibilityType; }
- // Implement isa/cast/dyncast/etc.
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) VisibilityAttr(VisibilityType); }
+ // Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) { return A->getKind() == Visibility; }
static bool classof(const VisibilityAttr *A) { return true; }
};
-class DLLImportAttr : public Attr {
-public:
- DLLImportAttr() : Attr(DLLImport) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == DLLImport; }
- static bool classof(const DLLImportAttr *A) { return true; }
-};
-
-class DLLExportAttr : public Attr {
-public:
- DLLExportAttr() : Attr(DLLExport) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == DLLExport; }
- static bool classof(const DLLExportAttr *A) { return true; }
-};
-
-class FastCallAttr : public Attr {
-public:
- FastCallAttr() : Attr(FastCall) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == FastCall; }
- static bool classof(const FastCallAttr *A) { return true; }
-};
-
-class StdCallAttr : public Attr {
-public:
- StdCallAttr() : Attr(StdCall) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == StdCall; }
- static bool classof(const StdCallAttr *A) { return true; }
-};
-
-class TransparentUnionAttr : public Attr {
-public:
- TransparentUnionAttr() : Attr(TransparentUnion) {}
-
- // Implement isa/cast/dyncast/etc.
+DEF_SIMPLE_ATTR(DLLImport);
+DEF_SIMPLE_ATTR(DLLExport);
+DEF_SIMPLE_ATTR(FastCall);
+DEF_SIMPLE_ATTR(StdCall);
+DEF_SIMPLE_ATTR(TransparentUnion);
+DEF_SIMPLE_ATTR(ObjCNSObject);
+DEF_SIMPLE_ATTR(ObjCException);
- static bool classof(const Attr *A) { return A->getKind() == TransparentUnion; }
- static bool classof(const TransparentUnionAttr *A) { return true; }
-};
-
-class ObjCNSObjectAttr : public Attr {
-// Implement isa/cast/dyncast/etc.
-public:
- ObjCNSObjectAttr() : Attr(ObjCNSObject) {}
-
-static bool classof(const Attr *A) { return A->getKind() == ObjCNSObject; }
-static bool classof(const ObjCNSObjectAttr *A) { return true; }
-};
-
-
-class ObjCExceptionAttr : public Attr {
-public:
- ObjCExceptionAttr() : Attr(ObjCException) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == ObjCException; }
- static bool classof(const ObjCExceptionAttr *A) { return true; }
-};
-
-
class OverloadableAttr : public Attr {
public:
OverloadableAttr() : Attr(Overloadable) { }
virtual bool isMerged() const { return false; }
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) OverloadableAttr; }
+
static bool classof(const Attr *A) { return A->getKind() == Overloadable; }
static bool classof(const OverloadableAttr *) { return true; }
};
BlocksAttrTypes getType() const { return BlocksAttrType; }
- // Implement isa/cast/dyncast/etc.
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) BlocksAttr(BlocksAttrType); }
+ // Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) { return A->getKind() == Blocks; }
static bool classof(const BlocksAttr *A) { return true; }
};
const FunctionDecl *getFunctionDecl() const { return FD; }
- // Implement isa/cast/dyncast/etc.
+ virtual Attr *clone(ASTContext &C) const { return ::new (C) CleanupAttr(FD); }
+ // Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) { return A->getKind() == Cleanup; }
static bool classof(const CleanupAttr *A) { return true; }
};
-class NodebugAttr : public Attr {
-public:
- NodebugAttr() : Attr(Nodebug) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Nodebug; }
- static bool classof(const NodebugAttr *A) { return true; }
-};
-
-class WarnUnusedResultAttr : public Attr {
-public:
- WarnUnusedResultAttr() : Attr(WarnUnusedResult) {}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == WarnUnusedResult;}
- static bool classof(const WarnUnusedResultAttr *A) { return true; }
-};
-
-class NoinlineAttr : public Attr {
-public:
- NoinlineAttr() : Attr(Noinline) {}
-
- // Implement isa/cast/dyncast/etc.
-
- static bool classof(const Attr *A) { return A->getKind() == Noinline; }
- static bool classof(const NoinlineAttr *A) { return true; }
-};
+DEF_SIMPLE_ATTR(Nodebug);
+DEF_SIMPLE_ATTR(WarnUnusedResult);
+DEF_SIMPLE_ATTR(Noinline);
class RegparmAttr : public Attr {
unsigned NumParams;
unsigned getNumParams() const { return NumParams; }
- // Implement isa/cast/dyncast/etc.
-
+ virtual Attr *clone(ASTContext &C) const {
+ return ::new (C) RegparmAttr(NumParams);
+ }
+
+ // Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) { return A->getKind() == Regparm; }
static bool classof(const RegparmAttr *A) { return true; }
};
-
-
-#define DEF_SIMPLE_ATTR(ATTR)\
-class ATTR##Attr : public Attr {\
-public:\
- ATTR##Attr() : Attr(ATTR) {}\
- static bool classof(const Attr *A) { return A->getKind() == ATTR; }\
- static bool classof(const ATTR##Attr *A) { return true; }\
-};
// Checker-specific attributes.
-DEF_SIMPLE_ATTR(ObjCOwnershipCFRelease)
-DEF_SIMPLE_ATTR(ObjCOwnershipRelease)
-DEF_SIMPLE_ATTR(ObjCOwnershipCFRetain)
-DEF_SIMPLE_ATTR(ObjCOwnershipRetain)
-DEF_SIMPLE_ATTR(ObjCOwnershipReturns)
+DEF_SIMPLE_ATTR(ObjCOwnershipCFRelease);
+DEF_SIMPLE_ATTR(ObjCOwnershipRelease);
+DEF_SIMPLE_ATTR(ObjCOwnershipCFRetain);
+DEF_SIMPLE_ATTR(ObjCOwnershipRetain);
+DEF_SIMPLE_ATTR(ObjCOwnershipReturns);
#undef DEF_SIMPLE_ATTR
/// MergeAttributes - append attributes from the Old decl to the New one.
static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) {
- Attr *attr = const_cast<Attr*>(Old->getAttrs());
-
- while (attr) {
- Attr *tmp = attr;
- attr = attr->getNext();
-
- if (!DeclHasAttr(New, tmp) && tmp->isMerged()) {
- tmp->setInherited(true);
- New->addAttr(tmp);
- } else {
- tmp->setNext(0);
- tmp->Destroy(C);
+ for (const Attr *attr = Old->getAttrs(); attr; attr = attr->getNext()) {
+ if (!DeclHasAttr(New, attr) && attr->isMerged()) {
+ Attr *NewAttr = attr->clone(C);
+ NewAttr->setInherited(true);
+ New->addAttr(NewAttr);
}
}
-
- Old->invalidateAttrs();
}
/// Used in MergeFunctionDecl to keep track of function parameters in
MergeAttributes(New, Old, Context);
// Merge the storage class.
- New->setStorageClass(Old->getStorageClass());
+ if (Old->getStorageClass() != FunctionDecl::Extern)
+ New->setStorageClass(Old->getStorageClass());
// Merge "inline"
if (Old->isInline())
isOutOfScopePreviousDeclaration(PrevDecl, DC, Context)))
PrevDecl = 0;
- // FIXME: We need to determine whether the GNU inline attribute will
- // be applied to this function declaration, since it affects
- // declaration merging. This hack will go away when the FIXME below
- // is resolved, since we should be putting *all* attributes onto the
- // declaration now.
- for (const AttributeList *Attr = D.getDeclSpec().getAttributes();
- Attr; Attr = Attr->getNext()) {
- if (Attr->getKind() == AttributeList::AT_gnu_inline) {
- NewFD->addAttr(::new (Context) GNUInlineAttr());
- break;
- }
- }
-
// Perform semantic checking on the function declaration.
bool OverloadableAttrRequired = false; // FIXME: HACK!
CheckFunctionDeclaration(NewFD, PrevDecl, Redeclaration,
// Here we determine whether this function, in isolation, would be a
// C99 inline definition. MergeCompatibleFunctionDecls looks at
// previous declarations.
- if (NewFD->isInline() &&
- NewFD->getDeclContext()->getLookupContext()->isTranslationUnit()) {
- bool GNUInline = NewFD->hasAttr<GNUInlineAttr>() ||
- (PrevDecl && PrevDecl->hasAttr<GNUInlineAttr>());
- if (GNUInline || (!getLangOptions().CPlusPlus && !getLangOptions().C99)) {
- // GNU "extern inline" is the same as "inline" in C99.
- if (NewFD->getStorageClass() == FunctionDecl::Extern)
- NewFD->setC99InlineDefinition(true);
- } else if (getLangOptions().C99 &&
- NewFD->getStorageClass() == FunctionDecl::None)
- NewFD->setC99InlineDefinition(true);
- }
+ if (NewFD->isInline() && getLangOptions().C99 &&
+ NewFD->getStorageClass() == FunctionDecl::None &&
+ NewFD->getDeclContext()->getLookupContext()->isTranslationUnit())
+ NewFD->setC99InlineDefinition(true);
// Check for a previous declaration of this name.
if (!PrevDecl && NewFD->isExternC(Context)) {